[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] scratch/javaimp-parse cbf9169: wip
From: |
Filipp Gunbin |
Subject: |
[elpa] scratch/javaimp-parse cbf9169: wip |
Date: |
Wed, 2 Jun 2021 16:47:43 -0400 (EDT) |
branch: scratch/javaimp-parse
commit cbf916981a29f6857a96d224d8d7ca3c1c52b2df
Author: Filipp Gunbin <fgunbin@fastmail.fm>
Commit: Filipp Gunbin <fgunbin@fastmail.fm>
wip
---
javaimp-parse.el | 116 +++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 104 insertions(+), 12 deletions(-)
diff --git a/javaimp-parse.el b/javaimp-parse.el
index 7c29794..b29b2e8 100644
--- a/javaimp-parse.el
+++ b/javaimp-parse.el
@@ -22,20 +22,31 @@
(require 'seq)
(cl-defstruct javaimp-scope
- type ; one of anonymous-class, class, interface, enum, local-class, unknown
+ type ; one of anonymous-class, class, interface, enum, local-class,
+ ; method, statement, unknown
name
start
open-brace)
-(defsubst javaimp--parse-is-class (scope)
- (memq (javaimp-scope-type scope) '(class interface enum)))
+(defconst javaimp--parse-class-keywords
+ '("class" "interface" "enum"))
+(defconst javaimp--parse-stmt-keywords
+ '("if" "for" "while" "switch" "try" "catch"))
-(defconst javaimp--parse-class-re
+(defun javaimp--parse-block-re (keywords)
(concat
- (regexp-opt '("class" "interface" "enum") 'words)
+ (regexp-opt keywords 'words)
(rx (and (+ (syntax whitespace))
(group (+ (any alnum ?_)))))))
+(defconst javaimp--parse-class-re
+ (javaimp--parse-block-re javaimp--parse-class-keywords))
+(defconst javaimp--parse-stmt-re
+ (javaimp--parse-block-re javaimp--parse-stmt-keywords))
+
+(defsubst javaimp--parse-is-class (scope)
+ (member (symbol-name (javaimp-scope-type scope))
javaimp--parse-class-keywords))
+
(defun javaimp--parse-get-package ()
(save-excursion
@@ -50,9 +61,12 @@
(defvar javaimp--parse-scope-hook
- '(javaimp--parse-scope-class
+ '(;; should be before method/stmt because looks similar, but with
+ ;; "new " in front
javaimp--parse-scope-anonymous-class
- javaimp--parse-scope-unknown ;fallback
+ javaimp--parse-scope-method-or-stmt
+ javaimp--parse-scope-class
+ javaimp--parse-scope-unknown ; catch-all
))
(defun javaimp--parse-scope-class (state)
@@ -73,11 +87,13 @@
(if (and (re-search-backward "\\<new\\s +" nil t)
;; skip arg list and ws
(setq end (save-excursion
- (ignore-errors
- (goto-char
- (scan-lists (nth 1 state) -1 0))
- (skip-syntax-backward "-")
- (point))))
+ (and (ignore-errors
+ (goto-char
+ (scan-lists (nth 1 state) -1 0)))
+ (eq (char-after) ?\()
+ (progn
+ (skip-syntax-backward "-")
+ (point)))))
(not (save-match-data
(search-forward "(" end t))))
(make-javaimp-scope :type 'anonymous-class
@@ -88,6 +104,82 @@
:start (match-beginning 0)
:open-brace (nth 1 state))))))
+(defun javaimp--parse-scope-method-or-stmt (state)
+ (save-excursion
+ (when (and (ignore-errors
+ (goto-char ;skip over 1 list
+ (scan-lists (nth 1 state) -1 0)))
+ (eq (char-after) ?\())
+ (let* ((arglist (buffer-substring-no-properties
+ (point)
+ (scan-lists (point) 1 0)))
+ (count (progn
+ (skip-syntax-backward "-")
+ (skip-syntax-backward "w_")))
+ (name (and (< count 0)
+ (buffer-substring-no-properties
+ (point) (+ (point) (abs count)))))
+ (type (when name
+ (if (member name javaimp--parse-stmt-keywords)
+ 'statement 'method))))
+ (when type
+ (make-javaimp-scope :type type
+ :name (if (eq type 'statement)
+ name
+ (concat name
+ ;; to distinguish overloaded
methods
+ (javaimp--parse-arglist
arglist)))
+ :start (point)
+ :open-brace (nth 1 state)))))))
+
+(defun javaimp--parse-arglist (arglist)
+ (with-temp-buffer
+ (with-syntax-table 'javaimp--arglist-syntax-table ;TODO <>
+ (condition-case nil
+ (let (name end res curr)
+ (insert arglist)
+ (backward-char) ; `)'
+ (while (not (bobp))
+ (setq end (point))
+ ;; name
+ (if (= 0 (skip-syntax-backward "w_"))
+ (error "No name")
+ (setq name (buffer-substring (point) end)))
+ (skip-syntax-backward "-")
+ (setq start nil
+ end (point))
+ ;; type - allow anything but skip over angle brackets
+ (while (not start)
+ (cond ((bobp)
+ (error "Invalid type"))
+ ((= (char-before) ? )
+ (setq start (point)))
+ ((= (char-before) ?>)
+ ;; skip over generics
+ (goto-char
+ (scan-lists (point) -1 0)))
+ (t
+ (backward-char))))
+ (push (cons (buffer-substring start end) name) res)
+ (setq curr nil)
+ ;; TODO skip everything up to comma or open-paren
+ )
+ res)
+ (t nil)))))
+
+
+(defun javaimp--parse-scope-class (state)
+ (save-excursion
+ (if (and (re-search-backward javaimp--parse-class-re nil t)
+ ;; if there's no paren in between - assume we're looking at
+ ;; class declaration
+ (not (save-match-data
+ (search-forward "(" (nth 1 state) t))))
+ (make-javaimp-scope :type (intern (match-string 1))
+ :name (match-string 2)
+ :start (match-beginning 1)
+ :open-brace (nth 1 state)))))
+
(defun javaimp--parse-scope-unknown (state)
(make-javaimp-scope :type 'unknown
:name "unknown"