@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,1433 @@
|
|
|
1
|
+
# Extend Function Audit - Comprehensive Analysis
|
|
2
|
+
|
|
3
|
+
## Analysis Date
|
|
4
|
+
2025-01-XX
|
|
5
|
+
|
|
6
|
+
## Purpose
|
|
7
|
+
Deep analysis of all functions in `extend.ts` and `find-extendable-locations.ts` to:
|
|
8
|
+
1. Document each function's concerns and responsibilities
|
|
9
|
+
2. Identify overlapping concerns and duplicate code
|
|
10
|
+
3. Find opportunities to reduce passes and consolidate operations
|
|
11
|
+
4. Identify potential bug locations (especially `.foo.foo` partial match bug)
|
|
12
|
+
5. Identify unused functions through call graph analysis
|
|
13
|
+
6. Create recommendations for code improvements
|
|
14
|
+
|
|
15
|
+
## Unused Functions Identified and Removed
|
|
16
|
+
|
|
17
|
+
The following functions were identified as unused through call graph analysis and have been removed:
|
|
18
|
+
|
|
19
|
+
1. **`handleCompoundFullExtend`** - Never called, logic handled inline in `extendSelector`
|
|
20
|
+
2. **`createValidatedIsWrapper`** - Never called, only `createValidatedIsWrapperWithErrors` is used
|
|
21
|
+
3. **`createValidatedCompoundSelector`** - Never called, only `createValidatedCompoundSelectorWithErrors` is used
|
|
22
|
+
4. **`isValidCompoundSelector`** - Never called, `validateCompoundSelector` has its own implementation
|
|
23
|
+
5. **`getIsSelectorArg`** - Only called from unused `handleCompoundFullExtend`
|
|
24
|
+
6. **`extendWithinIsArg`** - Only called from unused `handleCompoundFullExtend`
|
|
25
|
+
|
|
26
|
+
**Total removed**: ~162 lines of unused code
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## File: extend.ts
|
|
31
|
+
|
|
32
|
+
### Core Entry Points
|
|
33
|
+
|
|
34
|
+
#### `tryExtendSelector` (lines 694-711)
|
|
35
|
+
**Responsibilities:**
|
|
36
|
+
- Error handling wrapper around `extendSelector`
|
|
37
|
+
- Returns `ExtendResult` with optional error instead of throwing
|
|
38
|
+
- Catches `ExtendError` and wraps in result
|
|
39
|
+
|
|
40
|
+
**Calls:**
|
|
41
|
+
- `extendSelector()` - main extend logic
|
|
42
|
+
- `createSuccessResult()` - helper
|
|
43
|
+
- `createErrorResult()` - helper
|
|
44
|
+
|
|
45
|
+
**Concerns:**
|
|
46
|
+
- Finding: ❌ No
|
|
47
|
+
- Searching: ❌ No
|
|
48
|
+
- Extending: ✅ Yes (delegates)
|
|
49
|
+
- Normalizing: ❌ No
|
|
50
|
+
- Selector Type: All types
|
|
51
|
+
|
|
52
|
+
**Notes:** Pure wrapper function, no logic duplication.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
#### `extendSelector` (lines 725-1151)
|
|
57
|
+
**Responsibilities:**
|
|
58
|
+
- Main extend orchestration function
|
|
59
|
+
- Handles both partial and full matching modes
|
|
60
|
+
- Routes to specialized handlers based on context
|
|
61
|
+
- Manages SelectorList targets (iterates and extends each)
|
|
62
|
+
- Handles ampersand boundary crossing
|
|
63
|
+
- Rejects partial matches in full mode
|
|
64
|
+
- Detects boundary-crossing matches in compound selectors
|
|
65
|
+
- Routes to `handlePartialModeExtension` or `handleFullExtend`
|
|
66
|
+
|
|
67
|
+
**Calls:**
|
|
68
|
+
- `findExtendableLocations()` - search for matches
|
|
69
|
+
- `checkAmpersandCrossingDuringExtension()` - ampersand boundary check
|
|
70
|
+
- `handleAmpersandBoundaryCrossing()` - ampersand handling
|
|
71
|
+
- `detectAndHandleBoundaryCrossing()` - compound boundary crossing
|
|
72
|
+
- `handlePartialModeExtension()` - partial mode logic
|
|
73
|
+
- `handleFullExtend()` - full mode logic
|
|
74
|
+
- `applyExtensionAtLocation()` - apply extension
|
|
75
|
+
- `createExtendedSelectorList()` - create result
|
|
76
|
+
|
|
77
|
+
**Concerns:**
|
|
78
|
+
- Finding: ✅ Yes (delegates to findExtendableLocations)
|
|
79
|
+
- Searching: ✅ Yes (delegates)
|
|
80
|
+
- Extending: ✅ Yes (orchestrates)
|
|
81
|
+
- Normalizing: ❌ No (delegates to createExtendedSelectorList)
|
|
82
|
+
- Selector Type: All types
|
|
83
|
+
|
|
84
|
+
**Potential Issues:**
|
|
85
|
+
- **`.foo.foo` BUG LOCATION**: When processing SelectorList targets (lines 770-827), it only processes the first match per selector. If `.foo.foo` has two `.foo` matches, only the first one gets extended.
|
|
86
|
+
- **Multiple passes**: Calls `findExtendableLocations` once, then potentially calls `extendSelector` recursively for each selector in a SelectorList
|
|
87
|
+
- **Location selection logic** (lines 833-903): Complex logic to pick the "best" location from multiple matches - may miss some matches
|
|
88
|
+
|
|
89
|
+
**Notes:** This is the main orchestrator. Very complex with many responsibilities. Could benefit from splitting into smaller functions.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
### Normalization Functions
|
|
94
|
+
|
|
95
|
+
#### `deduplicateSelectors` (lines 182-195)
|
|
96
|
+
**Responsibilities:**
|
|
97
|
+
- Removes duplicate selectors from array using `valueOf()` comparison
|
|
98
|
+
- Uses Set for O(n) deduplication
|
|
99
|
+
|
|
100
|
+
**Calls:**
|
|
101
|
+
- None (pure function)
|
|
102
|
+
|
|
103
|
+
**Concerns:**
|
|
104
|
+
- Finding: ❌ No
|
|
105
|
+
- Searching: ❌ No
|
|
106
|
+
- Extending: ❌ No
|
|
107
|
+
- Normalizing: ✅ Yes (deduplication)
|
|
108
|
+
- Selector Type: All types
|
|
109
|
+
|
|
110
|
+
**Notes:** Simple utility, no issues. Used in multiple places.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
#### `createProcessedSelector` (lines 203-283)
|
|
115
|
+
**Responsibilities:**
|
|
116
|
+
- Single-pass normalization combining:
|
|
117
|
+
1. Flattening generated `:is()` wrappers
|
|
118
|
+
2. Deduplicating selectors
|
|
119
|
+
3. Resolving/discarding ampersands
|
|
120
|
+
- Recursively processes nested structures
|
|
121
|
+
- Handles PseudoSelector, SelectorList, CompoundSelector, ComplexSelector, Ampersand
|
|
122
|
+
|
|
123
|
+
**Calls:**
|
|
124
|
+
- `createProcessedSelector()` - recursive calls
|
|
125
|
+
- `SelectorList.create()` - create selector lists
|
|
126
|
+
- `CompoundSelector.create()` - create compounds
|
|
127
|
+
- `ComplexSelector.create()` - create complex selectors
|
|
128
|
+
|
|
129
|
+
**Concerns:**
|
|
130
|
+
- Finding: ❌ No
|
|
131
|
+
- Searching: ❌ No
|
|
132
|
+
- Extending: ❌ No
|
|
133
|
+
- Normalizing: ✅ Yes (comprehensive normalization)
|
|
134
|
+
- Selector Type: All types
|
|
135
|
+
|
|
136
|
+
**Notes:** This was recently consolidated from multiple separate passes. Good consolidation. However, it still makes recursive passes through the tree structure.
|
|
137
|
+
|
|
138
|
+
**Potential Issues:**
|
|
139
|
+
- Creates copies at line 219 (`el = el.copy()`) - may create multiple copies of the same node if called multiple times
|
|
140
|
+
- Recursive structure means multiple passes through nested selectors
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
#### `createExtendedSelectorList` (lines 293-296)
|
|
145
|
+
**Responsibilities:**
|
|
146
|
+
- Creates SelectorList with normalization applied
|
|
147
|
+
- Applies deduplication and flattening via `createProcessedSelector`
|
|
148
|
+
- Handles inheritance
|
|
149
|
+
|
|
150
|
+
**Calls:**
|
|
151
|
+
- `createProcessedSelector()` - normalization
|
|
152
|
+
- `SelectorList.create()` - create list
|
|
153
|
+
- `inherit()` - inheritance
|
|
154
|
+
|
|
155
|
+
**Concerns:**
|
|
156
|
+
- Finding: ❌ No
|
|
157
|
+
- Searching: ❌ No
|
|
158
|
+
- Extending: ❌ No
|
|
159
|
+
- Normalizing: ✅ Yes (delegates)
|
|
160
|
+
- Selector Type: SelectorList
|
|
161
|
+
|
|
162
|
+
**Notes:** Thin wrapper, good abstraction.
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
### Boundary Crossing Functions
|
|
167
|
+
|
|
168
|
+
#### `detectAndHandleBoundaryCrossing` (lines 313-414)
|
|
169
|
+
**Responsibilities:**
|
|
170
|
+
- Detects when a compound selector find matches across an `:is()` boundary
|
|
171
|
+
- Example: `:is(.a, .b).c` matching `.b.c` should flatten
|
|
172
|
+
- Checks if match consumes entire target (if so, doesn't flatten)
|
|
173
|
+
- Returns flattened SelectorList or null
|
|
174
|
+
|
|
175
|
+
**Calls:**
|
|
176
|
+
- `findExtendableLocations()` - search inside `:is()` and after
|
|
177
|
+
- `createFlattenedBoundaryCrossingResult()` - create flattened result
|
|
178
|
+
|
|
179
|
+
**Concerns:**
|
|
180
|
+
- Finding: ✅ Yes (delegates)
|
|
181
|
+
- Searching: ✅ Yes (delegates)
|
|
182
|
+
- Extending: ❌ No (detection only)
|
|
183
|
+
- Normalizing: ❌ No
|
|
184
|
+
- Selector Type: CompoundSelector
|
|
185
|
+
|
|
186
|
+
**Notes:** Specialized function for boundary crossing. Good separation of concerns.
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
#### `createFlattenedBoundaryCrossingResult` (lines 426-445)
|
|
191
|
+
**Responsibilities:**
|
|
192
|
+
- Creates flattened selectors for boundary-crossing matches
|
|
193
|
+
- Combines each `:is()` alternative with components after it
|
|
194
|
+
- Adds extendWith + components after
|
|
195
|
+
|
|
196
|
+
**Calls:**
|
|
197
|
+
- `CompoundSelector.create()` - create compounds
|
|
198
|
+
- `createExtendedSelectorList()` - create result
|
|
199
|
+
|
|
200
|
+
**Concerns:**
|
|
201
|
+
- Finding: ❌ No
|
|
202
|
+
- Searching: ❌ No
|
|
203
|
+
- Extending: ❌ No (construction only)
|
|
204
|
+
- Normalizing: ❌ No (delegates to createExtendedSelectorList)
|
|
205
|
+
- Selector Type: CompoundSelector, SelectorList
|
|
206
|
+
|
|
207
|
+
**Notes:** Construction helper, no issues.
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
### Extension Application Functions
|
|
212
|
+
|
|
213
|
+
#### `handlePartialModeExtension` (lines 1156-1220)
|
|
214
|
+
**Responsibilities:**
|
|
215
|
+
- Handles extension in partial matching mode
|
|
216
|
+
- Creates `:is()` wrappers for component-level matches
|
|
217
|
+
- Handles compound selector partial matching
|
|
218
|
+
- Handles compound selector match within complex selector
|
|
219
|
+
- Handles compound selector matches within complex selectors (nested)
|
|
220
|
+
|
|
221
|
+
**Calls:**
|
|
222
|
+
- `createValidatedIsWrapperWithErrors()` - create `:is()` wrapper
|
|
223
|
+
- `createValidatedCompoundSelectorWithErrors()` - create compound
|
|
224
|
+
- `createIsWrapper()` - create wrapper
|
|
225
|
+
- `ComplexSelector.create()` - create complex
|
|
226
|
+
- `applyExtensionAtLocation()` - default case
|
|
227
|
+
|
|
228
|
+
**Concerns:**
|
|
229
|
+
- Finding: ❌ No
|
|
230
|
+
- Searching: ❌ No
|
|
231
|
+
- Extending: ✅ Yes (applies extensions)
|
|
232
|
+
- Normalizing: ❌ No
|
|
233
|
+
- Selector Type: CompoundSelector, ComplexSelector
|
|
234
|
+
|
|
235
|
+
**Potential Issues:**
|
|
236
|
+
- **`.foo.foo` BUG LOCATION**: Only handles the first match location passed in. If multiple components match (like `.foo.foo`), only the first one gets wrapped in `:is()`.
|
|
237
|
+
|
|
238
|
+
**Notes:** Handles partial mode logic. Could be clearer about handling multiple matches.
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
#### `handleFullExtend` (lines 1230-1298)
|
|
243
|
+
**Responsibilities:**
|
|
244
|
+
- Handles full match extension (when `partial: false`)
|
|
245
|
+
- Adds extension as new alternative in selector list
|
|
246
|
+
- Handles SelectorList targets (adds to list)
|
|
247
|
+
- Handles PseudoSelector with selector arguments (extends inside)
|
|
248
|
+
- Handles CompoundSelector (creates selector list)
|
|
249
|
+
- Performance optimization: mutates generated selectors in place
|
|
250
|
+
|
|
251
|
+
**Calls:**
|
|
252
|
+
- `createExtendedSelectorList()` - create result
|
|
253
|
+
- `SelectorList.create()` - create lists
|
|
254
|
+
- `PseudoSelector.create()` - create pseudo-selectors
|
|
255
|
+
|
|
256
|
+
**Concerns:**
|
|
257
|
+
- Finding: ❌ No
|
|
258
|
+
- Searching: ❌ No
|
|
259
|
+
- Extending: ✅ Yes (applies extensions)
|
|
260
|
+
- Normalizing: ❌ No (delegates)
|
|
261
|
+
- Selector Type: All types
|
|
262
|
+
|
|
263
|
+
**Notes:** Consolidates full extend logic. Good performance optimization for generated selectors.
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
#### `handleCompoundFullExtend` (lines 1308-1374)
|
|
268
|
+
**Responsibilities:**
|
|
269
|
+
- Handles full extend for compound selectors containing `:is()` or pseudo-classes
|
|
270
|
+
- Checks for boundary-crossing matches
|
|
271
|
+
- Single loop to handle both `:is()` extension and regular component matching
|
|
272
|
+
- Replaces matched components with `:is()` wrappers
|
|
273
|
+
|
|
274
|
+
**Calls:**
|
|
275
|
+
- `detectAndHandleBoundaryCrossing()` - boundary check
|
|
276
|
+
- `getIsSelectorArg()` - get `:is()` argument
|
|
277
|
+
- `findExtendableLocations()` - search
|
|
278
|
+
- `extendWithinIsArg()` - extend inside `:is()`
|
|
279
|
+
- `createIsWrapper()` - create wrapper
|
|
280
|
+
- `createValidatedCompoundSelectorWithErrors()` - create compound
|
|
281
|
+
- `createExtendedSelectorList()` - create result
|
|
282
|
+
|
|
283
|
+
**Concerns:**
|
|
284
|
+
- Finding: ✅ Yes (delegates)
|
|
285
|
+
- Searching: ✅ Yes (delegates)
|
|
286
|
+
- Extending: ✅ Yes (applies extensions)
|
|
287
|
+
- Normalizing: ❌ No
|
|
288
|
+
- Selector Type: CompoundSelector
|
|
289
|
+
|
|
290
|
+
**Potential Issues:**
|
|
291
|
+
- **`.foo.foo` BUG LOCATION**: Single loop (line 1324) processes components one at a time. If `.foo.foo` has two `.foo` components, it will only extend the first one it encounters.
|
|
292
|
+
|
|
293
|
+
**Notes:** Handles compound-specific full extend logic. Good consolidation of boundary crossing and `:is()` handling.
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
#### `applyExtensionAtLocation` (lines 1130-1136)
|
|
298
|
+
**Responsibilities:**
|
|
299
|
+
- Applies extension at a specific location within selector tree
|
|
300
|
+
- Delegates to `applyExtensionAtPath`
|
|
301
|
+
|
|
302
|
+
**Calls:**
|
|
303
|
+
- `applyExtensionAtPath()` - recursive application
|
|
304
|
+
|
|
305
|
+
**Concerns:**
|
|
306
|
+
- Finding: ❌ No
|
|
307
|
+
- Searching: ❌ No
|
|
308
|
+
- Extending: ✅ Yes (applies)
|
|
309
|
+
- Normalizing: ❌ No
|
|
310
|
+
- Selector Type: All types
|
|
311
|
+
|
|
312
|
+
**Notes:** Thin wrapper.
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
#### `applyExtensionAtPath` (lines 1141-1236)
|
|
317
|
+
**Responsibilities:**
|
|
318
|
+
- Recursively applies extension at a specific path
|
|
319
|
+
- Navigates through SelectorList, CompoundSelector, ComplexSelector, PseudoSelector
|
|
320
|
+
- Handles different extension types: replace, append, wrap
|
|
321
|
+
|
|
322
|
+
**Calls:**
|
|
323
|
+
- `applyExtension()` - actual extension logic
|
|
324
|
+
- `SelectorList.create()` - create lists
|
|
325
|
+
- `CompoundSelector.create()` - create compounds
|
|
326
|
+
- `ComplexSelector.create()` - create complex
|
|
327
|
+
- `PseudoSelector.create()` - create pseudo-selectors
|
|
328
|
+
|
|
329
|
+
**Concerns:**
|
|
330
|
+
- Finding: ❌ No
|
|
331
|
+
- Searching: ❌ No
|
|
332
|
+
- Extending: ✅ Yes (applies)
|
|
333
|
+
- Normalizing: ❌ No
|
|
334
|
+
- Selector Type: All types
|
|
335
|
+
|
|
336
|
+
**Notes:** Recursive path navigation. Handles all selector types.
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
#### `applyExtension` (lines 1241-1276)
|
|
341
|
+
**Responsibilities:**
|
|
342
|
+
- Applies the actual extension based on extension type
|
|
343
|
+
- `replace`: returns extendWith
|
|
344
|
+
- `append`: adds to SelectorList or creates new list
|
|
345
|
+
- `wrap`: creates `:is()` wrapper
|
|
346
|
+
|
|
347
|
+
**Calls:**
|
|
348
|
+
- `SelectorList.create()` - create lists
|
|
349
|
+
- `PseudoSelector.create()` - create `:is()` wrapper
|
|
350
|
+
|
|
351
|
+
**Concerns:**
|
|
352
|
+
- Finding: ❌ No
|
|
353
|
+
- Searching: ❌ No
|
|
354
|
+
- Extending: ✅ Yes (applies)
|
|
355
|
+
- Normalizing: ❌ No
|
|
356
|
+
- Selector Type: All types
|
|
357
|
+
|
|
358
|
+
**Notes:** Core extension logic. Simple switch statement.
|
|
359
|
+
|
|
360
|
+
---
|
|
361
|
+
|
|
362
|
+
### :is() Wrapper Functions
|
|
363
|
+
|
|
364
|
+
#### `createIsWrapper` (lines 1380-1398)
|
|
365
|
+
**Responsibilities:**
|
|
366
|
+
- Creates `:is()` wrapper around given selectors
|
|
367
|
+
- Preserves comments on original selectors
|
|
368
|
+
- Strips comments from inheritance chain
|
|
369
|
+
- Deduplicates and flattens before creating wrapper
|
|
370
|
+
|
|
371
|
+
**Calls:**
|
|
372
|
+
- `deduplicateSelectors()` - deduplication
|
|
373
|
+
- `flattenGeneratedIs()` - flattening
|
|
374
|
+
- `SelectorList.create()` - create list
|
|
375
|
+
- `PseudoSelector.create()` - create wrapper
|
|
376
|
+
|
|
377
|
+
**Concerns:**
|
|
378
|
+
- Finding: ❌ No
|
|
379
|
+
- Searching: ❌ No
|
|
380
|
+
- Extending: ❌ No (construction only)
|
|
381
|
+
- Normalizing: ✅ Yes (deduplication, flattening)
|
|
382
|
+
- Selector Type: All types
|
|
383
|
+
|
|
384
|
+
**Notes:** Multiple normalization passes here: deduplicate → flatten → deduplicate again. Could be consolidated.
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
#### `createValidatedIsWrapper` (lines 1409-1425)
|
|
389
|
+
**Responsibilities:**
|
|
390
|
+
- Creates `:is()` wrapper with validation that returns fallback on conflicts
|
|
391
|
+
- Catches errors and returns fallback instead of throwing
|
|
392
|
+
|
|
393
|
+
**Calls:**
|
|
394
|
+
- `createValidatedIsWrapperWithErrors()` - actual creation
|
|
395
|
+
- Returns fallback on error
|
|
396
|
+
|
|
397
|
+
**Concerns:**
|
|
398
|
+
- Finding: ❌ No
|
|
399
|
+
- Searching: ❌ No
|
|
400
|
+
- Extending: ❌ No
|
|
401
|
+
- Normalizing: ❌ No
|
|
402
|
+
- Selector Type: PseudoSelector
|
|
403
|
+
|
|
404
|
+
**Notes:** Error-handling wrapper. Currently unused (only `createValidatedIsWrapperWithErrors` is used).
|
|
405
|
+
|
|
406
|
+
---
|
|
407
|
+
|
|
408
|
+
#### `createValidatedIsWrapperWithErrors` (lines 1436-1456)
|
|
409
|
+
**Responsibilities:**
|
|
410
|
+
- Creates `:is()` wrapper with validation that throws errors on conflicts
|
|
411
|
+
- Validates before creating wrapper
|
|
412
|
+
|
|
413
|
+
**Calls:**
|
|
414
|
+
- `validateIsWrapper()` - validation
|
|
415
|
+
- `createIsWrapper()` - actual creation
|
|
416
|
+
|
|
417
|
+
**Concerns:**
|
|
418
|
+
- Finding: ❌ No
|
|
419
|
+
- Searching: ❌ No
|
|
420
|
+
- Extending: ❌ No
|
|
421
|
+
- Normalizing: ❌ No
|
|
422
|
+
- Selector Type: PseudoSelector
|
|
423
|
+
|
|
424
|
+
**Notes:** Validation wrapper. Used throughout codebase.
|
|
425
|
+
|
|
426
|
+
---
|
|
427
|
+
|
|
428
|
+
#### `validateIsWrapper` (lines 1461-1582)
|
|
429
|
+
**Responsibilities:**
|
|
430
|
+
- Validates `:is()` wrapper contents for conflicts
|
|
431
|
+
- Checks for multiple different element types (ELEMENT_CONFLICT)
|
|
432
|
+
- Checks for multiple different ID selectors (ID_CONFLICT)
|
|
433
|
+
- Context-aware: checks if `:is()` would conflict with compound selector context
|
|
434
|
+
|
|
435
|
+
**Calls:**
|
|
436
|
+
- None (pure validation)
|
|
437
|
+
|
|
438
|
+
**Concerns:**
|
|
439
|
+
- Finding: ❌ No
|
|
440
|
+
- Searching: ❌ No
|
|
441
|
+
- Extending: ❌ No
|
|
442
|
+
- Normalizing: ❌ No
|
|
443
|
+
- Selector Type: PseudoSelector, CompoundSelector
|
|
444
|
+
|
|
445
|
+
**Notes:** Comprehensive validation. Good separation of concerns.
|
|
446
|
+
|
|
447
|
+
---
|
|
448
|
+
|
|
449
|
+
### Flattening Functions
|
|
450
|
+
|
|
451
|
+
#### `flattenGeneratedIs` (lines 494-540)
|
|
452
|
+
**Responsibilities:**
|
|
453
|
+
- Recursively flattens nested `:is()` wrappers that were generated
|
|
454
|
+
- Unwraps generated `:is()` pseudo-selectors and splices contents into parent
|
|
455
|
+
- Early bailout if no flattening needed
|
|
456
|
+
|
|
457
|
+
**Calls:**
|
|
458
|
+
- `flattenGeneratedIsInSelector()` - recursive processing
|
|
459
|
+
|
|
460
|
+
**Concerns:**
|
|
461
|
+
- Finding: ❌ No
|
|
462
|
+
- Searching: ❌ No
|
|
463
|
+
- Extending: ❌ No
|
|
464
|
+
- Normalizing: ✅ Yes (flattening)
|
|
465
|
+
- Selector Type: All types
|
|
466
|
+
|
|
467
|
+
**Notes:** Good performance optimization with early bailout. However, makes separate pass through selectors.
|
|
468
|
+
|
|
469
|
+
---
|
|
470
|
+
|
|
471
|
+
#### `flattenGeneratedIsInSelector` (lines 546-681)
|
|
472
|
+
**Responsibilities:**
|
|
473
|
+
- Recursively flattens generated `:is()` wrappers within a single selector
|
|
474
|
+
- Handles PseudoSelector, SelectorList, CompoundSelector, ComplexSelector
|
|
475
|
+
- Preserves `:is()` wrappers that are components of compound selectors (doesn't unwrap them)
|
|
476
|
+
- Optimizes unnecessary standalone `:is()` wrappers
|
|
477
|
+
|
|
478
|
+
**Calls:**
|
|
479
|
+
- `optimizeUnnecessaryIsWrapper()` - optimization
|
|
480
|
+
- `flattenGeneratedIs()` - recursive flattening
|
|
481
|
+
- `SelectorList.create()` - create lists
|
|
482
|
+
- `CompoundSelector.create()` - create compounds
|
|
483
|
+
- `ComplexSelector.create()` - create complex
|
|
484
|
+
- `PseudoSelector` constructor - create pseudo-selectors
|
|
485
|
+
|
|
486
|
+
**Concerns:**
|
|
487
|
+
- Finding: ❌ No
|
|
488
|
+
- Searching: ❌ No
|
|
489
|
+
- Extending: ❌ No
|
|
490
|
+
- Normalizing: ✅ Yes (flattening, optimization)
|
|
491
|
+
- Selector Type: All types
|
|
492
|
+
|
|
493
|
+
**Notes:** Complex recursive function. Handles many edge cases. Makes multiple passes through nested structures.
|
|
494
|
+
|
|
495
|
+
---
|
|
496
|
+
|
|
497
|
+
#### `optimizeUnnecessaryIsWrapper` (lines 1793-1821)
|
|
498
|
+
**Responsibilities:**
|
|
499
|
+
- Optimizes unnecessary standalone `:is()` wrappers
|
|
500
|
+
- Removes `:is()` when it wraps only one selector and was generated
|
|
501
|
+
- Example: `:is(.a)` → `.a` (when generated)
|
|
502
|
+
- Does NOT optimize `:is()` in compound selectors
|
|
503
|
+
|
|
504
|
+
**Calls:**
|
|
505
|
+
- None (pure optimization)
|
|
506
|
+
|
|
507
|
+
**Concerns:**
|
|
508
|
+
- Finding: ❌ No
|
|
509
|
+
- Searching: ❌ No
|
|
510
|
+
- Extending: ❌ No
|
|
511
|
+
- Normalizing: ✅ Yes (optimization)
|
|
512
|
+
- Selector Type: PseudoSelector
|
|
513
|
+
|
|
514
|
+
**Notes:** Good optimization. Used in flattening pipeline.
|
|
515
|
+
|
|
516
|
+
---
|
|
517
|
+
|
|
518
|
+
### Ampersand Functions
|
|
519
|
+
|
|
520
|
+
#### `checkAmpersandCrossingDuringExtension` (lines 1593-1626)
|
|
521
|
+
**Responsibilities:**
|
|
522
|
+
- Checks if extending target would cross an ampersand boundary
|
|
523
|
+
- Finds ampersands in selector
|
|
524
|
+
- Checks if target matches resolved form but not unresolved form
|
|
525
|
+
|
|
526
|
+
**Calls:**
|
|
527
|
+
- `findAmpersandsInSelector()` - find ampersands
|
|
528
|
+
- `replaceAmpersandWithItsValue()` - create resolved version
|
|
529
|
+
- `replaceAmpersandWithEmpty()` - create unresolved version
|
|
530
|
+
- `findExtendableLocations()` - check matches
|
|
531
|
+
|
|
532
|
+
**Concerns:**
|
|
533
|
+
- Finding: ✅ Yes (delegates)
|
|
534
|
+
- Searching: ✅ Yes (delegates)
|
|
535
|
+
- Extending: ❌ No (detection only)
|
|
536
|
+
- Normalizing: ❌ No
|
|
537
|
+
- Selector Type: All types
|
|
538
|
+
|
|
539
|
+
**Notes:** Specialized boundary detection. Good separation.
|
|
540
|
+
|
|
541
|
+
---
|
|
542
|
+
|
|
543
|
+
#### `findAmpersandsInSelector` (lines 1633-1644)
|
|
544
|
+
**Responsibilities:**
|
|
545
|
+
- Finds all ampersand nodes in a selector
|
|
546
|
+
- Uses `nodes()` iterator to traverse recursively
|
|
547
|
+
|
|
548
|
+
**Calls:**
|
|
549
|
+
- `selector.nodes()` - node iterator
|
|
550
|
+
|
|
551
|
+
**Concerns:**
|
|
552
|
+
- Finding: ✅ Yes (finds ampersands)
|
|
553
|
+
- Searching: ✅ Yes (traverses)
|
|
554
|
+
- Extending: ❌ No
|
|
555
|
+
- Normalizing: ❌ No
|
|
556
|
+
- Selector Type: All types
|
|
557
|
+
|
|
558
|
+
**Notes:** Simple traversal function.
|
|
559
|
+
|
|
560
|
+
---
|
|
561
|
+
|
|
562
|
+
#### `replaceAmpersandWithItsValue` (lines 1652-1674)
|
|
563
|
+
**Responsibilities:**
|
|
564
|
+
- Creates version of selector with ampersand replaced by its resolved value
|
|
565
|
+
- Finds and replaces ampersand node using helper functions
|
|
566
|
+
|
|
567
|
+
**Calls:**
|
|
568
|
+
- `selector.copy()` - copy selector
|
|
569
|
+
- `ampersand.value.selector.copy()` - copy resolved selector
|
|
570
|
+
- `selectorCopy.nodes()` - traverse
|
|
571
|
+
- `findParentOfNode()` - find parent
|
|
572
|
+
- `replaceNodeInParent()` - replace node
|
|
573
|
+
|
|
574
|
+
**Concerns:**
|
|
575
|
+
- Finding: ✅ Yes (finds ampersand)
|
|
576
|
+
- Searching: ✅ Yes (traverses)
|
|
577
|
+
- Extending: ❌ No
|
|
578
|
+
- Normalizing: ❌ No
|
|
579
|
+
- Selector Type: All types
|
|
580
|
+
|
|
581
|
+
**Notes:** Creates copies. May create multiple copies if called multiple times.
|
|
582
|
+
|
|
583
|
+
---
|
|
584
|
+
|
|
585
|
+
#### `replaceAmpersandWithEmpty` (lines 1682-1701)
|
|
586
|
+
**Responsibilities:**
|
|
587
|
+
- Creates version of selector with ampersand removed
|
|
588
|
+
- For boundary analysis
|
|
589
|
+
|
|
590
|
+
**Calls:**
|
|
591
|
+
- `selector.copy()` - copy selector
|
|
592
|
+
- `selectorCopy.nodes()` - traverse
|
|
593
|
+
- `findParentOfNode()` - find parent
|
|
594
|
+
|
|
595
|
+
**Concerns:**
|
|
596
|
+
- Finding: ✅ Yes (finds ampersand)
|
|
597
|
+
- Searching: ✅ Yes (traverses)
|
|
598
|
+
- Extending: ❌ No
|
|
599
|
+
- Normalizing: ❌ No
|
|
600
|
+
- Selector Type: All types
|
|
601
|
+
|
|
602
|
+
**Notes:** Creates copies.
|
|
603
|
+
|
|
604
|
+
---
|
|
605
|
+
|
|
606
|
+
#### `handleAmpersandBoundaryCrossing` (lines 1712-1731)
|
|
607
|
+
**Responsibilities:**
|
|
608
|
+
- Handles extension when it crosses an ampersand boundary
|
|
609
|
+
- Replaces ampersand with resolved selector
|
|
610
|
+
- Extends the resolved selector
|
|
611
|
+
- Marks for hoisting to root
|
|
612
|
+
|
|
613
|
+
**Calls:**
|
|
614
|
+
- `replaceAmpersandWithItsValue()` - replace ampersand
|
|
615
|
+
- `extendSelector()` - extend resolved selector
|
|
616
|
+
- `markSelectorForHoisting()` - mark for hoisting
|
|
617
|
+
|
|
618
|
+
**Concerns:**
|
|
619
|
+
- Finding: ❌ No
|
|
620
|
+
- Searching: ❌ No
|
|
621
|
+
- Extending: ✅ Yes (delegates)
|
|
622
|
+
- Normalizing: ❌ No
|
|
623
|
+
- Selector Type: All types
|
|
624
|
+
|
|
625
|
+
**Notes:** Specialized handler for ampersand boundary crossing.
|
|
626
|
+
|
|
627
|
+
---
|
|
628
|
+
|
|
629
|
+
#### `findParentOfNode` (lines 1739-1752)
|
|
630
|
+
**Responsibilities:**
|
|
631
|
+
- Finds the parent container of a specific node
|
|
632
|
+
- Searches through CompoundSelector, ComplexSelector, SelectorList, PseudoSelector
|
|
633
|
+
|
|
634
|
+
**Calls:**
|
|
635
|
+
- `root.nodes()` - traverse nodes
|
|
636
|
+
|
|
637
|
+
**Concerns:**
|
|
638
|
+
- Finding: ✅ Yes (finds parent)
|
|
639
|
+
- Searching: ✅ Yes (traverses)
|
|
640
|
+
- Extending: ❌ No
|
|
641
|
+
- Normalizing: ❌ No
|
|
642
|
+
- Selector Type: All types
|
|
643
|
+
|
|
644
|
+
**Notes:** Utility function for tree navigation.
|
|
645
|
+
|
|
646
|
+
---
|
|
647
|
+
|
|
648
|
+
#### `replaceNodeInParent` (lines 1760-1771)
|
|
649
|
+
**Responsibilities:**
|
|
650
|
+
- Replaces a node within its parent container
|
|
651
|
+
- Handles CompoundSelector, ComplexSelector, SelectorList, PseudoSelector
|
|
652
|
+
|
|
653
|
+
**Calls:**
|
|
654
|
+
- None (direct mutation)
|
|
655
|
+
|
|
656
|
+
**Concerns:**
|
|
657
|
+
- Finding: ❌ No
|
|
658
|
+
- Searching: ❌ No
|
|
659
|
+
- Extending: ❌ No
|
|
660
|
+
- Normalizing: ❌ No
|
|
661
|
+
- Selector Type: All types
|
|
662
|
+
|
|
663
|
+
**Notes:** Utility function for tree mutation.
|
|
664
|
+
|
|
665
|
+
---
|
|
666
|
+
|
|
667
|
+
#### `markSelectorForHoisting` (lines 1778-1783)
|
|
668
|
+
**Responsibilities:**
|
|
669
|
+
- Marks a selector for hoisting to root
|
|
670
|
+
- Clones selector and sets `hoistToRoot` option
|
|
671
|
+
|
|
672
|
+
**Calls:**
|
|
673
|
+
- `selector.copy()` - copy selector
|
|
674
|
+
|
|
675
|
+
**Concerns:**
|
|
676
|
+
- Finding: ❌ No
|
|
677
|
+
- Searching: ❌ No
|
|
678
|
+
- Extending: ❌ No
|
|
679
|
+
- Normalizing: ❌ No
|
|
680
|
+
- Selector Type: All types
|
|
681
|
+
|
|
682
|
+
**Notes:** Simple marker function.
|
|
683
|
+
|
|
684
|
+
---
|
|
685
|
+
|
|
686
|
+
### Compound Selector Functions
|
|
687
|
+
|
|
688
|
+
#### `getIsSelectorArg` (lines 453-462)
|
|
689
|
+
**Responsibilities:**
|
|
690
|
+
- Checks if component is `:is()` pseudo-selector with selector argument
|
|
691
|
+
- Returns SelectorList argument if valid, null otherwise
|
|
692
|
+
|
|
693
|
+
**Calls:**
|
|
694
|
+
- None (pure check)
|
|
695
|
+
|
|
696
|
+
**Concerns:**
|
|
697
|
+
- Finding: ❌ No
|
|
698
|
+
- Searching: ❌ No
|
|
699
|
+
- Extending: ❌ No
|
|
700
|
+
- Normalizing: ❌ No
|
|
701
|
+
- Selector Type: PseudoSelector
|
|
702
|
+
|
|
703
|
+
**Notes:** Simple utility function.
|
|
704
|
+
|
|
705
|
+
---
|
|
706
|
+
|
|
707
|
+
#### `extendWithinIsArg` (lines 473-480)
|
|
708
|
+
**Responsibilities:**
|
|
709
|
+
- Extends within an `:is()` pseudo-selector argument recursively
|
|
710
|
+
- Delegates to `extendSelector` with appropriate flags
|
|
711
|
+
|
|
712
|
+
**Calls:**
|
|
713
|
+
- `extendSelector()` - recursive extend
|
|
714
|
+
|
|
715
|
+
**Concerns:**
|
|
716
|
+
- Finding: ❌ No
|
|
717
|
+
- Searching: ❌ No
|
|
718
|
+
- Extending: ✅ Yes (delegates)
|
|
719
|
+
- Normalizing: ❌ No
|
|
720
|
+
- Selector Type: PseudoSelector
|
|
721
|
+
|
|
722
|
+
**Notes:** Thin wrapper for recursive extend.
|
|
723
|
+
|
|
724
|
+
---
|
|
725
|
+
|
|
726
|
+
#### `isValidCompoundSelector` (lines 1828-1854)
|
|
727
|
+
**Responsibilities:**
|
|
728
|
+
- Validates that a compound selector doesn't have duplicate element or ID selectors
|
|
729
|
+
- Recursively checks nested compounds
|
|
730
|
+
|
|
731
|
+
**Calls:**
|
|
732
|
+
- `isValidCompoundSelector()` - recursive check
|
|
733
|
+
|
|
734
|
+
**Concerns:**
|
|
735
|
+
- Finding: ❌ No
|
|
736
|
+
- Searching: ❌ No
|
|
737
|
+
- Extending: ❌ No
|
|
738
|
+
- Normalizing: ❌ No
|
|
739
|
+
- Selector Type: CompoundSelector
|
|
740
|
+
|
|
741
|
+
**Notes:** Validation function. Currently unused (replaced by `validateCompoundSelector`).
|
|
742
|
+
|
|
743
|
+
---
|
|
744
|
+
|
|
745
|
+
#### `createValidatedCompoundSelector` (lines 1864-1879)
|
|
746
|
+
**Responsibilities:**
|
|
747
|
+
- Creates compound selector with validation that returns fallback on conflicts
|
|
748
|
+
- Catches errors and returns fallback instead of throwing
|
|
749
|
+
|
|
750
|
+
**Calls:**
|
|
751
|
+
- `createValidatedCompoundSelectorWithErrors()` - actual creation
|
|
752
|
+
- Returns fallback on error
|
|
753
|
+
|
|
754
|
+
**Concerns:**
|
|
755
|
+
- Finding: ❌ No
|
|
756
|
+
- Searching: ❌ No
|
|
757
|
+
- Extending: ❌ No
|
|
758
|
+
- Normalizing: ❌ No
|
|
759
|
+
- Selector Type: CompoundSelector
|
|
760
|
+
|
|
761
|
+
**Notes:** Error-handling wrapper. Currently unused (only `createValidatedCompoundSelectorWithErrors` is used).
|
|
762
|
+
|
|
763
|
+
---
|
|
764
|
+
|
|
765
|
+
#### `createValidatedCompoundSelectorWithErrors` (lines 1889-1909)
|
|
766
|
+
**Responsibilities:**
|
|
767
|
+
- Creates compound selector with validation that throws errors on conflicts
|
|
768
|
+
- Validates before creating compound
|
|
769
|
+
|
|
770
|
+
**Calls:**
|
|
771
|
+
- `validateCompoundSelector()` - validation
|
|
772
|
+
- `CompoundSelector.create()` - create compound
|
|
773
|
+
|
|
774
|
+
**Concerns:**
|
|
775
|
+
- Finding: ❌ No
|
|
776
|
+
- Searching: ❌ No
|
|
777
|
+
- Extending: ❌ No
|
|
778
|
+
- Normalizing: ❌ No
|
|
779
|
+
- Selector Type: CompoundSelector
|
|
780
|
+
|
|
781
|
+
**Notes:** Validation wrapper. Used throughout codebase.
|
|
782
|
+
|
|
783
|
+
---
|
|
784
|
+
|
|
785
|
+
#### `validateCompoundSelector` (lines 1914-1961)
|
|
786
|
+
**Responsibilities:**
|
|
787
|
+
- Validates compound selector components for conflicts
|
|
788
|
+
- Checks for multiple different element types (ELEMENT_CONFLICT)
|
|
789
|
+
- Checks for multiple different ID selectors (ID_CONFLICT)
|
|
790
|
+
- Recursively checks nested compounds
|
|
791
|
+
|
|
792
|
+
**Calls:**
|
|
793
|
+
- `validateCompoundSelector()` - recursive check
|
|
794
|
+
|
|
795
|
+
**Concerns:**
|
|
796
|
+
- Finding: ❌ No
|
|
797
|
+
- Searching: ❌ No
|
|
798
|
+
- Extending: ❌ No
|
|
799
|
+
- Normalizing: ❌ No
|
|
800
|
+
- Selector Type: CompoundSelector
|
|
801
|
+
|
|
802
|
+
**Notes:** Comprehensive validation. Good separation of concerns.
|
|
803
|
+
|
|
804
|
+
---
|
|
805
|
+
|
|
806
|
+
### Chaining Functions
|
|
807
|
+
|
|
808
|
+
#### `findChainedExtends` (lines 1982-2035)
|
|
809
|
+
**Responsibilities:**
|
|
810
|
+
- Finds extends that should be processed next on a newly transformed selector
|
|
811
|
+
- Part of iterative extend process
|
|
812
|
+
- Checks if any selector in result matches other extend targets
|
|
813
|
+
- Only checks selectors that were in the original ruleset (not newly added ones)
|
|
814
|
+
|
|
815
|
+
**Calls:**
|
|
816
|
+
- None (pure analysis)
|
|
817
|
+
|
|
818
|
+
**Concerns:**
|
|
819
|
+
- Finding: ✅ Yes (finds chained extends)
|
|
820
|
+
- Searching: ✅ Yes (searches for matches)
|
|
821
|
+
- Extending: ❌ No
|
|
822
|
+
- Normalizing: ❌ No
|
|
823
|
+
- Selector Type: SelectorList
|
|
824
|
+
|
|
825
|
+
**Notes:** Chaining logic. Good separation of concerns.
|
|
826
|
+
|
|
827
|
+
---
|
|
828
|
+
|
|
829
|
+
## File: find-extendable-locations.ts
|
|
830
|
+
|
|
831
|
+
### Core Entry Points
|
|
832
|
+
|
|
833
|
+
#### `findExtendableLocations` (lines 71-141)
|
|
834
|
+
**Responsibilities:**
|
|
835
|
+
- Main entry point for finding extendable locations
|
|
836
|
+
- Enhanced selector matching with 7-layer optimization system
|
|
837
|
+
- Recursively searches selector tree to find all locations where target appears
|
|
838
|
+
- Performance optimizations: exact match cache, KeySet fast rejection, fast path matching
|
|
839
|
+
|
|
840
|
+
**Calls:**
|
|
841
|
+
- `tryFastPathExtendMatch()` - fast path optimization
|
|
842
|
+
- `searchWithinSelector()` - full recursive search
|
|
843
|
+
|
|
844
|
+
**Concerns:**
|
|
845
|
+
- Finding: ✅ Yes (finds all locations)
|
|
846
|
+
- Searching: ✅ Yes (searches recursively)
|
|
847
|
+
- Extending: ❌ No (finding only)
|
|
848
|
+
- Normalizing: ❌ No
|
|
849
|
+
- Selector Type: All types
|
|
850
|
+
|
|
851
|
+
**Notes:** Main search function. Good performance optimizations. Returns all matching locations, not just the first one.
|
|
852
|
+
|
|
853
|
+
**Potential Issues:**
|
|
854
|
+
- Returns multiple locations, but `extendSelector` may only use the first one in some cases
|
|
855
|
+
- Fast path may skip some matches in edge cases
|
|
856
|
+
|
|
857
|
+
---
|
|
858
|
+
|
|
859
|
+
### Fast Path Functions
|
|
860
|
+
|
|
861
|
+
#### `tryFastPathExtendMatch` (lines 148-321)
|
|
862
|
+
**Responsibilities:**
|
|
863
|
+
- Fast path extend matching for common patterns
|
|
864
|
+
- Handles: exact match, simple-to-simple, compound containing simple, small compound-to-compound, SelectorList in find, small SelectorList in target, complex selector patterns
|
|
865
|
+
- Comprehensive enough to skip slow path for most common cases
|
|
866
|
+
|
|
867
|
+
**Calls:**
|
|
868
|
+
- `trySmallCompoundExtendMatch()` - small compound matching
|
|
869
|
+
- `tryPartialComplexMatch()` - partial complex matching
|
|
870
|
+
- `tryBacktrackingComplexMatch()` - backtracking match
|
|
871
|
+
- `trySequentialComplexMatch()` - sequential complex matching
|
|
872
|
+
- `tryFastPathExtendMatch()` - recursive calls for SelectorList
|
|
873
|
+
|
|
874
|
+
**Concerns:**
|
|
875
|
+
- Finding: ✅ Yes (finds matches)
|
|
876
|
+
- Searching: ✅ Yes (searches)
|
|
877
|
+
- Extending: ❌ No
|
|
878
|
+
- Normalizing: ❌ No
|
|
879
|
+
- Selector Type: All types
|
|
880
|
+
|
|
881
|
+
**Potential Issues:**
|
|
882
|
+
- **`.foo.foo` BUG LOCATION**: Fast path 3 (lines 191-219) handles compound containing simple target. It loops through `target.value` and finds matches, but only returns locations for matches found. If `.foo.foo` has two `.foo` components, it should find both, but the caller may only process the first one.
|
|
883
|
+
|
|
884
|
+
**Notes:** Comprehensive fast path. Good performance optimization.
|
|
885
|
+
|
|
886
|
+
---
|
|
887
|
+
|
|
888
|
+
#### `trySmallCompoundExtendMatch` (lines 414-465)
|
|
889
|
+
**Responsibilities:**
|
|
890
|
+
- Optimized compound selector matching for small compounds (≤4 components)
|
|
891
|
+
- Checks for exact equivalence (order-independent)
|
|
892
|
+
- Checks for subset matching (find is subset of target)
|
|
893
|
+
- Calculates remainders for partial matches
|
|
894
|
+
|
|
895
|
+
**Calls:**
|
|
896
|
+
- `areCompoundSelectorsEquivalent()` - equivalence check
|
|
897
|
+
- `CompoundSelector.create()` - create remainder compounds
|
|
898
|
+
|
|
899
|
+
**Concerns:**
|
|
900
|
+
- Finding: ✅ Yes (finds matches)
|
|
901
|
+
- Searching: ✅ Yes (searches)
|
|
902
|
+
- Extending: ❌ No
|
|
903
|
+
- Normalizing: ❌ No
|
|
904
|
+
- Selector Type: CompoundSelector
|
|
905
|
+
|
|
906
|
+
**Potential Issues:**
|
|
907
|
+
- **`.foo.foo` BUG LOCATION**: When checking for subset matching (lines 429-461), it uses `find.value.every()` to check if all find components match. For `.foo.foo` matching `.foo`, it will find that `.foo` is a subset, but it only returns ONE location (the compound itself), not locations for each matching component.
|
|
908
|
+
|
|
909
|
+
**Notes:** Fast path for small compounds. Good optimization.
|
|
910
|
+
|
|
911
|
+
---
|
|
912
|
+
|
|
913
|
+
#### `tryPartialComplexMatch` (lines 326-409)
|
|
914
|
+
**Responsibilities:**
|
|
915
|
+
- Tries to match partial complex selectors
|
|
916
|
+
- Finds find pattern within target at different positions
|
|
917
|
+
- Calculates remainders (before and after match)
|
|
918
|
+
- Handles compound-to-simple partial matches
|
|
919
|
+
|
|
920
|
+
**Calls:**
|
|
921
|
+
- `componentsMatch()` - component matching
|
|
922
|
+
- `ComplexSelector.create()` - create remainder complex selectors
|
|
923
|
+
|
|
924
|
+
**Concerns:**
|
|
925
|
+
- Finding: ✅ Yes (finds matches)
|
|
926
|
+
- Searching: ✅ Yes (searches)
|
|
927
|
+
- Extending: ❌ No
|
|
928
|
+
- Normalizing: ❌ No
|
|
929
|
+
- Selector Type: ComplexSelector
|
|
930
|
+
|
|
931
|
+
**Notes:** Partial complex matching. Good for performance.
|
|
932
|
+
|
|
933
|
+
---
|
|
934
|
+
|
|
935
|
+
#### `trySequentialComplexMatch` (lines 776-882)
|
|
936
|
+
**Responsibilities:**
|
|
937
|
+
- Tries sequential complex matching with partial compound support
|
|
938
|
+
- Finds contiguous subsequence match that preserves combinator structure
|
|
939
|
+
- Calculates remainders (before, after, and within compounds)
|
|
940
|
+
- Handles compound-to-simple partial matches within complex selectors
|
|
941
|
+
|
|
942
|
+
**Calls:**
|
|
943
|
+
- `areSelectorArgumentsEquivalent()` - selector equivalence
|
|
944
|
+
- `ComplexSelector.create()` - create remainder complex selectors
|
|
945
|
+
- `CompoundSelector.create()` - create remainder compounds
|
|
946
|
+
|
|
947
|
+
**Concerns:**
|
|
948
|
+
- Finding: ✅ Yes (finds matches)
|
|
949
|
+
- Searching: ✅ Yes (searches)
|
|
950
|
+
- Extending: ❌ No
|
|
951
|
+
- Normalizing: ❌ No
|
|
952
|
+
- Selector Type: ComplexSelector
|
|
953
|
+
|
|
954
|
+
**Notes:** Sequential complex matching. Handles partial compound matches.
|
|
955
|
+
|
|
956
|
+
---
|
|
957
|
+
|
|
958
|
+
#### `tryBacktrackingComplexMatch` (lines 884-990)
|
|
959
|
+
**Responsibilities:**
|
|
960
|
+
- Add backtracking support for complex `:is()` scenarios
|
|
961
|
+
- Handles cases like `:is(.a > .b).d > .c` matching `.a > .b > .c`
|
|
962
|
+
- Preserves combinator sequences for correct matching
|
|
963
|
+
- Handles compound matching for backtracking
|
|
964
|
+
|
|
965
|
+
**Calls:**
|
|
966
|
+
- `componentsMatch()` - component matching
|
|
967
|
+
- `ComplexSelector.create()` - create remainder complex selectors
|
|
968
|
+
- `CompoundSelector.create()` - create remainder compounds
|
|
969
|
+
|
|
970
|
+
**Concerns:**
|
|
971
|
+
- Finding: ✅ Yes (finds matches)
|
|
972
|
+
- Searching: ✅ Yes (searches)
|
|
973
|
+
- Extending: ❌ No
|
|
974
|
+
- Normalizing: ❌ No
|
|
975
|
+
- Selector Type: ComplexSelector
|
|
976
|
+
|
|
977
|
+
**Notes:** Backtracking match for `:is()` scenarios. Complex logic.
|
|
978
|
+
|
|
979
|
+
---
|
|
980
|
+
|
|
981
|
+
### Recursive Search Functions
|
|
982
|
+
|
|
983
|
+
#### `searchWithinSelector` (lines 478-505)
|
|
984
|
+
**Responsibilities:**
|
|
985
|
+
- Enhanced recursive search with specialized handlers for each selector type
|
|
986
|
+
- Routes to type-specific search functions
|
|
987
|
+
- Checks for exact match first
|
|
988
|
+
|
|
989
|
+
**Calls:**
|
|
990
|
+
- `searchWithinSelectorList()` - search in SelectorList
|
|
991
|
+
- `searchWithinCompoundSelector()` - search in CompoundSelector
|
|
992
|
+
- `searchWithinComplexSelector()` - search in ComplexSelector
|
|
993
|
+
- `searchWithinPseudoSelector()` - search in PseudoSelector
|
|
994
|
+
|
|
995
|
+
**Concerns:**
|
|
996
|
+
- Finding: ✅ Yes (finds matches)
|
|
997
|
+
- Searching: ✅ Yes (searches recursively)
|
|
998
|
+
- Extending: ❌ No
|
|
999
|
+
- Normalizing: ❌ No
|
|
1000
|
+
- Selector Type: All types
|
|
1001
|
+
|
|
1002
|
+
**Notes:** Main recursive search router. Good separation by selector type.
|
|
1003
|
+
|
|
1004
|
+
---
|
|
1005
|
+
|
|
1006
|
+
#### `searchWithinSelectorList` (lines 510-519)
|
|
1007
|
+
**Responsibilities:**
|
|
1008
|
+
- Searches within a selector list
|
|
1009
|
+
- Iterates through each selector and searches recursively
|
|
1010
|
+
|
|
1011
|
+
**Calls:**
|
|
1012
|
+
- `searchWithinSelector()` - recursive search
|
|
1013
|
+
|
|
1014
|
+
**Concerns:**
|
|
1015
|
+
- Finding: ✅ Yes (finds matches)
|
|
1016
|
+
- Searching: ✅ Yes (searches)
|
|
1017
|
+
- Extending: ❌ No
|
|
1018
|
+
- Normalizing: ❌ No
|
|
1019
|
+
- Selector Type: SelectorList
|
|
1020
|
+
|
|
1021
|
+
**Notes:** Simple iteration. No issues.
|
|
1022
|
+
|
|
1023
|
+
---
|
|
1024
|
+
|
|
1025
|
+
#### `searchWithinCompoundSelector` (lines 524-610)
|
|
1026
|
+
**Responsibilities:**
|
|
1027
|
+
- Enhanced compound selector search with partial matching support
|
|
1028
|
+
- Handles PseudoSelector targets (checks for equivalent matches)
|
|
1029
|
+
- Standard recursive search through each component
|
|
1030
|
+
- Checks for partial matches within compound selectors (simple target)
|
|
1031
|
+
- Checks for compound-to-compound partial matching
|
|
1032
|
+
|
|
1033
|
+
**Calls:**
|
|
1034
|
+
- `arePseudoSelectorsEquivalent()` - pseudo-selector equivalence
|
|
1035
|
+
- `searchWithinSelector()` - recursive search
|
|
1036
|
+
- `CompoundSelector.create()` - create remainder compounds
|
|
1037
|
+
|
|
1038
|
+
**Concerns:**
|
|
1039
|
+
- Finding: ✅ Yes (finds matches)
|
|
1040
|
+
- Searching: ✅ Yes (searches)
|
|
1041
|
+
- Extending: ❌ No
|
|
1042
|
+
- Normalizing: ❌ No
|
|
1043
|
+
- Selector Type: CompoundSelector
|
|
1044
|
+
|
|
1045
|
+
**Potential Issues:**
|
|
1046
|
+
- **`.foo.foo` BUG LOCATION**: Lines 551-572 handle simple selector partial matching. It loops through `compound.value` and finds matches using `valueOf()` comparison. If `.foo.foo` has two `.foo` components, it will find both and add locations for both. However, the location path is `[...currentPath]` (the compound itself), not `[...currentPath, i]` (the specific component). This means both matches have the same path, and the caller may only process one.
|
|
1047
|
+
|
|
1048
|
+
**Notes:** Comprehensive compound search. Handles partial matches well, but path construction may be an issue for duplicate components.
|
|
1049
|
+
|
|
1050
|
+
---
|
|
1051
|
+
|
|
1052
|
+
#### `searchWithinComplexSelector` (lines 615-665)
|
|
1053
|
+
**Responsibilities:**
|
|
1054
|
+
- Enhanced complex selector search with combinator-aware optimizations
|
|
1055
|
+
- Iterates through components (skipping combinators)
|
|
1056
|
+
- Post-processes matches at position 0 to mark as partial if there are remainders
|
|
1057
|
+
- Handles complex selector pattern matching
|
|
1058
|
+
- Tries backtracking match for `:is()` scenarios
|
|
1059
|
+
|
|
1060
|
+
**Calls:**
|
|
1061
|
+
- `searchWithinSelector()` - recursive search
|
|
1062
|
+
- `tryComplexSelectorPatternMatch()` - pattern matching
|
|
1063
|
+
- `tryBacktrackingComplexMatch()` - backtracking match
|
|
1064
|
+
- `ComplexSelector.create()` - create remainder complex selectors
|
|
1065
|
+
|
|
1066
|
+
**Concerns:**
|
|
1067
|
+
- Finding: ✅ Yes (finds matches)
|
|
1068
|
+
- Searching: ✅ Yes (searches)
|
|
1069
|
+
- Extending: ❌ No
|
|
1070
|
+
- Normalizing: ❌ No
|
|
1071
|
+
- Selector Type: ComplexSelector
|
|
1072
|
+
|
|
1073
|
+
**Notes:** Comprehensive complex search. Good post-processing for partial matches.
|
|
1074
|
+
|
|
1075
|
+
---
|
|
1076
|
+
|
|
1077
|
+
#### `tryComplexSelectorPatternMatch` (lines 671-769)
|
|
1078
|
+
**Responsibilities:**
|
|
1079
|
+
- Attempts to find pattern matches within complex selectors
|
|
1080
|
+
- Handles common CSS combinator patterns with optimized matching
|
|
1081
|
+
- Tries to match target pattern at different positions within complex selector
|
|
1082
|
+
- Handles compound-to-simple partial matches
|
|
1083
|
+
- Calculates remainders (before and after match)
|
|
1084
|
+
|
|
1085
|
+
**Calls:**
|
|
1086
|
+
- `componentsMatch()` - component matching
|
|
1087
|
+
- `ComplexSelector.create()` - create remainder complex selectors
|
|
1088
|
+
- `CompoundSelector.create()` - create remainder compounds
|
|
1089
|
+
|
|
1090
|
+
**Concerns:**
|
|
1091
|
+
- Finding: ✅ Yes (finds matches)
|
|
1092
|
+
- Searching: ✅ Yes (searches)
|
|
1093
|
+
- Extending: ❌ No
|
|
1094
|
+
- Normalizing: ❌ No
|
|
1095
|
+
- Selector Type: ComplexSelector
|
|
1096
|
+
|
|
1097
|
+
**Notes:** Pattern matching for complex selectors. Good optimization.
|
|
1098
|
+
|
|
1099
|
+
---
|
|
1100
|
+
|
|
1101
|
+
#### `searchWithinPseudoSelector` (lines 1060-1121)
|
|
1102
|
+
**Responsibilities:**
|
|
1103
|
+
- Enhanced pseudo-selector search with `:is()` backtracking optimization
|
|
1104
|
+
- Special handling for `:is()` pseudo-selectors
|
|
1105
|
+
- Checks if target matches any alternative in `:is()` selector list
|
|
1106
|
+
- Recursive search within each alternative
|
|
1107
|
+
- Checks if target could be added as new alternative
|
|
1108
|
+
|
|
1109
|
+
**Calls:**
|
|
1110
|
+
- `isStructurallyEqual()` - structural equality
|
|
1111
|
+
- `searchWithinSelector()` - recursive search
|
|
1112
|
+
|
|
1113
|
+
**Concerns:**
|
|
1114
|
+
- Finding: ✅ Yes (finds matches)
|
|
1115
|
+
- Searching: ✅ Yes (searches)
|
|
1116
|
+
- Extending: ❌ No
|
|
1117
|
+
- Normalizing: ❌ No
|
|
1118
|
+
- Selector Type: PseudoSelector
|
|
1119
|
+
|
|
1120
|
+
**Notes:** Specialized `:is()` handling. Good optimization.
|
|
1121
|
+
|
|
1122
|
+
---
|
|
1123
|
+
|
|
1124
|
+
### Application Functions
|
|
1125
|
+
|
|
1126
|
+
#### `applyExtensionAtLocation` (lines 1130-1136)
|
|
1127
|
+
**Responsibilities:**
|
|
1128
|
+
- Applies an extension at a specific location within a selector tree
|
|
1129
|
+
- Delegates to `applyExtensionAtPath`
|
|
1130
|
+
|
|
1131
|
+
**Calls:**
|
|
1132
|
+
- `applyExtensionAtPath()` - recursive application
|
|
1133
|
+
|
|
1134
|
+
**Concerns:**
|
|
1135
|
+
- Finding: ❌ No
|
|
1136
|
+
- Searching: ❌ No
|
|
1137
|
+
- Extending: ✅ Yes (applies)
|
|
1138
|
+
- Normalizing: ❌ No
|
|
1139
|
+
- Selector Type: All types
|
|
1140
|
+
|
|
1141
|
+
**Notes:** Thin wrapper. Same as in extend.ts (duplicate?).
|
|
1142
|
+
|
|
1143
|
+
---
|
|
1144
|
+
|
|
1145
|
+
#### `applyExtensionAtPath` (lines 1141-1236)
|
|
1146
|
+
**Responsibilities:**
|
|
1147
|
+
- Recursively applies an extension at a specific path
|
|
1148
|
+
- Navigates through SelectorList, CompoundSelector, ComplexSelector, PseudoSelector
|
|
1149
|
+
- Handles different extension types: replace, append, wrap
|
|
1150
|
+
|
|
1151
|
+
**Calls:**
|
|
1152
|
+
- `applyExtension()` - actual extension logic
|
|
1153
|
+
- `SelectorList.create()` - create lists
|
|
1154
|
+
- `CompoundSelector.create()` - create compounds
|
|
1155
|
+
- `ComplexSelector.create()` - create complex
|
|
1156
|
+
- `PseudoSelector.create()` - create pseudo-selectors
|
|
1157
|
+
|
|
1158
|
+
**Concerns:**
|
|
1159
|
+
- Finding: ❌ No
|
|
1160
|
+
- Searching: ❌ No
|
|
1161
|
+
- Extending: ✅ Yes (applies)
|
|
1162
|
+
- Normalizing: ❌ No
|
|
1163
|
+
- Selector Type: All types
|
|
1164
|
+
|
|
1165
|
+
**Notes:** Same as in extend.ts (duplicate?).
|
|
1166
|
+
|
|
1167
|
+
---
|
|
1168
|
+
|
|
1169
|
+
#### `applyExtension` (lines 1241-1276)
|
|
1170
|
+
**Responsibilities:**
|
|
1171
|
+
- Applies the actual extension based on extension type
|
|
1172
|
+
- `replace`: returns extendWith
|
|
1173
|
+
- `append`: adds to SelectorList or creates new list
|
|
1174
|
+
- `wrap`: creates `:is()` wrapper
|
|
1175
|
+
|
|
1176
|
+
**Calls:**
|
|
1177
|
+
- `SelectorList.create()` - create lists
|
|
1178
|
+
- `PseudoSelector.create()` - create `:is()` wrapper
|
|
1179
|
+
|
|
1180
|
+
**Concerns:**
|
|
1181
|
+
- Finding: ❌ No
|
|
1182
|
+
- Searching: ❌ No
|
|
1183
|
+
- Extending: ✅ Yes (applies)
|
|
1184
|
+
- Normalizing: ❌ No
|
|
1185
|
+
- Selector Type: All types
|
|
1186
|
+
|
|
1187
|
+
**Notes:** Same as in extend.ts (duplicate?).
|
|
1188
|
+
|
|
1189
|
+
---
|
|
1190
|
+
|
|
1191
|
+
### Legacy Functions
|
|
1192
|
+
|
|
1193
|
+
#### `normalizeSelector` (lines 1001-1055)
|
|
1194
|
+
**Responsibilities:**
|
|
1195
|
+
- Normalizes a selector to handle `:is()` equivalences
|
|
1196
|
+
- Single source of truth for `:is()` expansion logic
|
|
1197
|
+
- Expands standalone `:is()` to selector list
|
|
1198
|
+
- Expands complex selector with `:is()` to selector list
|
|
1199
|
+
- Normalizes each selector in a selector list
|
|
1200
|
+
|
|
1201
|
+
**Calls:**
|
|
1202
|
+
- `expandComplexSelectorWithIs()` - expand complex with `:is()`
|
|
1203
|
+
- `normalizeSelector()` - recursive normalization
|
|
1204
|
+
- `SelectorList.create()` - create lists
|
|
1205
|
+
|
|
1206
|
+
**Concerns:**
|
|
1207
|
+
- Finding: ❌ No
|
|
1208
|
+
- Searching: ❌ No
|
|
1209
|
+
- Extending: ❌ No
|
|
1210
|
+
- Normalizing: ✅ Yes (normalization)
|
|
1211
|
+
- Selector Type: All types
|
|
1212
|
+
|
|
1213
|
+
**Notes:** Legacy normalization. Used by `matchSelectors`.
|
|
1214
|
+
|
|
1215
|
+
---
|
|
1216
|
+
|
|
1217
|
+
#### `matchSelectors` (lines 1302-1344)
|
|
1218
|
+
**Responsibilities:**
|
|
1219
|
+
- Legacy matchSelectors function for backward compatibility
|
|
1220
|
+
- Maps to the new `findExtendableLocations` API
|
|
1221
|
+
- Normalizes selectors first
|
|
1222
|
+
- Converts `ExtendSearchResult` to `MatchResult`
|
|
1223
|
+
|
|
1224
|
+
**Calls:**
|
|
1225
|
+
- `normalizeSelector()` - normalization
|
|
1226
|
+
- `findExtendableLocations()` - search
|
|
1227
|
+
|
|
1228
|
+
**Concerns:**
|
|
1229
|
+
- Finding: ✅ Yes (delegates)
|
|
1230
|
+
- Searching: ✅ Yes (delegates)
|
|
1231
|
+
- Extending: ❌ No
|
|
1232
|
+
- Normalizing: ✅ Yes (delegates)
|
|
1233
|
+
- Selector Type: All types
|
|
1234
|
+
|
|
1235
|
+
**Notes:** Legacy compatibility layer. Good abstraction.
|
|
1236
|
+
|
|
1237
|
+
---
|
|
1238
|
+
|
|
1239
|
+
#### `combineKeys` (lines 1349-1367)
|
|
1240
|
+
**Responsibilities:**
|
|
1241
|
+
- Legacy combineKeys function for backward compatibility
|
|
1242
|
+
- Combines two key sets (Set or string)
|
|
1243
|
+
|
|
1244
|
+
**Calls:**
|
|
1245
|
+
- None (pure function)
|
|
1246
|
+
|
|
1247
|
+
**Concerns:**
|
|
1248
|
+
- Finding: ❌ No
|
|
1249
|
+
- Searching: ❌ No
|
|
1250
|
+
- Extending: ❌ No
|
|
1251
|
+
- Normalizing: ❌ No
|
|
1252
|
+
- Selector Type: N/A
|
|
1253
|
+
|
|
1254
|
+
**Notes:** Legacy utility. Simple function.
|
|
1255
|
+
|
|
1256
|
+
---
|
|
1257
|
+
|
|
1258
|
+
## Key Findings
|
|
1259
|
+
|
|
1260
|
+
### 1. Overlapping Concerns and Duplicate Code
|
|
1261
|
+
|
|
1262
|
+
#### Duplicate Functions
|
|
1263
|
+
- **`applyExtensionAtLocation`**, **`applyExtensionAtPath`**, **`applyExtension`**: These functions exist in BOTH `extend.ts` and `find-extendable-locations.ts` with identical implementations. This is clear duplication that should be consolidated.
|
|
1264
|
+
|
|
1265
|
+
#### Multiple Normalization Passes
|
|
1266
|
+
- **`createIsWrapper`** (lines 1380-1398): Makes THREE passes:
|
|
1267
|
+
1. `deduplicateSelectors()`
|
|
1268
|
+
2. `flattenGeneratedIs()`
|
|
1269
|
+
3. `deduplicateSelectors()` again
|
|
1270
|
+
|
|
1271
|
+
This could be consolidated into a single pass in `createProcessedSelector`.
|
|
1272
|
+
|
|
1273
|
+
#### Similar Search Logic
|
|
1274
|
+
- **`searchWithinCompoundSelector`** and **`trySmallCompoundExtendMatch`**: Both handle compound selector matching with similar logic. The fast path version is optimized for small compounds, but the logic is duplicated.
|
|
1275
|
+
|
|
1276
|
+
#### Similar Extension Logic
|
|
1277
|
+
- **`handlePartialModeExtension`** and **`handleCompoundFullExtend`**: Both handle compound selector extensions, but with different modes. Some logic could be shared.
|
|
1278
|
+
|
|
1279
|
+
---
|
|
1280
|
+
|
|
1281
|
+
### 2. Multiple Passes Through Selectors
|
|
1282
|
+
|
|
1283
|
+
#### Normalization Passes
|
|
1284
|
+
1. **`createProcessedSelector`**: Makes recursive passes through entire selector tree
|
|
1285
|
+
2. **`flattenGeneratedIs`**: Makes separate pass to flatten `:is()` wrappers
|
|
1286
|
+
3. **`deduplicateSelectors`**: Called multiple times in different contexts
|
|
1287
|
+
4. **`createIsWrapper`**: Makes multiple normalization passes
|
|
1288
|
+
|
|
1289
|
+
**Opportunity**: Consolidate all normalization into a single pass in `createProcessedSelector`.
|
|
1290
|
+
|
|
1291
|
+
#### Search Passes
|
|
1292
|
+
1. **`findExtendableLocations`**: Makes full recursive search
|
|
1293
|
+
2. **`extendSelector`**: May call `findExtendableLocations` multiple times (for SelectorList targets, for ampersand checking, for boundary crossing)
|
|
1294
|
+
3. **`handleCompoundFullExtend`**: Makes additional searches for `:is()` arguments
|
|
1295
|
+
|
|
1296
|
+
**Opportunity**: Cache search results to avoid re-searching the same selectors.
|
|
1297
|
+
|
|
1298
|
+
#### Extension Passes
|
|
1299
|
+
1. **`extendSelector`**: Processes SelectorList by iterating and extending each selector
|
|
1300
|
+
2. **`handlePartialModeExtension`**: Processes multiple component matches in complex selectors
|
|
1301
|
+
3. **`createProcessedSelector`**: Makes another pass for normalization
|
|
1302
|
+
|
|
1303
|
+
**Opportunity**: Combine extension and normalization into fewer passes.
|
|
1304
|
+
|
|
1305
|
+
---
|
|
1306
|
+
|
|
1307
|
+
### 3. Node Copying Issues
|
|
1308
|
+
|
|
1309
|
+
#### Multiple Copies
|
|
1310
|
+
- **`createProcessedSelector`** (line 219): Creates copy of each selector: `el = el.copy()`
|
|
1311
|
+
- **`replaceAmpersandWithItsValue`** (line 1658): Creates copy of selector
|
|
1312
|
+
- **`replaceAmpersandWithEmpty`** (line 1684): Creates copy of selector
|
|
1313
|
+
- **`extendSelector`** (lines 804, 808, 813): Creates clones to avoid object reference issues
|
|
1314
|
+
- **`markSelectorForHoisting`** (line 1780): Creates copy
|
|
1315
|
+
|
|
1316
|
+
**Issue**: The same node may be copied multiple times in a single extend operation, especially when processing SelectorList targets.
|
|
1317
|
+
|
|
1318
|
+
**Opportunity**: Use a copy-on-write strategy or track which nodes have been copied to avoid duplicate copies.
|
|
1319
|
+
|
|
1320
|
+
---
|
|
1321
|
+
|
|
1322
|
+
### 4. `.foo.foo` Bug Analysis
|
|
1323
|
+
|
|
1324
|
+
#### Bug Description
|
|
1325
|
+
When a selector like `.foo.foo` is extended with a partial match targeting `.foo`, only the first `.foo` gets replaced, not both.
|
|
1326
|
+
|
|
1327
|
+
#### Potential Bug Locations
|
|
1328
|
+
|
|
1329
|
+
1. **`extendSelector`** (lines 770-827): When processing SelectorList targets, it only processes the first match per selector. If `.foo.foo` has two `.foo` matches, only the first one gets extended.
|
|
1330
|
+
|
|
1331
|
+
2. **`handlePartialModeExtension`** (lines 1156-1220): Only handles the first match location passed in. If multiple components match (like `.foo.foo`), only the first one gets wrapped in `:is()`.
|
|
1332
|
+
|
|
1333
|
+
3. **`handleCompoundFullExtend`** (line 1324): Single loop processes components one at a time. If `.foo.foo` has two `.foo` components, it will only extend the first one it encounters.
|
|
1334
|
+
|
|
1335
|
+
4. **`searchWithinCompoundSelector`** (lines 551-572): Finds matches for both `.foo` components, but the location path is `[...currentPath]` (the compound itself), not `[...currentPath, i]` (the specific component). This means both matches have the same path, and the caller may only process one.
|
|
1336
|
+
|
|
1337
|
+
5. **`tryFastPathExtendMatch`** (lines 191-219): Fast path 3 finds matches for both `.foo` components, but the caller may only process the first one.
|
|
1338
|
+
|
|
1339
|
+
6. **`trySmallCompoundExtendMatch`** (lines 429-461): When checking for subset matching, it only returns ONE location (the compound itself), not locations for each matching component.
|
|
1340
|
+
|
|
1341
|
+
#### Root Cause
|
|
1342
|
+
The search functions (`findExtendableLocations`, `searchWithinCompoundSelector`, etc.) correctly find ALL matching locations, including multiple matches for the same component in a compound selector. However, the extension functions (`extendSelector`, `handlePartialModeExtension`, etc.) only process the FIRST location or the first match per selector.
|
|
1343
|
+
|
|
1344
|
+
#### Solution
|
|
1345
|
+
The extension functions need to process ALL matching locations, not just the first one. For compound selectors with duplicate components, each matching component should get its own location with a unique path (e.g., `[0]` for first `.foo`, `[1]` for second `.foo`).
|
|
1346
|
+
|
|
1347
|
+
---
|
|
1348
|
+
|
|
1349
|
+
### 5. Function Responsibility Issues
|
|
1350
|
+
|
|
1351
|
+
#### Too Many Responsibilities
|
|
1352
|
+
- **`extendSelector`**: Handles routing, SelectorList iteration, ampersand checking, boundary crossing, partial/full mode, location selection, and delegation to handlers. This function is doing too much.
|
|
1353
|
+
|
|
1354
|
+
#### Unclear Separation
|
|
1355
|
+
- **`handlePartialModeExtension`** vs **`handleFullExtend`**: Both handle extensions but with different modes. The separation is clear, but some logic could be shared.
|
|
1356
|
+
|
|
1357
|
+
#### Mixed Concerns
|
|
1358
|
+
- **`createIsWrapper`**: Handles both construction AND normalization (deduplication, flattening). Normalization should be separate.
|
|
1359
|
+
|
|
1360
|
+
---
|
|
1361
|
+
|
|
1362
|
+
## Recommendations
|
|
1363
|
+
|
|
1364
|
+
### High Priority
|
|
1365
|
+
|
|
1366
|
+
1. **Fix `.foo.foo` Bug**:
|
|
1367
|
+
- Ensure `searchWithinCompoundSelector` creates unique paths for each matching component (e.g., `[0]` vs `[1]`)
|
|
1368
|
+
- Update `extendSelector` and `handlePartialModeExtension` to process ALL matching locations, not just the first one
|
|
1369
|
+
- Test with `.foo.foo` extending `.foo` to ensure both components get extended
|
|
1370
|
+
|
|
1371
|
+
2. **Consolidate Duplicate Functions**:
|
|
1372
|
+
- Remove duplicate `applyExtensionAtLocation`, `applyExtensionAtPath`, and `applyExtension` from `find-extendable-locations.ts`
|
|
1373
|
+
- Import from `extend.ts` instead
|
|
1374
|
+
|
|
1375
|
+
3. **Consolidate Normalization Passes**:
|
|
1376
|
+
- Move all normalization logic from `createIsWrapper` into `createProcessedSelector`
|
|
1377
|
+
- Ensure `createProcessedSelector` handles deduplication, flattening, and ampersand resolution in a single pass
|
|
1378
|
+
- Remove redundant `deduplicateSelectors` calls
|
|
1379
|
+
|
|
1380
|
+
### Medium Priority
|
|
1381
|
+
|
|
1382
|
+
4. **Reduce Node Copying**:
|
|
1383
|
+
- Implement copy-on-write strategy
|
|
1384
|
+
- Track which nodes have been copied to avoid duplicate copies
|
|
1385
|
+
- Only copy nodes when they're actually modified
|
|
1386
|
+
|
|
1387
|
+
5. **Cache Search Results**:
|
|
1388
|
+
- Cache `findExtendableLocations` results to avoid re-searching the same selectors
|
|
1389
|
+
- Especially important for SelectorList targets and ampersand checking
|
|
1390
|
+
|
|
1391
|
+
6. **Split `extendSelector`**:
|
|
1392
|
+
- Extract SelectorList handling into separate function
|
|
1393
|
+
- Extract location selection logic into separate function
|
|
1394
|
+
- Extract ampersand checking into separate function (already exists, but integrate better)
|
|
1395
|
+
- Make `extendSelector` a cleaner orchestrator
|
|
1396
|
+
|
|
1397
|
+
### Low Priority
|
|
1398
|
+
|
|
1399
|
+
7. **Share Logic Between Partial and Full Modes**:
|
|
1400
|
+
- Extract common extension logic from `handlePartialModeExtension` and `handleFullExtend`
|
|
1401
|
+
- Create shared helper functions for common patterns
|
|
1402
|
+
|
|
1403
|
+
8. **Optimize Fast Path**:
|
|
1404
|
+
- Ensure fast path handles `.foo.foo` cases correctly
|
|
1405
|
+
- Add fast path for duplicate component matching
|
|
1406
|
+
|
|
1407
|
+
9. **Remove Unused Functions**:
|
|
1408
|
+
- Remove `isValidCompoundSelector` (replaced by `validateCompoundSelector`)
|
|
1409
|
+
- Remove `createValidatedIsWrapper` and `createValidatedCompoundSelector` if fallback behavior is not needed
|
|
1410
|
+
|
|
1411
|
+
---
|
|
1412
|
+
|
|
1413
|
+
## Test Baseline
|
|
1414
|
+
|
|
1415
|
+
Before making changes, run all extend tests to establish a baseline:
|
|
1416
|
+
|
|
1417
|
+
```bash
|
|
1418
|
+
cd packages/core && pnpm test -- --run extend
|
|
1419
|
+
```
|
|
1420
|
+
|
|
1421
|
+
This will help identify any regressions introduced by refactoring.
|
|
1422
|
+
|
|
1423
|
+
---
|
|
1424
|
+
|
|
1425
|
+
## Next Steps
|
|
1426
|
+
|
|
1427
|
+
1. Run test baseline
|
|
1428
|
+
2. Fix `.foo.foo` bug (highest priority)
|
|
1429
|
+
3. Consolidate duplicate functions
|
|
1430
|
+
4. Consolidate normalization passes
|
|
1431
|
+
5. Reduce node copying
|
|
1432
|
+
6. Cache search results
|
|
1433
|
+
7. Split `extendSelector` for better maintainability
|