branch: scratch/javaimp-parse commit 6caed642add4555f570361934e0507577e7eaedf Author: Filipp Gunbin <fgun...@fastmail.fm> Commit: Filipp Gunbin <fgun...@fastmail.fm>
wip --- javaimp-parse.el | 104 +++++++++++++++++++++++++------------------------------ javaimp-tests.el | 2 +- 2 files changed, 49 insertions(+), 57 deletions(-) diff --git a/javaimp-parse.el b/javaimp-parse.el index 2b0c3e3..4255aae 100644 --- a/javaimp-parse.el +++ b/javaimp-parse.el @@ -49,11 +49,12 @@ (member (symbol-name (javaimp-scope-type scope)) javaimp--parse-class-keywords)) (defvar javaimp--arglist-syntax-table - "Enables parsing angle brackets as lists" (let ((st (make-syntax-table java-mode-syntax-table))) (modify-syntax-entry ?< "(>" st) (modify-syntax-entry ?> ")<" st) - st)) + (modify-syntax-entry ?. "_" st) ; separates parts of fully-qualified type + st) + "Enables parsing angle brackets as lists") @@ -70,9 +71,9 @@ (while (not (bobp)) (push (javaimp--parse-arglist-one-arg) res) ;; move back to the previous argument, if any - (javaimp--parse-arglist-until (lambda () - (= (char-before) ?,))) - (unless (bobp) + (when (javaimp--parse-arglist-until (lambda () + (and (not (bobp)) + (= (char-before) ?,)))) (backward-char))) res)))))) @@ -80,42 +81,49 @@ ;; Parse one argument backwards starting from point and return it in ;; the form (TYPE . NAME). Leave point at where the job is done: ;; skipping further backwards is done by the caller. - (let ((pos (progn - (skip-syntax-backward "-") - (point))) - name type) + (let ((limit (progn + (skip-syntax-backward "-") + (point))) + name) (if (= 0 (skip-syntax-backward "w_")) (error "Cannot parse argument name")) - (setq name (buffer-substring-no-properties (point) pos)) + (setq name (buffer-substring-no-properties (point) limit)) (skip-syntax-backward "-") - (setq pos (point)) + (setq limit (point)) ;; Parse type: allow anything, but stop at the word boundary which ;; is not inside list (this is presumably the type start..) - (javaimp--parse-arglist-until (lambda () - (looking-at "\\<"))) - (if (bobp) - (error "Cannot parse argument type") - (setq type (replace-regexp-in-string - "[[:space:]]+" " " - (buffer-substring-no-properties (point) pos))) - (cons type name)))) + (if (javaimp--parse-arglist-until (lambda () + (save-excursion + (skip-syntax-forward "-" limit) + (looking-at "\\_<")))) + (progn + (skip-syntax-forward "-") ;undo skipping by ..-until + (let ((type (replace-regexp-in-string + "[[:space:]]+" " " + (buffer-substring-no-properties (point) limit)))) + (cons type name))) + (error "Cannot parse argument type")))) (defun javaimp--parse-arglist-until (stop-p) ;; Goes backwards until position at which STOP-P returns non-nil. - ;; STOP-P is invoked without arguments and should not move point. + ;; Returns non-nil if stopped on this condition, nil if reached bob. + ;; STOP-P is invoked (possibly at the bob) without arguments and + ;; should not move point. Backward movement also skips any + ;; whitespace, so STOP-P looking forward should be prepared to + ;; see leading whitespace. (catch 'done (while t (skip-syntax-backward "-") (let ((state (syntax-ppss))) - (cond ((bobp) - (throw 'done nil)) - ((= (char-syntax (char-before)) ?\)) - (backward-list)) - ((syntax-ppss-context state) + (cond ((syntax-ppss-context state) ;; move out of comment/string if in one (goto-char (nth 8 state))) ((funcall stop-p) + (throw 'done t)) + ((bobp) (throw 'done nil)) + ((= (char-syntax (char-before)) ?\)) + (backward-list)) (t (backward-char))))))) @@ -146,33 +154,29 @@ (defun javaimp--parse-scope-anonymous-class (state) (save-excursion - (let (end) - (if (and (re-search-backward "\\<new\\s +" nil t) - ;; skip arg list and ws - (setq end (save-excursion - (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)))) + ;; skip arg-list and ws + (when (and (ignore-errors + (goto-char + (scan-lists (nth 1 state) -1 0))) + (= (char-after) ?\()) + (skip-syntax-backward "-") + (let ((end (point))) + (when (and (re-search-backward "\\<new\\s-+" nil t) + (not (save-match-data + (search-forward "(" end t)))) (make-javaimp-scope :type 'anonymous-class - :name (concat - "Anon_" - (buffer-substring-no-properties - (match-end 0) end)) + :name (concat "Anon_" + (buffer-substring-no-properties + (match-end 0) end)) :start (match-beginning 0) - :open-brace (nth 1 state)))))) + :open-brace (nth 1 state))))))) (defun javaimp--parse-scope-method-or-stmt (state) (save-excursion (when (and (ignore-errors (goto-char (scan-lists (nth 1 state) -1 0))) - (eq (char-after) ?\()) + (= (char-after) ?\()) (let* (;; leave open/close parens out (arglist-region (cons (1+ (point)) (1- (scan-lists (point) 1 0)))) @@ -203,18 +207,6 @@ :start (point) :open-brace (nth 1 state))))))) -(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" diff --git a/javaimp-tests.el b/javaimp-tests.el index 055e21a..51efcff 100644 --- a/javaimp-tests.el +++ b/javaimp-tests.el @@ -32,7 +32,7 @@ ("List<? extends Comparable<? super T>>" . "list") ("T..." . "elements")) ("org.foo.Map <? extends K, ? extends V> m, String [] array, int i" - ;; TODO fix code to clear up extra ws here + ;; TODO fix code to remove extra ws here ("org.foo.Map <? extends K, ? extends V>" . "m") ("String []" . "array") ("int" . "i"))