[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] scratch/javaimp-parse fbe2426: wip
From: |
Filipp Gunbin |
Subject: |
[elpa] scratch/javaimp-parse fbe2426: wip |
Date: |
Mon, 31 May 2021 16:45:51 -0400 (EDT) |
branch: scratch/javaimp-parse
commit fbe24265529a8c898a49b4f64bbf896a98a7d24e
Author: Filipp Gunbin <fgunbin@fastmail.fm>
Commit: Filipp Gunbin <fgunbin@fastmail.fm>
wip
---
javaimp-util.el | 127 ++++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 96 insertions(+), 31 deletions(-)
diff --git a/javaimp-util.el b/javaimp-util.el
index f2f4c00..70ccb0d 100644
--- a/javaimp-util.el
+++ b/javaimp-util.el
@@ -171,42 +171,107 @@ buffer and returns its result"
(unless (syntax-ppss-context state)
(throw 'found (match-string 1)))))))))
+;; for imenu: named classes, then their members (skip over `{' then just jump
by braces)
+;; indentation: from the point up
+
+(defconst javaimp--class-re
+ (concat
+ (regexp-opt '("class" "interface" "enum") 'words)
+ (rx (and (+ (syntax whitespace))
+ (group (+ (any alnum ?_)))))))
+
+(defstruct javaimp-scope
+ ;; one of anonymous, class, interface, enum, local-class, lambda,
+ ;; unknown
+ type
+ name
+ start
+ open-brace)
+
+(defun javaimp--parse-scope-class (state)
+ (if (and (re-search-backward javaimp--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 (point)
+ :open-brace (nth 1 state))))
+
+(defun javaimp--parse-scope-anonymous (state)
+ ;; TODO
+ ;; anonymous: find "new"; scan-lists -1; no parens between
+ ;; generate name based on superclass
+ )
+
+(defun javaimp--parse-scope-lambda (state)
+ ;; TODO
+ ;; "->" right before bracket; (scan-lists -1) if previous is `)', else
(scan-sexps -1)
+ )
+
+
+(defmacro javaimp--parse-scope (state &rest parsers)
+ `(or ,@(mapcar (lambda (p)
+ `(save-excursion
+ (funcall ,p ,state)))
+ parsers)))
+
+(defun javaimp--collect-scopes (count)
+ (interactive "p")
+ (let ((state (syntax-ppss))
+ curr res)
+ (unless (syntax-ppss-context state)
+ (save-excursion
+ (while (and (nth 1 state)
+ (or (not count)
+ (>= (setq count (1- count) 0))))
+ ;; find innermost enclosing open-bracket
+ (goto-char (nth 1 state))
+ (when (= (char-after) ?{)
+ (if (setq curr (javaimp--parse-scope
+ state
+ #'javaimp--parse-scope-anonymous
+ #'javaimp--parse-scope-class
+ #'javaimp--parse-scope-lambda))
+ (progn
+ (push curr res)
+ (goto-char (javaimp-scope-start curr)))
+ (push (make-javaimp-scope :type 'unknown
+ :name "unknown"
+ :start nil
+ :open-brace (nth 1 state)))))
+ (setq state (syntax-ppss)))))
+ ;; if a class is enclosed in anyting other than a class, then it
+ ;; should be local
+ (let ((tmp res)
+ in-local)
+ (while tmp
+ (if (eq (javaimp-scope-type (car tmp)) 'class)
+ (if in-local (setf (javiamp-scope-type (car tmp)) 'local-class))
+ (setq in-local t))
+ (setq tmp (cdr tmp))))
+ res))
+
+
(defun javaimp--get-file-classes (file)
(with-temp-buffer
(insert-file-contents file)
(let ((parse-sexp-ignore-comments t)
- (class-re (concat
- (regexp-opt '("class" "interface" "enum") 'words)
- (rx (and (+ (syntax whitespace))
- (group (+ (any alnum ?_)))))))
res)
- (while (re-search-forward class-re nil t)
- (let ((state (syntax-ppss))
- curr)
- (unless (syntax-ppss-context state)
- (setq curr (list (match-string 2)))
- ;; collect enclosing classes, if any
- (save-excursion
- (catch 'stop
- (while (nth 1 state)
- ;; find innermost enclosing open-bracket
- (goto-char (nth 1 state))
- (if (and (= (char-after) ?{)
- (re-search-backward class-re nil t)
- ;; if there's no paren in between - assume
- ;; it's a valid class (not a method - this
- ;; way we exclude local classes)
- (not (save-match-data
- (search-forward "(" (nth 1 state) t))))
- (progn
- (push (match-string 2) curr)
- (setq state (syntax-ppss)))
- (setq curr nil)
- (throw 'stop nil)))))
- (when curr
- (let ((package (javaimp--get-package)))
- (if package (push package curr)))
- (push (mapconcat #'identity curr ".") res)))))
+ (while (re-search-forward javaimp--class-re nil t)
+ (let ((scopes (javaimp--collect-scopes nil))
+ (curr (list (match-string 2))))
+ (catch 'stop
+ (dolist (scope scopes)
+ (if (eq (javaimp-scope-type scope) 'class)
+ (push (javaimp-scope-name scope) curr)
+ (setq curr nil)
+ (throw 'stop nil))))
+ (when curr
+ (let ((package (javaimp--get-package)))
+ (if package (push package curr)))
+ (push (mapconcat #'identity curr ".") res))))
(nreverse res))))
(provide 'javaimp-util)