[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/phpinspect 9b82c0d0f6 111/126: Reimplement `phpinspect-
From: |
ELPA Syncer |
Subject: |
[elpa] externals/phpinspect 9b82c0d0f6 111/126: Reimplement `phpinspect-fix-imports' using metadata objects |
Date: |
Sat, 12 Aug 2023 00:58:52 -0400 (EDT) |
branch: externals/phpinspect
commit 9b82c0d0f6d0cdf9af850554ed2dc8561c721037
Author: Hugo Thunnissen <devel@hugot.nl>
Commit: Hugo Thunnissen <devel@hugot.nl>
Reimplement `phpinspect-fix-imports' using metadata objects
---
phpinspect-imports.el | 108 ++++++++++++++++++++++++++------------------------
phpinspect-meta.el | 22 ++++++++++
phpinspect-splayt.el | 32 ++++++++++++++-
test/test-splayt.el | 17 ++++++++
4 files changed, 126 insertions(+), 53 deletions(-)
diff --git a/phpinspect-imports.el b/phpinspect-imports.el
index 0dc753bf7f..e971e75dd8 100644
--- a/phpinspect-imports.el
+++ b/phpinspect-imports.el
@@ -35,7 +35,14 @@
(goto-char point)
(insert data)))
-(defun phpinspect-add-use (fqn buffer &optional namespace-token)
+(defun phpinspect-find-first-use (token-meta)
+ (if (and (phpinspect-namespace-p (phpinspect-meta-token token-meta))
+ (phpinspect-namespace-is-blocked-p (phpinspect-meta-token
token-meta)))
+ (phpinspect-find-first-use (phpinspect-meta-last-child token-meta))
+ (phpinspect-meta-find-first-child-matching
+ token-meta (phpinspect-meta-wrap-token-pred #'phpinspect-use-p))))
+
+(defun phpinspect-add-use (fqn buffer &optional namespace-meta)
"Add use statement for FQN to BUFFER.
If NAMESPACE-TOKEN is non-nil, it is assumed to be a token that
@@ -44,46 +51,47 @@ buffer position to insert the use statement at."
(when (string-match "^\\\\" fqn)
(setq fqn (string-trim-left fqn "\\\\")))
- (if namespace-token
- (let* ((meta (phpinspect-bmap-token-meta
- (phpinspect-buffer-map buffer) namespace-token))
- (existing-use (seq-find #'phpinspect-use-p
- (phpinspect-namespace-body
namespace-token)))
- (namespace-block (phpinspect-namespace-block namespace-token)))
+ (if namespace-meta
+ (let* ((namespace-block (and (phpinspect-namespace-is-blocked-p
+ (phpinspect-meta-token namespace-meta))
+ (phpinspect-meta-last-child
namespace-meta)))
+ (existing-use (phpinspect-find-first-use namespace-meta)))
(if existing-use
(phpinspect-insert-at-point
- (phpinspect-meta-start
- (phpinspect-buffer-token-meta buffer existing-use))
- (format "use %s;%c" fqn ?\n))
+ (phpinspect-meta-start existing-use) (format "use %s;%c" fqn ?\n))
(if namespace-block
(phpinspect-insert-at-point
- (+ 1 (phpinspect-meta-start
- (phpinspect-buffer-token-meta buffer namespace-block)))
+ (+ 1 (phpinspect-meta-start namespace-block))
(format "%c%cuse %s;%c" ?\n ?\n fqn ?\n))
(phpinspect-insert-at-point
(phpinspect-meta-end
- (phpinspect-buffer-token-meta
- buffer (seq-find #'phpinspect-terminator-p
namespace-token)))
+ (phpinspect-meta-find-first-child-matching
+ namespace-meta (phpinspect-meta-wrap-token-pred
#'phpinspect-terminator-p)))
(format "%c%cuse %s;%c" ?\n ?\n fqn ?\n)))))
;; else
- (let ((existing-use (seq-find #'phpinspect-use-p
- (phpinspect-buffer-tree buffer))))
+ (let ((existing-use (phpinspect-meta-find-first-child-matching
+ (phpinspect-buffer-root-meta buffer)
+ (phpinspect-meta-wrap-token-pred #'phpinspect-use-p))))
(if existing-use
(phpinspect-insert-at-point
- (phpinspect-meta-start
- (phpinspect-buffer-token-meta buffer existing-use))
+ (phpinspect-meta-start existing-use)
(format "use %s;%c" fqn ?\n))
- (let ((first-token (cadr (phpinspect-buffer-tree buffer))))
- (if (and (phpinspect-word-p first-token)
- (string= "declare" (cadr first-token)))
+ (let* ((first-token (phpinspect-meta-first-child
(phpinspect-buffer-root-meta buffer)))
+ token-after)
+ (message "First token %s" (phpinspect-meta-string first-token))
+ (when (and (phpinspect-word-p (phpinspect-meta-token first-token))
+ (string= "declare" (cadr (phpinspect-meta-token
first-token))))
+ (progn
+ (setq token-after first-token)
+ (while (and token-after (not (phpinspect-terminator-p
+ (phpinspect-meta-token
token-after))))
+ (setq token-after (phpinspect-meta-find-right-sibling
token-after))
+ (message "Token after: %s" (phpinspect-meta-string
token-after)))))
+ (if token-after
(phpinspect-insert-at-point
- (phpinspect-meta-end
- (phpinspect-buffer-token-meta
- buffer (seq-find #'phpinspect-terminator-p
(phpinspect-buffer-tree buffer))))
- (format "%c%cuse %s;%c" ?\n ?\n fqn ?\n))
+ (phpinspect-meta-end token-after) (format "%c%cuse %s;%c" ?\n
?\n fqn ?\n))
(phpinspect-insert-at-point
- (phpinspect-meta-start
- (phpinspect-buffer-token-meta buffer first-token))
+ (phpinspect-meta-start first-token)
(format "%c%cuse %s;%c%c" ?\n ?\n fqn ?\n ?\n))))))))
(defun phpinspect-add-use-interactive (typename buffer project &optional
namespace-token)
@@ -109,10 +117,10 @@ buffer position to insert the use statement at."
that there are import (\"use\") statements for them."
(interactive)
(if phpinspect-current-buffer
- (let* ((tree (phpinspect-buffer-parse phpinspect-current-buffer))
+ (let* ((buffer phpinspect-current-buffer)
+ (tree (phpinspect-buffer-parse buffer))
(index (phpinspect--index-tokens
- tree nil (phpinspect-buffer-location-resolver
- phpinspect-current-buffer)))
+ tree nil (phpinspect-buffer-location-resolver buffer)))
(classes (alist-get 'classes index))
(imports (alist-get 'imports index))
(project (phpinspect--cache-get-project-create
@@ -122,20 +130,23 @@ that there are import (\"use\") statements for them."
(let* ((class-imports (alist-get 'imports class))
(used-types (alist-get 'used-types class))
(class-name (alist-get 'class-name class))
- (region))
- (dolist (type used-types)
- ;; Retrieve latest version of class location data changes with
- ;; each added use statement + reindex.
- (setq region
- (alist-get 'location
- (phpinspect-index-get-class
- index class-name)))
-
- (let ((namespace
- (seq-find (lambda (meta) (phpinspect-namespace-p
(phpinspect-meta-token meta)))
- (phpinspect-buffer-tokens-enclosing-point
- phpinspect-current-buffer
(phpinspect-region-start region)))))
+ (region (alist-get 'location class))
+ token-meta namespace)
+ (message "Region: %s" region)
+ (message "index: %s" index)
+ (setq token-meta (phpinspect-meta-find-parent-matching-token
+ (phpinspect-bmap-last-token-before-point
+ (phpinspect-buffer-map buffer)
+ (+ (phpinspect-region-start region) 1))
+ #'phpinspect-class-p))
+ (unless token-meta
+ (error "Unable to find token for class %s" class-name))
+
+
+ (dolist (type used-types)
+ (setq namespace (phpinspect-meta-find-parent-matching-token
+ token-meta #'phpinspect-namespace-p))
;; Add use statements for types that aren't imported.
(unless (or (or (alist-get type class-imports)
(alist-get type imports))
@@ -147,14 +158,7 @@ that there are import (\"use\") statements for them."
(phpinspect-autoloader-types
(phpinspect-project-autoload project))))
(phpinspect-add-use-interactive
- type phpinspect-current-buffer project
(phpinspect-meta-token namespace))
- ;; Buffer has been modified by adding type, update buffer map
- ;; and index for correct location data.
- (setq index
- (phpinspect--index-tokens
- (phpinspect-buffer-parse phpinspect-current-buffer)
- nil
- (phpinspect-buffer-location-resolver
- phpinspect-current-buffer)))))))))))
+ type buffer project namespace)
+ (phpinspect-buffer-parse buffer 'no-interrupt))))))))
(provide 'phpinspect-imports)
diff --git a/phpinspect-meta.el b/phpinspect-meta.el
index 2ba41bafdd..e898371c9e 100644
--- a/phpinspect-meta.el
+++ b/phpinspect-meta.el
@@ -133,6 +133,12 @@
(phpinspect-splayt-find-largest-before (phpinspect-meta-children
(phpinspect-meta-parent meta))
(phpinspect-meta-parent-offset
meta))))
+(cl-defmethod phpinspect-meta-find-right-sibling ((meta (head meta)))
+ (when (phpinspect-meta-parent meta)
+ (phpinspect-splayt-find-smallest-after (phpinspect-meta-children
(phpinspect-meta-parent meta))
+ (phpinspect-meta-parent-offset
meta))))
+
+
(cl-defmethod phpinspect-meta-find-overlapping-child ((meta (head meta))
(point integer))
(let ((child (phpinspect-splayt-find-largest-before
(phpinspect-meta-children meta) (phpinspect-meta--point-offset
meta point))))
@@ -162,6 +168,10 @@
(phpinspect-splayt-find-largest-before
(phpinspect-meta-children meta) (phpinspect-meta--point-offset meta point)))
+(cl-defmethod phpinspect-meta-find-child-after ((meta (head meta)) (point
integer))
+ (phpinspect-splayt-find-smallest-after
+ (phpinspect-meta-children meta) (phpinspect-meta--point-offset meta point)))
+
(cl-defmethod phpinspect-meta-find-child-before-recursively ((meta (head
meta)) (point integer))
(let ((child meta)
last)
@@ -180,6 +190,18 @@
(phpinspect-meta-children meta) (phpinspect-meta--point-offset meta
point))
#'phpinspect-meta-sort-start))
+(cl-defmethod phpinspect-meta-find-first-child-matching ((meta (head meta))
predicate)
+ (catch 'return
+ (phpinspect-splayt-traverse-lr (child (phpinspect-meta-children meta))
+ (when (funcall predicate child)
+ (throw 'return child)))))
+
+(cl-defmethod phpinspect-meta-last-child ((meta (head meta)))
+ (phpinspect-meta-find-child-before meta (phpinspect-meta-end meta)))
+
+(cl-defmethod phpinspect-meta-first-child ((meta (head meta)))
+ (phpinspect-meta-find-child-after meta (- (phpinspect-meta-start meta) 1)))
+
(defun phpinspect-meta-string (meta)
(if meta
diff --git a/phpinspect-splayt.el b/phpinspect-splayt.el
index c4874f6993..37f81fa08a 100644
--- a/phpinspect-splayt.el
+++ b/phpinspect-splayt.el
@@ -93,6 +93,9 @@ apeared to be a little more performant than using `let'."
(define-inline phpinspect-splayt-root-node (splayt)
(inline-quote (car ,splayt)))
+(define-inline phpinspect-splayt-empty-p (splayt)
+ (inline-quote (not (phpinspect-splayt-root-node ,splayt))))
+
(define-inline phpinspect-splayt-node-rotate-right (node &optional splayt)
(inline-letevals (node splayt)
(inline-quote
@@ -216,7 +219,7 @@ apeared to be a little more performant than using `let'."
(define-inline phpinspect-splayt-insert-node (splayt node)
(inline-letevals (splayt node (parent (inline-quote
(phpinspect-splayt-node-temp-store ,node))))
(inline-quote
- (if (not (phpinspect-splayt-root-node ,splayt))
+ (if (phpinspect-splayt-empty-p ,splayt)
(setf (phpinspect-splayt-root-node ,splayt) ,node)
(progn
(setf ,parent (phpinspect-splayt-find-insertion-node ,splayt
(phpinspect-splayt-node-key ,node)))
@@ -292,6 +295,33 @@ near the top of the tee."
(,(car place-and-splayt) (phpinspect-splayt-root-node ,(cadr
place-and-splayt)))
,@body))
+(defmacro phpinspect-splayt-node-traverse-lr (place-and-node &rest body)
+ (declare (indent 1))
+ (let ((place (car place-and-node))
+ (current (gensym))
+ (stack (gensym)))
+ `(let* ((,current ,(cadr place-and-node))
+ ,stack
+ ,@(if (symbolp place) (list place)))
+ (while (or ,stack ,current)
+ (if ,current
+ (progn
+ (push ,current ,stack)
+ (setq ,current (phpinspect-splayt-node-left ,current)))
+ (setq ,current (pop ,stack))
+ (setf ,place (phpinspect-splayt-node-value ,current))
+ ,@body
+ (setq ,current (phpinspect-splayt-node-right ,current)))))))
+
+(defmacro phpinspect-splayt-traverse-lr (place-and-splayt &rest body)
+ "Traverse splay tree in cadr of PLACE-AND-SPLAYT depth-first from left to
right, executing BODY.
+
+The car of PLACE-AND-SPLAYT is assigned the value of each node."
+ (declare (indent 1))
+ `(phpinspect-splayt-node-traverse-lr
+ (,(car place-and-splayt) (phpinspect-splayt-root-node ,(cadr
place-and-splayt)))
+ ,@body))
+
(define-inline phpinspect-splayt-node-key-less-p (node key)
(inline-quote (> ,key (phpinspect-splayt-node-key ,node))))
diff --git a/test/test-splayt.el b/test/test-splayt.el
index 525fe1aaae..7eacf7d5ce 100644
--- a/test/test-splayt.el
+++ b/test/test-splayt.el
@@ -101,6 +101,23 @@
(should (equal expected result)))))
+(ert-deftest phpinspect-splayt-traverse-lr ()
+ (let ((tree (phpinspect-make-splayt)))
+ (phpinspect-splayt-insert tree 9 "nine")
+ (phpinspect-splayt-insert tree 3 "three")
+ (phpinspect-splayt-insert tree 11 "eleven")
+ (phpinspect-splayt-insert tree 8 "eight")
+ (phpinspect-splayt-insert tree 12 "twelve")
+ (phpinspect-splayt-insert tree 4 "four")
+ (phpinspect-splayt-insert tree 1 "one")
+
+ (let ((expected '("one" "three" "four" "eight" "nine" "eleven" "twelve"))
+ result)
+ (phpinspect-splayt-traverse-lr (item tree)
+ (setq result (nconc result (list item))))
+
+ (should (equal expected result)))))
+
(ert-deftest phpinspect-splayt-find-smallest-after ()
(let ((tree (phpinspect-make-splayt)))
(phpinspect-splayt-insert tree 9 "nine")
- [elpa] externals/phpinspect 9d6ce5726d 076/126: Use `phpinspect-edtrack-original-position-at-point' for edit end determination, (continued)
- [elpa] externals/phpinspect 9d6ce5726d 076/126: Use `phpinspect-edtrack-original-position-at-point' for edit end determination, ELPA Syncer, 2023/08/12
- [elpa] externals/phpinspect 58ad65932b 069/126: Add `phpinspect-parser' type and `phpinspect-defparser' macro, ELPA Syncer, 2023/08/12
- [elpa] externals/phpinspect 5548734ef7 075/126: Implement parser interruption on user input, ELPA Syncer, 2023/08/12
- [elpa] externals/phpinspect 2049121810 097/126: Make edit delta lookup inclusive of current point, ELPA Syncer, 2023/08/12
- [elpa] externals/phpinspect 9a25959aad 095/126: Use metadata tree instead of hash table for token lookup, ELPA Syncer, 2023/08/12
- [elpa] externals/phpinspect 43310092ad 081/126: Clear tree and edit tracker when reparsing (to ensure full reparse), ELPA Syncer, 2023/08/12
- [elpa] externals/phpinspect 8dd9bb07e4 080/126: Increase phpinspect-bmap-last-token-before-point backward search limit to 100, ELPA Syncer, 2023/08/12
- [elpa] externals/phpinspect 75562aab35 085/126: Add some tests for edit tracker + patch newly discovered bugs, ELPA Syncer, 2023/08/12
- [elpa] externals/phpinspect 135263c533 110/126: Add tests for incremental parsing + fix parser bugs that came to light, ELPA Syncer, 2023/08/12
- [elpa] externals/phpinspect ea7795c76e 106/126: Remove commented code, ELPA Syncer, 2023/08/12
- [elpa] externals/phpinspect 9b82c0d0f6 111/126: Reimplement `phpinspect-fix-imports' using metadata objects,
ELPA Syncer <=
- [elpa] externals/phpinspect c20df819b8 114/126: Give `phpinspect-buffer' responsibility over buffer indexation, ELPA Syncer, 2023/08/12
- [elpa] externals/phpinspect 04606a4756 121/126: Fix test, ELPA Syncer, 2023/08/12
- [elpa] externals/phpinspect d51137e58e 112/126: Remove faulty edit tracker code based on wrong deduction, ELPA Syncer, 2023/08/12
- [elpa] externals/phpinspect db3ec3b67d 124/126: Add custom variables for worker and pipeline pause time, ELPA Syncer, 2023/08/12
- [elpa] externals/phpinspect 50d2bfeebe 002/126: Change indexer's cache dir from/to .cache/{phpns, phpinspect}, ELPA Syncer, 2023/08/12
- [elpa] externals/phpinspect 0b210309e7 041/126: Fix variable suggestion when there are loose dollar signs in the buffer, ELPA Syncer, 2023/08/12
- [elpa] externals/phpinspect c50f2ae09b 020/126: Fix resolving of "static" and "self" types, ELPA Syncer, 2023/08/12
- [elpa] externals/phpinspect 1816495538 045/126: Use thread-live-p in stead of thread-alive-p for emacs 28.1 support, ELPA Syncer, 2023/08/12
- [elpa] externals/phpinspect 8d3bd21015 006/126: Add license information, ELPA Syncer, 2023/08/12
- [elpa] externals/phpinspect 811a9a9141 010/126: Add more tests for the parser code, ELPA Syncer, 2023/08/12