@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,15 +1,15 @@
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\ContentType;
11
+ use Latte\Engine;
12
+ use function array_filter, compact, implode, is_int, str_contains, str_replace, trim;
13
13
 
14
14
 
15
15
  /**
@@ -28,45 +28,29 @@ final class TemplateGenerator
28
28
 
29
29
 
30
30
  /**
31
- * Compiles nodes to PHP file
31
+ * Builds template class.
32
+ * @param array<string, bool> $features
32
33
  */
33
- public function generate(
34
- Nodes\TemplateNode $node,
35
- string $className,
36
- ?string $templateName = null,
37
- bool $strictMode = false,
38
- ): string
34
+ public function buildClass(Nodes\TemplateNode $node, array $features = []): void
39
35
  {
40
- $context = new PrintContext($node->contentType);
41
- $code = $node->main->print($context);
42
- $code = self::buildParams($code, [], '$ʟ_args', $context);
43
- $this->addMethod('main', $code, 'array $ʟ_args');
44
-
45
- $head = (new NodeTraverser)->traverse($node->head, fn(Node $node) => $node instanceof Nodes\TextNode ? new Nodes\NopNode : $node);
46
- $code = $head->print($context);
47
- if ($code || $context->paramsExtraction) {
48
- $code .= 'return get_defined_vars();';
49
- $code = self::buildParams($code, $context->paramsExtraction, '$this->params', $context);
50
- $this->addMethod('prepare', $code, '', 'array');
51
- }
52
-
53
- if ($node->contentType !== ContentType::Html) {
54
- $this->addConstant('ContentType', $node->contentType);
55
- }
56
-
57
- if ($templateName !== null && !preg_match('#\n|\?#', $templateName)) {
58
- $this->addConstant('Source', $templateName);
59
- }
36
+ $context = new PrintContext($node->contentType, $features);
37
+ $this->generateBase($node, $context);
38
+ $this->generateBlocks($context);
39
+ }
60
40
 
61
- $this->generateBlocks($context->blocks, $context);
62
41
 
42
+ /**
43
+ * Compiles to PHP file
44
+ */
45
+ public function generateCode(string $className, ?string $templateName, bool $strictMode): string
46
+ {
63
47
  $members = [];
64
48
  foreach ($this->constants as $name => $value) {
65
- $members[] = "\tpublic const $name = " . PhpHelpers::dump($value, true) . ';';
49
+ $members[] = "\tpublic const $name = " . PhpHelpers::dump($value, multiline: true) . ';';
66
50
  }
67
51
 
68
52
  foreach ($this->properties as $name => $value) {
69
- $members[] = "\tpublic $$name = " . PhpHelpers::dump($value, true) . ';';
53
+ $members[] = "\tpublic $$name = " . PhpHelpers::dump($value, multiline: true) . ';';
70
54
  }
71
55
 
72
56
  foreach (array_filter($this->methods) as $name => $method) {
@@ -78,6 +62,7 @@ final class TemplateGenerator
78
62
  }
79
63
 
80
64
  $code = "<?php\n\n"
65
+ . '/** Generated by Latte ' . Engine::Version . " */\n\n"
81
66
  . ($strictMode ? "declare(strict_types=1);\n\n" : '')
82
67
  . "use Latte\\Runtime as LR;\n\n"
83
68
  . ($templateName === null ? '' : '/** source: ' . str_replace('*/', '* /', $templateName) . " */\n")
@@ -91,13 +76,38 @@ final class TemplateGenerator
91
76
  }
92
77
 
93
78
 
94
- /** @param Block[] $blocks */
95
- private function generateBlocks(array $blocks, PrintContext $context): void
79
+ private function generateBase(Nodes\TemplateNode $node, PrintContext $context): void
80
+ {
81
+ $code = $node->main->print($context);
82
+ $code = self::buildParams($code, [], '$ʟ_args', $context);
83
+ $this->addMethod('main', $code, 'array $ʟ_args');
84
+
85
+ $head = (new NodeTraverser)->traverse(
86
+ $node->head,
87
+ fn(Node $node) => $node instanceof Nodes\TextNode ? new Nodes\NopNode : $node,
88
+ );
89
+ $code = $head?->print($context) ?? '';
90
+ if ($code || $context->paramsExtraction) {
91
+ $code .= 'return get_defined_vars();';
92
+ $code = self::buildParams($code, $context->paramsExtraction, '$this->params', $context);
93
+ $this->addMethod('prepare', $code, '', 'array');
94
+ }
95
+
96
+ if ($node->contentType !== ContentType::Html) {
97
+ $this->addConstant('ContentType', $node->contentType);
98
+ }
99
+ }
100
+
101
+
102
+ private function generateBlocks(PrintContext $context): void
96
103
  {
97
104
  $contentType = $context->getEscaper()->getContentType();
98
- foreach ($blocks as $block) {
99
- if (!$block->isDynamic()) {
100
- $meta[$block->layer][$block->name->value] = $contentType === $block->escaping
105
+ foreach ($context->blocks as $block) {
106
+ $name = $block->name;
107
+ if (!$block->isDynamic()
108
+ && ($name instanceof Nodes\Php\Scalar\StringNode || $name instanceof Nodes\Php\Scalar\IntegerNode)
109
+ ) {
110
+ $meta[$block->layer][$name->value] = $contentType === $block->escaping
101
111
  ? $block->method
102
112
  : [$block->method, $block->escaping];
103
113
  }
@@ -123,6 +133,7 @@ final class TemplateGenerator
123
133
  }
124
134
 
125
135
 
136
+ /** @param Nodes\Php\ParameterNode[] $params */
126
137
  private function buildParams(string $body, array $params, string $cont, PrintContext $context): string
127
138
  {
128
139
  if (!str_contains($body, '$') && !str_contains($body, 'get_defined_vars()')) {
@@ -1,22 +1,26 @@
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;
11
+ use function array_merge, array_pop, array_shift, array_unshift, constant, dechex, is_int, ord, preg_last_error, preg_last_error_msg, preg_match, preg_quote, str_replace, str_starts_with, strlen, substr;
12
+ use const PREG_UNMATCHED_AS_NULL;
13
13
 
14
14
 
15
+ /**
16
+ * Tokenizes Latte template source code.
17
+ */
15
18
  final class TemplateLexer
16
19
  {
17
20
  public const
18
21
  StatePlain = 'Plain',
19
22
  StateLatteTag = 'LatteTag',
23
+ StateLatteContent = 'LatteContent',
20
24
  StateLatteComment = 'LatteComment',
21
25
  StateHtmlText = 'HtmlText',
22
26
  StateHtmlTag = 'HtmlTag',
@@ -33,10 +37,12 @@ final class TemplateLexer
33
37
  public const NPrefix = 'n:';
34
38
 
35
39
  /** HTML attribute name/value (\p{C} means \x00-\x1F except space) */
36
- private const ReAttrName = '[^\p{C} "\'<>=`/]';
40
+ public const ReAttrName = '[^\p{C} "\'<>=`/]';
37
41
 
38
42
  private string $openDelimiter = '';
39
43
  private string $closeDelimiter = '';
44
+
45
+ /** @var array{string, string}[] */
40
46
  private array $delimiters = [];
41
47
  private TagLexer $tagLexer;
42
48
 
@@ -76,6 +82,7 @@ final class TemplateLexer
76
82
  }
77
83
 
78
84
 
85
+ /** @return Token[] */
79
86
  private function statePlain(): array
80
87
  {
81
88
  return $this->match('~
@@ -90,13 +97,23 @@ final class TemplateLexer
90
97
  }
91
98
 
92
99
 
100
+ /** @return Token[] */
93
101
  private function stateLatteTag(): array
94
102
  {
95
103
  $tokens[] = $this->match('~
96
104
  (?<Slash>/)?
97
- (?<Latte_Name> = | _(?!_) | [a-z]\w*+(?:[.:-]\w+)*+(?!::|\(|\\\\))? # name, /name, but not function( or class:: or namespace\
105
+ (?<Latte_Name> = | _(?!_) | [a-z]\w*+(?:[.:-]\w+)*+(?!::|\(|\\\))? # name, /name, but not function( or class:: or namespace\
98
106
  ~xsiAu');
99
107
 
108
+ $tokens[] = $this->stateLatteContent();
109
+
110
+ return array_merge(...$tokens);
111
+ }
112
+
113
+
114
+ /** @return Token[] */
115
+ private function stateLatteContent(): array
116
+ {
100
117
  $tokens[] = $this->tagLexer->tokenizePartially($this->input, $this->position);
101
118
 
102
119
  $tokens[] = $this->match('~
@@ -109,6 +126,7 @@ final class TemplateLexer
109
126
  }
110
127
 
111
128
 
129
+ /** @return Token[] */
112
130
  private function stateLatteComment(): array
113
131
  {
114
132
  return $this->match('~
@@ -121,6 +139,7 @@ final class TemplateLexer
121
139
  }
122
140
 
123
141
 
142
+ /** @return Token[] */
124
143
  private function stateHtmlText(): array
125
144
  {
126
145
  return $this->match('~(?J)
@@ -137,6 +156,7 @@ final class TemplateLexer
137
156
  }
138
157
 
139
158
 
159
+ /** @return Token[] */
140
160
  private function stateHtmlTag(): array
141
161
  {
142
162
  return $this->match('~(?J)
@@ -154,6 +174,7 @@ final class TemplateLexer
154
174
  }
155
175
 
156
176
 
177
+ /** @return Token[] */
157
178
  private function stateHtmlQuotedValue(string $quote): array
158
179
  {
159
180
  return $this->match('~
@@ -168,6 +189,7 @@ final class TemplateLexer
168
189
  }
169
190
 
170
191
 
192
+ /** @return Token[] */
171
193
  private function stateHtmlQuotedNAttrValue(string $quote): array
172
194
  {
173
195
  return $this->match('~
@@ -180,6 +202,7 @@ final class TemplateLexer
180
202
  }
181
203
 
182
204
 
205
+ /** @return Token[] */
183
206
  private function stateHtmlRawText(string $tagName): array
184
207
  {
185
208
  return $this->match('~
@@ -195,6 +218,7 @@ final class TemplateLexer
195
218
  }
196
219
 
197
220
 
221
+ /** @return Token[] */
198
222
  private function stateHtmlComment(): array
199
223
  {
200
224
  return $this->match('~(?J)
@@ -209,6 +233,7 @@ final class TemplateLexer
209
233
  }
210
234
 
211
235
 
236
+ /** @return Token[] */
212
237
  private function stateHtmlBogus(): array
213
238
  {
214
239
  return $this->match('~
@@ -236,8 +261,8 @@ final class TemplateLexer
236
261
 
237
262
  $tokens = [];
238
263
  foreach ($matches as $k => $v) {
239
- if ($v !== null && !\is_int($k)) {
240
- $tokens[] = new Token(\constant(Token::class . '::' . $k), $v, $this->position);
264
+ if ($v !== null && !is_int($k)) {
265
+ $tokens[] = new Token(constant(Token::class . '::' . $k), $v, $this->position);
241
266
  $this->position = $this->position->advance($v);
242
267
  }
243
268
  }
@@ -246,15 +271,15 @@ final class TemplateLexer
246
271
  }
247
272
 
248
273
 
249
- public function setState(string $state, ...$args): void
274
+ public function setState(string $state, mixed ...$args): void
250
275
  {
251
276
  $this->states[0] = ['name' => $state, 'args' => $args];
252
277
  }
253
278
 
254
279
 
255
- public function pushState(string $state, ...$args): void
280
+ public function pushState(string $state, mixed ...$args): void
256
281
  {
257
- array_unshift($this->states, null);
282
+ array_unshift($this->states, ['name' => '', 'args' => []]);
258
283
  $this->setState($state, ...$args);
259
284
  }
260
285
 
@@ -281,7 +306,7 @@ final class TemplateLexer
281
306
 
282
307
  $this->delimiters[] = [$this->openDelimiter, $this->closeDelimiter];
283
308
  [$this->openDelimiter, $this->closeDelimiter] = match ($type) {
284
- null => [$left, '\}'], // {...}
309
+ null, 'single' => [$left, '\}'], // {...}
285
310
  'off' => [$endTag ? '(?=' . $end . ')\{' : '(?!x)x', '\}'],
286
311
  'double' => $endTag // {{...}}
287
312
  ? ['(?:\{' . $left . '|(?=' . $end . ')\{)', '\}(?:\}|(?<=' . $end . '))']
@@ -294,7 +319,7 @@ final class TemplateLexer
294
319
 
295
320
  public function popSyntax(): void
296
321
  {
297
- [$this->openDelimiter, $this->closeDelimiter] = array_pop($this->delimiters);
322
+ [$this->openDelimiter, $this->closeDelimiter] = array_pop($this->delimiters) ?? throw new \LogicException;
298
323
  }
299
324
 
300
325
 
@@ -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;
@@ -17,8 +15,12 @@ use Latte\Helpers;
17
15
  use Latte\Policy;
18
16
  use Latte\Runtime\Template;
19
17
  use Latte\SecurityViolationException;
18
+ use function array_keys, array_splice, count, end, in_array, preg_match, str_ends_with, str_starts_with, substr, trim, ucfirst;
20
19
 
21
20
 
21
+ /**
22
+ * Parses Latte template tokens into AST.
23
+ */
22
24
  final class TemplateParser
23
25
  {
24
26
  /** @var Block[][] */
@@ -28,26 +30,29 @@ final class TemplateParser
28
30
  public bool $strict = false;
29
31
  public ?Nodes\TextNode $lastIndentation = null;
30
32
 
31
- /** @var array<string, callable(Tag, self): (Node|\Generator|void)> */
33
+ /** @var array<string, \Closure(Tag, self): (Node|\Generator|void)> */
32
34
  private array $tagParsers = [];
33
35
 
34
36
  /** @var array<string, \stdClass> */
35
37
  private array $attrParsersInfo = [];
36
38
 
37
39
  private TemplateParserHtml $html;
38
- private ?TokenStream $stream = null;
40
+ private TokenStream $stream;
39
41
  private TemplateLexer $lexer;
40
42
  private ?Policy $policy = null;
41
43
  private string $contentType;
42
44
  private int $counter = 0;
43
45
  private ?Tag $tag = null;
44
- private $lastResolver;
46
+ private ?\Closure $lastResolver = null;
47
+
48
+ /** @var \WeakMap<Tag, ?list<string>> */
45
49
  private \WeakMap $lookFor;
46
50
 
47
51
 
48
52
  public function __construct()
49
53
  {
50
54
  $this->lexer = new TemplateLexer;
55
+ $this->stream = new TokenStream(new \EmptyIterator);
51
56
  $this->setContentType(ContentType::Html);
52
57
  }
53
58
 
@@ -70,7 +75,7 @@ final class TemplateParser
70
75
  };
71
76
 
72
77
  $node = new Nodes\TemplateNode;
73
- $node->main = $this->parseFragment([$this->html, 'inTextResolve'], $findLength);
78
+ $node->main = $this->parseFragment($this->html->inTextResolve(...), $findLength);
74
79
  $node->head = new FragmentNode(array_splice($node->main->children, 0, $headLength));
75
80
  $node->contentType = $this->contentType;
76
81
 
@@ -82,7 +87,11 @@ final class TemplateParser
82
87
  }
83
88
 
84
89
 
85
- 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
86
95
  {
87
96
  $res = new FragmentNode;
88
97
  $save = [$this->lastResolver, $this->tag];
@@ -90,6 +99,7 @@ final class TemplateParser
90
99
  try {
91
100
  while (!$this->stream->peek()->isEnd()) {
92
101
  if ($node = $resolver($res)) {
102
+ assert($node instanceof Nodes\AreaNode);
93
103
  $res->append($node);
94
104
  $after && $after($res);
95
105
  } else {
@@ -149,7 +159,7 @@ final class TemplateParser
149
159
 
150
160
  public function parseLatteComment(): Nodes\NopNode
151
161
  {
152
- if (str_ends_with($this->stream->peek(-1)?->text ?? "\n", "\n")) {
162
+ if (str_ends_with($this->stream->tryPeek(-1)->text ?? "\n", "\n")) {
153
163
  $this->lastIndentation ??= new Nodes\TextNode('');
154
164
  }
155
165
  $openToken = $this->stream->consume(Token::Latte_CommentOpen);
@@ -161,11 +171,11 @@ final class TemplateParser
161
171
  }
162
172
 
163
173
 
164
- public function parseLatteStatement(?callable $resolver = null): ?Node
174
+ public function parseLatteStatement(?\Closure $resolver = null): ?Node
165
175
  {
166
176
  $this->lexer->pushState(TemplateLexer::StateLatteTag);
167
177
  if ($this->stream->peek(1)->is(Token::Slash)
168
- || (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))
169
179
  ) {
170
180
  $this->lexer->popState();
171
181
  return null; // go back to previous parseLatteStatement()
@@ -211,13 +221,13 @@ final class TemplateParser
211
221
  $res->send([$content, $tag]);
212
222
  $this->ensureIsConsumed($tag);
213
223
  break;
214
- } elseif (in_array($tag->name, $this->lookFor[$startTag] ?? [], true)) {
224
+ } elseif (in_array($tag->name, $this->lookFor[$startTag] ?? [], strict: true)) {
215
225
  $this->pushTag($tag);
216
226
  $res->send([$content, $tag]);
217
227
  $this->ensureIsConsumed($tag);
218
228
  $this->popTag();
219
229
  } else {
220
- 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);
221
231
  }
222
232
  }
223
233
  }
@@ -229,7 +239,7 @@ final class TemplateParser
229
239
  $node = $res->getReturn();
230
240
 
231
241
  } elseif ($startTag->void) {
232
- 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);
233
243
 
234
244
  } else {
235
245
  $this->ensureIsConsumed($startTag);
@@ -255,17 +265,19 @@ final class TemplateParser
255
265
  private function parseLatteTag(): Tag
256
266
  {
257
267
  $stream = $this->stream;
258
- if (str_ends_with($stream->peek(-1)?->text ?? "\n", "\n")) {
268
+ if (str_ends_with($stream->tryPeek(-1)->text ?? "\n", "\n")) {
259
269
  $this->lastIndentation ??= new Nodes\TextNode('');
260
270
  }
261
271
 
262
- $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);
263
273
  $openToken = $stream->consume(Token::Latte_TagOpen);
264
274
  $this->lexer->pushState(TemplateLexer::StateLatteTag);
275
+ $closing = (bool) $stream->tryConsume(Token::Slash);
276
+ $nameToken = $stream->tryConsume(Token::Latte_Name);
265
277
  $tag = new Tag(
266
278
  position: $openToken->position,
267
- closing: $closing = (bool) $stream->tryConsume(Token::Slash),
268
- name: $stream->tryConsume(Token::Latte_Name)?->text ?? ($closing ? '' : '='),
279
+ closing: $closing,
280
+ name: $nameToken ? $nameToken->text : ($closing ? '' : '='),
269
281
  tokens: $this->consumeTag(),
270
282
  void: (bool) $stream->tryConsume(Token::Slash),
271
283
  inHead: $this->inHead,
@@ -278,7 +290,8 @@ final class TemplateParser
278
290
  }
279
291
 
280
292
 
281
- private function consumeTag(): array
293
+ /** @return Token[] */
294
+ public function consumeTag(): array
282
295
  {
283
296
  $res = [];
284
297
  while ($this->stream->peek()->isPhpKind()) {
@@ -309,8 +322,8 @@ final class TemplateParser
309
322
  }
310
323
 
311
324
 
312
- /** @return callable(Tag, self): (Node|\Generator|void) */
313
- 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
314
327
  {
315
328
  if (!isset($this->tagParsers[$name])) {
316
329
  $hint = ($t = Helpers::getSuggestion(array_keys($this->tagParsers), $name))
@@ -328,6 +341,7 @@ final class TemplateParser
328
341
  }
329
342
 
330
343
 
344
+ /** @return array<string, \Closure(Tag, self): (Node|\Generator|void)> */
331
345
  private function completeAttrParsers(): array
332
346
  {
333
347
  $list = Helpers::sortBeforeAfter($this->attrParsersInfo);