@jesscss/less-parser 2.0.0-alpha.6 → 2.0.0-alpha.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +149 -36
  2. package/lib/builders.d.ts +381 -0
  3. package/lib/builders.d.ts.map +1 -0
  4. package/lib/cst.cjs +14 -0
  5. package/lib/cst.d.ts +6 -0
  6. package/lib/cst.d.ts.map +1 -0
  7. package/lib/cst.js +12 -0
  8. package/lib/functional-parser.cjs +2654 -0
  9. package/lib/functional-parser.d.ts +18 -0
  10. package/lib/functional-parser.d.ts.map +1 -0
  11. package/lib/functional-parser.js +2589 -0
  12. package/lib/grammar.cjs +35057 -0
  13. package/lib/grammar.d.ts +2 -0
  14. package/lib/grammar.d.ts.map +1 -0
  15. package/lib/grammar.js +35056 -0
  16. package/lib/index.cjs +17 -4096
  17. package/lib/index.d.ts +9 -149
  18. package/lib/index.d.ts.map +1 -1
  19. package/lib/index.js +6 -4091
  20. package/lib/jess.cjs +3968 -0
  21. package/lib/jess.d.ts +7 -0
  22. package/lib/jess.d.ts.map +1 -0
  23. package/lib/jess.js +3962 -0
  24. package/lib/lessParser.d.ts +38 -0
  25. package/lib/lessParser.d.ts.map +1 -0
  26. package/lib/lessRecursiveParser.d.ts +99 -0
  27. package/lib/lessRecursiveParser.d.ts.map +1 -0
  28. package/lib/lessTokens.d.ts +23 -0
  29. package/lib/lessTokens.d.ts.map +1 -0
  30. package/lib/productions/guards.d.ts +113 -0
  31. package/lib/productions/guards.d.ts.map +1 -0
  32. package/lib/productions/index.d.ts +5 -0
  33. package/lib/productions/index.d.ts.map +1 -0
  34. package/lib/productions/root.d.ts +38 -0
  35. package/lib/productions/root.d.ts.map +1 -0
  36. package/lib/productions/selectors.d.ts +41 -0
  37. package/lib/productions/selectors.d.ts.map +1 -0
  38. package/lib/productions/values.d.ts +35 -0
  39. package/lib/productions/values.d.ts.map +1 -0
  40. package/lib/utils.d.ts +9 -0
  41. package/lib/utils.d.ts.map +1 -0
  42. package/package.json +40 -9
  43. package/src/__tests__/debug-log.ts +35 -0
  44. package/src/__tests__/wall5-parse.test.ts +67 -0
  45. package/src/builders.ts +3190 -0
  46. package/src/cst.ts +25 -0
  47. package/src/functional-parser.ts +162 -0
  48. package/src/grammar.ts +870 -0
  49. package/src/index.ts +19 -0
  50. package/src/jess.ts +6 -0
  51. package/src/lessParser.ts +120 -0
  52. package/src/lessRecursiveParser.ts +279 -0
  53. package/src/lessTokens.ts +350 -0
  54. package/src/productions/guards.ts +1066 -0
  55. package/src/productions/index.ts +29 -0
  56. package/src/productions/root.ts +1613 -0
  57. package/src/productions/selectors.ts +1309 -0
  58. package/src/productions/values.ts +1449 -0
  59. package/src/utils.ts +178 -0
  60. package/lib/index.d.cts +0 -150
  61. package/lib/index.d.cts.map +0 -1
  62. package/lib/index.js.map +0 -1
@@ -0,0 +1,67 @@
1
+ /* eslint-disable @typescript-eslint/no-unsafe-type-assertion -- test inspects parser tree internals structurally. */
2
+ import { describe, it, expect } from 'vitest';
3
+ import { Parser } from '../jess.js';
4
+
5
+ /**
6
+ * Bootstrap wall-5: `-(@gutter / 2)` (grid mixin `_grid.less`) threw
7
+ * `Cannot operate on Paren` at render. Root cause was in the grammar: the
8
+ * `-` in `-(…)` matched `GluedParen`'s lookbehind (its char class included a
9
+ * trailing `-`), so the paren body was parsed permissively — the inner `/`
10
+ * stayed a slash-`List` instead of a math `Operation`. `Negative` then tried to
11
+ * `operate` on the unreduced `Paren`, hitting the base `Cannot operate` throw.
12
+ *
13
+ * A standalone `(@g / 2)` (no leading minus) always took the strict `Paren`
14
+ * body and produced an `Operation`. The fix restricts GluedParen's trailing `-`
15
+ * to only match when it terminates an identifier, so a unary-minus paren falls
16
+ * through to the strict math paren.
17
+ */
18
+ function firstOfType(node: any, type: string): any {
19
+ if (!node || typeof node !== 'object') {
20
+ return undefined;
21
+ }
22
+ if (node.type === type) {
23
+ return node;
24
+ }
25
+ const keys = (node.constructor?.childKeys ?? []) as string[];
26
+ for (const k of keys) {
27
+ const v = node[k];
28
+ const arr = Array.isArray(v) ? v : [v];
29
+ for (const it of arr) {
30
+ const found = firstOfType(it, type);
31
+ if (found) {
32
+ return found;
33
+ }
34
+ }
35
+ }
36
+ // Operation stores operands positionally
37
+ if (node.type === 'Operation') {
38
+ return firstOfType(node.left, type) ?? firstOfType(node.right, type);
39
+ }
40
+ return undefined;
41
+ }
42
+
43
+ describe('wall5 parse: unary-minus paren keeps math division', () => {
44
+ const parse = (src: string): any => {
45
+ const p = new Parser({ mathMode: 'parens-division' } as never);
46
+ return (p as any).parse(src, 'Stylesheet');
47
+ };
48
+
49
+ it('parses `-(30px / 2)` as Negative(Paren(Operation /)), not a slash-List', () => {
50
+ const res = parse('.x { width: -(30px / 2); }');
51
+ expect(res.errors ?? []).toHaveLength(0);
52
+ const neg = firstOfType(res.tree, 'Negative');
53
+ expect(neg).toBeDefined();
54
+ const paren = firstOfType(neg, 'Paren');
55
+ expect(paren).toBeDefined();
56
+ // The Paren's inner must be a division Operation (in-parens math), not a
57
+ // preserved slash-List.
58
+ expect(paren.value?.type).toBe('Operation');
59
+ expect(paren.value?.operator).toBe('/');
60
+ });
61
+
62
+ it('keeps the standalone `(30px / 2)` a division Operation too', () => {
63
+ const res = parse('.x { width: (30px / 2); }');
64
+ const paren = firstOfType(res.tree, 'Paren');
65
+ expect(paren?.value?.type).toBe('Operation');
66
+ });
67
+ });