@jesscss/core 2.0.0-alpha.4 → 2.0.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 -94
- package/lib/tree/ampersand.d.ts.map +0 -1
- package/lib/tree/ampersand.js +0 -269
- 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,773 @@
|
|
|
1
|
+
// errors.ts
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { type IRecognitionException, type ILexingResult } from '@chevrotain/types';
|
|
5
|
+
import type { TreeContext } from './context.js';
|
|
6
|
+
import type { OptionalLocation } from './tree/node.js';
|
|
7
|
+
import type { Deprecation } from './deprecation.js';
|
|
8
|
+
|
|
9
|
+
type JessFile = TreeContext['file'];
|
|
10
|
+
|
|
11
|
+
/** Minimal shape for passing context and a node to helpers. */
|
|
12
|
+
export type TreeContextLike = { file: JessFile };
|
|
13
|
+
|
|
14
|
+
/** Node type carrying a `location` (full span, empty tuple, or unset). */
|
|
15
|
+
export type LocNode = { location?: OptionalLocation };
|
|
16
|
+
|
|
17
|
+
type Phase = 'parse' | 'resolve' | 'import' | 'eval' | 'extend' | 'plugin';
|
|
18
|
+
type Severity = 'error' | 'warn';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Normalized error format for all phases (lexing, parsing, evaluation).
|
|
22
|
+
* This is the format returned by safeParse/safeRender methods.
|
|
23
|
+
*/
|
|
24
|
+
export interface ErrorDiagnostic {
|
|
25
|
+
code: string;
|
|
26
|
+
phase: Phase;
|
|
27
|
+
message: string;
|
|
28
|
+
reason: string;
|
|
29
|
+
fix: string;
|
|
30
|
+
note?: string;
|
|
31
|
+
|
|
32
|
+
// File location information
|
|
33
|
+
file?: {
|
|
34
|
+
name: string;
|
|
35
|
+
path: string;
|
|
36
|
+
fullPath: string;
|
|
37
|
+
source?: string;
|
|
38
|
+
};
|
|
39
|
+
filePath?: string;
|
|
40
|
+
line: number;
|
|
41
|
+
column: number;
|
|
42
|
+
/**
|
|
43
|
+
* Relevant source lines for code frame display.
|
|
44
|
+
* Keys are line numbers (1-indexed), values are the line content.
|
|
45
|
+
* Includes the error line and context lines (before/after).
|
|
46
|
+
* Example: { 55: 'before line', 56: 'error line', 57: 'after line' }
|
|
47
|
+
*/
|
|
48
|
+
lines?: Record<number, string>;
|
|
49
|
+
|
|
50
|
+
// Raw error data (for parser/lexer errors)
|
|
51
|
+
errors?: IRecognitionException[];
|
|
52
|
+
lexerErrors?: ILexingResult['errors'];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Normalized warning format for all phases (lexing, parsing, evaluation).
|
|
57
|
+
* This is the format returned by safeParse/safeRender methods.
|
|
58
|
+
*/
|
|
59
|
+
export interface WarningDiagnostic {
|
|
60
|
+
code: string;
|
|
61
|
+
phase: Phase;
|
|
62
|
+
message: string;
|
|
63
|
+
reason: string;
|
|
64
|
+
fix: string;
|
|
65
|
+
note?: string;
|
|
66
|
+
|
|
67
|
+
// File location information
|
|
68
|
+
file?: {
|
|
69
|
+
name: string;
|
|
70
|
+
path: string;
|
|
71
|
+
fullPath: string;
|
|
72
|
+
// Note: source is NOT included - use 'lines' property for code frame display
|
|
73
|
+
};
|
|
74
|
+
filePath?: string;
|
|
75
|
+
line: number;
|
|
76
|
+
column: number;
|
|
77
|
+
endLine?: number;
|
|
78
|
+
endColumn?: number;
|
|
79
|
+
/**
|
|
80
|
+
* Relevant source lines for code frame display.
|
|
81
|
+
* Keys are line numbers (1-indexed), values are the line content.
|
|
82
|
+
* Includes the warning line and context lines (before/after).
|
|
83
|
+
* Example: { 55: 'before line', 56: 'warning line', 57: 'after line' }
|
|
84
|
+
*/
|
|
85
|
+
lines?: Record<number, string>;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Initialization bag for a diagnostic.
|
|
90
|
+
* Prefer passing `ctx` + `node` so file/line/column/source are auto-wired.
|
|
91
|
+
* If those aren’t available, provide `filePath`/`source`/`line`/`column` directly.
|
|
92
|
+
*/
|
|
93
|
+
export type JessErrorInit = {
|
|
94
|
+
severity?: Severity;
|
|
95
|
+
code: string;
|
|
96
|
+
phase: Phase;
|
|
97
|
+
|
|
98
|
+
/** Optional: auto-wire file/line/col/source from compiler context + node */
|
|
99
|
+
ctx?: TreeContextLike;
|
|
100
|
+
node?: LocNode;
|
|
101
|
+
|
|
102
|
+
/** Manual overrides if ctx/node aren’t provided */
|
|
103
|
+
filePath?: string;
|
|
104
|
+
source?: string;
|
|
105
|
+
line?: number;
|
|
106
|
+
column?: number;
|
|
107
|
+
|
|
108
|
+
/** Interpolation values for the selected template */
|
|
109
|
+
meta?: Record<string, unknown>;
|
|
110
|
+
|
|
111
|
+
/** Optional overrides for the template’s strings */
|
|
112
|
+
summary?: string;
|
|
113
|
+
reason?: string;
|
|
114
|
+
fix?: string;
|
|
115
|
+
|
|
116
|
+
/** Optional one-liner for extra context */
|
|
117
|
+
note?: string;
|
|
118
|
+
|
|
119
|
+
/** Optional overrides for the template’s strings */
|
|
120
|
+
errors?: IRecognitionException[];
|
|
121
|
+
lexerErrors?: ILexingResult['errors'];
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
/* =========================
|
|
125
|
+
* Template registry
|
|
126
|
+
* ========================= */
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Template record for codes.
|
|
130
|
+
* Keep these short and actionable. Use `${placeholders}` for meta fields.
|
|
131
|
+
*/
|
|
132
|
+
type Template = { summary: string; reason: string; fix: string };
|
|
133
|
+
|
|
134
|
+
/* eslint-disable @typescript-eslint/naming-convention */
|
|
135
|
+
const TEMPLATES = {
|
|
136
|
+
// Parse/Lex
|
|
137
|
+
'parse/unexpected-token': {
|
|
138
|
+
summary: 'Unexpected token',
|
|
139
|
+
reason: 'Token "${token}" is not valid here.',
|
|
140
|
+
fix: 'Check for a missing quote/comma or wrong operator.'
|
|
141
|
+
},
|
|
142
|
+
'parse/unterminated-string': {
|
|
143
|
+
summary: 'Unterminated string',
|
|
144
|
+
reason: 'Missing closing quote.',
|
|
145
|
+
fix: 'Close the string, e.g. url("hero.jpg").'
|
|
146
|
+
},
|
|
147
|
+
'parse/unexpected-syntax': {
|
|
148
|
+
summary: 'Unexpected syntax',
|
|
149
|
+
reason: 'Expected ${expected}, got ${got}.',
|
|
150
|
+
fix: 'Add the expected token or remove the unexpected one.'
|
|
151
|
+
},
|
|
152
|
+
'parse/syntax-error': {
|
|
153
|
+
summary: 'Syntax error',
|
|
154
|
+
reason: '${message}',
|
|
155
|
+
fix: 'Check surrounding tokens near this location.'
|
|
156
|
+
},
|
|
157
|
+
|
|
158
|
+
// Resolve/Import
|
|
159
|
+
'resolve/name-not-found': {
|
|
160
|
+
summary: 'Name not found',
|
|
161
|
+
reason: 'Symbol "${symbol}" is undefined in this scope.',
|
|
162
|
+
fix: 'Define "${symbol}" or import a file that provides it.'
|
|
163
|
+
},
|
|
164
|
+
'import/circular-compose': {
|
|
165
|
+
summary: 'Circular @-compose detected',
|
|
166
|
+
reason: '${chain}',
|
|
167
|
+
fix: 'Break the cycle (extract shared bits and compose that).'
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
// Eval
|
|
171
|
+
'eval/bad-call-arity': {
|
|
172
|
+
summary: 'Bad call: wrong arity',
|
|
173
|
+
reason: '${callee} expects ${expectedCount} args, got ${gotCount}.',
|
|
174
|
+
fix: 'Add/remove arguments to match the signature.'
|
|
175
|
+
},
|
|
176
|
+
'eval/type-mismatch': {
|
|
177
|
+
summary: 'Type mismatch',
|
|
178
|
+
reason: '${callee} expects ${expected}, got ${got}.',
|
|
179
|
+
fix: 'Pass a ${expected}; convert or choose a compatible value.'
|
|
180
|
+
},
|
|
181
|
+
|
|
182
|
+
// Extend
|
|
183
|
+
'extend/protected-boundary': {
|
|
184
|
+
summary: 'Extend blocked by protected boundary',
|
|
185
|
+
reason: '"${target}" is defined behind a protected compose boundary.',
|
|
186
|
+
fix: 'Move "${target}" to a shared file or create a local shim.'
|
|
187
|
+
},
|
|
188
|
+
'extend/not-found': {
|
|
189
|
+
summary: 'Extend target "${target}" not found',
|
|
190
|
+
reason: 'No ruleset found matching "${target}" in accessible extend roots.',
|
|
191
|
+
fix: 'Ensure "${target}" exists and is accessible from the current extend root.'
|
|
192
|
+
},
|
|
193
|
+
'extend/not-accessible': {
|
|
194
|
+
summary: 'Extend target "${target}" not accessible',
|
|
195
|
+
reason: '"${target}" exists but is not accessible from the current extend root (blocked by at-rule or compose boundary).',
|
|
196
|
+
fix: 'Move the extend or the target to a shared extend root, or use a different approach.'
|
|
197
|
+
},
|
|
198
|
+
|
|
199
|
+
// Plugin
|
|
200
|
+
'plugin/unsupported-feature': {
|
|
201
|
+
summary: 'Unsupported feature',
|
|
202
|
+
reason: 'Plugin "${plugin}" does not implement ${feature}.',
|
|
203
|
+
fix: 'Use a supported alternative or enable a fallback.'
|
|
204
|
+
},
|
|
205
|
+
|
|
206
|
+
// ---------- Warnings (examples you can expand) ----------
|
|
207
|
+
'eval/deprecated': {
|
|
208
|
+
summary: 'Deprecated feature',
|
|
209
|
+
reason: '"${what}" is deprecated.',
|
|
210
|
+
fix: 'Use "${use}" instead.'
|
|
211
|
+
},
|
|
212
|
+
'resolve/unused-variable': {
|
|
213
|
+
summary: 'Unused variable',
|
|
214
|
+
reason: '"${symbol}" is declared but its value is never used.',
|
|
215
|
+
fix: 'Remove it or prefix with "_" to silence.'
|
|
216
|
+
},
|
|
217
|
+
'selector/duplicate': {
|
|
218
|
+
summary: 'Duplicate selector',
|
|
219
|
+
reason: 'Selector "${selector}" is defined multiple times.',
|
|
220
|
+
fix: 'Consolidate rules or remove the duplicate.'
|
|
221
|
+
}
|
|
222
|
+
} satisfies Record<string, Template>;
|
|
223
|
+
/* eslint-enable @typescript-eslint/naming-convention */
|
|
224
|
+
|
|
225
|
+
export type JessErrorCode = keyof typeof TEMPLATES;
|
|
226
|
+
|
|
227
|
+
export function isJessErrorCode(code: string): code is JessErrorCode {
|
|
228
|
+
return Object.hasOwn(TEMPLATES, code);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Replaces `${key}` with values from `meta`. Unset keys render as `<key>`.
|
|
233
|
+
*/
|
|
234
|
+
function interpolate(s: string, meta: Record<string, unknown>): string {
|
|
235
|
+
return s.replace(/\$\{(\w+)\}/g, (_: string, k: string) => String(meta[k] ?? `<${k}>`));
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/* =========================
|
|
239
|
+
* OSC-8 hyperlinks
|
|
240
|
+
* ========================= */
|
|
241
|
+
|
|
242
|
+
function osc8(uri: string, label: string): string {
|
|
243
|
+
return `\x1b]8;;${uri}\x1b\\${label}\x1b]8;;\x1b\\`;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function supportsLinks(): boolean {
|
|
247
|
+
const tty = process.stderr.isTTY && process.env.TERM !== 'dumb';
|
|
248
|
+
if (!tty) {
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
return Boolean(
|
|
252
|
+
process.env.TERM_PROGRAM === 'vscode'
|
|
253
|
+
|| process.env.ITERM_SESSION_ID
|
|
254
|
+
|| process.env.WT_SESSION
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function linkFor(abs: string, line: number, col: number, label: string): string {
|
|
259
|
+
const uri = `vscode://file/${abs}:${line}:${col}`;
|
|
260
|
+
return supportsLinks() ? osc8(uri, label) : label;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/* =========================
|
|
264
|
+
* Path labeling (human-short)
|
|
265
|
+
* ========================= */
|
|
266
|
+
|
|
267
|
+
function trail(p: string, n: number): string {
|
|
268
|
+
const parts = p.split(path.sep).filter(Boolean);
|
|
269
|
+
return (parts.length <= n ? parts : ['…', ...parts.slice(parts.length - n)]).join(path.sep);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
function prettyLabel(abs: string, line: number, col: number): string {
|
|
273
|
+
const rel = path.relative(process.cwd(), abs);
|
|
274
|
+
const shown = (!rel.startsWith('..') && !path.isAbsolute(rel)) ? rel : trail(abs, 3);
|
|
275
|
+
return `${shown}:${line}:${col}`;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/* =========================
|
|
279
|
+
* Code-frame utilities
|
|
280
|
+
* ========================= */
|
|
281
|
+
|
|
282
|
+
function buildLineStarts(src: string): Uint32Array {
|
|
283
|
+
const starts: number[] = [0];
|
|
284
|
+
for (let i = 0; i < src.length; i++) {
|
|
285
|
+
const ch = src.charCodeAt(i);
|
|
286
|
+
if (ch === 10) {
|
|
287
|
+
starts.push(i + 1);
|
|
288
|
+
} else if (ch === 13) {
|
|
289
|
+
if (src.charCodeAt(i + 1) === 10) {
|
|
290
|
+
i++;
|
|
291
|
+
}
|
|
292
|
+
starts.push(i + 1);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return Uint32Array.from(starts);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Extracts relevant source lines for code frame display.
|
|
300
|
+
* Returns an object with line numbers as keys (1-indexed) and line content as values.
|
|
301
|
+
* Includes the target line and context lines (before/after).
|
|
302
|
+
* @param source - Full source code
|
|
303
|
+
* @param line - Target line number (1-indexed)
|
|
304
|
+
* @param contextLines - Number of context lines before/after (default: 1)
|
|
305
|
+
* @returns Object with line numbers as keys, e.g. { 55: 'before', 56: 'error', 57: 'after' }
|
|
306
|
+
*/
|
|
307
|
+
export function extractRelevantLines(
|
|
308
|
+
source: string | undefined,
|
|
309
|
+
line: number,
|
|
310
|
+
contextLines: number = 1
|
|
311
|
+
): Record<number, string> | undefined {
|
|
312
|
+
if (!source) {
|
|
313
|
+
return undefined;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Split source into lines once
|
|
317
|
+
const lines = source.split(/\r?\n/);
|
|
318
|
+
const totalLines = lines.length;
|
|
319
|
+
const targetLine = Math.max(1, Math.min(line, totalLines));
|
|
320
|
+
|
|
321
|
+
// Calculate line range (1-indexed)
|
|
322
|
+
const startLine = Math.max(1, targetLine - contextLines);
|
|
323
|
+
const endLine = Math.min(totalLines, targetLine + contextLines);
|
|
324
|
+
|
|
325
|
+
// Extract relevant lines
|
|
326
|
+
const result: Record<number, string> = {};
|
|
327
|
+
for (let i = startLine; i <= endLine; i++) {
|
|
328
|
+
result[i] = lines[i - 1]!; // Convert to 0-indexed for array access
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
return result;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
function ensureLineStarts(file: JessFile): Uint32Array | undefined {
|
|
335
|
+
if (!file?.source) {
|
|
336
|
+
return undefined;
|
|
337
|
+
}
|
|
338
|
+
// Your file type may already have `lines`; if not, store it there.
|
|
339
|
+
if (!file.lines) {
|
|
340
|
+
file.lines = buildLineStarts(file.source);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
return file.lines as Uint32Array;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
function getLine(file: JessFile, line: number): string {
|
|
347
|
+
const src = file?.source;
|
|
348
|
+
const idx = ensureLineStarts(file);
|
|
349
|
+
if (!src || !idx || line < 1 || line > idx.length) {
|
|
350
|
+
return '';
|
|
351
|
+
}
|
|
352
|
+
const start = idx[line - 1];
|
|
353
|
+
const end = line < idx.length ? idx[line]! - 1 : src.length;
|
|
354
|
+
const last = src.charCodeAt(end - 1);
|
|
355
|
+
const realEnd = last === 13 ? end - 1 : end; // trim trailing \r
|
|
356
|
+
return src.slice(start, realEnd);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
function codeFrameFromFile(file: JessFile, line = 1, col = 1): string {
|
|
360
|
+
if (!file?.source) {
|
|
361
|
+
return '';
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
ensureLineStarts(file);
|
|
365
|
+
|
|
366
|
+
const width = String(line).length;
|
|
367
|
+
const num = (n: number) => String(n).padStart(width, ' ');
|
|
368
|
+
const caret = ' '.repeat(Math.max(0, col - 1)) + '^';
|
|
369
|
+
|
|
370
|
+
const prev = getLine(file, line - 1);
|
|
371
|
+
const curr = getLine(file, line);
|
|
372
|
+
const next = getLine(file, line + 1);
|
|
373
|
+
|
|
374
|
+
let out = '';
|
|
375
|
+
if (prev) {
|
|
376
|
+
out += chalk.gray(`${num(line - 1)} | ${prev}\n`);
|
|
377
|
+
}
|
|
378
|
+
out += chalk.bold(`${num(line)} | ${curr}\n`);
|
|
379
|
+
out += chalk.gray(` ${' '.repeat(width)} | `) + chalk.red(caret) + '\n';
|
|
380
|
+
if (next) {
|
|
381
|
+
out += chalk.gray(`${num(line + 1)} | ${next}\n`);
|
|
382
|
+
}
|
|
383
|
+
return out;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/* =========================
|
|
387
|
+
* Diagnostic (error or warn)
|
|
388
|
+
* ========================= */
|
|
389
|
+
|
|
390
|
+
export class JessError extends Error {
|
|
391
|
+
severity: Severity = 'error';
|
|
392
|
+
code: keyof typeof TEMPLATES = 'parse/syntax-error';
|
|
393
|
+
phase: Phase = 'parse';
|
|
394
|
+
|
|
395
|
+
// Resolved source context (fileObj preferred; filePath is legacy)
|
|
396
|
+
fileObj?: JessFile;
|
|
397
|
+
filePath?: string;
|
|
398
|
+
line = 1;
|
|
399
|
+
column = 1;
|
|
400
|
+
source?: string;
|
|
401
|
+
node?: LocNode; // Store node to extract endLine/endColumn
|
|
402
|
+
|
|
403
|
+
reason = '';
|
|
404
|
+
fix = '';
|
|
405
|
+
note?: string;
|
|
406
|
+
|
|
407
|
+
errors?: IRecognitionException[];
|
|
408
|
+
lexerErrors?: ILexingResult['errors'];
|
|
409
|
+
|
|
410
|
+
constructor(init: JessErrorInit) {
|
|
411
|
+
// Resolve context from ctx/node first, else from explicit fields.
|
|
412
|
+
const fileObj = init.ctx?.file;
|
|
413
|
+
const abs = fileObj?.fullPath ?? init.filePath;
|
|
414
|
+
const line = init.node?.location?.[1] ?? init.line ?? 1;
|
|
415
|
+
const column = init.node?.location?.[2] ?? init.column ?? 1;
|
|
416
|
+
const source = fileObj?.source ?? init.source;
|
|
417
|
+
|
|
418
|
+
const code = isJessErrorCode(init.code) ? init.code : 'parse/syntax-error';
|
|
419
|
+
const meta = init.meta ?? {};
|
|
420
|
+
const t = TEMPLATES[code];
|
|
421
|
+
|
|
422
|
+
const summary = init.summary ?? interpolate(t.summary, meta);
|
|
423
|
+
const reason = init.reason ?? interpolate(t.reason, meta);
|
|
424
|
+
const fix = init.fix ?? interpolate(t.fix, meta);
|
|
425
|
+
|
|
426
|
+
super(summary);
|
|
427
|
+
|
|
428
|
+
this.name = 'JessError';
|
|
429
|
+
this.severity = init.severity ?? 'error';
|
|
430
|
+
this.code = code;
|
|
431
|
+
this.phase = init.phase;
|
|
432
|
+
|
|
433
|
+
this.fileObj = fileObj;
|
|
434
|
+
this.filePath = abs;
|
|
435
|
+
this.line = line;
|
|
436
|
+
this.column = column;
|
|
437
|
+
this.source = source;
|
|
438
|
+
this.node = init.node; // Store node for endLine/endColumn extraction
|
|
439
|
+
|
|
440
|
+
this.reason = reason;
|
|
441
|
+
this.fix = fix;
|
|
442
|
+
this.note = init.note;
|
|
443
|
+
|
|
444
|
+
this.errors = init.errors;
|
|
445
|
+
this.lexerErrors = init.lexerErrors;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/** Lightweight JSON for serializers (e.g. Vitest). Strips heavy Chevrotain token trees and full source. */
|
|
449
|
+
toJSON() {
|
|
450
|
+
return {
|
|
451
|
+
severity: this.severity,
|
|
452
|
+
code: this.code,
|
|
453
|
+
phase: this.phase,
|
|
454
|
+
fileObj: this.fileObj
|
|
455
|
+
? { name: this.fileObj.name, path: this.fileObj.path, fullPath: this.fileObj.fullPath }
|
|
456
|
+
: undefined,
|
|
457
|
+
filePath: this.filePath,
|
|
458
|
+
reason: this.reason,
|
|
459
|
+
fix: this.fix,
|
|
460
|
+
note: this.note,
|
|
461
|
+
errors: this.errors?.map(e => ({ message: e.message, stack: e.stack })),
|
|
462
|
+
lexerErrors: this.lexerErrors?.map(e => ({ message: e.message, line: e.line, column: e.column }))
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/** Pretty, clickable string for terminal/Problems panel. */
|
|
467
|
+
override toString(): string {
|
|
468
|
+
const abs = this.fileObj?.fullPath ?? this.filePath;
|
|
469
|
+
const l = this.line ?? 1;
|
|
470
|
+
const c = this.column ?? 1;
|
|
471
|
+
const label = abs ? prettyLabel(abs, l, c) : '(unknown)';
|
|
472
|
+
const clickable = abs ? linkFor(abs, l, c, label) : label;
|
|
473
|
+
|
|
474
|
+
const color = this.severity === 'warn' ? chalk.yellow : chalk.red;
|
|
475
|
+
|
|
476
|
+
const header =
|
|
477
|
+
`${color(this.severity)} ${color(this.code)} `
|
|
478
|
+
+ `${chalk.gray(`[${this.phase}]`)} ${chalk.cyan(clickable)} `
|
|
479
|
+
+ `${chalk.white('— ' + this.message)}`;
|
|
480
|
+
|
|
481
|
+
let frame = '';
|
|
482
|
+
if (this.fileObj?.source) {
|
|
483
|
+
frame = codeFrameFromFile(this.fileObj, l, c);
|
|
484
|
+
} else if (this.source) {
|
|
485
|
+
// Legacy, slower fallback
|
|
486
|
+
const lines = this.source.split(/\r?\n/);
|
|
487
|
+
const prev = lines[l - 2];
|
|
488
|
+
const curr = lines[l - 1] ?? '';
|
|
489
|
+
const next = lines[l];
|
|
490
|
+
const width = String(l).length;
|
|
491
|
+
const num = (n: number) => String(n).padStart(width, ' ');
|
|
492
|
+
const caret = ' '.repeat(Math.max(0, c - 1)) + '^';
|
|
493
|
+
if (prev) {
|
|
494
|
+
frame += chalk.gray(`${num(l - 1)} | ${prev}\n`);
|
|
495
|
+
}
|
|
496
|
+
frame += chalk.bold(`${num(l)} | ${curr}\n`);
|
|
497
|
+
frame += chalk.gray(` ${' '.repeat(width)} | `) + chalk.red(caret) + '\n';
|
|
498
|
+
if (next) {
|
|
499
|
+
frame += chalk.gray(`${num(l + 1)} | ${next}\n`);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
const out = [
|
|
504
|
+
header,
|
|
505
|
+
frame && frame.trimEnd(),
|
|
506
|
+
'',
|
|
507
|
+
`Reason: ${this.reason}`,
|
|
508
|
+
`Fix: ${this.fix}`,
|
|
509
|
+
this.note ? `Note: ${this.note}` : undefined,
|
|
510
|
+
(!supportsLinks() && abs) ? chalk.dim(`Path: ${abs}:${l}:${c}`) : undefined
|
|
511
|
+
]
|
|
512
|
+
.filter(Boolean)
|
|
513
|
+
.join('\n');
|
|
514
|
+
|
|
515
|
+
return out;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/* =========================
|
|
520
|
+
* Printing helpers
|
|
521
|
+
* ========================= */
|
|
522
|
+
|
|
523
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
524
|
+
const _seen = new Set<string>();
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* Emits a diagnostic to stderr (or a custom stream).
|
|
528
|
+
* Set `dedupe: true` to suppress repeats from the same location/message.
|
|
529
|
+
*/
|
|
530
|
+
export function emit(diag: JessError, opts?: { stream?: NodeJS.WriteStream; dedupe?: boolean }): void {
|
|
531
|
+
const stream = opts?.stream ?? process.stderr;
|
|
532
|
+
if (opts?.dedupe) {
|
|
533
|
+
const abs = diag.fileObj?.fullPath ?? diag.filePath ?? '';
|
|
534
|
+
const key = `${diag.severity}|${diag.code}|${abs}|${diag.line}|${diag.column}|${diag.message}`;
|
|
535
|
+
if (_seen.has(key)) {
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
_seen.add(key);
|
|
539
|
+
}
|
|
540
|
+
stream.write(String(diag) + '\n');
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
/** Clears the in-process de-duplication set. Useful for tests. */
|
|
544
|
+
export function resetDedupe(): void {
|
|
545
|
+
_seen.clear();
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
/* =========================
|
|
549
|
+
* Factories / Public API
|
|
550
|
+
* ========================= */
|
|
551
|
+
|
|
552
|
+
export function makeJessError(init: JessErrorInit): JessError {
|
|
553
|
+
return new JessError(init);
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
type Common = {
|
|
557
|
+
ctx?: TreeContextLike;
|
|
558
|
+
node?: LocNode;
|
|
559
|
+
|
|
560
|
+
filePath?: string;
|
|
561
|
+
source?: string;
|
|
562
|
+
line?: number;
|
|
563
|
+
column?: number;
|
|
564
|
+
|
|
565
|
+
note?: string;
|
|
566
|
+
summary?: string;
|
|
567
|
+
reason?: string;
|
|
568
|
+
fix?: string;
|
|
569
|
+
severity?: Severity;
|
|
570
|
+
|
|
571
|
+
meta?: Record<string, unknown>;
|
|
572
|
+
};
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* Primary **error** helpers.
|
|
576
|
+
* Each function returns a `JessError` ready to be thrown or emitted.
|
|
577
|
+
*/
|
|
578
|
+
export const ERR = {
|
|
579
|
+
// Parse/Lex
|
|
580
|
+
unexpectedToken(args: Common & { meta: { token: string } }) {
|
|
581
|
+
return makeJessError({ code: 'parse/unexpected-token', phase: 'parse', ...args });
|
|
582
|
+
},
|
|
583
|
+
|
|
584
|
+
unterminatedString(args: Common = {}) {
|
|
585
|
+
return makeJessError({ code: 'parse/unterminated-string', phase: 'parse', ...args });
|
|
586
|
+
},
|
|
587
|
+
|
|
588
|
+
// Resolve/Import
|
|
589
|
+
nameNotFound(args: Common & { meta: { symbol: string } }) {
|
|
590
|
+
return makeJessError({ code: 'resolve/name-not-found', phase: 'resolve', ...args });
|
|
591
|
+
},
|
|
592
|
+
|
|
593
|
+
circularCompose(args: Common & { meta: { chain: string } }) {
|
|
594
|
+
return makeJessError({ code: 'import/circular-compose', phase: 'import', ...args });
|
|
595
|
+
},
|
|
596
|
+
|
|
597
|
+
// Eval
|
|
598
|
+
arity(args: Common & { meta: { callee: string; expectedCount: number; gotCount: number } }) {
|
|
599
|
+
return makeJessError({ code: 'eval/bad-call-arity', phase: 'eval', ...args });
|
|
600
|
+
},
|
|
601
|
+
|
|
602
|
+
typeMismatch(args: Common & { meta: { callee: string; expected: string; got: string } }) {
|
|
603
|
+
return makeJessError({ code: 'eval/type-mismatch', phase: 'eval', ...args });
|
|
604
|
+
},
|
|
605
|
+
|
|
606
|
+
// Extend
|
|
607
|
+
extendBoundary(args: Common & { meta: { target: string } }) {
|
|
608
|
+
return makeJessError({ code: 'extend/protected-boundary', phase: 'extend', ...args });
|
|
609
|
+
},
|
|
610
|
+
|
|
611
|
+
extendNotFound(args: Common & { meta: { target: string } }) {
|
|
612
|
+
return makeJessError({ code: 'extend/not-found', phase: 'extend', ...args });
|
|
613
|
+
},
|
|
614
|
+
|
|
615
|
+
extendNotAccessible(args: Common & { meta: { target: string } }) {
|
|
616
|
+
return makeJessError({ code: 'extend/not-accessible', phase: 'extend', ...args });
|
|
617
|
+
},
|
|
618
|
+
|
|
619
|
+
// Plugin
|
|
620
|
+
pluginUnsupported(args: Common & { meta: { plugin: string; feature: string } }) {
|
|
621
|
+
return makeJessError({ code: 'plugin/unsupported-feature', phase: 'plugin', ...args });
|
|
622
|
+
}
|
|
623
|
+
};
|
|
624
|
+
|
|
625
|
+
/**
|
|
626
|
+
* Primary **warning** helpers.
|
|
627
|
+
* Same API shape as `ERR`, but default `severity: 'warn'`.
|
|
628
|
+
* Call `emit(WARN.*(...))` to log without throwing.
|
|
629
|
+
*/
|
|
630
|
+
export const WARN = {
|
|
631
|
+
deprecated(args: Common & { meta: { what: string; use: string; deprecation?: Deprecation } }) {
|
|
632
|
+
return makeJessError({ severity: 'warn', code: 'eval/deprecated', phase: 'eval', ...args });
|
|
633
|
+
},
|
|
634
|
+
|
|
635
|
+
unusedVar(args: Common & { meta: { symbol: string } }) {
|
|
636
|
+
return makeJessError({ severity: 'warn', code: 'resolve/unused-variable', phase: 'resolve', ...args });
|
|
637
|
+
},
|
|
638
|
+
|
|
639
|
+
duplicateSelector(args: Common & { meta: { selector: string } }) {
|
|
640
|
+
return makeJessError({ severity: 'warn', code: 'selector/duplicate', phase: 'extend', ...args });
|
|
641
|
+
},
|
|
642
|
+
|
|
643
|
+
extendNotFound(args: Common & { meta: { target: string } }) {
|
|
644
|
+
return makeJessError({ severity: 'warn', code: 'extend/not-found', phase: 'extend', ...args });
|
|
645
|
+
},
|
|
646
|
+
|
|
647
|
+
extendNotAccessible(args: Common & { meta: { target: string } }) {
|
|
648
|
+
return makeJessError({ severity: 'warn', code: 'extend/not-accessible', phase: 'extend', ...args });
|
|
649
|
+
}
|
|
650
|
+
};
|
|
651
|
+
|
|
652
|
+
/* =========================
|
|
653
|
+
* Chevrotain adapter
|
|
654
|
+
* ========================= */
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* Converts a Chevrotain parser/lexer error into a friendly diagnostic.
|
|
658
|
+
* If you pass `ctx`, the error will be clickable and include a code-frame.
|
|
659
|
+
*
|
|
660
|
+
* @param errors Chevrotain recognition errors
|
|
661
|
+
* @param lexerResult Chevrotain lexing result
|
|
662
|
+
* @param filePath Absolute path to the file (legacy fallback)
|
|
663
|
+
* @param source File contents (legacy fallback)
|
|
664
|
+
* @param ctx Optional TreeContext to auto-fill file/line/col/source
|
|
665
|
+
*/
|
|
666
|
+
export function getErrorFromParser(
|
|
667
|
+
errors: IRecognitionException[],
|
|
668
|
+
lexerErrors: ILexingResult['errors'] | undefined,
|
|
669
|
+
filePath: string,
|
|
670
|
+
source: string,
|
|
671
|
+
ctx?: TreeContextLike
|
|
672
|
+
): JessError {
|
|
673
|
+
const error = lexerErrors?.[0] ?? errors[0];
|
|
674
|
+
if (!error) {
|
|
675
|
+
return new JessError({ code: 'parse/syntax-error', phase: 'parse', filePath, source, ctx });
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
const isLex = !('token' in error);
|
|
679
|
+
|
|
680
|
+
const line =
|
|
681
|
+
'token' in error
|
|
682
|
+
? error.token?.startLine
|
|
683
|
+
: error.line;
|
|
684
|
+
|
|
685
|
+
const column =
|
|
686
|
+
'token' in error
|
|
687
|
+
? error.token?.startColumn
|
|
688
|
+
: error.column;
|
|
689
|
+
|
|
690
|
+
const message = error.message || '';
|
|
691
|
+
|
|
692
|
+
let code: keyof typeof TEMPLATES = 'parse/syntax-error';
|
|
693
|
+
let meta: Record<string, unknown> = {};
|
|
694
|
+
|
|
695
|
+
if (isLex) {
|
|
696
|
+
code = 'parse/unexpected-token';
|
|
697
|
+
meta = { token: ('char' in error ? String(error.char) : undefined) ?? '/' };
|
|
698
|
+
} else if (/unterminated|string not closed/i.test(message)) {
|
|
699
|
+
code = 'parse/unterminated-string';
|
|
700
|
+
} else if (/expecting/i.test(message)) {
|
|
701
|
+
code = 'parse/unexpected-syntax';
|
|
702
|
+
const m = message.match(/expecting\s+([^,]+).*?but found\s+'?([^']+)'?/i);
|
|
703
|
+
meta = m ? { expected: m[1], got: m[2] } : { expected: 'token', got: 'other' };
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
return new JessError({
|
|
707
|
+
code,
|
|
708
|
+
phase: 'parse',
|
|
709
|
+
meta,
|
|
710
|
+
ctx,
|
|
711
|
+
filePath,
|
|
712
|
+
source,
|
|
713
|
+
line: line ?? 1,
|
|
714
|
+
column: column ?? 1,
|
|
715
|
+
errors,
|
|
716
|
+
lexerErrors
|
|
717
|
+
});
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
/**
|
|
721
|
+
* Converts a JessError to a normalized ErrorDiagnostic or WarningDiagnostic.
|
|
722
|
+
* Extracts relevant source lines for code frame display.
|
|
723
|
+
*/
|
|
724
|
+
export function toDiagnostic(error: JessError): ErrorDiagnostic | WarningDiagnostic {
|
|
725
|
+
// Extract relevant lines from source (error line + context)
|
|
726
|
+
const lines = extractRelevantLines(error.source ?? error.fileObj?.source, error.line);
|
|
727
|
+
|
|
728
|
+
// Extract endLine/endColumn from node location if available
|
|
729
|
+
// Location format: [startOffset, startLine, startColumn, endOffset, endLine, endColumn]
|
|
730
|
+
const nodeLocation = error.node?.location;
|
|
731
|
+
const endLine = nodeLocation && nodeLocation.length >= 6
|
|
732
|
+
? nodeLocation[4]
|
|
733
|
+
: undefined;
|
|
734
|
+
const endColumn = nodeLocation && nodeLocation.length >= 6
|
|
735
|
+
? nodeLocation[5]
|
|
736
|
+
: undefined;
|
|
737
|
+
|
|
738
|
+
// Create file object without source (we only use 'lines' for code frames)
|
|
739
|
+
const file = error.fileObj
|
|
740
|
+
? {
|
|
741
|
+
name: error.fileObj.name,
|
|
742
|
+
path: error.fileObj.path,
|
|
743
|
+
fullPath: error.fileObj.fullPath
|
|
744
|
+
// Explicitly exclude source - we use 'lines' property instead
|
|
745
|
+
}
|
|
746
|
+
: undefined;
|
|
747
|
+
|
|
748
|
+
const base = {
|
|
749
|
+
code: error.code,
|
|
750
|
+
phase: error.phase,
|
|
751
|
+
message: error.message,
|
|
752
|
+
reason: error.reason,
|
|
753
|
+
fix: error.fix,
|
|
754
|
+
note: error.note,
|
|
755
|
+
file,
|
|
756
|
+
filePath: error.filePath,
|
|
757
|
+
line: error.line,
|
|
758
|
+
column: error.column,
|
|
759
|
+
endLine,
|
|
760
|
+
endColumn,
|
|
761
|
+
lines
|
|
762
|
+
};
|
|
763
|
+
|
|
764
|
+
if (error.severity === 'error') {
|
|
765
|
+
return {
|
|
766
|
+
...base,
|
|
767
|
+
errors: error.errors,
|
|
768
|
+
lexerErrors: error.lexerErrors
|
|
769
|
+
} as ErrorDiagnostic;
|
|
770
|
+
} else {
|
|
771
|
+
return base as WarningDiagnostic;
|
|
772
|
+
}
|
|
773
|
+
}
|