emacs-elpa-diffs
[Top][All Lists]
Advanced

[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")



reply via email to

[Prev in Thread] Current Thread [Next in Thread]