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

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

[elpa] externals/phps-mode f2c386d: Fixed interface class imenu indexing


From: Christian Johansson
Subject: [elpa] externals/phps-mode f2c386d: Fixed interface class imenu indexing and bookkeeping of isset() !empty() conditional blocks
Date: Wed, 23 Sep 2020 11:43:58 -0400 (EDT)

branch: externals/phps-mode
commit f2c386d6d48e9101268ccd5858ad6842d7ed7058
Author: Christian Johansson <christian@cvj.se>
Commit: Christian Johansson <christian@cvj.se>

    Fixed interface class imenu indexing and bookkeeping of isset() !empty() 
conditional blocks
---
 phps-mode-lex-analyzer.el           | 974 +++++++++++++++++++++---------------
 phps-mode.el                        |   4 +-
 test/phps-mode-test-lex-analyzer.el |  95 +++-
 3 files changed, 668 insertions(+), 405 deletions(-)

diff --git a/phps-mode-lex-analyzer.el b/phps-mode-lex-analyzer.el
index 35ff67e..e0a1d64 100644
--- a/phps-mode-lex-analyzer.el
+++ b/phps-mode-lex-analyzer.el
@@ -608,145 +608,146 @@
     (setq buffer (current-buffer)))
   (phps-mode-debug-message
    (message "Run process changes on buffer '%s'" buffer))
-  (with-current-buffer buffer
-    (let ((run-full-lexer nil)
-          (old-tokens phps-mode-lex-analyzer--tokens)
-          (old-states phps-mode-lex-analyzer--states)
-          (log '()))
-
-      (if phps-mode-lex-analyzer--change-min
-          (progn
-            (phps-mode-debug-message
-             (message "Processing change point minimum: %s" 
phps-mode-lex-analyzer--change-min))
-            (let ((incremental-state nil)
-                  (incremental-state-stack nil)
-                  (incremental-heredoc-label nil)
-                  (incremental-heredoc-label-stack nil)
-                  (incremental-tokens nil)
-                  (head-states '())
-                  (head-tokens '())
-                  (change-start phps-mode-lex-analyzer--change-min)
-                  (incremental-start-new-buffer 
phps-mode-lex-analyzer--change-min))
-
-              ;; Reset idle timer
-              (phps-mode-lex-analyzer--cancel-idle-timer)
-
-              ;; Reset buffer changes minimum index
-              (phps-mode-lex-analyzer--reset-changes)
-
-              ;; Reset tokens and states here
-              (setq phps-mode-lex-analyzer--tokens nil)
-              (setq phps-mode-lex-analyzer--states nil)
-              (setq phps-mode-lex-analyzer--state nil)
-              (setq phps-mode-lex-analyzer--state-stack nil)
-              (setq phps-mode-lex-analyzer--heredoc-label nil)
-              (setq phps-mode-lex-analyzer--heredoc-label-stack nil)
-
-              ;; NOTE Starts are inclusive while ends are exclusive buffer 
locations
-
-              ;; Some tokens have dynamic length and if a change occurs at 
token-end
-              ;; we must start the incremental process at previous token start
-
-              ;; Build list of tokens from old buffer before start of changes 
(head-tokens)
-
-              (catch 'quit
-                (dolist (token old-tokens)
-                  (let ((start (car (cdr token)))
-                        (end (cdr (cdr token))))
-                    (if (< end change-start)
-                        (push token head-tokens)
-                      (when (< start change-start)
-                        (phps-mode-debug-message
-                         (message "New incremental-start-new-buffer: %s" 
start))
-                        (setq incremental-start-new-buffer start))
-                      (throw 'quit "break")))))
+  (when (get-buffer buffer)
+    (with-current-buffer buffer
+      (let ((run-full-lexer nil)
+            (old-tokens phps-mode-lex-analyzer--tokens)
+            (old-states phps-mode-lex-analyzer--states)
+            (log '()))
 
-              (setq head-tokens (nreverse head-tokens))
+        (if phps-mode-lex-analyzer--change-min
+            (progn
               (phps-mode-debug-message
-               (message "Head tokens: %s" head-tokens)
-               (message "Incremental-start-new-buffer: %s" 
incremental-start-new-buffer))
+               (message "Processing change point minimum: %s" 
phps-mode-lex-analyzer--change-min))
+              (let ((incremental-state nil)
+                    (incremental-state-stack nil)
+                    (incremental-heredoc-label nil)
+                    (incremental-heredoc-label-stack nil)
+                    (incremental-tokens nil)
+                    (head-states '())
+                    (head-tokens '())
+                    (change-start phps-mode-lex-analyzer--change-min)
+                    (incremental-start-new-buffer 
phps-mode-lex-analyzer--change-min))
+
+                ;; Reset idle timer
+                (phps-mode-lex-analyzer--cancel-idle-timer)
+
+                ;; Reset buffer changes minimum index
+                (phps-mode-lex-analyzer--reset-changes)
+
+                ;; Reset tokens and states here
+                (setq phps-mode-lex-analyzer--tokens nil)
+                (setq phps-mode-lex-analyzer--states nil)
+                (setq phps-mode-lex-analyzer--state nil)
+                (setq phps-mode-lex-analyzer--state-stack nil)
+                (setq phps-mode-lex-analyzer--heredoc-label nil)
+                (setq phps-mode-lex-analyzer--heredoc-label-stack nil)
+
+                ;; NOTE Starts are inclusive while ends are exclusive buffer 
locations
+
+                ;; Some tokens have dynamic length and if a change occurs at 
token-end
+                ;; we must start the incremental process at previous token 
start
+
+                ;; Build list of tokens from old buffer before start of 
changes (head-tokens)
+
+                (catch 'quit
+                  (dolist (token old-tokens)
+                    (let ((start (car (cdr token)))
+                          (end (cdr (cdr token))))
+                      (if (< end change-start)
+                          (push token head-tokens)
+                        (when (< start change-start)
+                          (phps-mode-debug-message
+                           (message "New incremental-start-new-buffer: %s" 
start))
+                          (setq incremental-start-new-buffer start))
+                        (throw 'quit "break")))))
 
-              ;; Did we find a start for the incremental process?
-              (if head-tokens
-                  (progn
-                    (phps-mode-debug-message
-                     (message "Found head tokens"))
+                (setq head-tokens (nreverse head-tokens))
+                (phps-mode-debug-message
+                 (message "Head tokens: %s" head-tokens)
+                 (message "Incremental-start-new-buffer: %s" 
incremental-start-new-buffer))
 
-                    ;; TODO Change on ST_END_HEREDOC should start before it
+                ;; Did we find a start for the incremental process?
+                (if head-tokens
+                    (progn
+                      (phps-mode-debug-message
+                       (message "Found head tokens"))
+
+                      ;; TODO Change on ST_END_HEREDOC should start before it
+
+                      ;; In old buffer:
+                      ;; 1. Determine state (incremental-state) and 
state-stack (incremental-state-stack) heredoc label (incremental-heredoc-label) 
heredoc-label-stack (heredoc-label-stack) before incremental start
+                      ;; 2. Build list of states before incremental start 
(head-states)
+                      (catch 'quit
+                        (dolist (state-object (nreverse old-states))
+                          (let ((end (nth 1 state-object)))
+                            (if (< end change-start)
+                                (progn
+                                  (setq incremental-state (nth 2 state-object))
+                                  (setq incremental-state-stack (nth 3 
state-object))
+                                  (setq incremental-heredoc-label (nth 4 
state-object))
+                                  (setq incremental-heredoc-label-stack (nth 5 
state-object))
+                                  (push state-object head-states))
+                              (throw 'quit "break")))))
 
-                    ;; In old buffer:
-                    ;; 1. Determine state (incremental-state) and state-stack 
(incremental-state-stack) heredoc label (incremental-heredoc-label) 
heredoc-label-stack (heredoc-label-stack) before incremental start
-                    ;; 2. Build list of states before incremental start 
(head-states)
-                    (catch 'quit
-                      (dolist (state-object (nreverse old-states))
-                        (let ((end (nth 1 state-object)))
-                          (if (< end change-start)
-                              (progn
-                                (setq incremental-state (nth 2 state-object))
-                                (setq incremental-state-stack (nth 3 
state-object))
-                                (setq incremental-heredoc-label (nth 4 
state-object))
-                                (setq incremental-heredoc-label-stack (nth 5 
state-object))
-                                (push state-object head-states))
-                            (throw 'quit "break")))))
+                      (phps-mode-debug-message
+                       (message "Head states: %s" head-states)
+                       (message "Incremental state: %s" incremental-state)
+                       (message "State stack: %s" incremental-state-stack)
+                       (message "Incremental heredoc-label: %s" 
incremental-heredoc-label)
+                       (message "Incremental heredoc-label-stack: %s" 
incremental-heredoc-label-stack))
 
-                    (phps-mode-debug-message
-                     (message "Head states: %s" head-states)
-                     (message "Incremental state: %s" incremental-state)
-                     (message "State stack: %s" incremental-state-stack)
-                     (message "Incremental heredoc-label: %s" 
incremental-heredoc-label)
-                     (message "Incremental heredoc-label-stack: %s" 
incremental-heredoc-label-stack))
-
-                    (if (and
-                         head-states
-                         incremental-state)
-                        (progn
-                          (phps-mode-debug-message
-                           (message "Found head states"))
+                      (if (and
+                           head-states
+                           incremental-state)
+                          (progn
+                            (phps-mode-debug-message
+                             (message "Found head states"))
 
-                          (push (list 'INCREMENTAL-LEX 
incremental-start-new-buffer) log)
+                            (push (list 'INCREMENTAL-LEX 
incremental-start-new-buffer) log)
 
-                          ;; Do partial lex from previous-token-end to 
change-stop
+                            ;; Do partial lex from previous-token-end to 
change-stop
 
-                          (phps-mode-lex-analyzer--incremental-lex-string
-                           (buffer-name)
-                           (buffer-substring-no-properties (point-min) 
(point-max))
-                           incremental-start-new-buffer
-                           (point-max)
-                           head-states
-                           incremental-state
-                           incremental-state-stack
-                           incremental-heredoc-label
-                           incremental-heredoc-label-stack
-                           head-tokens
-                           force-synchronous)
+                            (phps-mode-lex-analyzer--incremental-lex-string
+                             (buffer-name)
+                             (buffer-substring-no-properties (point-min) 
(point-max))
+                             incremental-start-new-buffer
+                             (point-max)
+                             head-states
+                             incremental-state
+                             incremental-state-stack
+                             incremental-heredoc-label
+                             incremental-heredoc-label-stack
+                             head-tokens
+                             force-synchronous)
 
-                          (phps-mode-debug-message
-                           (message "Incremental tokens: %s" 
incremental-tokens)))
+                            (phps-mode-debug-message
+                             (message "Incremental tokens: %s" 
incremental-tokens)))
 
-                      (push (list 'FOUND-NO-HEAD-STATES 
incremental-start-new-buffer) log)
-                      (phps-mode-debug-message
-                       (message "Found no head states"))
+                        (push (list 'FOUND-NO-HEAD-STATES 
incremental-start-new-buffer) log)
+                        (phps-mode-debug-message
+                         (message "Found no head states"))
 
-                      (setq run-full-lexer t)))
+                        (setq run-full-lexer t)))
 
-                (push (list 'FOUND-NO-HEAD-TOKENS 
incremental-start-new-buffer) log)
-                (phps-mode-debug-message
-                 (message "Found no head tokens"))
+                  (push (list 'FOUND-NO-HEAD-TOKENS 
incremental-start-new-buffer) log)
+                  (phps-mode-debug-message
+                   (message "Found no head tokens"))
 
-                (setq run-full-lexer t))))
-        (push (list 'FOUND-NO-CHANGE-POINT-MINIMUM) log)
-        (phps-mode-debug-message
-         (message "Found no change point minimum"))
+                  (setq run-full-lexer t))))
+          (push (list 'FOUND-NO-CHANGE-POINT-MINIMUM) log)
+          (phps-mode-debug-message
+           (message "Found no change point minimum"))
 
-        (setq run-full-lexer t))
+          (setq run-full-lexer t))
 
-      (when run-full-lexer
-        (push (list 'RUN-FULL-LEXER) log)
-        (phps-mode-debug-message
-         (message "Running full lexer"))
-        (phps-mode-lex-analyzer--re2c-run force-synchronous))
+        (when run-full-lexer
+          (push (list 'RUN-FULL-LEXER) log)
+          (phps-mode-debug-message
+           (message "Running full lexer"))
+          (phps-mode-lex-analyzer--re2c-run force-synchronous))
 
-      log)))
+        log))))
 
 (defun phps-mode-lex-analyzer--process-current-buffer (&optional force)
   "Process current buffer, generate indentations and Imenu, trigger 
incremental lexer if we have change.  FORCE processes without change."
@@ -1071,6 +1072,7 @@ SQUARE-BRACKET-LEVEL and ROUND-BRACKET-LEVEL."
               (imenu-in-class-declaration nil)
               (imenu-open-class-level nil)
               (imenu-in-class-name nil)
+              (imenu-in-interface-class nil)
               (imenu-in-function-declaration nil)
               (imenu-open-function-level nil)
               (imenu-in-function-name nil)
@@ -1082,9 +1084,19 @@ SQUARE-BRACKET-LEVEL and ROUND-BRACKET-LEVEL."
               (in-anonymous-function-number 0)
               (in-anonymous-function-nesting-level)
               (in-global-declaration nil)
+              (in-static-declaration nil)
               (in-arrow-fn nil)
               (in-arrow-fn-declaration nil)
               (in-arrow-fn-number 0)
+              (in-conditional-declaration nil)
+              (in-loop-conditional-declaration nil)
+              (in-defined-prop nil)
+              (in-defined-block-number nil)
+              (in-defined-block-count 0)
+              (in-defined-block-curly nil)
+              (in-defined-block-alternative nil)
+              (in-defined-block-inline nil)
+              (in-defined-awaiting-start nil)
               (bookkeeping (make-hash-table :test 'equal)))
 
           (push `(END_PARSE ,(length string) . ,(length string)) tokens)
@@ -1146,229 +1158,287 @@ SQUARE-BRACKET-LEVEL and ROUND-BRACKET-LEVEL."
               (when token
 
                 ;; BOOKKEEPING LOGIC
-                (when (or
-                       (equal token 'T_VARIABLE)
-                       (and
-                        ;; $this->...
-                        (equal token 'T_STRING)
-                        (equal previous-token 'T_OBJECT_OPERATOR)
-                        (equal previous2-token 'T_VARIABLE)
-                        (not (or
-                              (equal next-token "(")
-                              (equal next-token "[")))))
-
-                  (let ((bookkeeping-namespace namespace)
-                        (bookkeeping-alternative-namespace nil)
-                        (bookkeeping-index (list token-start token-end))
-                        (bookkeeping-variable-name (substring string (1- 
token-start) (1- token-end)))
-                        (bookkeeping-in-assignment nil)
-                        (bookkeeping-named nil)
-                        (bookkeeping-is-superglobal nil))
-
-                    ;; Flag super-globals
-                    (when (and (equal token 'T_VARIABLE)
-                               (or
-                                (equal bookkeeping-variable-name "$_COOKIE")
-                                (equal bookkeeping-variable-name "$_GET")
-                                (equal bookkeeping-variable-name "$_GLOBALS")
-                                (equal bookkeeping-variable-name "$_POST")
-                                (equal bookkeeping-variable-name "$_REQUEST")
-                                (equal bookkeeping-variable-name "$_SERVER")
-                                (equal bookkeeping-variable-name "$_SESSION")
-                                (equal bookkeeping-variable-name "$_FILES")))
-                      (setq bookkeeping-is-superglobal t))
-
-                    ;; Build name-space
-                    (when (and imenu-in-namespace-name
-                               (or imenu-in-class-name imenu-in-function-name))
-                      (setq bookkeeping-namespace (concat 
bookkeeping-namespace " namespace " imenu-in-namespace-name)))
-                    (when imenu-in-class-name
-                      (setq bookkeeping-namespace (concat 
bookkeeping-namespace " class " imenu-in-class-name)))
 
-                    (when (and
-                           (equal token 'T_VARIABLE)
-                           (string= (downcase bookkeeping-variable-name) 
"$this"))
-                      (setq bookkeeping-variable-name "$this"))
-
-                    ;; self::$abc ... here
-                    (when (and
-                           (equal token 'T_VARIABLE)
-                           (equal previous-token 'T_PAAMAYIM_NEKUDOTAYIM))
-                      (let ((bookkeeping2-variable-name
-                             (downcase (substring string (1- 
previous2-token-start) (1- previous2-token-end)))))
-                        (when (string= bookkeeping2-variable-name "self")
-                          ;; (message "Found self: %s::%s" 
bookkeeping2-variable-name bookkeeping-variable-name)
-                          (setq bookkeeping-namespace (concat 
bookkeeping-namespace " static id " bookkeeping-variable-name))
-                          (setq bookkeeping-named t))))
-
-                    ;; $this->... here
-                    (when (equal token 'T_STRING)
-                      (let ((bookkeeping2-variable-name
-                             (downcase (substring string (1- 
previous2-token-start) (1- previous2-token-end)))))
-                        ;; (message "%s->%s" bookkeeping2-variable-name 
bookkeeping-variable-name)
-                        (when (string= bookkeeping2-variable-name "$this")
-                          (setq bookkeeping-namespace (concat 
bookkeeping-namespace " id $" bookkeeping-variable-name))
-                          ;; (message "Was here: '%s" bookkeeping-namespace)
-                          (setq bookkeeping-named t))))
-
-                    (unless bookkeeping-named
-                      (when imenu-in-function-name
-                        (setq bookkeeping-namespace (concat 
bookkeeping-namespace " function " imenu-in-function-name))
-
-                        ;; Add $this special variable in class function scope
-                        (when imenu-in-class-name
-                          (let ((bookkeeping-method-this (concat 
bookkeeping-namespace " id $this")))
-                            (unless (gethash bookkeeping-method-this 
bookkeeping)
-                              (puthash bookkeeping-method-this 1 
bookkeeping)))))
-
-                      ;; Anonymous function level
-                      (when in-anonymous-function-nesting-level
-                        (setq bookkeeping-namespace (format "%s anonymous 
function %s" bookkeeping-namespace in-anonymous-function-number)))
-
-                      ;; In arrow function body
-                      (when in-arrow-fn
-                        (if in-arrow-fn-declaration
-                            (setq bookkeeping-namespace (format "%s arrow 
function %s" bookkeeping-namespace in-arrow-fn-number))
-                          (setq bookkeeping-alternative-namespace 
bookkeeping-namespace)
-                          (setq bookkeeping-namespace (format "%s arrow 
function %s" bookkeeping-namespace in-arrow-fn-number)))))
-
-                    (unless bookkeeping-named
-                      (when (equal previous-token 'T_STATIC)
-                        (setq bookkeeping-namespace (concat 
bookkeeping-namespace " static"))
+                (let ((downcased-previous2))
+                  (when (and
+                         (equal token 'T_STRING)
+                         (equal previous-token 'T_OBJECT_OPERATOR)
+                         (equal previous2-token 'T_VARIABLE))
+                    (setq downcased-previous2 (downcase (substring string (1- 
previous2-token-start) (1- previous2-token-end)))))
+                  (when (or
+                         (equal token 'T_VARIABLE)
+                         (and
+                          ;; $this->...
+                          (equal token 'T_STRING)
+                          (equal downcased-previous2 "$this")
+                          (not (or
+                                (equal next-token "(")
+                                (equal next-token "[")))))
+
+                    (let ((bookkeeping-namespace namespace)
+                          (bookkeeping-namespace-old)
+                          (bookkeeping-alternative-namespace nil)
+                          (bookkeeping-index (list token-start token-end))
+                          (bookkeeping-variable-name (substring string (1- 
token-start) (1- token-end)))
+                          (bookkeeping-in-assignment nil)
+                          (bookkeeping-named nil)
+                          (bookkeeping-is-superglobal nil))
+
+                      ;; Flag super-globals
+                      (when (and (equal token 'T_VARIABLE)
+                                 (or
+                                  (equal bookkeeping-variable-name "$_COOKIE")
+                                  (equal bookkeeping-variable-name "$_GET")
+                                  (equal bookkeeping-variable-name "$_GLOBALS")
+                                  (equal bookkeeping-variable-name "$_POST")
+                                  (equal bookkeeping-variable-name "$_REQUEST")
+                                  (equal bookkeeping-variable-name "$_SERVER")
+                                  (equal bookkeeping-variable-name "$_SESSION")
+                                  (equal bookkeeping-variable-name "$_FILES")))
+                        (setq bookkeeping-is-superglobal t))
+
+                      ;; Build name-space
+                      (when (and imenu-in-namespace-name
+                                 (or imenu-in-class-name 
imenu-in-function-name))
+                        (setq bookkeeping-namespace (concat 
bookkeeping-namespace " namespace " imenu-in-namespace-name)))
+                      (when imenu-in-class-name
+                        (setq bookkeeping-namespace (concat 
bookkeeping-namespace " class " imenu-in-class-name)))
+
+                      (when (and
+                             (equal token 'T_VARIABLE)
+                             (string= (downcase bookkeeping-variable-name) 
"$this"))
+                        (setq bookkeeping-variable-name "$this"))
+
+                      ;; self::$abc ... here
+                      (when (and
+                             (equal token 'T_VARIABLE)
+                             (equal previous-token 'T_PAAMAYIM_NEKUDOTAYIM))
+                        (let ((bookkeeping2-variable-name
+                               (downcase (substring string (1- 
previous2-token-start) (1- previous2-token-end)))))
+                          (when (string= bookkeeping2-variable-name "self")
+                            ;; (message "Found self: %s::%s" 
bookkeeping2-variable-name bookkeeping-variable-name)
+                            (setq bookkeeping-namespace (concat 
bookkeeping-namespace " static id " bookkeeping-variable-name))
+                            (setq bookkeeping-named t))))
+
+                      ;; $this->... here
+                      (when (equal token 'T_STRING)
+                        (let ((bookkeeping2-variable-name
+                               (downcase (substring string (1- 
previous2-token-start) (1- previous2-token-end)))))
+                          ;; (message "%s->%s" bookkeeping2-variable-name 
bookkeeping-variable-name)
+                          (when (string= bookkeeping2-variable-name "$this")
+                            (setq bookkeeping-namespace (concat 
bookkeeping-namespace " id $" bookkeeping-variable-name))
+                            ;; (message "Was here: '%s" bookkeeping-namespace)
+                            (setq bookkeeping-named t))))
+
+                      (unless bookkeeping-named
+                        (when imenu-in-function-name
+                          (setq bookkeeping-namespace (concat 
bookkeeping-namespace " function " imenu-in-function-name))
+
+                          ;; Add $this special variable in class function scope
+                          (when (and imenu-in-class-name
+                                     (not imenu-in-interface-class))
+                            (let ((bookkeeping-method-this (concat 
bookkeeping-namespace " id $this")))
+                              (unless (gethash bookkeeping-method-this 
bookkeeping)
+                                (puthash bookkeeping-method-this 1 
bookkeeping)))))
+
+                        ;; Anonymous function level
+                        (when in-anonymous-function-nesting-level
+                          (setq bookkeeping-namespace (format "%s anonymous 
function %s" bookkeeping-namespace in-anonymous-function-number)))
+
+                        ;; In arrow function body
+                        (when in-arrow-fn
+                          (if in-arrow-fn-declaration
+                              (setq bookkeeping-namespace (format "%s arrow 
function %s" bookkeeping-namespace in-arrow-fn-number))
+                            (setq bookkeeping-alternative-namespace 
bookkeeping-namespace)
+                            (setq bookkeeping-namespace (format "%s arrow 
function %s" bookkeeping-namespace in-arrow-fn-number))))
+
+                        ;; Add namespace for isset / empty scope here
+                        (when in-defined-block-number
+                          (setq bookkeeping-namespace-old 
bookkeeping-namespace)
+                          (setq bookkeeping-alternative-namespace 
bookkeeping-namespace-old)
+                          (setq bookkeeping-namespace (format "%s defined %s" 
bookkeeping-namespace (car in-defined-block-number)))))
+
+                      (unless bookkeeping-named
+                        (when (and
+                               imenu-in-class-name
+                               (equal previous-token 'T_STATIC)
+                               (not imenu-in-function-declaration))
+                          (setq bookkeeping-namespace (concat 
bookkeeping-namespace " static"))
+                          (when bookkeeping-alternative-namespace
+                            (setq bookkeeping-alternative-namespace (concat 
bookkeeping-alternative-namespace " static"))))
+
+                        (setq bookkeeping-namespace (concat 
bookkeeping-namespace " id " bookkeeping-variable-name))
                         (when bookkeeping-alternative-namespace
-                          (setq bookkeeping-alternative-namespace (concat 
bookkeeping-alternative-namespace " static"))))
+                          (setq bookkeeping-alternative-namespace (concat 
bookkeeping-alternative-namespace " id " bookkeeping-variable-name))))
 
-                      (setq bookkeeping-namespace (concat 
bookkeeping-namespace " id " bookkeeping-variable-name))
-                      (when bookkeeping-alternative-namespace
-                        (setq bookkeeping-alternative-namespace (concat 
bookkeeping-alternative-namespace " id " bookkeeping-variable-name))))
-
-                    (phps-mode-debug-message
-                     (message "Bookkeeping-namespace: '%s'" 
bookkeeping-namespace))
-
-                    ;; Support foreach as $key, for ($i = 0), if ($a = ), 
while ($a = ) and do-while ($a)assignments here
-                    (when (and
-                           (equal token 'T_VARIABLE)
-                           (string= previous-token "(")
-                           (string= next-token "=")
-                           (or (equal previous2-token 'T_IF)
-                               (equal previous2-token 'T_ELSEIF)
-                               (equal previous2-token 'T_WHILE)
-                               (equal previous2-token 'T_FOR)
-                               (equal previous2-token 'T_FOREACH)))
-                      (setq bookkeeping-in-assignment t))
-
-                    ;; Support stuff like foreach ($items as &$key)...
-                    (when (and
-                           (equal token 'T_VARIABLE)
-                           (equal previous2-token 'T_AS)
-                           (equal previous-token "&"))
-                      (setq bookkeeping-in-assignment t))
-
-                    ;; Support foreach ($items as $key => $value)...
-                    (when (and
-                           (equal token 'T_VARIABLE)
-                           (equal previous3-token 'T_AS)
-                           (equal previous2-token 'T_VARIABLE)
-                           (equal previous-token 'T_DOUBLE_ARROW)
-                           (string= next-token ")"))
-                      (setq bookkeeping-in-assignment t))
-
-                    ;; Support foreach ($items as $key => &$value)...
-                    (when (and
-                           (equal token 'T_VARIABLE)
-                           (equal previous3-token 'T_VARIABLE)
-                           (equal previous2-token 'T_DOUBLE_ARROW)
-                           (equal previous-token "&")
-                           (string= next-token ")"))
-                      (setq bookkeeping-in-assignment t))
-
-                    ;; Stand-alone variable assignment
-                    (when (and (equal token 'T_VARIABLE)
-                               first-token-on-line
-                               (string= next-token "="))
-                      (setq bookkeeping-in-assignment t))
-
-                    ;; Naming of value
-                    (when (and
-                           (equal token 'T_VARIABLE)
-                           (equal previous-token 'T_AS))
-                      (setq bookkeeping-in-assignment t))
-
-                    ;; In catch declaration
-                    (when (and
-                           (equal token 'T_VARIABLE)
-                           in-catch-declaration)
-                      (setq bookkeeping-in-assignment t))
-
-                    ;; In function arguments
-                    (when (and imenu-in-function-declaration
-                               (equal token 'T_VARIABLE))
-                      (setq bookkeeping-in-assignment t))
-
-                    ;; In anonymous function arguments
-                    (when (and in-anonymous-function-declaration
-                               (equal token 'T_VARIABLE))
-                      (setq bookkeeping-in-assignment t))
-
-                    ;; In arrow function variable declaration
-                    (when (and in-arrow-fn-declaration
-                               (equal token 'T_VARIABLE))
-                      (setq bookkeeping-in-assignment t))
-
-                    ;; In global variable declaration
-                    (when (and in-global-declaration
-                               (equal token 'T_VARIABLE)
-                               imenu-in-function-name)
-                      (setq bookkeeping-in-assignment t))
-
-                    ;; In [$abc, $def] = .. or array($abc, $def) = ...
-                    (when (and
-                           array-variable-declaration
-                           (equal token 'T_VARIABLE))
-                      (setq bookkeeping-in-assignment t))
+                      (phps-mode-debug-message (message 
"Bookkeeping-namespace: '%s'" bookkeeping-namespace))
 
-                    ;; Class variables
-                    (when (and
-                           imenu-in-class-name
-                           (not imenu-in-function-name)
-                           (or
-                            (equal previous-token 'T_STATIC)
-                            (equal previous-token 'T_PRIVATE)
-                            (equal previous-token 'T_PROTECTED)
-                            (equal previous-token 'T_PUBLIC)
-                            (equal previous-token 'T_VAR)))
-                      (setq bookkeeping-in-assignment t))
-
-                    ;; Do we have a assignment?
-                    (when bookkeeping-in-assignment
-                      (let ((declarations (gethash bookkeeping-namespace 
bookkeeping)))
-                        ;; Track number of times this variable is defined
-                        (unless declarations
-                          (setq declarations 0))
-                        (setq declarations (1+ declarations))
-                        (phps-mode-debug-message
-                         (message "Bookkeeping-assignment: '%s'" 
bookkeeping-namespace))
-                        (puthash bookkeeping-namespace declarations 
bookkeeping)))
+                      ;; Support for ($i = 0), if ($a = ), if (!$ = ), while 
($a = ) and do {} while ($a = ) assignments here
+                      (when (and
+                             (equal token 'T_VARIABLE)
+                             (or
+                              in-conditional-declaration
+                              in-loop-conditional-declaration)
+                             (equal next-token "="))
+                        (setq bookkeeping-in-assignment t))
+
+                      ;; Support stuff like foreach ($items as &$key)...
+                      (when (and
+                             (equal token 'T_VARIABLE)
+                             (equal previous2-token 'T_AS)
+                             (equal previous-token "&"))
+                        (setq bookkeeping-in-assignment t))
+
+                      ;; Support foreach ($items as $key => $value)...
+                      (when (and
+                             (equal token 'T_VARIABLE)
+                             (equal previous3-token 'T_AS)
+                             (equal previous2-token 'T_VARIABLE)
+                             (equal previous-token 'T_DOUBLE_ARROW)
+                             (string= next-token ")"))
+                        (setq bookkeeping-in-assignment t))
+
+                      ;; Support foreach ($items as $key => &$value)...
+                      (when (and
+                             (equal token 'T_VARIABLE)
+                             (equal previous3-token 'T_VARIABLE)
+                             (equal previous2-token 'T_DOUBLE_ARROW)
+                             (equal previous-token "&")
+                             (string= next-token ")"))
+                        (setq bookkeeping-in-assignment t))
+
+                      ;; Stand-alone variable assignment
+                      (when (and (equal token 'T_VARIABLE)
+                                 first-token-on-line
+                                 (string= next-token "="))
+                        (setq bookkeeping-in-assignment t))
+
+                      ;; Naming of value
+                      (when (and
+                             (equal token 'T_VARIABLE)
+                             (equal previous-token 'T_AS))
+                        (setq bookkeeping-in-assignment t))
+
+                      ;; In catch declaration
+                      (when (and
+                             (equal token 'T_VARIABLE)
+                             in-catch-declaration)
+                        (setq bookkeeping-in-assignment t))
+
+                      ;; In function arguments
+                      (when (and imenu-in-function-declaration
+                                 (equal token 'T_VARIABLE))
+                        (setq bookkeeping-in-assignment t))
+
+                      ;; In anonymous function arguments
+                      (when (and in-anonymous-function-declaration
+                                 (equal token 'T_VARIABLE))
+                        (setq bookkeeping-in-assignment t))
+
+                      ;; In arrow function variable declaration
+                      (when (and in-arrow-fn-declaration
+                                 (equal token 'T_VARIABLE))
+                        (setq bookkeeping-in-assignment t))
+
+                      ;; In global variable declaration
+                      (when (and in-global-declaration
+                                 (equal token 'T_VARIABLE)
+                                 imenu-in-function-name)
+                        (setq bookkeeping-in-assignment t))
+
+                      ;; In static variable declaration
+                      (when (and in-static-declaration
+                                 (equal token 'T_VARIABLE)
+                                 imenu-in-function-name)
+                        (setq bookkeeping-in-assignment t))
+
+                      ;; In [$abc, $def] = .. or array($abc, $def) = ...
+                      (when (and
+                             array-variable-declaration
+                             (equal token 'T_VARIABLE))
+                        (setq bookkeeping-in-assignment t))
+
+                      ;; In isset($abc, $def) or empty($test)
+                      (when (and
+                             (equal token 'T_VARIABLE)
+                             in-defined-prop)
+                        (setq bookkeeping-in-assignment t))
+
+                      ;; Class variables
+                      (when (and
+                             imenu-in-class-name
+                             (not imenu-in-function-name)
+                             (or
+                              (equal previous-token 'T_STATIC)
+                              (equal previous-token 'T_PRIVATE)
+                              (equal previous-token 'T_PROTECTED)
+                              (equal previous-token 'T_PUBLIC)
+                              (equal previous-token 'T_VAR)))
+                        (setq bookkeeping-in-assignment t))
+
+                      ;; Do we have a assignment?
+                      (when bookkeeping-in-assignment
+                        (let ((declarations (gethash bookkeeping-namespace 
bookkeeping)))
+                          ;; Track number of times this variable is defined
+                          (unless declarations
+                            (setq declarations 0))
+                          (setq declarations (1+ declarations))
+                          (phps-mode-debug-message
+                           (message "Bookkeeping-assignment: '%s'" 
bookkeeping-namespace))
+                          (puthash bookkeeping-namespace declarations 
bookkeeping)))
 
-                    (if bookkeeping-is-superglobal
-                        ;; Super-globals always hit
-                        (puthash bookkeeping-index 1 bookkeeping)
+                      (if bookkeeping-is-superglobal
+                          ;; Super-globals always hit
+                          (puthash bookkeeping-index 1 bookkeeping)
 
-                      ;; Check scoped variable
-                      (if (gethash bookkeeping-namespace bookkeeping)
-                          (progn
-                            (phps-mode-debug-message
-                             (message "Bookkeeping-hit: %s" bookkeeping-index))
-                            (puthash bookkeeping-index 1 bookkeeping))
-                        (if (and bookkeeping-alternative-namespace
-                                 (gethash bookkeeping-alternative-namespace 
bookkeeping))
+                        ;; Check scoped variable
+                        (if (gethash bookkeeping-namespace bookkeeping)
                             (progn
                               (phps-mode-debug-message
-                               (message "Bookkeeping-alternative-hit: %s" 
bookkeeping-index))
+                               (message "Bookkeeping-hit: %s" 
bookkeeping-index))
                               (puthash bookkeeping-index 1 bookkeeping))
-                          (phps-mode-debug-message
-                           (message "Bookkeeping-miss: %s" bookkeeping-index))
-                          (puthash bookkeeping-index 0 bookkeeping))))))
+
+                          (if (and bookkeeping-alternative-namespace
+                                   (gethash bookkeeping-alternative-namespace 
bookkeeping))
+                              (progn
+                                (phps-mode-debug-message
+                                 (message "Bookkeeping-alternative-hit: %s" 
bookkeeping-index))
+                                (puthash bookkeeping-index 1 bookkeeping))
+
+                            ;; If we are in a nested define block, search 
parent scopes for match
+                            (if (and in-defined-block-number
+                                     (> (length in-defined-block-number) 1))
+                                (let ((parent-scopes in-defined-block-number)
+                                      (parent-scope)
+                                      (parent-namespace)
+                                      (parent-search t))
+                                  (setq parent-scope (pop parent-scopes))
+                                  (setq parent-scope (pop parent-scopes))
+
+                                  ;; Search parent scopes
+                                  (while (and
+                                          parent-search
+                                          parent-scope)
+                                    (setq parent-namespace
+                                          (format "%s defined %s id %s"
+                                                  bookkeeping-namespace-old
+                                                  parent-scope
+                                                  bookkeeping-variable-name))
+                                    (phps-mode-debug-message (message 
"Parent-namespace: %s" parent-namespace))
+                                    (when (gethash parent-namespace 
bookkeeping)
+                                      (setq parent-search nil))
+                                    (setq parent-scope (pop parent-scopes)))
+
+                                  (if parent-search
+                                      (progn
+                                        (phps-mode-debug-message (message 
"Found no parent hit"))
+                                        (puthash bookkeeping-index 0 
bookkeeping))
+                                    (phps-mode-debug-message (message "Found 
parent hit"))
+                                    (puthash bookkeeping-index 1 bookkeeping)))
+
+                              (phps-mode-debug-message
+                               (message "Bookkeeping-miss: %s" 
bookkeeping-index))
+                              (puthash bookkeeping-index 0 bookkeeping))))))))
 
                 ;; Keep track of array variable declaration
                 (when first-token-on-line
@@ -1377,11 +1447,16 @@ SQUARE-BRACKET-LEVEL and ROUND-BRACKET-LEVEL."
                       (setq array-variable-declaration t)
                     (setq array-variable-declaration nil)))
 
-                ;; Keep track of global declaration for bookkeeping
                 (when first-token-on-line
+                  ;; Keep track of global declaration for bookkeeping
                   (if (equal token 'T_GLOBAL)
                       (setq in-global-declaration t)
-                    (setq in-global-declaration nil)))
+                    (setq in-global-declaration nil))
+
+                  ;; Keep track of static declaration for bookkeeping
+                  (if (equal token 'T_STATIC)
+                      (setq in-static-declaration t)
+                    (setq in-static-declaration nil)))
 
                 ;; Keep track of open catch blocks for bookkeeping
                 (when (equal token 'T_CATCH)
@@ -1421,6 +1496,109 @@ SQUARE-BRACKET-LEVEL and ROUND-BRACKET-LEVEL."
                   (setq in-arrow-fn nil)
                   (setq in-arrow-fn-declaration nil))
 
+                ;; Keep track of when we are in conditional declarations
+                (when (and
+                       (not in-loop-conditional-declaration)
+                       (or
+                        (equal token 'T_WHILE)
+                        (equal token 'T_FOR)))
+                  (setq in-loop-conditional-declaration (1+ 
round-bracket-level)))
+                (when (and
+                       (not in-conditional-declaration)
+                       (or
+                        (equal token 'T_IF)
+                        (equal token 'T_ELSEIF)))
+                  (setq in-conditional-declaration (1+ round-bracket-level)))
+
+                ;; Keep track of when we are inside a defined proposition 
isset or !empty
+
+                ;; Detect we are at the beginning of if (..isset()) or if 
(...!empty()...)
+                (when (and
+                       in-conditional-declaration
+                       (not in-defined-prop)
+                       (or
+                        (and
+                         (equal token 'T_ISSET)
+                         (not (equal previous-token "!")))
+                        (and
+                         (equal token 'T_EMPTY)
+                         (string= previous-token "!"))))
+                  (setq in-defined-prop (1+ round-bracket-level))
+                  (setq in-defined-block-count (1+ in-defined-block-count))
+                  (push in-defined-block-count in-defined-block-number)
+                  (setq in-defined-awaiting-start 1)
+                  (phps-mode-debug-message
+                   (message "Awaiting start for defined block %s after %s" 
in-defined-block-count token-start)))
+
+                ;; Detect isset / !empty scope end
+                (when in-defined-block-number
+                  (cond
+
+                   ;; End of curly bracket block
+                   ((and
+                     (equal curly-bracket-level (car in-defined-block-curly))
+                     (equal token "}"))
+                    (pop in-defined-block-curly)
+                    (pop in-defined-block-number)
+                    (phps-mode-debug-message
+                     (message "Ended defined curly block at %s with level %s" 
token-start curly-bracket-level)))
+
+                   ;; End of inline block
+                   ((and
+                     in-defined-block-inline
+                     (equal token ";"))
+                    (setq in-defined-block-inline nil)
+                    (pop in-defined-block-number)
+                    (phps-mode-debug-message
+                     (message "Ended defined inline block at %s" token-start)))
+
+                   ;; End of alternative block
+                   ((and
+                     (equal alternative-control-structure-level (car 
in-defined-block-alternative))
+                     (or
+                      (equal token 'T_ELSE)
+                      (equal token 'T_ELSEIF)
+                      (equal token 'T_ENDIF)))
+                    (pop in-defined-block-alternative)
+                    (pop in-defined-block-number)
+                    (phps-mode-debug-message
+                     (message "Ended defined alternative block at %s with 
level %s" token-start alternative-control-structure-level)))))
+
+                ;; Detect isset / !empty scope start
+                (when (and in-defined-awaiting-start
+                           (= in-defined-awaiting-start 2))
+                  (cond
+                   ((equal token "{")
+                    (push (1+ curly-bracket-level) in-defined-block-curly)
+                    (phps-mode-debug-message
+                     (message "Started defined curly block at %s with level 
%s" token-start (car in-defined-block-curly))))
+                   ((equal token ":")
+                    (push (1+ alternative-control-structure-level) 
in-defined-block-alternative)
+                    (phps-mode-debug-message
+                     (message "Started defined alternative block at %s with 
level %s" token-start (car in-defined-block-alternative))))
+                   (t
+                    (setq in-defined-block-inline t)
+                    (phps-mode-debug-message
+                     (message "Started defined inline block at %s" 
token-start))))
+                  (setq in-defined-awaiting-start nil))
+
+                ;; Detect when IF / ELSEIF / FOR / WHILE condition end
+                (when (and
+                       in-conditional-declaration
+                       (equal token ")")
+                       (equal in-conditional-declaration round-bracket-level))
+                  (when (and
+                         in-defined-awaiting-start
+                         (equal in-defined-awaiting-start 1))
+                    (setq in-defined-prop nil)
+                    (setq in-defined-awaiting-start 2))
+                  (setq in-conditional-declaration nil))
+                (when (and
+                       in-loop-conditional-declaration
+                       (equal token ")")
+                       (equal in-loop-conditional-declaration 
round-bracket-level))
+                  (setq in-loop-conditional-declaration nil))
+
                 ;; IMENU LOGIC
 
                 (cond
@@ -1503,7 +1681,10 @@ SQUARE-BRACKET-LEVEL and ROUND-BRACKET-LEVEL."
                         (if imenu-in-namespace-name
                             (push `(,imenu-in-function-name . 
,imenu-in-function-index) imenu-namespace-index)
                           (push `(,imenu-in-function-name . 
,imenu-in-function-index) imenu-index))))
-                    (setq imenu-open-function-level imenu-nesting-level)
+
+                    (if (string= token "{")
+                        (setq imenu-open-function-level imenu-nesting-level)
+                      (setq imenu-in-function-name nil))
                     (setq imenu-in-function-declaration nil))
 
                    ((and (equal token 'T_STRING)
@@ -1519,9 +1700,15 @@ SQUARE-BRACKET-LEVEL and ROUND-BRACKET-LEVEL."
                       (setq imenu-in-namespace-declaration t))
 
                      ((and (not imenu-in-class-name)
-                           (or (equal token 'T_CLASS)
-                               (equal token 'T_INTERFACE)))
+                           (equal token 'T_CLASS))
+                      (setq imenu-in-class-name nil)
+                      (setq imenu-in-interface-class nil)
+                      (setq imenu-in-class-declaration t))
+
+                     ((and (not imenu-in-class-name)
+                           (equal token 'T_INTERFACE))
                       (setq imenu-in-class-name nil)
+                      (setq imenu-in-interface-class t)
                       (setq imenu-in-class-declaration t))
 
                      ((and (not imenu-in-function-name)
@@ -2815,58 +3002,59 @@ SQUARE-BRACKET-LEVEL and ROUND-BRACKET-LEVEL."
   (let ((buffer (generate-new-buffer "*PHPs Lexer*")))
 
     ;; Create temporary buffer and run lexer in it
-    (with-current-buffer buffer
-      (insert contents)
-
-      (if tokens
-          (setq phps-mode-lexer--tokens (nreverse tokens))
-        (setq phps-mode-lexer--tokens nil))
-      (if state
-          (setq phps-mode-lexer--state state)
-        (setq phps-mode-lexer--state 'ST_INITIAL))
-      (if states
-          (setq phps-mode-lexer--states states)
-        (setq phps-mode-lexer--states nil))
-      (if state-stack
-          (setq phps-mode-lexer--state-stack state-stack)
-        (setq phps-mode-lexer--state-stack nil))
-      (if heredoc-label
-          (setq phps-mode-lexer--heredoc-label heredoc-label)
-        (setq phps-mode-lexer--heredoc-label nil))
-      (if heredoc-label-stack
-          (setq phps-mode-lexer--heredoc-label-stack heredoc-label-stack)
-        (setq phps-mode-lexer--heredoc-label-stack nil))
-
-      ;; Setup lexer settings
-      (when (boundp 'phps-mode-syntax-table)
-        (setq semantic-lex-syntax-table phps-mode-syntax-table))
-      (setq semantic-lex-analyzer #'phps-mode-lex-analyzer--re2c-lex)
-
-      ;; Catch errors to kill generated buffer
-      (let ((got-error t))
-        (unwind-protect
-            ;; Run lexer or incremental lexer
-            (progn
-              (if (and start end)
-                  (let ((incremental-tokens (semantic-lex start end)))
-                    (setq
-                     phps-mode-lex-analyzer--tokens
-                     (append tokens incremental-tokens)))
-                (setq
-                 phps-mode-lex-analyzer--tokens
-                 (semantic-lex-buffer)))
-              (setq got-error nil))
-          (when got-error
-            (kill-buffer))))
-
-      ;; Copy variables outside of buffer
-      (setq state phps-mode-lexer--state)
-      (setq state-stack phps-mode-lexer--state-stack)
-      (setq states phps-mode-lexer--states)
-      (setq tokens (nreverse phps-mode-lexer--tokens))
-      (setq heredoc-label phps-mode-lexer--heredoc-label)
-      (setq heredoc-label-stack phps-mode-lexer--heredoc-label-stack)
-      (kill-buffer)))
+    (when (get-buffer buffer)
+      (with-current-buffer buffer
+        (insert contents)
+
+        (if tokens
+            (setq phps-mode-lexer--tokens (nreverse tokens))
+          (setq phps-mode-lexer--tokens nil))
+        (if state
+            (setq phps-mode-lexer--state state)
+          (setq phps-mode-lexer--state 'ST_INITIAL))
+        (if states
+            (setq phps-mode-lexer--states states)
+          (setq phps-mode-lexer--states nil))
+        (if state-stack
+            (setq phps-mode-lexer--state-stack state-stack)
+          (setq phps-mode-lexer--state-stack nil))
+        (if heredoc-label
+            (setq phps-mode-lexer--heredoc-label heredoc-label)
+          (setq phps-mode-lexer--heredoc-label nil))
+        (if heredoc-label-stack
+            (setq phps-mode-lexer--heredoc-label-stack heredoc-label-stack)
+          (setq phps-mode-lexer--heredoc-label-stack nil))
+
+        ;; Setup lexer settings
+        (when (boundp 'phps-mode-syntax-table)
+          (setq semantic-lex-syntax-table phps-mode-syntax-table))
+        (setq semantic-lex-analyzer #'phps-mode-lex-analyzer--re2c-lex)
+
+        ;; Catch errors to kill generated buffer
+        (let ((got-error t))
+          (unwind-protect
+              ;; Run lexer or incremental lexer
+              (progn
+                (if (and start end)
+                    (let ((incremental-tokens (semantic-lex start end)))
+                      (setq
+                       phps-mode-lex-analyzer--tokens
+                       (append tokens incremental-tokens)))
+                  (setq
+                   phps-mode-lex-analyzer--tokens
+                   (semantic-lex-buffer)))
+                (setq got-error nil))
+            (when got-error
+              (kill-buffer))))
+
+        ;; Copy variables outside of buffer
+        (setq state phps-mode-lexer--state)
+        (setq state-stack phps-mode-lexer--state-stack)
+        (setq states phps-mode-lexer--states)
+        (setq tokens (nreverse phps-mode-lexer--tokens))
+        (setq heredoc-label phps-mode-lexer--heredoc-label)
+        (setq heredoc-label-stack phps-mode-lexer--heredoc-label-stack)
+        (kill-buffer))))
   (list tokens states state state-stack heredoc-label heredoc-label-stack))
 
 (provide 'phps-mode-lex-analyzer)
diff --git a/phps-mode.el b/phps-mode.el
index 665a3d3..52e1944 100644
--- a/phps-mode.el
+++ b/phps-mode.el
@@ -5,8 +5,8 @@
 ;; Author: Christian Johansson <christian@cvj.se>
 ;; Maintainer: Christian Johansson <christian@cvj.se>
 ;; Created: 3 Mar 2018
-;; Modified: 16 Sep 2020
-;; Version: 0.3.58
+;; Modified: 23 Sep 2020
+;; Version: 0.3.62
 ;; Keywords: tools, convenience
 ;; URL: https://github.com/cjohansson/emacs-phps-mode
 
diff --git a/test/phps-mode-test-lex-analyzer.el 
b/test/phps-mode-test-lex-analyzer.el
index 3d26c91..9d27428 100644
--- a/test/phps-mode-test-lex-analyzer.el
+++ b/test/phps-mode-test-lex-analyzer.el
@@ -1216,6 +1216,11 @@
    "Imenu empty namespace without brackets"
    (should (equal (phps-mode-lex-analyzer--get-imenu) nil)))
 
+  (phps-mode-test--with-buffer
+   "<?php\ninterface myInterface\n{\n    function myFunction1();\n    function 
myFunction2($x); // NOTE Imenu not working either\n}\n"
+   "Imenu in interface class with arguments in one method"
+   (should (equal (phps-mode-lex-analyzer--get-imenu) '(("myInterface" 
("myFunction1" . 44) ("myFunction2" . 72))))))
+
   )
 
 (defun phps-mode-test-lex-analyzer--get-moved-imenu ()
@@ -1382,7 +1387,7 @@
 
   (phps-mode-test--with-buffer
    "<?php\n\n// Super-globals\n\nif ($_GET) {\n    echo 'Hit';\n}\nif ($_POST) 
{\n    echo 'Hit';\n}\nif ($_COOKIE) {\n    echo 'Hit';\n}\nif ($_SESSION) {\n  
  echo 'Hit';\n}\nif ($_REQUEST) {\n    echo 'Hit';\n}\nif ($_GLOBALS) {\n    
echo 'Hit';\n}\nif ($_SERVER) {\n    echo 'Hit';\n}\nif ($_FILES) {\n    echo 
'Hit';\n}\n"
-   "Super-globals"
+   "Bookkeeping of super-globals"
    (should (equal
             (phps-mode-test--hash-to-list 
(phps-mode-lex-analyzer--get-bookkeeping) t)
             (list (list (list 30 35) 1) (list (list 61 67) 1) (list (list 93 
101) 1) (list (list 127 136) 1) (list (list 162 171) 1) (list (list 197 206) 1) 
(list (list 232 240) 1) (list (list 266 273) 1)))))
@@ -1396,29 +1401,29 @@
 
   (phps-mode-test--with-buffer
    "<?php\n\n// Conditional assignments\n\n$items = array(1, 2, 3);\nforeach 
($items as $item) {\n    if ($item) {\n        echo 'Hit';\n    }\n}\nforeach 
($items as $key => $value) {\n    if ($key || $value) {\n        echo 'Hit';\n  
  }\n}\nfor ($i = 0; $i < count($items); $i++) {\n    if ($i) {\n        echo 
'Hit';\n    }\n}\nif ($a = 123) {\n    if ($a) {\n        echo 'Hit';\n    
}\n}\nwhile ($b = 123) {\n    if ($a) {\n        echo 'Hit';\n    }\n}\ndo {\n  
  echo 'Hit';\n} while ( [...]
-   "Conditional assignments"
+   "Bookkeeping of conditional assignments"
    (should (equal
             (phps-mode-test--hash-to-list 
(phps-mode-lex-analyzer--get-bookkeeping) t)
             (list (list " id $items" 1) (list (list 36 42) 1) (list (list 70 
76) 1) (list " id $item" 1) (list (list 80 85) 1) (list (list 97 102) 1) (list 
(list 143 149) 1) (list " id $key" 1) (list (list 153 157) 1) (list " id 
$value" 1) (list (list 161 167) 1) (list (list 179 183) 1) (list (list 187 193) 
1) (list " id $i" 1) (list (list 230 232) 1) (list (list 238 240) 1) (list 
(list 249 255) 1) (list (list 258 260) 1) (list (list 274 276) 1) (list " id 
$a" 1) (list (list 312 314) 1)  [...]
 
   (phps-mode-test--with-buffer
    "<?php\n\n// Class properties\n\nclass myParent {}\n\nclass myClass extends 
myParent {\n    private $var1 = 123;\n    protected static $var2;\n    public 
$var3;\n    var $var4;\n    function __construct() {\n        if ($this) {\n    
        echo 'Hit';\n        }\n        if ($this->var1) {\n            echo 
'Hit';\n        }\n        if (self::$var1) {\n            echo 'Miss';\n       
 }\n        if (self::$var2) {\n            echo 'Hit';\n        }\n        if 
($this->var3) {\n   [...]
-   "Class properties"
+   "Bookkeeping of class properties"
    ;; (message "Bookkeeping: %s" (phps-mode-test--hash-to-list 
(phps-mode-lex-analyzer--get-bookkeeping) t))
    (should (equal
             (phps-mode-test--hash-to-list 
(phps-mode-lex-analyzer--get-bookkeeping) t)
             (list (list " class myParent id $var1" 1) (list (list 93 98) 1) 
(list " class myParent static id $var2" 1) (list (list 127 132) 1) (list " 
class myParent id $var3" 1) (list (list 145 150) 1) (list " class myParent id 
$var4" 1) (list (list 160 165) 1) (list " class myParent function __construct 
id $this" 1) (list (list 208 213) 1) (list (list 263 268) 1) (list (list 270 
274) 1) (list (list 330 335) 0) (list (list 392 397) 1) (list (list 447 452) 1) 
(list (list 454 458) 1) (lis [...]
 
   (phps-mode-test--with-buffer
-   "<?php\n\ntry {\n    \n} catch (\Exception $e) {\n    if ($e) {\n        
echo 'Hit';\n    }\n}\n\nif ($e) {\n    echo 'Miss';\n}\n"
-   "Try catch variable assignment"
+   "<?php\n\ntry {\n    \n} catch (\\Exception $e) {\n    if ($e) {\n        
echo 'Hit';\n    }\n}\n\nif ($e) {\n    echo 'Miss';\n}\n"
+   "Bookkeeping of try catch variable assignment"
    (should (equal
             (phps-mode-test--hash-to-list 
(phps-mode-lex-analyzer--get-bookkeeping) t)
-            (list (list " id $e" 1) (list (list 38 40) 1) (list (list 52 54) 
1) (list (list 91 93) 1)))))
+            (list (list " id $e" 1) (list (list 39 41) 1) (list (list 53 55) 
1) (list (list 92 94) 1)))))
 
   (phps-mode-test--with-buffer
    "<?php\n\n$example = function ($test) {\n    if ($test) {\n        echo 
'Hit';\n    }\n    if ($example) {\n        echo 'Miss';\n    }\n};\n$example2 
= function ($test2) use ($example) {\n    if ($test2) {\n        echo 'Hit';\n  
  }\n    if ($example) {\n        echo 'Hit';\n    }\n    if ($example2) {\n    
    echo 'Miss';\n    }\n    if ($example3) {\n        echo 'Miss';\n    
}\n};\nif ($test) {\n    echo 'Miss';\n}\nif ($test2) {\n    echo 'Miss';\n}"
-   "Anonymous function variable assignments"
+   "Bookkeeping of anonymous function variable assignments"
    ;; (message "Bookkeeping: %s" (phps-mode-test--hash-to-list 
(phps-mode-lex-analyzer--get-bookkeeping) t))
    (should (equal
             (phps-mode-test--hash-to-list 
(phps-mode-lex-analyzer--get-bookkeeping) t)
@@ -1434,21 +1439,21 @@
 
   (phps-mode-test--with-buffer
    "<?php\n$items = array(1, 2, 3);\nforeach ($items as &$item) {\n    if 
($item) {\n        echo 'Hit';\n    }\n}\nforeach ($items as $key => &$item2) 
{\n    if ($item) {\n        echo 'Hit';\n    }\n}"
-   "Foreach reference variable declaration"
+   "Bookkeeping of foreach reference variable declaration"
    (should (equal
             (phps-mode-test--hash-to-list 
(phps-mode-lex-analyzer--get-bookkeeping) t)
             (list (list " id $items" 1) (list (list 7 13) 1) (list (list 41 
47) 1) (list " id $item" 1) (list (list 52 57) 1) (list (list 69 74) 1) (list 
(list 115 121) 1) (list " id $key" 1) (list (list 125 129) 1) (list " id 
$item2" 1) (list (list 134 140) 1) (list (list 152 157) 1)))))
 
   (phps-mode-test--with-buffer
    "<?php\n\n[$random, $bandom] = myValues();\nif ($random) {\n    echo 
'Hit';\n}\nif ($bandom) {\n    echo 'Hit';\n}\n\narray($random2, $bandom2] = 
myValues2();\nif ($random2) {\n    echo 'Hit';\n}\nif ($bandom3) {\n    echo 
'Hit';\n}\n\n    "
-   "Variable declarations in array"
+   "Bookkeeping of variable declarations in array"
    (should (equal
             (phps-mode-test--hash-to-list 
(phps-mode-lex-analyzer--get-bookkeeping) t)
             (list (list " id $random" 1) (list (list 9 16) 1) (list " id 
$bandom" 1) (list (list 18 25) 1) (list (list 45 52) 1) (list (list 78 85) 1) 
(list " id $random2" 1) (list (list 114 122) 1) (list " id $bandom2" 1) (list 
(list 124 132) 1) (list (list 153 161) 1) (list (list 187 195) 0)))))
 
   (phps-mode-test--with-buffer
    "<?php\n\n$var = 123;\n\nfunction test($abc) {\n    global $var;\n    if 
($var) {\n        echo 'Hit';\n    }\n}"
-   "Global variable declaration in function"
+   "Bookkeeping of global variable declaration in function"
    (should (equal
             (phps-mode-test--hash-to-list 
(phps-mode-lex-analyzer--get-bookkeeping) t)
             (list (list " id $var" 1) (list (list 8 12) 1) (list " function 
test id $abc" 1) (list (list 35 39) 1) (list " function test id $var" 1) (list 
(list 54 58) 1) (list (list 68 72) 1)))))
@@ -1460,6 +1465,76 @@
             (phps-mode-test--hash-to-list 
(phps-mode-lex-analyzer--get-bookkeeping) t)
             (list (list " id $y" 1) (list (list 7 9) 1) (list " id $fn1" 1) 
(list (list 15 19) 1) (list " arrow function 1 id $x" 1) (list (list 25 27) 1) 
(list (list 32 34) 1) (list (list 37 39) 1) (list " id $z" 1) (list (list 41 
43) 1) (list " id $fn" 1) (list (list 49 52) 1) (list " arrow function 2 id 
$x2" 1) (list (list 58 61) 1) (list " arrow function 2 id $y2" 1) (list (list 
69 72) 1) (list (list 77 80) 1) (list (list 83 86) 1) (list (list 89 91) 1) 
(list " arrow function 3 id $x [...]
 
+  (phps-mode-test--with-buffer
+   "<?php\n$z = (object) array('name' => 'random');\nif ($z->name) {\n    echo 
'Hit';\n}"
+   "Bookkeeping object properties."
+   (should (equal
+            (phps-mode-test--hash-to-list 
(phps-mode-lex-analyzer--get-bookkeeping) t)
+            (list (list " id $z" 1) (list (list 7 9) 1) (list (list 52 54) 
1)))))
+
+  (phps-mode-test--with-buffer
+   "<?php\nif (!$var = false) {\n    echo 'Hit';\n}\n"
+   "Bookkeeping negative conditional assignment"
+   (should (equal
+            (phps-mode-test--hash-to-list 
(phps-mode-lex-analyzer--get-bookkeeping) t)
+            (list (list " id $var" 1) (list (list 12 16) 1)))))
+
+  (phps-mode-test--with-buffer
+   "<?php\n\nif (isset($x)) {\n    if ($x) {\n        echo 'Hit';\n        if 
(isset($i, $u)) {\n            if ($i) {\n                echo 'Hit';\n         
   }\n            if ($u) {\n                echo 'Hit';\n            }\n       
     if ($x) {\n                echo 'Hit';\n            }\n        }\n        
if ($i) {\n            echo 'Miss';\n        }\n        if ($u) {\n            
echo 'Miss';\n        }\n    }\n}\nif ($x) {\n    echo 'Miss';\n}\n\nif 
(!empty($y)) {\n    if ( [...]
+   "Bookkeeping of isset() and !empty() scoped variables."
+   (should (equal
+            (phps-mode-test--hash-to-list 
(phps-mode-lex-analyzer--get-bookkeeping) t)
+            (list (list " defined 1 id $x" 1) (list (list 18 20) 1) (list 
(list 33 35) 1) (list " defined 2 id $i" 1) (list (list 77 79) 1) (list " 
defined 2 id $u" 1) (list (list 81 83) 1) (list (list 104 106) 1) (list (list 
168 170) 1) (list (list 232 234) 1) (list (list 302 304) 0) (list (list 355 
357) 0) (list (list 408 410) 0) (list " defined 3 id $y" 1) (list (list 445 
447) 1) (list (list 460 462) 1) (list " defined 4 id $k" 1) (list (list 505 
507) 1) (list " defined 4 id $L" 1) (l [...]
+
+  (phps-mode-test--with-buffer
+   "<?php\ninterface myInterface\n{\n    function myFunction1();\n    function 
myFunction2($x);\n}\n"
+   "Bookkeeping variable in interface function"
+   (should (equal
+            (phps-mode-test--hash-to-list 
(phps-mode-lex-analyzer--get-bookkeeping) t)
+            (list (list " class myInterface function myFunction2 id $x" 1) 
(list (list 84 86) 1)))))
+
+  (phps-mode-test--with-buffer
+   "<?php\n\nfunction myFunction1()\n{\n    return isset($a);\n}\n\nfunction 
myFunction2()\n{\n    $b = 2;\n    if ($b) {\n        echo 'Hit';\n    }\n    
if ($b) {\n        echo 'Hit';\n    }\n}\n"
+   "Bookkeeping after definition condition"
+   (should (equal
+            (phps-mode-test--hash-to-list 
(phps-mode-lex-analyzer--get-bookkeeping) t)
+            '(((50 52) 0) (" function myFunction2 id $b" 1) ((87 89) 1) ((103 
105) 1) ((143 145) 1)))))
+
+  (phps-mode-test--with-buffer
+   "<?php\n\n$a = array(1, 2, 3);\nforeach ($a as $uri => $page)\n{\n    if 
(isset($pages)) {\n        if ($a) {\n            echo 'Hit';\n        }\n      
  if ($uri) {\n            echo 'Hit';\n        }\n        if ($page) {\n       
     echo 'Hit';\n        }\n    }\n}\n"
+   "Bookkeeping of foreach variable inside if (isset()) block"
+   (should (equal
+            (phps-mode-test--hash-to-list 
(phps-mode-lex-analyzer--get-bookkeeping) t)
+            '((" id $a" 1) ((8 10) 1) ((38 40) 1) (" id $uri" 1) ((44 48) 1) 
(" id $page" 1) ((52 57) 1) (" defined 1 id $pages" 1) ((75 81) 1) ((98 100) 1) 
((150 154) 1) ((204 209) 1)))))
+
+  (phps-mode-test--with-buffer
+   "<?php\nif (isset($b)) {\n    $b = false;\n}\n$c = 2;\n\nif ($c) {\n    
echo 'Hit';\n}\n"
+   "Bookkeeping of variable after isset() block"
+   (should (equal
+            (phps-mode-test--hash-to-list 
(phps-mode-lex-analyzer--get-bookkeeping) t)
+            '((" defined 1 id $b" 2) ((17 19) 1) ((28 30) 1) (" id $c" 1) ((42 
44) 1) ((55 57) 1)))))
+
+  (phps-mode-test--with-buffer
+   "<?php\nif (!isset($a)) {\n    if ($a) {\n        echo 'Miss';\n    }\n}"
+   "Bookkeeping for variable in negative isset() conditional"
+   (should (equal
+            (phps-mode-test--hash-to-list 
(phps-mode-lex-analyzer--get-bookkeeping) t)
+            '(((18 20) 0) ((33 35) 0)))))
+
+  (phps-mode-test--with-buffer
+   "<?php\n\nfunction myFunction($a, $b, $c, $d)\n{\n    global $f, $g;\n    
if (isset($f)) {\n        if (!empty($g)) {\n            if ($a) {\n            
    echo 'Hit';\n            }\n            if ($b) {\n                echo 
'Hit';\n            }\n            if ($c) {\n                echo 'Hit';\n     
       }\n            if ($d) {\n                echo 'Hit';\n            }\n   
     }\n    }\n}\n"
+   "Bookkeeping variables inside nested isset() !empty() blocks"
+   (should (equal
+            (phps-mode-test--hash-to-list 
(phps-mode-lex-analyzer--get-bookkeeping) t)
+            '((" function myFunction id $a" 1) ((28 30) 1) (" function 
myFunction id $b" 1) ((32 34) 1) (" function myFunction id $c" 1) ((36 38) 1) 
(" function myFunction id $d" 1) ((40 42) 1) (" function myFunction id $f" 1) 
((57 59) 1) (" function myFunction id $g" 1) ((61 63) 1) (" function myFunction 
defined 1 id $f" 1) ((79 81) 1) (" function myFunction defined 2 id $g" 1) 
((105 107) 1) ((128 130) 1) ((192 194) 1) ((256 258) 1) ((320 322) 1)))))
+
+  (phps-mode-test--with-buffer
+   "<?php\n\n$var = 123;\n\nfunction test($abc) {\n    static $var;\n    if 
($var) {\n        echo 'Hit';\n    }\n}"
+   "Bookkeeping of static variable declaration in function"
+   (should (equal
+            (phps-mode-test--hash-to-list 
(phps-mode-lex-analyzer--get-bookkeeping) t)
+            '((" id $var" 1) ((8 12) 1) (" function test id $abc" 1) ((35 39) 
1) (" function test id $var" 1) ((54 58) 1) ((68 72) 1)))))
+
   )
 
 (defun phps-mode-test-lex-analyzer ()



reply via email to

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