@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,1099 @@
1
+ import { CALLER, CANONICAL, defineType, Node, F_MAY_ASYNC, F_VISIBLE, F_NON_STATIC, type OptionalLocation } from './node.js';
2
+ import type { Context, TreeContext } from '../context.js';
3
+ import { cast } from './util/cast.js';
4
+ import type { FindOptions } from './util/registry-utils.js';
5
+ import { Any, type AnyRole, Keyword } from './any.js';
6
+ import { Selector } from './selector.js';
7
+ import { isNode } from './util/is-node.js';
8
+ import { N } from './node-type.js';
9
+ import type { Call } from './call.js';
10
+ import type { Quoted } from './quoted.js';
11
+ import { atIndex } from './util/collections.js';
12
+ import type { Num } from './number.js';
13
+ import { type PrintOptions, getPrintOptions } from './util/print.js';
14
+ import { isThenable, type MaybePromise, pipe } from '@jesscss/awaitable-pipe';
15
+ import { getFunctionFromMixins } from './rules.js';
16
+ import type { MixinEntry, Rules } from './rules.js';
17
+ import type { Interpolated } from './interpolated.js';
18
+ import type { Ruleset } from './ruleset.js';
19
+ import type { Mixin } from './mixin.js';
20
+ import type { Declaration } from './declaration.js';
21
+ import type { Color } from './color.js';
22
+ import type { VarDeclaration } from './declaration-var.js';
23
+ import {
24
+ isTopLevelVarDeclaration,
25
+ getDependency,
26
+ getParent,
27
+ setParent,
28
+ getSourceParent,
29
+ setSourceParent,
30
+ setDependency
31
+ } from './util/field-helpers.js';
32
+ import { getCurrentParentNode } from './util/selector-utils.js';
33
+
34
+ /**
35
+ * The type is determined by syntax
36
+ * and location.
37
+ * e.g. in Jess
38
+ * - `$foo` refers to a variable
39
+ * - `$.foo` or `$target.foo` is a named member lookup (variable or property)
40
+ * - `$[foo]` or `$target[foo]` is a braced variable reference
41
+ * - `$['foo']` or `$target['foo']` is a braced property reference
42
+ * - `$[$var]` is a variable member name lookup
43
+ * - `$foo[0]` is an index lookup
44
+ * - in `$|.foo()`, `.foo` is a mixin
45
+ * - in `$foo|.mixin()`, `.mixin` is a mixin in `$foo`
46
+ * - Resolution:
47
+ * - `$` searches scope,
48
+ * - `$^` searches in declaration order
49
+ * in Less
50
+ * - `@foo` refers to a variable
51
+ * - `$foo` refers to a property
52
+ * - `.foo` or `#foo` refers to a mixin
53
+ */
54
+ export type ReferenceValue = {
55
+ target?: Reference | Call | undefined;
56
+ key:
57
+ string
58
+ | string[]
59
+ | Node
60
+ | Any
61
+ | number // $[0] or $.0
62
+ | Num // $.key or $[key] or $*key
63
+ | Quoted // $['key']
64
+ | Selector // $*(.selector)
65
+ | Reference // $.key
66
+ | Interpolated; // @{variable} interpolation
67
+ };
68
+
69
+ export type ReferenceOptions = {
70
+ /**
71
+ * What kind of lookup are we doing?
72
+ */
73
+ type?: 'index' | 'declaration' | 'variable' | 'property' | 'function' | 'mixin' | 'ruleset' | 'mixin-ruleset';
74
+ /**
75
+ * Resolution strategy:
76
+ * - 'scope': Search in scope (Less-style, default)
77
+ * - 'linear': Search linearly from definition position (Sass-style for regular code)
78
+ * - 'call-time': Search linearly from call site position (Sass-style for mixins/functions)
79
+ */
80
+ resolution?: 'scope' | 'linear' | 'call-time';
81
+ /**
82
+ * Optional references just resolve to the string
83
+ * representation if the fallback value is set to true.
84
+ *
85
+ * @note - Used by Less for function references
86
+ */
87
+ fallbackValue?: Node | true;
88
+ filter?: (node: Node) => boolean;
89
+ role?: AnyRole;
90
+ /** Internal: preserve lexical start-bound lookup for synthetic refs such as `+:` normalization. */
91
+ respectStart?: boolean;
92
+ };
93
+ const { isArray } = Array;
94
+
95
+ /**
96
+ * Extract mixin reference keys from a selector in document order,
97
+ * skipping combinators. For `#theme > .mixin`, returns `["#theme", ".mixin"]`.
98
+ *
99
+ * Must preserve the original selector child order (not bitset order)
100
+ * so that MixinRegistry lookup uses the correct startKey.
101
+ */
102
+ function getSelectorReferenceKeys(selector: Selector): string[] {
103
+ const value = 'value' in selector ? selector.value : undefined;
104
+ if (isArray(value)) {
105
+ const keys: string[] = [];
106
+ for (const child of value) {
107
+ if (isNode(child, N.Combinator)) {
108
+ continue;
109
+ }
110
+ if (isNode(child, N.Selector)) {
111
+ keys.push(...getSelectorReferenceKeys(child as Selector));
112
+ } else {
113
+ const val = String(child.valueOf());
114
+ if (val) {
115
+ keys.push(val);
116
+ }
117
+ }
118
+ }
119
+ return keys;
120
+ }
121
+ const val = String(selector.valueOf());
122
+ return val ? [val] : [];
123
+ }
124
+
125
+ function normalizeSelectorPathKey(
126
+ key: string,
127
+ type: ReferenceOptions['type']
128
+ ): string | string[] {
129
+ if (type !== 'mixin' && type !== 'ruleset' && type !== 'mixin-ruleset') {
130
+ return key;
131
+ }
132
+ if (key.includes(' ') || key.includes('>') || key.includes('+') || key.includes('~') || key.includes('||')) {
133
+ return key;
134
+ }
135
+ const parts = key.match(/[.#][^.#\s>+~|]+/g);
136
+ if (parts && parts.length > 1 && parts.join('') === key) {
137
+ return parts;
138
+ }
139
+ return key;
140
+ }
141
+
142
+ function isInsideSelectorCapture(node: Node | undefined, context?: Context): boolean {
143
+ let cursor: Node | undefined = node;
144
+ while (cursor) {
145
+ if (cursor.type === 'SelectorCapture') {
146
+ return true;
147
+ }
148
+ cursor = context ? getLookupParentNode(cursor, context) : cursor.parent;
149
+ }
150
+ return false;
151
+ }
152
+
153
+ function getLookupParentNode(node: Node, context: Context): Node | undefined {
154
+ return getParent(node, context);
155
+ }
156
+
157
+ function getStateRulesParent(node: Node, context: Context): Rules | undefined {
158
+ let possibleRules: Node | undefined = getLookupParentNode(node, context);
159
+ while (possibleRules && possibleRules.type !== 'Rules') {
160
+ possibleRules = getLookupParentNode(possibleRules, context);
161
+ }
162
+ return possibleRules as Rules | undefined;
163
+ }
164
+
165
+ function getNodeScopedParent(node: Node, context: Context): Node | undefined {
166
+ return getParent(node, {
167
+ ...context,
168
+ renderKey: undefined,
169
+ rulesContext: undefined
170
+ });
171
+ }
172
+
173
+ function getSourceRulesParent(node: Node, context: Context): Rules | undefined {
174
+ let possibleRules: Node | undefined = getNodeScopedParent(node, context);
175
+ while (possibleRules && possibleRules.type !== 'Rules') {
176
+ possibleRules = getNodeScopedParent(possibleRules, context);
177
+ }
178
+ return possibleRules as Rules | undefined;
179
+ }
180
+
181
+ function getStateSourceRulesParent(node: Node, context: Context): Rules | undefined {
182
+ let current: Node | undefined = node;
183
+ let sourceParent = getSourceParent(node, context);
184
+ while (current && !sourceParent) {
185
+ current = getLookupParentNode(current, context);
186
+ sourceParent = current ? getSourceParent(current, context) : undefined;
187
+ }
188
+ if (sourceParent && isNode(sourceParent, N.Rules)) {
189
+ return sourceParent as Rules;
190
+ }
191
+ return sourceParent ? getSourceRulesParent(sourceParent, context) : undefined;
192
+ }
193
+
194
+ function getCallerParentNode(node: Node, context: Context): Node | undefined {
195
+ let current: Node | undefined = node;
196
+ while (current) {
197
+ const callerParent = current.parentEdges?.get(CALLER);
198
+ if (callerParent) {
199
+ return callerParent;
200
+ }
201
+ current = getLookupParentNode(current, context);
202
+ }
203
+ return undefined;
204
+ }
205
+
206
+ function getCallerRulesParent(node: Node, context: Context): Rules | undefined {
207
+ const callerParent = getCallerParentNode(node, context);
208
+ if (callerParent && isNode(callerParent, N.Rules)) {
209
+ return callerParent as Rules;
210
+ }
211
+ return callerParent ? getStateRulesParent(callerParent, context) : undefined;
212
+ }
213
+
214
+ function shouldAnchorResolvedReferenceResult(
215
+ result: Node,
216
+ context: Context
217
+ ): boolean {
218
+ if ((result.nodeType & (N.Mixin | N.Ruleset | N.Rules | N.Func | N.JsFunction)) !== 0) {
219
+ return getSourceParent(result, context) === undefined;
220
+ }
221
+ return true;
222
+ }
223
+
224
+ function anchorResolvedReferenceResult<T extends Node>(
225
+ result: T,
226
+ sourceReference: Node,
227
+ context: Context
228
+ ): T {
229
+ if (shouldAnchorResolvedReferenceResult(result, context)) {
230
+ setSourceParent(result, sourceReference, context);
231
+ }
232
+ return result;
233
+ }
234
+
235
+ export type ReferenceChildData = {
236
+ target: Reference | Call | undefined;
237
+ key: ReferenceValue['key'];
238
+ };
239
+
240
+ /**
241
+ * This is a variable or property reference,
242
+ * which can itself contain a reference (a variable variable).
243
+ */
244
+ export interface Reference {
245
+ type: 'Reference';
246
+ shortType: 'ref';
247
+ }
248
+ export class Reference extends Node<ReferenceValue, ReferenceOptions, ReferenceChildData> {
249
+ static override childKeys = ['target', 'key'] as const;
250
+
251
+ target: Reference | Call | undefined;
252
+ key!: ReferenceValue['key'];
253
+
254
+ constructor(value: ReferenceValue | string, options?: ReferenceOptions, location?: OptionalLocation, treeContext?: TreeContext) {
255
+ if (typeof value === 'string') {
256
+ value = { key: value };
257
+ }
258
+ super(value, options, location, treeContext);
259
+ this.target = value.target;
260
+ this.key = value.key;
261
+ if (this.target instanceof Node) {
262
+ this.adopt(this.target);
263
+ }
264
+ if (this.key instanceof Node) {
265
+ this.adopt(this.key);
266
+ }
267
+ // References are always non-static and may be async
268
+ this.addFlags(F_MAY_ASYNC, F_VISIBLE, F_NON_STATIC);
269
+ }
270
+
271
+ override preEval(context: Context): MaybePromise<Node> {
272
+ if (this.preEvaluated) {
273
+ return this;
274
+ }
275
+ const node = this.clone();
276
+ node.preEvaluated = true;
277
+ if (this.parentEdges) {
278
+ node.parentEdges = new Map(this.parentEdges);
279
+ }
280
+ const out = node.forEachNode(child => child.preEval(context), context);
281
+ if (isThenable(out)) {
282
+ return (out as Promise<void>).then(() => node);
283
+ }
284
+ return node;
285
+ }
286
+
287
+ override valueOf() {
288
+ return '';
289
+ }
290
+
291
+ /**
292
+ * @note - A reference doesn't render `$` (unless it has a target);
293
+ * that's managed by the parent expression.
294
+ */
295
+ override toTrimmedString(options?: PrintOptions): string {
296
+ options = getPrintOptions(options);
297
+ const w = options.writer!;
298
+ const mark = w.mark();
299
+ let { type = 'variable', resolution, fallbackValue, role } = this.options;
300
+ const context = options.context;
301
+ const target = this.get('target', context);
302
+ const key = this.get('key', context);
303
+ const emitKey = (k: any) => {
304
+ if (typeof k === 'string' || typeof k === 'number') {
305
+ w.add(String(k), this);
306
+ } else if (k instanceof Node) {
307
+ k.toString(options);
308
+ } else if (isArray(k)) {
309
+ w.add(k.map(k => String(k)).join(''));
310
+ } else {
311
+ w.add(String(k));
312
+ }
313
+ };
314
+ if (target) {
315
+ target.toString(options);
316
+ }
317
+ if (resolution === 'linear') {
318
+ w.add('^');
319
+ } else if (resolution === 'call-time') {
320
+ w.add('~');
321
+ }
322
+ /**
323
+ * Reference serialization forms:
324
+ * 1. `$[key]` — braced variable reference (or `$target[key]` with a target)
325
+ * 2. `$['key']` — braced property reference (or `$target['key']` with a target)
326
+ * 3. `$.key` or `$target.key` — dot syntax for named member lookup (variable or property)
327
+ * 4. `$[$var]` — variable member name lookup (key is itself a reference)
328
+ * 5. `$[0]` — index (or `$target[0]` with a target)
329
+ * 6. `$[-1]` — negative index
330
+ */
331
+ if (role === 'ident' && (type === 'variable' || type === 'property') && !target) {
332
+ w.add('$[');
333
+ emitKey(key);
334
+ w.add(']');
335
+ return w.getSince(mark);
336
+ }
337
+ switch (type) {
338
+ case 'index':
339
+ if (!target) {
340
+ w.add('$');
341
+ }
342
+ w.add('[');
343
+ emitKey(key);
344
+ w.add(']');
345
+ break;
346
+ case 'variable':
347
+ if (target) {
348
+ // Braced variable: $target[key]
349
+ w.add('[');
350
+ emitKey(key);
351
+ w.add(']');
352
+ } else {
353
+ w.add('$');
354
+ emitKey(key);
355
+ }
356
+ break;
357
+ case 'declaration':
358
+ // Dot syntax for named member lookup: $.key or $target.key
359
+ if (!target) {
360
+ w.add('$');
361
+ }
362
+ w.add('.');
363
+ emitKey(key);
364
+ break;
365
+ case 'property':
366
+ // Braced property: $['key'] or $target['key']
367
+ if (!target) {
368
+ w.add('$');
369
+ }
370
+ w.add('[\'');
371
+ emitKey(key);
372
+ w.add('\']');
373
+ break;
374
+ case 'mixin':
375
+ // If this mixin reference has a target (e.g. `ns.foo`), render it as a scoped lookup:
376
+ // `ns > foo`. Without target, keep the legacy mixin marker form (`|foo`).
377
+ w.add(target ? ' > ' : '|');
378
+ emitKey(key);
379
+ break;
380
+
381
+ /** @todo - remove? This should be a selector capture node I think */
382
+ case 'ruleset':
383
+ w.add('*(');
384
+ emitKey(key);
385
+ w.add(')');
386
+ break;
387
+ case 'mixin-ruleset':
388
+ w.add('*');
389
+ emitKey(key);
390
+ break;
391
+ }
392
+ if (fallbackValue === true) {
393
+ w.add('?');
394
+ }
395
+ return w.getSince(mark);
396
+ }
397
+
398
+ /**
399
+ * We don't need to mark evaluated, because a reference
400
+ * should never resolve to itself
401
+ */
402
+ override evalNode(context: Context): MaybePromise<Node> {
403
+ const stripBoundaryPathInPlace = (
404
+ node: Node,
405
+ boundary: 'leading' | 'trailing'
406
+ ): void => {
407
+ if (boundary === 'leading') {
408
+ node.pre = undefined;
409
+ } else {
410
+ node.post = undefined;
411
+ }
412
+ if (!isNode(node, N.Sequence | N.List)) {
413
+ return;
414
+ }
415
+ const value = (node as unknown as { value: Node[] }).value;
416
+ const index = boundary === 'leading' ? 0 : value.length - 1;
417
+ const child = value[index];
418
+ if (!(child instanceof Node)) {
419
+ return;
420
+ }
421
+ const childClone = child.clone(false, undefined, context);
422
+ value[index] = childClone;
423
+ setParent(childClone, node, context);
424
+ stripBoundaryPathInPlace(childClone, boundary);
425
+ };
426
+
427
+ const materializeResolvedValue = <T extends Node>(node: T): T => {
428
+ const out = node.clone(false, undefined, context) as T;
429
+ if (isNode(out, N.Sequence | N.List)) {
430
+ stripBoundaryPathInPlace(out, 'leading');
431
+ stripBoundaryPathInPlace(out, 'trailing');
432
+ }
433
+ return out;
434
+ };
435
+
436
+ let target = this.get('target', context);
437
+ let key = this.get('key', context);
438
+ let { type, fallbackValue, filter: originalFilter } = this.options;
439
+ // Track reference chain for clearing remainders at outermost level
440
+ context.pushReference();
441
+ // Prefer the *current* evaluation rules context (mixin call-time scope) over the lexical rulesParent.
442
+ // This is critical for mixin parameters (e.g. `@fallback`) which are registered onto the call-time
443
+ // wrapper `Rules` and should be visible inside nested at-rule preludes.
444
+ const activeRulesParent = getStateRulesParent(this, context);
445
+ const activeSourceRulesParent = getStateSourceRulesParent(this, context);
446
+ const activeCallerRulesParent = getCallerRulesParent(this, context);
447
+ const lookupSourceRulesParent = context.lookupScope
448
+ ? getStateSourceRulesParent(context.lookupScope, context)
449
+ : undefined;
450
+ const lookupCallerRulesParent = context.lookupScope
451
+ ? getCallerRulesParent(context.lookupScope, context)
452
+ : undefined;
453
+ const sourceReference = this.sourceNode as Node;
454
+ let resolvedTarget = target
455
+ ? target.eval(context)
456
+ : (
457
+ type === 'property'
458
+ ? activeRulesParent ?? context.rulesContext
459
+ : context.rulesContext ?? activeRulesParent
460
+ );
461
+ const result = pipe(
462
+ () => {
463
+ if (isThenable(resolvedTarget)) {
464
+ return (resolvedTarget as Promise<any>).then(result => result);
465
+ }
466
+ return resolvedTarget;
467
+ },
468
+ (resolvedTarget) => {
469
+ let out: any;
470
+ try {
471
+ out = isNode(key) ? key.eval(context) : key;
472
+ } catch (err: unknown) {
473
+ throw err;
474
+ }
475
+ if (isThenable(out)) {
476
+ return out.then((k: any) => {
477
+ // If key is a Selector (CompoundSelector, ComplexSelector, etc.), extract keySet as array
478
+ if (isNode(k, N.Selector)) {
479
+ const keyArray = getSelectorReferenceKeys(k as Selector);
480
+ return [resolvedTarget, keyArray] as [any, string[]];
481
+ }
482
+ // If k is already an array, preserve it
483
+ if (isArray(k)) {
484
+ return [resolvedTarget, k] as [any, string[]];
485
+ }
486
+ return [resolvedTarget, k.valueOf()] as [any, string];
487
+ });
488
+ }
489
+ // If key is a Selector (CompoundSelector, ComplexSelector, etc.), extract keySet as array
490
+ if (isNode(out, N.Selector)) {
491
+ const keyArray = getSelectorReferenceKeys(out as Selector);
492
+ return [resolvedTarget, keyArray] as [any, string[]];
493
+ }
494
+ // If key is already an array, preserve it
495
+ if (isArray(out)) {
496
+ return [resolvedTarget, out] as [any, string[]];
497
+ }
498
+ const normalizedKey = typeof (isNode(out) ? out.valueOf() : out) === 'string'
499
+ ? normalizeSelectorPathKey(String(isNode(out) ? out.valueOf() : out), type)
500
+ : (isNode(out) ? out.valueOf() : out);
501
+ return [resolvedTarget, normalizedKey] as [any, string];
502
+ },
503
+ ([resolvedTarget, valueKey]) => {
504
+ /**
505
+ * If we don't have rules yet, assume that this node
506
+ * was an ambiguous reference to a mixin (such as a valid color
507
+ * or an interpolated identifier). In that case, try to resolve
508
+ * it as a reference to a mixin.
509
+ *
510
+ * (We have to do this for Less.)
511
+ */
512
+ if (resolvedTarget instanceof Node) {
513
+ if (!isNode(resolvedTarget, N.Rules | N.Ruleset | N.JsFunction | N.Mixin)) {
514
+ let targetKey = isNode(resolvedTarget as Node, N.Color) ? String((resolvedTarget as Color)._nodeValue) : (resolvedTarget as Node).valueOf();
515
+ if (typeof targetKey === 'string') {
516
+ let ref = new Reference(targetKey, { type: 'mixin-ruleset' });
517
+ this.adopt(ref, context);
518
+ return Promise.all([
519
+ ref.eval(context),
520
+ valueKey
521
+ ]);
522
+ }
523
+ }
524
+ }
525
+ return [resolvedTarget, valueKey] as [any, string | string[]];
526
+ },
527
+ ([resolvedTarget, valueKey]) => {
528
+ /**
529
+ * If we're looking something up on a function, we presume
530
+ * it needs to be called first, and that it has no arguments.
531
+ */
532
+ if (isNode(resolvedTarget, N.JsFunction)) {
533
+ const jsResult = ((resolvedTarget as any).value as (...args: any[]) => any).call(context);
534
+ if (isThenable(jsResult)) {
535
+ return (jsResult as Promise<any>).then((result) => {
536
+ return [result, valueKey] as [any, string | string[]];
537
+ });
538
+ } else {
539
+ resolvedTarget = jsResult;
540
+ return [resolvedTarget, valueKey] as [any, string | string[]];
541
+ }
542
+ }
543
+
544
+ /**
545
+ * If we're looking something up on a mixin or ruleset (namespace lookup),
546
+ * we need to evaluate its rules to get the Rules node first.
547
+ *
548
+ * Before evaluating, check if this Ruleset/Mixin has matched keys from a previous partial match
549
+ * (for chained calls like .jo.ki() where .jo finds .jo.ki with matched keys [".jo"])
550
+ * We accumulate the new key and use registry lookup to verify the compound match
551
+ */
552
+ if (isNode(resolvedTarget, N.Mixin | N.Ruleset)) {
553
+ const targetRules = isNode(resolvedTarget, N.Ruleset)
554
+ ? (resolvedTarget as Ruleset).enterRules(context)
555
+ : (resolvedTarget as Mixin)
556
+ .get('rules', context)
557
+ .withRenderOwner(
558
+ resolvedTarget as Node,
559
+ (resolvedTarget as Node).renderKey ?? context.renderKey,
560
+ context
561
+ );
562
+ return [targetRules, valueKey] as [Node, string | string[]];
563
+ }
564
+
565
+ return [resolvedTarget, valueKey] as [Node, string | string[]];
566
+ },
567
+ ([resolvedTarget, valueKey]) => {
568
+ originalFilter ??= () => true;
569
+ const isInterpolatedVariable =
570
+ this.options.type === 'variable'
571
+ && getLookupParentNode(this, context)?.type === 'Interpolated';
572
+ const filter = (n: Node) => {
573
+ const passesOriginal = originalFilter!(n);
574
+ const blockedBySearchScope = context.hasInSearchScope(n);
575
+ return passesOriginal && !blockedBySearchScope;
576
+ };
577
+ const hasTarget = !!target;
578
+
579
+ const performLookup = (targetRules: Rules | Node | undefined): any => {
580
+ if (!targetRules) {
581
+ return undefined;
582
+ }
583
+ const opts: FindOptions = { filter, context, hasTarget };
584
+ const findLocalLinearPropertyDeclaration = (rules: Rules, keyStr: string): Node | undefined => {
585
+ if (this.options.resolution !== 'linear' || opts.start === undefined) {
586
+ return undefined;
587
+ }
588
+ const children = rules.getRegistryChildren(context);
589
+ const start = Math.min(opts.start - 1, children.length - 1);
590
+ for (let i = start; i >= 0; i--) {
591
+ const candidate = children[i];
592
+ if (
593
+ candidate
594
+ && isNode(candidate, N.Declaration)
595
+ && String(candidate.get('name', context).valueOf()) === keyStr
596
+ && (!filter || filter(candidate))
597
+ ) {
598
+ return candidate;
599
+ }
600
+ }
601
+ return undefined;
602
+ };
603
+ if (
604
+ !target
605
+ && targetRules.options?.isMixinOutput === true
606
+ && (type === 'mixin' || type === 'mixin-ruleset' || type === 'ruleset')
607
+ ) {
608
+ opts.local = true;
609
+ }
610
+
611
+ const shouldRespectStart = type !== 'property' || this.options.respectStart === true;
612
+ if (this.options.resolution === 'linear' && !isInterpolatedVariable && shouldRespectStart) {
613
+ // For linear resolution, climb up the parent chain until we find a node with a Rules parent
614
+ // and use that node's index for linear lookup
615
+ let startIndex = this.index;
616
+ let currentNode: Node | undefined = this;
617
+ const shouldDebugPropertyStart = type === 'property'
618
+ && (isArray(valueKey) ? valueKey[0] : valueKey) === 'background-color';
619
+ const debugChain: Array<{ type: string; index: number | undefined; renderKey: string }> = shouldDebugPropertyStart
620
+ ? [{ type: currentNode.type, index: currentNode.index, renderKey: String(currentNode.renderKey) }]
621
+ : [];
622
+
623
+ // If this node doesn't have an index, climb up until we find one
624
+ if (startIndex === undefined) {
625
+ while (currentNode && startIndex === undefined) {
626
+ currentNode = getLookupParentNode(currentNode, context);
627
+ if (shouldDebugPropertyStart && currentNode) {
628
+ debugChain.push({ type: currentNode.type, index: currentNode.index, renderKey: String(currentNode.renderKey) });
629
+ }
630
+ if (currentNode) {
631
+ startIndex = currentNode.index;
632
+ }
633
+ }
634
+ }
635
+
636
+ // Now climb up until we find a node that has a Rules parent
637
+ while (currentNode) {
638
+ const currentParent = getLookupParentNode(currentNode, context);
639
+ if (!currentParent || isNode(currentParent, N.Rules)) {
640
+ break;
641
+ }
642
+ currentNode = currentParent;
643
+ if (shouldDebugPropertyStart) {
644
+ debugChain.push({ type: currentNode.type, index: currentNode.index, renderKey: String(currentNode.renderKey) });
645
+ }
646
+ if (currentNode && currentNode.index !== undefined) {
647
+ startIndex = currentNode.index;
648
+ }
649
+ }
650
+
651
+ if (startIndex !== undefined) {
652
+ opts.start = startIndex;
653
+ }
654
+ } else if (this.options.resolution === 'call-time' && !isInterpolatedVariable && shouldRespectStart) {
655
+ // For call-time resolution, use the call site's position (context.callSiteIndex)
656
+ // instead of the definition position. This allows mixins to resolve variables
657
+ // at the time they're called, not when they're defined.
658
+ if (context.rulesContext !== undefined) {
659
+ opts.start = context.rulesContext.index;
660
+ } else {
661
+ // Fall back to linear resolution if we can't find a call site
662
+ let startIndex = this.index;
663
+ let currentNode: Node | undefined = this;
664
+
665
+ if (startIndex === undefined) {
666
+ while (currentNode && startIndex === undefined) {
667
+ currentNode = getLookupParentNode(currentNode, context);
668
+ if (currentNode) {
669
+ startIndex = currentNode.index;
670
+ }
671
+ }
672
+ }
673
+
674
+ while (currentNode) {
675
+ const currentParent = getLookupParentNode(currentNode, context);
676
+ if (!currentParent || isNode(currentParent, N.Rules)) {
677
+ break;
678
+ }
679
+ currentNode = currentParent;
680
+ if (currentNode && currentNode.index !== undefined) {
681
+ startIndex = currentNode.index;
682
+ }
683
+ }
684
+
685
+ if (startIndex !== undefined) {
686
+ opts.start = startIndex;
687
+ }
688
+ }
689
+ }
690
+ switch (type) {
691
+ case 'index':
692
+ if (typeof valueKey === 'number') {
693
+ if (isNode(targetRules, N.Rules)) {
694
+ return targetRules.at(valueKey);
695
+ } else if (isNode(targetRules, N.JsArray)) {
696
+ return atIndex((targetRules as any).value, valueKey);
697
+ }
698
+ } else {
699
+ const keyStr = isArray(valueKey) ? (valueKey[0] ?? '') : valueKey;
700
+ if (isNode(targetRules, N.Rules)) {
701
+ // If the key was a Keyword, look up as a variable first
702
+ if (key instanceof Keyword) {
703
+ const found = targetRules.find('declaration', `${keyStr}`, 'VarDeclaration', opts);
704
+ if (found !== undefined) {
705
+ return found;
706
+ }
707
+ }
708
+ // If the key was a Quoted, look up as a property
709
+ if (isNode(key, N.Quoted)) { // property lookup
710
+ const found = targetRules.find('declaration', `${keyStr}`, 'Declaration', opts);
711
+ if (found !== undefined) {
712
+ return found;
713
+ }
714
+ }
715
+ return targetRules.find('declaration', `${keyStr}`, undefined, opts);
716
+ } else if (isNode(targetRules, N.JsObject)) {
717
+ return (targetRules as any).value[keyStr];
718
+ }
719
+ }
720
+ break;
721
+ case 'variable':
722
+ if (isNode(targetRules, N.Rules)) {
723
+ const keyStr = isArray(valueKey) ? valueKey[0] : valueKey;
724
+ const found = targetRules.find('declaration', `${keyStr}`, 'VarDeclaration', opts);
725
+ if (found !== undefined) {
726
+ return found;
727
+ }
728
+ return undefined;
729
+ }
730
+ break;
731
+ case 'function':
732
+ if (isNode(targetRules, N.Rules)) {
733
+ const keyStr = isArray(valueKey) ? valueKey[0] : valueKey;
734
+ const inCall = isNode(getLookupParentNode(this, context), N.Call);
735
+ const findFunction = () =>
736
+ targetRules.find('function', `${keyStr}`, undefined, opts)
737
+ ?? targetRules.findStatePatchedFunction(`${keyStr}`, opts);
738
+ // When called (e.g. `ns.func(...)`), prefer function lookup first, then fall back to a declaration.
739
+ // When not called, parsers should generally use `index`/`variable` references for `ns.func` so
740
+ // declarations win; but if we are here, keep behavior predictable.
741
+ if (inCall) {
742
+ return (
743
+ findFunction()
744
+ ?? targetRules.find('declaration', `${keyStr}`, undefined, opts)
745
+ );
746
+ }
747
+ // Not in call: prefer declaration first, then function.
748
+ return (
749
+ targetRules.find('declaration', `${keyStr}`, undefined, opts)
750
+ ?? findFunction()
751
+ );
752
+ }
753
+ break;
754
+ case 'property':
755
+ if (isNode(targetRules, N.Rules)) {
756
+ const keyStr = isArray(valueKey) ? (valueKey[0] ?? '') : valueKey;
757
+ opts.local = true;
758
+ const localLinear = findLocalLinearPropertyDeclaration(targetRules, keyStr);
759
+ if (localLinear !== undefined) {
760
+ return localLinear;
761
+ }
762
+ const declaration = targetRules.find('declaration', `${keyStr}`, 'Declaration', opts);
763
+ if (declaration !== undefined) {
764
+ return declaration;
765
+ }
766
+ return undefined;
767
+ } else if (isNode(targetRules, N.JsObject)) {
768
+ const keyStr = isArray(valueKey) ? (valueKey[0] ?? '') : valueKey;
769
+ return (targetRules as any).value[keyStr];
770
+ }
771
+ break;
772
+ case 'mixin':
773
+ if (isNode(targetRules, N.Rules)) {
774
+ // valueKey can be string or string[] - find() accepts both
775
+ const mixin = targetRules.find('mixin', valueKey, 'Mixin', opts);
776
+ if (mixin) {
777
+ return mixin;
778
+ }
779
+ // Some Less built-ins are invoked in mixin-like call positions.
780
+ // If a mixin lookup misses during a Call, allow function fallback.
781
+ if (isNode(getLookupParentNode(this, context), N.Call)) {
782
+ const keyStr = isArray(valueKey) ? (valueKey[0] ?? '') : valueKey;
783
+ return targetRules.find('function', `${keyStr}`, undefined, opts);
784
+ }
785
+ return undefined;
786
+ }
787
+ break;
788
+ case 'ruleset':
789
+ if (isNode(targetRules, N.Rules)) {
790
+ const keyStr = isArray(valueKey) ? valueKey[0] : valueKey;
791
+ return targetRules.find('mixin', `${keyStr}`, 'Ruleset', opts);
792
+ }
793
+ break;
794
+ case 'mixin-ruleset':
795
+ if (isNode(targetRules, N.Rules)) {
796
+ const mixinOrRuleset = targetRules.find('mixin', valueKey, undefined, opts);
797
+ if (mixinOrRuleset) {
798
+ return mixinOrRuleset;
799
+ }
800
+ if (isNode(getLookupParentNode(this, context), N.Call)) {
801
+ const keyStr = isArray(valueKey) ? (valueKey[0] ?? '') : valueKey;
802
+ return targetRules.find('function', `${keyStr}`, undefined, opts);
803
+ }
804
+ return undefined;
805
+ }
806
+ break;
807
+ }
808
+ return undefined;
809
+ };
810
+ const performExplicitParentVariableLookup = (): Declaration | undefined => {
811
+ if (type !== 'variable' || target) {
812
+ return undefined;
813
+ }
814
+ const keyStr = isArray(valueKey) ? valueKey[0] : valueKey;
815
+ const seenRules = new Set<Rules>();
816
+ let current: Node | undefined = this;
817
+ while (current) {
818
+ current = getLookupParentNode(current, context);
819
+ if (!current) {
820
+ break;
821
+ }
822
+ if (!isNode(current, N.Rules)) {
823
+ continue;
824
+ }
825
+ const rules = current as Rules;
826
+ if (seenRules.has(rules)) {
827
+ continue;
828
+ }
829
+ seenRules.add(rules);
830
+ const found = rules.find('declaration', `${keyStr}`, 'VarDeclaration', {
831
+ filter,
832
+ context,
833
+ hasTarget,
834
+ searchParents: false
835
+ });
836
+ if (found !== undefined) {
837
+ return found as Declaration;
838
+ }
839
+ }
840
+ return undefined;
841
+ };
842
+
843
+ // Lookup is driven by the resolved target scope.
844
+ // In mixin/at-rule nesting cases, `this.rulesParent` can point at a narrower scope (e.g. the
845
+ // nested @media Rules) while the variable lives on an ancestor Rules (e.g. mixin param wrapper).
846
+ const lookupTarget = isNode(resolvedTarget, N.Ruleset)
847
+ ? (resolvedTarget as Ruleset).enterRules(context)
848
+ : resolvedTarget;
849
+ let returnVal: any;
850
+ if (isNode(lookupTarget, N.Rules)) {
851
+ returnVal = performLookup(lookupTarget);
852
+
853
+ if (
854
+ returnVal === undefined
855
+ && !target
856
+ && type === 'variable'
857
+ ) {
858
+ returnVal = performExplicitParentVariableLookup();
859
+ }
860
+
861
+ if (
862
+ returnVal === undefined
863
+ && context.lookupScope
864
+ && context.lookupScope !== lookupTarget
865
+ ) {
866
+ returnVal = performLookup(context.lookupScope);
867
+ }
868
+
869
+ if (
870
+ returnVal === undefined
871
+ && !target
872
+ && type === 'variable'
873
+ && context.callStack.length > 0
874
+ && lookupSourceRulesParent
875
+ && lookupSourceRulesParent !== lookupTarget
876
+ && lookupSourceRulesParent !== context.lookupScope
877
+ ) {
878
+ returnVal = performLookup(lookupSourceRulesParent);
879
+ }
880
+
881
+ if (
882
+ returnVal === undefined
883
+ && !target
884
+ && type === 'variable'
885
+ && context.callStack.length > 0
886
+ && lookupCallerRulesParent
887
+ && lookupCallerRulesParent !== lookupTarget
888
+ && lookupCallerRulesParent !== context.lookupScope
889
+ ) {
890
+ returnVal = performLookup(lookupCallerRulesParent);
891
+ }
892
+
893
+ if (
894
+ returnVal === undefined
895
+ && !target
896
+ && type === 'variable'
897
+ && context.callStack.length > 0
898
+ && activeSourceRulesParent
899
+ && activeSourceRulesParent !== lookupTarget
900
+ ) {
901
+ returnVal = performLookup(activeSourceRulesParent);
902
+ }
903
+
904
+ if (
905
+ returnVal === undefined
906
+ && !target
907
+ && type === 'variable'
908
+ && context.callStack.length > 0
909
+ && activeCallerRulesParent
910
+ && activeCallerRulesParent !== lookupTarget
911
+ ) {
912
+ returnVal = performLookup(activeCallerRulesParent);
913
+ }
914
+
915
+ // If leakyRules is true, try caller scope as a secondary pass (historical behavior).
916
+ if (returnVal === undefined && context.leakyRules) {
917
+ returnVal = performLookup(activeRulesParent);
918
+ if (returnVal === undefined) {
919
+ returnVal = performLookup(activeSourceRulesParent);
920
+ }
921
+ if (returnVal === undefined) {
922
+ returnVal = performLookup(activeCallerRulesParent);
923
+ }
924
+ }
925
+ }
926
+ return { returnVal, valueKey };
927
+ },
928
+ ({ returnVal, valueKey }) => {
929
+ const valueKeyStr2 = isArray(valueKey) ? valueKey.join('') : String(valueKey);
930
+ if (returnVal === undefined) {
931
+ if (!fallbackValue) {
932
+ if (
933
+ (type === 'mixin' || type === 'mixin-ruleset')
934
+ && isInsideSelectorCapture(this, context)
935
+ ) {
936
+ return new Any(valueKeyStr2, { role: 'ident' });
937
+ }
938
+ switch (type) {
939
+ case 'mixin':
940
+ throw new ReferenceError(`No matching mixins found for '${valueKeyStr2}'`);
941
+ case 'ruleset':
942
+ throw new ReferenceError(`No matching rulesets found for '${valueKeyStr2}'`);
943
+ case 'mixin-ruleset':
944
+ throw new ReferenceError(`No matching mixins found for '${valueKeyStr2}'`);
945
+ }
946
+ throw new ReferenceError(`'${valueKeyStr2}' is not defined`);
947
+ }
948
+ if (fallbackValue === true) {
949
+ const any = new Any(`${valueKey}`, { role: this.options.role });
950
+ return any;
951
+ }
952
+ // Evaluate the fallbackValue if it's a Node
953
+ let out = fallbackValue.eval(context);
954
+ if (isThenable(out)) {
955
+ return (out as Promise<Node>).then(node => node);
956
+ }
957
+ return out;
958
+ }
959
+ if (isNode(returnVal, N.Declaration | N.VarDeclaration)) {
960
+ context.addToSearchScope(returnVal as Node);
961
+ const hasImportant = isNode(returnVal, N.Declaration) && !!(returnVal as Declaration).get('important');
962
+ const scopeRenderKey = context.lookupScope?.renderKey ?? context.renderKey;
963
+ const declarationValueContext = scopeRenderKey !== undefined && context.renderKey !== scopeRenderKey
964
+ ? { ...context, renderKey: scopeRenderKey }
965
+ : context;
966
+ const declValue = (returnVal as Declaration).get('value', declarationValueContext);
967
+ const declarationParent = scopeRenderKey !== undefined
968
+ ? getCurrentParentNode(returnVal as Node, scopeRenderKey)
969
+ : getCurrentParentNode(returnVal as Node, context);
970
+ const declarationRulesScope = isNode(declarationParent, N.Rules)
971
+ ? declarationParent as Rules
972
+ : getStateRulesParent(returnVal as Node, context);
973
+ if (
974
+ declValue instanceof Node
975
+ && getSourceParent(declValue, declarationValueContext) === undefined
976
+ ) {
977
+ const declarationScopeSourceParent = declarationRulesScope
978
+ ? getSourceParent(declarationRulesScope as Node, declarationValueContext)
979
+ : undefined;
980
+ const declarationSourceParent = getSourceParent(returnVal as Node, declarationValueContext)
981
+ ?? declarationScopeSourceParent;
982
+ if (declarationSourceParent) {
983
+ setSourceParent(declValue, declarationSourceParent, declarationValueContext);
984
+ }
985
+ }
986
+ // Mixin references (e.g. @foo: .a) are not resolved at lookup time; they are
987
+ // resolved only when called (@foo();) or used as target of a lookup (@foo[prop]).
988
+ const isMixinRef = isNode(declValue, N.Reference) && declValue.options?.type === 'mixin-ruleset';
989
+ return pipe(
990
+ () => {
991
+ // Track that this value came from an important declaration
992
+ // We push here but DON'T pop - let the consuming Declaration pop it
993
+ if (hasImportant) {
994
+ context.pushImportantSource();
995
+ }
996
+ declValue.frozen = true;
997
+ if (isMixinRef) {
998
+ return declValue;
999
+ }
1000
+ const previousRulesContext = context.rulesContext;
1001
+ const previousLookupScope = context.lookupScope;
1002
+ const previousRenderKey = context.renderKey;
1003
+ if (declarationRulesScope) {
1004
+ context.rulesContext = declarationRulesScope;
1005
+ context.lookupScope = declarationRulesScope;
1006
+ context.renderKey = scopeRenderKey ?? declarationRulesScope.renderKey ?? previousRenderKey;
1007
+ }
1008
+ try {
1009
+ return declValue.eval(context);
1010
+ } finally {
1011
+ context.rulesContext = previousRulesContext;
1012
+ context.lookupScope = previousLookupScope;
1013
+ context.renderKey = previousRenderKey;
1014
+ }
1015
+ },
1016
+ (evald) => {
1017
+ context.deleteFromSearchScope(returnVal as Node);
1018
+ // DON'T pop important source here - let the consuming Declaration pop it
1019
+ // after it has checked and merged the important flag
1020
+ let out = materializeResolvedValue(evald);
1021
+ out.pre = this.pre;
1022
+ out.post = this.post;
1023
+ setSourceParent(out, sourceReference, context);
1024
+ const dependency = isTopLevelVarDeclaration(returnVal as Node, context)
1025
+ ? {
1026
+ dependsOn: new Set<VarDeclaration>([returnVal as VarDeclaration]),
1027
+ sourceExpr: this as Node
1028
+ }
1029
+ : getDependency(evald, context);
1030
+ if (dependency?.dependsOn && dependency.dependsOn.size > 0) {
1031
+ setDependency(out, {
1032
+ dependsOn: new Set(dependency.dependsOn),
1033
+ sourceExpr: dependency.sourceExpr ?? this
1034
+ }, context);
1035
+ }
1036
+ return out;
1037
+ }
1038
+ );
1039
+ } else if (isArray(returnVal)) {
1040
+ // When a mixin-ruleset reference is used as the target of another
1041
+ // Reference (e.g. #theme -> .dark -> .navbar), preserve the resolved
1042
+ // scope entry instead of eagerly converting it into a callable mixin.
1043
+ if (type === 'mixin-ruleset' && !isNode(getLookupParentNode(this, context), N.Call) && context.referenceStack > 1) {
1044
+ const first = returnVal[0] as Node | undefined;
1045
+ if (first && isNode(first, N.Mixin | N.Ruleset)) {
1046
+ anchorResolvedReferenceResult(first as Node, sourceReference, context);
1047
+ context.popReference();
1048
+ return cast(first);
1049
+ }
1050
+ context.popReference();
1051
+ return cast(undefined);
1052
+ }
1053
+
1054
+ // Only pass Mixins and Rulesets to getFunctionFromMixins
1055
+ for (let item of returnVal) {
1056
+ anchorResolvedReferenceResult(item, sourceReference, context);
1057
+ if (!isNode(item, N.Mixin | N.Ruleset)) {
1058
+ context.popReference();
1059
+ return cast(undefined);
1060
+ }
1061
+ }
1062
+ // When the parent is a Call, return the resolved candidate(s) directly
1063
+ // so Call.evalNode keeps candidate placement/renderKey and dispatches
1064
+ // through the direct mixin path instead of the legacy JsFunction
1065
+ // wrapper path.
1066
+ if (
1067
+ (type === 'mixin' || type === 'mixin-ruleset')
1068
+ && isNode(getLookupParentNode(this, context), N.Call)
1069
+ ) {
1070
+ context.popReference();
1071
+ return returnVal.length === 1
1072
+ ? returnVal[0] as Node
1073
+ : returnVal as unknown as Node;
1074
+ }
1075
+ // Multi-match, namespace, or non-Call consumer: use legacy function wrapper.
1076
+ const func = getFunctionFromMixins(returnVal as MixinEntry[]);
1077
+ context.popReference();
1078
+ return cast(func);
1079
+ }
1080
+ const result = cast(returnVal);
1081
+ // Pop reference and clear remainders if we're at the outermost level
1082
+ context.popReference();
1083
+ anchorResolvedReferenceResult(result, sourceReference, context);
1084
+ return result;
1085
+ }
1086
+ );
1087
+ if (isThenable(result)) {
1088
+ return (result as Promise<Node>).then(
1089
+ res => res,
1090
+ (err) => {
1091
+ throw err;
1092
+ }
1093
+ );
1094
+ }
1095
+ return result as Node;
1096
+ }
1097
+ }
1098
+
1099
+ export const ref = defineType(Reference, 'Reference', 'ref');