@vituum/vite-plugin-latte 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +2 -2
- package/latte/PlaceholderFunction.php +2 -2
- package/package.json +10 -11
- package/vendor/autoload.php +18 -0
- package/vendor/bin/latte-lint +16 -4
- package/vendor/composer/ClassLoader.php +72 -65
- package/vendor/composer/InstalledVersions.php +21 -12
- package/vendor/composer/autoload_classmap.php +14 -8
- package/vendor/composer/autoload_namespaces.php +1 -1
- package/vendor/composer/autoload_psr4.php +1 -1
- package/vendor/composer/autoload_real.php +3 -22
- package/vendor/composer/autoload_static.php +13 -7
- package/vendor/composer/installed.json +8 -8
- package/vendor/composer/installed.php +10 -10
- package/vendor/latte/latte/bin/latte-lint +8 -2
- package/vendor/latte/latte/composer.json +1 -1
- package/vendor/latte/latte/readme.md +6 -6
- package/vendor/latte/latte/src/Bridges/Tracy/BlueScreenPanel.php +1 -0
- package/vendor/latte/latte/src/Bridges/Tracy/LattePanel.php +3 -2
- package/vendor/latte/latte/src/Latte/Compiler/Block.php +0 -3
- package/vendor/latte/latte/src/Latte/Compiler/Escaper.php +113 -89
- package/vendor/latte/latte/src/Latte/Compiler/ExpressionBuilder.php +2 -1
- package/vendor/latte/latte/src/Latte/Compiler/Node.php +0 -4
- package/vendor/latte/latte/src/Latte/Compiler/NodeHelpers.php +0 -4
- package/vendor/latte/latte/src/Latte/Compiler/NodeTraverser.php +0 -4
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/AuxiliaryNode.php +11 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/FragmentNode.php +10 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/AttributeNode.php +22 -4
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ElementNode.php +35 -12
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ArgumentNode.php +6 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ArrayItemNode.php +12 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayNode.php +4 -31
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignNode.php +15 -1
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignOpNode.php +11 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AuxiliaryNode.php +42 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClassConstantFetchNode.php +2 -2
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClosureNode.php +1 -1
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ConstantFetchNode.php +8 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/IssetNode.php +15 -1
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PostOpNode.php +11 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PreOpNode.php +11 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/{StaticCallNode.php → StaticMethodCallNode.php} +11 -1
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/{StaticCallableNode.php → StaticMethodCallableNode.php} +11 -1
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TemporaryNode.php +38 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ExpressionNode.php +24 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/FilterNode.php +1 -1
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ListItemNode.php +48 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ListNode.php +56 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ModifierNode.php +5 -5
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NameNode.php +11 -21
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/InterpolatedStringNode.php +1 -8
- package/vendor/latte/latte/src/Latte/Compiler/PhpHelpers.php +30 -0
- package/vendor/latte/latte/src/Latte/Compiler/Position.php +4 -8
- package/vendor/latte/latte/src/Latte/Compiler/PrintContext.php +15 -8
- package/vendor/latte/latte/src/Latte/Compiler/Tag.php +13 -14
- package/vendor/latte/latte/src/Latte/Compiler/TagLexer.php +5 -9
- package/vendor/latte/latte/src/Latte/Compiler/TagParser.php +52 -3
- package/vendor/latte/latte/src/Latte/Compiler/TagParserData.php +353 -326
- package/vendor/latte/latte/src/Latte/Compiler/TemplateGenerator.php +6 -5
- package/vendor/latte/latte/src/Latte/Compiler/TemplateLexer.php +105 -178
- package/vendor/latte/latte/src/Latte/Compiler/TemplateParser.php +40 -33
- package/vendor/latte/latte/src/Latte/Compiler/TemplateParserHtml.php +186 -126
- package/vendor/latte/latte/src/Latte/Compiler/Token.php +5 -9
- package/vendor/latte/latte/src/Latte/Compiler/TokenStream.php +6 -22
- package/vendor/latte/latte/src/Latte/Engine.php +136 -95
- package/vendor/latte/latte/src/Latte/Essential/AuxiliaryIterator.php +46 -0
- package/vendor/latte/latte/src/Latte/Essential/Blueprint.php +42 -27
- package/vendor/latte/latte/src/Latte/Essential/CachingIterator.php +0 -4
- package/vendor/latte/latte/src/Latte/Essential/CoreExtension.php +81 -66
- package/vendor/latte/latte/src/Latte/Essential/Filters.php +103 -43
- package/vendor/latte/latte/src/Latte/Essential/Nodes/BlockNode.php +1 -2
- package/vendor/latte/latte/src/Latte/Essential/Nodes/CaptureNode.php +2 -13
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ContentTypeNode.php +8 -1
- package/vendor/latte/latte/src/Latte/Essential/Nodes/DefineNode.php +1 -2
- package/vendor/latte/latte/src/Latte/Essential/Nodes/EmbedNode.php +1 -1
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ExtendsNode.php +0 -3
- package/vendor/latte/latte/src/Latte/Essential/Nodes/FirstLastSepNode.php +1 -1
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ForNode.php +1 -1
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ForeachNode.php +40 -13
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IfChangedNode.php +1 -1
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IfContentNode.php +4 -1
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IfNode.php +5 -3
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IncludeBlockNode.php +5 -2
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IterateWhileNode.php +6 -4
- package/vendor/latte/latte/src/Latte/Essential/Nodes/JumpNode.php +26 -23
- package/vendor/latte/latte/src/Latte/Essential/Nodes/NElseNode.php +88 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/NTagNode.php +20 -28
- package/vendor/latte/latte/src/Latte/Essential/Nodes/PrintNode.php +7 -12
- package/vendor/latte/latte/src/Latte/Essential/Nodes/RollbackNode.php +1 -1
- package/vendor/latte/latte/src/Latte/Essential/Nodes/SpacelessNode.php +1 -1
- package/vendor/latte/latte/src/Latte/Essential/Nodes/SwitchNode.php +1 -1
- package/vendor/latte/latte/src/Latte/Essential/Nodes/TemplatePrintNode.php +25 -3
- package/vendor/latte/latte/src/Latte/Essential/Nodes/TranslateNode.php +1 -1
- package/vendor/latte/latte/src/Latte/Essential/Nodes/TryNode.php +3 -4
- package/vendor/latte/latte/src/Latte/Essential/Nodes/VarPrintNode.php +9 -2
- package/vendor/latte/latte/src/Latte/Essential/Nodes/WhileNode.php +1 -1
- package/vendor/latte/latte/src/Latte/Essential/Passes.php +16 -58
- package/vendor/latte/latte/src/Latte/Essential/RawPhpExtension.php +0 -2
- package/vendor/latte/latte/src/Latte/Essential/TranslatorExtension.php +6 -1
- package/vendor/latte/latte/src/Latte/Helpers.php +3 -1
- package/vendor/latte/latte/src/Latte/Loader.php +1 -0
- package/vendor/latte/latte/src/Latte/Loaders/FileLoader.php +1 -4
- package/vendor/latte/latte/src/Latte/Loaders/StringLoader.php +0 -2
- package/vendor/latte/latte/src/Latte/PositionAwareException.php +1 -1
- package/vendor/latte/latte/src/Latte/Runtime/Block.php +0 -4
- package/vendor/latte/latte/src/Latte/Runtime/FilterExecutor.php +43 -51
- package/vendor/latte/latte/src/Latte/Runtime/FilterInfo.php +0 -2
- package/vendor/latte/latte/src/Latte/Runtime/Filters.php +64 -33
- package/vendor/latte/latte/src/Latte/Runtime/FunctionExecutor.php +68 -0
- package/vendor/latte/latte/src/Latte/Runtime/Html.php +0 -4
- package/vendor/latte/latte/src/Latte/Runtime/Template.php +3 -5
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/FunctionCallNode.php +2 -1
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/MethodCallNode.php +1 -1
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/SandboxNode.php +3 -3
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/{StaticCallNode.php → StaticMethodCallNode.php} +3 -3
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/{StaticCallableNode.php → StaticMethodCallableNode.php} +2 -2
- package/vendor/latte/latte/src/Latte/Sandbox/RuntimeChecker.php +0 -2
- package/vendor/latte/latte/src/Latte/Sandbox/SandboxExtension.php +11 -9
- package/vendor/latte/latte/src/Latte/Sandbox/SecurityPolicy.php +0 -2
- package/vendor/latte/latte/src/Latte/exceptions.php +2 -11
- package/vendor/latte/latte/src/Tools/Linter.php +13 -37
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/QuotedValue.php +0 -53
- package/vendor/latte/latte/src/Latte/Strict.php +0 -101
|
@@ -9,16 +9,12 @@ declare(strict_types=1);
|
|
|
9
9
|
|
|
10
10
|
namespace Latte\Compiler;
|
|
11
11
|
|
|
12
|
-
use Latte;
|
|
13
|
-
|
|
14
12
|
|
|
15
13
|
final class Position
|
|
16
14
|
{
|
|
17
|
-
use Latte\Strict;
|
|
18
|
-
|
|
19
15
|
public function __construct(
|
|
20
|
-
public /*readonly*/ int $line,
|
|
21
|
-
public /*readonly*/ int $column,
|
|
16
|
+
public /*readonly*/ int $line = 1,
|
|
17
|
+
public /*readonly*/ int $column = 1,
|
|
22
18
|
public /*readonly*/ int $offset = 0,
|
|
23
19
|
) {
|
|
24
20
|
}
|
|
@@ -42,8 +38,8 @@ final class Position
|
|
|
42
38
|
}
|
|
43
39
|
|
|
44
40
|
|
|
45
|
-
public function
|
|
41
|
+
public function __toString(): string
|
|
46
42
|
{
|
|
47
|
-
return "on line $this->line at column $this->column";
|
|
43
|
+
return "on line $this->line" . ($this->column ? " at column $this->column" : '');
|
|
48
44
|
}
|
|
49
45
|
}
|
|
@@ -9,7 +9,6 @@ declare(strict_types=1);
|
|
|
9
9
|
|
|
10
10
|
namespace Latte\Compiler;
|
|
11
11
|
|
|
12
|
-
use Latte;
|
|
13
12
|
use Latte\Compiler\Nodes\Php as Nodes;
|
|
14
13
|
use Latte\Compiler\Nodes\Php\Expression;
|
|
15
14
|
use Latte\Compiler\Nodes\Php\Scalar;
|
|
@@ -22,8 +21,6 @@ use Latte\ContentType;
|
|
|
22
21
|
*/
|
|
23
22
|
final class PrintContext
|
|
24
23
|
{
|
|
25
|
-
use Latte\Strict;
|
|
26
|
-
|
|
27
24
|
public array $paramsExtraction = [];
|
|
28
25
|
public array $blocks = [];
|
|
29
26
|
|
|
@@ -105,7 +102,7 @@ final class PrintContext
|
|
|
105
102
|
function ($m) use ($args) {
|
|
106
103
|
[, $pos, $fn, $var] = $m;
|
|
107
104
|
$var = substr($var, 1, -1);
|
|
108
|
-
/** @var Nodes\
|
|
105
|
+
/** @var Nodes\ModifierNode[] $args */
|
|
109
106
|
return match ($fn) {
|
|
110
107
|
'modify' => $args[$pos]->printSimple($this, $var),
|
|
111
108
|
'modifyContent' => $args[$pos]->printContentAware($this, $var),
|
|
@@ -298,8 +295,8 @@ final class PrintContext
|
|
|
298
295
|
|| $expr instanceof Expression\FunctionCallableNode
|
|
299
296
|
|| $expr instanceof Expression\MethodCallNode
|
|
300
297
|
|| $expr instanceof Expression\MethodCallableNode
|
|
301
|
-
|| $expr instanceof Expression\
|
|
302
|
-
|| $expr instanceof Expression\
|
|
298
|
+
|| $expr instanceof Expression\StaticMethodCallNode
|
|
299
|
+
|| $expr instanceof Expression\StaticMethodCallableNode
|
|
303
300
|
|| $expr instanceof Expression\ArrayNode
|
|
304
301
|
? $expr->print($this)
|
|
305
302
|
: '(' . $expr->print($this) . ')';
|
|
@@ -320,8 +317,8 @@ final class PrintContext
|
|
|
320
317
|
|| $expr instanceof Expression\FunctionCallableNode
|
|
321
318
|
|| $expr instanceof Expression\MethodCallNode
|
|
322
319
|
|| $expr instanceof Expression\MethodCallableNode
|
|
323
|
-
|| $expr instanceof Expression\
|
|
324
|
-
|| $expr instanceof Expression\
|
|
320
|
+
|| $expr instanceof Expression\StaticMethodCallNode
|
|
321
|
+
|| $expr instanceof Expression\StaticMethodCallableNode
|
|
325
322
|
|| $expr instanceof Expression\ArrayNode
|
|
326
323
|
|| $expr instanceof Scalar\StringNode
|
|
327
324
|
|| $expr instanceof Scalar\BooleanNode
|
|
@@ -331,4 +328,14 @@ final class PrintContext
|
|
|
331
328
|
? $expr->print($this)
|
|
332
329
|
: '(' . $expr->print($this) . ')';
|
|
333
330
|
}
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* @param Nodes\ArgumentNode[] $args
|
|
335
|
+
*/
|
|
336
|
+
public function argumentsAsArray(array $args): string
|
|
337
|
+
{
|
|
338
|
+
$items = array_map(fn(Nodes\ArgumentNode $arg) => $arg->toArrayItem(), $args);
|
|
339
|
+
return '[' . $this->implode($items) . ']';
|
|
340
|
+
}
|
|
334
341
|
}
|
|
@@ -9,8 +9,8 @@ declare(strict_types=1);
|
|
|
9
9
|
|
|
10
10
|
namespace Latte\Compiler;
|
|
11
11
|
|
|
12
|
-
use Latte;
|
|
13
12
|
use Latte\CompileException;
|
|
13
|
+
use Latte\Compiler\Nodes\AreaNode;
|
|
14
14
|
use Latte\Compiler\Nodes\Html\ElementNode;
|
|
15
15
|
|
|
16
16
|
|
|
@@ -19,8 +19,6 @@ use Latte\Compiler\Nodes\Html\ElementNode;
|
|
|
19
19
|
*/
|
|
20
20
|
final class Tag
|
|
21
21
|
{
|
|
22
|
-
use Latte\Strict;
|
|
23
|
-
|
|
24
22
|
public const
|
|
25
23
|
PrefixInner = 'inner',
|
|
26
24
|
PrefixTag = 'tag',
|
|
@@ -41,26 +39,27 @@ final class Tag
|
|
|
41
39
|
public /*readonly*/ Position $position,
|
|
42
40
|
public /*readonly*/ bool $void = false,
|
|
43
41
|
public /*readonly*/ bool $closing = false,
|
|
44
|
-
public /*readonly*/
|
|
42
|
+
public /*readonly*/ bool $inHead = false,
|
|
43
|
+
public /*readonly*/ bool $inTag = false,
|
|
45
44
|
public /*readonly*/ ?ElementNode $htmlElement = null,
|
|
46
45
|
public ?self $parent = null,
|
|
47
46
|
public /*readonly*/ ?string $prefix = null,
|
|
48
|
-
public
|
|
47
|
+
public ?AreaNode $node = null,
|
|
48
|
+
public ?AreaNode $nAttributeNode = null,
|
|
49
49
|
) {
|
|
50
|
-
$this->data ??= new \stdClass;
|
|
51
50
|
$this->parser = new TagParser($tokens);
|
|
52
51
|
}
|
|
53
52
|
|
|
54
53
|
|
|
55
54
|
public function isInHead(): bool
|
|
56
55
|
{
|
|
57
|
-
return $this->
|
|
56
|
+
return $this->inHead && !$this->parent;
|
|
58
57
|
}
|
|
59
58
|
|
|
60
59
|
|
|
61
60
|
public function isInText(): bool
|
|
62
61
|
{
|
|
63
|
-
return
|
|
62
|
+
return !$this->inTag;
|
|
64
63
|
}
|
|
65
64
|
|
|
66
65
|
|
|
@@ -85,13 +84,13 @@ final class Tag
|
|
|
85
84
|
|
|
86
85
|
|
|
87
86
|
/**
|
|
88
|
-
* @param string[] $
|
|
87
|
+
* @param class-string[] $classes
|
|
89
88
|
*/
|
|
90
|
-
public function closestTag(array $
|
|
89
|
+
public function closestTag(array $classes, ?callable $condition = null): ?self
|
|
91
90
|
{
|
|
92
91
|
$tag = $this->parent;
|
|
93
92
|
while ($tag && (
|
|
94
|
-
!in_array($tag->name, $
|
|
93
|
+
(!in_array($tag->node ? $tag->node::class : null, $classes, true) && !in_array($tag->name, $classes, true))
|
|
95
94
|
|| ($condition && !$condition($tag))
|
|
96
95
|
)) {
|
|
97
96
|
$tag = $tag->parent;
|
|
@@ -109,9 +108,9 @@ final class Tag
|
|
|
109
108
|
}
|
|
110
109
|
|
|
111
110
|
|
|
112
|
-
public function replaceNAttribute(
|
|
111
|
+
public function replaceNAttribute(AreaNode $node): void
|
|
113
112
|
{
|
|
114
|
-
$index = array_search($this->
|
|
115
|
-
$this->htmlElement->attributes->children[$index] = $node;
|
|
113
|
+
$index = array_search($this->nAttributeNode, $this->htmlElement->attributes->children, true);
|
|
114
|
+
$this->htmlElement->attributes->children[$index] = $this->nAttributeNode = $node;
|
|
116
115
|
}
|
|
117
116
|
}
|
|
@@ -9,9 +9,7 @@ declare(strict_types=1);
|
|
|
9
9
|
|
|
10
10
|
namespace Latte\Compiler;
|
|
11
11
|
|
|
12
|
-
use Latte;
|
|
13
12
|
use Latte\CompileException;
|
|
14
|
-
use Latte\RegexpException;
|
|
15
13
|
|
|
16
14
|
|
|
17
15
|
/**
|
|
@@ -19,8 +17,6 @@ use Latte\RegexpException;
|
|
|
19
17
|
*/
|
|
20
18
|
final class TagLexer
|
|
21
19
|
{
|
|
22
|
-
use Latte\Strict;
|
|
23
|
-
|
|
24
20
|
private const Keywords = [
|
|
25
21
|
'and' => Token::Php_LogicalAnd,
|
|
26
22
|
'array' => Token::Php_Array,
|
|
@@ -57,7 +53,7 @@ final class TagLexer
|
|
|
57
53
|
/** @return Token[] */
|
|
58
54
|
public function tokenize(string $input, ?Position $position = null): array
|
|
59
55
|
{
|
|
60
|
-
$position ??= new Position
|
|
56
|
+
$position ??= new Position;
|
|
61
57
|
$this->tokens = $this->tokenizePartially($input, $position, 0);
|
|
62
58
|
if ($this->offset !== strlen($input)) {
|
|
63
59
|
$token = str_replace("\n", '\n', substr($input, $this->offset, 10));
|
|
@@ -86,8 +82,8 @@ final class TagLexer
|
|
|
86
82
|
{
|
|
87
83
|
preg_match(
|
|
88
84
|
$colon
|
|
89
|
-
? '~ ( [./@_a-z0-9#!-] | :(?!:) | \{\$ [_a-z0-9\[\]()>-]+ })++ (?=\s+[!"\'$(\[{
|
|
90
|
-
: '~ ( [./@_a-z0-9#!-] | \{\$ [_a-z0-9\[\]()>-]+ })++ (?=\s+[!"\'$(\[{
|
|
85
|
+
? '~ ( [./@_a-z0-9#!-] | :(?!:) | \{\$ [_a-z0-9\[\]()>-]+ })++ (?=\s+[!"\'$(\[{,\\\\|\~\w-] | [,|] | \s*$) ~xAi'
|
|
86
|
+
: '~ ( [./@_a-z0-9#!-] | \{\$ [_a-z0-9\[\]()>-]+ })++ (?=\s+[!"\'$(\[{,\\\\|\~\w-] | [,:|] | \s*$) ~xAi',
|
|
91
87
|
$input,
|
|
92
88
|
$match,
|
|
93
89
|
offset: $position->offset - $offsetDelta,
|
|
@@ -185,7 +181,7 @@ final class TagLexer
|
|
|
185
181
|
matchRE:
|
|
186
182
|
preg_match_all($re, $this->input, $matches, PREG_SET_ORDER | PREG_UNMATCHED_AS_NULL, $this->offset);
|
|
187
183
|
if (preg_last_error()) {
|
|
188
|
-
throw new
|
|
184
|
+
throw new CompileException(preg_last_error_msg());
|
|
189
185
|
}
|
|
190
186
|
|
|
191
187
|
foreach ($matches as $m) {
|
|
@@ -330,7 +326,7 @@ final class TagLexer
|
|
|
330
326
|
matchRE:
|
|
331
327
|
preg_match_all($re, $this->input, $matches, PREG_SET_ORDER | PREG_UNMATCHED_AS_NULL, $this->offset);
|
|
332
328
|
if (preg_last_error()) {
|
|
333
|
-
throw new
|
|
329
|
+
throw new CompileException(preg_last_error_msg());
|
|
334
330
|
}
|
|
335
331
|
|
|
336
332
|
$buffer = '';
|
|
@@ -10,6 +10,7 @@ declare(strict_types=1);
|
|
|
10
10
|
namespace Latte\Compiler;
|
|
11
11
|
|
|
12
12
|
use Latte;
|
|
13
|
+
use Latte\CompileException;
|
|
13
14
|
use Latte\Compiler\Nodes\Php as Node;
|
|
14
15
|
use Latte\Compiler\Nodes\Php\Expression;
|
|
15
16
|
use Latte\Compiler\Nodes\Php\ExpressionNode;
|
|
@@ -23,17 +24,19 @@ use Latte\Compiler\Nodes\Php\Scalar;
|
|
|
23
24
|
*/
|
|
24
25
|
final class TagParser extends TagParserData
|
|
25
26
|
{
|
|
26
|
-
use Latte\Strict;
|
|
27
|
-
|
|
28
27
|
private const
|
|
29
28
|
SchemaExpression = 'e',
|
|
30
29
|
SchemaArguments = 'a',
|
|
31
|
-
SchemaFilters = 'm'
|
|
30
|
+
SchemaFilters = 'm',
|
|
31
|
+
SchemaForeach = 'f';
|
|
32
32
|
|
|
33
33
|
private const SymbolNone = -1;
|
|
34
34
|
|
|
35
35
|
public TokenStream /*readonly*/ $stream;
|
|
36
36
|
public string $text;
|
|
37
|
+
|
|
38
|
+
/** @var \SplObjectStorage<Expression\ArrayNode> */
|
|
39
|
+
protected \SplObjectStorage $shortArrays;
|
|
37
40
|
private int /*readonly*/ $offsetDelta;
|
|
38
41
|
|
|
39
42
|
|
|
@@ -116,6 +119,16 @@ final class TagParser extends TagParserData
|
|
|
116
119
|
}
|
|
117
120
|
|
|
118
121
|
|
|
122
|
+
/**
|
|
123
|
+
* Parses variables used in foreach.
|
|
124
|
+
* @internal
|
|
125
|
+
*/
|
|
126
|
+
public function parseForeach(): array
|
|
127
|
+
{
|
|
128
|
+
return $this->parse(self::SchemaForeach);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
|
|
119
132
|
/**
|
|
120
133
|
* Consumes optional token followed by whitespace. Suitable before parseUnquotedStringOrExpression().
|
|
121
134
|
*/
|
|
@@ -152,6 +165,7 @@ final class TagParser extends TagParserData
|
|
|
152
165
|
$stateStack = [$state];
|
|
153
166
|
$this->semStack = []; // Semantic value stack (contains values of tokens and semantic action results)
|
|
154
167
|
$stackPos = 0; // Current position in the stack(s)
|
|
168
|
+
$this->shortArrays = new \SplObjectStorage;
|
|
155
169
|
|
|
156
170
|
do {
|
|
157
171
|
if (self::ActionBase[$state] === 0) {
|
|
@@ -206,6 +220,7 @@ final class TagParser extends TagParserData
|
|
|
206
220
|
|
|
207
221
|
do {
|
|
208
222
|
if ($rule === 0) { // accept
|
|
223
|
+
$this->finalizeShortArrays();
|
|
209
224
|
return $this->semValue;
|
|
210
225
|
|
|
211
226
|
} elseif ($rule !== self::UnexpectedTokenRule) { // reduce
|
|
@@ -407,6 +422,40 @@ final class TagParser extends TagParserData
|
|
|
407
422
|
}
|
|
408
423
|
|
|
409
424
|
|
|
425
|
+
public function convertArrayToList(Expression\ArrayNode $array): Node\ListNode
|
|
426
|
+
{
|
|
427
|
+
$this->shortArrays->detach($array);
|
|
428
|
+
$items = [];
|
|
429
|
+
foreach ($array->items as $item) {
|
|
430
|
+
$value = $item->value;
|
|
431
|
+
if ($item->unpack) {
|
|
432
|
+
throw new CompileException('Spread operator is not supported in assignments.', $value->position);
|
|
433
|
+
}
|
|
434
|
+
$value = match (true) {
|
|
435
|
+
$value instanceof Expression\TemporaryNode => $value->value,
|
|
436
|
+
$value instanceof Expression\ArrayNode && $this->shortArrays->contains($value) => $this->convertArrayToList($value),
|
|
437
|
+
default => $value,
|
|
438
|
+
};
|
|
439
|
+
$items[] = $value
|
|
440
|
+
? new Node\ListItemNode($value, $item->key, $item->byRef, $item->position)
|
|
441
|
+
: null;
|
|
442
|
+
}
|
|
443
|
+
return new Node\ListNode($items, $array->position);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
private function finalizeShortArrays(): void
|
|
448
|
+
{
|
|
449
|
+
foreach ($this->shortArrays as $node) {
|
|
450
|
+
foreach ($node->items as $item) {
|
|
451
|
+
if ($item->value instanceof Expression\TemporaryNode) {
|
|
452
|
+
throw new CompileException('Cannot use empty array elements or list() in arrays.', $item->position);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
|
|
410
459
|
/** @param Token[] $tokens */
|
|
411
460
|
private function filterTokens(array $tokens): array
|
|
412
461
|
{
|