@jesscss/core 2.0.0-alpha.5 → 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.
- package/lib/index.cjs +20159 -0
- package/lib/index.d.cts +5993 -0
- package/lib/index.d.cts.map +1 -0
- package/lib/index.d.ts +5992 -21
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +19926 -22
- package/lib/index.js.map +1 -1
- package/package.json +15 -14
- package/src/__tests__/define-function-record.test.ts +58 -0
- package/src/__tests__/define-function-simple.test.ts +55 -0
- package/src/__tests__/define-function-split-sequence.test.ts +547 -0
- package/src/__tests__/define-function-type-parity.test.ts +9 -0
- package/src/__tests__/define-function.test.ts +763 -0
- package/src/__tests__/num-operations.test.ts +91 -0
- package/src/__tests__/safe-parse.test.ts +374 -0
- package/src/context.ts +896 -0
- package/src/conversions.ts +282 -0
- package/src/debug-log.ts +29 -0
- package/src/define-function.ts +1006 -0
- package/src/deprecation.ts +67 -0
- package/src/globals.d.ts +26 -0
- package/src/index.ts +31 -0
- package/src/jess-error.ts +773 -0
- package/src/logger/deprecation-processing.ts +109 -0
- package/src/logger.ts +31 -0
- package/src/plugin.ts +292 -0
- package/src/tree/LOOKUP_CHAINS.md +35 -0
- package/src/tree/README.md +18 -0
- package/src/tree/__tests__/__snapshots__/extend-eval-integration.test.ts.snap +1455 -0
- package/src/tree/__tests__/ampersand.test.ts +382 -0
- package/src/tree/__tests__/at-rule.test.ts +2047 -0
- package/src/tree/__tests__/basic-render.test.ts +212 -0
- package/src/tree/__tests__/block.test.ts +40 -0
- package/src/tree/__tests__/call.test.ts +346 -0
- package/src/tree/__tests__/color.test.ts +537 -0
- package/src/tree/__tests__/condition.test.ts +186 -0
- package/src/tree/__tests__/control.test.ts +564 -0
- package/src/tree/__tests__/declaration.test.ts +253 -0
- package/src/tree/__tests__/dependency-graph.test.ts +177 -0
- package/src/tree/__tests__/detached-rulesets.test.ts +213 -0
- package/src/tree/__tests__/dimension.test.ts +236 -0
- package/src/tree/__tests__/expression.test.ts +73 -0
- package/src/tree/__tests__/ext-node.test.ts +31 -0
- package/src/tree/__tests__/extend-eval-integration.test.ts +1033 -0
- package/src/tree/__tests__/extend-import-style.test.ts +929 -0
- package/src/tree/__tests__/extend-less-fixtures.test.ts +851 -0
- package/src/tree/__tests__/extend-list.test.ts +31 -0
- package/src/tree/__tests__/extend-roots.test.ts +1045 -0
- package/src/tree/__tests__/extend-rules.test.ts +740 -0
- package/src/tree/__tests__/func.test.ts +171 -0
- package/src/tree/__tests__/import-js.test.ts +33 -0
- package/src/tree/__tests__/import-style-test-helpers.ts +56 -0
- package/src/tree/__tests__/import-style.test.ts +1967 -0
- package/src/tree/__tests__/interpolated-reference.test.ts +44 -0
- package/src/tree/__tests__/interpolated.test.ts +41 -0
- package/src/tree/__tests__/list.test.ts +177 -0
- package/src/tree/__tests__/log.test.ts +83 -0
- package/src/tree/__tests__/mixin-recursion.test.ts +639 -0
- package/src/tree/__tests__/mixin.test.ts +2171 -0
- package/src/tree/__tests__/negative.test.ts +45 -0
- package/src/tree/__tests__/nesting-collapse.test.ts +519 -0
- package/src/tree/__tests__/node-flags-perf.test.ts +195 -0
- package/src/tree/__tests__/node-flags.test.ts +410 -0
- package/src/tree/__tests__/node-graph.test.ts +598 -0
- package/src/tree/__tests__/node-mutation.test.ts +182 -0
- package/src/tree/__tests__/operation.test.ts +18 -0
- package/src/tree/__tests__/paren.test.ts +90 -0
- package/src/tree/__tests__/preserve-mode-output.test.ts +50 -0
- package/src/tree/__tests__/quoted.test.ts +72 -0
- package/src/tree/__tests__/range.test.ts +59 -0
- package/src/tree/__tests__/reference.test.ts +743 -0
- package/src/tree/__tests__/rest.test.ts +29 -0
- package/src/tree/__tests__/rules-raw.test.ts +14 -0
- package/src/tree/__tests__/rules.test.ts +1271 -0
- package/src/tree/__tests__/ruleset.test.ts +597 -0
- package/src/tree/__tests__/selector-attr.test.ts +50 -0
- package/src/tree/__tests__/selector-basic.test.ts +44 -0
- package/src/tree/__tests__/selector-capture.test.ts +22 -0
- package/src/tree/__tests__/selector-complex.test.ts +120 -0
- package/src/tree/__tests__/selector-compound.test.ts +74 -0
- package/src/tree/__tests__/selector-interpolated.test.ts +50 -0
- package/src/tree/__tests__/selector-list.test.ts +59 -0
- package/src/tree/__tests__/selector-pseudo.test.ts +23 -0
- package/src/tree/__tests__/selector.test.ts +182 -0
- package/src/tree/__tests__/sequence.test.ts +226 -0
- package/src/tree/__tests__/serialize-types.test.ts +529 -0
- package/src/tree/__tests__/spaced.test.ts +8 -0
- package/src/tree/__tests__/url.test.ts +72 -0
- package/src/tree/__tests__/var-declaration.test.ts +90 -0
- package/src/tree/ampersand.ts +538 -0
- package/src/tree/any.ts +169 -0
- package/src/tree/at-rule.ts +760 -0
- package/src/tree/block.ts +72 -0
- package/src/tree/bool.ts +46 -0
- package/src/tree/call.ts +593 -0
- package/src/tree/collection.ts +52 -0
- package/src/tree/color.ts +629 -0
- package/src/tree/combinator.ts +30 -0
- package/src/tree/comment.ts +36 -0
- package/src/tree/condition.ts +194 -0
- package/src/tree/control.ts +452 -0
- package/src/tree/declaration-custom.ts +56 -0
- package/src/tree/declaration-var.ts +87 -0
- package/src/tree/declaration.ts +742 -0
- package/src/tree/default-guard.ts +35 -0
- package/src/tree/dimension.ts +392 -0
- package/src/tree/expression.ts +97 -0
- package/src/tree/extend-list.ts +51 -0
- package/src/tree/extend.ts +391 -0
- package/src/tree/function.ts +254 -0
- package/src/tree/import-js.ts +130 -0
- package/src/tree/import-style.ts +875 -0
- package/{lib/tree/index.js → src/tree/index.ts} +49 -22
- package/src/tree/interpolated.ts +346 -0
- package/src/tree/js-array.ts +21 -0
- package/src/tree/js-expr.ts +50 -0
- package/src/tree/js-function.ts +31 -0
- package/src/tree/js-object.ts +22 -0
- package/src/tree/list.ts +415 -0
- package/src/tree/log.ts +89 -0
- package/src/tree/mixin.ts +331 -0
- package/src/tree/negative.ts +58 -0
- package/src/tree/nil.ts +57 -0
- package/src/tree/node-base.ts +1716 -0
- package/src/tree/node-type.ts +122 -0
- package/src/tree/node.ts +118 -0
- package/src/tree/number.ts +54 -0
- package/src/tree/operation.ts +187 -0
- package/src/tree/paren.ts +132 -0
- package/src/tree/query-condition.ts +47 -0
- package/src/tree/quoted.ts +119 -0
- package/src/tree/range.ts +101 -0
- package/src/tree/reference.ts +1099 -0
- package/src/tree/rest.ts +55 -0
- package/src/tree/rules-raw.ts +52 -0
- package/src/tree/rules.ts +2896 -0
- package/src/tree/ruleset.ts +1217 -0
- package/src/tree/selector-attr.ts +172 -0
- package/src/tree/selector-basic.ts +75 -0
- package/src/tree/selector-capture.ts +85 -0
- package/src/tree/selector-complex.ts +189 -0
- package/src/tree/selector-compound.ts +205 -0
- package/src/tree/selector-interpolated.ts +95 -0
- package/src/tree/selector-list.ts +245 -0
- package/src/tree/selector-pseudo.ts +173 -0
- package/src/tree/selector-simple.ts +10 -0
- package/src/tree/selector.ts +152 -0
- package/src/tree/sequence.ts +463 -0
- package/src/tree/tree.ts +130 -0
- package/src/tree/url.ts +95 -0
- package/src/tree/util/EXTEND_ARCHITECTURE_ANALYSIS.md +215 -0
- package/src/tree/util/EXTEND_AUDIT.md +233 -0
- package/src/tree/util/EXTEND_BASELINE.md +64 -0
- package/src/tree/util/EXTEND_CALL_GRAPH_ANALYSIS.md +244 -0
- package/src/tree/util/EXTEND_DOCS.md +24 -0
- package/src/tree/util/EXTEND_FINAL_SUMMARY.md +95 -0
- package/src/tree/util/EXTEND_FUNCTION_AUDIT.md +1433 -0
- package/src/tree/util/EXTEND_OPTIMIZATION_PLAN.md +114 -0
- package/src/tree/util/EXTEND_REFACTORING_SUMMARY.md +152 -0
- package/src/tree/util/EXTEND_RULES.md +74 -0
- package/src/tree/util/EXTEND_UNUSED_FUNCTIONS.md +127 -0
- package/src/tree/util/EXTEND_UNUSED_FUNCTIONS_ANALYSIS.md +227 -0
- package/src/tree/util/NODE_COPY_REDUCTION_PLAN.md +12 -0
- package/src/tree/util/__tests__/EXTEND_TEST_INDEX.md +59 -0
- package/src/tree/util/__tests__/OPTIMIZATION-ANALYSIS.md +130 -0
- package/src/tree/util/__tests__/WALK_AND_CONSUME_DESIGN.md +138 -0
- package/src/tree/util/__tests__/_archive/2026-02-09__OPTIMIZATION-ANALYSIS.md +9 -0
- package/src/tree/util/__tests__/_archive/README.md +4 -0
- package/src/tree/util/__tests__/bitset.test.ts +142 -0
- package/src/tree/util/__tests__/debug-log.ts +50 -0
- package/src/tree/util/__tests__/extend-comment-handling.test.ts +187 -0
- package/src/tree/util/__tests__/extend-core-unit.test.ts +941 -0
- package/src/tree/util/__tests__/extend-pipeline-bench.test.ts +154 -0
- package/src/tree/util/__tests__/extend-pipeline-bench.ts +190 -0
- package/src/tree/util/__tests__/fast-reject.test.ts +377 -0
- package/src/tree/util/__tests__/is-node.test.ts +63 -0
- package/src/tree/util/__tests__/list-like.test.ts +63 -0
- package/src/tree/util/__tests__/outputwriter.test.ts +523 -0
- package/src/tree/util/__tests__/print.test.ts +183 -0
- package/src/tree/util/__tests__/process-extends.test.ts +226 -0
- package/src/tree/util/__tests__/process-leading-is.test.ts +205 -0
- package/src/tree/util/__tests__/recursion-helper.test.ts +184 -0
- package/src/tree/util/__tests__/selector-match-unit.test.ts +1427 -0
- package/src/tree/util/__tests__/sourcemap.test.ts +117 -0
- package/src/tree/util/ampersand-template.ts +9 -0
- package/src/tree/util/bitset.ts +194 -0
- package/src/tree/util/calculate.ts +11 -0
- package/src/tree/util/cast.ts +89 -0
- package/src/tree/util/cloning.ts +8 -0
- package/src/tree/util/collections.ts +299 -0
- package/src/tree/util/compare.ts +90 -0
- package/src/tree/util/cursor.ts +171 -0
- package/src/tree/util/extend-core.ts +2139 -0
- package/src/tree/util/extend-roots.ts +1108 -0
- package/src/tree/util/field-helpers.ts +354 -0
- package/src/tree/util/is-node.ts +43 -0
- package/src/tree/util/list-like.ts +93 -0
- package/src/tree/util/mixin-instance-primitives.ts +2020 -0
- package/src/tree/util/print.ts +303 -0
- package/src/tree/util/process-leading-is.ts +421 -0
- package/src/tree/util/recursion-helper.ts +54 -0
- package/src/tree/util/regex.ts +2 -0
- package/src/tree/util/registry-utils.ts +1953 -0
- package/src/tree/util/ruleset-trace.ts +17 -0
- package/src/tree/util/scoped-body-eval.ts +320 -0
- package/src/tree/util/selector-match-core.ts +2005 -0
- package/src/tree/util/selector-utils.ts +757 -0
- package/src/tree/util/serialize-helper.ts +535 -0
- package/src/tree/util/serialize-types.ts +318 -0
- package/src/tree/util/should-operate.ts +78 -0
- package/src/tree/util/sourcemap.ts +37 -0
- package/src/types/config.ts +247 -0
- package/src/types/index.ts +12 -0
- package/{lib/types/modes.d.ts → src/types/modes.ts} +2 -1
- package/src/types.d.ts +9 -0
- package/src/types.ts +68 -0
- package/src/use-webpack-resolver.ts +56 -0
- package/src/visitor/__tests__/visitor.test.ts +136 -0
- package/src/visitor/index.ts +263 -0
- package/{lib/visitor/less-visitor.js → src/visitor/less-visitor.ts} +3 -2
- package/lib/context.d.ts +0 -352
- package/lib/context.d.ts.map +0 -1
- package/lib/context.js +0 -636
- package/lib/context.js.map +0 -1
- package/lib/conversions.d.ts +0 -73
- package/lib/conversions.d.ts.map +0 -1
- package/lib/conversions.js +0 -253
- package/lib/conversions.js.map +0 -1
- package/lib/debug-log.d.ts +0 -2
- package/lib/debug-log.d.ts.map +0 -1
- package/lib/debug-log.js +0 -27
- package/lib/debug-log.js.map +0 -1
- package/lib/define-function.d.ts +0 -587
- package/lib/define-function.d.ts.map +0 -1
- package/lib/define-function.js +0 -726
- package/lib/define-function.js.map +0 -1
- package/lib/deprecation.d.ts +0 -34
- package/lib/deprecation.d.ts.map +0 -1
- package/lib/deprecation.js +0 -57
- package/lib/deprecation.js.map +0 -1
- package/lib/jess-error.d.ts +0 -343
- package/lib/jess-error.d.ts.map +0 -1
- package/lib/jess-error.js +0 -508
- package/lib/jess-error.js.map +0 -1
- package/lib/logger/deprecation-processing.d.ts +0 -41
- package/lib/logger/deprecation-processing.d.ts.map +0 -1
- package/lib/logger/deprecation-processing.js +0 -81
- package/lib/logger/deprecation-processing.js.map +0 -1
- package/lib/logger.d.ts +0 -10
- package/lib/logger.d.ts.map +0 -1
- package/lib/logger.js +0 -20
- package/lib/logger.js.map +0 -1
- package/lib/plugin.d.ts +0 -94
- package/lib/plugin.d.ts.map +0 -1
- package/lib/plugin.js +0 -174
- package/lib/plugin.js.map +0 -1
- package/lib/tree/ampersand.d.ts +0 -98
- package/lib/tree/ampersand.d.ts.map +0 -1
- package/lib/tree/ampersand.js +0 -319
- package/lib/tree/ampersand.js.map +0 -1
- package/lib/tree/any.d.ts +0 -58
- package/lib/tree/any.d.ts.map +0 -1
- package/lib/tree/any.js +0 -104
- package/lib/tree/any.js.map +0 -1
- package/lib/tree/at-rule.d.ts +0 -53
- package/lib/tree/at-rule.d.ts.map +0 -1
- package/lib/tree/at-rule.js +0 -503
- package/lib/tree/at-rule.js.map +0 -1
- package/lib/tree/block.d.ts +0 -22
- package/lib/tree/block.d.ts.map +0 -1
- package/lib/tree/block.js +0 -24
- package/lib/tree/block.js.map +0 -1
- package/lib/tree/bool.d.ts +0 -18
- package/lib/tree/bool.d.ts.map +0 -1
- package/lib/tree/bool.js +0 -28
- package/lib/tree/bool.js.map +0 -1
- package/lib/tree/call.d.ts +0 -66
- package/lib/tree/call.d.ts.map +0 -1
- package/lib/tree/call.js +0 -306
- package/lib/tree/call.js.map +0 -1
- package/lib/tree/collection.d.ts +0 -30
- package/lib/tree/collection.d.ts.map +0 -1
- package/lib/tree/collection.js +0 -37
- package/lib/tree/collection.js.map +0 -1
- package/lib/tree/color.d.ts +0 -101
- package/lib/tree/color.d.ts.map +0 -1
- package/lib/tree/color.js +0 -513
- package/lib/tree/color.js.map +0 -1
- package/lib/tree/combinator.d.ts +0 -13
- package/lib/tree/combinator.d.ts.map +0 -1
- package/lib/tree/combinator.js +0 -12
- package/lib/tree/combinator.js.map +0 -1
- package/lib/tree/comment.d.ts +0 -20
- package/lib/tree/comment.d.ts.map +0 -1
- package/lib/tree/comment.js +0 -19
- package/lib/tree/comment.js.map +0 -1
- package/lib/tree/condition.d.ts +0 -31
- package/lib/tree/condition.d.ts.map +0 -1
- package/lib/tree/condition.js +0 -103
- package/lib/tree/condition.js.map +0 -1
- package/lib/tree/control.d.ts +0 -104
- package/lib/tree/control.d.ts.map +0 -1
- package/lib/tree/control.js +0 -430
- package/lib/tree/control.js.map +0 -1
- package/lib/tree/declaration-custom.d.ts +0 -18
- package/lib/tree/declaration-custom.d.ts.map +0 -1
- package/lib/tree/declaration-custom.js +0 -24
- package/lib/tree/declaration-custom.js.map +0 -1
- package/lib/tree/declaration-var.d.ts +0 -35
- package/lib/tree/declaration-var.d.ts.map +0 -1
- package/lib/tree/declaration-var.js +0 -63
- package/lib/tree/declaration-var.js.map +0 -1
- package/lib/tree/declaration.d.ts +0 -78
- package/lib/tree/declaration.d.ts.map +0 -1
- package/lib/tree/declaration.js +0 -286
- package/lib/tree/declaration.js.map +0 -1
- package/lib/tree/default-guard.d.ts +0 -15
- package/lib/tree/default-guard.d.ts.map +0 -1
- package/lib/tree/default-guard.js +0 -19
- package/lib/tree/default-guard.js.map +0 -1
- package/lib/tree/dimension.d.ts +0 -34
- package/lib/tree/dimension.d.ts.map +0 -1
- package/lib/tree/dimension.js +0 -294
- package/lib/tree/dimension.js.map +0 -1
- package/lib/tree/expression.d.ts +0 -25
- package/lib/tree/expression.d.ts.map +0 -1
- package/lib/tree/expression.js +0 -32
- package/lib/tree/expression.js.map +0 -1
- package/lib/tree/extend-list.d.ts +0 -23
- package/lib/tree/extend-list.d.ts.map +0 -1
- package/lib/tree/extend-list.js +0 -23
- package/lib/tree/extend-list.js.map +0 -1
- package/lib/tree/extend.d.ts +0 -47
- package/lib/tree/extend.d.ts.map +0 -1
- package/lib/tree/extend.js +0 -296
- package/lib/tree/extend.js.map +0 -1
- package/lib/tree/function.d.ts +0 -48
- package/lib/tree/function.d.ts.map +0 -1
- package/lib/tree/function.js +0 -74
- package/lib/tree/function.js.map +0 -1
- package/lib/tree/import-js.d.ts +0 -35
- package/lib/tree/import-js.d.ts.map +0 -1
- package/lib/tree/import-js.js +0 -45
- package/lib/tree/import-js.js.map +0 -1
- package/lib/tree/import-style.d.ts +0 -156
- package/lib/tree/import-style.d.ts.map +0 -1
- package/lib/tree/import-style.js +0 -566
- package/lib/tree/import-style.js.map +0 -1
- package/lib/tree/index.d.ts +0 -71
- package/lib/tree/index.d.ts.map +0 -1
- package/lib/tree/index.js.map +0 -1
- package/lib/tree/interpolated-reference.d.ts +0 -24
- package/lib/tree/interpolated-reference.d.ts.map +0 -1
- package/lib/tree/interpolated-reference.js +0 -37
- package/lib/tree/interpolated-reference.js.map +0 -1
- package/lib/tree/interpolated.d.ts +0 -62
- package/lib/tree/interpolated.d.ts.map +0 -1
- package/lib/tree/interpolated.js +0 -204
- package/lib/tree/interpolated.js.map +0 -1
- package/lib/tree/js-array.d.ts +0 -10
- package/lib/tree/js-array.d.ts.map +0 -1
- package/lib/tree/js-array.js +0 -10
- package/lib/tree/js-array.js.map +0 -1
- package/lib/tree/js-expr.d.ts +0 -23
- package/lib/tree/js-expr.d.ts.map +0 -1
- package/lib/tree/js-expr.js +0 -28
- package/lib/tree/js-expr.js.map +0 -1
- package/lib/tree/js-function.d.ts +0 -20
- package/lib/tree/js-function.d.ts.map +0 -1
- package/lib/tree/js-function.js +0 -16
- package/lib/tree/js-function.js.map +0 -1
- package/lib/tree/js-object.d.ts +0 -10
- package/lib/tree/js-object.d.ts.map +0 -1
- package/lib/tree/js-object.js +0 -10
- package/lib/tree/js-object.js.map +0 -1
- package/lib/tree/list.d.ts +0 -38
- package/lib/tree/list.d.ts.map +0 -1
- package/lib/tree/list.js +0 -83
- package/lib/tree/list.js.map +0 -1
- package/lib/tree/log.d.ts +0 -29
- package/lib/tree/log.d.ts.map +0 -1
- package/lib/tree/log.js +0 -56
- package/lib/tree/log.js.map +0 -1
- package/lib/tree/mixin.d.ts +0 -87
- package/lib/tree/mixin.d.ts.map +0 -1
- package/lib/tree/mixin.js +0 -112
- package/lib/tree/mixin.js.map +0 -1
- package/lib/tree/negative.d.ts +0 -17
- package/lib/tree/negative.d.ts.map +0 -1
- package/lib/tree/negative.js +0 -22
- package/lib/tree/negative.js.map +0 -1
- package/lib/tree/nil.d.ts +0 -30
- package/lib/tree/nil.d.ts.map +0 -1
- package/lib/tree/nil.js +0 -35
- package/lib/tree/nil.js.map +0 -1
- package/lib/tree/node-base.d.ts +0 -361
- package/lib/tree/node-base.d.ts.map +0 -1
- package/lib/tree/node-base.js +0 -930
- package/lib/tree/node-base.js.map +0 -1
- package/lib/tree/node.d.ts +0 -10
- package/lib/tree/node.d.ts.map +0 -1
- package/lib/tree/node.js +0 -45
- package/lib/tree/node.js.map +0 -1
- package/lib/tree/number.d.ts +0 -21
- package/lib/tree/number.d.ts.map +0 -1
- package/lib/tree/number.js +0 -27
- package/lib/tree/number.js.map +0 -1
- package/lib/tree/operation.d.ts +0 -26
- package/lib/tree/operation.d.ts.map +0 -1
- package/lib/tree/operation.js +0 -103
- package/lib/tree/operation.js.map +0 -1
- package/lib/tree/paren.d.ts +0 -19
- package/lib/tree/paren.d.ts.map +0 -1
- package/lib/tree/paren.js +0 -92
- package/lib/tree/paren.js.map +0 -1
- package/lib/tree/query-condition.d.ts +0 -17
- package/lib/tree/query-condition.d.ts.map +0 -1
- package/lib/tree/query-condition.js +0 -39
- package/lib/tree/query-condition.js.map +0 -1
- package/lib/tree/quoted.d.ts +0 -28
- package/lib/tree/quoted.d.ts.map +0 -1
- package/lib/tree/quoted.js +0 -75
- package/lib/tree/quoted.js.map +0 -1
- package/lib/tree/range.d.ts +0 -33
- package/lib/tree/range.d.ts.map +0 -1
- package/lib/tree/range.js +0 -47
- package/lib/tree/range.js.map +0 -1
- package/lib/tree/reference.d.ts +0 -76
- package/lib/tree/reference.d.ts.map +0 -1
- package/lib/tree/reference.js +0 -521
- package/lib/tree/reference.js.map +0 -1
- package/lib/tree/rest.d.ts +0 -15
- package/lib/tree/rest.d.ts.map +0 -1
- package/lib/tree/rest.js +0 -32
- package/lib/tree/rest.js.map +0 -1
- package/lib/tree/rules-raw.d.ts +0 -17
- package/lib/tree/rules-raw.d.ts.map +0 -1
- package/lib/tree/rules-raw.js +0 -37
- package/lib/tree/rules-raw.js.map +0 -1
- package/lib/tree/rules.d.ts +0 -262
- package/lib/tree/rules.d.ts.map +0 -1
- package/lib/tree/rules.js +0 -2359
- package/lib/tree/rules.js.map +0 -1
- package/lib/tree/ruleset.d.ts +0 -92
- package/lib/tree/ruleset.d.ts.map +0 -1
- package/lib/tree/ruleset.js +0 -528
- package/lib/tree/ruleset.js.map +0 -1
- package/lib/tree/selector-attr.d.ts +0 -31
- package/lib/tree/selector-attr.d.ts.map +0 -1
- package/lib/tree/selector-attr.js +0 -99
- package/lib/tree/selector-attr.js.map +0 -1
- package/lib/tree/selector-basic.d.ts +0 -24
- package/lib/tree/selector-basic.d.ts.map +0 -1
- package/lib/tree/selector-basic.js +0 -38
- package/lib/tree/selector-basic.js.map +0 -1
- package/lib/tree/selector-capture.d.ts +0 -23
- package/lib/tree/selector-capture.d.ts.map +0 -1
- package/lib/tree/selector-capture.js +0 -34
- package/lib/tree/selector-capture.js.map +0 -1
- package/lib/tree/selector-complex.d.ts +0 -40
- package/lib/tree/selector-complex.d.ts.map +0 -1
- package/lib/tree/selector-complex.js +0 -143
- package/lib/tree/selector-complex.js.map +0 -1
- package/lib/tree/selector-compound.d.ts +0 -16
- package/lib/tree/selector-compound.d.ts.map +0 -1
- package/lib/tree/selector-compound.js +0 -114
- package/lib/tree/selector-compound.js.map +0 -1
- package/lib/tree/selector-interpolated.d.ts +0 -23
- package/lib/tree/selector-interpolated.d.ts.map +0 -1
- package/lib/tree/selector-interpolated.js +0 -27
- package/lib/tree/selector-interpolated.js.map +0 -1
- package/lib/tree/selector-list.d.ts +0 -17
- package/lib/tree/selector-list.d.ts.map +0 -1
- package/lib/tree/selector-list.js +0 -174
- package/lib/tree/selector-list.js.map +0 -1
- package/lib/tree/selector-pseudo.d.ts +0 -42
- package/lib/tree/selector-pseudo.d.ts.map +0 -1
- package/lib/tree/selector-pseudo.js +0 -204
- package/lib/tree/selector-pseudo.js.map +0 -1
- package/lib/tree/selector-simple.d.ts +0 -5
- package/lib/tree/selector-simple.d.ts.map +0 -1
- package/lib/tree/selector-simple.js +0 -6
- package/lib/tree/selector-simple.js.map +0 -1
- package/lib/tree/selector.d.ts +0 -43
- package/lib/tree/selector.d.ts.map +0 -1
- package/lib/tree/selector.js +0 -56
- package/lib/tree/selector.js.map +0 -1
- package/lib/tree/sequence.d.ts +0 -43
- package/lib/tree/sequence.d.ts.map +0 -1
- package/lib/tree/sequence.js +0 -151
- package/lib/tree/sequence.js.map +0 -1
- package/lib/tree/tree.d.ts +0 -87
- package/lib/tree/tree.d.ts.map +0 -1
- package/lib/tree/tree.js +0 -2
- package/lib/tree/tree.js.map +0 -1
- package/lib/tree/url.d.ts +0 -18
- package/lib/tree/url.d.ts.map +0 -1
- package/lib/tree/url.js +0 -35
- package/lib/tree/url.js.map +0 -1
- package/lib/tree/util/__tests__/debug-log.d.ts +0 -1
- package/lib/tree/util/__tests__/debug-log.d.ts.map +0 -1
- package/lib/tree/util/__tests__/debug-log.js +0 -36
- package/lib/tree/util/__tests__/debug-log.js.map +0 -1
- package/lib/tree/util/calculate.d.ts +0 -3
- package/lib/tree/util/calculate.d.ts.map +0 -1
- package/lib/tree/util/calculate.js +0 -10
- package/lib/tree/util/calculate.js.map +0 -1
- package/lib/tree/util/cast.d.ts +0 -10
- package/lib/tree/util/cast.d.ts.map +0 -1
- package/lib/tree/util/cast.js +0 -87
- package/lib/tree/util/cast.js.map +0 -1
- package/lib/tree/util/cloning.d.ts +0 -4
- package/lib/tree/util/cloning.d.ts.map +0 -1
- package/lib/tree/util/cloning.js +0 -8
- package/lib/tree/util/cloning.js.map +0 -1
- package/lib/tree/util/collections.d.ts +0 -57
- package/lib/tree/util/collections.d.ts.map +0 -1
- package/lib/tree/util/collections.js +0 -136
- package/lib/tree/util/collections.js.map +0 -1
- package/lib/tree/util/compare.d.ts +0 -11
- package/lib/tree/util/compare.d.ts.map +0 -1
- package/lib/tree/util/compare.js +0 -89
- package/lib/tree/util/compare.js.map +0 -1
- package/lib/tree/util/extend-helpers.d.ts +0 -2
- package/lib/tree/util/extend-helpers.d.ts.map +0 -1
- package/lib/tree/util/extend-helpers.js +0 -2
- package/lib/tree/util/extend-helpers.js.map +0 -1
- package/lib/tree/util/extend-roots.d.ts +0 -37
- package/lib/tree/util/extend-roots.d.ts.map +0 -1
- package/lib/tree/util/extend-roots.js +0 -700
- package/lib/tree/util/extend-roots.js.map +0 -1
- package/lib/tree/util/extend-roots.old.d.ts +0 -132
- package/lib/tree/util/extend-roots.old.d.ts.map +0 -1
- package/lib/tree/util/extend-roots.old.js +0 -2272
- package/lib/tree/util/extend-roots.old.js.map +0 -1
- package/lib/tree/util/extend-trace-debug.d.ts +0 -13
- package/lib/tree/util/extend-trace-debug.d.ts.map +0 -1
- package/lib/tree/util/extend-trace-debug.js +0 -34
- package/lib/tree/util/extend-trace-debug.js.map +0 -1
- package/lib/tree/util/extend-walk.d.ts +0 -53
- package/lib/tree/util/extend-walk.d.ts.map +0 -1
- package/lib/tree/util/extend-walk.js +0 -881
- package/lib/tree/util/extend-walk.js.map +0 -1
- package/lib/tree/util/extend.d.ts +0 -218
- package/lib/tree/util/extend.d.ts.map +0 -1
- package/lib/tree/util/extend.js +0 -3182
- package/lib/tree/util/extend.js.map +0 -1
- package/lib/tree/util/find-extendable-locations.d.ts +0 -2
- package/lib/tree/util/find-extendable-locations.d.ts.map +0 -1
- package/lib/tree/util/find-extendable-locations.js +0 -2
- package/lib/tree/util/find-extendable-locations.js.map +0 -1
- package/lib/tree/util/format.d.ts +0 -20
- package/lib/tree/util/format.d.ts.map +0 -1
- package/lib/tree/util/format.js +0 -67
- package/lib/tree/util/format.js.map +0 -1
- package/lib/tree/util/is-node.d.ts +0 -13
- package/lib/tree/util/is-node.d.ts.map +0 -1
- package/lib/tree/util/is-node.js +0 -43
- package/lib/tree/util/is-node.js.map +0 -1
- package/lib/tree/util/print.d.ts +0 -80
- package/lib/tree/util/print.d.ts.map +0 -1
- package/lib/tree/util/print.js +0 -205
- package/lib/tree/util/print.js.map +0 -1
- package/lib/tree/util/process-leading-is.d.ts +0 -25
- package/lib/tree/util/process-leading-is.d.ts.map +0 -1
- package/lib/tree/util/process-leading-is.js +0 -364
- package/lib/tree/util/process-leading-is.js.map +0 -1
- package/lib/tree/util/recursion-helper.d.ts +0 -15
- package/lib/tree/util/recursion-helper.d.ts.map +0 -1
- package/lib/tree/util/recursion-helper.js +0 -43
- package/lib/tree/util/recursion-helper.js.map +0 -1
- package/lib/tree/util/regex.d.ts +0 -4
- package/lib/tree/util/regex.d.ts.map +0 -1
- package/lib/tree/util/regex.js +0 -4
- package/lib/tree/util/regex.js.map +0 -1
- package/lib/tree/util/registry-utils.d.ts +0 -192
- package/lib/tree/util/registry-utils.d.ts.map +0 -1
- package/lib/tree/util/registry-utils.js +0 -1214
- package/lib/tree/util/registry-utils.js.map +0 -1
- package/lib/tree/util/ruleset-trace.d.ts +0 -4
- package/lib/tree/util/ruleset-trace.d.ts.map +0 -1
- package/lib/tree/util/ruleset-trace.js +0 -14
- package/lib/tree/util/ruleset-trace.js.map +0 -1
- package/lib/tree/util/selector-compare.d.ts +0 -2
- package/lib/tree/util/selector-compare.d.ts.map +0 -1
- package/lib/tree/util/selector-compare.js +0 -2
- package/lib/tree/util/selector-compare.js.map +0 -1
- package/lib/tree/util/selector-match-core.d.ts +0 -184
- package/lib/tree/util/selector-match-core.d.ts.map +0 -1
- package/lib/tree/util/selector-match-core.js +0 -1603
- package/lib/tree/util/selector-match-core.js.map +0 -1
- package/lib/tree/util/selector-utils.d.ts +0 -30
- package/lib/tree/util/selector-utils.d.ts.map +0 -1
- package/lib/tree/util/selector-utils.js +0 -100
- package/lib/tree/util/selector-utils.js.map +0 -1
- package/lib/tree/util/serialize-helper.d.ts +0 -13
- package/lib/tree/util/serialize-helper.d.ts.map +0 -1
- package/lib/tree/util/serialize-helper.js +0 -387
- package/lib/tree/util/serialize-helper.js.map +0 -1
- package/lib/tree/util/serialize-types.d.ts +0 -9
- package/lib/tree/util/serialize-types.d.ts.map +0 -1
- package/lib/tree/util/serialize-types.js +0 -216
- package/lib/tree/util/serialize-types.js.map +0 -1
- package/lib/tree/util/should-operate.d.ts +0 -23
- package/lib/tree/util/should-operate.d.ts.map +0 -1
- package/lib/tree/util/should-operate.js +0 -46
- package/lib/tree/util/should-operate.js.map +0 -1
- package/lib/tree/util/sourcemap.d.ts +0 -7
- package/lib/tree/util/sourcemap.d.ts.map +0 -1
- package/lib/tree/util/sourcemap.js +0 -25
- package/lib/tree/util/sourcemap.js.map +0 -1
- package/lib/types/config.d.ts +0 -205
- package/lib/types/config.d.ts.map +0 -1
- package/lib/types/config.js +0 -2
- package/lib/types/config.js.map +0 -1
- package/lib/types/index.d.ts +0 -15
- package/lib/types/index.d.ts.map +0 -1
- package/lib/types/index.js +0 -3
- package/lib/types/index.js.map +0 -1
- package/lib/types/modes.d.ts.map +0 -1
- package/lib/types/modes.js +0 -2
- package/lib/types/modes.js.map +0 -1
- package/lib/types.d.ts +0 -61
- package/lib/types.d.ts.map +0 -1
- package/lib/types.js +0 -2
- package/lib/types.js.map +0 -1
- package/lib/use-webpack-resolver.d.ts +0 -9
- package/lib/use-webpack-resolver.d.ts.map +0 -1
- package/lib/use-webpack-resolver.js +0 -41
- package/lib/use-webpack-resolver.js.map +0 -1
- package/lib/visitor/index.d.ts +0 -136
- package/lib/visitor/index.d.ts.map +0 -1
- package/lib/visitor/index.js +0 -135
- package/lib/visitor/index.js.map +0 -1
- package/lib/visitor/less-visitor.d.ts +0 -7
- package/lib/visitor/less-visitor.d.ts.map +0 -1
- 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');
|