@jesscss/core 2.0.0-alpha.4 → 2.0.0-alpha.6

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 (637) hide show
  1. package/lib/index.cjs +20159 -0
  2. package/lib/index.d.cts +5993 -0
  3. package/lib/index.d.cts.map +1 -0
  4. package/lib/index.d.ts +5992 -21
  5. package/lib/index.d.ts.map +1 -1
  6. package/lib/index.js +19926 -22
  7. package/lib/index.js.map +1 -1
  8. package/package.json +15 -14
  9. package/src/__tests__/define-function-record.test.ts +58 -0
  10. package/src/__tests__/define-function-simple.test.ts +55 -0
  11. package/src/__tests__/define-function-split-sequence.test.ts +547 -0
  12. package/src/__tests__/define-function-type-parity.test.ts +9 -0
  13. package/src/__tests__/define-function.test.ts +763 -0
  14. package/src/__tests__/num-operations.test.ts +91 -0
  15. package/src/__tests__/safe-parse.test.ts +374 -0
  16. package/src/context.ts +896 -0
  17. package/src/conversions.ts +282 -0
  18. package/src/debug-log.ts +29 -0
  19. package/src/define-function.ts +1006 -0
  20. package/src/deprecation.ts +67 -0
  21. package/src/globals.d.ts +26 -0
  22. package/src/index.ts +31 -0
  23. package/src/jess-error.ts +773 -0
  24. package/src/logger/deprecation-processing.ts +109 -0
  25. package/src/logger.ts +31 -0
  26. package/src/plugin.ts +292 -0
  27. package/src/tree/LOOKUP_CHAINS.md +35 -0
  28. package/src/tree/README.md +18 -0
  29. package/src/tree/__tests__/__snapshots__/extend-eval-integration.test.ts.snap +1455 -0
  30. package/src/tree/__tests__/ampersand.test.ts +382 -0
  31. package/src/tree/__tests__/at-rule.test.ts +2047 -0
  32. package/src/tree/__tests__/basic-render.test.ts +212 -0
  33. package/src/tree/__tests__/block.test.ts +40 -0
  34. package/src/tree/__tests__/call.test.ts +346 -0
  35. package/src/tree/__tests__/color.test.ts +537 -0
  36. package/src/tree/__tests__/condition.test.ts +186 -0
  37. package/src/tree/__tests__/control.test.ts +564 -0
  38. package/src/tree/__tests__/declaration.test.ts +253 -0
  39. package/src/tree/__tests__/dependency-graph.test.ts +177 -0
  40. package/src/tree/__tests__/detached-rulesets.test.ts +213 -0
  41. package/src/tree/__tests__/dimension.test.ts +236 -0
  42. package/src/tree/__tests__/expression.test.ts +73 -0
  43. package/src/tree/__tests__/ext-node.test.ts +31 -0
  44. package/src/tree/__tests__/extend-eval-integration.test.ts +1033 -0
  45. package/src/tree/__tests__/extend-import-style.test.ts +929 -0
  46. package/src/tree/__tests__/extend-less-fixtures.test.ts +851 -0
  47. package/src/tree/__tests__/extend-list.test.ts +31 -0
  48. package/src/tree/__tests__/extend-roots.test.ts +1045 -0
  49. package/src/tree/__tests__/extend-rules.test.ts +740 -0
  50. package/src/tree/__tests__/func.test.ts +171 -0
  51. package/src/tree/__tests__/import-js.test.ts +33 -0
  52. package/src/tree/__tests__/import-style-test-helpers.ts +56 -0
  53. package/src/tree/__tests__/import-style.test.ts +1967 -0
  54. package/src/tree/__tests__/interpolated-reference.test.ts +44 -0
  55. package/src/tree/__tests__/interpolated.test.ts +41 -0
  56. package/src/tree/__tests__/list.test.ts +177 -0
  57. package/src/tree/__tests__/log.test.ts +83 -0
  58. package/src/tree/__tests__/mixin-recursion.test.ts +639 -0
  59. package/src/tree/__tests__/mixin.test.ts +2171 -0
  60. package/src/tree/__tests__/negative.test.ts +45 -0
  61. package/src/tree/__tests__/nesting-collapse.test.ts +519 -0
  62. package/src/tree/__tests__/node-flags-perf.test.ts +195 -0
  63. package/src/tree/__tests__/node-flags.test.ts +410 -0
  64. package/src/tree/__tests__/node-graph.test.ts +598 -0
  65. package/src/tree/__tests__/node-mutation.test.ts +182 -0
  66. package/src/tree/__tests__/operation.test.ts +18 -0
  67. package/src/tree/__tests__/paren.test.ts +90 -0
  68. package/src/tree/__tests__/preserve-mode-output.test.ts +50 -0
  69. package/src/tree/__tests__/quoted.test.ts +72 -0
  70. package/src/tree/__tests__/range.test.ts +59 -0
  71. package/src/tree/__tests__/reference.test.ts +743 -0
  72. package/src/tree/__tests__/rest.test.ts +29 -0
  73. package/src/tree/__tests__/rules-raw.test.ts +14 -0
  74. package/src/tree/__tests__/rules.test.ts +1271 -0
  75. package/src/tree/__tests__/ruleset.test.ts +597 -0
  76. package/src/tree/__tests__/selector-attr.test.ts +50 -0
  77. package/src/tree/__tests__/selector-basic.test.ts +44 -0
  78. package/src/tree/__tests__/selector-capture.test.ts +22 -0
  79. package/src/tree/__tests__/selector-complex.test.ts +120 -0
  80. package/src/tree/__tests__/selector-compound.test.ts +74 -0
  81. package/src/tree/__tests__/selector-interpolated.test.ts +50 -0
  82. package/src/tree/__tests__/selector-list.test.ts +59 -0
  83. package/src/tree/__tests__/selector-pseudo.test.ts +23 -0
  84. package/src/tree/__tests__/selector.test.ts +182 -0
  85. package/src/tree/__tests__/sequence.test.ts +226 -0
  86. package/src/tree/__tests__/serialize-types.test.ts +529 -0
  87. package/src/tree/__tests__/spaced.test.ts +8 -0
  88. package/src/tree/__tests__/url.test.ts +72 -0
  89. package/src/tree/__tests__/var-declaration.test.ts +90 -0
  90. package/src/tree/ampersand.ts +538 -0
  91. package/src/tree/any.ts +169 -0
  92. package/src/tree/at-rule.ts +760 -0
  93. package/src/tree/block.ts +72 -0
  94. package/src/tree/bool.ts +46 -0
  95. package/src/tree/call.ts +593 -0
  96. package/src/tree/collection.ts +52 -0
  97. package/src/tree/color.ts +629 -0
  98. package/src/tree/combinator.ts +30 -0
  99. package/src/tree/comment.ts +36 -0
  100. package/src/tree/condition.ts +194 -0
  101. package/src/tree/control.ts +452 -0
  102. package/src/tree/declaration-custom.ts +56 -0
  103. package/src/tree/declaration-var.ts +87 -0
  104. package/src/tree/declaration.ts +742 -0
  105. package/src/tree/default-guard.ts +35 -0
  106. package/src/tree/dimension.ts +392 -0
  107. package/src/tree/expression.ts +97 -0
  108. package/src/tree/extend-list.ts +51 -0
  109. package/src/tree/extend.ts +391 -0
  110. package/src/tree/function.ts +254 -0
  111. package/src/tree/import-js.ts +130 -0
  112. package/src/tree/import-style.ts +875 -0
  113. package/{lib/tree/index.js → src/tree/index.ts} +49 -22
  114. package/src/tree/interpolated.ts +346 -0
  115. package/src/tree/js-array.ts +21 -0
  116. package/src/tree/js-expr.ts +50 -0
  117. package/src/tree/js-function.ts +31 -0
  118. package/src/tree/js-object.ts +22 -0
  119. package/src/tree/list.ts +415 -0
  120. package/src/tree/log.ts +89 -0
  121. package/src/tree/mixin.ts +331 -0
  122. package/src/tree/negative.ts +58 -0
  123. package/src/tree/nil.ts +57 -0
  124. package/src/tree/node-base.ts +1716 -0
  125. package/src/tree/node-type.ts +122 -0
  126. package/src/tree/node.ts +118 -0
  127. package/src/tree/number.ts +54 -0
  128. package/src/tree/operation.ts +187 -0
  129. package/src/tree/paren.ts +132 -0
  130. package/src/tree/query-condition.ts +47 -0
  131. package/src/tree/quoted.ts +119 -0
  132. package/src/tree/range.ts +101 -0
  133. package/src/tree/reference.ts +1099 -0
  134. package/src/tree/rest.ts +55 -0
  135. package/src/tree/rules-raw.ts +52 -0
  136. package/src/tree/rules.ts +2896 -0
  137. package/src/tree/ruleset.ts +1217 -0
  138. package/src/tree/selector-attr.ts +172 -0
  139. package/src/tree/selector-basic.ts +75 -0
  140. package/src/tree/selector-capture.ts +85 -0
  141. package/src/tree/selector-complex.ts +189 -0
  142. package/src/tree/selector-compound.ts +205 -0
  143. package/src/tree/selector-interpolated.ts +95 -0
  144. package/src/tree/selector-list.ts +245 -0
  145. package/src/tree/selector-pseudo.ts +173 -0
  146. package/src/tree/selector-simple.ts +10 -0
  147. package/src/tree/selector.ts +152 -0
  148. package/src/tree/sequence.ts +463 -0
  149. package/src/tree/tree.ts +130 -0
  150. package/src/tree/url.ts +95 -0
  151. package/src/tree/util/EXTEND_ARCHITECTURE_ANALYSIS.md +215 -0
  152. package/src/tree/util/EXTEND_AUDIT.md +233 -0
  153. package/src/tree/util/EXTEND_BASELINE.md +64 -0
  154. package/src/tree/util/EXTEND_CALL_GRAPH_ANALYSIS.md +244 -0
  155. package/src/tree/util/EXTEND_DOCS.md +24 -0
  156. package/src/tree/util/EXTEND_FINAL_SUMMARY.md +95 -0
  157. package/src/tree/util/EXTEND_FUNCTION_AUDIT.md +1433 -0
  158. package/src/tree/util/EXTEND_OPTIMIZATION_PLAN.md +114 -0
  159. package/src/tree/util/EXTEND_REFACTORING_SUMMARY.md +152 -0
  160. package/src/tree/util/EXTEND_RULES.md +74 -0
  161. package/src/tree/util/EXTEND_UNUSED_FUNCTIONS.md +127 -0
  162. package/src/tree/util/EXTEND_UNUSED_FUNCTIONS_ANALYSIS.md +227 -0
  163. package/src/tree/util/NODE_COPY_REDUCTION_PLAN.md +12 -0
  164. package/src/tree/util/__tests__/EXTEND_TEST_INDEX.md +59 -0
  165. package/src/tree/util/__tests__/OPTIMIZATION-ANALYSIS.md +130 -0
  166. package/src/tree/util/__tests__/WALK_AND_CONSUME_DESIGN.md +138 -0
  167. package/src/tree/util/__tests__/_archive/2026-02-09__OPTIMIZATION-ANALYSIS.md +9 -0
  168. package/src/tree/util/__tests__/_archive/README.md +4 -0
  169. package/src/tree/util/__tests__/bitset.test.ts +142 -0
  170. package/src/tree/util/__tests__/debug-log.ts +50 -0
  171. package/src/tree/util/__tests__/extend-comment-handling.test.ts +187 -0
  172. package/src/tree/util/__tests__/extend-core-unit.test.ts +941 -0
  173. package/src/tree/util/__tests__/extend-pipeline-bench.test.ts +154 -0
  174. package/src/tree/util/__tests__/extend-pipeline-bench.ts +190 -0
  175. package/src/tree/util/__tests__/fast-reject.test.ts +377 -0
  176. package/src/tree/util/__tests__/is-node.test.ts +63 -0
  177. package/src/tree/util/__tests__/list-like.test.ts +63 -0
  178. package/src/tree/util/__tests__/outputwriter.test.ts +523 -0
  179. package/src/tree/util/__tests__/print.test.ts +183 -0
  180. package/src/tree/util/__tests__/process-extends.test.ts +226 -0
  181. package/src/tree/util/__tests__/process-leading-is.test.ts +205 -0
  182. package/src/tree/util/__tests__/recursion-helper.test.ts +184 -0
  183. package/src/tree/util/__tests__/selector-match-unit.test.ts +1427 -0
  184. package/src/tree/util/__tests__/sourcemap.test.ts +117 -0
  185. package/src/tree/util/ampersand-template.ts +9 -0
  186. package/src/tree/util/bitset.ts +194 -0
  187. package/src/tree/util/calculate.ts +11 -0
  188. package/src/tree/util/cast.ts +89 -0
  189. package/src/tree/util/cloning.ts +8 -0
  190. package/src/tree/util/collections.ts +299 -0
  191. package/src/tree/util/compare.ts +90 -0
  192. package/src/tree/util/cursor.ts +171 -0
  193. package/src/tree/util/extend-core.ts +2139 -0
  194. package/src/tree/util/extend-roots.ts +1108 -0
  195. package/src/tree/util/field-helpers.ts +354 -0
  196. package/src/tree/util/is-node.ts +43 -0
  197. package/src/tree/util/list-like.ts +93 -0
  198. package/src/tree/util/mixin-instance-primitives.ts +2020 -0
  199. package/src/tree/util/print.ts +303 -0
  200. package/src/tree/util/process-leading-is.ts +421 -0
  201. package/src/tree/util/recursion-helper.ts +54 -0
  202. package/src/tree/util/regex.ts +2 -0
  203. package/src/tree/util/registry-utils.ts +1953 -0
  204. package/src/tree/util/ruleset-trace.ts +17 -0
  205. package/src/tree/util/scoped-body-eval.ts +320 -0
  206. package/src/tree/util/selector-match-core.ts +2005 -0
  207. package/src/tree/util/selector-utils.ts +757 -0
  208. package/src/tree/util/serialize-helper.ts +535 -0
  209. package/src/tree/util/serialize-types.ts +318 -0
  210. package/src/tree/util/should-operate.ts +78 -0
  211. package/src/tree/util/sourcemap.ts +37 -0
  212. package/src/types/config.ts +247 -0
  213. package/src/types/index.ts +12 -0
  214. package/{lib/types/modes.d.ts → src/types/modes.ts} +2 -1
  215. package/src/types.d.ts +9 -0
  216. package/src/types.ts +68 -0
  217. package/src/use-webpack-resolver.ts +56 -0
  218. package/src/visitor/__tests__/visitor.test.ts +136 -0
  219. package/src/visitor/index.ts +263 -0
  220. package/{lib/visitor/less-visitor.js → src/visitor/less-visitor.ts} +3 -2
  221. package/lib/context.d.ts +0 -352
  222. package/lib/context.d.ts.map +0 -1
  223. package/lib/context.js +0 -636
  224. package/lib/context.js.map +0 -1
  225. package/lib/conversions.d.ts +0 -73
  226. package/lib/conversions.d.ts.map +0 -1
  227. package/lib/conversions.js +0 -253
  228. package/lib/conversions.js.map +0 -1
  229. package/lib/debug-log.d.ts +0 -2
  230. package/lib/debug-log.d.ts.map +0 -1
  231. package/lib/debug-log.js +0 -27
  232. package/lib/debug-log.js.map +0 -1
  233. package/lib/define-function.d.ts +0 -587
  234. package/lib/define-function.d.ts.map +0 -1
  235. package/lib/define-function.js +0 -726
  236. package/lib/define-function.js.map +0 -1
  237. package/lib/deprecation.d.ts +0 -34
  238. package/lib/deprecation.d.ts.map +0 -1
  239. package/lib/deprecation.js +0 -57
  240. package/lib/deprecation.js.map +0 -1
  241. package/lib/jess-error.d.ts +0 -343
  242. package/lib/jess-error.d.ts.map +0 -1
  243. package/lib/jess-error.js +0 -508
  244. package/lib/jess-error.js.map +0 -1
  245. package/lib/logger/deprecation-processing.d.ts +0 -41
  246. package/lib/logger/deprecation-processing.d.ts.map +0 -1
  247. package/lib/logger/deprecation-processing.js +0 -81
  248. package/lib/logger/deprecation-processing.js.map +0 -1
  249. package/lib/logger.d.ts +0 -10
  250. package/lib/logger.d.ts.map +0 -1
  251. package/lib/logger.js +0 -20
  252. package/lib/logger.js.map +0 -1
  253. package/lib/plugin.d.ts +0 -94
  254. package/lib/plugin.d.ts.map +0 -1
  255. package/lib/plugin.js +0 -174
  256. package/lib/plugin.js.map +0 -1
  257. package/lib/tree/ampersand.d.ts +0 -94
  258. package/lib/tree/ampersand.d.ts.map +0 -1
  259. package/lib/tree/ampersand.js +0 -269
  260. package/lib/tree/ampersand.js.map +0 -1
  261. package/lib/tree/any.d.ts +0 -58
  262. package/lib/tree/any.d.ts.map +0 -1
  263. package/lib/tree/any.js +0 -104
  264. package/lib/tree/any.js.map +0 -1
  265. package/lib/tree/at-rule.d.ts +0 -53
  266. package/lib/tree/at-rule.d.ts.map +0 -1
  267. package/lib/tree/at-rule.js +0 -503
  268. package/lib/tree/at-rule.js.map +0 -1
  269. package/lib/tree/block.d.ts +0 -22
  270. package/lib/tree/block.d.ts.map +0 -1
  271. package/lib/tree/block.js +0 -24
  272. package/lib/tree/block.js.map +0 -1
  273. package/lib/tree/bool.d.ts +0 -18
  274. package/lib/tree/bool.d.ts.map +0 -1
  275. package/lib/tree/bool.js +0 -28
  276. package/lib/tree/bool.js.map +0 -1
  277. package/lib/tree/call.d.ts +0 -66
  278. package/lib/tree/call.d.ts.map +0 -1
  279. package/lib/tree/call.js +0 -306
  280. package/lib/tree/call.js.map +0 -1
  281. package/lib/tree/collection.d.ts +0 -30
  282. package/lib/tree/collection.d.ts.map +0 -1
  283. package/lib/tree/collection.js +0 -37
  284. package/lib/tree/collection.js.map +0 -1
  285. package/lib/tree/color.d.ts +0 -101
  286. package/lib/tree/color.d.ts.map +0 -1
  287. package/lib/tree/color.js +0 -513
  288. package/lib/tree/color.js.map +0 -1
  289. package/lib/tree/combinator.d.ts +0 -13
  290. package/lib/tree/combinator.d.ts.map +0 -1
  291. package/lib/tree/combinator.js +0 -12
  292. package/lib/tree/combinator.js.map +0 -1
  293. package/lib/tree/comment.d.ts +0 -20
  294. package/lib/tree/comment.d.ts.map +0 -1
  295. package/lib/tree/comment.js +0 -19
  296. package/lib/tree/comment.js.map +0 -1
  297. package/lib/tree/condition.d.ts +0 -31
  298. package/lib/tree/condition.d.ts.map +0 -1
  299. package/lib/tree/condition.js +0 -103
  300. package/lib/tree/condition.js.map +0 -1
  301. package/lib/tree/control.d.ts +0 -104
  302. package/lib/tree/control.d.ts.map +0 -1
  303. package/lib/tree/control.js +0 -430
  304. package/lib/tree/control.js.map +0 -1
  305. package/lib/tree/declaration-custom.d.ts +0 -18
  306. package/lib/tree/declaration-custom.d.ts.map +0 -1
  307. package/lib/tree/declaration-custom.js +0 -24
  308. package/lib/tree/declaration-custom.js.map +0 -1
  309. package/lib/tree/declaration-var.d.ts +0 -35
  310. package/lib/tree/declaration-var.d.ts.map +0 -1
  311. package/lib/tree/declaration-var.js +0 -63
  312. package/lib/tree/declaration-var.js.map +0 -1
  313. package/lib/tree/declaration.d.ts +0 -78
  314. package/lib/tree/declaration.d.ts.map +0 -1
  315. package/lib/tree/declaration.js +0 -286
  316. package/lib/tree/declaration.js.map +0 -1
  317. package/lib/tree/default-guard.d.ts +0 -15
  318. package/lib/tree/default-guard.d.ts.map +0 -1
  319. package/lib/tree/default-guard.js +0 -19
  320. package/lib/tree/default-guard.js.map +0 -1
  321. package/lib/tree/dimension.d.ts +0 -34
  322. package/lib/tree/dimension.d.ts.map +0 -1
  323. package/lib/tree/dimension.js +0 -294
  324. package/lib/tree/dimension.js.map +0 -1
  325. package/lib/tree/expression.d.ts +0 -25
  326. package/lib/tree/expression.d.ts.map +0 -1
  327. package/lib/tree/expression.js +0 -32
  328. package/lib/tree/expression.js.map +0 -1
  329. package/lib/tree/extend-list.d.ts +0 -23
  330. package/lib/tree/extend-list.d.ts.map +0 -1
  331. package/lib/tree/extend-list.js +0 -23
  332. package/lib/tree/extend-list.js.map +0 -1
  333. package/lib/tree/extend.d.ts +0 -47
  334. package/lib/tree/extend.d.ts.map +0 -1
  335. package/lib/tree/extend.js +0 -296
  336. package/lib/tree/extend.js.map +0 -1
  337. package/lib/tree/function.d.ts +0 -48
  338. package/lib/tree/function.d.ts.map +0 -1
  339. package/lib/tree/function.js +0 -74
  340. package/lib/tree/function.js.map +0 -1
  341. package/lib/tree/import-js.d.ts +0 -35
  342. package/lib/tree/import-js.d.ts.map +0 -1
  343. package/lib/tree/import-js.js +0 -45
  344. package/lib/tree/import-js.js.map +0 -1
  345. package/lib/tree/import-style.d.ts +0 -156
  346. package/lib/tree/import-style.d.ts.map +0 -1
  347. package/lib/tree/import-style.js +0 -566
  348. package/lib/tree/import-style.js.map +0 -1
  349. package/lib/tree/index.d.ts +0 -71
  350. package/lib/tree/index.d.ts.map +0 -1
  351. package/lib/tree/index.js.map +0 -1
  352. package/lib/tree/interpolated-reference.d.ts +0 -24
  353. package/lib/tree/interpolated-reference.d.ts.map +0 -1
  354. package/lib/tree/interpolated-reference.js +0 -37
  355. package/lib/tree/interpolated-reference.js.map +0 -1
  356. package/lib/tree/interpolated.d.ts +0 -62
  357. package/lib/tree/interpolated.d.ts.map +0 -1
  358. package/lib/tree/interpolated.js +0 -204
  359. package/lib/tree/interpolated.js.map +0 -1
  360. package/lib/tree/js-array.d.ts +0 -10
  361. package/lib/tree/js-array.d.ts.map +0 -1
  362. package/lib/tree/js-array.js +0 -10
  363. package/lib/tree/js-array.js.map +0 -1
  364. package/lib/tree/js-expr.d.ts +0 -23
  365. package/lib/tree/js-expr.d.ts.map +0 -1
  366. package/lib/tree/js-expr.js +0 -28
  367. package/lib/tree/js-expr.js.map +0 -1
  368. package/lib/tree/js-function.d.ts +0 -20
  369. package/lib/tree/js-function.d.ts.map +0 -1
  370. package/lib/tree/js-function.js +0 -16
  371. package/lib/tree/js-function.js.map +0 -1
  372. package/lib/tree/js-object.d.ts +0 -10
  373. package/lib/tree/js-object.d.ts.map +0 -1
  374. package/lib/tree/js-object.js +0 -10
  375. package/lib/tree/js-object.js.map +0 -1
  376. package/lib/tree/list.d.ts +0 -38
  377. package/lib/tree/list.d.ts.map +0 -1
  378. package/lib/tree/list.js +0 -83
  379. package/lib/tree/list.js.map +0 -1
  380. package/lib/tree/log.d.ts +0 -29
  381. package/lib/tree/log.d.ts.map +0 -1
  382. package/lib/tree/log.js +0 -56
  383. package/lib/tree/log.js.map +0 -1
  384. package/lib/tree/mixin.d.ts +0 -87
  385. package/lib/tree/mixin.d.ts.map +0 -1
  386. package/lib/tree/mixin.js +0 -112
  387. package/lib/tree/mixin.js.map +0 -1
  388. package/lib/tree/negative.d.ts +0 -17
  389. package/lib/tree/negative.d.ts.map +0 -1
  390. package/lib/tree/negative.js +0 -22
  391. package/lib/tree/negative.js.map +0 -1
  392. package/lib/tree/nil.d.ts +0 -30
  393. package/lib/tree/nil.d.ts.map +0 -1
  394. package/lib/tree/nil.js +0 -35
  395. package/lib/tree/nil.js.map +0 -1
  396. package/lib/tree/node-base.d.ts +0 -361
  397. package/lib/tree/node-base.d.ts.map +0 -1
  398. package/lib/tree/node-base.js +0 -930
  399. package/lib/tree/node-base.js.map +0 -1
  400. package/lib/tree/node.d.ts +0 -10
  401. package/lib/tree/node.d.ts.map +0 -1
  402. package/lib/tree/node.js +0 -45
  403. package/lib/tree/node.js.map +0 -1
  404. package/lib/tree/number.d.ts +0 -21
  405. package/lib/tree/number.d.ts.map +0 -1
  406. package/lib/tree/number.js +0 -27
  407. package/lib/tree/number.js.map +0 -1
  408. package/lib/tree/operation.d.ts +0 -26
  409. package/lib/tree/operation.d.ts.map +0 -1
  410. package/lib/tree/operation.js +0 -103
  411. package/lib/tree/operation.js.map +0 -1
  412. package/lib/tree/paren.d.ts +0 -19
  413. package/lib/tree/paren.d.ts.map +0 -1
  414. package/lib/tree/paren.js +0 -92
  415. package/lib/tree/paren.js.map +0 -1
  416. package/lib/tree/query-condition.d.ts +0 -17
  417. package/lib/tree/query-condition.d.ts.map +0 -1
  418. package/lib/tree/query-condition.js +0 -39
  419. package/lib/tree/query-condition.js.map +0 -1
  420. package/lib/tree/quoted.d.ts +0 -28
  421. package/lib/tree/quoted.d.ts.map +0 -1
  422. package/lib/tree/quoted.js +0 -75
  423. package/lib/tree/quoted.js.map +0 -1
  424. package/lib/tree/range.d.ts +0 -33
  425. package/lib/tree/range.d.ts.map +0 -1
  426. package/lib/tree/range.js +0 -47
  427. package/lib/tree/range.js.map +0 -1
  428. package/lib/tree/reference.d.ts +0 -76
  429. package/lib/tree/reference.d.ts.map +0 -1
  430. package/lib/tree/reference.js +0 -521
  431. package/lib/tree/reference.js.map +0 -1
  432. package/lib/tree/rest.d.ts +0 -15
  433. package/lib/tree/rest.d.ts.map +0 -1
  434. package/lib/tree/rest.js +0 -32
  435. package/lib/tree/rest.js.map +0 -1
  436. package/lib/tree/rules-raw.d.ts +0 -17
  437. package/lib/tree/rules-raw.d.ts.map +0 -1
  438. package/lib/tree/rules-raw.js +0 -37
  439. package/lib/tree/rules-raw.js.map +0 -1
  440. package/lib/tree/rules.d.ts +0 -262
  441. package/lib/tree/rules.d.ts.map +0 -1
  442. package/lib/tree/rules.js +0 -2359
  443. package/lib/tree/rules.js.map +0 -1
  444. package/lib/tree/ruleset.d.ts +0 -92
  445. package/lib/tree/ruleset.d.ts.map +0 -1
  446. package/lib/tree/ruleset.js +0 -528
  447. package/lib/tree/ruleset.js.map +0 -1
  448. package/lib/tree/selector-attr.d.ts +0 -31
  449. package/lib/tree/selector-attr.d.ts.map +0 -1
  450. package/lib/tree/selector-attr.js +0 -99
  451. package/lib/tree/selector-attr.js.map +0 -1
  452. package/lib/tree/selector-basic.d.ts +0 -24
  453. package/lib/tree/selector-basic.d.ts.map +0 -1
  454. package/lib/tree/selector-basic.js +0 -38
  455. package/lib/tree/selector-basic.js.map +0 -1
  456. package/lib/tree/selector-capture.d.ts +0 -23
  457. package/lib/tree/selector-capture.d.ts.map +0 -1
  458. package/lib/tree/selector-capture.js +0 -34
  459. package/lib/tree/selector-capture.js.map +0 -1
  460. package/lib/tree/selector-complex.d.ts +0 -40
  461. package/lib/tree/selector-complex.d.ts.map +0 -1
  462. package/lib/tree/selector-complex.js +0 -143
  463. package/lib/tree/selector-complex.js.map +0 -1
  464. package/lib/tree/selector-compound.d.ts +0 -16
  465. package/lib/tree/selector-compound.d.ts.map +0 -1
  466. package/lib/tree/selector-compound.js +0 -114
  467. package/lib/tree/selector-compound.js.map +0 -1
  468. package/lib/tree/selector-interpolated.d.ts +0 -23
  469. package/lib/tree/selector-interpolated.d.ts.map +0 -1
  470. package/lib/tree/selector-interpolated.js +0 -27
  471. package/lib/tree/selector-interpolated.js.map +0 -1
  472. package/lib/tree/selector-list.d.ts +0 -17
  473. package/lib/tree/selector-list.d.ts.map +0 -1
  474. package/lib/tree/selector-list.js +0 -174
  475. package/lib/tree/selector-list.js.map +0 -1
  476. package/lib/tree/selector-pseudo.d.ts +0 -42
  477. package/lib/tree/selector-pseudo.d.ts.map +0 -1
  478. package/lib/tree/selector-pseudo.js +0 -204
  479. package/lib/tree/selector-pseudo.js.map +0 -1
  480. package/lib/tree/selector-simple.d.ts +0 -5
  481. package/lib/tree/selector-simple.d.ts.map +0 -1
  482. package/lib/tree/selector-simple.js +0 -6
  483. package/lib/tree/selector-simple.js.map +0 -1
  484. package/lib/tree/selector.d.ts +0 -43
  485. package/lib/tree/selector.d.ts.map +0 -1
  486. package/lib/tree/selector.js +0 -56
  487. package/lib/tree/selector.js.map +0 -1
  488. package/lib/tree/sequence.d.ts +0 -43
  489. package/lib/tree/sequence.d.ts.map +0 -1
  490. package/lib/tree/sequence.js +0 -151
  491. package/lib/tree/sequence.js.map +0 -1
  492. package/lib/tree/tree.d.ts +0 -87
  493. package/lib/tree/tree.d.ts.map +0 -1
  494. package/lib/tree/tree.js +0 -2
  495. package/lib/tree/tree.js.map +0 -1
  496. package/lib/tree/url.d.ts +0 -18
  497. package/lib/tree/url.d.ts.map +0 -1
  498. package/lib/tree/url.js +0 -35
  499. package/lib/tree/url.js.map +0 -1
  500. package/lib/tree/util/__tests__/debug-log.d.ts +0 -1
  501. package/lib/tree/util/__tests__/debug-log.d.ts.map +0 -1
  502. package/lib/tree/util/__tests__/debug-log.js +0 -36
  503. package/lib/tree/util/__tests__/debug-log.js.map +0 -1
  504. package/lib/tree/util/calculate.d.ts +0 -3
  505. package/lib/tree/util/calculate.d.ts.map +0 -1
  506. package/lib/tree/util/calculate.js +0 -10
  507. package/lib/tree/util/calculate.js.map +0 -1
  508. package/lib/tree/util/cast.d.ts +0 -10
  509. package/lib/tree/util/cast.d.ts.map +0 -1
  510. package/lib/tree/util/cast.js +0 -87
  511. package/lib/tree/util/cast.js.map +0 -1
  512. package/lib/tree/util/cloning.d.ts +0 -4
  513. package/lib/tree/util/cloning.d.ts.map +0 -1
  514. package/lib/tree/util/cloning.js +0 -8
  515. package/lib/tree/util/cloning.js.map +0 -1
  516. package/lib/tree/util/collections.d.ts +0 -57
  517. package/lib/tree/util/collections.d.ts.map +0 -1
  518. package/lib/tree/util/collections.js +0 -136
  519. package/lib/tree/util/collections.js.map +0 -1
  520. package/lib/tree/util/compare.d.ts +0 -11
  521. package/lib/tree/util/compare.d.ts.map +0 -1
  522. package/lib/tree/util/compare.js +0 -89
  523. package/lib/tree/util/compare.js.map +0 -1
  524. package/lib/tree/util/extend-helpers.d.ts +0 -2
  525. package/lib/tree/util/extend-helpers.d.ts.map +0 -1
  526. package/lib/tree/util/extend-helpers.js +0 -2
  527. package/lib/tree/util/extend-helpers.js.map +0 -1
  528. package/lib/tree/util/extend-roots.d.ts +0 -37
  529. package/lib/tree/util/extend-roots.d.ts.map +0 -1
  530. package/lib/tree/util/extend-roots.js +0 -700
  531. package/lib/tree/util/extend-roots.js.map +0 -1
  532. package/lib/tree/util/extend-roots.old.d.ts +0 -132
  533. package/lib/tree/util/extend-roots.old.d.ts.map +0 -1
  534. package/lib/tree/util/extend-roots.old.js +0 -2272
  535. package/lib/tree/util/extend-roots.old.js.map +0 -1
  536. package/lib/tree/util/extend-trace-debug.d.ts +0 -13
  537. package/lib/tree/util/extend-trace-debug.d.ts.map +0 -1
  538. package/lib/tree/util/extend-trace-debug.js +0 -34
  539. package/lib/tree/util/extend-trace-debug.js.map +0 -1
  540. package/lib/tree/util/extend-walk.d.ts +0 -53
  541. package/lib/tree/util/extend-walk.d.ts.map +0 -1
  542. package/lib/tree/util/extend-walk.js +0 -881
  543. package/lib/tree/util/extend-walk.js.map +0 -1
  544. package/lib/tree/util/extend.d.ts +0 -218
  545. package/lib/tree/util/extend.d.ts.map +0 -1
  546. package/lib/tree/util/extend.js +0 -3182
  547. package/lib/tree/util/extend.js.map +0 -1
  548. package/lib/tree/util/find-extendable-locations.d.ts +0 -2
  549. package/lib/tree/util/find-extendable-locations.d.ts.map +0 -1
  550. package/lib/tree/util/find-extendable-locations.js +0 -2
  551. package/lib/tree/util/find-extendable-locations.js.map +0 -1
  552. package/lib/tree/util/format.d.ts +0 -20
  553. package/lib/tree/util/format.d.ts.map +0 -1
  554. package/lib/tree/util/format.js +0 -67
  555. package/lib/tree/util/format.js.map +0 -1
  556. package/lib/tree/util/is-node.d.ts +0 -13
  557. package/lib/tree/util/is-node.d.ts.map +0 -1
  558. package/lib/tree/util/is-node.js +0 -43
  559. package/lib/tree/util/is-node.js.map +0 -1
  560. package/lib/tree/util/print.d.ts +0 -80
  561. package/lib/tree/util/print.d.ts.map +0 -1
  562. package/lib/tree/util/print.js +0 -205
  563. package/lib/tree/util/print.js.map +0 -1
  564. package/lib/tree/util/process-leading-is.d.ts +0 -25
  565. package/lib/tree/util/process-leading-is.d.ts.map +0 -1
  566. package/lib/tree/util/process-leading-is.js +0 -364
  567. package/lib/tree/util/process-leading-is.js.map +0 -1
  568. package/lib/tree/util/recursion-helper.d.ts +0 -15
  569. package/lib/tree/util/recursion-helper.d.ts.map +0 -1
  570. package/lib/tree/util/recursion-helper.js +0 -43
  571. package/lib/tree/util/recursion-helper.js.map +0 -1
  572. package/lib/tree/util/regex.d.ts +0 -4
  573. package/lib/tree/util/regex.d.ts.map +0 -1
  574. package/lib/tree/util/regex.js +0 -4
  575. package/lib/tree/util/regex.js.map +0 -1
  576. package/lib/tree/util/registry-utils.d.ts +0 -192
  577. package/lib/tree/util/registry-utils.d.ts.map +0 -1
  578. package/lib/tree/util/registry-utils.js +0 -1214
  579. package/lib/tree/util/registry-utils.js.map +0 -1
  580. package/lib/tree/util/ruleset-trace.d.ts +0 -4
  581. package/lib/tree/util/ruleset-trace.d.ts.map +0 -1
  582. package/lib/tree/util/ruleset-trace.js +0 -14
  583. package/lib/tree/util/ruleset-trace.js.map +0 -1
  584. package/lib/tree/util/selector-compare.d.ts +0 -2
  585. package/lib/tree/util/selector-compare.d.ts.map +0 -1
  586. package/lib/tree/util/selector-compare.js +0 -2
  587. package/lib/tree/util/selector-compare.js.map +0 -1
  588. package/lib/tree/util/selector-match-core.d.ts +0 -184
  589. package/lib/tree/util/selector-match-core.d.ts.map +0 -1
  590. package/lib/tree/util/selector-match-core.js +0 -1603
  591. package/lib/tree/util/selector-match-core.js.map +0 -1
  592. package/lib/tree/util/selector-utils.d.ts +0 -30
  593. package/lib/tree/util/selector-utils.d.ts.map +0 -1
  594. package/lib/tree/util/selector-utils.js +0 -100
  595. package/lib/tree/util/selector-utils.js.map +0 -1
  596. package/lib/tree/util/serialize-helper.d.ts +0 -13
  597. package/lib/tree/util/serialize-helper.d.ts.map +0 -1
  598. package/lib/tree/util/serialize-helper.js +0 -387
  599. package/lib/tree/util/serialize-helper.js.map +0 -1
  600. package/lib/tree/util/serialize-types.d.ts +0 -9
  601. package/lib/tree/util/serialize-types.d.ts.map +0 -1
  602. package/lib/tree/util/serialize-types.js +0 -216
  603. package/lib/tree/util/serialize-types.js.map +0 -1
  604. package/lib/tree/util/should-operate.d.ts +0 -23
  605. package/lib/tree/util/should-operate.d.ts.map +0 -1
  606. package/lib/tree/util/should-operate.js +0 -46
  607. package/lib/tree/util/should-operate.js.map +0 -1
  608. package/lib/tree/util/sourcemap.d.ts +0 -7
  609. package/lib/tree/util/sourcemap.d.ts.map +0 -1
  610. package/lib/tree/util/sourcemap.js +0 -25
  611. package/lib/tree/util/sourcemap.js.map +0 -1
  612. package/lib/types/config.d.ts +0 -205
  613. package/lib/types/config.d.ts.map +0 -1
  614. package/lib/types/config.js +0 -2
  615. package/lib/types/config.js.map +0 -1
  616. package/lib/types/index.d.ts +0 -15
  617. package/lib/types/index.d.ts.map +0 -1
  618. package/lib/types/index.js +0 -3
  619. package/lib/types/index.js.map +0 -1
  620. package/lib/types/modes.d.ts.map +0 -1
  621. package/lib/types/modes.js +0 -2
  622. package/lib/types/modes.js.map +0 -1
  623. package/lib/types.d.ts +0 -61
  624. package/lib/types.d.ts.map +0 -1
  625. package/lib/types.js +0 -2
  626. package/lib/types.js.map +0 -1
  627. package/lib/use-webpack-resolver.d.ts +0 -9
  628. package/lib/use-webpack-resolver.d.ts.map +0 -1
  629. package/lib/use-webpack-resolver.js +0 -41
  630. package/lib/use-webpack-resolver.js.map +0 -1
  631. package/lib/visitor/index.d.ts +0 -136
  632. package/lib/visitor/index.d.ts.map +0 -1
  633. package/lib/visitor/index.js +0 -135
  634. package/lib/visitor/index.js.map +0 -1
  635. package/lib/visitor/less-visitor.d.ts +0 -7
  636. package/lib/visitor/less-visitor.d.ts.map +0 -1
  637. package/lib/visitor/less-visitor.js.map +0 -1
@@ -0,0 +1,639 @@
1
+ import { mixin, rules, el, decl, any, ref, Node, call, ruleset, compound, Comment, list, condition, expr, num, op } from '../index.js';
2
+ import { Context } from '../../context.js';
3
+ import { JessError } from '../../jess-error.js';
4
+
5
+ let context: Context;
6
+
7
+ // Helper to check for errors without serializing the resolved value
8
+ async function expectRejects<T>(
9
+ promiseOrValue: Promise<T> | T,
10
+ ErrorType?: new (...args: any[]) => Error,
11
+ messagePattern?: RegExp
12
+ ): Promise<void> {
13
+ let error: unknown;
14
+ try {
15
+ await Promise.resolve(promiseOrValue);
16
+ // Create error that will point to the call site
17
+ const err = new Error('Expected promise to reject, but it resolved');
18
+ // Remove this function from the stack trace so it points to the call site
19
+ if (Error.captureStackTrace) {
20
+ Error.captureStackTrace(err, expectRejects);
21
+ } else {
22
+ // Fallback: remove the first line (this function) from stack
23
+ const stack = err.stack?.split('\n');
24
+ if (stack && stack.length > 1) {
25
+ err.stack = stack.slice(1).join('\n');
26
+ }
27
+ }
28
+ throw err;
29
+ } catch (e) {
30
+ if (e instanceof Error && e.message === 'Expected promise to reject, but it resolved') {
31
+ throw e;
32
+ }
33
+ error = e;
34
+ }
35
+ if (!error) {
36
+ const err = new Error('Expected promise to reject, but it resolved');
37
+ if (Error.captureStackTrace) {
38
+ Error.captureStackTrace(err, expectRejects);
39
+ }
40
+ throw err;
41
+ }
42
+ if (ErrorType && !(error instanceof ErrorType)) {
43
+ const errorName = error instanceof Error ? error.constructor.name : 'unknown';
44
+ const errorMsg = error instanceof Error ? error.message : String(error);
45
+ const err = new Error(`Expected error to be instance of ${ErrorType.name}, but got ${errorName}: ${errorMsg}`);
46
+ if (Error.captureStackTrace) {
47
+ Error.captureStackTrace(err, expectRejects);
48
+ }
49
+ throw err;
50
+ }
51
+ if (messagePattern) {
52
+ const errorMsg = error instanceof Error ? error.message : String(error);
53
+ if (!messagePattern.test(errorMsg)) {
54
+ const err = new Error(`Expected error message to match ${messagePattern}, but got: ${errorMsg}`);
55
+ if (Error.captureStackTrace) {
56
+ Error.captureStackTrace(err, expectRejects);
57
+ }
58
+ throw err;
59
+ }
60
+ }
61
+ }
62
+
63
+ describe('Mixin Recursion Detection', () => {
64
+ beforeEach(() => {
65
+ context = new Context({
66
+ collapseNesting: true
67
+ });
68
+ context.depth = 2;
69
+ });
70
+
71
+ describe('nested mixin calls that should succeed', () => {
72
+ it('should be able to call a nested mixin', async () => {
73
+ // .foo {
74
+ // .bar {
75
+ // color: red;
76
+ // }
77
+ // }
78
+ // .output {
79
+ // .foo.bar();
80
+ // }
81
+ const fooRuleset = ruleset({
82
+ selector: el('.foo'),
83
+ rules: rules([
84
+ ruleset({
85
+ selector: el('.bar'),
86
+ rules: rules([decl({ name: 'color', value: any('red') })])
87
+ })
88
+ ])
89
+ });
90
+ const outputRuleset = ruleset({
91
+ selector: el('.output'),
92
+ rules: rules([
93
+ call({
94
+ name: ref({
95
+ key: compound([el('.foo'), el('.bar')])
96
+ }, { type: 'mixin-ruleset' })
97
+ })
98
+ ])
99
+ });
100
+ const root = rules([fooRuleset, outputRuleset]);
101
+ context.root = root;
102
+ const evald = await root.eval(context);
103
+ const css = evald.render(context);
104
+ expect(css).toBeString(`
105
+ .foo .bar {
106
+ color: red;
107
+ }
108
+ .output {
109
+ color: red;
110
+ }
111
+ `);
112
+ });
113
+
114
+ it('should be able to match a compound selector', async () => {
115
+ // .foo.bar {
116
+ // color: red;
117
+ // }
118
+ // .output {
119
+ // .foo.bar();
120
+ // }
121
+ const fooRuleset = ruleset({
122
+ selector: compound([el('.foo'), el('.bar')]),
123
+ rules: rules([decl({ name: 'color', value: any('red') })])
124
+ });
125
+ const outputRuleset = ruleset({
126
+ selector: el('.output'),
127
+ rules: rules([
128
+ call({
129
+ name: ref({
130
+ key: compound([el('.foo'), el('.bar')])
131
+ }, { type: 'mixin-ruleset' })
132
+ })
133
+ ])
134
+ });
135
+ const root = rules([fooRuleset, outputRuleset]);
136
+ context.root = root;
137
+ const evald = await root.eval(context);
138
+ const css = evald.render(context);
139
+ expect(css).toBeString(`
140
+ .foo.bar {
141
+ color: red;
142
+ }
143
+ .output {
144
+ color: red;
145
+ }
146
+ `);
147
+ });
148
+
149
+ it('should be able to call nested mixin from within container #1', async () => {
150
+ // .container {
151
+ // .foo {
152
+ // .bar {
153
+ // color: blue;
154
+ // }
155
+ // }
156
+ // .foo.bar();
157
+ // }
158
+ const containerRuleset = ruleset({
159
+ selector: el('.container'),
160
+ rules: rules([
161
+ ruleset({
162
+ selector: el('.foo'),
163
+ rules: rules([
164
+ ruleset({
165
+ selector: el('.bar'),
166
+ rules: rules([decl({ name: 'color', value: any('blue') })])
167
+ })
168
+ ])
169
+ }),
170
+ call({
171
+ name: ref({
172
+ key: compound([el('.foo'), el('.bar')])
173
+ }, { type: 'mixin-ruleset' })
174
+ })
175
+ ])
176
+ });
177
+ const root = rules([containerRuleset]);
178
+ context.root = root;
179
+ const evald = await root.eval(context);
180
+ const css = evald.render(context);
181
+ expect(css).toBeString(`
182
+ .container .foo .bar {
183
+ color: blue;
184
+ }
185
+ .container {
186
+ color: blue;
187
+ }
188
+ `);
189
+ });
190
+
191
+ it('should be able to call nested mixin from within container #2', async () => {
192
+ // .container {
193
+ // .foo {
194
+ // .bar {
195
+ // color: blue;
196
+ // }
197
+ // }
198
+ // .container.foo.bar();
199
+ // }
200
+ const containerRuleset = ruleset({
201
+ selector: el('.container'),
202
+ rules: rules([
203
+ ruleset({
204
+ selector: el('.foo'),
205
+ rules: rules([
206
+ ruleset({
207
+ selector: el('.bar'),
208
+ rules: rules([decl({ name: 'color', value: any('blue') })])
209
+ })
210
+ ])
211
+ }),
212
+ call({
213
+ name: ref({
214
+ key: compound([el('.container'), el('.foo'), el('.bar')])
215
+ }, { type: 'mixin-ruleset' })
216
+ })
217
+ ])
218
+ });
219
+ const root = rules([containerRuleset]);
220
+ context.root = root;
221
+ const evald = await root.eval(context);
222
+ const css = evald.render(context);
223
+ expect(css).toBeString(`
224
+ .container .foo .bar {
225
+ color: blue;
226
+ }
227
+ .container {
228
+ color: blue;
229
+ }
230
+ `);
231
+ });
232
+
233
+ it('should be able to call nested mixin from outside container', async () => {
234
+ // .container {
235
+ // .foo {
236
+ // .bar {
237
+ // color: blue;
238
+ // }
239
+ // }
240
+ // }
241
+ // .container.foo();
242
+ const containerRuleset = ruleset({
243
+ selector: el('.container'),
244
+ rules: rules([
245
+ ruleset({
246
+ selector: el('.foo'),
247
+ rules: rules([
248
+ ruleset({
249
+ selector: el('.bar'),
250
+ rules: rules([decl({ name: 'color', value: any('blue') })])
251
+ })
252
+ ])
253
+ })
254
+ ])
255
+ });
256
+ const outputRuleset = call({
257
+ name: ref({
258
+ key: compound([el('.container'), el('.foo')])
259
+ }, { type: 'mixin-ruleset' })
260
+ });
261
+ const root = rules([containerRuleset, outputRuleset]);
262
+ context.root = root;
263
+ const evald = await root.eval(context);
264
+ const css = evald.render(context);
265
+ expect(css).toBeString(`
266
+ .container .foo .bar {
267
+ color: blue;
268
+ }
269
+ .bar {
270
+ color: blue;
271
+ }
272
+ `);
273
+ });
274
+ });
275
+
276
+ describe('recursive mixin calls that should fail', () => {
277
+ it.skip('should fail when calling .foo.bar() from within .foo .bar (would cause recursion)', async () => {
278
+ // .foo {
279
+ // .bar {
280
+ // .foo.bar();
281
+ // color: red;
282
+ // }
283
+ // }
284
+ const fooRuleset = ruleset({
285
+ selector: el('.foo'),
286
+ rules: rules([
287
+ ruleset({
288
+ selector: el('.bar'),
289
+ rules: rules([
290
+ call({
291
+ name: ref({
292
+ key: ['.foo', '.bar']
293
+ }, { type: 'mixin-ruleset' })
294
+ }),
295
+ decl({ name: 'color', value: any('red') })
296
+ ])
297
+ })
298
+ ])
299
+ });
300
+
301
+ const root = rules([fooRuleset]);
302
+ context.root = root;
303
+
304
+ await expectRejects(root.eval(context), ReferenceError, /No matching mixins/);
305
+ });
306
+
307
+ it('should fail when calling .foo() from within .foo .bar (would cause recursion)', async () => {
308
+ // .foo {
309
+ // .bar {
310
+ // .foo();
311
+ // color: red;
312
+ // }
313
+ // }
314
+ const fooRuleset = ruleset({
315
+ selector: el('.foo'),
316
+ rules: rules([
317
+ ruleset({
318
+ selector: el('.bar'),
319
+ rules: rules([
320
+ call({ name: ref({ key: '.foo' }, { type: 'mixin-ruleset' }) }),
321
+ decl({ name: 'color', value: any('red') })
322
+ ])
323
+ })
324
+ ])
325
+ });
326
+
327
+ const root = rules([fooRuleset]);
328
+ context.root = root;
329
+
330
+ await expectRejects(root.eval(context), ReferenceError, /No matching mixins/);
331
+ });
332
+
333
+ it('should fail when calling .clearfix() from within .clearfix (direct self-reference)', async () => {
334
+ // .clearfix {
335
+ // .clearfix();
336
+ // }
337
+ const clearfixRuleset = ruleset({
338
+ selector: el('.clearfix'),
339
+ rules: rules([
340
+ call({ name: ref({ key: '.clearfix' }, { type: 'mixin-ruleset' }) })
341
+ ])
342
+ });
343
+
344
+ const root = rules([clearfixRuleset]);
345
+ context.root = root;
346
+
347
+ await expectRejects(root.eval(context), ReferenceError, /No matching mixins/);
348
+ });
349
+
350
+ it('should fail when duplicate .foo .bar blocks both call .foo.bar() (would cause mutual recursion)', async () => {
351
+ // .foo {
352
+ // .bar {
353
+ // .foo.bar();
354
+ // color: red;
355
+ // }
356
+ // }
357
+ // .foo {
358
+ // .bar {
359
+ // .foo.bar();
360
+ // color: red;
361
+ // }
362
+ // }
363
+ const fooRuleset1 = ruleset({
364
+ selector: el('.foo'),
365
+ rules: rules([
366
+ ruleset({
367
+ selector: el('.bar'),
368
+ rules: rules([
369
+ call({ name: ref({ key: '.foo.bar' }, { type: 'mixin-ruleset' }) }),
370
+ decl({ name: 'color', value: any('red') })
371
+ ])
372
+ })
373
+ ])
374
+ });
375
+
376
+ const fooRuleset2 = ruleset({
377
+ selector: el('.foo'),
378
+ rules: rules([
379
+ ruleset({
380
+ selector: el('.bar'),
381
+ rules: rules([
382
+ call({ name: ref({ key: '.foo.bar' }, { type: 'mixin-ruleset' }) }),
383
+ decl({ name: 'color', value: any('red') })
384
+ ])
385
+ })
386
+ ])
387
+ });
388
+
389
+ const root = rules([fooRuleset1, fooRuleset2]);
390
+ context.root = root;
391
+
392
+ await expectRejects(root.eval(context), ReferenceError, /No matching mixins/);
393
+ });
394
+
395
+ it('should fail when mixin A calls mixin B, and mixin B would call mixin A (mutual recursion)', async () => {
396
+ // .a {
397
+ // .b();
398
+ // }
399
+ // .b {
400
+ // .a();
401
+ // }
402
+ const aRuleset = ruleset({
403
+ selector: el('.a'),
404
+ rules: rules([
405
+ call({ name: ref({ key: '.b' }, { type: 'mixin-ruleset' }) })
406
+ ])
407
+ });
408
+
409
+ const bRuleset = ruleset({
410
+ selector: el('.b'),
411
+ rules: rules([
412
+ call({ name: ref({ key: '.a' }, { type: 'mixin-ruleset' }) })
413
+ ])
414
+ });
415
+
416
+ const root = rules([aRuleset, bRuleset]);
417
+ context.root = root;
418
+
419
+ // When .a is called, it calls .b, which would call .a again - should fail
420
+ const testRuleset = ruleset({
421
+ selector: el('.test'),
422
+ rules: rules([
423
+ call({ name: ref({ key: '.a' }, { type: 'mixin-ruleset' }) })
424
+ ])
425
+ });
426
+
427
+ const rootWithCall = rules([aRuleset, bRuleset, testRuleset]);
428
+ context.root = rootWithCall;
429
+
430
+ await expectRejects(rootWithCall.eval(context), undefined, /No matching mixins/);
431
+ });
432
+ });
433
+
434
+ describe('non-recursive mixin calls that should succeed', () => {
435
+ it('should allow recursive mixin calls when the argument signature changes', async () => {
436
+ const recursiveMixin = mixin({
437
+ name: any('.mixin-recursive'),
438
+ params: list([
439
+ any('n', { role: 'property' })
440
+ ]),
441
+ guard: condition([
442
+ expr(ref({ key: 'n' }, { type: 'variable' })),
443
+ '>',
444
+ num(0)
445
+ ]),
446
+ rules: rules([
447
+ decl({ name: 'level', value: ref({ key: 'n' }, { type: 'variable' }) }),
448
+ call({
449
+ name: ref({ key: '.mixin-recursive' }, { type: 'mixin' }),
450
+ args: list([
451
+ op([
452
+ expr(ref({ key: 'n' }, { type: 'variable' })),
453
+ '-',
454
+ expr(num(1))
455
+ ])
456
+ ])
457
+ })
458
+ ])
459
+ });
460
+
461
+ const recursiveDone = mixin({
462
+ name: any('.mixin-recursive'),
463
+ params: list([
464
+ any('n', { role: 'property' })
465
+ ]),
466
+ guard: condition([
467
+ expr(ref({ key: 'n' }, { type: 'variable' })),
468
+ '<=',
469
+ num(0)
470
+ ]),
471
+ rules: rules([
472
+ decl({ name: 'done', value: any('true') })
473
+ ])
474
+ });
475
+
476
+ const testRuleset = ruleset({
477
+ selector: el('.test-recursive'),
478
+ rules: rules([
479
+ call({
480
+ name: ref({ key: '.mixin-recursive' }, { type: 'mixin' }),
481
+ args: list([num(3)])
482
+ })
483
+ ])
484
+ });
485
+
486
+ const root = rules([recursiveMixin, recursiveDone, testRuleset]);
487
+ context.root = root;
488
+
489
+ const evald = await root.eval(context);
490
+ const css = evald.render(context);
491
+
492
+ expect(css).toBeString(`
493
+ .test-recursive {
494
+ level: 3;
495
+ level: 2;
496
+ level: 1;
497
+ done: true;
498
+ }
499
+ `);
500
+ });
501
+
502
+ it('should succeed when calling .foo.foo() from within .foo .bar if .foo .foo exists (no recursion)', async () => {
503
+ // .foo {
504
+ // .bar {
505
+ // .foo.foo();
506
+ // color: red;
507
+ // }
508
+ // .foo {
509
+ // color: blue;
510
+ // }
511
+ // }
512
+ const fooRuleset = ruleset({
513
+ selector: el('.foo'),
514
+ rules: rules([
515
+ ruleset({
516
+ selector: el('.bar'),
517
+ rules: rules([
518
+ call({ name: ref({ key: ['.foo', '.foo'] }, { type: 'mixin-ruleset' }) }),
519
+ decl({ name: 'color', value: any('red') })
520
+ ])
521
+ }),
522
+ ruleset({
523
+ selector: el('.foo'),
524
+ rules: rules([
525
+ decl({ name: 'color', value: any('blue') })
526
+ ])
527
+ })
528
+ ])
529
+ });
530
+
531
+ const root = rules([fooRuleset]);
532
+ context.root = root;
533
+
534
+ const evald = await root.eval(context);
535
+ const css = evald.render(context);
536
+
537
+ expect(css).toBeString(`
538
+ .foo .bar {
539
+ color: blue;
540
+ color: red;
541
+ }
542
+ .foo .foo {
543
+ color: blue;
544
+ }
545
+ `);
546
+ });
547
+
548
+ it('should succeed when calling a mixin from a different ruleset (no recursion)', async () => {
549
+ // .foo {
550
+ // .bar();
551
+ // }
552
+ // .bar {
553
+ // color: blue;
554
+ // }
555
+ const fooRuleset = ruleset({
556
+ selector: el('.foo'),
557
+ rules: rules([
558
+ call({ name: ref({ key: '.bar' }, { type: 'mixin-ruleset' }) })
559
+ ])
560
+ });
561
+
562
+ const barRuleset = ruleset({
563
+ selector: el('.bar'),
564
+ rules: rules([
565
+ decl({ name: 'color', value: any('blue') })
566
+ ])
567
+ });
568
+
569
+ const root = rules([fooRuleset, barRuleset]);
570
+ context.root = root;
571
+
572
+ const evald = await root.eval(context);
573
+ const css = evald.render(context);
574
+
575
+ expect(css).toBeString(`
576
+ .foo {
577
+ color: blue;
578
+ }
579
+ .bar {
580
+ color: blue;
581
+ }
582
+ `);
583
+ });
584
+
585
+ it('should succeed when multiple .clearfix rulesets call .clearfix() mixin (no recursion)', async () => {
586
+ // .clearfix {
587
+ // zoom: 1;
588
+ // }
589
+ // .clearfix {
590
+ // .clearfix();
591
+ // }
592
+ // .clearfix {
593
+ // .clearfix();
594
+ // }
595
+ // .clearfix {
596
+ // .clearfix();
597
+ // }
598
+ // The first .clearfix ruleset is the mixin definition that can be called
599
+ const clearfixMixin = ruleset({
600
+ selector: el('.clearfix'),
601
+ rules: rules([
602
+ new Comment('// .clearfix', { lineComment: true })
603
+ ])
604
+ });
605
+
606
+ // These rulesets call .clearfix() - they should find the first one, not themselves
607
+ const clearfixRuleset1 = ruleset({
608
+ selector: el('.clearfix'),
609
+ rules: rules([
610
+ call({ name: ref({ key: '.clearfix' }, { type: 'mixin-ruleset' }) })
611
+ ])
612
+ });
613
+
614
+ const clearfixRuleset2 = ruleset({
615
+ selector: el('.clearfix'),
616
+ rules: rules([
617
+ call({ name: ref({ key: '.clearfix' }, { type: 'mixin-ruleset' }) })
618
+ ])
619
+ });
620
+
621
+ const clearfixRuleset3 = ruleset({
622
+ selector: el('.clearfix'),
623
+ rules: rules([
624
+ call({ name: ref({ key: '.clearfix' }, { type: 'mixin-ruleset' }) })
625
+ ])
626
+ });
627
+
628
+ const root = rules([clearfixMixin, clearfixRuleset1, clearfixRuleset2, clearfixRuleset3]);
629
+ context.root = root;
630
+
631
+ const evald = await root.eval(context);
632
+ const css = evald.render(context);
633
+
634
+ // Each .clearfix ruleset should have called the first .clearfix() mixin
635
+ expect(css).toBeString(``);
636
+ // Should not throw recursion error
637
+ });
638
+ });
639
+ });