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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/phpinspect a1107ea176 1/5: BROKEN/WIP: change parsing o


From: ELPA Syncer
Subject: [elpa] externals/phpinspect a1107ea176 1/5: BROKEN/WIP: change parsing of type definitions
Date: Sun, 22 Sep 2024 03:59:02 -0400 (EDT)

branch: externals/phpinspect
commit a1107ea1768b695204837c4fb141d82cd62adeab
Author: Hugo Thunnissen <devel@hugot.nl>
Commit: Hugo Thunnissen <devel@hugot.nl>

    BROKEN/WIP: change parsing of type definitions
---
 phpinspect-bmap.el             |  7 +++-
 phpinspect-buffer.el           | 18 ++++++---
 phpinspect-index.el            |  2 +-
 phpinspect-meta.el             |  3 ++
 phpinspect-parser.el           | 84 ++++++++++++++++++++++++++++++++++--------
 phpinspect-token-predicates.el | 12 ++++--
 phpinspect-type.el             | 64 +++++++++++++-------------------
 phpinspect-typedef.el          |  5 ++-
 test/test-type.el              | 17 +++++++++
 9 files changed, 146 insertions(+), 66 deletions(-)

diff --git a/phpinspect-bmap.el b/phpinspect-bmap.el
index e5a5db65b3..6cbb7dbf3c 100644
--- a/phpinspect-bmap.el
+++ b/phpinspect-bmap.el
@@ -32,6 +32,8 @@
 (require 'phpinspect-token-predicates)
 
 (eval-when-compile
+  (require 'cl-macs)
+
   (defvar phpinspect-parse-context nil
     "dummy for compilation")
 
@@ -40,6 +42,8 @@
   (phpinspect--declare-log-group 'bmap))
 
 (cl-defstruct (phpinspect-bmap (:constructor phpinspect-make-bmap))
+  "A bmap, short for buffer-map, is a structure whose purpose is to
+map parsed tokens to metadata about them and vice versa."
   (starts (make-hash-table :test #'eql
                            :size (floor (/ (point-max) 2))
                            :rehash-size 1.5))
@@ -48,7 +52,8 @@
                            :rehash-size 1.5))
   (meta (make-hash-table :test #'eq
                            :size (floor (/ (point-max) 2))
-                           :rehash-size 1.5))
+                           :rehash-size 1.5)
+        :documentation "A hash-table containing all newly registered tokens.")
   (token-stack nil
                :type list)
   (overlays (phpinspect-make-splayt)
diff --git a/phpinspect-buffer.el b/phpinspect-buffer.el
index 6cafc5142b..0f0f717867 100644
--- a/phpinspect-buffer.el
+++ b/phpinspect-buffer.el
@@ -278,12 +278,16 @@ linked with."
     (list imports namespace-name)))
 
 (defun phpinspect--buffer-update-type-declaration (buffer typedef declaration 
class-token imports namespace-name)
+  (cl-assert (phpinspect-meta-p declaration))
+
   (phpi-typedef-update-declaration
-   typedef declaration imports namespace-name
+   typedef (phpinspect-meta-token declaration) imports namespace-name
    (phpinspect-buffer-get-trait-configuration-between-points
     buffer (phpinspect-meta-start class-token) (phpinspect-meta-end 
class-token)
     (phpinspect--make-type-resolver
-     imports (phpinspect-class-block (phpinspect-meta-token class-token)) 
namespace-name))))
+     imports (phpinspect-class-block (phpinspect-meta-token class-token)) 
namespace-name))
+   (thread-last (phpinspect-meta-parent declaration)
+                (phpinspect-meta-token))))
 
 (cl-defmethod phpinspect-buffer-index-classes ((buffer phpinspect-buffer) 
(classes (head phpinspect-splayt)))
   (let ((declarations (phpinspect-buffer-declarations buffer))
@@ -327,7 +331,9 @@ linked with."
                                             (phpinspect--make-type-resolver
                                              (phpinspect--uses-to-types 
imports)
                                              (phpinspect-class-block 
(phpinspect-meta-token (cdr class)))
-                                             namespace-name)))
+                                             namespace-name)
+                                            (thread-last 
(phpinspect-meta-parent declaration)
+                                                         
(phpinspect-meta-token))))
                 (when class-name
                   (setq  class-obj (phpinspect-project-get-typedef-create 
project class-name 'no-enqueue))
                   (phpinspect-buffer-set-index-reference-for-token buffer 
(phpinspect-meta-token (cdr class)) class-obj)
@@ -343,13 +349,15 @@ linked with."
                                       (phpinspect--make-type-resolver
                                        (phpinspect--uses-to-types imports)
                                        (phpinspect-class-block 
(phpinspect-meta-token class))
-                                       namespace-name)))
+                                       namespace-name)
+                                      (thread-last (phpinspect-meta-parent 
declaration)
+                                                   (phpinspect-meta-token))))
                      (class-obj))
           (when class-name
             (setq class-obj (phpinspect-project-get-typedef-create project 
class-name 'no-enqueue))
             (phpinspect-buffer-set-index-reference-for-token buffer 
(phpinspect-meta-token class) class-obj)
             (phpinspect--buffer-update-type-declaration
-             buffer class-obj (phpinspect-meta-token declaration) class 
imports namespace-name)))))))
+             buffer class-obj declaration class imports namespace-name)))))))
 
 (cl-defmethod phpinspect-buffer-index-functions ((buffer phpinspect-buffer) 
(functions (head phpinspect-splayt)))
   (let ((classes (phpinspect-buffer-classes buffer))
diff --git a/phpinspect-index.el b/phpinspect-index.el
index 49a5f35021..7b664e00c1 100644
--- a/phpinspect-index.el
+++ b/phpinspect-index.el
@@ -351,7 +351,7 @@ SCOPE should be a scope token (`phpinspect-scope-p')."
               (setq used-types additional-used-types))))
 
     (pcase-setq `(,class-name ,extends ,implements ,used-types)
-                (phpinspect--index-class-declaration (cadr class) 
type-resolver))
+                (phpinspect--index-class-declaration (cadr class) 
type-resolver class))
 
 
     (dolist (token (caddr class))
diff --git a/phpinspect-meta.el b/phpinspect-meta.el
index 26f6a7dac6..cb20c44173 100644
--- a/phpinspect-meta.el
+++ b/phpinspect-meta.el
@@ -58,6 +58,9 @@
   (inline-quote (list 'meta ,parent ,start ,end ,whitespace-before ,token 
,overlay
                       (or ,children (phpinspect-make-splayt)) ,parent-offset 
,deleted)))
 
+(define-inline phpinspect-meta-p (meta)
+  (inline-quote (eq 'meta (car-safe ,meta))))
+
 (define-inline phpinspect-meta-parent (meta)
   (inline-quote (cadr ,meta)))
 
diff --git a/phpinspect-parser.el b/phpinspect-parser.el
index 852155921a..3a2cf60335 100644
--- a/phpinspect-parser.el
+++ b/phpinspect-parser.el
@@ -284,8 +284,9 @@ root token, in string form without \":\" prefix.")
                       attribute-reference variable
                       assignment-operator whitespace scope-keyword
                       static-keyword const-keyword use-keyword
-                      class-keyword function-keyword word terminator
-                      here-doc string string-concatenator comment block)
+                      class-keyword interface-keyword trait-keyword 
enum-keyword
+                      function-keyword word terminator here-doc string
+                      string-concatenator comment block)
               :type list
               :read-only t
               :documentation "A list of symbols referring to the
@@ -790,6 +791,21 @@ Returns the consumed text string without face properties."
                                    nil t)
                 (buffer-substring-no-properties start-point (- (point) 
1)))))))))
 
+(phpinspect-defhandler extends-keyword (start-token &rest _max-point)
+  "Handler for the extends keyword in a class declaration."
+  ((regexp . (concat "extends" (phpinspect--word-end-regex))))
+  (phpinspect--skip-over-word start-token)
+  '(:extends))
+
+(phpinspect-defhandler implements-keyword (start-token &rest _max-point)
+  "Handler for the implements keyword in a class declaration."
+  ((regexp . (concat "implements" (phpinspect--word-end-regex))))
+  (phpinspect--skip-over-word start-token)
+  '(:implements))
+
+(phpinspect-defparser class-declaration
+  :tree-keyword "class-declaration"
+  :handlers '(comment extends-keyword implements-keyword comma word list 
terminator tag))
 
 (phpinspect-defparser declaration
   :tree-keyword "declaration"
@@ -889,23 +905,58 @@ Returns the consumed text string without face properties."
       (setcar token :incomplete-array))
     token))
 
+(define-inline phpinspect--parse-type-declaration (max-point)
+  (inline-quote
+   (phpinspect--parse-class-declaration
+    (current-buffer)
+    ,max-point
+    nil
+    (lambda () (not (char-equal (char-after) ?{)))
+    'root)))
+
+(define-inline phpinspect--skip-over-word (word-plus-whitespace)
+  (inline-quote
+   (forward-char (length (phpinspect--strip-word-end-space 
,word-plus-whitespace)))))
+
+(phpinspect-defhandler final-keyword (start-token &rest _max-point)
+  "Handler for the final keyword."
+  ((regexp . (concat "final" (phpinspect--word-end-regex))))
+  (phpinspect--skip-over-word start-token)
+  '(:final))
+
+(phpinspect-defhandler abstract-keyword (start-token &rest _max-point)
+  "Handler for the abstract keyword."
+  ((regexp . (concat "abstract" (phpinspect--word-end-regex))))
+  (phpinspect--skip-over-word start-token)
+  '(:abstract))
+
+(phpinspect-defhandler interface-keyword (start-token max-point)
+  "Handler for the interface keyword."
+  ((regexp . (concat "interface" (phpinspect--word-end-regex))))
+  (phpinspect--skip-over-word start-token)
+  `(:interface ,(phpinspect--parse-type-declaration max-point)
+               ,@(cdr (phpinspect--parse-class-body (current-buffer) max-point 
nil))))
+
+(phpinspect-defhandler trait-keyword (start-token max-point)
+  "Handler for the interface keyword."
+  ((regexp . (concat "trait" (phpinspect--word-end-regex))))
+  (phpinspect--skip-over-word start-token)
+  `(:trait ,(phpinspect--parse-type-declaration max-point)
+           ,@(cdr (phpinspect--parse-class-body (current-buffer) max-point 
nil))))
+
+(phpinspect-defhandler enum-keyword (start-token max-point)
+  "Handler for the interface keyword."
+  ((regexp . (concat "enum" (phpinspect--word-end-regex))))
+  (phpinspect--skip-over-word start-token)
+  `(:enum ,(phpinspect--parse-type-declaration max-point)
+          ,@(cdr (phpinspect--parse-class-body (current-buffer) max-point 
nil))))
+
 (phpinspect-defhandler class-keyword (start-token max-point)
   "Handler for the class keyword, and tokens that follow to define
 the properties of the class"
-  ;; FIXME: "case" keyworded enum cases are not recognized/parsed into anything
-  ;; other than "word" tokens. Enums might require a different (specialized)
-  ;; handler to parse into an indexable tree. For now, this works to get basic
-  ;; functionality (enum methods) as enum case support hasn't been implemented
-  ;; yet.
-  ((regexp . (concat 
"\\(abstract\\|final\\|class\\|interface\\|trait\\|enum\\)"
-                     (phpinspect--word-end-regex))))
-  (setq start-token (phpinspect--strip-word-end-space start-token))
-  `(:class ,(phpinspect--parse-declaration
-                (current-buffer)
-                max-point
-                nil
-                (lambda () (not (char-equal (char-after) ?{)))
-                'root)
+  ((regexp . (concat "class" (phpinspect--word-end-regex))))
+  (phpinspect--skip-over-word start-token)
+  `(:class ,(phpinspect--parse-type-declaration max-point)
            ,@(cdr (phpinspect--parse-class-body (current-buffer) max-point 
nil))))
 
 (phpinspect-defparser class-body
@@ -921,6 +972,7 @@ the properties of the class"
   :handlers '(namespace array equals list comma attribute-reference variable
                         assignment-operator whitespace scope-keyword
                         static-keyword const-keyword use-keyword class-keyword
+                        interface-keyword trait-keyword enum-keyword
                         function-keyword word terminator here-doc string 
string-concatenator
                         comment tag block))
 
diff --git a/phpinspect-token-predicates.el b/phpinspect-token-predicates.el
index b60e05013a..5bf498542d 100644
--- a/phpinspect-token-predicates.el
+++ b/phpinspect-token-predicates.el
@@ -24,13 +24,13 @@
 ;;; Code:
 
 
-(define-inline phpinspect-token-type-p (object type)
+(define-inline phpinspect-token-type-p (object &rest types)
   "Returns t if OBJECT is a token of type TYPE.
 Type can be any of the token types returned by
 `phpinspect-parse-buffer-until-point`"
   (inline-letevals (object)
     (inline-quote
-     (and (eq (car-safe ,object) ,type)))))
+     (memq (car-safe ,object) ,(cons 'list types)))))
 
 (define-inline phpinspect-object-attrib-p (token)
   (inline-quote
@@ -133,7 +133,13 @@ Type can be any of the token types returned by
   (inline-quote (phpinspect-token-type-p ,token :function)))
 
 (define-inline phpinspect-class-p (token)
-  (inline-quote (phpinspect-token-type-p ,token :class)))
+  (inline-quote (phpinspect-token-type-p ,token :class :interface :trait 
:enum)))
+
+(define-inline phpinspect-implements-p (token)
+  (inline-quote (phpinspect-token-type-p ,token :implements)))
+
+(define-inline phpinspect-extends-p (token)
+  (inline-quote (phpinspect-token-type-p ,token :extends)))
 
 (defun phpinspect-not-list-p (token)
   (not (phpinspect-list-p token)))
diff --git a/phpinspect-type.el b/phpinspect-type.el
index f121a44c61..08e87ad4cd 100644
--- a/phpinspect-type.el
+++ b/phpinspect-type.el
@@ -408,48 +408,36 @@ mutability of the variable")
                             (cadr class-token))))
     (cadr subtoken)))
 
-(defun phpinspect--index-class-declaration (decl type-resolver)
+(defun phpinspect--index-class-declaration (decl type-resolver parent)
   ;; Find out what the class extends or implements
   (let (keyword encountered-extends encountered-implements encountered-class
         class-name extends implements used-types)
     (dolist (word decl)
-      (if (phpinspect-word-p word)
-          (cond ((string= (cadr word) "extends")
-                 (phpinspect--log "Class %s extends other classes" class-name)
-                 (setq encountered-extends t))
-                ((string= (cadr word) "implements")
-                 (setq encountered-extends nil)
-                 (phpinspect--log "Class %s implements in interface" 
class-name)
-                 (setq encountered-implements t))
-                ((string-match-p
-                  (eval-when-compile
-                    (concat "^" (phpinspect--class-keyword-handler-regexp) 
"?$"))
-                  (cadr word))
-                 (setq keyword word
-                       encountered-class t))
-                (t
-                 (phpinspect--log "Calling Resolver from index-class on %s" 
(cadr word))
-                 (cond (encountered-extends
-                        (push (funcall type-resolver (phpinspect--make-type
-                                                      :name (cadr word)))
-                              extends)
-                        (push (cadr word) used-types))
-                       (encountered-implements
-                        (push (funcall type-resolver (phpinspect--make-type
-                                                      :name (cadr word)))
-                              implements)
-                        (push (cadr word) used-types))
-                       (encountered-class
-                        (setq class-name
-                              (funcall type-resolver (phpinspect--make-type
-                                                      :category (pcase (cadr 
keyword)
-                                                                  ("class" 
'class)
-                                                                  ("trait" 
'trait)
-                                                                  ("interface" 
'interface)
-                                                                  ("enum" 
'enum)
-                                                                  (_ 'class))
-                                                      :name (cadr word)))
-                              encountered-class nil)))))))
+      (cond ((phpinspect-word-p word)
+             (cond (encountered-implements
+                    (push (funcall type-resolver (phpinspect--make-type
+                                                  :name (cadr word)))
+                          implements)
+                    (push (cadr word) used-types))
+                   (encountered-extends
+                    (push (funcall type-resolver (phpinspect--make-type
+                                                  :name (cadr word)))
+                          extends)
+                    (push (cadr word) used-types))
+                   (t
+                    (setq class-name
+                          (funcall type-resolver (phpinspect--make-type
+                                                  :category (pcase (car parent)
+                                                              (:class 'class)
+                                                              (:trait 'trait)
+                                                              (:interface 
'interface)
+                                                              (:enum 'enum)
+                                                              (_ 'class))
+                                                  :name (cadr word)))))))
+            ((phpinspect-extends-p word)
+             (setq encountered-extends t))
+            ((phpinspect-implements-p word)
+             (setq encountered-implements t))))
 
     (list class-name extends implements used-types)))
 
diff --git a/phpinspect-typedef.el b/phpinspect-typedef.el
index 499b71da60..35456c5334 100644
--- a/phpinspect-typedef.el
+++ b/phpinspect-typedef.el
@@ -354,7 +354,7 @@ TYPE must be a structure of type `phpinspect--type'."
         (phpi-mcol-set-home-type (phpi-typedef-static-methods def) type)
        (phpi-pcol-set-home-type (phpi-typedef-properties def) type)))))
 
-(defun phpi-typedef-update-declaration (def declaration imports namespace-name 
trait-config)
+(defun phpi-typedef-update-declaration (def declaration imports namespace-name 
trait-config parent)
   "Update declaration of DEF.
 
 DECLARATION must be a token of type `phpinspect-declaration-p`.
@@ -371,7 +371,8 @@ TRAIT-CONFIG must be a trait configuration as returned by
     (pcase-let ((`(,type ,extends ,implements ,_used-types)
                  (phpinspect--index-class-declaration
                   declaration (phpinspect--make-type-resolver
-                               (phpinspect--uses-to-types imports) nil 
namespace-name))))
+                               (phpinspect--uses-to-types imports) nil 
namespace-name)
+                  parent)))
       (phpi-typedef-set-name def type)
       (setf (phpi-typedef-declaration def) declaration)
       (phpi-typedef-update-extensions
diff --git a/test/test-type.el b/test/test-type.el
index d5933cb93a..69123da589 100644
--- a/test/test-type.el
+++ b/test/test-type.el
@@ -36,3 +36,20 @@
                 (phpinspect--make-type :name "\\AType"))
 
                (phpinspect--make-type :name (cdr set)))))))
+
+(ert-deftest phpinspect--index-class-declaration ()
+  (let* ((class (cadr (phpinspect-parse-string "class A extends B implements 
C, D {}")))
+         (declaration (cadr class)))
+
+
+    (should (equal '(:class-declaration (:word "A")
+                                        (:extends) (:word "B")
+                                        (:implements) (:word "C") (:comma ",") 
(:word "D"))
+                   declaration))
+
+    (pcase-let ((`(,name ,extends ,implements ,used-types)
+                 (phpinspect--index-class-declaration declaration 
(phpinspect--make-type-resolver nil) class)))
+      (should (phpinspect--type= (phpinspect--make-type :name "\\A") name))
+      (should (length= extends 1))
+      (should (length= implements 2))
+      (should (length= used-types 3)))))



reply via email to

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