@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.
Files changed (201) hide show
  1. package/README.md +39 -0
  2. package/handler.js +9 -0
  3. package/index.js +138 -0
  4. package/index.php +173 -0
  5. package/latte/AssetFilter.php +11 -0
  6. package/latte/FetchFunction.php +28 -0
  7. package/latte/IconFilter.php +14 -0
  8. package/latte/JsonTag.php +64 -0
  9. package/latte/PlaceholderFunction.php +11 -0
  10. package/latte/RandomColorFunction.php +14 -0
  11. package/latte/TelFilter.php +22 -0
  12. package/package.json +35 -0
  13. package/vendor/autoload.php +7 -0
  14. package/vendor/bin/latte-lint +107 -0
  15. package/vendor/composer/ClassLoader.php +572 -0
  16. package/vendor/composer/InstalledVersions.php +350 -0
  17. package/vendor/composer/LICENSE +21 -0
  18. package/vendor/composer/autoload_classmap.php +183 -0
  19. package/vendor/composer/autoload_namespaces.php +9 -0
  20. package/vendor/composer/autoload_psr4.php +9 -0
  21. package/vendor/composer/autoload_real.php +57 -0
  22. package/vendor/composer/autoload_static.php +193 -0
  23. package/vendor/composer/installed.json +93 -0
  24. package/vendor/composer/installed.php +32 -0
  25. package/vendor/composer/platform_check.php +26 -0
  26. package/vendor/latte/latte/bin/latte-lint +29 -0
  27. package/vendor/latte/latte/composer.json +53 -0
  28. package/vendor/latte/latte/license.md +60 -0
  29. package/vendor/latte/latte/ncs.php +14 -0
  30. package/vendor/latte/latte/ncs.xml +9 -0
  31. package/vendor/latte/latte/readme.md +21 -0
  32. package/vendor/latte/latte/src/Bridges/Tracy/BlueScreenPanel.php +114 -0
  33. package/vendor/latte/latte/src/Bridges/Tracy/LattePanel.php +99 -0
  34. package/vendor/latte/latte/src/Bridges/Tracy/templates/LattePanel.panel.phtml +98 -0
  35. package/vendor/latte/latte/src/Bridges/Tracy/templates/LattePanel.tab.phtml +15 -0
  36. package/vendor/latte/latte/src/Latte/Compiler/Block.php +44 -0
  37. package/vendor/latte/latte/src/Latte/Compiler/Escaper.php +244 -0
  38. package/vendor/latte/latte/src/Latte/Compiler/ExpressionBuilder.php +128 -0
  39. package/vendor/latte/latte/src/Latte/Compiler/Node.php +28 -0
  40. package/vendor/latte/latte/src/Latte/Compiler/NodeHelpers.php +132 -0
  41. package/vendor/latte/latte/src/Latte/Compiler/NodeTraverser.php +77 -0
  42. package/vendor/latte/latte/src/Latte/Compiler/Nodes/AreaNode.php +17 -0
  43. package/vendor/latte/latte/src/Latte/Compiler/Nodes/AuxiliaryNode.php +27 -0
  44. package/vendor/latte/latte/src/Latte/Compiler/Nodes/FragmentNode.php +59 -0
  45. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/AttributeNode.php +48 -0
  46. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/BogusTagNode.php +46 -0
  47. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/CommentNode.php +39 -0
  48. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ElementNode.php +129 -0
  49. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/QuotedValue.php +53 -0
  50. package/vendor/latte/latte/src/Latte/Compiler/Nodes/NopNode.php +21 -0
  51. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ArgumentNode.php +45 -0
  52. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ComplexTypeNode.php +17 -0
  53. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayAccessNode.php +41 -0
  54. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayItemNode.php +52 -0
  55. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayNode.php +94 -0
  56. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignNode.php +39 -0
  57. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignOpNode.php +45 -0
  58. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/BinaryOpNode.php +65 -0
  59. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CastNode.php +43 -0
  60. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClassConstantFetchNode.php +42 -0
  61. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CloneNode.php +36 -0
  62. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClosureNode.php +73 -0
  63. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClosureUseNode.php +37 -0
  64. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ConstantFetchNode.php +37 -0
  65. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/EmptyNode.php +36 -0
  66. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ErrorSuppressNode.php +36 -0
  67. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FilterCallNode.php +39 -0
  68. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FunctionCallNode.php +45 -0
  69. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FunctionCallableNode.php +39 -0
  70. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InRangeNode.php +42 -0
  71. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InstanceofNode.php +40 -0
  72. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/IssetNode.php +40 -0
  73. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MatchNode.php +49 -0
  74. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MethodCallNode.php +50 -0
  75. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MethodCallableNode.php +42 -0
  76. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/NewNode.php +45 -0
  77. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/NotNode.php +36 -0
  78. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PostOpNode.php +43 -0
  79. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PreOpNode.php +43 -0
  80. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PropertyFetchNode.php +42 -0
  81. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticCallNode.php +55 -0
  82. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticCallableNode.php +47 -0
  83. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticPropertyFetchNode.php +42 -0
  84. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TernaryNode.php +50 -0
  85. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/UnaryOpNode.php +45 -0
  86. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/VariableNode.php +40 -0
  87. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ExpressionNode.php +17 -0
  88. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/FilterNode.php +67 -0
  89. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/IdentifierNode.php +36 -0
  90. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/IntersectionTypeNode.php +39 -0
  91. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/MatchArmNode.php +45 -0
  92. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ModifierNode.php +107 -0
  93. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NameNode.php +89 -0
  94. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NullableTypeNode.php +35 -0
  95. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ParameterNode.php +54 -0
  96. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/BooleanNode.php +30 -0
  97. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/EncapsedStringNode.php +80 -0
  98. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/EncapsedStringPartNode.php +30 -0
  99. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/FloatNode.php +63 -0
  100. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/IntegerNode.php +70 -0
  101. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/NullNode.php +29 -0
  102. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/StringNode.php +40 -0
  103. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ScalarNode.php +15 -0
  104. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/SuperiorTypeNode.php +29 -0
  105. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/UnionTypeNode.php +39 -0
  106. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/VarLikeIdentifierNode.php +21 -0
  107. package/vendor/latte/latte/src/Latte/Compiler/Nodes/StatementNode.php +15 -0
  108. package/vendor/latte/latte/src/Latte/Compiler/Nodes/TemplateNode.php +34 -0
  109. package/vendor/latte/latte/src/Latte/Compiler/Nodes/TextNode.php +37 -0
  110. package/vendor/latte/latte/src/Latte/Compiler/PhpHelpers.php +227 -0
  111. package/vendor/latte/latte/src/Latte/Compiler/Position.php +43 -0
  112. package/vendor/latte/latte/src/Latte/Compiler/PrintContext.php +334 -0
  113. package/vendor/latte/latte/src/Latte/Compiler/Tag.php +117 -0
  114. package/vendor/latte/latte/src/Latte/Compiler/TagLexer.php +399 -0
  115. package/vendor/latte/latte/src/Latte/Compiler/TagParser.php +388 -0
  116. package/vendor/latte/latte/src/Latte/Compiler/TagParserData.php +580 -0
  117. package/vendor/latte/latte/src/Latte/Compiler/TemplateGenerator.php +206 -0
  118. package/vendor/latte/latte/src/Latte/Compiler/TemplateLexer.php +391 -0
  119. package/vendor/latte/latte/src/Latte/Compiler/TemplateParser.php +448 -0
  120. package/vendor/latte/latte/src/Latte/Compiler/TemplateParserHtml.php +506 -0
  121. package/vendor/latte/latte/src/Latte/Compiler/Token.php +259 -0
  122. package/vendor/latte/latte/src/Latte/Compiler/TokenStream.php +151 -0
  123. package/vendor/latte/latte/src/Latte/ContentType.php +22 -0
  124. package/vendor/latte/latte/src/Latte/Engine.php +591 -0
  125. package/vendor/latte/latte/src/Latte/Essential/Blueprint.php +160 -0
  126. package/vendor/latte/latte/src/Latte/Essential/CachingIterator.php +232 -0
  127. package/vendor/latte/latte/src/Latte/Essential/CoreExtension.php +232 -0
  128. package/vendor/latte/latte/src/Latte/Essential/Filters.php +591 -0
  129. package/vendor/latte/latte/src/Latte/Essential/Nodes/BlockNode.php +161 -0
  130. package/vendor/latte/latte/src/Latte/Essential/Nodes/CaptureNode.php +98 -0
  131. package/vendor/latte/latte/src/Latte/Essential/Nodes/ContentTypeNode.php +74 -0
  132. package/vendor/latte/latte/src/Latte/Essential/Nodes/DebugbreakNode.php +53 -0
  133. package/vendor/latte/latte/src/Latte/Essential/Nodes/DefineNode.php +134 -0
  134. package/vendor/latte/latte/src/Latte/Essential/Nodes/DoNode.php +49 -0
  135. package/vendor/latte/latte/src/Latte/Essential/Nodes/DumpNode.php +58 -0
  136. package/vendor/latte/latte/src/Latte/Essential/Nodes/EmbedNode.php +125 -0
  137. package/vendor/latte/latte/src/Latte/Essential/Nodes/ExtendsNode.php +60 -0
  138. package/vendor/latte/latte/src/Latte/Essential/Nodes/FirstLastSepNode.php +81 -0
  139. package/vendor/latte/latte/src/Latte/Essential/Nodes/ForNode.php +91 -0
  140. package/vendor/latte/latte/src/Latte/Essential/Nodes/ForeachNode.php +155 -0
  141. package/vendor/latte/latte/src/Latte/Essential/Nodes/IfChangedNode.php +141 -0
  142. package/vendor/latte/latte/src/Latte/Essential/Nodes/IfContentNode.php +82 -0
  143. package/vendor/latte/latte/src/Latte/Essential/Nodes/IfNode.php +180 -0
  144. package/vendor/latte/latte/src/Latte/Essential/Nodes/ImportNode.php +49 -0
  145. package/vendor/latte/latte/src/Latte/Essential/Nodes/IncludeBlockNode.php +140 -0
  146. package/vendor/latte/latte/src/Latte/Essential/Nodes/IncludeFileNode.php +81 -0
  147. package/vendor/latte/latte/src/Latte/Essential/Nodes/IterateWhileNode.php +94 -0
  148. package/vendor/latte/latte/src/Latte/Essential/Nodes/NAttrNode.php +105 -0
  149. package/vendor/latte/latte/src/Latte/Essential/Nodes/NClassNode.php +54 -0
  150. package/vendor/latte/latte/src/Latte/Essential/Nodes/NTagNode.php +79 -0
  151. package/vendor/latte/latte/src/Latte/Essential/Nodes/ParametersNode.php +84 -0
  152. package/vendor/latte/latte/src/Latte/Essential/Nodes/PrintNode.php +70 -0
  153. package/vendor/latte/latte/src/Latte/Essential/Nodes/RawPhpNode.php +46 -0
  154. package/vendor/latte/latte/src/Latte/Essential/Nodes/RollbackNode.php +37 -0
  155. package/vendor/latte/latte/src/Latte/Essential/Nodes/SkipNode.php +71 -0
  156. package/vendor/latte/latte/src/Latte/Essential/Nodes/SpacelessNode.php +62 -0
  157. package/vendor/latte/latte/src/Latte/Essential/Nodes/SwitchNode.php +118 -0
  158. package/vendor/latte/latte/src/Latte/Essential/Nodes/TemplatePrintNode.php +39 -0
  159. package/vendor/latte/latte/src/Latte/Essential/Nodes/TemplateTypeNode.php +38 -0
  160. package/vendor/latte/latte/src/Latte/Essential/Nodes/TraceNode.php +35 -0
  161. package/vendor/latte/latte/src/Latte/Essential/Nodes/TranslateNode.php +104 -0
  162. package/vendor/latte/latte/src/Latte/Essential/Nodes/TryNode.php +75 -0
  163. package/vendor/latte/latte/src/Latte/Essential/Nodes/VarNode.php +106 -0
  164. package/vendor/latte/latte/src/Latte/Essential/Nodes/VarPrintNode.php +40 -0
  165. package/vendor/latte/latte/src/Latte/Essential/Nodes/VarTypeNode.php +36 -0
  166. package/vendor/latte/latte/src/Latte/Essential/Nodes/WhileNode.php +81 -0
  167. package/vendor/latte/latte/src/Latte/Essential/Passes.php +115 -0
  168. package/vendor/latte/latte/src/Latte/Essential/RawPhpExtension.php +28 -0
  169. package/vendor/latte/latte/src/Latte/Essential/RollbackException.php +16 -0
  170. package/vendor/latte/latte/src/Latte/Essential/Tracer.php +117 -0
  171. package/vendor/latte/latte/src/Latte/Essential/TranslatorExtension.php +101 -0
  172. package/vendor/latte/latte/src/Latte/Extension.php +97 -0
  173. package/vendor/latte/latte/src/Latte/Helpers.php +96 -0
  174. package/vendor/latte/latte/src/Latte/Loader.php +37 -0
  175. package/vendor/latte/latte/src/Latte/Loaders/FileLoader.php +95 -0
  176. package/vendor/latte/latte/src/Latte/Loaders/StringLoader.php +76 -0
  177. package/vendor/latte/latte/src/Latte/Policy.php +24 -0
  178. package/vendor/latte/latte/src/Latte/PositionAwareException.php +50 -0
  179. package/vendor/latte/latte/src/Latte/Runtime/Block.php +24 -0
  180. package/vendor/latte/latte/src/Latte/Runtime/FilterExecutor.php +151 -0
  181. package/vendor/latte/latte/src/Latte/Runtime/FilterInfo.php +39 -0
  182. package/vendor/latte/latte/src/Latte/Runtime/Filters.php +234 -0
  183. package/vendor/latte/latte/src/Latte/Runtime/Html.php +35 -0
  184. package/vendor/latte/latte/src/Latte/Runtime/HtmlStringable.php +17 -0
  185. package/vendor/latte/latte/src/Latte/Runtime/Template.php +381 -0
  186. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/FunctionCallNode.php +30 -0
  187. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/FunctionCallableNode.php +29 -0
  188. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/MethodCallNode.php +32 -0
  189. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/MethodCallableNode.php +30 -0
  190. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/PropertyFetchNode.php +32 -0
  191. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/SandboxNode.php +73 -0
  192. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticCallNode.php +31 -0
  193. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticCallableNode.php +30 -0
  194. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticPropertyFetchNode.php +32 -0
  195. package/vendor/latte/latte/src/Latte/Sandbox/RuntimeChecker.php +116 -0
  196. package/vendor/latte/latte/src/Latte/Sandbox/SandboxExtension.php +132 -0
  197. package/vendor/latte/latte/src/Latte/Sandbox/SecurityPolicy.php +185 -0
  198. package/vendor/latte/latte/src/Latte/Strict.php +101 -0
  199. package/vendor/latte/latte/src/Latte/attributes.php +24 -0
  200. package/vendor/latte/latte/src/Latte/exceptions.php +69 -0
  201. 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
+ }