@vituum/vite-plugin-latte 2.0.0-next.4 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (234) hide show
  1. package/README.md +1 -1
  2. package/index.js +4 -2
  3. package/package.json +11 -9
  4. package/types/index.d.ts +1 -1
  5. package/vendor/autoload.php +1 -4
  6. package/vendor/composer/InstalledVersions.php +36 -2
  7. package/vendor/composer/autoload_classmap.php +14 -15
  8. package/vendor/composer/autoload_psr4.php +2 -0
  9. package/vendor/composer/autoload_static.php +38 -15
  10. package/vendor/composer/installed.json +32 -22
  11. package/vendor/composer/installed.php +12 -12
  12. package/vendor/composer/platform_check.php +4 -5
  13. package/vendor/latte/latte/bin/latte-lint +10 -3
  14. package/vendor/latte/latte/composer.json +16 -6
  15. package/vendor/latte/latte/src/Bridges/Tracy/BlueScreenPanel.php +13 -38
  16. package/vendor/latte/latte/src/Bridges/Tracy/LattePanel.php +9 -7
  17. package/vendor/latte/latte/src/Bridges/Tracy/TracyExtension.php +2 -4
  18. package/vendor/latte/latte/src/Bridges/Tracy/dist/panel.phtml +94 -0
  19. package/vendor/latte/latte/src/Bridges/Tracy/dist/tab.phtml +10 -0
  20. package/vendor/latte/latte/src/Latte/Compiler/Block.php +4 -6
  21. package/vendor/latte/latte/src/Latte/Compiler/Escaper.php +67 -86
  22. package/vendor/latte/latte/src/Latte/Compiler/Node.php +6 -3
  23. package/vendor/latte/latte/src/Latte/Compiler/NodeHelpers.php +16 -6
  24. package/vendor/latte/latte/src/Latte/Compiler/NodeTraverser.php +25 -12
  25. package/vendor/latte/latte/src/Latte/Compiler/Nodes/AreaNode.php +7 -3
  26. package/vendor/latte/latte/src/Latte/Compiler/Nodes/AuxiliaryNode.php +5 -4
  27. package/vendor/latte/latte/src/Latte/Compiler/Nodes/FragmentNode.php +8 -4
  28. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/AttributeNode.php +7 -15
  29. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/BogusTagNode.php +4 -6
  30. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/CommentNode.php +4 -3
  31. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ElementNode.php +37 -67
  32. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ExpressionAttributeNode.php +60 -0
  33. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/TagNode.php +70 -0
  34. package/vendor/latte/latte/src/Latte/Compiler/Nodes/NopNode.php +4 -3
  35. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ArgumentNode.php +4 -3
  36. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ArrayItemNode.php +4 -15
  37. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ClosureUseNode.php +4 -3
  38. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ComplexTypeNode.php +4 -3
  39. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayAccessNode.php +4 -3
  40. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayNode.php +6 -22
  41. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignNode.php +18 -5
  42. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignOpNode.php +18 -7
  43. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AuxiliaryNode.php +5 -4
  44. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/BinaryOpNode.php +38 -9
  45. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CastNode.php +14 -6
  46. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClassConstantFetchNode.php +4 -3
  47. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CloneNode.php +12 -4
  48. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClosureNode.php +10 -6
  49. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ConstantFetchNode.php +7 -6
  50. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/EmptyNode.php +4 -3
  51. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FilterCallNode.php +10 -4
  52. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FunctionCallNode.php +14 -5
  53. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InNode.php +4 -3
  54. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InstanceofNode.php +14 -5
  55. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/IssetNode.php +6 -3
  56. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MatchNode.php +6 -3
  57. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MethodCallNode.php +18 -5
  58. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/NewNode.php +14 -4
  59. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PostOpNode.php +14 -6
  60. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PreOpNode.php +14 -6
  61. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PropertyFetchNode.php +4 -3
  62. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticMethodCallNode.php +14 -15
  63. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticPropertyFetchNode.php +4 -3
  64. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TemporaryNode.php +7 -6
  65. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TernaryNode.php +16 -11
  66. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/UnaryOpNode.php +19 -9
  67. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/VariableNode.php +4 -3
  68. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ExpressionNode.php +4 -3
  69. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/FilterNode.php +33 -8
  70. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/IdentifierNode.php +4 -3
  71. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/InterpolatedStringPartNode.php +4 -3
  72. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/IntersectionTypeNode.php +6 -3
  73. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ListItemNode.php +4 -3
  74. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ListNode.php +4 -3
  75. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/MatchArmNode.php +6 -3
  76. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ModifierNode.php +29 -41
  77. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NameNode.php +9 -4
  78. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NullableTypeNode.php +4 -3
  79. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/OperatorNode.php +27 -0
  80. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ParameterNode.php +4 -3
  81. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/BooleanNode.php +4 -3
  82. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/FloatNode.php +9 -6
  83. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/IntegerNode.php +8 -6
  84. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/InterpolatedStringNode.php +9 -5
  85. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/NullNode.php +4 -3
  86. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/StringNode.php +6 -4
  87. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ScalarNode.php +4 -3
  88. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/SuperiorTypeNode.php +4 -3
  89. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/UnionTypeNode.php +6 -3
  90. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/VarLikeIdentifierNode.php +4 -3
  91. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/{Expression/NotNode.php → VariadicPlaceholderNode.php} +9 -9
  92. package/vendor/latte/latte/src/Latte/{Essential → Compiler}/Nodes/PrintNode.php +9 -15
  93. package/vendor/latte/latte/src/Latte/Compiler/Nodes/StatementNode.php +7 -3
  94. package/vendor/latte/latte/src/Latte/Compiler/Nodes/TemplateNode.php +4 -3
  95. package/vendor/latte/latte/src/Latte/Compiler/Nodes/TextNode.php +6 -4
  96. package/vendor/latte/latte/src/Latte/Compiler/PhpHelpers.php +32 -18
  97. package/vendor/latte/latte/src/Latte/Compiler/Position.php +7 -7
  98. package/vendor/latte/latte/src/Latte/Compiler/PrintContext.php +72 -104
  99. package/vendor/latte/latte/src/Latte/Compiler/Tag.php +17 -16
  100. package/vendor/latte/latte/src/Latte/Compiler/TagLexer.php +11 -8
  101. package/vendor/latte/latte/src/Latte/Compiler/TagParser.php +28 -23
  102. package/vendor/latte/latte/src/Latte/Compiler/TagParserData.php +360 -336
  103. package/vendor/latte/latte/src/Latte/Compiler/TemplateGenerator.php +49 -38
  104. package/vendor/latte/latte/src/Latte/Compiler/TemplateLexer.php +37 -12
  105. package/vendor/latte/latte/src/Latte/Compiler/TemplateParser.php +35 -21
  106. package/vendor/latte/latte/src/Latte/Compiler/TemplateParserHtml.php +121 -71
  107. package/vendor/latte/latte/src/Latte/Compiler/Token.php +79 -70
  108. package/vendor/latte/latte/src/Latte/Compiler/TokenStream.php +21 -14
  109. package/vendor/latte/latte/src/Latte/ContentType.php +4 -3
  110. package/vendor/latte/latte/src/Latte/Engine.php +147 -188
  111. package/vendor/latte/latte/src/Latte/Essential/AuxiliaryIterator.php +5 -7
  112. package/vendor/latte/latte/src/Latte/Essential/Blueprint.php +5 -5
  113. package/vendor/latte/latte/src/Latte/Essential/CachingIterator.php +5 -4
  114. package/vendor/latte/latte/src/Latte/Essential/CoreExtension.php +155 -127
  115. package/vendor/latte/latte/src/Latte/Essential/Filters.php +99 -44
  116. package/vendor/latte/latte/src/Latte/Essential/Nodes/BlockNode.php +14 -13
  117. package/vendor/latte/latte/src/Latte/Essential/Nodes/CaptureNode.php +5 -6
  118. package/vendor/latte/latte/src/Latte/Essential/Nodes/ContentTypeNode.php +3 -4
  119. package/vendor/latte/latte/src/Latte/Essential/Nodes/CustomFunctionCallNode.php +46 -0
  120. package/vendor/latte/latte/src/Latte/Essential/Nodes/DebugbreakNode.php +2 -3
  121. package/vendor/latte/latte/src/Latte/Essential/Nodes/DefineNode.php +10 -7
  122. package/vendor/latte/latte/src/Latte/Essential/Nodes/DoNode.php +3 -4
  123. package/vendor/latte/latte/src/Latte/Essential/Nodes/DumpNode.php +2 -3
  124. package/vendor/latte/latte/src/Latte/Essential/Nodes/EmbedNode.php +8 -9
  125. package/vendor/latte/latte/src/Latte/Essential/Nodes/ExtendsNode.php +3 -5
  126. package/vendor/latte/latte/src/Latte/Essential/Nodes/FirstLastSepNode.php +4 -7
  127. package/vendor/latte/latte/src/Latte/Essential/Nodes/ForNode.php +6 -5
  128. package/vendor/latte/latte/src/Latte/Essential/Nodes/ForeachNode.php +7 -7
  129. package/vendor/latte/latte/src/Latte/Essential/Nodes/IfChangedNode.php +4 -5
  130. package/vendor/latte/latte/src/Latte/Essential/Nodes/IfContentNode.php +7 -6
  131. package/vendor/latte/latte/src/Latte/Essential/Nodes/IfNode.php +11 -11
  132. package/vendor/latte/latte/src/Latte/Essential/Nodes/ImportNode.php +5 -6
  133. package/vendor/latte/latte/src/Latte/Essential/Nodes/IncludeBlockNode.php +26 -27
  134. package/vendor/latte/latte/src/Latte/Essential/Nodes/IncludeFileNode.php +7 -10
  135. package/vendor/latte/latte/src/Latte/Essential/Nodes/IterateWhileNode.php +6 -6
  136. package/vendor/latte/latte/src/Latte/Essential/Nodes/JumpNode.php +4 -8
  137. package/vendor/latte/latte/src/Latte/Essential/Nodes/NAttrNode.php +35 -47
  138. package/vendor/latte/latte/src/Latte/Essential/Nodes/NClassNode.php +4 -5
  139. package/vendor/latte/latte/src/Latte/Essential/Nodes/NElseNode.php +69 -34
  140. package/vendor/latte/latte/src/Latte/Essential/Nodes/NTagNode.php +9 -33
  141. package/vendor/latte/latte/src/Latte/Essential/Nodes/ParametersNode.php +7 -4
  142. package/vendor/latte/latte/src/Latte/Essential/Nodes/RawPhpNode.php +3 -4
  143. package/vendor/latte/latte/src/Latte/Essential/Nodes/RollbackNode.php +2 -3
  144. package/vendor/latte/latte/src/Latte/Essential/Nodes/SpacelessNode.php +4 -5
  145. package/vendor/latte/latte/src/Latte/Essential/Nodes/SwitchNode.php +9 -7
  146. package/vendor/latte/latte/src/Latte/Essential/Nodes/TemplatePrintNode.php +4 -4
  147. package/vendor/latte/latte/src/Latte/Essential/Nodes/TemplateTypeNode.php +3 -4
  148. package/vendor/latte/latte/src/Latte/Essential/Nodes/TraceNode.php +2 -3
  149. package/vendor/latte/latte/src/Latte/Essential/Nodes/TranslateNode.php +5 -5
  150. package/vendor/latte/latte/src/Latte/Essential/Nodes/TryNode.php +4 -5
  151. package/vendor/latte/latte/src/Latte/Essential/Nodes/VarNode.php +10 -6
  152. package/vendor/latte/latte/src/Latte/Essential/Nodes/VarPrintNode.php +2 -3
  153. package/vendor/latte/latte/src/Latte/Essential/Nodes/VarTypeNode.php +3 -4
  154. package/vendor/latte/latte/src/Latte/Essential/Nodes/WhileNode.php +5 -5
  155. package/vendor/latte/latte/src/Latte/Essential/Passes.php +82 -21
  156. package/vendor/latte/latte/src/Latte/Essential/RawPhpExtension.php +2 -4
  157. package/vendor/latte/latte/src/Latte/Essential/RollbackException.php +1 -3
  158. package/vendor/latte/latte/src/Latte/Essential/Tracer.php +24 -28
  159. package/vendor/latte/latte/src/Latte/Essential/TranslatorExtension.php +14 -14
  160. package/vendor/latte/latte/src/Latte/Extension.php +12 -6
  161. package/vendor/latte/latte/src/Latte/Feature.php +24 -0
  162. package/vendor/latte/latte/src/Latte/Helpers.php +65 -15
  163. package/vendor/latte/latte/src/Latte/Loader.php +1 -9
  164. package/vendor/latte/latte/src/Latte/Loaders/FileLoader.php +11 -17
  165. package/vendor/latte/latte/src/Latte/Loaders/StringLoader.php +7 -21
  166. package/vendor/latte/latte/src/Latte/Policy.php +4 -3
  167. package/vendor/latte/latte/src/Latte/Runtime/Block.php +2 -4
  168. package/vendor/latte/latte/src/Latte/Runtime/Cache.php +143 -0
  169. package/vendor/latte/latte/src/Latte/Runtime/FilterExecutor.php +5 -6
  170. package/vendor/latte/latte/src/Latte/Runtime/FilterInfo.php +11 -11
  171. package/vendor/latte/latte/src/Latte/Runtime/FunctionExecutor.php +5 -6
  172. package/vendor/latte/latte/src/Latte/Runtime/Helpers.php +91 -0
  173. package/vendor/latte/latte/src/Latte/Runtime/Html.php +3 -5
  174. package/vendor/latte/latte/src/Latte/Runtime/HtmlHelpers.php +374 -0
  175. package/vendor/latte/latte/src/Latte/Runtime/HtmlStringable.php +1 -3
  176. package/vendor/latte/latte/src/Latte/Runtime/Template.php +162 -182
  177. package/vendor/latte/latte/src/Latte/Runtime/XmlHelpers.php +108 -0
  178. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/FunctionCallNode.php +12 -4
  179. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/MethodCallNode.php +15 -5
  180. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/PropertyFetchNode.php +4 -3
  181. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/SandboxNode.php +5 -6
  182. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticMethodCallNode.php +14 -4
  183. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticPropertyFetchNode.php +4 -3
  184. package/vendor/latte/latte/src/Latte/Sandbox/RuntimeChecker.php +8 -6
  185. package/vendor/latte/latte/src/Latte/Sandbox/SandboxExtension.php +16 -12
  186. package/vendor/latte/latte/src/Latte/Sandbox/SecurityPolicy.php +18 -16
  187. package/vendor/latte/latte/src/Latte/attributes.php +7 -3
  188. package/vendor/latte/latte/src/Latte/exceptions.php +52 -6
  189. package/vendor/latte/latte/src/Tools/Linter.php +74 -28
  190. package/vendor/latte/latte/src/Tools/LinterExtension.php +176 -0
  191. package/vendor/nette/utils/composer.json +15 -5
  192. package/vendor/nette/utils/readme.md +1 -1
  193. package/vendor/nette/utils/src/HtmlStringable.php +4 -1
  194. package/vendor/nette/utils/src/Iterators/CachingIterator.php +10 -25
  195. package/vendor/nette/utils/src/Iterators/Mapper.php +2 -3
  196. package/vendor/nette/utils/src/SmartObject.php +3 -0
  197. package/vendor/nette/utils/src/StaticClass.php +1 -11
  198. package/vendor/nette/utils/src/Translator.php +1 -1
  199. package/vendor/nette/utils/src/Utils/ArrayHash.php +6 -10
  200. package/vendor/nette/utils/src/Utils/ArrayList.php +8 -12
  201. package/vendor/nette/utils/src/Utils/Arrays.php +38 -18
  202. package/vendor/nette/utils/src/Utils/Callback.php +13 -8
  203. package/vendor/nette/utils/src/Utils/DateTime.php +95 -26
  204. package/vendor/nette/utils/src/Utils/FileInfo.php +6 -7
  205. package/vendor/nette/utils/src/Utils/FileSystem.php +10 -5
  206. package/vendor/nette/utils/src/Utils/Finder.php +31 -12
  207. package/vendor/nette/utils/src/Utils/Floats.php +1 -0
  208. package/vendor/nette/utils/src/Utils/Helpers.php +22 -2
  209. package/vendor/nette/utils/src/Utils/Html.php +130 -127
  210. package/vendor/nette/utils/src/Utils/Image.php +80 -60
  211. package/vendor/nette/utils/src/Utils/ImageColor.php +5 -0
  212. package/vendor/nette/utils/src/Utils/ImageType.php +2 -0
  213. package/vendor/nette/utils/src/Utils/Iterables.php +41 -7
  214. package/vendor/nette/utils/src/Utils/Json.php +2 -0
  215. package/vendor/nette/utils/src/Utils/ObjectHelpers.php +2 -0
  216. package/vendor/nette/utils/src/Utils/Paginator.php +10 -43
  217. package/vendor/nette/utils/src/Utils/Random.php +2 -0
  218. package/vendor/nette/utils/src/Utils/Reflection.php +22 -15
  219. package/vendor/nette/utils/src/Utils/ReflectionMethod.php +6 -1
  220. package/vendor/nette/utils/src/Utils/Strings.php +62 -57
  221. package/vendor/nette/utils/src/Utils/Type.php +91 -42
  222. package/vendor/nette/utils/src/Utils/Validators.php +9 -7
  223. package/vendor/latte/latte/src/Bridges/Tracy/templates/LattePanel.panel.phtml +0 -101
  224. package/vendor/latte/latte/src/Bridges/Tracy/templates/LattePanel.tab.phtml +0 -15
  225. package/vendor/latte/latte/src/Latte/Compiler/ExpressionBuilder.php +0 -129
  226. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ErrorSuppressNode.php +0 -36
  227. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FunctionCallableNode.php +0 -39
  228. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MethodCallableNode.php +0 -42
  229. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticMethodCallableNode.php +0 -57
  230. package/vendor/latte/latte/src/Latte/PositionAwareException.php +0 -47
  231. package/vendor/latte/latte/src/Latte/Runtime/Filters.php +0 -283
  232. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/FunctionCallableNode.php +0 -29
  233. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/MethodCallableNode.php +0 -30
  234. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticMethodCallableNode.php +0 -30
@@ -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\Essential\Nodes;
11
9
 
12
10
  use Latte\Compiler\Nodes\Php\Expression\ArrayNode;
@@ -19,7 +17,7 @@ use Latte\Compiler\Tag;
19
17
 
20
18
 
21
19
  /**
22
- * {include [file] "file" [with blocks] [,] [params]}
20
+ * {include 'file.latte' [with blocks]}
23
21
  */
24
22
  class IncludeFileNode extends StatementNode
25
23
  {
@@ -48,25 +46,24 @@ class IncludeFileNode extends StatementNode
48
46
  $stream->tryConsume(',');
49
47
  $node->args = $tag->parser->parseArguments();
50
48
  $node->modifier = $tag->parser->parseModifier();
51
- $node->modifier->escape = (bool) $node->modifier->filters;
49
+ $node->modifier->escape = !$node->modifier->removeFilter('noescape');
52
50
  return $node;
53
51
  }
54
52
 
55
53
 
56
54
  public function print(PrintContext $context): string
57
55
  {
58
- $noEscape = $this->modifier->hasFilter('noescape');
59
56
  return $context->format(
60
- '$this->createTemplate(%node, %node? + $this->params, %dump)->renderToContentType(%raw) %line;',
61
- $this->file,
57
+ '$this->createTemplate(%raw, %node? + $this->params, %dump)->renderToContentType(%raw) %line;',
58
+ $context->ensureString($this->file, 'Template name'),
62
59
  $this->args,
63
60
  $this->mode,
64
- count($this->modifier->filters) > (int) $noEscape
61
+ $this->modifier->filters
65
62
  ? $context->format(
66
63
  'function ($s, $type) { $ʟ_fi = new LR\FilterInfo($type); return %modifyContent($s); }',
67
64
  $this->modifier,
68
65
  )
69
- : PhpHelpers::dump($noEscape ? null : $context->getEscaper()->export()),
66
+ : PhpHelpers::dump($this->modifier->escape ? $context->getEscaper()->export() : null),
70
67
  $this->position,
71
68
  );
72
69
  }
@@ -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\Essential\Nodes;
11
9
 
12
10
  use Latte\CompileException;
@@ -19,7 +17,8 @@ use Latte\Compiler\Tag;
19
17
 
20
18
 
21
19
  /**
22
- * {iterateWhile $cond}
20
+ * {iterateWhile [$cond]} ... {/iterateWhile [$cond]}
21
+ * Groups consecutive items in {foreach} by condition.
23
22
  */
24
23
  class IterateWhileNode extends StatementNode
25
24
  {
@@ -30,11 +29,11 @@ class IterateWhileNode extends StatementNode
30
29
  public bool $postTest;
31
30
 
32
31
 
33
- /** @return \Generator<int, ?array, array{AreaNode, ?Tag}, static> */
32
+ /** @return \Generator<int, ?list<string>, array{AreaNode, ?Tag}, static> */
34
33
  public static function create(Tag $tag): \Generator
35
34
  {
36
35
  $foreach = $tag->closestTag([ForeachNode::class])?->node;
37
- if (!$foreach) {
36
+ if (!$foreach instanceof ForeachNode) {
38
37
  throw new CompileException("Tag {{$tag->name}} must be inside {foreach} ... {/foreach}.", $tag->position);
39
38
  }
40
39
 
@@ -48,6 +47,7 @@ class IterateWhileNode extends StatementNode
48
47
  $node->value = $foreach->value;
49
48
  [$node->content, $nextTag] = yield;
50
49
  if ($node->postTest) {
50
+ assert($nextTag !== null);
51
51
  $nextTag->expectArguments();
52
52
  $node->condition = $nextTag->parser->parseExpression();
53
53
  }
@@ -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\Essential\Nodes;
11
9
 
12
10
  use Latte\CompileException;
@@ -17,10 +15,8 @@ use Latte\Compiler\Tag;
17
15
 
18
16
 
19
17
  /**
20
- * {breakIf ...}
21
- * {continueIf ...}
22
- * {skipIf ...}
23
- * {exitIf ...}
18
+ * {breakIf $cond}, {continueIf $cond}, {skipIf $cond}, {exitIf $cond}
19
+ * Note: {skipIf} is like {continueIf} but doesn't increment $iterator->counter.
24
20
  */
25
21
  class JumpNode extends StatementNode
26
22
  {
@@ -50,7 +46,7 @@ class JumpNode extends StatementNode
50
46
  }
51
47
 
52
48
  $last = $parent?->prefix === Tag::PrefixNone
53
- ? $parent->htmlElement->parent
49
+ ? $parent->htmlElement?->parent
54
50
  : $parent?->htmlElement;
55
51
  $el = $tag->htmlElement;
56
52
  while ($el && $el !== $last) {
@@ -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\Essential\Nodes;
11
9
 
12
10
  use Latte;
@@ -14,10 +12,12 @@ use Latte\Compiler\Nodes\Php\Expression\ArrayNode;
14
12
  use Latte\Compiler\Nodes\StatementNode;
15
13
  use Latte\Compiler\PrintContext;
16
14
  use Latte\Compiler\Tag;
15
+ use Latte\Runtime as LR;
16
+ use function is_array;
17
17
 
18
18
 
19
19
  /**
20
- * n:attr="..."
20
+ * <div n:attr="class => $class, id => $id">
21
21
  */
22
22
  final class NAttrNode extends StatementNode
23
23
  {
@@ -37,64 +37,52 @@ final class NAttrNode extends StatementNode
37
37
  {
38
38
  return $context->format(
39
39
  '$ʟ_tmp = %node;
40
- echo %raw::attrs(isset($ʟ_tmp[0]) && is_array($ʟ_tmp[0]) ? $ʟ_tmp[0] : $ʟ_tmp, %dump) %line;',
40
+ echo %raw::attrs($ʟ_tmp, %dump, %dump?) %line;',
41
41
  $this->args,
42
42
  self::class,
43
43
  $context->getEscaper()->getContentType() === Latte\ContentType::Xml,
44
+ $context->hasFeature(Latte\Feature::MigrationWarnings) ?: null,
44
45
  $this->position,
45
46
  );
46
47
  }
47
48
 
48
49
 
49
- /** @internal */
50
- public static function attrs($attrs, bool $xml): string
50
+ public static function attrs(mixed $attrs, bool $xml, bool $migrationWarnings = false): string
51
51
  {
52
+ $attrs = $attrs === [$attrs[0] ?? null] ? $attrs[0] : $attrs; // checks if the value is an array, e.g. n:attr="$attrs"
52
53
  if (!is_array($attrs)) {
53
54
  return '';
54
55
  }
55
56
 
56
- $s = '';
57
- foreach ($attrs as $key => $value) {
58
- if ($value === null || $value === false) {
59
- continue;
60
-
61
- } elseif ($value === true) {
62
- $s .= ' ' . $key . ($xml ? '="' . $key . '"' : '');
63
- continue;
64
-
65
- } elseif (is_array($value)) {
66
- $tmp = null;
67
- foreach ($value as $k => $v) {
68
- if ($v != null) { // intentionally ==, skip nulls & empty string
69
- // composite 'style' vs. 'others'
70
- $tmp[] = $v === true
71
- ? $k
72
- : (is_string($k) ? $k . ':' . $v : $v);
73
- }
74
- }
75
-
76
- if ($tmp === null) {
77
- continue;
78
- }
79
-
80
- $value = implode($key === 'style' || !strncmp($key, 'on', 2) ? ';' : ' ', $tmp);
81
-
82
- } else {
83
- $value = (string) $value;
84
- }
85
-
86
- $q = !str_contains($value, '"') ? '"' : "'";
87
- $s .= ' ' . $key . '=' . $q
88
- . str_replace(
89
- ['&', $q, '<'],
90
- ['&amp;', $q === '"' ? '&quot;' : '&#39;', $xml ? '&lt;' : '<'],
91
- $value,
92
- )
93
- . (str_contains($value, '`') && strpbrk($value, ' <>"\'') === false ? ' ' : '')
94
- . $q;
57
+ $res = '';
58
+ foreach ($attrs as $name => $value) {
59
+ $attr = $xml ? self::formatXmlAttribute($name, $value) : self::formatHtmlAttribute($name, $value, $migrationWarnings);
60
+ $res .= $attr ? ' ' . $attr : '';
95
61
  }
96
62
 
97
- return $s;
63
+ return $res;
64
+ }
65
+
66
+
67
+ public static function formatHtmlAttribute(mixed $name, mixed $value, bool $migrationWarnings = false): string
68
+ {
69
+ LR\HtmlHelpers::validateAttributeName($name);
70
+ $type = LR\HtmlHelpers::classifyAttributeType($name);
71
+ if ($value === null || ($value === false && $type !== 'data' && $type !== 'aria')) {
72
+ return '';
73
+ } elseif ($value === true && $type === '') {
74
+ return $name;
75
+ } elseif ($migrationWarnings && is_array($value) && $type === 'data') {
76
+ LR\HtmlHelpers::triggerMigrationWarning($name, "array value: previously it rendered as $name=\"val1 val2 ...\", now the attribute is JSON-encoded");
77
+ }
78
+ return LR\HtmlHelpers::{"format{$type}Attribute"}($name, $value, $migrationWarnings);
79
+ }
80
+
81
+
82
+ public static function formatXmlAttribute(mixed $name, mixed $value): string
83
+ {
84
+ LR\XmlHelpers::validateAttributeName($name);
85
+ return $value === false ? '' : LR\XmlHelpers::formatAttribute($name, $value);
98
86
  }
99
87
 
100
88
 
@@ -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\Essential\Nodes;
11
9
 
12
10
  use Latte\CompileException;
@@ -17,7 +15,7 @@ use Latte\Compiler\Tag;
17
15
 
18
16
 
19
17
  /**
20
- * n:class="..."
18
+ * <div n:class="$isActive ? active, highlight">
21
19
  */
22
20
  final class NClassNode extends StatementNode
23
21
  {
@@ -26,6 +24,7 @@ final class NClassNode extends StatementNode
26
24
 
27
25
  public static function create(Tag $tag): static
28
26
  {
27
+ assert($tag->htmlElement !== null);
29
28
  if ($tag->htmlElement->getAttribute('class')) {
30
29
  throw new CompileException('It is not possible to combine class with n:class.', $tag->position);
31
30
  }
@@ -40,7 +39,7 @@ final class NClassNode extends StatementNode
40
39
  public function print(PrintContext $context): string
41
40
  {
42
41
  return $context->format(
43
- 'echo ($ʟ_tmp = array_filter(%node)) ? \' class="\' . LR\Filters::escapeHtmlAttr(implode(" ", array_unique($ʟ_tmp))) . \'"\' : "" %line;',
42
+ 'echo ($ʟ_tmp = array_filter(%node)) ? \' class="\' . LR\HtmlHelpers::escapeAttr(implode(" ", array_unique($ʟ_tmp))) . \'"\' : "" %line;',
44
43
  $this->args,
45
44
  $this->position,
46
45
  );
@@ -1,18 +1,17 @@
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\Essential\Nodes;
11
9
 
12
10
  use Latte\CompileException;
13
11
  use Latte\Compiler\Node;
14
12
  use Latte\Compiler\Nodes;
15
13
  use Latte\Compiler\Nodes\AreaNode;
14
+ use Latte\Compiler\Nodes\Php\ExpressionNode;
16
15
  use Latte\Compiler\Nodes\StatementNode;
17
16
  use Latte\Compiler\NodeTraverser;
18
17
  use Latte\Compiler\PrintContext;
@@ -20,17 +19,23 @@ use Latte\Compiler\Tag;
20
19
 
21
20
 
22
21
  /**
23
- * n:else
22
+ * <div n:if="$cond"> ... <div n:else>
23
+ * <div n:if="$cond"> ... <div n:elseif="$cond2">
24
24
  */
25
25
  final class NElseNode extends StatementNode
26
26
  {
27
27
  public AreaNode $content;
28
+ public ?ExpressionNode $condition = null;
28
29
 
29
30
 
30
- /** @return \Generator<int, ?array, array{AreaNode, ?Tag}, static> */
31
+ /** @return \Generator<int, ?list<string>, array{AreaNode, ?Tag}, static> */
31
32
  public static function create(Tag $tag): \Generator
32
33
  {
33
34
  $node = $tag->node = new static;
35
+ if ($tag->name === 'elseif') {
36
+ $tag->expectArguments();
37
+ $node->condition = $tag->parser->parseExpression();
38
+ }
34
39
  [$node->content] = yield;
35
40
  return $node;
36
41
  }
@@ -44,6 +49,9 @@ final class NElseNode extends StatementNode
44
49
 
45
50
  public function &getIterator(): \Generator
46
51
  {
52
+ if ($this->condition) {
53
+ yield $this->condition;
54
+ }
47
55
  yield $this->content;
48
56
  }
49
57
 
@@ -52,37 +60,64 @@ final class NElseNode extends StatementNode
52
60
  {
53
61
  (new NodeTraverser)->traverse($node, function (Node $node) {
54
62
  if ($node instanceof Nodes\FragmentNode) {
55
- for ($i = count($node->children) - 1; $i >= 0; $i--) {
56
- $nElse = $node->children[$i];
57
- if (!$nElse instanceof self) {
58
- continue;
59
- }
60
-
61
- array_splice($node->children, $i, 1);
62
- $prev = $node->children[--$i] ?? null;
63
- if ($prev instanceof Nodes\TextNode && trim($prev->content) === '') {
64
- array_splice($node->children, $i, 1);
65
- $prev = $node->children[--$i] ?? null;
66
- }
67
-
68
- if (
69
- $prev instanceof IfNode
70
- || $prev instanceof ForeachNode
71
- || $prev instanceof TryNode
72
- || $prev instanceof IfChangedNode
73
- || $prev instanceof IfContentNode
74
- ) {
75
- if ($prev->else) {
76
- throw new CompileException('Multiple "else" found.', $nElse->position);
77
- }
78
- $prev->else = $nElse->content;
79
- } else {
80
- throw new CompileException('n:else must be immediately after n:if, n:foreach etc', $nElse->position);
81
- }
82
- }
63
+ $node->children = self::processFragment($node->children);
83
64
  } elseif ($node instanceof self) {
84
- throw new CompileException('n:else must be immediately after n:if, n:foreach etc', $node->position);
65
+ self::processFragment([$node]);
85
66
  }
86
67
  });
87
68
  }
69
+
70
+
71
+ /**
72
+ * @param AreaNode[] $children
73
+ * @return AreaNode[]
74
+ */
75
+ private static function processFragment(array $children): array
76
+ {
77
+ $currentNode = null;
78
+ for ($i = 0; isset($children[$i]); $i++) {
79
+ $child = $children[$i];
80
+
81
+ if ($child instanceof IfNode
82
+ || $child instanceof ForeachNode
83
+ || $child instanceof TryNode
84
+ || $child instanceof IfChangedNode
85
+ || $child instanceof IfContentNode
86
+ ) {
87
+ $currentNode = $child;
88
+
89
+ } elseif ($child instanceof Nodes\TextNode && trim($child->content) === '') {
90
+ continue;
91
+
92
+ } elseif ($child instanceof self) {
93
+ $nElse = $child;
94
+ if ($currentNode === null) {
95
+ throw new CompileException('n:else must be immediately after n:if, n:foreach etc', $nElse->position);
96
+ } elseif ($currentNode->else) {
97
+ throw new CompileException('Multiple "else" found.', $nElse->position);
98
+ }
99
+
100
+ if ($nElse->condition) {
101
+ $elseIfNode = new IfNode;
102
+ $elseIfNode->condition = $nElse->condition;
103
+ $elseIfNode->then = $nElse->content;
104
+ $elseIfNode->position = $nElse->position;
105
+ $currentNode->else = $elseIfNode;
106
+ $currentNode = $elseIfNode;
107
+ } else {
108
+ $currentNode->else = $nElse->content;
109
+ $currentNode = null;
110
+ }
111
+
112
+ unset($children[$i]);
113
+ for ($o = 1; ($children[$i - $o] ?? null) instanceof Nodes\TextNode; $o++) {
114
+ unset($children[$i - $o]);
115
+ }
116
+ } else {
117
+ $currentNode = null;
118
+ }
119
+ }
120
+
121
+ return array_values($children);
122
+ }
88
123
  }
@@ -1,45 +1,36 @@
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\Essential\Nodes;
11
9
 
12
- use Latte;
13
10
  use Latte\CompileException;
14
- use Latte\Compiler\Nodes\Php\Expression\AuxiliaryNode;
11
+ use Latte\Compiler\Nodes\Html\TagNode;
15
12
  use Latte\Compiler\Nodes\StatementNode;
16
13
  use Latte\Compiler\PrintContext;
17
14
  use Latte\Compiler\Tag;
18
- use Latte\Compiler\TemplateParser;
19
- use Latte\ContentType;
15
+ use function preg_match;
20
16
 
21
17
 
22
18
  /**
23
- * n:tag="..."
19
+ * <div n:tag="$useSpan ? span">
24
20
  */
25
21
  final class NTagNode extends StatementNode
26
22
  {
27
- public static function create(Tag $tag, TemplateParser $parser): void
23
+ public static function create(Tag $tag): void
28
24
  {
25
+ assert($tag->htmlElement !== null);
29
26
  if (preg_match('(style$|script$)iA', $tag->htmlElement->name)) {
30
27
  throw new CompileException('Attribute n:tag is not allowed in <script> or <style>', $tag->position);
31
28
  }
32
29
 
33
30
  $tag->expectArguments();
34
- $tag->htmlElement->variableName = new AuxiliaryNode(
35
- fn(PrintContext $context, $newName) => $context->format(
36
- self::class . '::check(%dump, %node, %dump)',
37
- $tag->htmlElement->name,
38
- $newName,
39
- $parser->getContentType() === ContentType::Xml,
40
- ),
41
- [$tag->parser->parseExpression()],
42
- );
31
+ $tag->htmlElement->dynamicTag ??= new TagNode($tag->htmlElement);
32
+ assert($tag->htmlElement->dynamicTag instanceof TagNode);
33
+ $tag->htmlElement->dynamicTag->name = $tag->parser->parseExpression();
43
34
  }
44
35
 
45
36
 
@@ -49,21 +40,6 @@ final class NTagNode extends StatementNode
49
40
  }
50
41
 
51
42
 
52
- public static function check(string $orig, mixed $new, bool $xml): mixed
53
- {
54
- if ($new === null) {
55
- return $orig;
56
- } elseif (!$xml
57
- && is_string($new)
58
- && isset(Latte\Helpers::$emptyElements[strtolower($orig)]) !== isset(Latte\Helpers::$emptyElements[strtolower($new)])
59
- ) {
60
- throw new Latte\RuntimeException("Forbidden tag <$orig> change to <$new>");
61
- }
62
-
63
- return $new;
64
- }
65
-
66
-
67
43
  public function &getIterator(): \Generator
68
44
  {
69
45
  false && yield;
@@ -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\Essential\Nodes;
11
9
 
12
10
  use Latte\CompileException;
@@ -18,10 +16,13 @@ use Latte\Compiler\Nodes\StatementNode;
18
16
  use Latte\Compiler\PrintContext;
19
17
  use Latte\Compiler\Tag;
20
18
  use Latte\Compiler\Token;
19
+ use Latte\Helpers;
20
+ use function is_string;
21
21
 
22
22
 
23
23
  /**
24
- * {parameters [type] $var, ...}
24
+ * {parameters [Type] $name [= default], ...}
25
+ * Declares and filters template parameters.
25
26
  */
26
27
  class ParametersNode extends StatementNode
27
28
  {
@@ -41,6 +42,7 @@ class ParametersNode extends StatementNode
41
42
  }
42
43
 
43
44
 
45
+ /** @return ParameterNode[] */
44
46
  private static function parseParameters(Tag $tag): array
45
47
  {
46
48
  $stream = $tag->parser->stream;
@@ -80,5 +82,6 @@ class ParametersNode extends StatementNode
80
82
  foreach ($this->parameters as &$param) {
81
83
  yield $param;
82
84
  }
85
+ Helpers::removeNulls($this->parameters);
83
86
  }
84
87
  }
@@ -1,21 +1,20 @@
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\Essential\Nodes;
11
9
 
12
10
  use Latte\Compiler\Nodes\StatementNode;
13
11
  use Latte\Compiler\PrintContext;
14
12
  use Latte\Compiler\Tag;
13
+ use function preg_match, trim;
15
14
 
16
15
 
17
16
  /**
18
- * {php statement; statement; ...}
17
+ * {php code} (requires RawPhpExtension)
19
18
  */
20
19
  class RawPhpNode extends StatementNode
21
20
  {
@@ -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\Essential\Nodes;
11
9
 
12
10
  use Latte\CompileException;
@@ -17,6 +15,7 @@ use Latte\Compiler\Tag;
17
15
 
18
16
  /**
19
17
  * {rollback}
18
+ * Discards {try} block output and jumps to {else}.
20
19
  */
21
20
  class RollbackNode extends StatementNode
22
21
  {
@@ -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\Essential\Nodes;
11
9
 
12
10
  use Latte\Compiler\Nodes\AreaNode;
@@ -17,14 +15,15 @@ use Latte\ContentType;
17
15
 
18
16
 
19
17
  /**
20
- * {spaceless}
18
+ * {spaceless} ... {/spaceless}
19
+ * Removes whitespace between HTML tags.
21
20
  */
22
21
  class SpacelessNode extends StatementNode
23
22
  {
24
23
  public AreaNode $content;
25
24
 
26
25
 
27
- /** @return \Generator<int, ?array, array{AreaNode, ?Tag}, static> */
26
+ /** @return \Generator<int, ?list<string>, array{AreaNode, ?Tag}, static> */
28
27
  public static function create(Tag $tag): \Generator
29
28
  {
30
29
  $node = $tag->node = new static;