branch: externals/phps-mode
commit 258551c02a3ab6b30c5f04e925a75b9da31f0a50
Author: Christian Johansson <christ...@cvj.se>
Commit: Christian Johansson <christ...@cvj.se>

    More work on bookkeeping generation via SDT
---
 phps-mode-ast-bookkeeping.el | 1077 +-----------------------------------------
 phps-mode-parser-sdt.el      |   48 +-
 2 files changed, 48 insertions(+), 1077 deletions(-)

diff --git a/phps-mode-ast-bookkeeping.el b/phps-mode-ast-bookkeeping.el
index e4fd2b2b9e..6bf8875c65 100644
--- a/phps-mode-ast-bookkeeping.el
+++ b/phps-mode-ast-bookkeeping.el
@@ -249,1081 +249,8 @@
 
 (defun phps-mode-ast-bookkeeping--generate (&optional tree)
   "Generate AST for current buffer or optionally for TREE."
-  (let ((bookkeeping (make-hash-table :test 'equal))
-        (bookkeeping-stack (if tree tree phps-mode-ast--tree))
-        (bookkeeping-objects)
-        (inline-function-count 0)
-        (arrow-function-count 0)
-        (defined-count 0)
-        (global-namespace))
-    (while bookkeeping-stack
-      (let ((item-raw (pop bookkeeping-stack))
-            (item)
-            (scope))
-        (if (listp (car item-raw))
-            (progn
-              (setq
-               scope
-               (car item-raw))
-              (setq
-               item
-               (car (cdr item-raw))))
-          (setq
-           item
-           item-raw))
-
-        ;; Set global namespace (if any)
-        (when global-namespace
-          (let ((had-scope-p scope))
-            (when had-scope-p
-              (setq scope (reverse scope)))
-            (push
-             (list 'type 'namespace 'name global-namespace)
-             scope)
-            (when had-scope-p
-              (setq scope (reverse scope)))))
-
-        (let ((type (plist-get item 'ast-type)))
-          (cond
-
-           ((equal type 'simple-variable)
-            (let* ((object-name (plist-get item 'name))
-                   (object-start (plist-get item 'start))
-                   (object-end (plist-get item 'end))
-                   (ids
-                    (phps-mode-ast-bookkeeping--generate-variable-scope-string
-                     scope
-                     object-name
-                     t))
-                   (object
-                    (list
-                     object-start
-                     object-end))
-                   (defined-p 0)
-                   (bookkeeping-object
-                    (list
-                     'type type
-                     'name object-name
-                     'scope scope
-                     'start object-start
-                     'end object-end)))
-              (push
-               bookkeeping-object
-               bookkeeping-objects)
-
-              (dolist (id ids)
-                (when (gethash id bookkeeping)
-                  (setq
-                   defined-p
-                   1)))
-
-              ;; Is it a super-global variable?
-              (when
-                  (gethash
-                   (plist-get item 'name)
-                   phps-mode-ast-bookkeeping--superglobal-variable-p)
-                (setq
-                 defined-p
-                 1))
-              (puthash
-               object
-               defined-p
-               bookkeeping)))
-
-           ((equal type 'static-variables-statement)
-            (when-let ((variables (reverse (plist-get item 'static-var-list))))
-              (dolist (variable variables)
-                (let* ((object-name (plist-get variable 'name))
-                       (object-start (plist-get variable 'start))
-                       (object-end (plist-get variable 'end))
-                       (ids
-                        
(phps-mode-ast-bookkeeping--generate-variable-scope-string
-                         scope
-                         object-name))
-                       (object
-                        (list
-                         object-start
-                         object-end))
-                       (bookkeeping-object
-                        (list
-                         'type type
-                         'name object-name
-                         'scope scope
-                         'start object-start
-                         'end object-end)))
-                  (push
-                   bookkeeping-object
-                   bookkeeping-objects)
-
-                  (dolist (id ids)
-                    (puthash
-                     id
-                     1
-                     bookkeeping))
-                  (puthash
-                   object
-                   1
-                   bookkeeping)))))
-
-           ((equal type 'function)
-            (let ((name (plist-get item 'name))
-                  (sub-scope scope))
-              (push `(type function name ,name) sub-scope)
-              (when-let ((parameter-list (plist-get item 'parameter-list)))
-                (dolist (parameter parameter-list)
-                  (let* ((object-name (plist-get parameter 'name))
-                         (object-start (plist-get parameter 'start))
-                         (object-end (plist-get parameter 'end))
-                         (ids
-                          
(phps-mode-ast-bookkeeping--generate-variable-scope-string
-                           sub-scope
-                           object-name))
-                         (object
-                          (list
-                           object-start
-                           object-end))
-                         (bookkeeping-object
-                          (list
-                           'type type
-                           'name object-name
-                           'scope scope
-                           'start object-start
-                           'end object-end)))
-                    (push
-                     bookkeeping-object
-                     bookkeeping-objects)
-
-                    (dolist (id ids)
-                      (puthash
-                       id
-                       1
-                       bookkeeping))
-                    (puthash
-                     object
-                     1
-                     bookkeeping))))
-
-              (when-let ((children (reverse (plist-get item 'children))))
-                (dolist (child children)
-                  (push `(,sub-scope ,child) bookkeeping-stack)))))
-
-           ((equal type 'return-statement)
-            (when-let ((expr (reverse (plist-get item 'optional-expr))))
-              (dolist (e expr)
-                (push `(,scope ,e) bookkeeping-stack))))
-
-           ((equal type 'method)
-            (let ((name (plist-get item 'name))
-                  (sub-scope scope)
-                  (parent-is-interface)
-                  (is-static))
-              (push `(type function name ,name) sub-scope)
-
-              (when-let ((modifiers (plist-get item 'modifiers)))
-                (dolist (modifier modifiers)
-                  (when (equal modifier 'static)
-                    (setq
-                     is-static
-                     t))))
-
-              (when (equal (plist-get (car scope) 'type) 'interface)
-                (setq parent-is-interface t))
-
-              (unless (or
-                       is-static
-                       parent-is-interface)
-                (let ((this-ids
-                       
(phps-mode-ast-bookkeeping--generate-variable-scope-string
-                        sub-scope
-                        "$this")))
-                  (dolist (this-id this-ids)
-                    (puthash
-                     this-id
-                     1
-                     bookkeeping))))
-
-              (when-let ((parameter-list (plist-get item 'parameter-list)))
-                (dolist (parameter parameter-list)
-                  (let* ((object-name (plist-get parameter 'name))
-                         (object-start (plist-get parameter 'start))
-                         (object-end (plist-get parameter 'end))
-                         (ids
-                          
(phps-mode-ast-bookkeeping--generate-variable-scope-string
-                           sub-scope
-                           object-name))
-                         (object
-                          (list
-                           object-start
-                           object-end))
-                         (bookkeeping-object
-                          (list
-                           'type type
-                           'name object-name
-                           'scope scope
-                           'start object-start
-                           'end object-end)))
-                    (push
-                     bookkeeping-object
-                     bookkeeping-objects)
-
-                    (dolist (id ids)
-                      (puthash
-                       id
-                       1
-                       bookkeeping))
-                    (puthash
-                     object
-                     1
-                     bookkeeping))))
-
-              (when-let ((children (reverse (plist-get item 'children))))
-                (dolist (child children)
-                  (push `(,sub-scope ,child) bookkeeping-stack)))))
-
-           ((equal type 'namespace)
-            (let ((name (plist-get item 'name))
-                  (sub-scope scope))
-              (push `(type namespace name ,name) sub-scope)
-              (if-let ((children (reverse (plist-get item 'children))))
-                  (dolist (child children)
-                    (push `(,sub-scope ,child) bookkeeping-stack))
-                (setq global-namespace name))))
-
-           ((equal type 'class)
-            (let ((name (plist-get item 'name))
-                  (sub-scope scope))
-              (push `(type class name ,name) sub-scope)
-              (when-let ((children (reverse (plist-get item 'children))))
-                (dolist (child children)
-                  (push `(,sub-scope ,child) bookkeeping-stack)))))
-
-           ((equal type 'interface)
-            (let ((name (plist-get item 'name))
-                  (sub-scope scope))
-              (push `(type interface name ,name) sub-scope)
-              (when-let ((children (reverse (plist-get item 'children))))
-                (dolist (child children)
-                  (push `(,sub-scope ,child) bookkeeping-stack)))))
-
-           ((equal type 'if)
-            (let* ((conditions (reverse (plist-get item 'condition)))
-                   (condition-stack conditions)
-                   (found-defined-scope)
-                   (sub-scope scope))
-              (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))))
-                (dolist (child children)
-                  (push `(,sub-scope, child) bookkeeping-stack)))
-              (when conditions
-                (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)
-                (push `(,scope ,child) bookkeeping-stack)))
-            (when-let ((value (plist-get item 'value)))
-              (if (equal (plist-get value 'ast-type) 
'foreach-referenced-variable)
-                  (push
-                   (list
-                    scope
-                    (list
-                     'ast-type
-                     'assign-variable
-                     'key
-                     (plist-get value 'variable)))
-                   bookkeeping-stack)
-                (push
-                 (list
-                  scope
-                  (list
-                   'ast-type
-                   'assign-variable
-                   'key
-                   value))
-                 bookkeeping-stack)))
-            (when-let ((key (plist-get item 'key)))
-              (push
-               (list
-                scope
-                (list
-                 'ast-type
-                 'assign-variable
-                 'key
-                 key))
-               bookkeeping-stack))
-            (when-let ((expression (reverse (plist-get item 'expression))))
-              (dolist (expr expression)
-                (push `(,scope ,expr) bookkeeping-stack))))
-
-           ((equal type 'for)
-            (when-let ((children (reverse (plist-get item 'children))))
-              (dolist (child children)
-                (push `(,scope ,child) bookkeeping-stack)))
-            (when-let ((children (reverse (plist-get item 'incremental))))
-              (dolist (child children)
-                (push `(,scope ,child) bookkeeping-stack)))
-            (when-let ((children (reverse (plist-get item 'test))))
-              (dolist (child children)
-                (push `(,scope ,child) bookkeeping-stack)))
-            (when-let ((children (reverse (plist-get item 'initial))))
-              (dolist (child children)
-                (push `(,scope ,child) bookkeeping-stack))))
-
-           ((equal type 'while)
-            (when-let ((children (reverse (plist-get item 'children))))
-              (dolist (child children)
-                (push `(,scope ,child) bookkeeping-stack)))
-            (when-let ((conditions (reverse (plist-get item 'condition))))
-              (dolist (condition conditions)
-                (push `(,scope ,condition) bookkeeping-stack))))
-
-           ((equal type 'do-while)
-            (when-let ((conditions (reverse (plist-get item 'condition))))
-              (dolist (condition conditions)
-                (push `(,scope ,condition) bookkeeping-stack)))
-            (when-let ((children (reverse (plist-get item 'children))))
-              (dolist (child children)
-                (push `(,scope ,child) bookkeeping-stack))))
-
-           ((equal type 'assign-property-variable)
-            (let* ((object-key (plist-get item 'key))
-                   (object-start (plist-get item 'start))
-                   (object-end (plist-get item 'end))
-                   (ids
-                    (phps-mode-ast-bookkeeping--generate-variable-scope-string
-                     scope
-                     object-key))
-                   (object
-                    (list
-                     object-start
-                     object-end))
-                   (defined 1)
-                   (bookkeeping-object
-                    (list
-                     'type type
-                     'name object-key
-                     'scope scope
-                     'start object-start
-                     'end object-end)))
-              (push
-               bookkeeping-object
-               bookkeeping-objects)
-
-              (dolist (id ids)
-                (when-let ((predefined (gethash id bookkeeping)))
-                  (setq
-                   defined
-                   (1+ predefined))))
-              (dolist (id ids)
-                (puthash
-                 id
-                 defined
-                 bookkeeping))
-              (puthash
-               object
-               defined
-               bookkeeping)))
-
-           ;; Infix expressions
-           ((or
-             (equal type 'boolean-or-expression)
-             (equal type 'boolean-and-expression)
-             (equal type 'logical-or-expression)
-             (equal type 'logical-and-expression)
-             (equal type 'logical-xor-expression)
-             (equal type 'bitwise-or-expression)
-             (equal type 'bitwise-and-expression)
-             (equal type 'bitwise-xor-expression)
-             (equal type 'concat-expression)
-             (equal type 'addition-expression)
-             (equal type 'subtraction-expression)
-             (equal type 'multiplication-expression)
-             (equal type 'exponentiation-expression)
-             (equal type 'division-expression)
-             (equal type 'modulo-expression)
-             (equal type 'bitwise-shift-left-expression)
-             (equal type 'bitwise-shift-right-expression))
-            (when-let ((bs (reverse (plist-get item 'b))))
-              (dolist (b bs)
-                (push `(,scope ,b) bookkeeping-stack)))
-            (when-let ((as (reverse (plist-get item 'a))))
-              (dolist (a as)
-                (push `(,scope ,a) bookkeeping-stack))))
-
-           ((equal type 'global-statement)
-            (when-let ((global-var-list (reverse (plist-get item 
'global-var-list))))
-              (dolist (global-var global-var-list)
-                (push
-                 (list
-                  scope
-                  (list
-                   'ast-type
-                   'assign-variable
-                   'key
-                   global-var))
-                 bookkeeping-stack))))
-
-           ((equal type 'assign-variables-from-array)
-            (when-let ((keys (reverse (plist-get item 'keys))))
-              (dolist (key keys)
-                (push
-                 (list
-                  scope
-                  (list
-                   'ast-type
-                   'assign-variable
-                   'key
-                   key))
-                 bookkeeping-stack))))
-
-           ((and
-             (equal type 'assign-variable)
-             (plist-get (plist-get item 'key) 'name))
-            (let* ((object-name (plist-get (plist-get item 'key) 'name))
-                   (object-start (plist-get (plist-get item 'key) 'start))
-                   (object-end (plist-get (plist-get item 'key) 'end))
-                   (ids
-                    (phps-mode-ast-bookkeeping--generate-variable-scope-string
-                     scope
-                     object-name))
-                   (object
-                    (list
-                     object-start
-                     object-end))
-                   (defined 1)
-                   (bookkeeping-object
-                    (list
-                     'type type
-                     'name object-name
-                     'scope scope
-                     'start object-start
-                     'end object-end)))
-              (push
-               bookkeeping-object
-               bookkeeping-objects)
-
-              (dolist (id ids)
-                (when-let ((predefined (gethash id bookkeeping)))
-                  (setq
-                   defined
-                   (1+ predefined))))
-              (dolist (id ids)
-                (puthash
-                 id
-                 defined
-                 bookkeeping))
-              (puthash
-               object
-               defined
-               bookkeeping)
-              (when-let ((exps (plist-get item 'value)))
-                (when (listp exps)
-                  (dolist (exp exps)
-                    (push `(,scope ,exp) bookkeeping-stack))))))
-
-           ((equal type 'property)
-            (let ((subject (plist-get item 'subject))
-                  (static-p)
-                  (sub-scope scope))
-              (when-let ((modifiers (plist-get item 'modifiers)))
-                (dolist (modifier modifiers)
-                  (when (equal modifier 'static)
-                    (setq
-                     static-p
-                     t))))
-              (when static-p
-                (push '(type static) sub-scope))
-              (if (stringp subject)
-                  (let ((ids))
-                    (setq
-                     ids
-                     (phps-mode-ast-bookkeeping--generate-variable-scope-string
-                      sub-scope
-                      subject))
-                    (let* ((object-name subject)
-                           (object-start (plist-get item 'start))
-                           (object-end (plist-get item 'end))
-                           (object
-                            (list
-                             object-start
-                             object-end))
-                           (defined 1)
-                           (bookkeeping-object
-                            (list
-                             'type type
-                             'name object-name
-                             'scope scope
-                             'start object-start
-                             'end object-end)))
-                      (push
-                       bookkeeping-object
-                       bookkeeping-objects)
-
-                      (dolist (id ids)
-                        (when-let ((predefined (gethash id bookkeeping)))
-                          (setq
-                           defined
-                           (1+ predefined))))
-                      (dolist (id ids)
-                        (puthash
-                         id
-                         defined
-                         bookkeeping))
-                      (puthash
-                       object
-                       defined
-                       bookkeeping)))
-                (push `(,sub-scope ,subject) bookkeeping-stack))))
-
-           ((equal type 'function-call)
-            (when-let ((arguments (plist-get item 'argument-list)))
-              (dolist (argument arguments)
-                (push `(,scope ,argument) bookkeeping-stack))))
-
-           ((equal type 'increment-variable)
-            (push `(,scope ,(plist-get item 'variable)) bookkeeping-stack))
-
-           ((equal type 'negated-expression)
-            (push `(,scope ,(plist-get item 'expression)) bookkeeping-stack))
-
-           ((equal type 'try)
-            (when-let ((children (reverse (plist-get item 
'inner-statement-list))))
-              (dolist (child children)
-                (push `(,scope ,child) bookkeeping-stack)))
-            (when-let ((children (reverse (plist-get item 'catch-list))))
-              (dolist (child children)
-                (push `(,scope ,child) bookkeeping-stack)))
-            (when-let ((children (reverse (plist-get item 
'finally-statement))))
-              (dolist (child children)
-                (push `(,scope ,child) bookkeeping-stack))))
-
-           ((equal type 'catch)
-            (when-let ((optional-variable
-                        (plist-get item 'optional-variable)))
-              (let* ((object-name optional-variable)
-                     (object-start (plist-get item 'optional-variable-start))
-                     (object-end (plist-get item 'optional-variable-end))
-                     (ids
-                      
(phps-mode-ast-bookkeeping--generate-variable-scope-string
-                       scope
-                       object-name))
-                     (bookkeeping-object
-                      (list
-                       'type type
-                       'name object-name
-                       'scope scope
-                       'start object-start
-                       'end object-end)))
-                (push
-                 bookkeeping-object
-                 bookkeeping-objects)
-                (dolist (id ids)
-                  (puthash
-                   id
-                   1
-                   bookkeeping))
-                (puthash
-                 (list
-                  object-start
-                  object-end)
-                 1
-                 bookkeeping)))
-            (when-let ((children (reverse (plist-get item 'children))))
-              (dolist (child children)
-                (push `(,scope ,child) bookkeeping-stack))))
-
-           ((equal type 'array-object-dereferencable)
-            (let* ((subject (plist-get item 'subject))
-                   (downcase-subject-name (downcase (plist-get subject 'name)))
-                   (property-name (plist-get item 'property-name)))
-
-              (when downcase-subject-name
-                (cond
-
-                 ((string= downcase-subject-name "$this")
-                  (puthash
-                   (list
-                    (plist-get subject 'start)
-                    (plist-get subject 'end))
-                   1
-                   bookkeeping)
-                  ;; When current scope is arrow function
-                  ;; we should go up in scope until we get out of
-                  ;; arrow functions scope
-                  (let ((sub-scope scope)
-                        (head-scope)
-                        (is-arrow-function-scope t))
-                    (while (and
-                            sub-scope
-                            is-arrow-function-scope)
-                      (setq
-                       head-scope
-                       (car sub-scope))
-                      (setq
-                       sub-scope
-                       (cdr sub-scope))
-                      (unless (equal
-                               (plist-get head-scope 'type)
-                               'arrow-function)
-                        (setq is-arrow-function-scope nil)))
-                    (let* ((object-name (concat "$" property-name))
-                           (object-start (plist-get item 'property-start))
-                           (object-end (plist-get item 'property-end))
-                           (predefined)
-                           (variable-ids
-                            
(phps-mode-ast-bookkeeping--generate-variable-scope-string
-                             sub-scope
-                             object-name
-                             t))
-                           (symbol-id
-                            
(phps-mode-ast-bookkeeping--generate-symbol-scope-string
-                             sub-scope
-                             property-name))
-                           (bookkeeping-object2
-                            (list
-                             object-start
-                             object-end))
-                           (bookkeeping-object
-                            (list
-                             'type type
-                             'name object-name
-                             'scope scope
-                             'start object-start
-                             'end object-end)))
-                      (push
-                       bookkeeping-object
-                       bookkeeping-objects)
-                      (when (gethash symbol-id bookkeeping)
-                        (setq
-                         predefined
-                         t))
-                      (dolist (variable-id variable-ids)
-                        (when (gethash variable-id bookkeeping)
-                          (setq
-                           predefined
-                           t)))
-                      (if predefined
-                          (puthash
-                           bookkeeping-object2
-                           1
-                           bookkeeping)
-                        (puthash
-                         bookkeeping-object2
-                         0
-                         bookkeeping)))))
-
-                 (t
-                  (let* ((object-name (plist-get subject 'name))
-                         (object-start (plist-get subject 'start))
-                         (object-end (plist-get subject 'end))
-                         (variable-ids
-                          
(phps-mode-ast-bookkeeping--generate-variable-scope-string
-                           scope
-                           object-name
-                           t))
-                         (predefined 0)
-                         (bookkeeping-object
-                          (list
-                           'type type
-                           'name object-name
-                           'scope scope
-                           'start object-start
-                           'end object-end)))
-                    (push
-                     bookkeeping-object
-                     bookkeeping-objects)
-                    (dolist (variable-id variable-ids)
-                      (when (gethash
-                             variable-id
-                             bookkeeping)
-                        (setq
-                         predefined
-                         1)))
-                    (puthash
-                     (list
-                      object-start
-                      object-end)
-                     predefined
-                     bookkeeping)))
-
-                 ))))
-
-           ((equal type 'variable)
-            (let* ((subject (plist-get item 'array-object-dereferencable))
-                   (downcase-subject-name (downcase (plist-get subject 'name)))
-                   (property-name (plist-get item 'property-name)))
-
-              (when downcase-subject-name
-                (cond
-
-                 ((string= downcase-subject-name "$this")
-                  (puthash
-                   (list
-                    (plist-get subject 'start)
-                    (plist-get subject 'end))
-                   1
-                   bookkeeping)
-                  ;; When current scope is arrow function
-                  ;; we should go up in scope until we get out of
-                  ;; arrow functions scope
-                  (let ((sub-scope scope)
-                        (head-scope)
-                        (is-arrow-function-scope t))
-                    (while (and
-                            sub-scope
-                            is-arrow-function-scope)
-                      (setq
-                       head-scope
-                       (car sub-scope))
-                      (setq
-                       sub-scope
-                       (cdr sub-scope))
-                      (unless (equal
-                               (plist-get head-scope 'type)
-                               'arrow-function)
-                        (setq is-arrow-function-scope nil)))
-                    (let* ((object-name (concat "$" property-name))
-                           (object-start (plist-get item 'property-start))
-                           (object-end (plist-get item 'property-end))
-                           (predefined)
-                           (variable-ids
-                            
(phps-mode-ast-bookkeeping--generate-variable-scope-string
-                             sub-scope
-                             object-name
-                             t))
-                           (symbol-id
-                            
(phps-mode-ast-bookkeeping--generate-symbol-scope-string
-                             sub-scope
-                             property-name))
-                           (bookkeeping-object2
-                            (list
-                             object-start
-                             object-end))
-                           (bookkeeping-object
-                            (list
-                             'type type
-                             'name object-name
-                             'scope scope
-                             'start object-start
-                             'end object-end)))
-                      (push
-                       bookkeeping-object
-                       bookkeeping-objects)
-                      (when (gethash symbol-id bookkeeping)
-                        (setq
-                         predefined
-                         t))
-                      (dolist (variable-id variable-ids)
-                        (when (gethash variable-id bookkeeping)
-                          (setq
-                           predefined
-                           t)))
-                      (if predefined
-                          (puthash
-                           bookkeeping-object2
-                           1
-                           bookkeeping)
-                        (puthash
-                         bookkeeping-object2
-                         0
-                         bookkeeping)))))
-
-                 (t
-                  (let* ((object-name (plist-get subject 'name))
-                         (object-start (plist-get subject 'start))
-                         (object-end (plist-get subject 'end))
-                         (variable-ids
-                          
(phps-mode-ast-bookkeeping--generate-variable-scope-string
-                           scope
-                           object-name
-                           t))
-                         (predefined 0)
-                         (bookkeeping-object
-                          (list
-                           'type type
-                           'name object-name
-                           'scope scope
-                           'start object-start
-                           'end object-end)))
-                    (push
-                     bookkeeping-object
-                     bookkeeping-objects)
-                    (dolist (variable-id variable-ids)
-                      (when (gethash
-                             variable-id
-                             bookkeeping)
-                        (setq
-                         predefined
-                         1)))
-                    (puthash
-                     (list
-                      object-start
-                      object-end)
-                     predefined
-                     bookkeeping)))
-
-                 ))))
-
-           ((equal type 'static-member)
-            (let* ((parent-class (plist-get item 'class))
-                   (downcased-parent-class (downcase parent-class))
-                   (member (plist-get item 'member))
-                   (member-type (plist-get member 'ast-type)))
-
-              (cond
-
-               ((or (string= downcased-parent-class "self")
-                    (string= downcased-parent-class "static"))
-
-                (cond
-
-                 ((equal member-type 'simple-variable)
-                  ;; When current scope is arrow function
-                  ;; we should go up in scope until we get out of
-                  ;; arrow functions scope
-                  (let ((sub-scope scope)
-                        (head-scope)
-                        (is-arrow-function-scope t))
-                    (while (and
-                            sub-scope
-                            is-arrow-function-scope)
-                      (setq
-                       head-scope
-                       (car sub-scope))
-                      (setq
-                       sub-scope
-                       (cdr sub-scope))
-                      (unless (equal
-                               (plist-get head-scope 'type)
-                               'arrow-function)
-                        (setq is-arrow-function-scope nil)))
-                    (push '(type static) sub-scope)
-                    (let* ((object-name (plist-get member 'name))
-                           (object-start (plist-get member 'start))
-                           (object-end (plist-get member 'end))
-                           (predefined)
-                           (variable-ids
-                            
(phps-mode-ast-bookkeeping--generate-variable-scope-string
-                             sub-scope
-                             object-name
-                             t))
-                           (bookkeeping-object2
-                            (list
-                             object-start
-                             object-end))
-                           (bookkeeping-object
-                            (list
-                             'type type
-                             'name object-name
-                             'scope scope
-                             'start object-start
-                             'end object-end)))
-                      (push
-                       bookkeeping-object
-                       bookkeeping-objects)
-                      (dolist (variable-id variable-ids)
-                        (when (gethash variable-id bookkeeping)
-                          (setq
-                           predefined
-                           t)))
-                      (if predefined
-                          (puthash
-                           bookkeeping-object2
-                           1
-                           bookkeeping)
-                        (puthash
-                         bookkeeping-object2
-                         0
-                         bookkeeping)))))
-
-                 )
-
-                ))))
-
-           ((equal type 'static-inline-function)
-            (push `(,scope ,(plist-get item 'inline-function)) 
bookkeeping-stack))
-
-           ((equal type 'echo-statement)
-            (let ((children (reverse (plist-get item 'children))))
-              (dolist (child children)
-                (when (listp child)
-                  (push `(,scope ,child) bookkeeping-stack)))))
-
-           ((equal type 'arrow-function)
-            (let ((sub-scope scope))
-              (setq arrow-function-count (1+ arrow-function-count))
-              (push `(type arrow-function name ,arrow-function-count) 
sub-scope)
-              (when-let ((expr (reverse (plist-get item 'expr))))
-                (dolist (e expr)
-                  (push `(,sub-scope ,e) bookkeeping-stack)))
-              (when-let ((parameter-list (plist-get item 'parameter-list)))
-                (dolist (parameter parameter-list)
-                  (let* ((object-name (plist-get parameter 'name))
-                         (object-start (plist-get parameter 'start))
-                         (object-end (plist-get parameter 'end))
-                         (ids
-                          
(phps-mode-ast-bookkeeping--generate-variable-scope-string
-                           sub-scope
-                           object-name))
-                         (object
-                          (list
-                           object-start
-                           object-end))
-                         (bookkeeping-object
-                          (list
-                           'type type
-                           'name object-name
-                           'scope scope
-                           'start object-start
-                           'end object-end)))
-                    (push
-                     bookkeeping-object
-                     bookkeeping-objects)
-                    (dolist (id ids)
-                      (puthash
-                       id
-                       1
-                       bookkeeping))
-                    (puthash
-                     object
-                     1
-                     bookkeeping))))))
-
-           ((equal type 'inline-function)
-            (let ((sub-scope scope))
-              (setq inline-function-count (1+ inline-function-count))
-              (push `(type inline-function name ,inline-function-count) 
sub-scope)
-              (when-let ((inner-statement-list (reverse (plist-get item 
'inner-statement-list))))
-                (dolist (inner-statement inner-statement-list)
-                  (push `(,sub-scope ,inner-statement) bookkeeping-stack)))
-              (when-let ((parameter-list (plist-get item 'parameter-list)))
-                (dolist (parameter parameter-list)
-                  (let ((ids
-                         
(phps-mode-ast-bookkeeping--generate-variable-scope-string
-                          sub-scope
-                          (plist-get parameter 'name)))
-                        (object
-                         (list
-                          (plist-get parameter 'start)
-                          (plist-get parameter 'end))))
-                    (dolist (id ids)
-                      (puthash
-                       id
-                       1
-                       bookkeeping))
-                    (puthash
-                     object
-                     1
-                     bookkeeping))))
-              (when-let ((lexical-vars (plist-get item 'lexical-vars)))
-                (dolist (lexical-var lexical-vars)
-                  (let* ((object-name (plist-get lexical-var 'name))
-                         (object-start (plist-get lexical-var 'start))
-                         (object-end (plist-get lexical-var 'end))
-                         (ids
-                          
(phps-mode-ast-bookkeeping--generate-variable-scope-string
-                           sub-scope
-                           object-name))
-                         (object
-                          (list
-                           object-start
-                           object-end))
-                         (bookkeeping-object
-                          (list
-                           'type type
-                           'name object-name
-                           'scope scope
-                           'start object-start
-                           'end object-end)))
-                    (push
-                     bookkeeping-object
-                     bookkeeping-objects)
-
-                    (dolist (id ids)
-                      (puthash
-                       id
-                       1
-                       bookkeeping))
-                    (puthash
-                     object
-                     1
-                     bookkeeping))))))
-
-           ))))
-    (setq
-     phps-mode-ast-bookkeeping--index
-     bookkeeping)
-    (setq
-     phps-mode-ast-bookkeeping--object-index
-     bookkeeping-objects)
-
-    ;; (message "\nBookkeeping\n:%S\n" bookkeeping)
-    phps-mode-ast-bookkeeping--index))
+  (setq phps-mode-ast-bookkeeping--index phps-mode-parser-sdt-bookkeeping)
+  phps-mode-ast-bookkeeping--index)
 
 
 (provide 'phps-mode-ast-bookkeeping)
diff --git a/phps-mode-parser-sdt.el b/phps-mode-parser-sdt.el
index 265bba60e9..c4c3f52583 100644
--- a/phps-mode-parser-sdt.el
+++ b/phps-mode-parser-sdt.el
@@ -591,6 +591,11 @@
   (make-hash-table :test 'equal)
   "Bookkeeping")
 
+(defvar-local
+  phps-mode-parser-sdt-bookkeeping-namespace
+  ""
+  "Current bookkeeping namespace.")
+
 ;; SDT starts here
 
 ;; 0 ((start) (top_statement_list))
@@ -3158,7 +3163,7 @@
  (lambda(args terminals)
    `(
      ast-type
-     expr-assign-variable
+     expr-assign-variable-by-expr
      variable
      ,(nth 0 args)
      expr
@@ -5052,7 +5057,46 @@
 ;; 515 ((simple_variable) (T_VARIABLE))
 (puthash
  515
- (lambda(args _terminals)
+ (lambda(args terminals)
+   (let ((namespaced-variable
+          (format
+           "%s id %s"
+           phps-mode-parser-sdt-bookkeeping-namespace
+           args)))
+
+     ;; Bookkeep whether we hit or miss the variable
+     (if (gethash
+          namespaced-variable
+          phps-mode-parser-sdt-bookkeeping)
+       (puthash
+        (list
+         (car (cdr terminals))
+         (cdr (cdr terminals)))
+        1
+        phps-mode-parser-sdt-bookkeeping)
+       (puthash
+        (list
+         (car (cdr terminals))
+         (cdr (cdr terminals)))
+        0
+        phps-mode-parser-sdt-bookkeeping))
+
+     ;; Declare variable
+     (unless (gethash
+              namespaced-variable
+              phps-mode-parser-sdt-bookkeeping)
+
+       ;; TODO Should not declare in this production
+       (puthash
+        namespaced-variable
+        1
+        phps-mode-parser-sdt-bookkeeping)
+       (message "Declared variable")
+       )
+     ;; Flag whether we hit or missed variable in the bookkeeping here
+     )
+   (message "args: %S" args)
+   (message "terminals: %S" terminals)
    `(
      ast-type
      simple-variable-variable


Reply via email to