[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/javaimp 62d9fca: Add javaimp-parse.el
From: |
Filipp Gunbin |
Subject: |
[elpa] externals/javaimp 62d9fca: Add javaimp-parse.el |
Date: |
Mon, 31 May 2021 21:58:26 -0400 (EDT) |
branch: externals/javaimp
commit 62d9fcaae4c667ecb6644ad8befbd94081b086a0
Author: Filipp Gunbin <fgunbin@fastmail.fm>
Commit: Filipp Gunbin <fgunbin@fastmail.fm>
Add javaimp-parse.el
---
javaimp-parse.el | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
javaimp-tests.el | 8 +--
javaimp-util.el | 52 --------------------
javaimp.el | 5 +-
4 files changed, 152 insertions(+), 58 deletions(-)
diff --git a/javaimp-parse.el b/javaimp-parse.el
new file mode 100644
index 0000000..7c29794
--- /dev/null
+++ b/javaimp-parse.el
@@ -0,0 +1,145 @@
+;;; javaimp-parse.el --- javaimp parsing -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc.
+
+;; Author: Filipp Gunbin <fgunbin@fastmail.fm>
+;; Maintainer: Filipp Gunbin <fgunbin@fastmail.fm>
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+(require 'cl-lib)
+(require 'seq)
+
+(cl-defstruct javaimp-scope
+ type ; one of anonymous-class, class, interface, enum, local-class, unknown
+ name
+ start
+ open-brace)
+
+(defsubst javaimp--parse-is-class (scope)
+ (memq (javaimp-scope-type scope) '(class interface enum)))
+
+(defconst javaimp--parse-class-re
+ (concat
+ (regexp-opt '("class" "interface" "enum") 'words)
+ (rx (and (+ (syntax whitespace))
+ (group (+ (any alnum ?_)))))))
+
+
+(defun javaimp--parse-get-package ()
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (point-min))
+ (catch 'found
+ (while (re-search-forward "^\\s *package\\s +\\([^;]+\\)\\s *;" nil t)
+ (let ((state (syntax-ppss)))
+ (unless (syntax-ppss-context state)
+ (throw 'found (match-string 1)))))))))
+
+
+(defvar javaimp--parse-scope-hook
+ '(javaimp--parse-scope-class
+ javaimp--parse-scope-anonymous-class
+ javaimp--parse-scope-unknown ;fallback
+ ))
+
+(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-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
+ (ignore-errors
+ (goto-char
+ (scan-lists (nth 1 state) -1 0))
+ (skip-syntax-backward "-")
+ (point))))
+ (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))
+ :start (match-beginning 0)
+ :open-brace (nth 1 state))))))
+
+(defun javaimp--parse-scope-unknown (state)
+ (make-javaimp-scope :type 'unknown
+ :name "unknown"
+ :start nil
+ :open-brace (nth 1 state)))
+
+(defun javaimp--parse-scopes (count)
+ (let ((state (syntax-ppss))
+ 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) ?{)
+ (let ((scope (run-hook-with-args-until-success
+ 'javaimp--parse-scope-hook state)))
+ (push scope res)
+ (if (javaimp-scope-start scope)
+ (goto-char (javaimp-scope-start scope)))))
+ (setq state (syntax-ppss)))))
+ ;; if a class is enclosed in anything other than a class, then it
+ ;; should be local
+ (let ((tmp res)
+ in-local)
+ (while tmp
+ (if (javaimp--parse-is-class (car tmp))
+ (if in-local
+ (setf (javaimp-scope-type (car tmp)) 'local-class))
+ (setq in-local t))
+ (setq tmp (cdr tmp))))
+ res))
+
+(defun javaimp--parse-get-file-classes (file)
+ (with-temp-buffer
+ (insert-file-contents file)
+ (let ((parse-sexp-ignore-comments t)
+ (package (javaimp--parse-get-package))
+ res)
+ (while (re-search-forward javaimp--parse-class-re nil t)
+ (when (and (ignore-errors
+ (goto-char (scan-lists (point) 1 -1)))
+ (= (char-before) ?{))
+ (let ((scopes (javaimp--parse-scopes nil))
+ curr)
+ (when (seq-every-p #'javaimp--parse-is-class scopes)
+ (setq curr (mapconcat #'javaimp-scope-name scopes "."))
+ (if package
+ (setq curr (concat package "." curr)))
+ (push curr res)))))
+ (nreverse res))))
+
+(provide 'javaimp-parse)
diff --git a/javaimp-tests.el b/javaimp-tests.el
index 36b4686..9951a81 100644
--- a/javaimp-tests.el
+++ b/javaimp-tests.el
@@ -23,15 +23,15 @@
(should (eql (length projects) 2)))))
-(ert-deftest javaimp-test--get-package ()
+(ert-deftest javaimp-test--parse-get-package ()
(with-temp-buffer
(insert "//package org.commented1;
/*package org.commented2;*/
package org.foo;")
- (should (equal (javaimp--get-package) "org.foo"))))
+ (should (equal (javaimp--parse-get-package) "org.foo"))))
-(ert-deftest javaimp-test--get-file-classes ()
- (should (equal (javaimp--get-file-classes
+(ert-deftest javaimp-test--parse-get-file-classes ()
+ (should (equal (javaimp--parse-get-file-classes
(concat javaimp--basedir
"testdata/test-get-file-classes-1.java"))
'("org.foo.Top"
"org.foo.Top.CInner1"
diff --git a/javaimp-util.el b/javaimp-util.el
index f2f4c00..9304fce 100644
--- a/javaimp-util.el
+++ b/javaimp-util.el
@@ -157,56 +157,4 @@ buffer and returns its result"
(setf (javaimp-node-children this-node) child-nodes)
this-node)))
-
-;; Java source parsing
-
-(defun javaimp--get-package ()
- (save-excursion
- (save-restriction
- (widen)
- (goto-char (point-min))
- (catch 'found
- (while (re-search-forward "^\\s *package\\s +\\([^;]+\\)\\s *;" nil t)
- (let ((state (syntax-ppss)))
- (unless (syntax-ppss-context state)
- (throw 'found (match-string 1)))))))))
-
-(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)))))
- (nreverse res))))
-
(provide 'javaimp-util)
diff --git a/javaimp.el b/javaimp.el
index 8b368ea..a0dd555 100644
--- a/javaimp.el
+++ b/javaimp.el
@@ -77,6 +77,7 @@
(require 'javaimp-maven)
(require 'javaimp-gradle)
+(require 'javaimp-parse)
@@ -444,7 +445,7 @@ prefix arg is given, don't do this filtering."
javaimp-additional-source-dirs)))
(defun javaimp--dir-above-current-package ()
- (let ((package (javaimp--get-package)))
+ (let ((package (javaimp--parse-get-package)))
(when package
(string-remove-suffix
(mapconcat #'file-name-as-directory
@@ -453,7 +454,7 @@ prefix arg is given, don't do this filtering."
(defun javaimp--get-directory-classes (dir)
(if (file-accessible-directory-p dir)
- (seq-mapcat #'javaimp--get-file-classes
+ (seq-mapcat #'javaimp--parse-get-file-classes
(seq-filter (lambda (file)
(not (file-symlink-p file)))
(directory-files-recursively dir
"\\.java\\'")))))
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [elpa] externals/javaimp 62d9fca: Add javaimp-parse.el,
Filipp Gunbin <=