@vituum/vite-plugin-latte 0.1.8
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/README.md +39 -0
- package/handler.js +9 -0
- package/index.js +138 -0
- package/index.php +173 -0
- package/latte/AssetFilter.php +11 -0
- package/latte/FetchFunction.php +28 -0
- package/latte/IconFilter.php +14 -0
- package/latte/JsonTag.php +64 -0
- package/latte/PlaceholderFunction.php +11 -0
- package/latte/RandomColorFunction.php +14 -0
- package/latte/TelFilter.php +22 -0
- package/package.json +35 -0
- package/vendor/autoload.php +7 -0
- package/vendor/bin/latte-lint +107 -0
- package/vendor/composer/ClassLoader.php +572 -0
- package/vendor/composer/InstalledVersions.php +350 -0
- package/vendor/composer/LICENSE +21 -0
- package/vendor/composer/autoload_classmap.php +183 -0
- package/vendor/composer/autoload_namespaces.php +9 -0
- package/vendor/composer/autoload_psr4.php +9 -0
- package/vendor/composer/autoload_real.php +57 -0
- package/vendor/composer/autoload_static.php +193 -0
- package/vendor/composer/installed.json +93 -0
- package/vendor/composer/installed.php +32 -0
- package/vendor/composer/platform_check.php +26 -0
- package/vendor/latte/latte/bin/latte-lint +29 -0
- package/vendor/latte/latte/composer.json +53 -0
- package/vendor/latte/latte/license.md +60 -0
- package/vendor/latte/latte/ncs.php +14 -0
- package/vendor/latte/latte/ncs.xml +9 -0
- package/vendor/latte/latte/readme.md +21 -0
- package/vendor/latte/latte/src/Bridges/Tracy/BlueScreenPanel.php +114 -0
- package/vendor/latte/latte/src/Bridges/Tracy/LattePanel.php +99 -0
- package/vendor/latte/latte/src/Bridges/Tracy/templates/LattePanel.panel.phtml +98 -0
- package/vendor/latte/latte/src/Bridges/Tracy/templates/LattePanel.tab.phtml +15 -0
- package/vendor/latte/latte/src/Latte/Compiler/Block.php +44 -0
- package/vendor/latte/latte/src/Latte/Compiler/Escaper.php +244 -0
- package/vendor/latte/latte/src/Latte/Compiler/ExpressionBuilder.php +128 -0
- package/vendor/latte/latte/src/Latte/Compiler/Node.php +28 -0
- package/vendor/latte/latte/src/Latte/Compiler/NodeHelpers.php +132 -0
- package/vendor/latte/latte/src/Latte/Compiler/NodeTraverser.php +77 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/AreaNode.php +17 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/AuxiliaryNode.php +27 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/FragmentNode.php +59 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/AttributeNode.php +48 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/BogusTagNode.php +46 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/CommentNode.php +39 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ElementNode.php +129 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/QuotedValue.php +53 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/NopNode.php +21 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ArgumentNode.php +45 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ComplexTypeNode.php +17 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayAccessNode.php +41 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayItemNode.php +52 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayNode.php +94 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignNode.php +39 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignOpNode.php +45 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/BinaryOpNode.php +65 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CastNode.php +43 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClassConstantFetchNode.php +42 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CloneNode.php +36 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClosureNode.php +73 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClosureUseNode.php +37 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ConstantFetchNode.php +37 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/EmptyNode.php +36 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ErrorSuppressNode.php +36 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FilterCallNode.php +39 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FunctionCallNode.php +45 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FunctionCallableNode.php +39 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InRangeNode.php +42 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InstanceofNode.php +40 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/IssetNode.php +40 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MatchNode.php +49 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MethodCallNode.php +50 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MethodCallableNode.php +42 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/NewNode.php +45 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/NotNode.php +36 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PostOpNode.php +43 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PreOpNode.php +43 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PropertyFetchNode.php +42 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticCallNode.php +55 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticCallableNode.php +47 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticPropertyFetchNode.php +42 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TernaryNode.php +50 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/UnaryOpNode.php +45 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/VariableNode.php +40 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ExpressionNode.php +17 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/FilterNode.php +67 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/IdentifierNode.php +36 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/IntersectionTypeNode.php +39 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/MatchArmNode.php +45 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ModifierNode.php +107 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NameNode.php +89 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NullableTypeNode.php +35 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ParameterNode.php +54 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/BooleanNode.php +30 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/EncapsedStringNode.php +80 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/EncapsedStringPartNode.php +30 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/FloatNode.php +63 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/IntegerNode.php +70 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/NullNode.php +29 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/StringNode.php +40 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ScalarNode.php +15 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/SuperiorTypeNode.php +29 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/UnionTypeNode.php +39 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/VarLikeIdentifierNode.php +21 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/StatementNode.php +15 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/TemplateNode.php +34 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/TextNode.php +37 -0
- package/vendor/latte/latte/src/Latte/Compiler/PhpHelpers.php +227 -0
- package/vendor/latte/latte/src/Latte/Compiler/Position.php +43 -0
- package/vendor/latte/latte/src/Latte/Compiler/PrintContext.php +334 -0
- package/vendor/latte/latte/src/Latte/Compiler/Tag.php +117 -0
- package/vendor/latte/latte/src/Latte/Compiler/TagLexer.php +399 -0
- package/vendor/latte/latte/src/Latte/Compiler/TagParser.php +388 -0
- package/vendor/latte/latte/src/Latte/Compiler/TagParserData.php +580 -0
- package/vendor/latte/latte/src/Latte/Compiler/TemplateGenerator.php +206 -0
- package/vendor/latte/latte/src/Latte/Compiler/TemplateLexer.php +391 -0
- package/vendor/latte/latte/src/Latte/Compiler/TemplateParser.php +448 -0
- package/vendor/latte/latte/src/Latte/Compiler/TemplateParserHtml.php +506 -0
- package/vendor/latte/latte/src/Latte/Compiler/Token.php +259 -0
- package/vendor/latte/latte/src/Latte/Compiler/TokenStream.php +151 -0
- package/vendor/latte/latte/src/Latte/ContentType.php +22 -0
- package/vendor/latte/latte/src/Latte/Engine.php +591 -0
- package/vendor/latte/latte/src/Latte/Essential/Blueprint.php +160 -0
- package/vendor/latte/latte/src/Latte/Essential/CachingIterator.php +232 -0
- package/vendor/latte/latte/src/Latte/Essential/CoreExtension.php +232 -0
- package/vendor/latte/latte/src/Latte/Essential/Filters.php +591 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/BlockNode.php +161 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/CaptureNode.php +98 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ContentTypeNode.php +74 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/DebugbreakNode.php +53 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/DefineNode.php +134 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/DoNode.php +49 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/DumpNode.php +58 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/EmbedNode.php +125 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ExtendsNode.php +60 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/FirstLastSepNode.php +81 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ForNode.php +91 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ForeachNode.php +155 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IfChangedNode.php +141 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IfContentNode.php +82 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IfNode.php +180 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ImportNode.php +49 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IncludeBlockNode.php +140 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IncludeFileNode.php +81 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IterateWhileNode.php +94 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/NAttrNode.php +105 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/NClassNode.php +54 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/NTagNode.php +79 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ParametersNode.php +84 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/PrintNode.php +70 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/RawPhpNode.php +46 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/RollbackNode.php +37 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/SkipNode.php +71 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/SpacelessNode.php +62 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/SwitchNode.php +118 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/TemplatePrintNode.php +39 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/TemplateTypeNode.php +38 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/TraceNode.php +35 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/TranslateNode.php +104 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/TryNode.php +75 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/VarNode.php +106 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/VarPrintNode.php +40 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/VarTypeNode.php +36 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/WhileNode.php +81 -0
- package/vendor/latte/latte/src/Latte/Essential/Passes.php +115 -0
- package/vendor/latte/latte/src/Latte/Essential/RawPhpExtension.php +28 -0
- package/vendor/latte/latte/src/Latte/Essential/RollbackException.php +16 -0
- package/vendor/latte/latte/src/Latte/Essential/Tracer.php +117 -0
- package/vendor/latte/latte/src/Latte/Essential/TranslatorExtension.php +101 -0
- package/vendor/latte/latte/src/Latte/Extension.php +97 -0
- package/vendor/latte/latte/src/Latte/Helpers.php +96 -0
- package/vendor/latte/latte/src/Latte/Loader.php +37 -0
- package/vendor/latte/latte/src/Latte/Loaders/FileLoader.php +95 -0
- package/vendor/latte/latte/src/Latte/Loaders/StringLoader.php +76 -0
- package/vendor/latte/latte/src/Latte/Policy.php +24 -0
- package/vendor/latte/latte/src/Latte/PositionAwareException.php +50 -0
- package/vendor/latte/latte/src/Latte/Runtime/Block.php +24 -0
- package/vendor/latte/latte/src/Latte/Runtime/FilterExecutor.php +151 -0
- package/vendor/latte/latte/src/Latte/Runtime/FilterInfo.php +39 -0
- package/vendor/latte/latte/src/Latte/Runtime/Filters.php +234 -0
- package/vendor/latte/latte/src/Latte/Runtime/Html.php +35 -0
- package/vendor/latte/latte/src/Latte/Runtime/HtmlStringable.php +17 -0
- package/vendor/latte/latte/src/Latte/Runtime/Template.php +381 -0
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/FunctionCallNode.php +30 -0
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/FunctionCallableNode.php +29 -0
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/MethodCallNode.php +32 -0
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/MethodCallableNode.php +30 -0
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/PropertyFetchNode.php +32 -0
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/SandboxNode.php +73 -0
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticCallNode.php +31 -0
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticCallableNode.php +30 -0
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticPropertyFetchNode.php +32 -0
- package/vendor/latte/latte/src/Latte/Sandbox/RuntimeChecker.php +116 -0
- package/vendor/latte/latte/src/Latte/Sandbox/SandboxExtension.php +132 -0
- package/vendor/latte/latte/src/Latte/Sandbox/SecurityPolicy.php +185 -0
- package/vendor/latte/latte/src/Latte/Strict.php +101 -0
- package/vendor/latte/latte/src/Latte/attributes.php +24 -0
- package/vendor/latte/latte/src/Latte/exceptions.php +69 -0
- package/vendor/latte/latte/src/Tools/Linter.php +175 -0
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This file is part of the Latte (https://latte.nette.org)
|
|
5
|
+
* Copyright (c) 2008 David Grudl (https://davidgrudl.com)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
declare(strict_types=1);
|
|
9
|
+
|
|
10
|
+
namespace Latte\Compiler;
|
|
11
|
+
|
|
12
|
+
use Latte;
|
|
13
|
+
use Latte\Compiler\Nodes\Php as Nodes;
|
|
14
|
+
use Latte\Compiler\Nodes\Php\Expression;
|
|
15
|
+
use Latte\Compiler\Nodes\Php\Scalar;
|
|
16
|
+
use Latte\ContentType;
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* PHP printing helpers and context.
|
|
21
|
+
* The parts are based on great nikic/PHP-Parser project by Nikita Popov.
|
|
22
|
+
*/
|
|
23
|
+
final class PrintContext
|
|
24
|
+
{
|
|
25
|
+
use Latte\Strict;
|
|
26
|
+
|
|
27
|
+
public array $paramsExtraction = [];
|
|
28
|
+
public array $blocks = [];
|
|
29
|
+
|
|
30
|
+
private array $exprPrecedenceMap = [
|
|
31
|
+
// [precedence, associativity] (-1 is %left, 0 is %nonassoc and 1 is %right)
|
|
32
|
+
Expression\PreOpNode::class => [10, 1],
|
|
33
|
+
Expression\PostOpNode::class => [10, -1],
|
|
34
|
+
Expression\UnaryOpNode::class => [10, 1],
|
|
35
|
+
Expression\CastNode::class => [10, 1],
|
|
36
|
+
Expression\ErrorSuppressNode::class => [10, 1],
|
|
37
|
+
Expression\InstanceofNode::class => [20, 0],
|
|
38
|
+
Expression\NotNode::class => [30, 1],
|
|
39
|
+
Expression\TernaryNode::class => [150, 0],
|
|
40
|
+
// parser uses %left for assignments, but they really behave as %right
|
|
41
|
+
Expression\AssignNode::class => [160, 1],
|
|
42
|
+
Expression\AssignOpNode::class => [160, 1],
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
private array $binaryPrecedenceMap = [
|
|
46
|
+
// [precedence, associativity] (-1 is %left, 0 is %nonassoc and 1 is %right)
|
|
47
|
+
'**' => [0, 1],
|
|
48
|
+
'*' => [40, -1],
|
|
49
|
+
'/' => [40, -1],
|
|
50
|
+
'%' => [40, -1],
|
|
51
|
+
'+' => [50, -1],
|
|
52
|
+
'-' => [50, -1],
|
|
53
|
+
'.' => [50, -1],
|
|
54
|
+
'<<' => [60, -1],
|
|
55
|
+
'>>' => [60, -1],
|
|
56
|
+
'<' => [70, 0],
|
|
57
|
+
'<=' => [70, 0],
|
|
58
|
+
'>' => [70, 0],
|
|
59
|
+
'>=' => [70, 0],
|
|
60
|
+
'==' => [80, 0],
|
|
61
|
+
'!=' => [80, 0],
|
|
62
|
+
'===' => [80, 0],
|
|
63
|
+
'!==' => [80, 0],
|
|
64
|
+
'<=>' => [80, 0],
|
|
65
|
+
'&' => [90, -1],
|
|
66
|
+
'^' => [100, -1],
|
|
67
|
+
'|' => [110, -1],
|
|
68
|
+
'&&' => [120, -1],
|
|
69
|
+
'||' => [130, -1],
|
|
70
|
+
'??' => [140, 1],
|
|
71
|
+
'and' => [170, -1],
|
|
72
|
+
'xor' => [180, -1],
|
|
73
|
+
'or' => [190, -1],
|
|
74
|
+
];
|
|
75
|
+
private int $counter = 0;
|
|
76
|
+
|
|
77
|
+
/** @var Escaper[] */
|
|
78
|
+
private array $escaperStack = [];
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
public function __construct(string $contentType = ContentType::Html)
|
|
82
|
+
{
|
|
83
|
+
$this->escaperStack[] = new Escaper($contentType);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Expands %node, %dump, %raw, %args, %line, %escape(), %modify(), %modifyContent() in code.
|
|
89
|
+
*/
|
|
90
|
+
public function format(string $mask, mixed ...$args): string
|
|
91
|
+
{
|
|
92
|
+
$pos = 0; // enumerate arguments except for %escape
|
|
93
|
+
$mask = preg_replace_callback(
|
|
94
|
+
'#%([a-z]{3,})#i',
|
|
95
|
+
function ($m) use (&$pos) {
|
|
96
|
+
return $m[1] === 'escape'
|
|
97
|
+
? '%0.escape'
|
|
98
|
+
: '%' . ($pos++) . '.' . $m[1];
|
|
99
|
+
},
|
|
100
|
+
$mask,
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
$mask = preg_replace_callback(
|
|
104
|
+
'#% (\d+) \. (escape|modify(?:Content)?) ( \( ([^()]*+|(?-2))+ \) )#xi',
|
|
105
|
+
function ($m) use ($args) {
|
|
106
|
+
[, $pos, $fn, $var] = $m;
|
|
107
|
+
$var = substr($var, 1, -1);
|
|
108
|
+
/** @var Nodes\ModifierNode[] $args */
|
|
109
|
+
return match ($fn) {
|
|
110
|
+
'modify' => $args[$pos]->printSimple($this, $var),
|
|
111
|
+
'modifyContent' => $args[$pos]->printContentAware($this, $var),
|
|
112
|
+
'escape' => end($this->escaperStack)->escape($var),
|
|
113
|
+
};
|
|
114
|
+
},
|
|
115
|
+
$mask,
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
return preg_replace_callback(
|
|
119
|
+
'#([,+]?\s*)? % (\d+) \. ([a-z]{3,}) (\?)? (\s*\+\s*)? ()#xi',
|
|
120
|
+
function ($m) use ($args) {
|
|
121
|
+
[, $l, $pos, $format, $cond, $r] = $m;
|
|
122
|
+
$arg = $args[$pos];
|
|
123
|
+
|
|
124
|
+
$code = match ($format) {
|
|
125
|
+
'dump' => PhpHelpers::dump($arg),
|
|
126
|
+
'node' => $arg ? $arg->print($this) : '',
|
|
127
|
+
'raw' => (string) $arg,
|
|
128
|
+
'args' => $this->implode($arg instanceof Expression\ArrayNode ? $arg->toArguments() : $arg),
|
|
129
|
+
'line' => $arg?->line ? "/* line $arg->line */" : '',
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
if ($cond && ($code === '[]' || $code === '')) {
|
|
133
|
+
return $r ? $l : $r;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return $code === ''
|
|
137
|
+
? trim($l) . $r
|
|
138
|
+
: $l . $code . $r;
|
|
139
|
+
},
|
|
140
|
+
$mask,
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
public function beginEscape(): Escaper
|
|
146
|
+
{
|
|
147
|
+
return $this->escaperStack[] = $this->getEscaper();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
public function restoreEscape(): void
|
|
152
|
+
{
|
|
153
|
+
array_pop($this->escaperStack);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
public function getEscaper(): Escaper
|
|
158
|
+
{
|
|
159
|
+
return clone end($this->escaperStack);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
public function addBlock(Block $block): void
|
|
164
|
+
{
|
|
165
|
+
$block->escaping = $this->getEscaper()->export();
|
|
166
|
+
$block->method = 'block' . ucfirst(trim(preg_replace('#\W+#', '_', $block->name->print($this)), '_'));
|
|
167
|
+
$lower = strtolower($block->method);
|
|
168
|
+
$used = $this->blocks + ['block' => 1];
|
|
169
|
+
$counter = null;
|
|
170
|
+
while (isset($used[$lower . $counter])) {
|
|
171
|
+
$counter++;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
$block->method .= $counter;
|
|
175
|
+
$this->blocks[$lower . $counter] = $block;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
public function generateId(): int
|
|
180
|
+
{
|
|
181
|
+
return $this->counter++;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
// PHP helpers
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
public function encodeString(string $str, string $quote = "'"): string
|
|
189
|
+
{
|
|
190
|
+
return $quote === "'"
|
|
191
|
+
? "'" . addcslashes($str, "'\\") . "'"
|
|
192
|
+
: '"' . addcslashes($str, "\n\r\t\f\v$\"\\") . '"';
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Prints an infix operation while taking precedence into account.
|
|
198
|
+
*/
|
|
199
|
+
public function infixOp(Node $node, Node $leftNode, string $operatorString, Node $rightNode): string
|
|
200
|
+
{
|
|
201
|
+
[$precedence, $associativity] = $this->getPrecedence($node);
|
|
202
|
+
return $this->prec($leftNode, $precedence, $associativity, -1)
|
|
203
|
+
. $operatorString
|
|
204
|
+
. $this->prec($rightNode, $precedence, $associativity, 1);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Prints a prefix operation while taking precedence into account.
|
|
210
|
+
*/
|
|
211
|
+
public function prefixOp(Node $node, string $operatorString, Node $expr): string
|
|
212
|
+
{
|
|
213
|
+
[$precedence, $associativity] = $this->getPrecedence($node);
|
|
214
|
+
return $operatorString . $this->prec($expr, $precedence, $associativity, 1);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Prints a postfix operation while taking precedence into account.
|
|
220
|
+
*/
|
|
221
|
+
public function postfixOp(Node $node, Node $var, string $operatorString): string
|
|
222
|
+
{
|
|
223
|
+
[$precedence, $associativity] = $this->getPrecedence($node);
|
|
224
|
+
return $this->prec($var, $precedence, $associativity, -1) . $operatorString;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Prints an expression node with the least amount of parentheses necessary to preserve the meaning.
|
|
230
|
+
*/
|
|
231
|
+
private function prec(Node $node, int $parentPrecedence, int $parentAssociativity, int $childPosition): string
|
|
232
|
+
{
|
|
233
|
+
$precedence = $this->getPrecedence($node);
|
|
234
|
+
if ($precedence) {
|
|
235
|
+
$childPrecedence = $precedence[0];
|
|
236
|
+
if ($childPrecedence > $parentPrecedence
|
|
237
|
+
|| ($parentPrecedence === $childPrecedence && $parentAssociativity !== $childPosition)
|
|
238
|
+
) {
|
|
239
|
+
return '(' . $node->print($this) . ')';
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return $node->print($this);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
private function getPrecedence(Node $node): ?array
|
|
248
|
+
{
|
|
249
|
+
return $node instanceof Expression\BinaryOpNode
|
|
250
|
+
? $this->binaryPrecedenceMap[$node->operator]
|
|
251
|
+
: $this->exprPrecedenceMap[$node::class] ?? null;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Prints an array of nodes and implodes the printed values with $glue
|
|
257
|
+
*/
|
|
258
|
+
public function implode(array $nodes, string $glue = ', '): string
|
|
259
|
+
{
|
|
260
|
+
$pNodes = [];
|
|
261
|
+
foreach ($nodes as $node) {
|
|
262
|
+
if ($node === null) {
|
|
263
|
+
$pNodes[] = '';
|
|
264
|
+
} else {
|
|
265
|
+
$pNodes[] = $node->print($this);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return implode($glue, $pNodes);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
public function objectProperty(Node $node): string
|
|
274
|
+
{
|
|
275
|
+
return $node instanceof Nodes\NameNode || $node instanceof Nodes\IdentifierNode
|
|
276
|
+
? (string) $node
|
|
277
|
+
: '{' . $node->print($this) . '}';
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
public function memberAsString(Node $node): string
|
|
282
|
+
{
|
|
283
|
+
return $node instanceof Nodes\NameNode || $node instanceof Nodes\IdentifierNode
|
|
284
|
+
? $this->encodeString((string) $node)
|
|
285
|
+
: $node->print($this);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Wraps the LHS of a call in parentheses if needed.
|
|
291
|
+
*/
|
|
292
|
+
public function callExpr(Node $expr): string
|
|
293
|
+
{
|
|
294
|
+
return $expr instanceof Nodes\NameNode
|
|
295
|
+
|| $expr instanceof Expression\VariableNode
|
|
296
|
+
|| $expr instanceof Expression\ArrayAccessNode
|
|
297
|
+
|| $expr instanceof Expression\FunctionCallNode
|
|
298
|
+
|| $expr instanceof Expression\FunctionCallableNode
|
|
299
|
+
|| $expr instanceof Expression\MethodCallNode
|
|
300
|
+
|| $expr instanceof Expression\MethodCallableNode
|
|
301
|
+
|| $expr instanceof Expression\StaticCallNode
|
|
302
|
+
|| $expr instanceof Expression\StaticCallableNode
|
|
303
|
+
|| $expr instanceof Expression\ArrayNode
|
|
304
|
+
? $expr->print($this)
|
|
305
|
+
: '(' . $expr->print($this) . ')';
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Wraps the LHS of a dereferencing operation in parentheses if needed.
|
|
311
|
+
*/
|
|
312
|
+
public function dereferenceExpr(Node $expr): string
|
|
313
|
+
{
|
|
314
|
+
return $expr instanceof Expression\VariableNode
|
|
315
|
+
|| $expr instanceof Nodes\NameNode
|
|
316
|
+
|| $expr instanceof Expression\ArrayAccessNode
|
|
317
|
+
|| $expr instanceof Expression\PropertyFetchNode
|
|
318
|
+
|| $expr instanceof Expression\StaticPropertyFetchNode
|
|
319
|
+
|| $expr instanceof Expression\FunctionCallNode
|
|
320
|
+
|| $expr instanceof Expression\FunctionCallableNode
|
|
321
|
+
|| $expr instanceof Expression\MethodCallNode
|
|
322
|
+
|| $expr instanceof Expression\MethodCallableNode
|
|
323
|
+
|| $expr instanceof Expression\StaticCallNode
|
|
324
|
+
|| $expr instanceof Expression\StaticCallableNode
|
|
325
|
+
|| $expr instanceof Expression\ArrayNode
|
|
326
|
+
|| $expr instanceof Scalar\StringNode
|
|
327
|
+
|| $expr instanceof Scalar\BooleanNode
|
|
328
|
+
|| $expr instanceof Scalar\NullNode
|
|
329
|
+
|| $expr instanceof Expression\ConstantFetchNode
|
|
330
|
+
|| $expr instanceof Expression\ClassConstantFetchNode
|
|
331
|
+
? $expr->print($this)
|
|
332
|
+
: '(' . $expr->print($this) . ')';
|
|
333
|
+
}
|
|
334
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This file is part of the Latte (https://latte.nette.org)
|
|
5
|
+
* Copyright (c) 2008 David Grudl (https://davidgrudl.com)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
declare(strict_types=1);
|
|
9
|
+
|
|
10
|
+
namespace Latte\Compiler;
|
|
11
|
+
|
|
12
|
+
use Latte;
|
|
13
|
+
use Latte\CompileException;
|
|
14
|
+
use Latte\Compiler\Nodes\Html\ElementNode;
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Latte tag or n:attribute.
|
|
19
|
+
*/
|
|
20
|
+
final class Tag
|
|
21
|
+
{
|
|
22
|
+
use Latte\Strict;
|
|
23
|
+
|
|
24
|
+
public const
|
|
25
|
+
PrefixInner = 'inner',
|
|
26
|
+
PrefixTag = 'tag',
|
|
27
|
+
PrefixNone = '';
|
|
28
|
+
|
|
29
|
+
public const
|
|
30
|
+
OutputNone = 0,
|
|
31
|
+
OutputKeepIndentation = 1,
|
|
32
|
+
OutputRemoveIndentation = 2;
|
|
33
|
+
|
|
34
|
+
public TagParser $parser;
|
|
35
|
+
public int $outputMode = self::OutputNone;
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
public function __construct(
|
|
39
|
+
public /*readonly*/ string $name,
|
|
40
|
+
array $tokens,
|
|
41
|
+
public /*readonly*/ Position $position,
|
|
42
|
+
public /*readonly*/ bool $void = false,
|
|
43
|
+
public /*readonly*/ bool $closing = false,
|
|
44
|
+
public /*readonly*/ int $location = 0,
|
|
45
|
+
public /*readonly*/ ?ElementNode $htmlElement = null,
|
|
46
|
+
public ?self $parent = null,
|
|
47
|
+
public /*readonly*/ ?string $prefix = null,
|
|
48
|
+
public ?\stdClass $data = null,
|
|
49
|
+
) {
|
|
50
|
+
$this->data ??= new \stdClass;
|
|
51
|
+
$this->parser = new TagParser($tokens);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
public function isInHead(): bool
|
|
56
|
+
{
|
|
57
|
+
return $this->location === TemplateParser::LocationHead && !$this->parent;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
public function isInText(): bool
|
|
62
|
+
{
|
|
63
|
+
return $this->location <= TemplateParser::LocationText;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
public function isNAttribute(): bool
|
|
68
|
+
{
|
|
69
|
+
return $this->prefix !== null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
public function getNotation(bool $withArgs = false): string
|
|
74
|
+
{
|
|
75
|
+
return $this->isNAttribute()
|
|
76
|
+
? TemplateLexer::NPrefix . ($this->prefix ? $this->prefix . '-' : '')
|
|
77
|
+
. $this->name
|
|
78
|
+
. ($withArgs ? '="' . $this->parser->text . '"' : '')
|
|
79
|
+
: '{'
|
|
80
|
+
. ($this->closing ? '/' : '')
|
|
81
|
+
. $this->name
|
|
82
|
+
. ($withArgs ? $this->parser->text : '')
|
|
83
|
+
. '}';
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @param string[] $names
|
|
89
|
+
*/
|
|
90
|
+
public function closestTag(array $names, ?callable $condition = null): ?self
|
|
91
|
+
{
|
|
92
|
+
$tag = $this->parent;
|
|
93
|
+
while ($tag && (
|
|
94
|
+
!in_array($tag->name, $names, true)
|
|
95
|
+
|| ($condition && !$condition($tag))
|
|
96
|
+
)) {
|
|
97
|
+
$tag = $tag->parent;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return $tag;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
public function expectArguments(string $what = 'arguments'): void
|
|
105
|
+
{
|
|
106
|
+
if ($this->parser->isEnd()) {
|
|
107
|
+
throw new CompileException("Missing $what in " . $this->getNotation(), $this->position);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
public function replaceNAttribute(Node $node): void
|
|
113
|
+
{
|
|
114
|
+
$index = array_search($this->data->node, $this->htmlElement->attributes->children, true);
|
|
115
|
+
$this->htmlElement->attributes->children[$index] = $node;
|
|
116
|
+
}
|
|
117
|
+
}
|