esrap 2.2.12 → 2.3.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "esrap",
3
- "version": "2.2.12",
3
+ "version": "2.3.0",
4
4
  "description": "Parse in reverse",
5
5
  "repository": {
6
6
  "type": "git",
@@ -484,20 +484,50 @@ export default (options = {}) => {
484
484
  }
485
485
  }
486
486
 
487
+ const boundary_tokens = options.boundaryTokens === true;
488
+
489
+ /**
490
+ * A one-character synthetic token node so structural tokens (`(`, `[`, `{`,
491
+ * unary operators, …) written where a node's SOURCE span begins or ends get a
492
+ * sourcemap anchor. Without it, everything up to the next mapped token is
493
+ * attributed to the PREVIOUS token's source position — `write(content, node)`
494
+ * only maps tokens written with a node, and these boundary characters belong
495
+ * to no written token. Opt-in (`boundaryTokens`): denser maps, byte-identical
496
+ * output.
497
+ * @param {{ line: number, column: number } | undefined} pos
498
+ * @param {number} [length]
499
+ */
500
+ function token_at(pos, length = 1) {
501
+ if (!boundary_tokens) return undefined;
502
+ if (!pos) return undefined;
503
+ return /** @type {any} */ ({
504
+ loc: { start: pos, end: { line: pos.line, column: pos.column + length } }
505
+ });
506
+ }
507
+
508
+ /** @param {{ line: number, column: number } | undefined} pos */
509
+ function token_before(pos) {
510
+ if (!boundary_tokens) return undefined;
511
+ if (!pos || pos.column === 0) return undefined;
512
+ return /** @type {any} */ ({
513
+ loc: { start: { line: pos.line, column: pos.column - 1 }, end: pos }
514
+ });
515
+ }
516
+
487
517
  const shared = {
488
518
  /**
489
519
  * @param {TSESTree.ArrayExpression | TSESTree.ArrayPattern} node
490
520
  * @param {Context} context
491
521
  */
492
522
  'ArrayExpression|ArrayPattern': (node, context) => {
493
- context.write('[');
523
+ context.write('[', token_at(node.loc?.start));
494
524
  sequence(
495
525
  context,
496
526
  /** @type {TSESTree.Node[]} */ (node.elements),
497
527
  node.loc?.end ?? null,
498
528
  false
499
529
  );
500
- context.write(']');
530
+ context.write(']', token_before(node.loc?.end));
501
531
  },
502
532
 
503
533
  /**
@@ -631,7 +661,7 @@ export default (options = {}) => {
631
661
  join.write(' ');
632
662
  }
633
663
 
634
- context.write(')');
664
+ context.write(')', token_before(node.loc?.end));
635
665
  },
636
666
 
637
667
  /**
@@ -653,12 +683,25 @@ export default (options = {}) => {
653
683
 
654
684
  if (node.id) {
655
685
  context.visit(node.id);
686
+ }
687
+
688
+ if (node.typeParameters) {
689
+ context.visit(node.typeParameters);
690
+ }
691
+
692
+ if (node.id || node.typeParameters) {
656
693
  context.write(' ');
657
694
  }
658
695
 
659
696
  if (node.superClass) {
660
697
  context.write('extends ');
698
+ // the `extends` clause is a LeftHandSideExpression; anything lower (a
699
+ // logical/binary/conditional/etc.) must be parenthesized
700
+ const wrap_super =
701
+ EXPRESSIONS_PRECEDENCE[node.superClass.type] < EXPRESSIONS_PRECEDENCE.NewExpression;
702
+ if (wrap_super) context.write('(');
661
703
  context.visit(node.superClass);
704
+ if (wrap_super) context.write(')');
662
705
 
663
706
  // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
664
707
  var type_arguments = node.superTypeParameters ?? node.superTypeArguments;
@@ -791,9 +834,15 @@ export default (options = {}) => {
791
834
 
792
835
  if (node.value.generator) context.write('*');
793
836
 
794
- if (node.computed) context.write('[');
837
+ if (node.computed) context.write('[', token_before(node.key.loc?.start));
795
838
  context.visit(node.key);
796
- if (node.computed) context.write(']');
839
+ if (node.computed) context.write(']', token_at(node.key.loc?.end));
840
+
841
+ // optional method (`m?()`)
842
+ if (node.optional) context.write('?');
843
+
844
+ // @ts-expect-error `typeParameters` lives on the method node, not its value
845
+ if (node.typeParameters) context.visit(node.typeParameters);
797
846
 
798
847
  context.write('(');
799
848
  sequence(
@@ -827,6 +876,8 @@ export default (options = {}) => {
827
876
 
828
877
  const kw = create_keyword_write(context, node, field_modifiers_keywords_map_ok);
829
878
 
879
+ if (node.declare) kw('declare ');
880
+
830
881
  if (node.accessibility) {
831
882
  kw(node.accessibility + ' ');
832
883
  }
@@ -844,6 +895,10 @@ export default (options = {}) => {
844
895
  kw('static ');
845
896
  }
846
897
 
898
+ if (node.override) kw('override ');
899
+
900
+ if (node.readonly) kw('readonly ');
901
+
847
902
  if (
848
903
  // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions
849
904
  node.accessor ||
@@ -854,13 +909,17 @@ export default (options = {}) => {
854
909
  }
855
910
 
856
911
  if (node.computed) {
857
- context.write('[');
912
+ context.write('[', token_before(node.key.loc?.start));
858
913
  context.visit(node.key);
859
- context.write(']');
914
+ context.write(']', token_at(node.key.loc?.end));
860
915
  } else {
861
916
  context.visit(node.key);
862
917
  }
863
918
 
919
+ // `x?: T` (optional) / `x!: T` (definite assignment)
920
+ if (node.optional) context.write('?');
921
+ else if (node.definite) context.write('!');
922
+
864
923
  if (node.typeAnnotation) {
865
924
  if (node.type === 'AccessorProperty' || node.type === 'TSAbstractAccessorProperty') {
866
925
  context.visit(node.typeAnnotation);
@@ -1101,7 +1160,14 @@ export default (options = {}) => {
1101
1160
 
1102
1161
  Decorator(node, context) {
1103
1162
  context.write('@');
1163
+ // a decorator must be an identifier/member/call (or parenthesized); anything
1164
+ // else (ternary, logical, assignment, unary, `as`, optional chain…) needs wrapping
1165
+ const wrap =
1166
+ /** @type {string} */ (node.expression.type) === 'ChainExpression' ||
1167
+ EXPRESSIONS_PRECEDENCE[node.expression.type] < EXPRESSIONS_PRECEDENCE.CallExpression;
1168
+ if (wrap) context.write('(');
1104
1169
  context.visit(node.expression);
1170
+ if (wrap) context.write(')');
1105
1171
  context.newline();
1106
1172
  },
1107
1173
 
@@ -1211,12 +1277,8 @@ export default (options = {}) => {
1211
1277
  },
1212
1278
 
1213
1279
  ExpressionStatement(node, context) {
1214
- // wrap when a leading `{`/`function` would otherwise be parsed as a block/declaration
1215
- const wrap =
1216
- node.expression.type === 'ObjectExpression' ||
1217
- (node.expression.type === 'AssignmentExpression' &&
1218
- node.expression.left.type === 'ObjectPattern') ||
1219
- node.expression.type === 'FunctionExpression';
1280
+ // would otherwise be parsed as a block / function / class declaration
1281
+ const wrap = leads_with_curly_or_keyword(node.expression);
1220
1282
  maybe_wrap(context, node.expression, wrap);
1221
1283
  context.write(';');
1222
1284
  },
@@ -1253,7 +1315,9 @@ export default (options = {}) => {
1253
1315
  let name = node.name;
1254
1316
  context.write(name, node);
1255
1317
 
1318
+ // optional parameters (`a?: T`) carry `optional` on the identifier
1256
1319
  if (node.optional) context.write('?');
1320
+
1257
1321
  if (node.typeAnnotation) context.visit(node.typeAnnotation);
1258
1322
  },
1259
1323
 
@@ -1412,7 +1476,7 @@ export default (options = {}) => {
1412
1476
  }
1413
1477
  context.write('[');
1414
1478
  context.visit(node.property);
1415
- context.write(']');
1479
+ context.write(']', token_before(node.loc?.end));
1416
1480
  } else {
1417
1481
  context.write(node.optional ? '?.' : '.');
1418
1482
  context.visit(node.property);
@@ -1430,22 +1494,28 @@ export default (options = {}) => {
1430
1494
  NewExpression: shared['CallExpression|NewExpression'],
1431
1495
 
1432
1496
  ObjectExpression(node, context) {
1433
- context.write('{');
1497
+ context.write('{', token_at(node.loc?.start));
1434
1498
  sequence(context, node.properties, node.loc?.end ?? null, true);
1435
- context.write('}');
1499
+ context.write('}', token_before(node.loc?.end));
1436
1500
  },
1437
1501
 
1438
1502
  ObjectPattern(node, context) {
1439
- context.write('{');
1503
+ context.write('{', token_at(node.loc?.start));
1440
1504
  sequence(context, node.properties, node.loc?.end ?? null, true);
1441
- context.write('}');
1505
+ context.write('}', token_before(node.loc?.end));
1442
1506
 
1443
1507
  if (node.typeAnnotation) context.visit(node.typeAnnotation);
1444
1508
  },
1445
1509
 
1446
1510
  // @ts-expect-error this isn't a real node type, but Acorn produces it
1447
1511
  ParenthesizedExpression(node, context) {
1448
- maybe_wrap(context, node.expression, true);
1512
+ if (node.loc) {
1513
+ context.write('(', token_at(node.loc.start));
1514
+ context.visit(node.expression);
1515
+ context.write(')', token_before(node.loc.end));
1516
+ } else {
1517
+ maybe_wrap(context, node.expression, true);
1518
+ }
1449
1519
  },
1450
1520
 
1451
1521
  PrivateIdentifier(node, context) {
@@ -1479,9 +1549,9 @@ export default (options = {}) => {
1479
1549
  if (node.kind !== 'init') kw(node.kind + ' ');
1480
1550
  if (node.value.async) kw('async ');
1481
1551
  if (node.value.generator) context.write('*');
1482
- if (node.computed) context.write('[');
1552
+ if (node.computed) context.write('[', token_before(node.key.loc?.start));
1483
1553
  context.visit(node.key);
1484
- if (node.computed) context.write(']');
1554
+ if (node.computed) context.write(']', token_at(node.key.loc?.end));
1485
1555
  context.write('(');
1486
1556
  sequence(
1487
1557
  context,
@@ -1496,12 +1566,17 @@ export default (options = {}) => {
1496
1566
  context.write(' ');
1497
1567
  context.visit(node.value.body);
1498
1568
  } else {
1499
- if (node.computed) context.write('[');
1569
+ if (node.computed) context.write('[', token_before(node.key.loc?.start));
1500
1570
  if (node.kind === 'get' || node.kind === 'set') {
1501
1571
  write_keyword(context, node, node.kind, ' ');
1502
1572
  }
1503
1573
  context.visit(node.key);
1504
- context.write(node.computed ? ']: ' : ': ');
1574
+ if (node.computed) {
1575
+ context.write(']', token_at(node.key.loc?.end));
1576
+ context.write(': ');
1577
+ } else {
1578
+ context.write(': ');
1579
+ }
1505
1580
  context.visit(node.value);
1506
1581
  }
1507
1582
  },
@@ -1594,7 +1669,12 @@ export default (options = {}) => {
1594
1669
  },
1595
1670
 
1596
1671
  TaggedTemplateExpression(node, context) {
1597
- maybe_wrap(context, node.tag, node.tag.type === 'ChainExpression');
1672
+ // the tag is a LeftHandSideExpression; a lower-precedence tag (logical,
1673
+ // conditional, arrow, `as`, unary…) or an optional chain must be wrapped
1674
+ const wrap =
1675
+ /** @type {string} */ (node.tag.type) === 'ChainExpression' ||
1676
+ EXPRESSIONS_PRECEDENCE[node.tag.type] < EXPRESSIONS_PRECEDENCE.CallExpression;
1677
+ maybe_wrap(context, node.tag, wrap);
1598
1678
  context.visit(node.quasi);
1599
1679
  },
1600
1680
 
@@ -1663,7 +1743,7 @@ export default (options = {}) => {
1663
1743
  },
1664
1744
 
1665
1745
  UnaryExpression(node, context) {
1666
- context.write(node.operator);
1746
+ context.write(node.operator, token_at(node.loc?.start, node.operator.length));
1667
1747
 
1668
1748
  if (node.operator.length > 1) {
1669
1749
  context.write(' ');
@@ -1847,7 +1927,9 @@ export default (options = {}) => {
1847
1927
  },
1848
1928
 
1849
1929
  TSPropertySignature(node, context) {
1930
+ if (node.computed) context.write('[', token_before(node.key.loc?.start));
1850
1931
  context.visit(node.key);
1932
+ if (node.computed) context.write(']', token_at(node.key.loc?.end));
1851
1933
  if (node.optional) context.write('?');
1852
1934
  if (node.typeAnnotation) context.visit(node.typeAnnotation);
1853
1935
  },
@@ -1939,6 +2021,11 @@ export default (options = {}) => {
1939
2021
  },
1940
2022
 
1941
2023
  TSTypeParameter(node, context) {
2024
+ // modifiers: `const T`, `in T` / `out T` (variance)
2025
+ if (node.const) context.write('const ');
2026
+ if (node.in) context.write('in ');
2027
+ if (node.out) context.write('out ');
2028
+
1942
2029
  if (node.name && node.name.type) context.visit(node.name);
1943
2030
  // @ts-expect-error type mismatch TSESTree and acorn-typescript?
1944
2031
  else context.write(node.name, node);
@@ -1955,19 +2042,14 @@ export default (options = {}) => {
1955
2042
  },
1956
2043
 
1957
2044
  TSTypePredicate(node, context) {
1958
- if (node.parameterName) {
1959
- context.visit(node.parameterName);
1960
- } else if (node.typeAnnotation) {
1961
- context.visit(node.typeAnnotation);
1962
- }
2045
+ // `asserts` precedes the parameter name; `is <type>` follows it. Forms:
2046
+ // `x is T`, `asserts x is T`, `asserts x`
2047
+ if (node.asserts) context.write('asserts ');
1963
2048
 
1964
- if (node.asserts) {
1965
- context.write(' asserts ');
1966
- } else {
1967
- context.write(' is ');
1968
- }
2049
+ if (node.parameterName) context.visit(node.parameterName);
1969
2050
 
1970
2051
  if (node.typeAnnotation) {
2052
+ context.write(' is ');
1971
2053
  context.visit(node.typeAnnotation.typeAnnotation);
1972
2054
  }
1973
2055
  },
@@ -2005,7 +2087,16 @@ export default (options = {}) => {
2005
2087
  },
2006
2088
 
2007
2089
  TSMappedType(node, context) {
2008
- context.write('{[');
2090
+ context.write('{');
2091
+
2092
+ // `readonly` / `+readonly` / `-readonly` modifier
2093
+ if (node.readonly) {
2094
+ context.write(
2095
+ node.readonly === '-' ? '-readonly ' : node.readonly === '+' ? '+readonly ' : 'readonly '
2096
+ );
2097
+ }
2098
+
2099
+ context.write('[');
2009
2100
 
2010
2101
  const legacy_type_parameter = node.typeParameter;
2011
2102
  const key = node.key ?? legacy_type_parameter?.name;
@@ -2022,8 +2113,19 @@ export default (options = {}) => {
2022
2113
  context.visit(constraint);
2023
2114
  }
2024
2115
 
2116
+ // `as` key remapping
2117
+ if (node.nameType) {
2118
+ context.write(' as ');
2119
+ context.visit(node.nameType);
2120
+ }
2121
+
2025
2122
  context.write(']');
2026
2123
 
2124
+ // `?` / `+?` / `-?` optionality modifier
2125
+ if (node.optional) {
2126
+ context.write(node.optional === '-' ? '-?' : node.optional === '+' ? '+?' : '?');
2127
+ }
2128
+
2027
2129
  if (node.typeAnnotation) {
2028
2130
  context.write(': ');
2029
2131
  context.visit(node.typeAnnotation);
@@ -2033,7 +2135,9 @@ export default (options = {}) => {
2033
2135
  },
2034
2136
 
2035
2137
  TSMethodSignature(node, context) {
2138
+ if (node.computed) context.write('[', token_before(node.key.loc?.start));
2036
2139
  context.visit(node.key);
2140
+ if (node.computed) context.write(']', token_at(node.key.loc?.end));
2037
2141
 
2038
2142
  context.write('(');
2039
2143
  sequence(
@@ -2191,8 +2295,17 @@ export default (options = {}) => {
2191
2295
  context.visit(node.id);
2192
2296
  }
2193
2297
 
2194
- if (!node.body) return;
2195
- context.visit(node.body);
2298
+ // a qualified name (`namespace A.B.C`) is represented as nested
2299
+ // `TSModuleDeclaration`s whose body is the next name part, not a block
2300
+ let body = /** @type {any} */ (node.body);
2301
+ while (body && body.type === 'TSModuleDeclaration') {
2302
+ context.write('.');
2303
+ context.visit(body.id);
2304
+ body = body.body;
2305
+ }
2306
+
2307
+ if (!body) return;
2308
+ context.visit(body);
2196
2309
  },
2197
2310
 
2198
2311
  TSNonNullExpression(node, context) {
@@ -2320,19 +2433,20 @@ function operand_needs_wrap(node, parent, is_right) {
2320
2433
  return true;
2321
2434
  }
2322
2435
 
2323
- // `**` can't take a unary/await left operand: `-2 ** 2`, `await x ** 2` are syntax errors
2436
+ // `**` can't take a unary/await/assertion left operand: `-2 ** 2`, `await x ** 2`,
2437
+ // `<T>x ** 2` are syntax errors
2324
2438
  const unary_base_of_pow =
2325
2439
  !is_right &&
2326
2440
  parent.operator === '**' &&
2327
- (node.type === 'UnaryExpression' || node.type === 'AwaitExpression');
2441
+ (node.type === 'UnaryExpression' ||
2442
+ node.type === 'AwaitExpression' ||
2443
+ node.type === 'TSTypeAssertion');
2328
2444
  if (unary_base_of_pow) return true;
2329
2445
 
2330
2446
  const precedence = EXPRESSIONS_PRECEDENCE[node.type];
2331
2447
  const parent_precedence = EXPRESSIONS_PRECEDENCE[parent.type];
2332
2448
  if (precedence !== parent_precedence) return precedence < parent_precedence;
2333
-
2334
2449
  const operator = /** @type {TSESTree.BinaryExpression} */ (node).operator;
2335
-
2336
2450
  if (operator === '**' && parent.operator === '**') {
2337
2451
  // exponentiation is right-associative
2338
2452
  return !is_right;
@@ -2375,6 +2489,95 @@ function has_call_expression(node) {
2375
2489
  return false;
2376
2490
  }
2377
2491
 
2492
+ /**
2493
+ * True when printing `node` as an expression statement would begin with `{`,
2494
+ * `function`, or `class` — which the parser would misread as a block, function
2495
+ * declaration, or class declaration. Walks the left spine following the same
2496
+ * parenthesization the visitors apply, so it stops as soon as a child position
2497
+ * would already be wrapped.
2498
+ * @param {TSESTree.Node} node
2499
+ * @returns {boolean}
2500
+ */
2501
+ function leads_with_curly_or_keyword(node) {
2502
+ while (node) {
2503
+ switch (node.type) {
2504
+ case 'ObjectExpression':
2505
+ case 'ObjectPattern':
2506
+ case 'FunctionExpression':
2507
+ case 'ClassExpression':
2508
+ return true;
2509
+
2510
+ case 'BinaryExpression':
2511
+ case 'LogicalExpression':
2512
+ if (operand_needs_wrap(node.left, node, false)) return false;
2513
+ node = node.left;
2514
+ continue;
2515
+
2516
+ case 'AssignmentExpression':
2517
+ node = node.left;
2518
+ continue;
2519
+
2520
+ case 'ConditionalExpression':
2521
+ if (
2522
+ EXPRESSIONS_PRECEDENCE[node.test.type] <= EXPRESSIONS_PRECEDENCE.ConditionalExpression
2523
+ ) {
2524
+ return false;
2525
+ }
2526
+ node = node.test;
2527
+ continue;
2528
+
2529
+ case 'MemberExpression':
2530
+ if (
2531
+ /** @type {string} */ (node.object.type) === 'ChainExpression' ||
2532
+ EXPRESSIONS_PRECEDENCE[node.object.type] < EXPRESSIONS_PRECEDENCE.MemberExpression
2533
+ ) {
2534
+ return false;
2535
+ }
2536
+ node = node.object;
2537
+ continue;
2538
+
2539
+ case 'CallExpression':
2540
+ if (
2541
+ /** @type {string} */ (node.callee.type) === 'ChainExpression' ||
2542
+ EXPRESSIONS_PRECEDENCE[node.callee.type] < EXPRESSIONS_PRECEDENCE.CallExpression
2543
+ ) {
2544
+ return false;
2545
+ }
2546
+ node = node.callee;
2547
+ continue;
2548
+
2549
+ case 'TaggedTemplateExpression':
2550
+ if (
2551
+ /** @type {string} */ (node.tag.type) === 'ChainExpression' ||
2552
+ EXPRESSIONS_PRECEDENCE[node.tag.type] < EXPRESSIONS_PRECEDENCE.CallExpression
2553
+ ) {
2554
+ return false;
2555
+ }
2556
+ node = node.tag;
2557
+ continue;
2558
+
2559
+ case 'UpdateExpression':
2560
+ if (node.prefix) return false;
2561
+ node = node.argument;
2562
+ continue;
2563
+
2564
+ case 'TSAsExpression':
2565
+ case 'TSSatisfiesExpression':
2566
+ case 'TSNonNullExpression':
2567
+ node = node.expression;
2568
+ continue;
2569
+
2570
+ // a sequence expression always prints its own wrapping parens
2571
+ case 'SequenceExpression':
2572
+ return false;
2573
+
2574
+ default:
2575
+ return false;
2576
+ }
2577
+ }
2578
+ return false;
2579
+ }
2580
+
2378
2581
  /**
2379
2582
  * @param {TSESTree.VariableDeclaration} node
2380
2583
  * @param {Context} context
@@ -2,6 +2,14 @@ import type { BaseNode } from '../types';
2
2
 
3
3
  export type TSOptions = {
4
4
  quotes?: 'double' | 'single';
5
+ /**
6
+ * Anchor structural tokens (array/object brackets and braces, preserved
7
+ * parentheses, unary operators, and the closing tokens of calls and
8
+ * computed member access) with one-character source locations, so
9
+ * node-boundary positions always resolve through the source map instead of
10
+ * being attributed to the previous token. Denser maps; identical output.
11
+ */
12
+ boundaryTokens?: boolean;
5
13
  comments?: Comment[];
6
14
  getLeadingComments?: (node: BaseNode) => BaseComment[] | undefined;
7
15
  getTrailingComments?: (node: BaseNode) => BaseComment[] | undefined;
package/types/index.d.ts CHANGED
@@ -95,6 +95,14 @@ declare module 'esrap/languages/ts' {
95
95
  : SpecialisedVisitors<T> & { _?: (node: T, context: Context, visit: (node: T) => void) => void };
96
96
  type TSOptions = {
97
97
  quotes?: 'double' | 'single';
98
+ /**
99
+ * Anchor structural tokens (array/object brackets and braces, preserved
100
+ * parentheses, unary operators, and the closing tokens of calls and
101
+ * computed member access) with one-character source locations, so
102
+ * node-boundary positions always resolve through the source map instead of
103
+ * being attributed to the previous token. Denser maps; identical output.
104
+ */
105
+ boundaryTokens?: boolean;
98
106
  comments?: Comment[];
99
107
  getLeadingComments?: (node: BaseNode) => BaseComment[] | undefined;
100
108
  getTrailingComments?: (node: BaseNode) => BaseComment[] | undefined;
@@ -149,6 +157,14 @@ declare module 'esrap/languages/tsx' {
149
157
  : SpecialisedVisitors<T> & { _?: (node: T, context: Context, visit: (node: T) => void) => void };
150
158
  type TSOptions = {
151
159
  quotes?: 'double' | 'single';
160
+ /**
161
+ * Anchor structural tokens (array/object brackets and braces, preserved
162
+ * parentheses, unary operators, and the closing tokens of calls and
163
+ * computed member access) with one-character source locations, so
164
+ * node-boundary positions always resolve through the source map instead of
165
+ * being attributed to the previous token. Denser maps; identical output.
166
+ */
167
+ boundaryTokens?: boolean;
152
168
  comments?: Comment[];
153
169
  getLeadingComments?: (node: BaseNode) => BaseComment[] | undefined;
154
170
  getTrailingComments?: (node: BaseNode) => BaseComment[] | undefined;
@@ -37,6 +37,6 @@
37
37
  null,
38
38
  null
39
39
  ],
40
- "mappings": ";MAEYA,QAAQA;;;;;;;;MAQfC,MAAMA;;MAENC,mBAAmBA;;;;MAIZC,OAAOA;;aAEPC,QAAQA;;;;WAWHC,QAAQA;;;;;;MAWbC,OAAOA;;kBAEFC,YAAYA;;;;;;;;;iBCWbC,KAAKA;;;;cC7CRC,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aCLRC,IAAIA;yBACQC,EAAEA;;cAELC,sBAAsBA;MHJ/BZ,QAAQA;;;;;;;;MAQfC,MAAMA;;MAENC,mBAAmBA;;;;MAIZC,OAAOA;;MAEPC,QAAQA;;;MIhBRS,SAASA;;;;;;;WAOXC,QAAQA;;;;;;;kBAODC,WAAWA;;;;;;;kBAOXC,OAAOA;;;;;;;;;;;;aCpBZN,IAAIA;yBACQO,GAAGA;MLFfjB,QAAQA;;;;;;;;MAQfC,MAAMA;;MAENC,mBAAmBA;;;;MAIZC,OAAOA;;MAEPC,QAAQA;;;MIhBRS,SAASA;;;;;;;WAOXC,QAAQA;;;;;;;kBAODC,WAAWA;;;;;;;kBAOXC,OAAOA",
40
+ "mappings": ";MAEYA,QAAQA;;;;;;;;MAQfC,MAAMA;;MAENC,mBAAmBA;;;;MAIZC,OAAOA;;aAEPC,QAAQA;;;;WAWHC,QAAQA;;;;;;MAWbC,OAAOA;;kBAEFC,YAAYA;;;;;;;;;iBCWbC,KAAKA;;;;cC7CRC,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aCLRC,IAAIA;yBACQC,EAAEA;;cAELC,sBAAsBA;MHJ/BZ,QAAQA;;;;;;;;MAQfC,MAAMA;;MAENC,mBAAmBA;;;;MAIZC,OAAOA;;MAEPC,QAAQA;;;MIhBRS,SAASA;;;;;;;;;;;;;;;WAeXC,QAAQA;;;;;;;kBAODC,WAAWA;;;;;;;kBAOXC,OAAOA;;;;;;;;;;;;aC5BZN,IAAIA;yBACQO,GAAGA;MLFfjB,QAAQA;;;;;;;;MAQfC,MAAMA;;MAENC,mBAAmBA;;;;MAIZC,OAAOA;;MAEPC,QAAQA;;;MIhBRS,SAASA;;;;;;;;;;;;;;;WAeXC,QAAQA;;;;;;;kBAODC,WAAWA;;;;;;;kBAOXC,OAAOA",
41
41
  "ignoreList": []
42
42
  }