@vituum/vite-plugin-latte 2.0.0-next.5 → 2.0.1

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 (213) hide show
  1. package/README.md +1 -1
  2. package/index.js +2 -1
  3. package/package.json +20 -10
  4. package/vendor/composer/autoload_classmap.php +3 -2
  5. package/vendor/composer/autoload_static.php +3 -2
  6. package/vendor/composer/installed.json +21 -17
  7. package/vendor/composer/installed.php +8 -8
  8. package/vendor/latte/latte/composer.json +9 -2
  9. package/vendor/latte/latte/src/Bridges/Tracy/BlueScreenPanel.php +7 -7
  10. package/vendor/latte/latte/src/Bridges/Tracy/LattePanel.php +5 -4
  11. package/vendor/latte/latte/src/Bridges/Tracy/TracyExtension.php +2 -4
  12. package/vendor/latte/latte/src/Bridges/Tracy/dist/panel.phtml +2 -4
  13. package/vendor/latte/latte/src/Bridges/Tracy/dist/tab.phtml +2 -4
  14. package/vendor/latte/latte/src/Latte/Compiler/Block.php +1 -3
  15. package/vendor/latte/latte/src/Latte/Compiler/Escaper.php +4 -8
  16. package/vendor/latte/latte/src/Latte/Compiler/Node.php +6 -3
  17. package/vendor/latte/latte/src/Latte/Compiler/NodeHelpers.php +15 -6
  18. package/vendor/latte/latte/src/Latte/Compiler/NodeTraverser.php +14 -9
  19. package/vendor/latte/latte/src/Latte/Compiler/Nodes/AreaNode.php +7 -3
  20. package/vendor/latte/latte/src/Latte/Compiler/Nodes/AuxiliaryNode.php +4 -3
  21. package/vendor/latte/latte/src/Latte/Compiler/Nodes/FragmentNode.php +5 -4
  22. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/AttributeNode.php +6 -5
  23. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/BogusTagNode.php +4 -6
  24. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/CommentNode.php +4 -3
  25. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ElementNode.php +5 -7
  26. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ExpressionAttributeNode.php +6 -4
  27. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/TagNode.php +1 -3
  28. package/vendor/latte/latte/src/Latte/Compiler/Nodes/NopNode.php +4 -3
  29. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ArgumentNode.php +4 -3
  30. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ArrayItemNode.php +4 -3
  31. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ClosureUseNode.php +4 -3
  32. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ComplexTypeNode.php +4 -3
  33. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayAccessNode.php +4 -3
  34. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayNode.php +4 -3
  35. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignNode.php +4 -3
  36. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignOpNode.php +5 -4
  37. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AuxiliaryNode.php +4 -3
  38. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/BinaryOpNode.php +5 -4
  39. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CastNode.php +4 -3
  40. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClassConstantFetchNode.php +4 -3
  41. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CloneNode.php +4 -3
  42. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClosureNode.php +7 -6
  43. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ConstantFetchNode.php +5 -4
  44. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/EmptyNode.php +4 -3
  45. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FilterCallNode.php +4 -3
  46. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FunctionCallNode.php +4 -3
  47. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InNode.php +4 -3
  48. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InstanceofNode.php +4 -3
  49. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/IssetNode.php +4 -3
  50. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MatchNode.php +4 -3
  51. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MethodCallNode.php +4 -3
  52. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/NewNode.php +4 -3
  53. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PostOpNode.php +4 -3
  54. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PreOpNode.php +4 -3
  55. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PropertyFetchNode.php +4 -3
  56. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticMethodCallNode.php +4 -3
  57. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticPropertyFetchNode.php +4 -3
  58. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TemporaryNode.php +7 -6
  59. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TernaryNode.php +4 -3
  60. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/UnaryOpNode.php +4 -3
  61. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/VariableNode.php +4 -3
  62. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ExpressionNode.php +4 -3
  63. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/FilterNode.php +4 -3
  64. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/IdentifierNode.php +4 -3
  65. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/InterpolatedStringPartNode.php +4 -3
  66. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/IntersectionTypeNode.php +4 -3
  67. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ListItemNode.php +4 -3
  68. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ListNode.php +4 -3
  69. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/MatchArmNode.php +4 -3
  70. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ModifierNode.php +4 -3
  71. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NameNode.php +4 -3
  72. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NullableTypeNode.php +4 -3
  73. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/OperatorNode.php +1 -3
  74. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ParameterNode.php +4 -3
  75. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/BooleanNode.php +4 -3
  76. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/FloatNode.php +5 -4
  77. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/IntegerNode.php +5 -4
  78. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/InterpolatedStringNode.php +6 -5
  79. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/NullNode.php +4 -3
  80. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/StringNode.php +5 -4
  81. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ScalarNode.php +4 -3
  82. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/SuperiorTypeNode.php +4 -3
  83. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/UnionTypeNode.php +4 -3
  84. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/VarLikeIdentifierNode.php +4 -3
  85. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/VariadicPlaceholderNode.php +4 -3
  86. package/vendor/latte/latte/src/Latte/Compiler/Nodes/PrintNode.php +3 -4
  87. package/vendor/latte/latte/src/Latte/Compiler/Nodes/StatementNode.php +7 -3
  88. package/vendor/latte/latte/src/Latte/Compiler/Nodes/TemplateNode.php +4 -3
  89. package/vendor/latte/latte/src/Latte/Compiler/Nodes/TextNode.php +5 -4
  90. package/vendor/latte/latte/src/Latte/Compiler/PhpHelpers.php +23 -15
  91. package/vendor/latte/latte/src/Latte/Compiler/Position.php +5 -7
  92. package/vendor/latte/latte/src/Latte/Compiler/PrintContext.php +30 -9
  93. package/vendor/latte/latte/src/Latte/Compiler/Tag.php +6 -6
  94. package/vendor/latte/latte/src/Latte/Compiler/TagLexer.php +4 -6
  95. package/vendor/latte/latte/src/Latte/Compiler/TagParser.php +14 -11
  96. package/vendor/latte/latte/src/Latte/Compiler/TagParserData.php +2 -4
  97. package/vendor/latte/latte/src/Latte/Compiler/TemplateGenerator.php +13 -11
  98. package/vendor/latte/latte/src/Latte/Compiler/TemplateLexer.php +21 -7
  99. package/vendor/latte/latte/src/Latte/Compiler/TemplateParser.php +32 -19
  100. package/vendor/latte/latte/src/Latte/Compiler/TemplateParserHtml.php +28 -21
  101. package/vendor/latte/latte/src/Latte/Compiler/Token.php +10 -9
  102. package/vendor/latte/latte/src/Latte/Compiler/TokenStream.php +20 -14
  103. package/vendor/latte/latte/src/Latte/ContentType.php +4 -3
  104. package/vendor/latte/latte/src/Latte/Engine.php +64 -35
  105. package/vendor/latte/latte/src/Latte/Essential/AuxiliaryIterator.php +3 -7
  106. package/vendor/latte/latte/src/Latte/Essential/Blueprint.php +4 -5
  107. package/vendor/latte/latte/src/Latte/Essential/CachingIterator.php +2 -3
  108. package/vendor/latte/latte/src/Latte/Essential/CoreExtension.php +1 -3
  109. package/vendor/latte/latte/src/Latte/Essential/Filters.php +65 -32
  110. package/vendor/latte/latte/src/Latte/Essential/Nodes/BlockNode.php +8 -6
  111. package/vendor/latte/latte/src/Latte/Essential/Nodes/CaptureNode.php +5 -6
  112. package/vendor/latte/latte/src/Latte/Essential/Nodes/ContentTypeNode.php +3 -4
  113. package/vendor/latte/latte/src/Latte/Essential/Nodes/CustomFunctionCallNode.php +2 -4
  114. package/vendor/latte/latte/src/Latte/Essential/Nodes/DebugbreakNode.php +2 -3
  115. package/vendor/latte/latte/src/Latte/Essential/Nodes/DefineNode.php +6 -6
  116. package/vendor/latte/latte/src/Latte/Essential/Nodes/DoNode.php +3 -4
  117. package/vendor/latte/latte/src/Latte/Essential/Nodes/DumpNode.php +2 -3
  118. package/vendor/latte/latte/src/Latte/Essential/Nodes/EmbedNode.php +3 -5
  119. package/vendor/latte/latte/src/Latte/Essential/Nodes/ExtendsNode.php +3 -5
  120. package/vendor/latte/latte/src/Latte/Essential/Nodes/FirstLastSepNode.php +4 -7
  121. package/vendor/latte/latte/src/Latte/Essential/Nodes/ForNode.php +3 -5
  122. package/vendor/latte/latte/src/Latte/Essential/Nodes/ForeachNode.php +7 -8
  123. package/vendor/latte/latte/src/Latte/Essential/Nodes/IfChangedNode.php +4 -5
  124. package/vendor/latte/latte/src/Latte/Essential/Nodes/IfContentNode.php +7 -6
  125. package/vendor/latte/latte/src/Latte/Essential/Nodes/IfNode.php +6 -9
  126. package/vendor/latte/latte/src/Latte/Essential/Nodes/ImportNode.php +3 -4
  127. package/vendor/latte/latte/src/Latte/Essential/Nodes/IncludeBlockNode.php +8 -7
  128. package/vendor/latte/latte/src/Latte/Essential/Nodes/IncludeFileNode.php +2 -4
  129. package/vendor/latte/latte/src/Latte/Essential/Nodes/IterateWhileNode.php +6 -6
  130. package/vendor/latte/latte/src/Latte/Essential/Nodes/JumpNode.php +4 -8
  131. package/vendor/latte/latte/src/Latte/Essential/Nodes/NAttrNode.php +3 -5
  132. package/vendor/latte/latte/src/Latte/Essential/Nodes/NClassNode.php +3 -4
  133. package/vendor/latte/latte/src/Latte/Essential/Nodes/NElseNode.php +8 -5
  134. package/vendor/latte/latte/src/Latte/Essential/Nodes/NTagNode.php +4 -4
  135. package/vendor/latte/latte/src/Latte/Essential/Nodes/ParametersNode.php +4 -4
  136. package/vendor/latte/latte/src/Latte/Essential/Nodes/RawPhpNode.php +2 -4
  137. package/vendor/latte/latte/src/Latte/Essential/Nodes/RollbackNode.php +2 -3
  138. package/vendor/latte/latte/src/Latte/Essential/Nodes/SpacelessNode.php +4 -5
  139. package/vendor/latte/latte/src/Latte/Essential/Nodes/SwitchNode.php +9 -7
  140. package/vendor/latte/latte/src/Latte/Essential/Nodes/TemplatePrintNode.php +3 -4
  141. package/vendor/latte/latte/src/Latte/Essential/Nodes/TemplateTypeNode.php +3 -4
  142. package/vendor/latte/latte/src/Latte/Essential/Nodes/TraceNode.php +2 -3
  143. package/vendor/latte/latte/src/Latte/Essential/Nodes/TranslateNode.php +3 -4
  144. package/vendor/latte/latte/src/Latte/Essential/Nodes/TryNode.php +4 -5
  145. package/vendor/latte/latte/src/Latte/Essential/Nodes/VarNode.php +8 -7
  146. package/vendor/latte/latte/src/Latte/Essential/Nodes/VarPrintNode.php +2 -3
  147. package/vendor/latte/latte/src/Latte/Essential/Nodes/VarTypeNode.php +3 -4
  148. package/vendor/latte/latte/src/Latte/Essential/Nodes/WhileNode.php +5 -5
  149. package/vendor/latte/latte/src/Latte/Essential/Passes.php +26 -15
  150. package/vendor/latte/latte/src/Latte/Essential/RawPhpExtension.php +1 -3
  151. package/vendor/latte/latte/src/Latte/Essential/RollbackException.php +1 -3
  152. package/vendor/latte/latte/src/Latte/Essential/Tracer.php +20 -13
  153. package/vendor/latte/latte/src/Latte/Essential/TranslatorExtension.php +9 -10
  154. package/vendor/latte/latte/src/Latte/Extension.php +10 -6
  155. package/vendor/latte/latte/src/Latte/Feature.php +24 -0
  156. package/vendor/latte/latte/src/Latte/Helpers.php +18 -10
  157. package/vendor/latte/latte/src/Latte/Loader.php +1 -3
  158. package/vendor/latte/latte/src/Latte/Loaders/FileLoader.php +8 -5
  159. package/vendor/latte/latte/src/Latte/Loaders/StringLoader.php +5 -13
  160. package/vendor/latte/latte/src/Latte/Policy.php +4 -3
  161. package/vendor/latte/latte/src/Latte/Runtime/Block.php +2 -4
  162. package/vendor/latte/latte/src/Latte/{Cache.php → Runtime/Cache.php} +12 -11
  163. package/vendor/latte/latte/src/Latte/Runtime/FilterExecutor.php +3 -5
  164. package/vendor/latte/latte/src/Latte/Runtime/FilterInfo.php +10 -11
  165. package/vendor/latte/latte/src/Latte/Runtime/FunctionExecutor.php +4 -6
  166. package/vendor/latte/latte/src/Latte/Runtime/Helpers.php +5 -7
  167. package/vendor/latte/latte/src/Latte/Runtime/Html.php +3 -5
  168. package/vendor/latte/latte/src/Latte/Runtime/HtmlHelpers.php +18 -18
  169. package/vendor/latte/latte/src/Latte/Runtime/HtmlStringable.php +1 -3
  170. package/vendor/latte/latte/src/Latte/Runtime/Template.php +23 -42
  171. package/vendor/latte/latte/src/Latte/Runtime/XmlHelpers.php +5 -7
  172. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/FunctionCallNode.php +14 -8
  173. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/MethodCallNode.php +17 -11
  174. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/PropertyFetchNode.php +4 -3
  175. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/SandboxNode.php +3 -4
  176. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticMethodCallNode.php +16 -10
  177. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticPropertyFetchNode.php +4 -3
  178. package/vendor/latte/latte/src/Latte/Sandbox/RuntimeChecker.php +6 -5
  179. package/vendor/latte/latte/src/Latte/Sandbox/SandboxExtension.php +5 -4
  180. package/vendor/latte/latte/src/Latte/Sandbox/SecurityPolicy.php +17 -16
  181. package/vendor/latte/latte/src/Latte/attributes.php +7 -3
  182. package/vendor/latte/latte/src/Latte/exceptions.php +38 -3
  183. package/vendor/latte/latte/src/Tools/Linter.php +20 -14
  184. package/vendor/latte/latte/src/Tools/LinterExtension.php +26 -7
  185. package/vendor/nette/utils/composer.json +8 -1
  186. package/vendor/nette/utils/src/HtmlStringable.php +4 -1
  187. package/vendor/nette/utils/src/Iterators/CachingIterator.php +9 -24
  188. package/vendor/nette/utils/src/Iterators/Mapper.php +2 -3
  189. package/vendor/nette/utils/src/SmartObject.php +3 -0
  190. package/vendor/nette/utils/src/StaticClass.php +1 -1
  191. package/vendor/nette/utils/src/Translator.php +1 -1
  192. package/vendor/nette/utils/src/Utils/ArrayHash.php +1 -5
  193. package/vendor/nette/utils/src/Utils/ArrayList.php +3 -6
  194. package/vendor/nette/utils/src/Utils/Arrays.php +33 -10
  195. package/vendor/nette/utils/src/Utils/Callback.php +12 -7
  196. package/vendor/nette/utils/src/Utils/DateTime.php +1 -1
  197. package/vendor/nette/utils/src/Utils/FileInfo.php +5 -7
  198. package/vendor/nette/utils/src/Utils/FileSystem.php +5 -2
  199. package/vendor/nette/utils/src/Utils/Finder.php +27 -8
  200. package/vendor/nette/utils/src/Utils/Helpers.php +7 -1
  201. package/vendor/nette/utils/src/Utils/Html.php +123 -118
  202. package/vendor/nette/utils/src/Utils/Image.php +72 -54
  203. package/vendor/nette/utils/src/Utils/ImageColor.php +4 -0
  204. package/vendor/nette/utils/src/Utils/Iterables.php +16 -8
  205. package/vendor/nette/utils/src/Utils/Paginator.php +10 -43
  206. package/vendor/nette/utils/src/Utils/Reflection.php +17 -7
  207. package/vendor/nette/utils/src/Utils/ReflectionMethod.php +4 -1
  208. package/vendor/nette/utils/src/Utils/Strings.php +48 -15
  209. package/vendor/nette/utils/src/Utils/Type.php +41 -27
  210. package/vendor/nette/utils/src/Utils/Validators.php +8 -7
  211. package/vendor/latte/latte/src/Bridges/Tracy/panel.latte +0 -94
  212. package/vendor/latte/latte/src/Bridges/Tracy/tab.latte +0 -8
  213. package/vendor/latte/latte/src/Latte/PositionAwareException.php +0 -47
@@ -1,12 +1,10 @@
1
- <?php
1
+ <?php declare(strict_types=1);
2
2
 
3
3
  /**
4
4
  * This file is part of the Latte (https://latte.nette.org)
5
5
  * Copyright (c) 2008 David Grudl (https://davidgrudl.com)
6
6
  */
7
7
 
8
- declare(strict_types=1);
9
-
10
8
  namespace Latte\Compiler;
11
9
 
12
10
  use Latte;
@@ -20,6 +18,9 @@ use Latte\SecurityViolationException;
20
18
  use function array_keys, array_splice, count, end, in_array, preg_match, str_ends_with, str_starts_with, substr, trim, ucfirst;
21
19
 
22
20
 
21
+ /**
22
+ * Parses Latte template tokens into AST.
23
+ */
23
24
  final class TemplateParser
24
25
  {
25
26
  /** @var Block[][] */
@@ -29,26 +30,29 @@ final class TemplateParser
29
30
  public bool $strict = false;
30
31
  public ?Nodes\TextNode $lastIndentation = null;
31
32
 
32
- /** @var array<string, callable(Tag, self): (Node|\Generator|void)> */
33
+ /** @var array<string, \Closure(Tag, self): (Node|\Generator|void)> */
33
34
  private array $tagParsers = [];
34
35
 
35
36
  /** @var array<string, \stdClass> */
36
37
  private array $attrParsersInfo = [];
37
38
 
38
39
  private TemplateParserHtml $html;
39
- private ?TokenStream $stream = null;
40
+ private TokenStream $stream;
40
41
  private TemplateLexer $lexer;
41
42
  private ?Policy $policy = null;
42
43
  private string $contentType;
43
44
  private int $counter = 0;
44
45
  private ?Tag $tag = null;
45
- private $lastResolver;
46
+ private ?\Closure $lastResolver = null;
47
+
48
+ /** @var \WeakMap<Tag, ?list<string>> */
46
49
  private \WeakMap $lookFor;
47
50
 
48
51
 
49
52
  public function __construct()
50
53
  {
51
54
  $this->lexer = new TemplateLexer;
55
+ $this->stream = new TokenStream(new \EmptyIterator);
52
56
  $this->setContentType(ContentType::Html);
53
57
  }
54
58
 
@@ -83,7 +87,11 @@ final class TemplateParser
83
87
  }
84
88
 
85
89
 
86
- public function parseFragment(callable $resolver, ?callable $after = null): FragmentNode
90
+ /**
91
+ * @param \Closure(FragmentNode): ?Node $resolver
92
+ * @param ?(\Closure(FragmentNode): void) $after
93
+ */
94
+ public function parseFragment(\Closure $resolver, ?\Closure $after = null): FragmentNode
87
95
  {
88
96
  $res = new FragmentNode;
89
97
  $save = [$this->lastResolver, $this->tag];
@@ -91,6 +99,7 @@ final class TemplateParser
91
99
  try {
92
100
  while (!$this->stream->peek()->isEnd()) {
93
101
  if ($node = $resolver($res)) {
102
+ assert($node instanceof Nodes\AreaNode);
94
103
  $res->append($node);
95
104
  $after && $after($res);
96
105
  } else {
@@ -150,7 +159,7 @@ final class TemplateParser
150
159
 
151
160
  public function parseLatteComment(): Nodes\NopNode
152
161
  {
153
- if (str_ends_with($this->stream->peek(-1)?->text ?? "\n", "\n")) {
162
+ if (str_ends_with($this->stream->tryPeek(-1)->text ?? "\n", "\n")) {
154
163
  $this->lastIndentation ??= new Nodes\TextNode('');
155
164
  }
156
165
  $openToken = $this->stream->consume(Token::Latte_CommentOpen);
@@ -162,11 +171,11 @@ final class TemplateParser
162
171
  }
163
172
 
164
173
 
165
- public function parseLatteStatement(?callable $resolver = null): ?Node
174
+ public function parseLatteStatement(?\Closure $resolver = null): ?Node
166
175
  {
167
176
  $this->lexer->pushState(TemplateLexer::StateLatteTag);
168
177
  if ($this->stream->peek(1)->is(Token::Slash)
169
- || (isset($this->tag, $this->lookFor[$this->tag]) && in_array($this->stream->peek(1)->text, $this->lookFor[$this->tag], true))
178
+ || (isset($this->tag, $this->lookFor[$this->tag]) && in_array($this->stream->peek(1)->text, $this->lookFor[$this->tag], strict: true))
170
179
  ) {
171
180
  $this->lexer->popState();
172
181
  return null; // go back to previous parseLatteStatement()
@@ -212,13 +221,13 @@ final class TemplateParser
212
221
  $res->send([$content, $tag]);
213
222
  $this->ensureIsConsumed($tag);
214
223
  break;
215
- } elseif (in_array($tag->name, $this->lookFor[$startTag] ?? [], true)) {
224
+ } elseif (in_array($tag->name, $this->lookFor[$startTag] ?? [], strict: true)) {
216
225
  $this->pushTag($tag);
217
226
  $res->send([$content, $tag]);
218
227
  $this->ensureIsConsumed($tag);
219
228
  $this->popTag();
220
229
  } else {
221
- throw new CompileException('Unexpected tag ' . substr($tag->getNotation(true), 0, -1) . '}', $tag->position);
230
+ throw new CompileException('Unexpected tag ' . substr($tag->getNotation(withArgs: true), 0, -1) . '}', $tag->position);
222
231
  }
223
232
  }
224
233
  }
@@ -230,7 +239,7 @@ final class TemplateParser
230
239
  $node = $res->getReturn();
231
240
 
232
241
  } elseif ($startTag->void) {
233
- throw new CompileException('Unexpected /} in tag ' . substr($startTag->getNotation(true), 0, -1) . '/}', $startTag->position);
242
+ throw new CompileException('Unexpected /} in tag ' . substr($startTag->getNotation(withArgs: true), 0, -1) . '/}', $startTag->position);
234
243
 
235
244
  } else {
236
245
  $this->ensureIsConsumed($startTag);
@@ -256,17 +265,19 @@ final class TemplateParser
256
265
  private function parseLatteTag(): Tag
257
266
  {
258
267
  $stream = $this->stream;
259
- if (str_ends_with($stream->peek(-1)?->text ?? "\n", "\n")) {
268
+ if (str_ends_with($stream->tryPeek(-1)->text ?? "\n", "\n")) {
260
269
  $this->lastIndentation ??= new Nodes\TextNode('');
261
270
  }
262
271
 
263
- $inTag = in_array($this->lexer->getState(), [TemplateLexer::StateHtmlTag, TemplateLexer::StateHtmlQuotedValue, TemplateLexer::StateHtmlComment, TemplateLexer::StateHtmlBogus], true);
272
+ $inTag = in_array($this->lexer->getState(), [TemplateLexer::StateHtmlTag, TemplateLexer::StateHtmlQuotedValue, TemplateLexer::StateHtmlComment, TemplateLexer::StateHtmlBogus], strict: true);
264
273
  $openToken = $stream->consume(Token::Latte_TagOpen);
265
274
  $this->lexer->pushState(TemplateLexer::StateLatteTag);
275
+ $closing = (bool) $stream->tryConsume(Token::Slash);
276
+ $nameToken = $stream->tryConsume(Token::Latte_Name);
266
277
  $tag = new Tag(
267
278
  position: $openToken->position,
268
- closing: $closing = (bool) $stream->tryConsume(Token::Slash),
269
- name: $stream->tryConsume(Token::Latte_Name)?->text ?? ($closing ? '' : '='),
279
+ closing: $closing,
280
+ name: $nameToken ? $nameToken->text : ($closing ? '' : '='),
270
281
  tokens: $this->consumeTag(),
271
282
  void: (bool) $stream->tryConsume(Token::Slash),
272
283
  inHead: $this->inHead,
@@ -279,6 +290,7 @@ final class TemplateParser
279
290
  }
280
291
 
281
292
 
293
+ /** @return Token[] */
282
294
  public function consumeTag(): array
283
295
  {
284
296
  $res = [];
@@ -310,8 +322,8 @@ final class TemplateParser
310
322
  }
311
323
 
312
324
 
313
- /** @return callable(Tag, self): (Node|\Generator|void) */
314
- private function getTagParser(string $name, Position $pos): callable
325
+ /** @return \Closure(Tag, self): (Node|\Generator|void) */
326
+ private function getTagParser(string $name, Position $pos): \Closure
315
327
  {
316
328
  if (!isset($this->tagParsers[$name])) {
317
329
  $hint = ($t = Helpers::getSuggestion(array_keys($this->tagParsers), $name))
@@ -329,6 +341,7 @@ final class TemplateParser
329
341
  }
330
342
 
331
343
 
344
+ /** @return array<string, \Closure(Tag, self): (Node|\Generator|void)> */
332
345
  private function completeAttrParsers(): array
333
346
  {
334
347
  $list = Helpers::sortBeforeAfter($this->attrParsersInfo);
@@ -1,12 +1,10 @@
1
- <?php
1
+ <?php declare(strict_types=1);
2
2
 
3
3
  /**
4
4
  * This file is part of the Latte (https://latte.nette.org)
5
5
  * Copyright (c) 2008 David Grudl (https://davidgrudl.com)
6
6
  */
7
7
 
8
- declare(strict_types=1);
9
-
10
8
  namespace Latte\Compiler;
11
9
 
12
10
  use Latte;
@@ -25,22 +23,20 @@ use function array_keys, array_pop, end, implode, in_array, key, preg_replace, s
25
23
  */
26
24
  final class TemplateParserHtml
27
25
  {
28
- /** @var array<string, callable(Tag, TemplateParser): (Node|\Generator|void)> */
29
- private readonly array $attrParsers;
30
26
  private ?Html\ElementNode $element = null;
31
- private readonly TemplateParser $parser;
32
27
 
33
- /** @var array{string, ?Nodes\Php\ExpressionNode} */
28
+ /** @var array{string, ?Nodes\Php\ExpressionNode}|null */
34
29
  private ?array $endName = null;
35
30
 
36
31
  /** @var \WeakMap<Html\ElementNode, object{tag: mixed, textualName: string, unclosedTags?: array<string>}> */
37
32
  private \WeakMap $elementData;
38
33
 
39
34
 
40
- public function __construct(TemplateParser $parser, array $attrParsers)
41
- {
42
- $this->parser = $parser;
43
- $this->attrParsers = $attrParsers;
35
+ public function __construct(
36
+ private readonly TemplateParser $parser,
37
+ /** @var array<string, \Closure(Tag, TemplateParser): (Node|\Generator|void)> */
38
+ private readonly array $attrParsers,
39
+ ) {
44
40
  $this->elementData = new \WeakMap;
45
41
  }
46
42
 
@@ -85,7 +81,7 @@ final class TemplateParserHtml
85
81
  $stream = $this->parser->getStream();
86
82
  $lexer = $this->parser->getLexer();
87
83
  $lexer->pushState(TemplateLexer::StateHtmlTag);
88
- $closing = $stream->peek(1)?->is(Token::Slash);
84
+ $closing = $stream->tryPeek(1)?->is(Token::Slash);
89
85
  $lexer->popState();
90
86
  if (!$closing) {
91
87
  return $this->parseElement();
@@ -100,7 +96,7 @@ final class TemplateParserHtml
100
96
  return null; // go to parseElement() one level up to close the element
101
97
  }
102
98
  $stream->seek($save);
103
- if (!in_array($endText, $this->elementData[$this->element]->unclosedTags ?? [], true)) {
99
+ if (!in_array($endText, $this->elementData[$this->element]->unclosedTags ?? [], strict: true)) {
104
100
  return null; // go to parseElement() one level up to collapse
105
101
  }
106
102
  }
@@ -145,7 +141,7 @@ final class TemplateParserHtml
145
141
  $this->parser->getLexer()->popState();
146
142
  }
147
143
 
148
- [$endText, $endVariable] = $this->endName;
144
+ [$endText, $endVariable] = $this->endName ?? [null, null];
149
145
  $this->endName = null;
150
146
  if ($endText && ($this->element->is($endText) || $this->elementData[$this->element]->textualName === $endText)) {
151
147
  $elem->content = $content;
@@ -159,7 +155,7 @@ final class TemplateParserHtml
159
155
  ) {
160
156
  $stream->throwUnexpectedException(
161
157
  addendum: ", expecting </{$this->elementData[$elem]->textualName}> for element started $elem->position",
162
- excerpt: $endText ? "/{$endText}>" : $stream->peek(1)?->text . $stream->peek(2)?->text,
158
+ excerpt: $endText ? "/{$endText}>" : ($stream->tryPeek(1)->text ?? '') . ($stream->tryPeek(2)->text ?? ''),
163
159
  );
164
160
  } else { // element collapsed to tags
165
161
  $res->append($content);
@@ -193,6 +189,7 @@ final class TemplateParserHtml
193
189
  }
194
190
 
195
191
 
192
+ /** @param-out Html\ElementNode $elem */
196
193
  private function parseStartTag(&$elem = null): Html\ElementNode
197
194
  {
198
195
  $stream = $this->parser->getStream();
@@ -252,7 +249,8 @@ final class TemplateParserHtml
252
249
  /** @return array{string, ?Nodes\Php\ExpressionNode} */
253
250
  private function parseTagName(bool $strict = true): array
254
251
  {
255
- $variable = $text = null;
252
+ $variable = null;
253
+ $text = '';
256
254
  $parts = [];
257
255
  $stream = $this->parser->getStream();
258
256
  do {
@@ -261,7 +259,7 @@ final class TemplateParserHtml
261
259
  $statement = $this->parser->parseLatteStatement($this->inTagResolve(...));
262
260
  if (!$statement instanceof Nodes\PrintNode) {
263
261
  if (!$parts || $strict) {
264
- throw new CompileException('Only expression can be used as a HTML tag name.', $statement->position);
262
+ throw new CompileException('Only expression can be used as a HTML tag name.', $statement?->position);
265
263
  }
266
264
  $stream->seek($save);
267
265
  break;
@@ -291,7 +289,7 @@ final class TemplateParserHtml
291
289
  }
292
290
 
293
291
 
294
- private function parseBogusEndTag(): ?Html\BogusTagNode
292
+ private function parseBogusEndTag(): Html\BogusTagNode
295
293
  {
296
294
  $stream = $this->parser->getStream();
297
295
  $lexer = $this->parser->getLexer();
@@ -371,7 +369,7 @@ final class TemplateParserHtml
371
369
  $name = $this->parser->parseText();
372
370
  }
373
371
 
374
- [$value, $quote] = $this->parseAttributeValue();
372
+ [$value, $quote] = $this->parseAttributeValue() ?? [null, null];
375
373
  if ($name instanceof Nodes\TextNode && $value instanceof Nodes\PrintNode && $value->modifier->escape) {
376
374
  if (($indent = end($fragment->children)) instanceof Nodes\TextNode && $indent->isWhitespace()) {
377
375
  array_pop($fragment->children);
@@ -395,6 +393,7 @@ final class TemplateParserHtml
395
393
  }
396
394
 
397
395
 
396
+ /** @return ?array{AreaNode|Nodes\PrintNode, ?string} */
398
397
  private function parseAttributeValue(): ?array
399
398
  {
400
399
  $stream = $this->parser->getStream();
@@ -410,6 +409,7 @@ final class TemplateParserHtml
410
409
  $lexer = $this->parser->getLexer();
411
410
  $lexer->pushState(TemplateLexer::StateHtmlQuotedValue, $quoteToken->text);
412
411
  $value = $this->parser->parseFragment($this->parser->inTextResolve(...))->simplify(allowsNull: false);
412
+ assert($value !== null);
413
413
  $stream->tryConsume(Token::Quote) || $stream->throwUnexpectedException([$quoteToken->text], addendum: ", end of HTML attribute started $quoteToken->position");
414
414
  $lexer->popState();
415
415
  return [$value, $quoteToken->text];
@@ -429,6 +429,7 @@ final class TemplateParserHtml
429
429
 
430
430
  private function parseNAttribute(): Nodes\TextNode
431
431
  {
432
+ assert($this->element !== null);
432
433
  $stream = $this->parser->getStream();
433
434
  $nameToken = $stream->consume(Token::Html_Name);
434
435
  $save = $stream->getIndex();
@@ -468,6 +469,8 @@ final class TemplateParserHtml
468
469
  }
469
470
  $tokens ??= [new Token(Token::End, '', $pos)];
470
471
 
472
+ assert($nameToken->position !== null);
473
+ assert($this->element !== null);
471
474
  $this->element->nAttributes[$name] = new Tag(
472
475
  name: preg_replace('~(inner-|tag-|)~', '', $name),
473
476
  tokens: $tokens,
@@ -520,6 +523,10 @@ final class TemplateParserHtml
520
523
  }
521
524
 
522
525
 
526
+ /**
527
+ * @param array<Tag> $attrs
528
+ * @return array<string, list<Tag>>
529
+ */
523
530
  private function prepareNAttrs(array $attrs, bool $void): array
524
531
  {
525
532
  $res = [];
@@ -591,8 +598,8 @@ final class TemplateParserHtml
591
598
  }
592
599
 
593
600
 
594
- /** @return callable(Tag, TemplateParser): (Node|\Generator|void) */
595
- private function getAttrParser(string $name, Position $pos): callable
601
+ /** @return \Closure(Tag, TemplateParser): (Node|\Generator|void) */
602
+ private function getAttrParser(string $name, Position $pos): \Closure
596
603
  {
597
604
  if (!isset($this->attrParsers[$name])) {
598
605
  $hint = ($t = Helpers::getSuggestion(array_keys($this->attrParsers), $name))
@@ -1,18 +1,19 @@
1
- <?php
1
+ <?php declare(strict_types=1);
2
2
 
3
3
  /**
4
4
  * This file is part of the Latte (https://latte.nette.org)
5
5
  * Copyright (c) 2008 David Grudl (https://davidgrudl.com)
6
6
  */
7
7
 
8
- declare(strict_types=1);
9
-
10
8
  namespace Latte\Compiler;
11
9
 
12
10
  use function in_array;
13
11
 
14
12
 
15
- final class Token
13
+ /**
14
+ * Token produced by lexers.
15
+ */
16
+ final readonly class Token
16
17
  {
17
18
  public const
18
19
  End = 0,
@@ -236,17 +237,17 @@ final class Token
236
237
 
237
238
 
238
239
  public function __construct(
239
- public readonly int $type,
240
- public readonly string $text,
241
- public readonly ?Position $position = null,
240
+ public int $type,
241
+ public string $text,
242
+ public ?Position $position = null,
242
243
  ) {
243
244
  }
244
245
 
245
246
 
246
247
  public function is(int|string ...$kind): bool
247
248
  {
248
- return in_array($this->type, $kind, true)
249
- || in_array($this->text, $kind, true);
249
+ return in_array($this->type, $kind, strict: true)
250
+ || in_array($this->text, $kind, strict: true);
250
251
  }
251
252
 
252
253
 
@@ -1,12 +1,10 @@
1
- <?php
1
+ <?php declare(strict_types=1);
2
2
 
3
3
  /**
4
4
  * This file is part of the Latte (https://latte.nette.org)
5
5
  * Copyright (c) 2008 David Grudl (https://davidgrudl.com)
6
6
  */
7
7
 
8
- declare(strict_types=1);
9
-
10
8
  namespace Latte\Compiler;
11
9
 
12
10
  use Latte\CompileException;
@@ -21,13 +19,12 @@ final class TokenStream
21
19
  {
22
20
  /** @var Token[] */
23
21
  private array $tokens = [];
24
- private readonly \Iterator $source;
25
22
  private int $index = 0;
26
23
 
27
24
 
28
- public function __construct(\Iterator $source)
29
- {
30
- $this->source = $source;
25
+ public function __construct(
26
+ private readonly \Iterator $source,
27
+ ) {
31
28
  }
32
29
 
33
30
 
@@ -40,10 +37,19 @@ final class TokenStream
40
37
  }
41
38
 
42
39
 
40
+ /**
41
+ * Gets the token at $offset from the current position or throws.
42
+ */
43
+ public function peek(int $offset = 0): Token
44
+ {
45
+ return $this->tryPeek($offset) ?? throw new CompileException('Unexpected end');
46
+ }
47
+
48
+
43
49
  /**
44
50
  * Gets the token at $offset from the current position.
45
51
  */
46
- public function peek(int $offset = 0): ?Token
52
+ public function tryPeek(int $offset = 0): ?Token
47
53
  {
48
54
  $pos = $this->index + $offset;
49
55
  while ($pos >= 0 && !isset($this->tokens[$pos]) && $this->source->valid()) {
@@ -82,8 +88,8 @@ final class TokenStream
82
88
  */
83
89
  public function tryConsume(int|string ...$kind): ?Token
84
90
  {
85
- $token = $this->peek();
86
- if (!$token->is(...$kind)) {
91
+ $token = $this->tryPeek();
92
+ if (!$token?->is(...$kind)) {
87
93
  return null;
88
94
  } elseif (!$token->isEnd()) {
89
95
  $this->index++;
@@ -115,11 +121,11 @@ final class TokenStream
115
121
 
116
122
  /**
117
123
  * @throws CompileException
118
- * @return never
124
+ * @param array<string|int> $expected
119
125
  */
120
- public function throwUnexpectedException(array $expected = [], string $addendum = '', string $excerpt = ''): void
126
+ public function throwUnexpectedException(array $expected = [], string $addendum = '', string $excerpt = ''): never
121
127
  {
122
- $token = $this->peek()->text . $excerpt;
128
+ $token = ($this->tryPeek()->text ?? '') . $excerpt;
123
129
  $expected = array_map(fn($item) => is_int($item) ? Token::Names[$item] : $item, $expected);
124
130
  throw new CompileException(
125
131
  'Unexpected '
@@ -130,7 +136,7 @@ final class TokenStream
130
136
  ? ', expecting ' . implode(', ', $expected)
131
137
  : '')
132
138
  . $addendum,
133
- $this->peek()->position,
139
+ $this->tryPeek()?->position,
134
140
  );
135
141
  }
136
142
  }
@@ -1,15 +1,16 @@
1
- <?php
1
+ <?php declare(strict_types=1);
2
2
 
3
3
  /**
4
4
  * This file is part of the Latte (https://latte.nette.org)
5
5
  * Copyright (c) 2008 David Grudl (https://davidgrudl.com)
6
6
  */
7
7
 
8
- declare(strict_types=1);
9
-
10
8
  namespace Latte;
11
9
 
12
10
 
11
+ /**
12
+ * Content type constants for context-aware escaping.
13
+ */
13
14
  /*enum*/ final class ContentType
14
15
  {
15
16
  public const