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

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

[elpa] externals/phps-mode c48b8f3265 1/2: Improved support for new PHP


From: Christian Johansson
Subject: [elpa] externals/phps-mode c48b8f3265 1/2: Improved support for new PHP 7.3 HEREDOC and NOWDOC formats
Date: Thu, 3 Nov 2022 01:38:49 -0400 (EDT)

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

    Improved support for new PHP 7.3 HEREDOC and NOWDOC formats
---
 phps-mode-lexer.el           | 15 +++------
 test/phps-mode-test-lexer.el | 80 +++++++++++++++++++++++++++++++++-----------
 2 files changed, 65 insertions(+), 30 deletions(-)

diff --git a/phps-mode-lexer.el b/phps-mode-lexer.el
index 6754ce5cc1..637e906821 100644
--- a/phps-mode-lexer.el
+++ b/phps-mode-lexer.el
@@ -124,13 +124,10 @@
 (defvar phps-mode-lexer--lambdas-by-state #s(hash-table size 65 test equal 
rehash-size 1.5 rehash-threshold 0.8125 data (ST_IN_SCRIPTING (((lambda nil 
(looking-at "exit")) (lambda nil (phps-mode-lexer--return-token-with-indent 
'T_EXIT))) ((lambda nil (looking-at "die")) (lambda nil 
(phps-mode-lexer--return-token-with-indent 'T_EXIT))) ((lambda nil (looking-at 
"fn")) (lambda nil (phps-mode-lexer--return-token-with-indent 'T_FN))) ((lambda 
nil (looking-at "function")) (lambda nil (phps-mod [...]
 
        ]*("))) (lambda nil (phps-mode-lexer--yyless (length "readonly")) 
(phps-mode-lexer--return-token-with-str 'T_STRING 0))) ((lambda nil (looking-at 
"unset")) (lambda nil (phps-mode-lexer--return-token-with-indent 'T_UNSET))) 
((lambda nil (looking-at "=>")) (lambda nil (phps-mode-lexer--return-token 
'T_DOUBLE_ARROW))) ((lambda nil (looking-at "list")) (lambda nil 
(phps-mode-lexer--return-token-with-indent 'T_LIST))) ((lambda nil (looking-at 
"array")) (lambda nil (phps-mode-lexer--return-tok [...]
 ]*" "\\(\\$\\|\\.\\.\\.\\)"))) (lambda nil (phps-mode-lexer--yyless 1) 
(phps-mode-lexer--return-token 'T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG 
(match-beginning 0) (- (match-end 0) 1)))) ((lambda nil (looking-at "&")) 
(lambda nil (phps-mode-lexer--return-token 
'T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG))) ((lambda nil (looking-at (concat 
"\\(" "]" "\\|" ")" "\\)"))) (lambda nil 
(phps-mode-lexer--return-exit-nesting-token))) ((lambda nil (looking-at (concat 
"\\(" "\\[" "\\|" "(" "\\)"))) (la [...]
-[       ]*" phps-mode-lexer--heredoc-label ";?
-\\|\\$" phps-mode-lexer--label "\\|{\\$" phps-mode-lexer--label "\\|\\${" 
phps-mode-lexer--label "\\)") nil t))) (if string-start (let* ((start 
(match-beginning 0)) (end (match-end 0)) (data (buffer-substring-no-properties 
start end))) (cond ((string-match-p (concat "
-[       ]*" phps-mode-lexer--heredoc-label ";?
-") data) (phps-mode-lexer--return-token-with-val 'T_ENCAPSED_AND_WHITESPACE 
old-end start) (phps-mode-lexer--begin 'ST_END_HEREDOC)) (t 
(phps-mode-lexer--return-token-with-val 'T_ENCAPSED_AND_WHITESPACE old-end 
start)))) (progn (signal 'phps-lexer-error (list (format "Found no ending of 
heredoc starting at %d" old-start) old-start))))))))) ST_LOOKING_FOR_VARNAME 
(((lambda nil (looking-at (concat phps-mode-lexer--label "[\\[}]"))) (lambda 
nil (let* ((start (match-beginning 0)) (end (1- (m [...]
+[       ]*" phps-mode-lexer--heredoc-label "\\|\\$" phps-mode-lexer--label 
"\\|{\\$" phps-mode-lexer--label "\\|\\${" phps-mode-lexer--label "\\)") nil 
t))) (if string-start (let* ((start (match-beginning 0)) (end (match-end 0)) 
(data (buffer-substring-no-properties start end))) (cond ((string-match-p 
(concat "
+[       ]*" phps-mode-lexer--heredoc-label) data) 
(phps-mode-lexer--return-token-with-val 'T_ENCAPSED_AND_WHITESPACE old-end 
start) (phps-mode-lexer--begin 'ST_END_HEREDOC)) (t 
(phps-mode-lexer--return-token-with-val 'T_ENCAPSED_AND_WHITESPACE old-end 
start)))) (progn (signal 'phps-lexer-error (list (format "Found no ending of 
heredoc starting at %d" old-start) old-start))))))))) ST_LOOKING_FOR_VARNAME 
(((lambda nil (looking-at (concat phps-mode-lexer--label "[\\[}]"))) (lambda 
nil (let* ((st [...]
 
        '#]"))) (lambda nil (phps-mode-lexer--yyless 0) 
(phps-mode-lexer--yy-pop-state) (phps-mode-lexer--return-token-with-val 
'T_ENCAPSED_AND_WHITESPACE))) ((lambda nil (looking-at phps-mode-lexer--label)) 
(lambda nil (phps-mode-lexer--return-token-with-str 'T_STRING 0))) ((lambda nil 
(looking-at phps-mode-lexer--any-char)) (lambda nil (signal 'phps-lexer-error 
(list (format "Unexpected character at %d" (match-beginning 0)) 
(match-beginning 0)))))) quote (((lambda nil (looking-at (concat "#!.* [...]
-[       ]*" phps-mode-lexer--heredoc-label ";?\\
-") nil t))) (if string-start (let* ((start (match-beginning 0)) (end 
(match-end 0)) (_data (buffer-substring-no-properties start end))) 
(phps-mode-lexer--return-token-with-val 'T_ENCAPSED_AND_WHITESPACE 
phps-mode-lexer--generated-new-tokens-index start) (phps-mode-lexer--begin 
'ST_END_HEREDOC)) (progn (signal 'phps-lexer-error (list (format "Found no 
ending of nowdoc starting at %d" start) start)))))))))))
+[       ]*" phps-mode-lexer--heredoc-label) nil t))) (if string-start (let* 
((start (match-beginning 0)) (end (match-end 0)) (_data 
(buffer-substring-no-properties start end))) 
(phps-mode-lexer--return-token-with-val 'T_ENCAPSED_AND_WHITESPACE 
phps-mode-lexer--generated-new-tokens-index start) (phps-mode-lexer--begin 
'ST_END_HEREDOC)) (progn (signal 'phps-lexer-error (list (format "Found no 
ending of nowdoc starting at %d" start) start)))))))))))
   "Hash-table of lex-analyzer rules organized by state.")
 
 (defvar-local phps-mode-lexer--generated-tokens nil
@@ -1892,7 +1889,7 @@
              (concat
               "\\(\n[\t ]*"
               phps-mode-lexer--heredoc-label
-              ";?\n\\|\\$"
+              "\\|\\$"
               phps-mode-lexer--label
               "\\|{\\$"
               phps-mode-lexer--label
@@ -1913,7 +1910,6 @@
                 (concat
                  "\n[\t ]*"
                  phps-mode-lexer--heredoc-label
-                 ";?\n"
                  )
                 data)
                ;; (message "Found heredoc end at %s-%s" start end)
@@ -1947,8 +1943,7 @@
             (search-forward-regexp
              (concat
               "\n[\t ]*"
-              phps-mode-lexer--heredoc-label
-              ";?\\\n")
+              phps-mode-lexer--heredoc-label)
              nil
              t)))
        (if string-start
diff --git a/test/phps-mode-test-lexer.el b/test/phps-mode-test-lexer.el
index 32a5911a0d..e8de0e6e13 100644
--- a/test/phps-mode-test-lexer.el
+++ b/test/phps-mode-test-lexer.el
@@ -380,10 +380,57 @@
 
   ;; HEREDOC
 
+  (phps-mode-test--with-buffer
+   "<?php\n// no indentation\necho <<<END\n      a\n     b\n    
c\n\n\nEND;\n\n// 4 spaces of indentation\necho <<<END\n      a\n     b\n    
c\n    END;\n"
+   "Example #1 Basic Heredoc example as of PHP 7.3.0"
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_COMMENT 7 . 24) (T_ECHO 25 . 29) (T_START_HEREDOC 
30 . 37) (T_ENCAPSED_AND_WHITESPACE 37 . 59) (T_END_HEREDOC 59 . 63) (";" 63 . 
64) (T_COMMENT 66 . 92) (T_ECHO 93 . 97) (T_START_HEREDOC 98 . 105) 
(T_ENCAPSED_AND_WHITESPACE 105 . 125) (T_END_HEREDOC 125 . 129) (T_STRING 130 . 
133) (";" 133 . 134)))))
+
+  (phps-mode-test--with-buffer
+   "<?php\necho <<<END\n  a\n b\nc\n   END;\n"
+   "Example #2 Closing identifier must not be indented further than any lines 
of the body"
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) (T_START_HEREDOC 12 . 19) 
(T_ENCAPSED_AND_WHITESPACE 19 . 27) (T_END_HEREDOC 27 . 31) (T_STRING 31 . 34) 
(";" 34 . 35)))))
+
+  (phps-mode-test--with-buffer
+   "<?php\n// All the following code do not work.\n\n// different indentation 
for body (spaces) ending marker (tabs)\n{\n    echo <<<END\n     a\n        
END;\n\n\n// mixing spaces and tabs in body\n{\n    echo <<<END\n        a\n    
 END;\n\n\n// mixing spaces and tabs in ending marker\n{\n    echo <<<END\n     
     a\n         END;\n\n"
+   "Example #3 Different indentation for body (spaces) closing identifier"
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_COMMENT 7 . 45) (T_COMMENT 47 . 110) ("{" 111 . 
112) (T_ECHO 117 . 121) (T_START_HEREDOC 122 . 129) (T_ENCAPSED_AND_WHITESPACE 
129 . 135) (T_END_HEREDOC 135 . 139) (T_STRING 144 . 147) (";" 147 . 148) 
(T_COMMENT 151 . 184) ("{" 185 . 186) (T_ECHO 191 . 195) (T_START_HEREDOC 196 . 
203) (T_ENCAPSED_AND_WHITESPACE 203 . 212) (T_END_HEREDOC 212 . 216) (T_STRING 
218 . 221) (";" 221 . 222) (T_COMMENT 225 . 267) ("{" 268 . 269) (T_ECHO 274 . 
278) (T_START_HEREDOC 27 [...]
+
+  (phps-mode-test--with-buffer
+   "<?php\n$values = [<<<END\na\n  b\n    c\nEND, 'd e 
f'];\nvar_dump($values);\n"
+   "Example #4 Continuing an expression after a closing identifier"
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 14) ("=" 15 . 16) ("[" 17 . 18) 
(T_START_HEREDOC 18 . 25) (T_ENCAPSED_AND_WHITESPACE 25 . 36) (T_END_HEREDOC 36 
. 40) ("," 40 . 41) (T_CONSTANT_ENCAPSED_STRING 42 . 49) ("]" 49 . 50) (";" 50 
. 51) (T_STRING 52 . 60) ("(" 60 . 61) (T_VARIABLE 61 . 68) (")" 68 . 69) (";" 
69 . 70)))))
+
+  (phps-mode-test--with-buffer
+   "<?php\n$values = [<<<END\na\nb\nEND ING\nEND, 'd e f'];\n"
+   "Example #5 Closing identifier in body of the string tends to cause 
ParseError"
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_VARIABLE 7 . 14) ("=" 15 . 16) ("[" 17 . 18) 
(T_START_HEREDOC 18 . 25) (T_ENCAPSED_AND_WHITESPACE 25 . 28) (T_END_HEREDOC 28 
. 32) (T_STRING 33 . 36) (T_STRING 37 . 40) ("," 40 . 41) 
(T_CONSTANT_ENCAPSED_STRING 42 . 49) ("]" 49 . 50) (";" 50 . 51)))))
+
+  (phps-mode-test--with-buffer
+   "<?php\nclass foo {\n    public $bar = <<<EOT\nbar\n    EOT;\n}\n// 
Identifier must not be indented\n?>\n"
+   "Example #6 Invalid example, prior to PHP 7.3.0"
+   (should
+    (equal
+     phps-mode-lex-analyzer--tokens
+     '((T_OPEN_TAG 1 . 7) (T_CLASS 7 . 12) (T_STRING 13 . 16) ("{" 17 . 18) 
(T_PUBLIC 23 . 29) (T_VARIABLE 30 . 34) ("=" 35 . 36) (T_START_HEREDOC 37 . 44) 
(T_ENCAPSED_AND_WHITESPACE 44 . 47) (T_END_HEREDOC 47 . 51) (T_STRING 52 . 55) 
(";" 55 . 56) ("}" 57 . 58) (T_COMMENT 59 . 93) (T_CLOSE_TAG 94 . 96) 
(T_INLINE_HTML 96 . 97)))))
+
   (phps-mode-test--with-buffer
    "<?php\nclass foo {\n    public $bar = <<<EOT\nbar\nEOT;\n}\n?>\n"
-   "Example #2 Valid example (HEREDOC)"
-   ;; (message "tokens: %s" phps-mode-lex-analyzer--tokens)
+   "Example #7 Valid example, even if prior to PHP 7.3.0"
    (should
     (equal
      phps-mode-lex-analyzer--tokens
@@ -391,7 +438,7 @@
 
   (phps-mode-test--with-buffer
    "<?php\n$str = <<<EOD\nExample of string\nspanning multiple lines\nusing 
heredoc syntax.\nEOD;\n\n/* More complex example, with variables. */\nclass 
foo\n{\n    var $foo;\n    var $bar;\n\n    function __construct()\n    {\n     
   $this->foo = 'Foo';\n        $this->bar = array('Bar1', 'Bar2', 'Bar3');\n   
 }\n}\n\n$foo = new foo();\n$name = 'MyName';\n\necho <<<EOT\nMy name is 
\"$name\". I am printing some $foo->foo.\nNow, I am printing some 
{$foo->bar[1]}.\nThis should print a capi [...]
-   "Example #3 Heredoc string quoting example"
+   "Example #8 Heredoc string quoting example"
    (should
     (equal
      phps-mode-lex-analyzer--tokens
@@ -399,7 +446,7 @@
 
   (phps-mode-test--with-buffer
    "<?php\nvar_dump(array(<<<EOD\nfoobar!\nEOD\n));\n?>\n"
-   "Example #4 Heredoc in arguments example"
+   "Example #9 Heredoc in arguments example"
    (should
     (equal
      phps-mode-lex-analyzer--tokens
@@ -407,41 +454,34 @@
 
   (phps-mode-test--with-buffer
    "<?php\n// Static variables\nfunction foo()\n{\n    static $bar = 
<<<LABEL\nNothing in here...\nLABEL;\n}\n\n// Class properties/constants\nclass 
foo\n{\n    const BAR = <<<FOOBAR\nConstant example\nFOOBAR;\n\n    public $baz 
= <<<FOOBAR\nProperty example\nFOOBAR;\n}\n?>\n"
-   "Example #5 Using Heredoc to initialize static values"
+   "Example #10 Using Heredoc to initialize static values"
    (should
     (equal
      phps-mode-lex-analyzer--tokens
      '((T_OPEN_TAG 1 . 7) (T_COMMENT 7 . 26) (T_FUNCTION 27 . 35) (T_STRING 36 
. 39) ("(" 39 . 40) (")" 40 . 41) ("{" 42 . 43) (T_STATIC 48 . 54) (T_VARIABLE 
55 . 59) ("=" 60 . 61) (T_START_HEREDOC 62 . 71) (T_ENCAPSED_AND_WHITESPACE 71 
. 89) (T_END_HEREDOC 89 . 95) (";" 95 . 96) ("}" 97 . 98) (T_COMMENT 100 . 129) 
(T_CLASS 130 . 135) (T_STRING 136 . 139) ("{" 140 . 141) (T_CONST 146 . 151) 
(T_STRING 152 . 155) ("=" 156 . 157) (T_START_HEREDOC 158 . 168) 
(T_ENCAPSED_AND_WHITESPACE 168 .  [...]
 
   (phps-mode-test--with-buffer
-   "<?php\necho <<<\"FOOBAR\"\nHello World!\nFOOBAR;\n?>\n"
-   "Example #6 Using double quotes in Heredoc"
+   "\n<?php\necho <<<\"FOOBAR\"\nHello World!\nFOOBAR;\n?>\n"
+   "Example #11 Using double quotes in Heredoc"
    (should
     (equal
      phps-mode-lex-analyzer--tokens
-     '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) (T_START_HEREDOC 12 . 24) 
(T_ENCAPSED_AND_WHITESPACE 24 . 36) (T_END_HEREDOC 36 . 43) (";" 43 . 44) 
(T_CLOSE_TAG 45 . 47) (T_INLINE_HTML 47 . 48)))))
+     '((T_INLINE_HTML 1 . 2) (T_OPEN_TAG 2 . 8) (T_ECHO 8 . 12) 
(T_START_HEREDOC 13 . 25) (T_ENCAPSED_AND_WHITESPACE 25 . 37) (T_END_HEREDOC 37 
. 44) (";" 44 . 45) (T_CLOSE_TAG 46 . 48) (T_INLINE_HTML 48 . 49)))))
 
-  (phps-mode-test--with-buffer
-   "<?php\n\nclass MyClass\n{\n    public const MY_CONSTANT = <<<DELIMITER\n   
 {\n        some {\n            json\n        }\n    }\n    DELIMITER;\n}\n"
-   "Heredoc where ending delimiter is not first on line (PHP > 7.3)"
-   (should
-    (equal
-     phps-mode-lex-analyzer--tokens
-     '((T_OPEN_TAG 1 . 7) (T_CLASS 8 . 13) (T_STRING 14 . 21) ("{" 22 . 23) 
(T_PUBLIC 28 . 34) (T_CONST 35 . 40) (T_STRING 41 . 52) ("=" 53 . 54) 
(T_START_HEREDOC 55 . 68) (T_ENCAPSED_AND_WHITESPACE 68 . 121) (T_END_HEREDOC 
121 . 131) (T_STRING 131 . 135) (";" 135 . 136) ("}" 137 . 138)))))
 
   ;; NOWDOC
 
   (phps-mode-test--with-buffer
-   "<?php\necho <<<'EOD'\nExample of string spanning multiple lines\nusing 
nowdoc syntax. Backslashes are always treated literally,\ne.g. \\ and 
\'.\nEOD;\n"
-   "Example #7 Nowdoc string quoting example"
+   "<?php\necho <<<'EOD'\nExample of string spanning multiple lines\nusing 
nowdoc syntax. Backslashes are always treated literally,\ne.g. \\ and 
\\'.\nEOD;\n"
+   "Example #12 Nowdoc string quoting example"
    (should
     (equal
      phps-mode-lex-analyzer--tokens
-     '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) (T_START_HEREDOC 12 . 21) 
(T_ENCAPSED_AND_WHITESPACE 21 . 139) (T_END_HEREDOC 139 . 143) (";" 143 . 
144)))))
+     '((T_OPEN_TAG 1 . 7) (T_ECHO 7 . 11) (T_START_HEREDOC 12 . 21) 
(T_ENCAPSED_AND_WHITESPACE 21 . 140) (T_END_HEREDOC 140 . 144) (";" 144 . 
145)))))
 
   (phps-mode-test--with-buffer
    "<?php\nclass foo\n{\n    public $foo;\n    public $bar;\n\n    function 
__construct()\n    {\n        $this->foo = 'Foo';\n        $this->bar = 
array('Bar1', 'Bar2', 'Bar3');\n    }\n}\n\n$foo = new foo();\n$name = 
'MyName';\n\necho <<<'EOT'\nMy name is \"$name\". I am printing some 
$foo->foo.\nNow, I am printing some {$foo->bar[1]}.\nThis should not print a 
capital 'A': \x41\nEOT;\n?>\n"
-   "Example #8 Nowdoc string quoting example with variables"
+   "Example #13 Nowdoc string quoting example with variables"
    (should
     (equal
      phps-mode-lex-analyzer--tokens
@@ -449,7 +489,7 @@
 
   (phps-mode-test--with-buffer
    "<?php\nclass foo {\n    public $bar = <<<'EOT'\nbar\nEOT;\n}\n?>\n"
-   "Example #9 Static data example (Nowdoc)"
+   "Example #14 Static data example"
    (should
     (equal
      phps-mode-lex-analyzer--tokens



reply via email to

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