[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/phps-mode f69df4fdf6 083/212: Moved indentation to sepa
From: |
Christian Johansson |
Subject: |
[elpa] externals/phps-mode f69df4fdf6 083/212: Moved indentation to separate file and test |
Date: |
Wed, 26 Jan 2022 01:50:57 -0500 (EST) |
branch: externals/phps-mode
commit f69df4fdf68419faa39db2954d8b4fe78da791e2
Author: Christian Johansson <christian@cvj.se>
Commit: Christian Johansson <christian@cvj.se>
Moved indentation to separate file and test
---
phps-mode-lex-analyzer.el | 1892 -----------------------------------
phps-mode.el | 3 +-
test/phps-mode-test-lex-analyzer.el | 881 +---------------
3 files changed, 6 insertions(+), 2770 deletions(-)
diff --git a/phps-mode-lex-analyzer.el b/phps-mode-lex-analyzer.el
index 91b2e2b595..7fc0d8e57c 100644
--- a/phps-mode-lex-analyzer.el
+++ b/phps-mode-lex-analyzer.el
@@ -24,7 +24,6 @@
;;
;; * Executing different kinds of lexers based on conditions
;; * Also supply logic for indentation and imenu-handling
-;; * Indentation based on lexer tokens
;; * Imenu based on lexer tokens
;; * Syntax coloring based on lexer tokens
@@ -799,1897 +798,6 @@
(nreverse new-index)))
-(defun phps-mode-lex-analyzer--get-lines-in-buffer (beg end)
- "Return the number of lines in buffer between BEG and END."
- (phps-mode-lex-analyzer--get-lines-in-string (buffer-substring-no-properties
beg end)))
-
-(defun phps-mode-lex-analyzer--get-lines-in-string (string)
- "Return the number of lines in STRING."
- (let ((lines-in-string 0)
- (start 0))
- (while (string-match "[\n]" string start)
- (setq start (match-end 0))
- (setq lines-in-string (1+ lines-in-string)))
- lines-in-string))
-
-(defun phps-mode-lex-analyzer--get-inline-html-indentation
- (
- inline-html
- indent
- tag-level
- curly-bracket-level
- square-bracket-level
- round-bracket-level)
- "Generate a list of indentation for each line in INLINE-HTML.
-Working incrementally on INDENT, TAG-LEVEL, CURLY-BRACKET-LEVEL,
-SQUARE-BRACKET-LEVEL and ROUND-BRACKET-LEVEL."
- (phps-mode-debug-message
- (message "Calculating HTML indent for: '%s'" inline-html))
-
- ;; Add trailing newline if missing
- (unless (string-match-p "\n$" inline-html)
- (setq inline-html (concat inline-html "\n")))
-
- (let ((start 0)
- (indent-start indent)
- (indent-end indent)
- (line-indents nil)
- (first-object-on-line t)
- (first-object-is-nesting-decrease nil))
- (while
- (string-match
-
"\\([\n]\\)\\|\\(<[a-zA-Z]+\\)\\|\\(</[a-zA-Z]+\\)\\|\\(/>\\)\\|\\(\\[\\)\\|\\()\\)\\|\\((\\)\\|\\({\\|}\\)"
- inline-html
- start)
- (let* ((end (match-end 0))
- (string (substring inline-html (match-beginning 0) end)))
-
- (cond
-
- ((string-match-p "\n" string)
-
- (let ((temp-indent indent))
- (when first-object-is-nesting-decrease
- (phps-mode-debug-message
- (message "Decreasing indent with one since first object was a
nesting decrease"))
- (setq temp-indent (1- indent))
- (when (< temp-indent 0)
- (setq temp-indent 0)))
- (push temp-indent line-indents))
-
- (setq indent-end (+ tag-level curly-bracket-level
square-bracket-level round-bracket-level))
- (phps-mode-debug-message "Encountered a new-line")
- (if (> indent-end indent-start)
- (progn
- (phps-mode-debug-message
- (message "Increasing indent since %s is above %s" indent-end
indent-start))
- (setq indent (1+ indent)))
- (when (< indent-end indent-start)
- (phps-mode-debug-message
- (message "Decreasing indent since %s is below %s" indent-end
indent-start))
- (setq indent (1- indent))
- (when (< indent 0)
- (setq indent 0))))
-
- (setq indent-start indent-end)
- (setq first-object-on-line t)
- (setq first-object-is-nesting-decrease nil))
-
- ((string= string "(")
- (setq round-bracket-level (1+ round-bracket-level)))
- ((string= string ")")
- (setq round-bracket-level (1- round-bracket-level)))
-
- ((string= string "[")
- (setq square-bracket-level (1+ square-bracket-level)))
- ((string= string "]")
- (setq square-bracket-level (1- square-bracket-level)))
-
- ((string= string "{")
- (setq curly-bracket-level (1+ curly-bracket-level)))
- ((string= string "}")
- (setq curly-bracket-level (1- curly-bracket-level)))
-
- ((string-match "<[a-zA-Z]+" string)
- (setq tag-level (1+ tag-level)))
-
- ((string-match "\\(</[a-zA-Z]+\\)\\|\\(/>\\)" string)
- (setq tag-level (1- tag-level)))
-
- )
-
- (when first-object-on-line
- (unless (string-match-p "\n" string)
- (setq first-object-on-line nil)
- (setq indent-end (+ tag-level curly-bracket-level
square-bracket-level round-bracket-level))
- (when (< indent-end indent-start)
- (phps-mode-debug-message "First object was nesting decrease")
- (setq first-object-is-nesting-decrease t))))
-
- (setq start end)))
- (list (nreverse line-indents) indent tag-level curly-bracket-level
square-bracket-level round-bracket-level)))
-
-(defun phps-mode-lex-analyzer--process-tokens-in-string (tokens string
&optional namespace)
- "Generate indexes for imenu and indentation for TOKENS and STRING with
optional NAMESPACE one pass. Complexity: O(n)."
- (unless namespace
- (setq namespace ""))
- (if tokens
- (progn
- (phps-mode-debug-message
- (message
- "\nCalculation indentation and imenu for all lines in buffer:\n\n%s"
- string))
- (let ((in-heredoc nil)
- (in-heredoc-started-this-line nil)
- (in-heredoc-ended-this-line nil)
- (in-inline-control-structure nil)
- (inline-html-indent 0)
- (inline-html-indent-start 0)
- (inline-html-tag-level 0)
- (inline-html-curly-bracket-level 0)
- (inline-html-square-bracket-level 0)
- (inline-html-round-bracket-level 0)
- (inline-html-is-whitespace nil)
- (inline-html-rest-is-whitespace nil)
- (first-token-is-inline-html nil)
- (after-special-control-structure nil)
- (after-special-control-structure-token nil)
- (after-extra-special-control-structure nil)
- (after-extra-special-control-structure-first-on-line nil)
- (switch-curly-stack nil)
- (switch-alternative-stack nil)
- (switch-case-alternative-stack nil)
- (curly-bracket-level 0)
- (round-bracket-level 0)
- (square-bracket-level 0)
- (alternative-control-structure-level 0)
- (alternative-control-structure-line 0)
- (in-concatenation nil)
- (in-concatenation-round-bracket-level nil)
- (in-concatenation-square-bracket-level nil)
- (in-concatenation-level 0)
- (in-double-quotes nil)
- (column-level 0)
- (column-level-start 0)
- (tuning-level 0)
- (nesting-start 0)
- (nesting-end 0)
- (last-line-number 0)
- (first-token-on-line t)
- (line-indents (make-hash-table :test 'equal))
- (first-token-is-nesting-decrease nil)
- (token-number 1)
- (allow-custom-column-increment nil)
- (allow-custom-column-decrement nil)
- (in-assignment nil)
- (in-assignment-round-bracket-level nil)
- (in-assignment-square-bracket-level nil)
- (in-assignment-level 0)
- (in-object-operator nil)
- (in-object-operator-round-bracket-level nil)
- (in-object-operator-square-bracket-level nil)
- (after-object-operator nil)
- (in-object-operator-level 0)
- (in-class-declaration nil)
- (in-class-declaration-level 0)
- (in-return nil)
- (in-return-curly-bracket-level nil)
- (in-return-level 0)
- (previous-token nil)
- (previous-token-end nil)
- (previous-token-start nil)
- (previous2-token nil)
- (previous2-token-end nil)
- (previous2-token-start nil)
- (previous3-token nil)
- (token nil)
- (token-start nil)
- (token-end nil)
- (token-start-line-number 0)
- (token-end-line-number 0)
- (tokens (nreverse (copy-sequence tokens)))
- (nesting-stack nil)
- (nesting-key nil)
- (nesting-value nil)
- (class-declaration-started-this-line nil)
- (special-control-structure-started-this-line nil)
- (temp-pre-indent nil)
- (temp-post-indent nil)
- (array-variable-declaration nil)
- (imenu-index '())
- (imenu-namespace-index '())
- (imenu-class-index '())
- (imenu-in-namespace-declaration nil)
- (imenu-in-namespace-name nil)
- (imenu-in-namespace-with-brackets nil)
- (imenu-open-namespace-level nil)
- (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)
- (imenu-in-function-index nil)
- (imenu-nesting-level 0)
- (incremental-line-number 1)
- (in-catch-declaration)
- (in-anonymous-function-declaration)
- (in-anonymous-function-number 0)
- (in-anonymous-function-nesting-level)
- (in-global-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)
-
- ;; Iterate through all buffer tokens from beginning to end
- (dolist (item (nreverse tokens))
- ;; (message "Items: %s %s" item phps-mode-lex-analyzer--tokens)
- (let ((next-token (car item))
- (next-token-start (car (cdr item)))
- (next-token-end (cdr (cdr item)))
- (next-token-start-line-number nil)
- (next-token-end-line-number nil))
-
- (when (and token
- (< token-end next-token-start))
- ;; NOTE We use a incremental-line-number calculation because
`line-at-pos' takes a lot of time
- (setq
- incremental-line-number
- (+
- incremental-line-number
- (phps-mode-lex-analyzer--get-lines-in-string
- (substring
- string
- (1- token-end)
- (1- next-token-start))))))
-
- ;; Handle the pseudo-token for last-line
- (if (equal next-token 'END_PARSE)
- (progn
- (setq next-token-start-line-number (1+
token-start-line-number))
- (setq next-token-end-line-number (1+
token-end-line-number)))
- (setq next-token-start-line-number incremental-line-number)
-
- ;; NOTE We use a incremental-line-number calculation because
`line-at-pos' takes a lot of time
- ;; (message "Lines for %s '%s'" next-token (substring string
(1- next-token-start) (1- next-token-end)))
- (setq
- incremental-line-number
- (+
- incremental-line-number
- (phps-mode-lex-analyzer--get-lines-in-string
- (substring
- string
- (1- next-token-start)
- (1- next-token-end)))))
- (setq next-token-end-line-number incremental-line-number)
- (phps-mode-debug-message
- (message
- "Token '%s' pos: %s-%s lines: %s-%s"
- next-token
- next-token-start
- next-token-end
- next-token-start-line-number
- next-token-end-line-number)))
-
- ;; Token logic - we have one-two token look-ahead at this point
- ;; `token' is previous token
- ;; `next-token' is current token
- ;; `previous-token' is maybe two tokens back
- (when token
-
- ;; BOOKKEEPING LOGIC
-
- (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 "$GLOBALS")
- (equal bookkeeping-variable-name "$_COOKIE")
- (equal bookkeeping-variable-name "$_ENV")
- (equal bookkeeping-variable-name "$_FILES")
- (equal bookkeeping-variable-name "$_GET")
- (equal bookkeeping-variable-name "$_POST")
- (equal bookkeeping-variable-name "$_REQUEST")
- (equal bookkeeping-variable-name "$_SERVER")
- (equal bookkeeping-variable-name "$_SESSION")
- (equal bookkeeping-variable-name "$argc")
- (equal bookkeeping-variable-name "$argv")
- (equal bookkeeping-variable-name
"$http_​response_​header")
- ))
- (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))
- (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
- (or
- (equal previous-token 'T_STATIC)
- (equal previous2-token 'T_STATIC))
- (equal token 'T_VARIABLE)
- (not imenu-in-function-declaration)
- (not imenu-in-function-name))
- (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 " id " bookkeeping-variable-name))))
-
- (phps-mode-debug-message
- (message
- "Bookkeeping-namespace: '%s'"
- bookkeeping-namespace))
-
- ;; 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)
- (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))
- (setq bookkeeping-in-assignment t))
-
- ;; In static variable declaration
- (when (and
- (or
- (equal previous-token 'T_STATIC)
- (equal previous2-token 'T_STATIC))
- (equal token 'T_VARIABLE))
- (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)
- (equal previous2-token 'T_STATIC)
- (equal previous2-token 'T_PRIVATE)
- (equal previous2-token 'T_PROTECTED)
- (equal previous2-token 'T_PUBLIC)
- (equal previous2-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)
-
- ;; 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))
- (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
- (if (or (equal token 'T_ARRAY)
- (equal token "["))
- (setq array-variable-declaration t)
- (setq array-variable-declaration nil)))
-
- (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)))
-
- ;; Keep track of open catch blocks for bookkeeping
- (when (equal token 'T_CATCH)
- (setq in-catch-declaration t))
- (when (and in-catch-declaration
- (equal token "{"))
- (setq in-catch-declaration nil))
-
- ;; Keep track of anonymous functions for bookkeeping
- (when (and
- (equal token 'T_FUNCTION)
- (string= next-token "("))
- (setq in-anonymous-function-declaration t)
- (setq in-anonymous-function-number (1+
in-anonymous-function-number))
- (push (1+ curly-bracket-level)
in-anonymous-function-nesting-level))
- (when (and in-anonymous-function-declaration
- (equal token "{"))
- (setq in-anonymous-function-declaration nil))
- (when (and in-anonymous-function-nesting-level
- (string= token "}")
- (equal curly-bracket-level (car
in-anonymous-function-nesting-level)))
- (pop in-anonymous-function-nesting-level))
-
- ;; Keep track of arrow function declaration
- (when (equal token 'T_FN)
- (unless in-arrow-fn
- (setq in-arrow-fn-number (1+ in-arrow-fn-number)))
- (setq in-arrow-fn t)
- (setq in-arrow-fn-declaration t))
- (when (and
- in-arrow-fn-declaration
- (equal token ")"))
- (setq in-arrow-fn-declaration nil))
- (when (and
- in-arrow-fn
- (equal token ";"))
- (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
-
- ((or (string= token "{")
- (equal token 'T_CURLY_OPEN)
- (equal token 'T_DOLLAR_OPEN_CURLY_BRACES))
- (setq imenu-nesting-level (1+ imenu-nesting-level)))
-
- ((string= token "}")
-
- (when (and
- imenu-open-namespace-level
- (= imenu-open-namespace-level imenu-nesting-level)
- imenu-in-namespace-name
- imenu-namespace-index)
- (let ((imenu-add-list (nreverse imenu-namespace-index)))
- (push `(,imenu-in-namespace-name . ,imenu-add-list)
imenu-index))
- (setq imenu-in-namespace-name nil))
-
- (when (and imenu-open-class-level
- (= imenu-open-class-level imenu-nesting-level)
- imenu-in-class-name
- imenu-class-index)
- (let ((imenu-add-list (nreverse imenu-class-index)))
- (if imenu-in-namespace-name
- (push `(,imenu-in-class-name . ,imenu-add-list)
imenu-namespace-index)
- (push `(,imenu-in-class-name . ,imenu-add-list)
imenu-index)))
- (setq imenu-in-class-name nil))
-
- (when (and imenu-open-function-level
- (= imenu-open-function-level imenu-nesting-level)
- imenu-in-function-name)
- (setq imenu-in-function-name nil))
-
- (setq imenu-nesting-level (1- imenu-nesting-level))))
-
- (cond
-
- (imenu-in-namespace-declaration
- (cond
-
- ((or (string= token "{")
- (string= token ";"))
- (setq imenu-in-namespace-with-brackets (string= token "{"))
- (setq imenu-open-namespace-level imenu-nesting-level)
- (setq imenu-namespace-index '())
- (setq imenu-in-namespace-declaration nil))
-
- ((and (or
- (equal token 'T_STRING)
- (equal token 'T_NAME_RELATIVE)
- (equal token 'T_NAME_FULLY_QUALIFIED)
- (equal token 'T_NAME_QUALIFIED))
- (setq
- imenu-in-namespace-name
- (concat
- imenu-in-namespace-name
- (substring
- string
- (1- token-start)
- (1- token-end))))))))
-
- (imenu-in-class-declaration
- (cond
-
- ((string= token "{")
- (setq imenu-open-class-level imenu-nesting-level)
- (setq imenu-in-class-declaration nil)
- (setq imenu-class-index '()))
-
- ((and (equal token 'T_STRING)
- (not imenu-in-class-name))
- (setq imenu-in-class-name (substring string (1-
token-start) (1- token-end))))))
-
- (imenu-in-function-declaration
- (cond
-
- ((or (string= token "{")
- (string= token ";"))
- (when imenu-in-function-name
- (if imenu-in-class-name
- (push `(,imenu-in-function-name .
,imenu-in-function-index) imenu-class-index)
- (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))))
-
- (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)
- (not imenu-in-function-name))
- (setq imenu-in-function-name (substring string (1-
token-start) (1- token-end)))
- (setq imenu-in-function-index token-start))))
-
- (t (cond
-
- ((and (not imenu-in-namespace-name)
- (equal token 'T_NAMESPACE))
- (setq imenu-in-namespace-name nil)
- (setq imenu-in-namespace-declaration t))
-
- ((and (not imenu-in-class-name)
- (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)
- (equal token 'T_FUNCTION))
- (setq imenu-in-function-name nil)
- (setq imenu-in-function-declaration t)))))
-
- (when (and (equal next-token 'END_PARSE)
- imenu-in-namespace-name
- (not imenu-in-namespace-with-brackets)
- imenu-namespace-index)
- (let ((imenu-add-list (nreverse imenu-namespace-index)))
- (push `(,imenu-in-namespace-name . ,imenu-add-list)
imenu-index))
- (setq imenu-in-namespace-name nil))
-
-
- ;; INDENTATION LOGIC
-
-
- ;; Keep track of round bracket level
- (when (string= token "(")
- (setq round-bracket-level (1+ round-bracket-level)))
- (when (string= token ")")
- (setq round-bracket-level (1- round-bracket-level))
- (when first-token-on-line
- (setq first-token-is-nesting-decrease t)))
-
- ;; Keep track of opened double quotes
- (when (string= token "\"")
- (setq in-double-quotes (not in-double-quotes)))
-
- ;; Keep track of square bracket level
- (when (string= token "[")
- (setq square-bracket-level (1+ square-bracket-level)))
- (when (string= token "]")
- (setq square-bracket-level (1- square-bracket-level))
- (when first-token-on-line
- (setq first-token-is-nesting-decrease t)))
-
- ;; Handle INLINE_HTML blocks
- (when (equal token 'T_INLINE_HTML)
-
- ;; Flag whether inline-html is whitespace or not
- (setq
- inline-html-is-whitespace
- (string=
- (string-trim
- (substring
- string
- (1- token-start)
- (1- token-end))) ""))
- (setq
- inline-html-rest-is-whitespace
- (string-match
- "^[\ \t\r\f]+\n"
- (substring
- string
- (1- token-start)
- (1- token-end))))
-
- (when first-token-on-line
- (setq first-token-is-inline-html t))
-
- (let ((inline-html-indents
- (phps-mode-lex-analyzer--get-inline-html-indentation
- (substring
- string
- (1- token-start)
- (1- token-end))
- inline-html-indent
- inline-html-tag-level
- inline-html-curly-bracket-level
- inline-html-square-bracket-level
- inline-html-round-bracket-level)))
-
- (phps-mode-debug-message
- (message
- "Received inline html indent: %s from inline HTML: '%s'"
- inline-html-indents
- (substring
- string
- (1- token-start)
- (1- token-end))))
-
- ;; Update indexes
- (setq inline-html-indent (nth 1 inline-html-indents))
- (setq inline-html-tag-level (nth 2 inline-html-indents))
- (setq inline-html-curly-bracket-level (nth 3
inline-html-indents))
- (setq inline-html-square-bracket-level (nth 4
inline-html-indents))
- (setq inline-html-round-bracket-level (nth 5
inline-html-indents))
-
- (phps-mode-debug-message
- (message "First token is inline html: %s"
first-token-is-inline-html))
-
- ;; Does inline html span several lines or starts a new
line?
- (when (or (> token-end-line-number token-start-line-number)
- first-token-is-inline-html)
-
- ;; Token does not only contain white-space?
- (unless inline-html-is-whitespace
- (let ((token-line-number-diff token-start-line-number))
- ;; Iterate lines here and add indents
- (dolist (item (nth 0 inline-html-indents))
- ;; Skip first line unless first token on line was
inline-html
- (when (or (not (= token-line-number-diff
token-start-line-number))
- first-token-is-inline-html)
- (unless (gethash token-line-number-diff
line-indents)
- (puthash token-line-number-diff (list item 0)
line-indents)
- (phps-mode-debug-message
- (message
- "Putting indent at line %s to %s from inline
HTML"
- token-line-number-diff
- item))))
- (setq token-line-number-diff (1+
token-line-number-diff))))))))
-
- ;; Keep track of when we are inside a class definition
- (if in-class-declaration
- (if (string= token "{")
- (progn
- (setq in-class-declaration nil)
- (setq in-class-declaration-level 0)
-
- (unless class-declaration-started-this-line
- (setq column-level (1- column-level))
- (pop nesting-stack))
-
- (when first-token-on-line
- (setq first-token-is-nesting-decrease t))
-
- )
- (when first-token-on-line
- (setq in-class-declaration-level 1)))
-
- ;; If ::class is used as a magical class constant it should
not be considered start of a class declaration
- (when (and (equal token 'T_CLASS)
- (or (not previous-token)
- (not (equal previous-token
'T_PAAMAYIM_NEKUDOTAYIM))))
- (setq in-class-declaration t)
- (setq in-class-declaration-level 1)
- (setq class-declaration-started-this-line t)))
-
- ;; Keep track of curly bracket level
- (when (or (equal token 'T_CURLY_OPEN)
- (equal token 'T_DOLLAR_OPEN_CURLY_BRACES)
- (string= token "{"))
- (setq curly-bracket-level (1+ curly-bracket-level))
- (phps-mode-debug-message
- (message "New-curly-bracket-level: %s"
curly-bracket-level)))
- (when (string= token "}")
- (setq curly-bracket-level (1- curly-bracket-level))
- (phps-mode-debug-message
- (message "New-curly-bracket-level: %s" curly-bracket-level))
-
- (when (and switch-curly-stack
- (= (1+ curly-bracket-level) (car
switch-curly-stack)))
-
- (phps-mode-debug-message
- (message "Ended switch curly stack at %s"
curly-bracket-level))
-
- (setq allow-custom-column-decrement t)
- (pop nesting-stack)
- (setq alternative-control-structure-level (1-
alternative-control-structure-level))
- (pop switch-curly-stack))
-
- (when first-token-on-line
- (setq first-token-is-nesting-decrease t)))
-
- ;; Keep track of ending alternative control structure level
- (when (or (equal token 'T_ENDIF)
- (equal token 'T_ENDWHILE)
- (equal token 'T_ENDFOR)
- (equal token 'T_ENDFOREACH)
- (equal token 'T_ENDSWITCH))
- (setq alternative-control-structure-level (1-
alternative-control-structure-level))
- ;; (message "Found ending alternative token %s %s" token
alternative-control-structure-level)
-
- (when (and (equal token 'T_ENDSWITCH)
- switch-case-alternative-stack)
-
- (phps-mode-debug-message
- (message "Ended alternative switch stack at %s"
alternative-control-structure-level))
-
- (pop switch-alternative-stack)
- (pop switch-case-alternative-stack)
- (setq allow-custom-column-decrement t)
- (pop nesting-stack)
- (setq alternative-control-structure-level (1-
alternative-control-structure-level)))
-
- (when first-token-on-line
- (setq first-token-is-nesting-decrease t)))
-
- ;; When we encounter a token except () after a
control-structure
- (when (and after-special-control-structure
- (= after-special-control-structure
round-bracket-level)
- (not (string= token ")"))
- (not (string= token "(")))
-
- ;; Handle the else if case
- (if (equal 'T_IF token)
- (progn
- (setq after-special-control-structure-token token)
- (setq alternative-control-structure-line
token-start-line-number))
-
- ;; Is token not a curly bracket - because that is a
ordinary control structure syntax
- (if (string= token "{")
-
- ;; Save curly bracket level when switch starts
- (when (equal after-special-control-structure-token
'T_SWITCH)
-
- (phps-mode-debug-message
- (message "Started switch curly stack at %s"
curly-bracket-level))
-
- (push curly-bracket-level switch-curly-stack))
-
- ;; Is it the start of an alternative control structure?
- (if (string= token ":")
-
- (progn
-
- ;; Save alternative nesting level for switch
- (when (equal after-special-control-structure-token
'T_SWITCH)
-
- (phps-mode-debug-message
- (message "Started switch alternative stack at
%s" alternative-control-structure-level))
-
- (push alternative-control-structure-level
switch-alternative-stack))
-
- (setq alternative-control-structure-level (1+
alternative-control-structure-level))
-
- (setq nesting-value token)
-
- (phps-mode-debug-message
- (message
- "\nIncreasing alternative-control-structure
after %s %s to %s\n"
- after-special-control-structure-token
- token
- alternative-control-structure-level))
- )
-
- ;; Don't start inline control structures after a while
($condition); expression
- (unless (string= token ";")
- (phps-mode-debug-message
- (message
- "\nStarted inline control-structure after %s at
%s\n"
- after-special-control-structure-token
- token))
-
- (setq in-inline-control-structure t)
- (when (< alternative-control-structure-line
token-start-line-number)
- (setq temp-pre-indent (1+ column-level))))))
-
- (setq after-special-control-structure nil)
- (setq after-special-control-structure-token nil)
- (setq alternative-control-structure-line nil)))
-
- ;; Support extra special control structures (CASE)
- (when (and after-extra-special-control-structure
- (string= token ":"))
- (setq nesting-value token)
- (setq alternative-control-structure-level (1+
alternative-control-structure-level))
- (when after-extra-special-control-structure-first-on-line
- (setq first-token-is-nesting-decrease t))
- (setq after-extra-special-control-structure nil))
-
- ;; Keep track of concatenation
- (if in-concatenation
- (when (or (string= token ";")
- (and (string= token ")")
- (< round-bracket-level (car
in-concatenation-round-bracket-level)))
- (and (string= token ",")
- (= round-bracket-level (car
in-concatenation-round-bracket-level))
- (= square-bracket-level (car
in-concatenation-square-bracket-level)))
- (and (string= token"]")
- (< square-bracket-level (car
in-concatenation-square-bracket-level))))
- (phps-mode-debug-message "Ended concatenation")
- (pop in-concatenation-round-bracket-level)
- (pop in-concatenation-square-bracket-level)
- (unless in-concatenation-round-bracket-level
- (setq in-concatenation nil))
- (setq in-concatenation-level (1-
in-concatenation-level)))
- (when (and (> next-token-start-line-number
token-end-line-number)
- (or (string= token ".")
- (string= next-token ".")))
- (phps-mode-debug-message "Started concatenation")
- (setq in-concatenation t)
- (push round-bracket-level
in-concatenation-round-bracket-level)
- (push square-bracket-level
in-concatenation-square-bracket-level)
- (setq in-concatenation-level (1+ in-concatenation-level))))
-
- ;; Did we reach a semicolon inside a inline block? Close the
inline block
- (when (and in-inline-control-structure
- (string= token ";")
- (not special-control-structure-started-this-line))
- (setq in-inline-control-structure nil))
-
- ;; Did we encounter a token that supports alternative and
inline control structures?
- (when (or (equal token 'T_IF)
- (equal token 'T_WHILE)
- (equal token 'T_FOR)
- (equal token 'T_FOREACH)
- (equal token 'T_SWITCH)
- (equal token 'T_ELSE)
- (equal token 'T_ELSEIF)
- (equal token 'T_DEFAULT))
- (setq after-special-control-structure round-bracket-level)
- (setq after-special-control-structure-token token)
- (setq alternative-control-structure-line
token-start-line-number)
- (setq nesting-key token)
- (setq nesting-value nil)
- (setq special-control-structure-started-this-line t)
-
- ;; ELSE and ELSEIF after a IF, ELSE, ELESIF
- ;; and DEFAULT after a CASE
- ;; should decrease alternative control structure level
- (when (and nesting-stack
- (string= (car (cdr (cdr (cdr (car
nesting-stack))))) ":")
- (or
- (and (or (equal token 'T_ELSE)
- (equal token 'T_ELSEIF))
- (or (equal (car (cdr (cdr (car
nesting-stack)))) 'T_IF)
- (equal (car (cdr (cdr (car
nesting-stack)))) 'T_ELSEIF)
- (equal (car (cdr (cdr (car
nesting-stack)))) 'T_ELSE)))
- (and (equal token 'T_DEFAULT)
- (equal (car (cdr (cdr (car
nesting-stack)))) 'T_CASE))))
- (setq alternative-control-structure-level (1-
alternative-control-structure-level))
-
- (when first-token-on-line
- (setq first-token-is-nesting-decrease t))
-
- (phps-mode-debug-message
- (message
- "\nDecreasing alternative control structure nesting at
%s to %s\n"
- token
- alternative-control-structure-level)))
-
- )
-
- ;; Keep track of assignments
- (when in-assignment
- (when (or (string= token ";")
- (and (string= token ")")
- (or (< round-bracket-level (car
in-assignment-round-bracket-level))
- (and
- (= round-bracket-level (car
in-assignment-round-bracket-level))
- (= square-bracket-level (car
in-assignment-square-bracket-level))
- (or (string= next-token ")")
- (string= next-token "]")))))
- (and (string= token ",")
- (= round-bracket-level (car
in-assignment-round-bracket-level))
- (= square-bracket-level (car
in-assignment-square-bracket-level)))
- (and (string= token "]")
- (or (< square-bracket-level (car
in-assignment-square-bracket-level))
- (and
- (= square-bracket-level (car
in-assignment-square-bracket-level))
- (= round-bracket-level (car
in-assignment-round-bracket-level))
- (or (string= next-token "]")
- (string= next-token ")")))))
- (and (equal token 'T_FUNCTION)
- (= round-bracket-level (car
in-assignment-round-bracket-level))))
-
- ;; NOTE Ending an assignment because of a T_FUNCTION token
is to support PSR-2 Closures
-
- (phps-mode-debug-message
- (message "Ended assignment %s at %s %s"
in-assignment-level token next-token))
- (pop in-assignment-square-bracket-level)
- (pop in-assignment-round-bracket-level)
- (unless in-assignment-round-bracket-level
- (setq in-assignment nil))
- (setq in-assignment-level (1- in-assignment-level))
-
- ;; Did we end two assignment at once?
- (when (and
- in-assignment-round-bracket-level
- in-assignment-square-bracket-level
- (= round-bracket-level (car
in-assignment-round-bracket-level))
- (= square-bracket-level (car
in-assignment-square-bracket-level))
- (or (string= next-token ")")
- (string= next-token "]")))
- (phps-mode-debug-message
- (message "Ended another assignment %s at %s %s"
in-assignment-level token next-token))
- (pop in-assignment-square-bracket-level)
- (pop in-assignment-round-bracket-level)
- (unless in-assignment-round-bracket-level
- (setq in-assignment nil))
- (setq in-assignment-level (1- in-assignment-level)))
-
- ))
-
- (when (and (not after-special-control-structure)
- (or (string= token "=")
- (equal token 'T_DOUBLE_ARROW)
- (equal token 'T_CONCAT_EQUAL)
- (equal token 'T_POW_EQUAL)
- (equal token 'T_DIV_EQUAL)
- (equal token 'T_PLUS_EQUAL)
- (equal token 'T_MINUS_EQUAL)
- (equal token 'T_MUL_EQUAL)
- (equal token 'T_MOD_EQUAL)
- (equal token 'T_SL_EQUAL)
- (equal token 'T_SR_EQUAL)
- (equal token 'T_AND_EQUAL)
- (equal token 'T_OR_EQUAL)
- (equal token 'T_XOR_EQUAL)
- (equal token 'T_COALESCE_EQUAL)))
- (phps-mode-debug-message
- (message "Started assignment at token: %s" token))
- (setq in-assignment t)
- (push round-bracket-level in-assignment-round-bracket-level)
- (push square-bracket-level
in-assignment-square-bracket-level)
- (setq in-assignment-level (1+ in-assignment-level)))
-
- ;; Second token after a object-operator
- (when (and
- in-object-operator
- in-object-operator-round-bracket-level
- in-object-operator-square-bracket-level
- (<= round-bracket-level (car
in-object-operator-round-bracket-level))
- (<= square-bracket-level (car
in-object-operator-square-bracket-level))
- (not (or
- (equal next-token 'T_OBJECT_OPERATOR)
- (equal next-token 'T_PAAMAYIM_NEKUDOTAYIM))))
- (phps-mode-debug-message
- (message "Ended object-operator at %s %s at level %s" token
next-token in-object-operator-level))
- (pop in-object-operator-round-bracket-level)
- (pop in-object-operator-square-bracket-level)
- (setq in-object-operator-level (1- in-object-operator-level))
- (when (= in-object-operator-level 0)
- (setq in-object-operator nil)))
-
- ;; First token after a object-operator
- (when after-object-operator
- (when (or (equal next-token 'T_STRING)
- (string= next-token "("))
- (progn
- (phps-mode-debug-message
- (message
- "Started object-operator at %s %s on level %s"
- token
- next-token
- in-object-operator-level
- ))
- (push round-bracket-level
in-object-operator-round-bracket-level)
- (push square-bracket-level
in-object-operator-square-bracket-level)
- (setq in-object-operator t)
- (setq in-object-operator-level (1+
in-object-operator-level))))
- (setq after-object-operator nil))
-
- ;; Starting object-operator?
- (when (and (or (equal token 'T_OBJECT_OPERATOR)
- (equal token 'T_PAAMAYIM_NEKUDOTAYIM))
- (equal next-token 'T_STRING))
- (phps-mode-debug-message
- (message "After object-operator at %s level %s" token
in-object-operator-level))
- (setq after-object-operator t))
-
- ;; Keep track of return expressions
- (when in-return
- (when (and (string= token ";")
- (= curly-bracket-level (car
in-return-curly-bracket-level)))
-
- (phps-mode-debug-message (message "Ended return at %s"
token))
- (pop in-return-curly-bracket-level)
- (unless in-return-curly-bracket-level
- (setq in-return nil))
- (setq in-return-level (1- in-return-level))))
- (when (equal token 'T_RETURN)
- (phps-mode-debug-message "Started return")
- (setq in-return t)
- (push curly-bracket-level in-return-curly-bracket-level)
- (setq in-return-level (1+ in-return-level)))
-
- ;; Did we encounter a token that supports extra special
alternative control structures?
- (when (equal token 'T_CASE)
- (setq after-extra-special-control-structure t)
- (setq nesting-key token)
- (setq nesting-value nil)
- (setq after-extra-special-control-structure-first-on-line
first-token-on-line)
-
- (when (and switch-case-alternative-stack
- (= (1- alternative-control-structure-level) (car
switch-case-alternative-stack)))
-
- (phps-mode-debug-message
- (message "Found CASE %s vs %s" (1-
alternative-control-structure-level) (car switch-case-alternative-stack)))
-
- (setq alternative-control-structure-level (1-
alternative-control-structure-level))
- (when first-token-on-line
- (setq first-token-is-nesting-decrease t))
- (pop switch-case-alternative-stack))
-
- (push alternative-control-structure-level
switch-case-alternative-stack)))
-
- ;; Do we have one token look-ahead?
- (when token
-
- (phps-mode-debug-message (message "Processing token: %s"
token))
-
- ;; Calculate nesting
- (setq
- nesting-end
- (+
- round-bracket-level
- square-bracket-level
- curly-bracket-level
- alternative-control-structure-level
- in-assignment-level
- in-class-declaration-level
- in-concatenation-level
- in-return-level
- in-object-operator-level))
-
- (phps-mode-debug-message
- (message "Nesting-end: %s from (+ %s %s %s %s %s %s %s %s %s)"
- nesting-end
- round-bracket-level
- square-bracket-level
- curly-bracket-level
- alternative-control-structure-level
- in-assignment-level
- in-class-declaration-level
- in-concatenation-level
- in-return-level
- in-object-operator-level))
-
- ;; Keep track of whether we are inside a HEREDOC or NOWDOC
- (when (equal token 'T_START_HEREDOC)
- (setq in-heredoc t)
- (setq in-heredoc-started-this-line t))
- (when (equal token 'T_END_HEREDOC)
- (setq in-heredoc nil)
- (setq in-heredoc-ended-this-line t))
-
- ;; Has nesting increased?
- (when (and nesting-stack
- (<= nesting-end (car (car nesting-stack))))
- (let ((nesting-decrement 0))
-
- ;; Handle case were nesting has decreased less than next
as well
- (while (and nesting-stack
- (<= nesting-end (car (car nesting-stack))))
- (phps-mode-debug-message
- (message
- "\nPopping %s from nesting-stack since %s is lesser or
equal to %s, next value is: %s\n"
- (car nesting-stack)
- nesting-end
- (car (car nesting-stack))
- (nth 1 nesting-stack)))
- (pop nesting-stack)
- (setq nesting-decrement (1+ nesting-decrement)))
-
- (if first-token-is-nesting-decrease
-
- (progn
- ;; Decrement column
- (if allow-custom-column-decrement
- (progn
- (phps-mode-debug-message
- (message
- "Doing custom decrement 1 from %s to %s"
- column-level
- (- column-level
- (- nesting-start nesting-end))))
- (setq column-level (- column-level (-
nesting-start nesting-end)))
- (setq allow-custom-column-decrement nil))
- (phps-mode-debug-message
- (message
- "Doing regular decrement 1 from %s to %s"
- column-level
- (1- column-level)))
- (setq column-level (- column-level
nesting-decrement)))
-
- ;; Prevent negative column-values
- (when (< column-level 0)
- (setq column-level 0)))
-
- (unless temp-post-indent
- (phps-mode-debug-message
- (message "Temporary setting post indent %s"
column-level))
- (setq temp-post-indent column-level))
-
- ;; Decrement column
- (if allow-custom-column-decrement
- (progn
- (phps-mode-debug-message
- (message
- "Doing custom decrement 2 from %s to %s"
- column-level
- (- column-level
- (- nesting-start nesting-end))))
- (setq
- temp-post-indent
- (- temp-post-indent
- (- nesting-start nesting-end)))
- (setq allow-custom-column-decrement nil))
- (setq temp-post-indent (- temp-post-indent
nesting-decrement)))
-
- ;; Prevent negative column-values
- (when (< temp-post-indent 0)
- (setq temp-post-indent 0))
-
- )))
-
- ;; Are we on a new line or is it the last token of the buffer?
- (if (> next-token-start-line-number token-start-line-number)
- (progn
-
-
- ;; ;; Start indentation might differ from ending
indentation in cases like } else {
- (setq column-level-start column-level)
-
- ;; Support temporarily pre-indent
- (when temp-pre-indent
- (setq column-level-start temp-pre-indent)
- (setq temp-pre-indent nil))
-
- ;; HEREDOC lines should have zero indent
- (when (or (and in-heredoc
- (not in-heredoc-started-this-line))
- in-heredoc-ended-this-line)
- (setq column-level-start 0))
-
- ;; Inline HTML should have zero indent
- (when (and first-token-is-inline-html
- (not inline-html-is-whitespace))
- (phps-mode-debug-message
- (message "Setting column-level to inline HTML indent:
%s" inline-html-indent-start))
- (setq column-level-start inline-html-indent-start))
-
- ;; Save line indent
- (phps-mode-debug-message
- (message
- "Process line ending. nesting: %s-%s, line-number:
%s-%s, indent: %s.%s, token: %s"
- nesting-start
- nesting-end
- token-start-line-number
- token-end-line-number
- column-level-start
- tuning-level
- token))
-
- (when (and (> token-start-line-number 0)
- (or
- (not first-token-is-inline-html)
- inline-html-is-whitespace
- inline-html-rest-is-whitespace))
- (phps-mode-debug-message
- (message
- "Putting indent on line %s to %s at #C"
- token-start-line-number
- column-level-start))
- (puthash
- token-start-line-number
- `(,column-level-start ,tuning-level)
- line-indents))
-
- ;; Support trailing indent decrements
- (when temp-post-indent
- (setq column-level temp-post-indent)
- (setq temp-post-indent nil))
-
- ;; Increase indentation
- (when (and (> nesting-end 0)
- (or (not nesting-stack)
- (> nesting-end (car (cdr (car
nesting-stack))))))
- (let ((nesting-stack-end 0))
- (when nesting-stack
- (setq nesting-stack-end (car (cdr (car
nesting-stack)))))
-
- (if allow-custom-column-increment
- (progn
- (setq column-level (+ column-level (-
nesting-end nesting-start)))
- (setq allow-custom-column-increment nil))
- (setq column-level (1+ column-level)))
-
- (phps-mode-debug-message
- (message
- "\nPushing (%s %s %s %s) to nesting-stack since %s
is greater than %s or stack is empty\n"
- nesting-start
- nesting-end
- nesting-key
- nesting-value
- nesting-end
- (car (cdr (car nesting-stack))))
- )
- (push `(,nesting-stack-end ,nesting-end ,nesting-key
,nesting-value) nesting-stack)))
-
-
- ;; Does token span over several lines and is it not a
INLINE_HTML token?
- (when (and (> token-end-line-number
token-start-line-number)
- (not (equal token 'T_INLINE_HTML)))
- (let ((column-level-end column-level))
-
- ;; HEREDOC lines should have zero indent
- (when (or (and in-heredoc
- (not in-heredoc-started-this-line))
- in-heredoc-ended-this-line)
- (setq column-level-end 0))
-
- ;; Indent doc-comment lines with 1 tuning
- (when (equal token 'T_DOC_COMMENT)
- (setq tuning-level 1))
-
- (let ((token-line-number-diff (1- (-
token-end-line-number token-start-line-number))))
- (while (>= token-line-number-diff 0)
- (phps-mode-debug-message
- (message
- "Putting indent on line %s to %s at #A"
- (- token-end-line-number
token-line-number-diff)
- column-level-end))
- (puthash
- (- token-end-line-number token-line-number-diff)
- `(,column-level-end ,tuning-level) line-indents)
- ;; (message "Saved line %s indent %s %s" (-
token-end-line-number token-line-number-diff) column-level tuning-level)
- (setq token-line-number-diff (1-
token-line-number-diff))))
-
- ;; Rest tuning-level used for comments
- (setq tuning-level 0)))
-
- ;; Indent token-less lines here in between last tokens
if distance is more than 1 line
- (when (and (> next-token-start-line-number (1+
token-end-line-number))
- (not (equal token 'T_CLOSE_TAG)))
-
- (phps-mode-debug-message
- (message
- "\nDetected token-less lines between %s and %s,
should have indent: %s\n"
- token-end-line-number
- next-token-start-line-number
- column-level))
-
- (let ((token-line-number-diff (1- (-
next-token-start-line-number token-end-line-number))))
- (while (> token-line-number-diff 0)
- (phps-mode-debug-message
- (message
- "Putting indent at line %s indent %s at #B"
- (- next-token-start-line-number
token-line-number-diff)
- column-level))
- (puthash
- (- next-token-start-line-number
token-line-number-diff)
- `(,column-level ,tuning-level) line-indents)
- (setq token-line-number-diff (1-
token-line-number-diff)))))
-
-
- ;; Calculate indentation level at start of line
- (setq
- nesting-start
- (+
- round-bracket-level
- square-bracket-level
- curly-bracket-level
- alternative-control-structure-level
- in-assignment-level
- in-class-declaration-level
- in-concatenation-level
- in-return-level
- in-object-operator-level))
-
- ;; Set initial values for tracking first token
- (when (> token-start-line-number last-line-number)
- (setq inline-html-indent-start inline-html-indent)
- (setq first-token-on-line t)
- (setq first-token-is-nesting-decrease nil)
- (setq first-token-is-inline-html nil)
- (setq in-class-declaration-level 0)
- (setq class-declaration-started-this-line nil)
- (setq in-heredoc-started-this-line nil)
- (setq special-control-structure-started-this-line nil)
-
- ;; When line ends with multi-line inline-html flag
first token as inline-html
- (when (and
- (equal token 'T_INLINE_HTML)
- (not inline-html-is-whitespace)
- (> token-end-line-number
token-start-line-number))
-
- (setq inline-html-is-whitespace
- (not (null
- (string-match "[\r\n][ \f\t]+$"
(substring string (1- token-start) (1- token-end))))))
- (phps-mode-debug-message
- (message "Trailing inline html line is whitespace:
%s" inline-html-is-whitespace))
- (phps-mode-debug-message
- (message
- "Setting first-token-is-inline-html to true since
last token on line is inline-html and spans several lines"))
- (setq first-token-is-inline-html t))))
-
- ;; Current token is not first if it's not <?php or <?=
- (unless (or (equal token 'T_OPEN_TAG)
- (equal token 'T_OPEN_TAG_WITH_ECHO))
- (setq first-token-on-line nil))
-
- (when (> token-end-line-number token-start-line-number)
- ;; (message "Token not first on line %s starts at %s and
ends at %s" token token-start-line-number token-end-line-number)
- (when (equal token 'T_DOC_COMMENT)
- (setq tuning-level 1))
-
- (let ((token-line-number-diff (1- (- token-end-line-number
token-start-line-number))))
- (while (>= token-line-number-diff 0)
- (phps-mode-debug-message
- (message
- "Putting indent on line %s to %s at #E"
- (-
- token-end-line-number
- token-line-number-diff)
- column-level))
- (puthash
- (- token-end-line-number token-line-number-diff)
- `(,column-level ,tuning-level) line-indents)
- (setq token-line-number-diff (1-
token-line-number-diff))))
- (setq tuning-level 0))))
-
- ;; Update current token
- (setq previous3-token previous2-token)
- (setq previous2-token previous-token)
- (setq previous2-token-end previous-token-end)
- (setq previous2-token-start previous-token-start)
- (setq previous-token token)
- (setq previous-token-end token-end)
- (setq previous-token-start token-start)
- (setq token next-token)
- (setq token-start next-token-start)
- (setq token-end next-token-end)
- (setq token-start-line-number next-token-start-line-number)
- (setq token-end-line-number next-token-end-line-number)
- (setq token-number (1+ token-number))))
- (list (nreverse imenu-index) line-indents bookkeeping)))
- (list nil nil)))
-
-(defun phps-mode-lex-analyzer--indent-line ()
- "Indent line."
- (phps-mode-lex-analyzer--alternative-indentation (point)))
-
-(defun phps-mode-lex-analyzer--alternative-indentation (&optional point)
- "Apply alternative indentation at POINT here."
- (unless point
- (setq point (point)))
- (let ((new-indentation 0)
- (point-at-end-of-line (equal point (line-end-position))))
- (save-excursion
- (let ((line-number (line-number-at-pos point))
- (move-length 0)
- (line-is-empty t)
- line-beginning-position
- line-end-position
- line-string
- current-line-string)
- (goto-char point)
- (setq
- current-line-string
- (buffer-substring-no-properties
- (line-beginning-position)
- (line-end-position))
- )
- (if (> line-number 1)
- (progn
- (while (and
- (> line-number 0)
- line-is-empty)
- (forward-line -1)
- (setq line-number (1- line-number))
- (beginning-of-line)
- (setq line-beginning-position (line-beginning-position))
- (setq line-end-position (line-end-position))
- (setq
- line-string
- (buffer-substring-no-properties line-beginning-position
line-end-position))
- (setq line-is-empty (string-match-p "^[ \t\f\r\n]*$"
line-string))
- (setq move-length (1+ move-length)))
-
- (unless line-is-empty
- (let* ((old-indentation (current-indentation))
- (current-line-starts-with-closing-bracket
(phps-mode-lex-analyzer--string-starts-with-closing-bracket-p
current-line-string))
- (line-starts-with-closing-bracket
(phps-mode-lex-analyzer--string-starts-with-closing-bracket-p line-string))
- (line-starts-with-opening-doc-comment
(phps-mode-lex-analyzer--string-starts-with-opening-doc-comment-p line-string))
- (line-ends-with-assignment
(phps-mode-lex-analyzer--string-ends-with-assignment-p line-string))
- (line-ends-with-opening-bracket
(phps-mode-lex-analyzer--string-ends-with-opening-bracket-p line-string))
- (line-ends-with-terminus
(phps-mode-lex-analyzer--string-ends-with-terminus-p line-string))
- (bracket-level
(phps-mode-lex-analyzer--get-string-brackets-count line-string)))
- (setq new-indentation old-indentation)
- (goto-char point)
-
- (when (> bracket-level 0)
- (if (< bracket-level tab-width)
- (setq new-indentation (+ new-indentation 1))
- (setq new-indentation (+ new-indentation tab-width))))
-
- (when (= bracket-level -1)
- (setq new-indentation (1- new-indentation)))
-
- (when (and (= bracket-level 0)
- line-starts-with-closing-bracket)
- (setq new-indentation (+ new-indentation tab-width)))
-
- (when current-line-starts-with-closing-bracket
- (setq new-indentation (- new-indentation tab-width)))
-
- (when line-starts-with-opening-doc-comment
- (setq new-indentation (+ new-indentation 1)))
-
- (when (and
- line-ends-with-assignment
- (<= bracket-level 0))
- (setq new-indentation (+ new-indentation tab-width)))
-
- (when (and
- line-ends-with-opening-bracket
- (< bracket-level 0))
- (setq new-indentation (+ new-indentation tab-width)))
-
- (when line-ends-with-terminus
- ;; Back-trace buffer from previous line
- ;; Determine if semi-colon ended an assignment or
bracket-less command or not
- (forward-line (* -1 move-length))
- (end-of-line)
- (forward-char -1)
- (let ((not-found t)
- (is-assignment nil)
- (parenthesis-level 0)
- (is-bracket-less-command nil))
- (while (and
- not-found
- (search-backward-regexp
"\\(;\\|{\\|(\\|)\\|=\\|echo[\t ]+\\|print[\t ]+\\)" nil t))
- (let ((match (buffer-substring-no-properties
(match-beginning 0) (match-end 0))))
- (when (string= match ")")
- (setq parenthesis-level (1- parenthesis-level)))
- (when (= parenthesis-level 0)
- (setq is-assignment (string= match "="))
- (setq is-bracket-less-command
- (string-match-p
- "\\(echo[\t ]+\\|print[\t ]+\\)"
- match))
- (setq not-found nil))
-
- (when (string= match "(")
- (setq parenthesis-level (1+ parenthesis-level)))))
- ;; If it ended an assignment on a previous line,
decrease indentation
- (when
- (and
- (or
- (and
- is-assignment
- (> bracket-level -1))
- is-bracket-less-command)
- (not (= line-number (line-number-at-pos))))
- ;; NOTE stuff like $var = array(\n 4\n);\n
- ;; will end assignment but also decrease bracket-level
- (setq new-indentation (- new-indentation tab-width))))
-
- (goto-char point))
-
- ;; Decrease indentation if current line decreases in bracket
level
- (when (< new-indentation 0)
- (setq new-indentation 0))
-
- (indent-line-to new-indentation))))
- (indent-line-to 0))))
- ;; Only move to end of line if point is the current point and is at end of
line
- (when (equal point (point))
- (if point-at-end-of-line
- (end-of-line)
- (back-to-indentation)))
- new-indentation))
-
-(defun phps-mode-lex-analyzer--get-string-brackets-count (string)
- "Get bracket count for STRING."
- (let ((bracket-level 0)
- (start 0)
- (line-is-empty
- (string-match-p "^[ \t\f\r\n]*$" string)))
- (unless line-is-empty
- (while (string-match
- "\\([\]{}()[]\\|<[a-zA-Z]+\\|</[a-zA-Z]+\\|/>\\|^[\t
]/\\*\\*\\|^[\t\\* ]*\\*/\\)"
- string
- start)
- (setq start (match-end 0))
- (let ((bracket (substring string (match-beginning 0) (match-end 0))))
- (cond
- ((or
- (string= bracket "{")
- (string= bracket "[")
- (string= bracket "(")
- (string= bracket "<")
- (string-match "<[a-zA-Z]+" bracket))
- (setq bracket-level (+ bracket-level tab-width)))
- ((string-match "^[\t\\* ]*\\*/" bracket )
- (setq bracket-level (- bracket-level 1)))
- ((or
- (string-match "^/\\*\\*" bracket)
- (string-match "^[\t ]*\\*" bracket))
- (setq bracket-level (+ bracket-level 1)))
- (t
- (setq bracket-level (- bracket-level tab-width)))))))
- bracket-level))
-
-(defun phps-mode-lex-analyzer--string-starts-with-closing-bracket-p (string)
- "Get bracket count for STRING."
- (string-match-p "^[\t ]*\\([\]})[]\\|</[a-zA-Z]+\\|/>\\)" string))
-
-(defun phps-mode-lex-analyzer--string-starts-with-opening-doc-comment-p
(string)
- "Does string start with opening doc comment?"
- (string-match-p "^[\t ]*/\\*\\*" string))
-
-(defun phps-mode-lex-analyzer--string-ends-with-opening-bracket-p (string)
- "Get bracket count for STRING."
- (string-match-p "\\([\[{(]\\|<[a-zA-Z]+\\)[\t ]*$" string))
-
-(defun phps-mode-lex-analyzer--string-ends-with-assignment-p (string)
- "Get bracket count for STRING."
- (string-match-p "=>?[\t ]*$" string))
-
-(defun phps-mode-lex-analyzer--string-ends-with-terminus-p (string)
- "Get bracket count for STRING."
- (string-match-p "\\(;\\|,\\)[\t ]*$" string))
-
(defun phps-mode-lex-analyzer--cancel-idle-timer ()
"Cancel idle timer."
(phps-mode-debug-message (message "Cancelled idle timer"))
diff --git a/phps-mode.el b/phps-mode.el
index a1727eff7d..246264fa88 100644
--- a/phps-mode.el
+++ b/phps-mode.el
@@ -48,6 +48,7 @@
;;; Code:
(require 'phps-mode-flymake)
+(require 'phps-mode-indent)
(require 'phps-mode-lex-analyzer)
(require 'phps-mode-syntax-table)
@@ -174,7 +175,7 @@
;; Indentation
;; Indent-region will call this on each line of selected region
- (setq-local indent-line-function #'phps-mode-lex-analyzer--indent-line)
+ (setq-local indent-line-function #'phps-mode-indent-line)
;; Custom Imenu
(setq-local imenu-create-index-function
#'phps-mode-lex-analyzer--imenu-create-index)
diff --git a/test/phps-mode-test-lex-analyzer.el
b/test/phps-mode-test-lex-analyzer.el
index c4fbd04700..5585f54ec3 100644
--- a/test/phps-mode-test-lex-analyzer.el
+++ b/test/phps-mode-test-lex-analyzer.el
@@ -1,30 +1,17 @@
-;;; phps-mode-test-lex-analyzer.el --- Tests for functions -*-
lexical-binding: t -*-
+;;; phps-mode-test-lex-analyzer.el --- Tests for lex-analyzer -*-
lexical-binding: t -*-
;; Copyright (C) 2018-2021 Free Software Foundation, Inc.
-;; This file is not part of GNU Emacs.
-
-;; This program is free software; you can redistribute it and/or
-;; modify it under the terms of the GNU General Public License as
-;; published by the Free Software Foundation; either version 2, or (at
-;; your option) any later version.
-
-;; This program is distributed in the hope that it will be useful, but
-;; WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-;; General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-
;;; Commentary:
-;; Run from terminal make functions-test
+
+;; Run from terminal make test-lex-analyzer
;;; Code:
+
(require 'ert)
(require 'phps-mode)
(require 'phps-mode-test)
@@ -59,790 +46,6 @@
)
-(defun phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer ()
- "Use alternative indentation of every line of buffer."
- (goto-char (point-min))
- (phps-mode-lex-analyzer--alternative-indentation)
- (while (search-forward "\n" nil t nil)
- (phps-mode-lex-analyzer--alternative-indentation)))
-
-(defun phps-mode-test-lex-analyzer--alternative-indentation ()
- "Test `phps-mode-lex-analyzer--alternative-indentation'."
-
- (phps-mode-test--with-buffer
- "<?php\nif ($myCondition) {\necho 'I was here';\n}"
- "Alternative indentation inside if block"
- (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer)
- (let ((buffer-contents (buffer-substring-no-properties (point-min)
(point-max))))
- (should (equal
- buffer-contents
- "<?php\nif ($myCondition) {\n echo 'I was here';\n}"))))
-
- (phps-mode-test--with-buffer
- "<?php\nif ($myCondition) {\necho 'I was here';\necho 'I was here
again';\n}"
- "Alternative indentation on closing if block"
- (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer)
- (let ((buffer-contents (buffer-substring-no-properties (point-min)
(point-max))))
- (should (equal
- buffer-contents
- "<?php\nif ($myCondition) {\n echo 'I was here';\n echo 'I
was here again';\n}"))))
-
- (phps-mode-test--with-buffer
- "<?php\nif ($test) {\nif ($test2) {\n\n}\n}"
- "Alternative indentation on nested if block with empty contents"
- (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer)
- (let ((buffer-contents (buffer-substring-no-properties (point-min)
(point-max))))
- (should (equal
- buffer-contents
- "<?php\nif ($test) {\n if ($test2) {\n \n }\n}"))))
-
- (phps-mode-test--with-buffer
- "<?php\nif ($test) {\nif ($test2) {\n\n}\n\n}"
- "Alternative indentation on multiple closing brackets"
- (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer)
- (let ((buffer-contents (buffer-substring-no-properties (point-min)
(point-max))))
- (should (equal
- buffer-contents
- "<?php\nif ($test) {\n if ($test2) {\n \n }\n
\n}"))))
-
- (phps-mode-test--with-buffer
- "<?php\nif ($test) {\n\n} else if ($test) {\n\n}\n"
- "Alternative indentation on elseif block"
- (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer)
- (let ((buffer-contents (buffer-substring-no-properties (point-min)
(point-max))))
- (should (equal
- buffer-contents
- "<?php\nif ($test) {\n \n} else if ($test) {\n \n}\n"))))
-
- (phps-mode-test--with-buffer
- "if ($true) {\nif ($true) {\n}\n}"
- "Alternative indentation on closing bracket inside parent bracket"
- (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer)
- (let ((buffer-contents (buffer-substring-no-properties (point-min)
(point-max))))
- (should (equal
- buffer-contents
- "if ($true) {\n if ($true) {\n }\n}"))))
-
- (phps-mode-test--with-buffer
- "/**\n*\n*/"
- "Alternative indentation on last line of doc comment block"
- (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer)
- (let ((buffer-contents (buffer-substring-no-properties (point-min)
(point-max))))
- (should (equal
- buffer-contents
- "/**\n *\n */"))))
-
- (phps-mode-test--with-buffer
- " $var = 'abc';\n // Comment"
- "Alternative indentation on single-line assignment"
- (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer)
- (let ((buffer-contents (buffer-substring-no-properties (point-min)
(point-max))))
- (should (equal
- buffer-contents
- "$var = 'abc';\n// Comment"))))
-
- (phps-mode-test--with-buffer
- "$var =\n'abc';\n$var =\n'abc'\n. 'def';\n// Comment\n"
- "Alternative indentation on multi-line assignment"
- (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer)
- (let ((buffer-contents (buffer-substring-no-properties (point-min)
(point-max))))
- (should (equal
- buffer-contents
- "$var =\n 'abc';\n$var =\n 'abc'\n . 'def';\n//
Comment\n"))))
-
- (phps-mode-test--with-buffer
- "<?php\nif ($here) {\nif ($wasHere)\n{\n\n}\n}\n\n"
- "Alternative indentation on line after condition"
- (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer)
- (let ((buffer-contents (buffer-substring-no-properties (point-min)
(point-max))))
- (should (equal
- buffer-contents
- "<?php\nif ($here) {\n if ($wasHere)\n {\n \n
}\n}\n\n"))))
-
- (phps-mode-test--with-buffer
- "<?php\nif ($myCondition)\n{\n$var = array(\n'was here'\n);\n// Was
here\n}\n"
- "Alternative indentation on line after array declaration"
- (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer)
- (let ((buffer-contents (buffer-substring-no-properties (point-min)
(point-max))))
- (should (equal
- buffer-contents
- "<?php\nif ($myCondition)\n{\n $var = array(\n 'was
here'\n );\n // Was here\n}\n"
- ))))
-
- (phps-mode-test--with-buffer
- "<?php\nif ($myCondition == 2) {\necho 'store_vars: <pre>' .
print_r($store_vars, true) . '</pre>';\necho 'search_ids: <pre>' .
print_r($search_ids, true) . '</pre>';\n}"
- "Alternative indentation on line echo"
- (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer)
- (let ((buffer-contents (buffer-substring-no-properties (point-min)
(point-max))))
- (should (equal
- buffer-contents
- "<?php\nif ($myCondition == 2) {\n echo 'store_vars: <pre>' .
print_r($store_vars, true) . '</pre>';\n echo 'search_ids: <pre>' .
print_r($search_ids, true) . '</pre>';\n}"
- ))))
-
- (phps-mode-test--with-buffer
- "<?php\nif (is_array(\n$array\n)) {\necho 'was here';\n}"
- "Alternative indentation after trailing opening bracket while closing two
earlier on line"
- (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer)
- (let ((buffer-contents (buffer-substring-no-properties (point-min)
(point-max))))
- (should (equal
- buffer-contents
- "<?php\nif (is_array(\n $array\n)) {\n echo 'was here';\n}"
- ))))
-
- (phps-mode-test--with-buffer
- "<?php\n\n$var = array(\n'123' =>\n'def',\n);"
- "Alternative indentation on lines after lines ending with T_DOUBLE_ARROW"
- (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer)
- (let ((buffer-contents (buffer-substring-no-properties (point-min)
(point-max))))
- (should (equal
- buffer-contents
- "<?php\n\n$var = array(\n '123' =>\n 'def',\n);"
- ))))
-
- (phps-mode-test--with-buffer
- "<?php\n$var = array(\n'123' => true,\n\n);"
- "Alternative indentation after comma ended double arrow assignment"
- (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer)
- (let ((buffer-contents (buffer-substring-no-properties (point-min)
(point-max))))
- (should (equal
- buffer-contents
- "<?php\n$var = array(\n '123' => true,\n \n);"
- ))))
-
- (phps-mode-test--with-buffer
- "<?php\nfunction myFunction(\n$arg = true,\n$arg2 = false\n) {\n\n}"
- "Line after function argument with default value"
- (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer)
- (let ((buffer-contents (buffer-substring-no-properties (point-min)
(point-max))))
- (should (equal
- buffer-contents
- "<?php\nfunction myFunction(\n $arg = true,\n $arg2 =
false\n) {\n \n}"
- ))))
-
- (phps-mode-test--with-buffer
- "$random = get_post_meta(\n $postId,\n '_random',
// TODO Here\n true // TODO Here\n );"
- "Line in multi-line function call"
- (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer)
- (let ((buffer-contents (buffer-substring-no-properties (point-min)
(point-max))))
- (should (equal
- buffer-contents
- "$random = get_post_meta(\n $postId,\n '_random', // TODO
Here\n true // TODO Here\n);"
- ))))
-
- (phps-mode-test--with-buffer
- "$cartPrice = round(\n $cartPrice,\n2 // TODO Here\n);"
- "Assignment with multi-line function call"
- (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer)
- (let ((buffer-contents (buffer-substring-no-properties (point-min)
(point-max))))
- (should (equal
- buffer-contents
- "$cartPrice = round(\n $cartPrice,\n 2 // TODO Here\n);"
- ))))
-
- (phps-mode-test--with-buffer
- "$applications =\n $transaction->getResponseBodyDecoded();\n // TODO
Here\n"
- "Line after multi-line assignment with object-operator"
- (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer)
- (let ((buffer-contents (buffer-substring-no-properties (point-min)
(point-max))))
- (should (equal
- buffer-contents
- "$applications =\n
$transaction->getResponseBodyDecoded();\n// TODO Here\n"
- ))))
-
- (phps-mode-test--with-buffer
- "<?php\necho '<dl><dt>' . __('Data', 'something')\n . ':</dt><dd><pre>'
. print_r($decodedData, true) . '</pre></dd></dl>';\necho '<div class=\"meta
actions\">';\n"
- "Two echo statements, one spans two lines"
- (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer)
- (let ((buffer-contents (buffer-substring-no-properties (point-min)
(point-max))))
- (should (equal
- buffer-contents
- "<?php\necho '<dl><dt>' . __('Data', 'something')\n .
':</dt><dd><pre>' . print_r($decodedData, true) . '</pre></dd></dl>';\necho
'<div class=\"meta actions\">';\n "
- ))))
-
- (phps-mode-test--with-buffer
- "<?php\nif ($shippingMethod->id ===\n \\MyClass::METHOD_ID\n )
{\n"
- "Multi-line if statement testing equality in two lines"
- (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer)
- (let ((buffer-contents (buffer-substring-no-properties (point-min)
(point-max))))
- (should (equal
- buffer-contents
- "<?php\nif ($shippingMethod->id ===\n \\MyClass::METHOD_ID\n)
{\n "
- ))))
-
- (phps-mode-test--with-buffer
- ""
- "Multi-line if block after opening parenthesis"
- (execute-kbd-macro "<?php")
- (execute-kbd-macro (kbd "<return>"))
- (execute-kbd-macro "if (true) {")
- (execute-kbd-macro (kbd "<return>"))
- (execute-kbd-macro "if (")
- (execute-kbd-macro (kbd "<return>"))
- (let ((buffer-contents
- (buffer-substring-no-properties
- (point-min)
- (point-max))))
- (should (equal
- buffer-contents
- "<?php\nif (true) {\n if (\n \n )\n}"
- ))))
-
- )
-
-(defun phps-mode-test-lex-analyzer--indent-should-equal (string name)
- "Test indent of whole buffer containing STRING with NAME."
- (phps-mode-test--with-buffer
- string
- name
- (phps-mode-test-lex-analyzer--alternative-indentation-whole-buffer)
- (let ((buffer-contents (buffer-substring-no-properties (point-min)
(point-max))))
- (should (equal
- buffer-contents
- string)))))
-
-(defun phps-mode-test-lex-analyzer--get-lines-indent ()
- "Test indent function."
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n/**\n * Bla\n */"
- "DOC-COMMENT")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nmyFunction(array(\n 23,\n [\n 25\n ]\n )\n);"
- "Round and square bracket expressions")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nvar_dump(array(<<<EOD\nfoobar!\nEOD\n));\n?>"
- "HEREDOC in arguments example")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$str = <<<'EOD'\nExample of string\nspanning multiple lines\nusing
nowdoc syntax.\nEOD;\n"
- "Multi-line NOWDOC string")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$var = \"A line\nmore text here\nlast line here\";"
- "Multi-line double-quoted string")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$var = 'A line\nmore text here\nlast line here';"
- "Multi-line single-quoted string")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\necho \"A line\" .\n \"more text here\" .\n \"last line
here\";"
- "Concatenated double-quoted-string spanning multiple-lines")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\necho myFunction(\"A line\" .\n \"more text here\" .\n \"last
line here\");"
- "Concatenated double-quoted-string spanning multiple-lines inside function")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\necho \"A line\"\n . \"more text here\"\n . \"last line
here\";"
- "Concatenated double-quoted-string spanning multiple-lines 2")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\necho myFunction(\"A line\" .\n \"more text here\" .\n \"last
line here\");"
- "Concatenated double-quoted-string spanning multiple-lines inside function
2")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\necho 'A line' .\n 'more text here' .\n 'last line here';"
- "Concatenated single-quoted-string spanning multiple-lines")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\necho myFunction('A line' .\n 'more text here' .\n 'last line
here');"
- "Concatenated single-quoted-string spanning multiple-lines inside function")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\necho 'A line'\n . 'more text here'\n . 'last line here';"
- "Concatenated single-quoted-string spanning multiple-lines 2")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\necho myFunction('A line'\n . 'more text here'\n . 'last line
here');"
- "Concatenated single-quoted-string spanning multiple-lines inside function
2")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\necho <<<EOD\nExample of string\nspanning multiple lines\nusing
heredoc syntax.\nEOD;\n"
- "Multi-line HEREDOC string outside assignment")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n/**\n * @var string\n */\necho 'was here';\n"
- "Statement after doc-comment")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n/** @define _SYSTEM_START_TIME_ Startup time for system
*/\ndefine('_SYSTEM_START_TIME_', microtime(true));\necho 'statement';\n"
- "Statement after a define() with a doc-comment")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nfunction myFunction($parameters = null)\n{\n echo
'statement';\n}\n"
- "Statement after one-lined function declaration with optional argument")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php if (true) { ?>\n <?php echo 'here'; ?>\n<?php } ?>"
- "Regular if-expression but inside scripting tags")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\ndo {\n echo 'true';\n} while ($number > 0\n && $letter >
0\n);"
- "Do while loop with multi-line condition")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\ndo {\n echo 'true';\n} while ($number > 0\n && $letter >
0\n);"
- "Do while loop with multi-line condition")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$myVar = 'blaha'\n . 'ijeije' . __(\n 'okeoke'\n ) .
'okeoke';\n?>"
- "Concatenated assignment string with function call")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$myVar = 'blaha'\n . 'ijeije' . __(\n 'okeoke'\n )\n
. 'okeoke';\n?>"
- "Concatenated assignment string with function call")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\necho 'blaha'\n . 'ijeije' . __(\n 'okeoke'\n ) .
'okeoke';\n?>"
- "Concatenated echo string with function call")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\necho 'blaha'\n . 'ijeije' . __(\n 'okeoke'\n )\n .
'okeoke';\n?>"
- "Concatenated echo string with function call")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$options = [\n 0 => [\n 'label' => __('No'),\n
'value' => 0,\n ],\n];"
- "Assignment with square bracketed array")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$options = array(\n 'blaha' .\n 'blaha',\n 123,\n
'blaha'\n);"
- "Assignment with square bracketed array")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nreturn $variable\n && $variable;"
- "Multi-line return statement")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$options = myFunction(\n array(array(\n 'options' =>
123\n ))\n);"
- "Assignment with double-dimensional array with double arrow assignment
inside function call")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nswitch ($condition) {\n case 34:\n if ($item['Random'] %
10 == 0) {\n $attributes['item'] = ($item['IntegerValue'] / 10);\n
} else {\n $attributes['item'] =\n
number_format(($item['IntegerValue'] / 10), 1, '.', '');\n }\n
break;\n}\n"
- "Switch case with conditional modulo expression")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$options = array(\n 'options' => array(array(\n
'errorTo'\n ))\n);"
- "Assignment with three-dimensional array with double arrow assignment")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nif ($myCondition) {\n $myObject->myMethod(myClass::class)\n
->myMethod2($myArgument2);\n }"
- "Object-oriented file with bracket-less namespace with multiple levels,
class that extends and implements and functions with optional arguments")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$myObj->myFunction()\n ->mySecondaryFunction();"
- "Indentation of chained class method calls outside of assignments and
conditionals")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n\n$myVar = $myClass->meMethod()\n ->mySecondMethod()\n
->myThirdMethod()\n->myFourthFunction(\n $myVariable\n);"
- "Indentation for chained object operators in assignment with method call
with arguments")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n\n$myResult = !empty($myVar->myMethod3)\n && $myVar->myMethod\n
&& $myVar->myMethod2;\n"
- "Indentation for chained object operators in assignment")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$array = [\n 'second' => [\n 'hello' => true\n
]\n];\n\n$array = array(\n 'second' => array(\n 'third' => true\n
)\n);"
- "Indent multi-dimensional arrays without trailing commas")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<html>\n <head>\n <?php echo $title; ?>\n </head>\n
<body>\n <?php\n\n if ($myTest) {\n doSomething();\n }\n\n
?>\n </body>\n</html>"
- "A mixed HTML and PHP file.")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n\n if ($fullInfo) $fullInfo = unserialize ($fullInfo);\n else
array();\n\n"
- "Indentation for single-line inline control structures.")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php
\n\nif (true) {\n // Was here\n}"
- "If condition after a mixed newline encoded file")
-
- )
-
-(defun phps-mode-test-lex-analyzer--get-lines-indent-psr-2 ()
- "Test PSR-2 examples from: https://www.php-fig.org/psr/psr-2/."
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nnamespace Vendor\\Package;\n\nuse FooInterface;\nuse BarClass as
Bar;\nuse OtherVendor\\OtherPackage\\BazClass;\n\nclass Foo extends Bar
implements FooInterface\n{\n public function sampleMethod($a, $b = null)\n
{\n if ($a === $b) {\n bar();\n } elseif ($a > $b)
{\n $foo->bar($arg1);\n } else {\n
BazClass::bar($arg2, $arg3);\n }\n }\n\n final public static
function bar()\n {\n // method body\n [...]
- "PSR-2 : 1.1. Example")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nnamespace Vendor\\Package;\n\nuse FooClass;\nuse BarClass as
Bar;\nuse OtherVendor\\OtherPackage\\BazClass;\n\n// ... additional PHP code
..."
- "PSR-2 : 3. Namespace and Use Declarations")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nnamespace Vendor\\Package;\n\nuse FooClass;\nuse BarClass as
Bar;\nuse OtherVendor\\OtherPackage\\BazClass;\n\nclass ClassName extends
ParentClass implements \\ArrayAccess, \\Countable\n{\n // constants,
properties, methods\n}"
- "PSR-2 : 4.1. Extends and Implements : Example 1")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nnamespace Vendor\\Package;\n\nuse FooClass;\nuse BarClass as
Bar;\nuse OtherVendor\\OtherPackage\\BazClass;\n\nclass ClassName extends
ParentClass implements\n \\ArrayAccess,\n \\Countable,\n
\\Serializable\n{\n // constants, properties, methods\n}"
- "PSR-2 : 4.1. Extends and Implements : Example 2")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nnamespace Vendor\\Package;\n\nclass ClassName\n{\n public $foo =
null;\n}"
- "PSR-2 : 4.2. Properties")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nnamespace Vendor\\Package;\n\nclass ClassName\n{\n public
function fooBarBaz($arg1, &$arg2, $arg3 = [])\n {\n // method body\n
}\n}"
- "PSR-2 : 4.3. Methods")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nnamespace Vendor\\Package;\n\nclass ClassName\n{\n public
function foo($arg1, &$arg2, $arg3 = [])\n {\n // method body\n
}\n}"
- "PSR-2 : 4.4. Method Arguments : Example 1")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nnamespace Vendor\\Package;\n\nclass ClassName\n{\n public
function aVeryLongMethodName(\n ClassTypeHint $arg1,\n &$arg2,\n
array $arg3 = []\n ) {\n // method body\n }\n}"
- "PSR-2 : 4.4. Method Arguments : Example 2")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nnamespace Vendor\\Package;\n\nabstract class ClassName\n{\n
protected static $foo;\n\n abstract protected function zim();\n\n final
public static function bar()\n {\n // method body\n }\n}"
- "PSR-2 ; 4.5. abstract, final, and static")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nbar();\n$foo->bar($arg1);\nFoo::bar($arg2, $arg3);"
- "PSR-2 : 4.6. Method and Function Calls : Example 1")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$foo->bar(\n $longArgument,\n $longerArgument,\n
$muchLongerArgument\n);"
- "PSR-2 : 4.6. Method and Function Calls : Example 2")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nif ($expr1) {\n // if body\n} elseif ($expr2) {\n // elseif
body\n} else {\n // else body;\n}"
- "PSR-2 : 5.1. if, elseif, else")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nswitch ($expr) {\n case 0:\n echo 'First case, with a
break';\n break;\n case 1:\n echo 'Second case, which falls
through';\n // no break\n case 2:\n case 3:\n case 4:\n
echo 'Third case, return instead of break';\n return;\n default:\n
echo 'Default case';\n break;\n}"
- "PSR-2 : 5.2. switch, case")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nwhile ($expr) {\n // structure body\n}"
- "PSR-2 : 5.3. while, do while : Example 1")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\ndo {\n // structure body;\n} while ($expr);"
- "PSR-2 : 5.3. while, do while : Example 2")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nfor ($i = 0; $i < 10; $i++) {\n // for body\n}"
- "PSR-2 : 5.4. for")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nforeach ($iterable as $key => $value) {\n // foreach body\n}"
- "PSR-2 : 5.5. foreach")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\ntry {\n // try body\n} catch (FirstExceptionType $e) {\n //
catch body\n} catch (OtherExceptionType $e) {\n // catch body\n}"
- "PSR-2 : 5.6. try, catch")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$closureWithArgs = function ($arg1, $arg2) {\n //
body\n};\n\n$closureWithArgsAndVars = function ($arg1, $arg2) use ($var1,
$var2) {\n // body\n};"
- "PSR-2 : 6. Closures : Example 1")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$longArgs_noVars = function (\n $longArgument,\n
$longerArgument,\n $muchLongerArgument\n) {\n //
body\n};\n\n$noArgs_longVars = function () use (\n $longVar1,\n
$longerVar2,\n $muchLongerVar3\n) {\n // body\n};\n\n$longArgs_longVars =
function (\n $longArgument,\n $longerArgument,\n
$muchLongerArgument\n) use (\n $longVar1,\n $longerVar2,\n
$muchLongerVar3\n) {\n // body\n};\n\n$longArgs_shortVars = function (\n
$longArgument,\n [...]
- "PSR-2 : 6. Closures : Example 2")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$foo->bar(\n $arg1,\n function ($arg2) use ($var1) {\n
// body\n },\n $arg3\n);"
- "PSR-2 : 6. Closures : Example 3")
-
- )
-
-(defun phps-mode-test-lex-analyzer--get-lines-indent-multi-line-assignments ()
- "Test for multi-line assignments."
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$variable = array(\n 'random4'\n);\n$variable = true;\n"
- "Array assignment on three lines")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$variable = array(\n 'random4' =>\n 'hello'\n);"
- "Array assignment with double arrow elements on four lines")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$variable = array(\n 'random4');\n$variable = true;\n"
- "Array assignment on two lines")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$var = 'A line' .\n 'more text here' .\n 'last line here';"
- "Concatenated single-quoted-string multiple-lines in assignment")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$var .=\n 'A line';"
- "Concatenated equal single-quoted-string on multiple-lines in assignment")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$var *=\n 25;"
- "Multiplication equal assignment on multiple-lines")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$str = <<<EOD\nExample of string\nspanning multiple lines\nusing
heredoc syntax.\nEOD;\n"
- "Multi-line HEREDOC string in assignment")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$var =\n 500 .\n \"200\" .\n 100.0 .\n '200' .\n
$this->getTail()\n ->getBottom();"
- "Multi-line assignments")
-
- )
-
-(defun phps-mode-test-lex-analyzer--get-lines-indent-inline-if ()
- "Test for inline if indentations."
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nif (true)\n echo 'Something';\nelse\n echo 'Something
else';\necho true;\n"
- "Inline control structures if else")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nif (true)\n echo 'Something';\nelse if (true)\n echo
'Something else';\necho true;\n"
- "Inline control structures if else if")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nwhile (true)\n echo 'Something';"
- "Inline control structures while")
-
- )
-
-(defun phps-mode-test-lex-analyzer--get-lines-indent-alternative-if ()
- "Test for alternative if indentations."
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nif (true):\n echo 'Something';\nelseif (true):\n echo
'Something';\nelse:\n echo 'Something else';\n echo 'Something else
again';\nendif;\necho true;\n"
- "Alternative control structures")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nif (true):\n echo 'Something';\nelseif (true\n && true\n):\n
echo 'Something';\nelse:\n echo 'Something else';\n echo 'Something
else again';\nendif;\necho true;\n"
- "Alternative control structures with multi-line elseif 1")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nif (true):\n echo 'Something';\nelseif (true\n && true):\n
echo 'Something';\nelse:\n echo 'Something else';\n echo 'Something else
again';\nendif;\necho true;\n"
- "Alternative control structures with multi-line elseif 2")
-
- )
-
-(defun phps-mode-test-lex-analyzer--get-lines-indent-classes ()
- "Test for class indent."
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nnamespace myNamespace\n{\n class myClass\n {\n public
function myFunction()\n {\n echo 'my statement';\n }\n
}\n}\n"
- "Regular PHP with namespaces, classes and functions")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nnamespace myNamespace\n{\n class myClass {\n public
function myFunction()\n {\n echo 'my statement';\n }\n
}\n}\n"
- "Regular PHP with namespaces, classes and functions")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nclass MyClass extends MyAbstract implements\n myInterface,\n
myInterface2\n{\n}\n"
- "Class multi-line implements")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nclass MyClass\n extends MyAbstract\n implements myInterface,
myInterface2\n{\n}\n"
- "Class multi-line extends and implements")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n/**\n *\n */\nnamespace Aomebo\n{\n /**\n *\n */\n
class Base\n {\n }\n}\n"
- "Namespace and class with doc-comments")
-
- )
-
-(defun phps-mode-test-lex-analyzer--get-lines-indent-if ()
- "Test for multi-line if expressions."
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nif (\n true\n && true\n) {\n echo 'was here';\n}\n"
- "If expression spanning multiple lines 1")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n// Can we load configuration?\nif ($configuration::load(\n
self::getParameter(self::PARAMETER_CONFIGURATION_INTERNAL_FILENAME),\n
self::getParameter(self::PARAMETER_CONFIGURATION_EXTERNAL_FILENAME),\n
self::getParameter(self::PARAMETER_STRUCTURE_INTERNAL_FILENAME),\n
self::getParameter(self::PARAMETER_STRUCTURE_EXTERNAL_FILENAME)\n)) {\n echo
'was here';\n}\n"
- "If expression spanning multiple lines 2")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nif (true) {\n if ($configuration::load(\n
self::getParameter(self::PARAMETER_CONFIGURATION_INTERNAL_FILENAME),\n
self::getParameter(self::PARAMETER_CONFIGURATION_EXTERNAL_FILENAME),\n
self::getParameter(self::PARAMETER_STRUCTURE_INTERNAL_FILENAME),\n
self::getParameter(self::PARAMETER_STRUCTURE_EXTERNAL_FILENAME))\n ) {\n
echo 'was here';\n }\n}\n"
- "If expression spanning multiple lines 3")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nif (myFunction(true)\n) {\n echo 'was here';\n}\n"
- "If expression spanning multiple lines 4")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nif (myFunction(\n true)\n) {\n echo 'was here';\n}\n"
- "If expression spanning multiple lines 5")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nif (true) {\n if (myFunction(\n true)\n ) {\n
echo 'was here';\n }\n}\n"
- "Nested if expression spanning multiple lines 6")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<html><head><title><?php if ($myCondition) {\n if ($mySeconCondition)
{\n echo $title2;\n\n } ?></title><body>Bla bla</body></html>"
- "Mixed HTML/PHP with if expression and token-less lines")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<html><head><title><?php\nif ($myCondition) {\n if ($mySecondCondition)
{\n echo $title;\n } else if ($mySecondCondition) {\n echo
$title4;\n } else {\n echo $title2;\n echo $title3;\n }\n}
?></title><body>Bla bla</body></html>"
- "Mixed HTML/PHP with if expression 2")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nif (myFirstCondition()) {\n $this->var = 'abc123';\n} else {\n
$this->var = 'def456';\n}\n"
- "Regular else expression indent calculation")
-
- )
-
-(defun phps-mode-test-lex-analyzer--get-lines-indent-switch-case ()
- "Test for switch-case indentation."
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nswitch ($condition) {\n case true:\n echo 'here';\n
echo 'here 2';\n case false:\n echo 'here 4';\n default:\n
echo 'here 3';\n}\n"
- "Switch, case, default")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nswitch ($condition):\n case true:\n echo 'here';\n
echo 'here 2';\n case false:\n echo 'here 4';\n default:\n
echo 'here 3';\nendswitch;\n"
- "Switch, case, default with alternative control structure")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nif (true) {\n switch ($condition):\n case true:\n
echo 'here';\n echo 'here 2';\n case false:\n
echo 'here 4';\n default:\n echo 'here 3';\n endswitch;\n
sprintf(__(\n 'Error: %s',\n $error\n ));\n}\n"
- "Alternative switch, case, default with exception after it")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nif (true) {\n switch ($condition) {\n case true:\n
echo 'here';\n echo 'here 2';\n case false:\n
echo 'here 4';\n default:\n echo 'here 3';\n }\n
sprintf(__(\n 'Error: %s',\n $error\n ));\n}\n"
- "Curly switch, case, default with exception after it")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$product_path = \"${filename[0]}/${filename[1]}/\";\necho 'here';\n"
- "Double-quoted string with multiple indexed variables in it")
-
- )
-
-(defun phps-mode-test-lex-analyzer--indent-line ()
- "Test for indentation."
-
- ;; Curly bracket tests
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<html><head><title><?php if ($myCondition) {\nif ($mySeconCondition) {\n
echo $title;\n\n} ?></title><body>Bla bla</body></html>"
- "Curly bracket test")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<html><head><title><?php if ($myCondition) {\nif ($mySeconCondition)
{\necho $title2;\n\n} ?></title><body>Bla bla</body></html>"
- "Curly bracket test 3")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<html><head><title><?php if ($myCondition) {\nif ($mySeconCondition)
{\necho $title3;\n\n}\n?>\n</title><body>Bla bla</body></html>"
- "Curly bracket test 4")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$variable = array(\n'random3'\n);\n$variable = true;\n"
- "Assignment test 1")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$variable = array(\n 'random2'\n );\n$variable = true;\n"
- "Assignment test 2")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n/**\n* My first line\n* My second line\n**/\n"
- "Doc-comment test 1")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n/**\n* My first line\n* My second line\n**/\n"
- "Doc-comment test 2")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n/**\n* My first line\n* My second line\n**/\n"
- "Doc-comment test 3")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$variable = array(\n 'random4');\n$variable = true;\n"
- "Round bracket test 1")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nadd_filter(\n\"views_{$screen->id}\",'__return_empty_array'\n);"
- "Round bracket test 2")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nif (random_expression(\ntrue\n)) {\nsome_logic_here();\n}"
- "Round bracket test 3")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nif (empty(\n$this->var\n) && !empty($this->var)\n) {\n$this->var =
'abc123';\n}\n"
- "Nested if-expression")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nif (myFirstCondition()) {\n $this->var = 'abc123';\n } else
{\n $this->var = 'def456';\n}\n"
- "Regular else expression")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nif (myFirstCondition()) {\n $this->var = 'abc123';\n } else
if (mySeconCondition()) {\n $this->var = 'def456';\n}\n"
- "Regular else if test")
-
- ;; Square bracket
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$var = [\n 'random' => [\n 'hello',\n],\n];\n"
- "Square bracket test 1")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nif (myRandomCondition()):\necho 'Something here';\n else:\n
echo 'Something else here 8';\nendif;\n"
- "Alternative else test")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nswitch (myRandomCondition()) {\ncase 'Something here':\necho
'Something else here';\n}\n"
- "Switch case indentation test")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nswitch (myRandomCondition()): \ncase 'Something here':\necho
'Something else here';\nendswitch;\n"
- "Alternative switch case indentation test 2")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nif (myRandomCondition())\necho 'Something here';\necho 'Something
else here';\n"
- "Inline control structure indentation")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nif (myRandomCondition())\n echo 'Something here';\n echo
'Something else here';\n"
- "Inline control structure indentation 2")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nif (myRandomCondition()):\necho 'Something here';\n echo
'Something else here';\nendif;\n"
- "Alternative control structure indentation 1")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nmyFunction(\n array(\n 'random' => 'abc',\n ),\n
$var5\n);\n"
- "Function arguments with associate array indentation")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$var = $var2->getHead()\n->getTail();\n"
- "Multi-line assignment indentation test 1")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n$var =\n'random string';\n"
- "Single-line assignment indentation test")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nif (empty($this->var)):\n$this->var = 'abc123';\n endif;"
- "Alternative control structure if expression")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nif (empty($this->var)):\n$this->var = 'abc123';\nendif;"
- "Alternative control structure test")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<html>\n<head>\n<title><?php echo $title;
?></title>\n</head>\n<body>\n<div class=\"contents\"><?php echo $body;
?></div>\n</body>\n</html>"
- "A mixed HTML and PHP file, each PHP command is inside HTML markup")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<html>\n<head>\n<title><?php echo $title; ?></title>\n</head>\n<body
class=\"<?php echo $class; ?>\">\n<div class=\"contents\"><?php echo $body;
?></div>\n</body>\n</html>"
- "A mixed HTML and PHP file, each PHP command is inside HTML markup, one PHP
inside markup tag")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<html>\n <head>\n <title><?php $myTitle; ?></title>\n
</head>\n <body>\n <?php echo 'test'; ?>\n <h1>My title</h1>\n
<?php if ($myTest): ?>\n <div>\n A lot of other
stuff.\n </div>\n <?php endif; ?>\n </body>\n</html>"
- "Indent mixed HTML and one-line PHP lines.")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\nif ($here) {\n $var = \"abc $b[abc] def\";\n// Was here\n}\n\n"
- "Indentation after line with square brackets inside double quoted string")
-
- (phps-mode-test-lex-analyzer--indent-should-equal
- "<?php\n\n// Adjust days to delivery accorind to document\nswitch
($dayOfWeek)\n{\n case 1: // Monday\n case 2: // Tuesday\n case 3: //
Wednesday\n case 7: // Sunday\n $daysToDelivery = 3;\n
break;\n case 4: // Thursday\n case 5: // Friday\n $daysToDelivery
= 5;\n break;\n case 6: // Saturday\n $daysToDelivery = 4;\n
break;\n default:\n throw new \Exception(sprintf(\n
'day of week above interval (1-7): [...]
- "Switch case with default case and trailing comments")
-
- )
-
(defun phps-mode-test-lex-analyzer--get-moved-imenu ()
"Test for moving imenu index."
@@ -949,86 +152,10 @@
)
-(defun phps-mode-test-lex-analyzer--get-inline-html-indentation ()
- "Test function."
-
- (should (equal
- '(0 1 2 1 1 2 1 0)
- (nth 0 (phps-mode-lex-analyzer--get-inline-html-indentation
-
"<html>\n<head>\n<title>MyTitle</title>\n</head>\n<body>\n<p>My
paragraph</p>\n</body>\n</html>"
- 0
- 0
- 0
- 0
- 0
- ))))
-
- (should (equal
- '(2 2 1 0)
- (nth 0 (phps-mode-lex-analyzer--get-inline-html-indentation
- "\n<p>My paragraph</p>\n</body>\n</html>"
- 2
- 2
- 0
- 0
- 0
- ))))
-
- (should (equal
- '(0)
- (nth 0 (phps-mode-lex-analyzer--get-inline-html-indentation
- "<html>"
- 0
- 0
- 0
- 0
- 0
- ))))
-
- (should (equal
- '(0 1 2 1 0)
- (nth 0 (phps-mode-lex-analyzer--get-inline-html-indentation
- "<script type=\"text/javascript\">\n if (something())
{\n alert('Something here');\n }\n</script>\n"
- 0
- 0
- 0
- 0
- 0
- ))))
-
- )
-
-(defun phps-mode-test-lex-analyzer--parse-string ()
- "Test the parser."
-
- (should
- (equal
- '(80 459 466 411 333 332 154 102 79)
- (car (car (cdr (phps-mode-lex-analyzer--lex-string
- "<?php echo 'abc';"))))))
- (message "Passed valid parse test")
-
- (should-error
- (phps-mode-lex-analyzer--lex-string
- "<?php echo 'abc'"))
- (message "Passed error parse test")
- )
-
(defun phps-mode-test-lex-analyzer ()
"Run test for functions."
;; (setq debug-on-error t)
(phps-mode-test-lex-analyzer--process-changes)
- (phps-mode-test-lex-analyzer--alternative-indentation)
- (phps-mode-test-lex-analyzer--get-inline-html-indentation)
- (phps-mode-test-lex-analyzer--get-lines-indent-if)
- (phps-mode-test-lex-analyzer--get-lines-indent-classes)
- (phps-mode-test-lex-analyzer--get-lines-indent-inline-if)
- (phps-mode-test-lex-analyzer--get-lines-indent-alternative-if)
- (phps-mode-test-lex-analyzer--get-lines-indent-multi-line-assignments)
- (phps-mode-test-lex-analyzer--get-lines-indent-switch-case)
- (phps-mode-test-lex-analyzer--get-lines-indent-psr-2)
- (phps-mode-test-lex-analyzer--get-lines-indent)
- (phps-mode-test-lex-analyzer--indent-line)
(phps-mode-test-lex-analyzer--get-moved-imenu)
(phps-mode-test-lex-analyzer--comment-uncomment-region))
- [elpa] externals/phps-mode d9115ec583 069/212: Cleaned up AST bookkeeping tests, (continued)
- [elpa] externals/phps-mode d9115ec583 069/212: Cleaned up AST bookkeeping tests, Christian Johansson, 2022/01/26
- [elpa] externals/phps-mode f4d2164f8b 067/212: Bookkeeping via parser SDT passing static variables in function, Christian Johansson, 2022/01/26
- [elpa] externals/phps-mode e66abd00e5 064/212: Bookkeeping via AST passing nested isset() !empty() expressions, Christian Johansson, 2022/01/26
- [elpa] externals/phps-mode 8b5ce22d87 072/212: Fixed issue with SDT for return statement, Christian Johansson, 2022/01/26
- [elpa] externals/phps-mode 491c82a2a1 071/212: Added TODO item for bookkeeping via AST, Christian Johansson, 2022/01/26
- [elpa] externals/phps-mode 5ec32f5f5a 076/212: Bookkeeping via AST passing all tests, Christian Johansson, 2022/01/26
- [elpa] externals/phps-mode 228f212127 080/212: Starting on removing the old process tokens in string function, Christian Johansson, 2022/01/26
- [elpa] externals/phps-mode 5b1f5b4774 079/212: Improved format of SDT, Christian Johansson, 2022/01/26
- [elpa] externals/phps-mode 3f3a8bb0fa 081/212: Major refactor of indent tests, Christian Johansson, 2022/01/26
- [elpa] externals/phps-mode b469f0ffbb 088/212: Passing indentation for multi-line class implements, Christian Johansson, 2022/01/26
- [elpa] externals/phps-mode f69df4fdf6 083/212: Moved indentation to separate file and test,
Christian Johansson <=
- [elpa] externals/phps-mode 481deb6331 082/212: More work on indentation, Christian Johansson, 2022/01/26
- [elpa] externals/phps-mode fe9cb90c44 097/212: Passing indent test for some multi-line assignments, Christian Johansson, 2022/01/26
- [elpa] externals/phps-mode c9f715a1fd 093/212: Improved comments, Christian Johansson, 2022/01/26
- [elpa] externals/phps-mode f0ab7a2cdb 095/212: Passed tests for inline control structures, Christian Johansson, 2022/01/26
- [elpa] externals/phps-mode 08f57c1d36 107/212: Added TODO item for indent, Christian Johansson, 2022/01/26
- [elpa] externals/phps-mode 3853ddf32a 099/212: Passed another concatenation test for indentation, Christian Johansson, 2022/01/26
- [elpa] externals/phps-mode 1ed09d42f5 111/212: Passing another indent test, Christian Johansson, 2022/01/26
- [elpa] externals/phps-mode d205d8392f 113/212: Passed another indent test, Christian Johansson, 2022/01/26
- [elpa] externals/phps-mode 1a62f48783 130/212: Improved indentation in cases with multi-expressions last line does not start with closing bracket, Christian Johansson, 2022/01/26
- [elpa] externals/phps-mode a3b9559880 121/212: Improved indent support for nested switch case, Christian Johansson, 2022/01/26