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