branch: externals/phps-mode commit d802a669c0b8c0693fbfa22d1944c5d6b060e8d2 Author: Christian Johansson <christ...@cvj.se> Commit: Christian Johansson <christ...@cvj.se>
Bookkeeping via AST working with isset() and !empty() scoped variables --- phps-mode-ast-bookkeeping.el | 120 +++++++++++++++++++++++++++---------------- test/phps-mode-test-ast.el | 2 +- 2 files changed, 76 insertions(+), 46 deletions(-) diff --git a/phps-mode-ast-bookkeeping.el b/phps-mode-ast-bookkeeping.el index 1054f87282..35a14eb3d7 100644 --- a/phps-mode-ast-bookkeeping.el +++ b/phps-mode-ast-bookkeeping.el @@ -171,6 +171,15 @@ ((and (equal scope-type 'defined) scope-name) + (when read-only + ;; Branch off here in alternative scope without this defined context + ;; but only for read-only contexts + (push + (list + scope-string + namespace + bubbles) + bubbles-stack)) (setq scope-string (format @@ -355,50 +364,64 @@ (push `(,sub-scope ,child) bookkeeping-stack))))) ((equal type 'if) - (let ((conditions (reverse (plist-get item 'condition))) + (let* ((conditions (reverse (plist-get item 'condition))) + (condition-stack conditions) + (condition) (found-defined-scope) (sub-scope scope)) - (dolist (condition conditions) - (when-let ((condition-type (plist-get condition 'ast-type))) - (cond - - ((equal condition-type 'isset-variables) - (let ((sub-scope scope)) - (unless found-defined-scope - (setq defined-count (1+ defined-count)) - (setq found-defined-scope t)) - (push `(type defined name ,defined-count) sub-scope) - (let ((isset-variables (plist-get condition 'variables))) - (dolist (isset-variable isset-variables) - (let ((id - (phps-mode-ast-bookkeeping--generate-variable-scope-string - sub-scope - (plist-get isset-variable 'name)))) - (puthash - id - 1 - bookkeeping)))))) - - ((and - (equal condition-type 'negated-expression) - (equal (plist-get (plist-get condition 'expression) 'ast-type) 'empty-expression)) - (let ((sub-scope scope)) - (unless found-defined-scope - (setq defined-count (1+ defined-count)) - (setq found-defined-scope t)) - (push `(type defined name ,defined-count) sub-scope) - (let ((not-empty-variables (plist-get (plist-get condition 'expression) 'variables))) - (dolist (not-empty-variable not-empty-variables) - (let ((id - (phps-mode-ast-bookkeeping--generate-variable-scope-string - sub-scope - (plist-get not-empty-variable 'name)))) - (puthash - id - 1 - bookkeeping)))))) - - ))) + (while condition-stack + (let ((condition (pop condition-stack))) + (when-let ((condition-type (plist-get condition 'ast-type))) + (cond + + ((or (equal condition-type 'boolean-and-expression) + (equal condition-type 'boolean-or-expression)) + (let ((as (reverse (plist-get condition 'a))) + (bs (reverse (plist-get condition 'b)))) + (dolist (b bs) + (push b condition-stack)) + (dolist (a as) + (push a condition-stack)))) + + ((equal condition-type 'isset-variables) + (let ((sub-scope scope)) + (unless found-defined-scope + (setq defined-count (1+ defined-count)) + (setq found-defined-scope t)) + (push `(type defined name ,defined-count) sub-scope) + (let ((isset-variables (plist-get condition 'variables))) + (dolist (isset-variable isset-variables) + (let ((ids + (phps-mode-ast-bookkeeping--generate-variable-scope-string + sub-scope + (plist-get isset-variable 'name)))) + (dolist (id ids) + (puthash + id + 1 + bookkeeping))))))) + + ((and + (equal condition-type 'negated-expression) + (equal (plist-get (plist-get condition 'expression) 'ast-type) 'empty-expression)) + (let ((sub-scope scope)) + (unless found-defined-scope + (setq defined-count (1+ defined-count)) + (setq found-defined-scope t)) + (push `(type defined name ,defined-count) sub-scope) + (let ((not-empty-variables (plist-get (plist-get condition 'expression) 'variables))) + (dolist (not-empty-variable not-empty-variables) + (let ((ids + (phps-mode-ast-bookkeeping--generate-variable-scope-string + sub-scope + (plist-get not-empty-variable 'name)))) + (dolist (id ids) + (puthash + id + 1 + bookkeeping))))))) + + )))) (when found-defined-scope (push `(type defined name ,defined-count) sub-scope)) (when-let ((children (reverse (plist-get item 'children)))) @@ -408,6 +431,16 @@ (dolist (condition conditions) (push `(,sub-scope ,condition) bookkeeping-stack))))) + ((equal type 'isset-variables) + (let ((isset-variables (reverse (plist-get item 'variables)))) + (dolist (isset-variable isset-variables) + (push `(,scope ,isset-variable) bookkeeping-stack)))) + + ((equal type 'empty-expression) + (let ((not-empty-variables (reverse (plist-get item 'variables)))) + (dolist (not-empty-variable not-empty-variables) + (push `(,scope ,not-empty-variable) bookkeeping-stack)))) + ((equal type 'foreach) (when-let ((children (reverse (plist-get item 'children)))) (dolist (child children) @@ -597,7 +630,6 @@ (plist-get item 'start) (plist-get item 'end))) (defined 1)) - ;; (message "ids: %S from %S" ids item) (dolist (id ids) (when-let ((predefined (gethash id bookkeeping))) (setq @@ -689,7 +721,6 @@ (list (plist-get item 'property-start) (plist-get item 'property-end)))) - ;; (message "dereferenced: %S %S" variable-id symbol-id) (when (gethash symbol-id bookkeeping) (setq predefined @@ -716,7 +747,6 @@ (plist-get subject 'name) t)) (predefined 0)) - ;; (message "variable-ids: %S" variable-ids) (dolist (variable-id variable-ids) (when (gethash variable-id diff --git a/test/phps-mode-test-ast.el b/test/phps-mode-test-ast.el index e58001c914..bf4fa56eef 100644 --- a/test/phps-mode-test-ast.el +++ b/test/phps-mode-test-ast.el @@ -603,7 +603,7 @@ (should (equal (phps-mode-test--hash-to-list phps-mode-ast-bookkeeping--index t) - '((" defined 1 id $x" 1) ((18 20) 1) ((33 35) 1) (" defined 2 id $i" 1) (" defined 2 id $u" 1) ((77 79) 1) ((81 83) 1) ((104 106) 1) ((168 170) 1) ((232 234) 1) ((302 304) 0) ((355 357) 0) ((408 410) 0) (" defined 3 id $y" 1) ((445 447) 1) ((460 462) 1) (" defined 4 id $k" 1) ((505 507) 1) (" defined 4 id $L" 1) ((519 521) 1) ((542 544) 1) ((606 608) 1) ((670 672) 1) ((740 742) 0) ((793 795) 0) ((846 848) 0)))))) + '((" defined 1 id $x" 1) ((18 20) 1) ((33 35) 1) (" defined 1 defined 2 id $i" 1) (" defined 1 defined 2 id $u" 1) ((77 79) 1) ((81 83) 1) ((104 106) 1) ((168 170) 1) ((232 234) 1) ((302 304) 0) ((355 357) 0) ((408 410) 0) (" defined 3 id $y" 1) ((445 447) 1) ((460 462) 1) (" defined 3 defined 4 id $k" 1) (" defined 3 defined 4 id $L" 1) ((505 507) 1) ((519 521) 1) ((542 544) 1) ((606 608) 1) ((670 672) 1) ((740 742) 0) ((793 795) 0) ((846 848) 0)))))) (phps-mode-test-ast--buffer-contents "<?php\ninterface myInterface\n{\n function myFunction1();\n function myFunction2($x);\n}\n"