@bamboocss/parser 1.48.5 → 1.50.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/dist/index.cjs +211 -206
- package/dist/index.d.cts +11 -3
- package/dist/index.d.mts +11 -3
- package/dist/index.mjs +179 -174
- package/package.json +13 -12
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
let
|
|
2
|
+
let _bamboocss_ts_ast = require("@bamboocss/ts-ast");
|
|
3
3
|
let _bamboocss_extractor = require("@bamboocss/extractor");
|
|
4
4
|
let _bamboocss_shared = require("@bamboocss/shared");
|
|
5
5
|
let node_crypto = require("node:crypto");
|
|
@@ -411,20 +411,6 @@ function createReportMaps() {
|
|
|
411
411
|
};
|
|
412
412
|
}
|
|
413
413
|
//#endregion
|
|
414
|
-
//#region src/get-module-specifier-value.ts
|
|
415
|
-
/**
|
|
416
|
-
* Both declaration kinds carry a specifier, and `export { x } from './m'` is how a barrel
|
|
417
|
-
* forwards a recipe — so this reads either. An `export { x }` with no `from` returns
|
|
418
|
-
* undefined, which is the same answer the throwing case gives.
|
|
419
|
-
*/
|
|
420
|
-
const getModuleSpecifierValue = (node) => {
|
|
421
|
-
try {
|
|
422
|
-
return node.getModuleSpecifierValue();
|
|
423
|
-
} catch {
|
|
424
|
-
return;
|
|
425
|
-
}
|
|
426
|
-
};
|
|
427
|
-
//#endregion
|
|
428
414
|
//#region src/imported-recipes.ts
|
|
429
415
|
/**
|
|
430
416
|
* A module's exported recipes, memoized.
|
|
@@ -440,15 +426,15 @@ const clearImportedRecipeCache = () => {
|
|
|
440
426
|
/** The names a file bound `cva`/`sva` to, or empty when it imports neither. */
|
|
441
427
|
const recipeFactoryAliases = (sourceFile, imports) => {
|
|
442
428
|
const aliases = /* @__PURE__ */ new Set();
|
|
443
|
-
for (const declaration of
|
|
444
|
-
if (
|
|
445
|
-
const mod = getModuleSpecifierValue(declaration);
|
|
429
|
+
for (const declaration of (0, _bamboocss_ts_ast.getImportDeclarations)(sourceFile)) {
|
|
430
|
+
if ((0, _bamboocss_ts_ast.isTypeOnly)(declaration)) continue;
|
|
431
|
+
const mod = (0, _bamboocss_ts_ast.getModuleSpecifierValue)(declaration);
|
|
446
432
|
if (!mod) continue;
|
|
447
|
-
for (const specifier of
|
|
448
|
-
if (
|
|
449
|
-
const name =
|
|
433
|
+
for (const specifier of (0, _bamboocss_ts_ast.getNamedImports)(declaration)) {
|
|
434
|
+
if ((0, _bamboocss_ts_ast.isTypeOnly)(specifier)) continue;
|
|
435
|
+
const name = (0, _bamboocss_ts_ast.nameNodeOf)(specifier)?.getText();
|
|
450
436
|
if (name !== "cva" && name !== "sva") continue;
|
|
451
|
-
const alias =
|
|
437
|
+
const alias = (0, _bamboocss_ts_ast.getAliasNode)(specifier)?.getText() || name;
|
|
452
438
|
if (!imports.match({
|
|
453
439
|
name,
|
|
454
440
|
alias,
|
|
@@ -469,21 +455,21 @@ const declaredRecipes = (sourceFile, imports) => {
|
|
|
469
455
|
declared,
|
|
470
456
|
exported
|
|
471
457
|
};
|
|
472
|
-
const filePath =
|
|
473
|
-
for (const statement of sourceFile.
|
|
474
|
-
if (!
|
|
475
|
-
if (!(statement.declarationList.flags &
|
|
458
|
+
const filePath = (0, _bamboocss_ts_ast.pathOf)(sourceFile);
|
|
459
|
+
for (const statement of sourceFile.statements) {
|
|
460
|
+
if (!_bamboocss_ts_ast.ts.isVariableStatement(statement)) continue;
|
|
461
|
+
if (!(statement.declarationList.flags & _bamboocss_ts_ast.ts.NodeFlags.Const)) continue;
|
|
476
462
|
for (const declaration of statement.declarationList.declarations) {
|
|
477
463
|
const initializer = declaration.initializer;
|
|
478
|
-
if (!initializer || !
|
|
464
|
+
if (!initializer || !_bamboocss_ts_ast.ts.isCallExpression(initializer)) continue;
|
|
479
465
|
const callee = initializer.expression;
|
|
480
|
-
if (!
|
|
466
|
+
if (!_bamboocss_ts_ast.ts.isIdentifier(callee) || !_bamboocss_ts_ast.ts.isIdentifier(declaration.name)) continue;
|
|
481
467
|
if (!factories.has(callee.text)) continue;
|
|
482
468
|
declared.set(declaration.name.text, {
|
|
483
469
|
filePath,
|
|
484
470
|
name: declaration.name.text
|
|
485
471
|
});
|
|
486
|
-
if (statement.modifiers?.some((modifier) => modifier.kind ===
|
|
472
|
+
if (statement.modifiers?.some((modifier) => modifier.kind === _bamboocss_ts_ast.ts.SyntaxKind.ExportKeyword)) exported.add(declaration.name.text);
|
|
487
473
|
}
|
|
488
474
|
}
|
|
489
475
|
return {
|
|
@@ -530,13 +516,13 @@ const walkExports = (sourceFile, imports, resolveModule, seen) => {
|
|
|
530
516
|
const imported = walkImports(sourceFile, imports, resolveModule, seen);
|
|
531
517
|
complete &&= imported.complete;
|
|
532
518
|
for (const [alias, origin] of imported.bindings) if (!local.has(alias)) local.set(alias, origin);
|
|
533
|
-
for (const declaration of
|
|
534
|
-
if (
|
|
535
|
-
const specifier = getModuleSpecifierValue(declaration);
|
|
519
|
+
for (const declaration of (0, _bamboocss_ts_ast.getExportDeclarations)(sourceFile)) {
|
|
520
|
+
if ((0, _bamboocss_ts_ast.isTypeOnly)(declaration)) continue;
|
|
521
|
+
const specifier = (0, _bamboocss_ts_ast.getModuleSpecifierValue)(declaration);
|
|
536
522
|
const target = specifier ? resolveModule(specifier, sourceFile) : void 0;
|
|
537
523
|
if (specifier && !target) continue;
|
|
538
|
-
if (
|
|
539
|
-
if (
|
|
524
|
+
if ((0, _bamboocss_ts_ast.getNamespaceExport)(declaration)) continue;
|
|
525
|
+
if ((0, _bamboocss_ts_ast.isStarExport)(declaration)) {
|
|
540
526
|
if (!target) continue;
|
|
541
527
|
const walk = walkExports(target, imports, resolveModule, seen);
|
|
542
528
|
complete &&= walk.complete;
|
|
@@ -556,11 +542,11 @@ const walkExports = (sourceFile, imports, resolveModule, seen) => {
|
|
|
556
542
|
complete &&= walk.complete;
|
|
557
543
|
source = walk.names;
|
|
558
544
|
}
|
|
559
|
-
for (const exportSpecifier of
|
|
560
|
-
if (
|
|
561
|
-
const name =
|
|
562
|
-
const origin = source.get(name);
|
|
563
|
-
if (origin) names.set(
|
|
545
|
+
for (const exportSpecifier of (0, _bamboocss_ts_ast.getNamedExports)(declaration)) {
|
|
546
|
+
if ((0, _bamboocss_ts_ast.isTypeOnly)(exportSpecifier)) continue;
|
|
547
|
+
const name = (0, _bamboocss_ts_ast.nameNodeOf)(exportSpecifier)?.getText();
|
|
548
|
+
const origin = source.get(name ?? "");
|
|
549
|
+
if (origin) names.set((0, _bamboocss_ts_ast.getAliasNode)(exportSpecifier)?.getText() || (name ?? ""), origin);
|
|
564
550
|
}
|
|
565
551
|
}
|
|
566
552
|
for (const [name, origin] of starred) if (!names.has(name) && !ambiguous.has(name)) names.set(name, origin);
|
|
@@ -580,11 +566,11 @@ const walkExports = (sourceFile, imports, resolveModule, seen) => {
|
|
|
580
566
|
const walkImports = (sourceFile, imports, resolveModule, seen) => {
|
|
581
567
|
const bindings = /* @__PURE__ */ new Map();
|
|
582
568
|
let complete = true;
|
|
583
|
-
for (const declaration of
|
|
584
|
-
if (
|
|
585
|
-
const named =
|
|
569
|
+
for (const declaration of (0, _bamboocss_ts_ast.getImportDeclarations)(sourceFile)) {
|
|
570
|
+
if ((0, _bamboocss_ts_ast.isTypeOnly)(declaration)) continue;
|
|
571
|
+
const named = (0, _bamboocss_ts_ast.getNamedImports)(declaration);
|
|
586
572
|
if (named.length === 0) continue;
|
|
587
|
-
const specifier = getModuleSpecifierValue(declaration);
|
|
573
|
+
const specifier = (0, _bamboocss_ts_ast.getModuleSpecifierValue)(declaration);
|
|
588
574
|
if (!specifier) continue;
|
|
589
575
|
const target = resolveModule(specifier, sourceFile);
|
|
590
576
|
if (!target || target === sourceFile) continue;
|
|
@@ -593,10 +579,10 @@ const walkImports = (sourceFile, imports, resolveModule, seen) => {
|
|
|
593
579
|
const { names } = walk;
|
|
594
580
|
if (names.size === 0) continue;
|
|
595
581
|
for (const importSpecifier of named) {
|
|
596
|
-
if (
|
|
597
|
-
const origin = names.get(
|
|
582
|
+
if ((0, _bamboocss_ts_ast.isTypeOnly)(importSpecifier)) continue;
|
|
583
|
+
const origin = names.get((0, _bamboocss_ts_ast.nameNodeOf)(importSpecifier)?.getText() ?? "");
|
|
598
584
|
if (!origin) continue;
|
|
599
|
-
bindings.set(
|
|
585
|
+
bindings.set((0, _bamboocss_ts_ast.getAliasNode)(importSpecifier)?.getText() || ((0, _bamboocss_ts_ast.nameNodeOf)(importSpecifier)?.getText() ?? ""), origin);
|
|
600
586
|
}
|
|
601
587
|
}
|
|
602
588
|
return {
|
|
@@ -645,7 +631,7 @@ const digestExportValue = (sourceFile, exportedName, resolveModule, onCrossing)
|
|
|
645
631
|
try {
|
|
646
632
|
const declaration = (0, _bamboocss_extractor.getExportedVarDeclarationWithName)(exportedName, sourceFile, [], boxCtx);
|
|
647
633
|
if (!declaration) return "bamboo:export-missing";
|
|
648
|
-
const initializer =
|
|
634
|
+
const initializer = (0, _bamboocss_ts_ast.childOf)(declaration, "initializer");
|
|
649
635
|
if (!initializer) return void 0;
|
|
650
636
|
const box = (0, _bamboocss_extractor.maybeBoxNode)(initializer, [], boxCtx);
|
|
651
637
|
if (!box || Array.isArray(box)) return void 0;
|
|
@@ -660,17 +646,18 @@ const digestExportValue = (sourceFile, exportedName, resolveModule, onCrossing)
|
|
|
660
646
|
};
|
|
661
647
|
//#endregion
|
|
662
648
|
//#region src/get-import-declarations.ts
|
|
663
|
-
function getImportDeclarations(context, sourceFile) {
|
|
649
|
+
function getImportDeclarations$1(context, sourceFile) {
|
|
664
650
|
const { imports, tsOptions } = context;
|
|
665
651
|
const importDeclarations = [];
|
|
666
|
-
|
|
667
|
-
const mod = getModuleSpecifierValue(node);
|
|
652
|
+
(0, _bamboocss_ts_ast.getImportDeclarations)(sourceFile).forEach((node) => {
|
|
653
|
+
const mod = (0, _bamboocss_ts_ast.getModuleSpecifierValue)(node);
|
|
668
654
|
if (!mod) return;
|
|
669
|
-
|
|
670
|
-
const name =
|
|
655
|
+
(0, _bamboocss_ts_ast.getNamedImports)(node).forEach((specifier) => {
|
|
656
|
+
const name = (0, _bamboocss_ts_ast.nameNodeOf)(specifier)?.getText();
|
|
657
|
+
const alias = (0, _bamboocss_ts_ast.getAliasNode)(specifier)?.getText() || name;
|
|
671
658
|
const result = {
|
|
672
|
-
name,
|
|
673
|
-
alias:
|
|
659
|
+
name: name ?? "",
|
|
660
|
+
alias: alias ?? "",
|
|
674
661
|
mod,
|
|
675
662
|
kind: "named"
|
|
676
663
|
};
|
|
@@ -680,7 +667,7 @@ function getImportDeclarations(context, sourceFile) {
|
|
|
680
667
|
})) return;
|
|
681
668
|
importDeclarations.push(result);
|
|
682
669
|
});
|
|
683
|
-
const namespace =
|
|
670
|
+
const namespace = (0, _bamboocss_ts_ast.getNamespaceImport)(node);
|
|
684
671
|
if (namespace) {
|
|
685
672
|
const name = namespace.getText();
|
|
686
673
|
const result = {
|
|
@@ -717,7 +704,7 @@ const findUnresolvable = (node, path, out, seen = /* @__PURE__ */ new Set()) =>
|
|
|
717
704
|
}
|
|
718
705
|
if (_bamboocss_extractor.box.isConditional(node)) return;
|
|
719
706
|
if (_bamboocss_extractor.box.isLiteral(node) && node.value === void 0) {
|
|
720
|
-
if (
|
|
707
|
+
if (_bamboocss_ts_ast.Node.isTemplateExpression(node.getNode())) out.push(path.join("."));
|
|
721
708
|
return;
|
|
722
709
|
}
|
|
723
710
|
if (_bamboocss_extractor.box.isMap(node)) {
|
|
@@ -740,17 +727,17 @@ const findUnresolvable = (node, path, out, seen = /* @__PURE__ */ new Set()) =>
|
|
|
740
727
|
*/
|
|
741
728
|
const writtenProps = (node) => {
|
|
742
729
|
let literal = node;
|
|
743
|
-
if (literal &&
|
|
744
|
-
const args = literal.
|
|
730
|
+
if (literal && _bamboocss_ts_ast.Node.isCallExpression(literal)) {
|
|
731
|
+
const args = literal.arguments;
|
|
745
732
|
if (args.length !== 1) return void 0;
|
|
746
733
|
literal = args[0];
|
|
747
734
|
}
|
|
748
|
-
if (!literal || !
|
|
735
|
+
if (!literal || !_bamboocss_ts_ast.Node.isObjectLiteralExpression(literal)) return void 0;
|
|
749
736
|
const names = [];
|
|
750
737
|
let uncertain = false;
|
|
751
|
-
for (const property of literal.
|
|
752
|
-
if (
|
|
753
|
-
const name =
|
|
738
|
+
for (const property of literal.properties) {
|
|
739
|
+
if (_bamboocss_ts_ast.Node.isPropertyAssignment(property) || _bamboocss_ts_ast.Node.isShorthandPropertyAssignment(property)) {
|
|
740
|
+
const name = (0, _bamboocss_ts_ast.getName)(property) ?? "";
|
|
754
741
|
if (name.startsWith("[")) {
|
|
755
742
|
uncertain = true;
|
|
756
743
|
continue;
|
|
@@ -786,11 +773,11 @@ const writtenProps = (node) => {
|
|
|
786
773
|
const findUnresolvedInValue = (node, resolved, path, out) => {
|
|
787
774
|
const value = node ? (0, _bamboocss_extractor.unwrapExpression)(node) : void 0;
|
|
788
775
|
if (!value) return;
|
|
789
|
-
if (
|
|
790
|
-
value.
|
|
776
|
+
if (_bamboocss_ts_ast.Node.isArrayLiteralExpression(value)) {
|
|
777
|
+
value.elements.forEach((element, index) => {
|
|
791
778
|
const at = path ? `${path}.${index}` : String(index);
|
|
792
779
|
const element_ = resolved?.[index];
|
|
793
|
-
if (
|
|
780
|
+
if (_bamboocss_ts_ast.Node.isSpreadElement(element) && element_ == null) {
|
|
794
781
|
out.push({
|
|
795
782
|
prop: at || void 0,
|
|
796
783
|
reason: "unenumerable-keys"
|
|
@@ -801,17 +788,17 @@ const findUnresolvedInValue = (node, resolved, path, out) => {
|
|
|
801
788
|
});
|
|
802
789
|
return;
|
|
803
790
|
}
|
|
804
|
-
if (!
|
|
805
|
-
const properties = value.
|
|
791
|
+
if (!_bamboocss_ts_ast.Node.isObjectLiteralExpression(value)) return;
|
|
792
|
+
const properties = value.properties;
|
|
806
793
|
const written = [];
|
|
807
794
|
let uncertain = false;
|
|
808
795
|
for (const property of properties) {
|
|
809
|
-
if (
|
|
810
|
-
const spread = (0, _bamboocss_extractor.unwrapExpression)(property.
|
|
811
|
-
if (
|
|
812
|
-
for (const inner of spread.
|
|
813
|
-
if (!
|
|
814
|
-
const innerName =
|
|
796
|
+
if (_bamboocss_ts_ast.Node.isSpreadAssignment(property)) {
|
|
797
|
+
const spread = (0, _bamboocss_extractor.unwrapExpression)(property.expression);
|
|
798
|
+
if (_bamboocss_ts_ast.Node.isObjectLiteralExpression(spread)) {
|
|
799
|
+
for (const inner of spread.properties) {
|
|
800
|
+
if (!_bamboocss_ts_ast.Node.isPropertyAssignment(inner) && !_bamboocss_ts_ast.Node.isShorthandPropertyAssignment(inner)) continue;
|
|
801
|
+
const innerName = (0, _bamboocss_ts_ast.getName)(inner) ?? "";
|
|
815
802
|
if (!innerName.startsWith("[")) written.push(innerName.replace(/^['"]|['"]$/g, ""));
|
|
816
803
|
}
|
|
817
804
|
continue;
|
|
@@ -819,8 +806,8 @@ const findUnresolvedInValue = (node, resolved, path, out) => {
|
|
|
819
806
|
uncertain = true;
|
|
820
807
|
continue;
|
|
821
808
|
}
|
|
822
|
-
if (!
|
|
823
|
-
const name =
|
|
809
|
+
if (!_bamboocss_ts_ast.Node.isPropertyAssignment(property) && !_bamboocss_ts_ast.Node.isShorthandPropertyAssignment(property)) continue;
|
|
810
|
+
const name = (0, _bamboocss_ts_ast.getName)(property) ?? "";
|
|
824
811
|
if (name.startsWith("[")) {
|
|
825
812
|
uncertain = true;
|
|
826
813
|
continue;
|
|
@@ -837,10 +824,10 @@ const findUnresolvedInValue = (node, resolved, path, out) => {
|
|
|
837
824
|
reason: "unenumerable-keys"
|
|
838
825
|
});
|
|
839
826
|
for (const property of properties) {
|
|
840
|
-
if (!
|
|
841
|
-
const name =
|
|
827
|
+
if (!_bamboocss_ts_ast.Node.isPropertyAssignment(property)) continue;
|
|
828
|
+
const name = ((0, _bamboocss_ts_ast.getName)(property) ?? "").replace(/^['"]|['"]$/g, "");
|
|
842
829
|
if (name.startsWith("[")) continue;
|
|
843
|
-
findUnresolvedInValue(property.
|
|
830
|
+
findUnresolvedInValue(property.initializer, resolved?.[name], path ? `${path}.${name}` : name, out);
|
|
844
831
|
}
|
|
845
832
|
};
|
|
846
833
|
/** A recipe config the build could not fully read — see `findUnresolvedInValue`. */
|
|
@@ -849,20 +836,20 @@ const findUnresolvedRecipeStyles = (item) => {
|
|
|
849
836
|
const sourceFile = node?.getSourceFile();
|
|
850
837
|
if (!node || !sourceFile) return [];
|
|
851
838
|
let argument = node;
|
|
852
|
-
if (
|
|
853
|
-
const args = argument.
|
|
839
|
+
if (_bamboocss_ts_ast.Node.isCallExpression(argument)) {
|
|
840
|
+
const args = argument.arguments;
|
|
854
841
|
if (args.length !== 1) return [];
|
|
855
842
|
argument = args[0];
|
|
856
843
|
}
|
|
857
844
|
const losses = [];
|
|
858
845
|
const config = argument ? (0, _bamboocss_extractor.unwrapExpression)(argument) : void 0;
|
|
859
|
-
if (!config || !
|
|
846
|
+
if (!config || !_bamboocss_ts_ast.Node.isObjectLiteralExpression(config)) losses.push({ reason: "unresolvable-value" });
|
|
860
847
|
else findUnresolvedInValue(config, item.data[0], "", losses);
|
|
861
848
|
if (!losses.length) return [];
|
|
862
|
-
const { line, column } =
|
|
849
|
+
const { line, column } = (0, _bamboocss_ts_ast.getLineAndColumnAtPos)(sourceFile, node.getStart());
|
|
863
850
|
return losses.map((loss) => ({
|
|
864
851
|
column,
|
|
865
|
-
filePath:
|
|
852
|
+
filePath: (0, _bamboocss_ts_ast.pathOf)(sourceFile),
|
|
866
853
|
kind: "recipe",
|
|
867
854
|
line,
|
|
868
855
|
...loss
|
|
@@ -892,9 +879,9 @@ const findUnresolvedStyles = (item, kind) => {
|
|
|
892
879
|
if (written.uncertain && !hasKeyOutside(resolved, written.names)) losses.push({ reason: "unenumerable-keys" });
|
|
893
880
|
}
|
|
894
881
|
if (!losses.length) return [];
|
|
895
|
-
const { line, column } =
|
|
882
|
+
const { line, column } = (0, _bamboocss_ts_ast.getLineAndColumnAtPos)(sourceFile, node.getStart());
|
|
896
883
|
const at = {
|
|
897
|
-
filePath:
|
|
884
|
+
filePath: (0, _bamboocss_ts_ast.pathOf)(sourceFile),
|
|
898
885
|
line,
|
|
899
886
|
column
|
|
900
887
|
};
|
|
@@ -1120,7 +1107,7 @@ var ParserResult = class {
|
|
|
1120
1107
|
const visit = (node) => {
|
|
1121
1108
|
if (!node || seen.has(node)) return;
|
|
1122
1109
|
seen.add(node);
|
|
1123
|
-
const path = node.getNode?.()?.getSourceFile()
|
|
1110
|
+
const path = (0, _bamboocss_ts_ast.pathOf)(node.getNode?.()?.getSourceFile())?.replaceAll("\\", "/");
|
|
1124
1111
|
if (path && path !== own) paths.add(path);
|
|
1125
1112
|
if (_bamboocss_extractor.box.isMap(node)) for (const child of node.value.values()) visit(child);
|
|
1126
1113
|
else if (_bamboocss_extractor.box.isArray(node)) for (const child of node.value) visit(child);
|
|
@@ -1172,6 +1159,17 @@ const combineResult = (unboxed) => {
|
|
|
1172
1159
|
...unboxed.spreadConditions
|
|
1173
1160
|
];
|
|
1174
1161
|
};
|
|
1162
|
+
/** The exact binding token accounting visits for a token call. */
|
|
1163
|
+
const tokenCalleeRange = (call) => {
|
|
1164
|
+
if (!_bamboocss_ts_ast.Node.isCallExpression(call)) return void 0;
|
|
1165
|
+
let current = call.expression;
|
|
1166
|
+
while (_bamboocss_ts_ast.Node.isPropertyAccessExpression(current)) current = current.expression;
|
|
1167
|
+
if (!_bamboocss_ts_ast.Node.isIdentifier(current)) return void 0;
|
|
1168
|
+
return {
|
|
1169
|
+
start: current.getStart(),
|
|
1170
|
+
end: current.getEnd()
|
|
1171
|
+
};
|
|
1172
|
+
};
|
|
1175
1173
|
const defaultEnv = { preset: "ECMA" };
|
|
1176
1174
|
/**
|
|
1177
1175
|
* `fallback()` is generated into `styled-system/css`, so evaluating a call to it would mean
|
|
@@ -1185,23 +1183,23 @@ function createParser(context) {
|
|
|
1185
1183
|
const { jsx, imports, recipes } = context;
|
|
1186
1184
|
return function parse(sourceFile, encoder, options, resolveModule) {
|
|
1187
1185
|
if (!sourceFile) return;
|
|
1188
|
-
const importDeclarations = getImportDeclarations(context, sourceFile);
|
|
1186
|
+
const importDeclarations = getImportDeclarations$1(context, sourceFile);
|
|
1189
1187
|
const file = imports.file(importDeclarations);
|
|
1190
|
-
const filePath =
|
|
1188
|
+
const filePath = (0, _bamboocss_ts_ast.pathOf)(sourceFile);
|
|
1191
1189
|
_bamboocss_logger.logger.debug("ast:import", !file.isEmpty() ? `Found import { ${file.toString()} } in ${filePath}` : `No import found in ${filePath}`);
|
|
1192
1190
|
const parserResult = new ParserResult(context, encoder);
|
|
1193
1191
|
const importedRecipes = resolveModule ? importedRecipeBindings(sourceFile, imports, resolveModule) : /* @__PURE__ */ new Map();
|
|
1194
1192
|
if (file.isEmpty() && !jsx.isEnabled && importedRecipes.size === 0) return parserResult;
|
|
1195
1193
|
parserResult.importedRecipes = importedRecipes;
|
|
1196
1194
|
for (const binding of importedRecipes.keys()) file.addLocalRecipe(binding);
|
|
1197
|
-
if (file.importsRecipeFactory()) for (const statement of sourceFile.
|
|
1198
|
-
if (!
|
|
1199
|
-
if (!(statement.declarationList.flags &
|
|
1195
|
+
if (file.importsRecipeFactory()) for (const statement of sourceFile.statements) {
|
|
1196
|
+
if (!_bamboocss_ts_ast.ts.isVariableStatement(statement)) continue;
|
|
1197
|
+
if (!(statement.declarationList.flags & _bamboocss_ts_ast.ts.NodeFlags.Const)) continue;
|
|
1200
1198
|
for (const declaration of statement.declarationList.declarations) {
|
|
1201
1199
|
const initializer = declaration.initializer;
|
|
1202
|
-
if (!initializer || !
|
|
1200
|
+
if (!initializer || !_bamboocss_ts_ast.ts.isCallExpression(initializer)) continue;
|
|
1203
1201
|
const callee = initializer.expression;
|
|
1204
|
-
if (!
|
|
1202
|
+
if (!_bamboocss_ts_ast.ts.isIdentifier(callee) || !_bamboocss_ts_ast.ts.isIdentifier(declaration.name)) continue;
|
|
1205
1203
|
const imported = file.getName(callee.text);
|
|
1206
1204
|
if (imported !== "cva" && imported !== "sva") continue;
|
|
1207
1205
|
if (!file.matchFn(callee.text)) continue;
|
|
@@ -1219,7 +1217,7 @@ function createParser(context) {
|
|
|
1219
1217
|
* Defined out here rather than inside `getEvaluateOptions`, which runs per call node.
|
|
1220
1218
|
*/
|
|
1221
1219
|
const reportUnresolvedRaw = (base, at) => {
|
|
1222
|
-
const { line, column } =
|
|
1220
|
+
const { line, column } = (0, _bamboocss_ts_ast.getLineAndColumnAtPos)(sourceFile, at.getStart());
|
|
1223
1221
|
parserResult.unresolved.push({
|
|
1224
1222
|
kind: "atomic",
|
|
1225
1223
|
prop: base,
|
|
@@ -1261,14 +1259,14 @@ function createParser(context) {
|
|
|
1261
1259
|
matchArg: () => true
|
|
1262
1260
|
},
|
|
1263
1261
|
getEvaluateOptions: (node) => {
|
|
1264
|
-
if (!
|
|
1265
|
-
const propAccessExpr = node.
|
|
1266
|
-
if (
|
|
1262
|
+
if (!_bamboocss_ts_ast.Node.isCallExpression(node)) return evaluateOptions;
|
|
1263
|
+
const propAccessExpr = node.expression;
|
|
1264
|
+
if (_bamboocss_ts_ast.Node.isIdentifier(propAccessExpr)) {
|
|
1267
1265
|
const local = propAccessExpr.getText();
|
|
1268
1266
|
if (!file.match(local) || file.getName(local) !== "fallback") return evaluateOptions;
|
|
1269
1267
|
return { environment: Object.assign({}, defaultEnv, { extra: { [local]: fallbackImpl } }) };
|
|
1270
1268
|
}
|
|
1271
|
-
if (!
|
|
1269
|
+
if (!_bamboocss_ts_ast.Node.isPropertyAccessExpression(propAccessExpr)) return evaluateOptions;
|
|
1272
1270
|
let name = propAccessExpr.getText();
|
|
1273
1271
|
const rawBase = name.endsWith(".raw") ? name.slice(0, -4) : void 0;
|
|
1274
1272
|
if (rawBase && file.isLocalRecipe(rawBase)) {
|
|
@@ -1307,7 +1305,8 @@ function createParser(context) {
|
|
|
1307
1305
|
if (query.kind === "call-expression") parserResult.setToken({
|
|
1308
1306
|
name: "token.value",
|
|
1309
1307
|
box: query.box.value[0] ?? _bamboocss_extractor.box.fallback(query.box),
|
|
1310
|
-
data: combineResult((0, _bamboocss_extractor.unbox)(query.box.value[0]))
|
|
1308
|
+
data: combineResult((0, _bamboocss_extractor.unbox)(query.box.value[0])),
|
|
1309
|
+
tokenCalleeRange: tokenCalleeRange(query.box.getNode())
|
|
1311
1310
|
}, "tokenValue");
|
|
1312
1311
|
});
|
|
1313
1312
|
return;
|
|
@@ -1330,12 +1329,13 @@ function createParser(context) {
|
|
|
1330
1329
|
if (query.kind === "call-expression") parserResult.setToken({
|
|
1331
1330
|
name,
|
|
1332
1331
|
box: query.box.value[0] ?? _bamboocss_extractor.box.fallback(query.box),
|
|
1333
|
-
data: combineResult((0, _bamboocss_extractor.unbox)(query.box.value[0]))
|
|
1332
|
+
data: combineResult((0, _bamboocss_extractor.unbox)(query.box.value[0])),
|
|
1333
|
+
tokenCalleeRange: tokenCalleeRange(query.box.getNode())
|
|
1334
1334
|
});
|
|
1335
1335
|
});
|
|
1336
1336
|
}).when(file.isValidPattern, (name) => {
|
|
1337
1337
|
result.queryList.forEach((query) => {
|
|
1338
|
-
if (query.kind === "call-expression") parserResult.setPattern(name, {
|
|
1338
|
+
if (query.kind === "call-expression") parserResult.setPattern(name ?? "", {
|
|
1339
1339
|
name,
|
|
1340
1340
|
box: query.box.value[0] ?? _bamboocss_extractor.box.fallback(query.box),
|
|
1341
1341
|
data: combineResult((0, _bamboocss_extractor.unbox)(query.box.value[0]))
|
|
@@ -1343,7 +1343,7 @@ function createParser(context) {
|
|
|
1343
1343
|
});
|
|
1344
1344
|
}).when(file.isValidRecipe, (name) => {
|
|
1345
1345
|
result.queryList.forEach((query) => {
|
|
1346
|
-
if (query.kind === "call-expression") parserResult.setRecipe(name, {
|
|
1346
|
+
if (query.kind === "call-expression") parserResult.setRecipe(name ?? "", {
|
|
1347
1347
|
name,
|
|
1348
1348
|
box: query.box.value[0] ?? _bamboocss_extractor.box.fallback(query.box),
|
|
1349
1349
|
data: combineResult((0, _bamboocss_extractor.unbox)(query.box.value[0]))
|
|
@@ -1361,8 +1361,8 @@ function createParser(context) {
|
|
|
1361
1361
|
} else if (jsx.isEnabled && result.kind === "component") result.queryList.forEach((query) => {
|
|
1362
1362
|
const data = combineResult((0, _bamboocss_extractor.unbox)(query.box));
|
|
1363
1363
|
for (const tag of [name, alias]) {
|
|
1364
|
-
if (!jsx.isJsxTagRecipe(tag)) continue;
|
|
1365
|
-
recipes.filter(tag).forEach((recipe) => {
|
|
1364
|
+
if (!jsx.isJsxTagRecipe(tag ?? "")) continue;
|
|
1365
|
+
recipes.filter(tag ?? "").forEach((recipe) => {
|
|
1366
1366
|
parserResult.setRecipe(recipe.baseName, {
|
|
1367
1367
|
type: "jsx-recipe",
|
|
1368
1368
|
name: tag,
|
|
@@ -1375,19 +1375,16 @@ function createParser(context) {
|
|
|
1375
1375
|
});
|
|
1376
1376
|
});
|
|
1377
1377
|
parserResult.deadCalls = file.getDeadCalls();
|
|
1378
|
-
if (exportReadPairs.size) {
|
|
1379
|
-
const
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
};
|
|
1389
|
-
}));
|
|
1390
|
-
}
|
|
1378
|
+
if (exportReadPairs.size) parserResult.setExportReads([...exportReadPairs].map((pair) => {
|
|
1379
|
+
const at = pair.indexOf("\0");
|
|
1380
|
+
const file = pair.slice(0, at);
|
|
1381
|
+
const name = pair.slice(at + 1);
|
|
1382
|
+
return {
|
|
1383
|
+
file,
|
|
1384
|
+
name,
|
|
1385
|
+
digest: digestExportValue(resolveModule?.(file, sourceFile), name, resolveModule)
|
|
1386
|
+
};
|
|
1387
|
+
}));
|
|
1391
1388
|
return parserResult;
|
|
1392
1389
|
};
|
|
1393
1390
|
}
|
|
@@ -1404,11 +1401,16 @@ const invalidateResolutions = () => {
|
|
|
1404
1401
|
(0, _bamboocss_extractor.clearBoxNodeCache)();
|
|
1405
1402
|
clearImportedRecipeCache();
|
|
1406
1403
|
};
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1404
|
+
/**
|
|
1405
|
+
* Compiler options as given.
|
|
1406
|
+
*
|
|
1407
|
+
* TypeScript 6 needed `convertCompilerOptionsFromJson` to turn a tsconfig's JSON spellings —
|
|
1408
|
+
* `"target": "esnext"`, relative `paths` — into the enum values and absolute paths a program
|
|
1409
|
+
* consumed. TypeScript 7 parses the tsconfig in the Go process and hands back options already
|
|
1410
|
+
* in that form, so there is nothing left to convert; the argument survives because callers pass
|
|
1411
|
+
* overrides that are already normalized.
|
|
1412
|
+
*/
|
|
1413
|
+
const normalizeCompilerOptions = (raw, _basePath = process.cwd()) => raw ?? {};
|
|
1412
1414
|
/** Snapshot the JSON-shaped ts-morph options while retaining opaque hosts and callbacks. */
|
|
1413
1415
|
const snapshotProjectOption = (value) => {
|
|
1414
1416
|
if (Array.isArray(value)) return value.map(snapshotProjectOption);
|
|
@@ -1438,7 +1440,7 @@ const prepareTsProjectOptions = (options, snapshotNested = false, compilerOption
|
|
|
1438
1440
|
}
|
|
1439
1441
|
};
|
|
1440
1442
|
};
|
|
1441
|
-
const createTsProject = (options) => new
|
|
1443
|
+
const createTsProject = (options) => new _bamboocss_ts_ast.Project(options);
|
|
1442
1444
|
/** Filesystem errors proving a lexical candidate cannot name a resolvable file. */
|
|
1443
1445
|
const isMissingPathShapeError = (error) => {
|
|
1444
1446
|
const code = error?.code;
|
|
@@ -1482,7 +1484,7 @@ const setProjectOnReceiver = (receiver, project) => {
|
|
|
1482
1484
|
*/
|
|
1483
1485
|
const scriptKindFor = (filePath) => {
|
|
1484
1486
|
const extension = filePath.slice(filePath.lastIndexOf(".")).toLowerCase();
|
|
1485
|
-
return extension === ".ts" || extension === ".mts" || extension === ".cts" ?
|
|
1487
|
+
return extension === ".ts" || extension === ".mts" || extension === ".cts" ? _bamboocss_ts_ast.ScriptKind.TS : _bamboocss_ts_ast.ScriptKind.TSX;
|
|
1486
1488
|
};
|
|
1487
1489
|
var Project = class {
|
|
1488
1490
|
/**
|
|
@@ -1619,32 +1621,33 @@ var Project = class {
|
|
|
1619
1621
|
this.#assertSourceFilesAccessor();
|
|
1620
1622
|
const revision = this.#sourceFiles.revision;
|
|
1621
1623
|
this.#sourceFiles.phase = "loading";
|
|
1624
|
+
let candidate;
|
|
1622
1625
|
try {
|
|
1623
|
-
|
|
1626
|
+
candidate = createTsProject(this.#sourceFiles.projectOptions);
|
|
1624
1627
|
this.#assertSourceFilesTransaction(revision);
|
|
1625
1628
|
let loaded = 0;
|
|
1629
|
+
const entries = [];
|
|
1626
1630
|
for (const [index, file] of this.#sourceFiles.initialFiles.entries()) try {
|
|
1627
1631
|
const content = read(file, index);
|
|
1628
1632
|
this.#assertSourceFilesTransaction(revision);
|
|
1629
|
-
|
|
1630
|
-
overwrite: true,
|
|
1631
|
-
scriptKind: scriptKindFor(file)
|
|
1632
|
-
});
|
|
1633
|
+
entries.push([file, content]);
|
|
1633
1634
|
this.#assertSourceFilesTransaction(revision);
|
|
1634
1635
|
loaded++;
|
|
1635
1636
|
} catch (error) {
|
|
1636
1637
|
this.#assertSourceFilesTransaction(revision);
|
|
1637
1638
|
if (!skipMissing || error?.code !== "ENOENT") throw error;
|
|
1638
1639
|
}
|
|
1640
|
+
candidate.addSourceFiles(entries);
|
|
1639
1641
|
this.#assertSourceFilesTransaction(revision);
|
|
1640
1642
|
if (loaded > 0) invalidateResolutions();
|
|
1641
|
-
this.#
|
|
1643
|
+
this.#resolver = void 0;
|
|
1642
1644
|
this.#fileTreeRevision++;
|
|
1643
1645
|
this.#assertSourceFilesTransaction(revision);
|
|
1644
1646
|
this.#sourceFiles.project = candidate;
|
|
1645
1647
|
this.#sourceFiles.phase = "ready";
|
|
1646
1648
|
return;
|
|
1647
1649
|
} catch (error) {
|
|
1650
|
+
candidate?.dispose();
|
|
1648
1651
|
this.#sourceFiles.project = void 0;
|
|
1649
1652
|
this.#sourceFiles.phase = "pending";
|
|
1650
1653
|
throw error;
|
|
@@ -1717,7 +1720,7 @@ var Project = class {
|
|
|
1717
1720
|
sourceFilesRead: 0
|
|
1718
1721
|
};
|
|
1719
1722
|
resetResolutionState = () => {
|
|
1720
|
-
this.#
|
|
1723
|
+
this.#resolver = void 0;
|
|
1721
1724
|
this.#fileTreeRevision++;
|
|
1722
1725
|
this.dependents = /* @__PURE__ */ new Map();
|
|
1723
1726
|
this.dependencies = /* @__PURE__ */ new Map();
|
|
@@ -1758,12 +1761,24 @@ var Project = class {
|
|
|
1758
1761
|
};
|
|
1759
1762
|
getSourceFile = (filePath) => {
|
|
1760
1763
|
this.#assertNotLoading();
|
|
1764
|
+
if (!this.project.has(filePath)) return void 0;
|
|
1761
1765
|
return this.project.getSourceFile(filePath);
|
|
1762
1766
|
};
|
|
1767
|
+
/**
|
|
1768
|
+
* How many syntax errors this file's parse produced.
|
|
1769
|
+
*
|
|
1770
|
+
* Asked by the token accounting, which may only speak for a file whose tree it can trust: a
|
|
1771
|
+
* construct the parser could not read leaves an ast that stops early, and every call below
|
|
1772
|
+
* the offending line silently ceases to exist. Zero means the file parsed as written.
|
|
1773
|
+
*/
|
|
1774
|
+
getSyntacticDiagnosticCount = (filePath) => {
|
|
1775
|
+
this.#assertNotLoading();
|
|
1776
|
+
return this.project.getSyntacticDiagnosticCount(filePath);
|
|
1777
|
+
};
|
|
1763
1778
|
/** ts-morph reports forward slashes; normalize callers' paths to match on Windows. */
|
|
1764
1779
|
normalizePath = (filePath) => filePath.replaceAll("\\", "/");
|
|
1765
1780
|
/** Shared filesystem-only resolution cache; no type checker is constructed. */
|
|
1766
|
-
#
|
|
1781
|
+
#resolver;
|
|
1767
1782
|
/**
|
|
1768
1783
|
* Everything memoized against the shape of the file tree, including the negative half.
|
|
1769
1784
|
*
|
|
@@ -1796,7 +1811,7 @@ var Project = class {
|
|
|
1796
1811
|
}
|
|
1797
1812
|
invalidateResolutions();
|
|
1798
1813
|
if (fileTreeChanged) {
|
|
1799
|
-
this.#
|
|
1814
|
+
this.#resolver = void 0;
|
|
1800
1815
|
this.#fileTreeRevision++;
|
|
1801
1816
|
}
|
|
1802
1817
|
};
|
|
@@ -1819,17 +1834,10 @@ var Project = class {
|
|
|
1819
1834
|
...this.#sourceFiles.projectOptions,
|
|
1820
1835
|
compilerOptions: snapshotProjectOption(next)
|
|
1821
1836
|
};
|
|
1822
|
-
|
|
1823
|
-
const current = this.project.getCompilerOptions();
|
|
1824
|
-
const cleared = Object.fromEntries(Object.keys(current).map((key) => [key, void 0]));
|
|
1825
|
-
this.project.compilerOptions.set({
|
|
1826
|
-
...cleared,
|
|
1827
|
-
...next
|
|
1828
|
-
});
|
|
1829
|
-
}
|
|
1837
|
+
this.#sourceFiles.project?.setCompilerOptions(next);
|
|
1830
1838
|
}
|
|
1831
1839
|
invalidateResolutions();
|
|
1832
|
-
this.#
|
|
1840
|
+
this.#resolver = void 0;
|
|
1833
1841
|
this.#fileTreeRevision++;
|
|
1834
1842
|
this.sourcePreparations.clear();
|
|
1835
1843
|
};
|
|
@@ -1875,33 +1883,33 @@ var Project = class {
|
|
|
1875
1883
|
this.#assertNotLoading();
|
|
1876
1884
|
const project = this.project;
|
|
1877
1885
|
const compilerOptions = project.getCompilerOptions();
|
|
1878
|
-
this.#moduleResolutionCache ??= ts_morph.ts.createModuleResolutionCache(project.getFileSystem().getCurrentDirectory(), (f) => f, compilerOptions);
|
|
1879
1886
|
const configurationFiles = /* @__PURE__ */ new Set();
|
|
1880
|
-
const resolutionHost = project.getModuleResolutionHost();
|
|
1881
1887
|
const recordConfigurationFile = (filePath) => {
|
|
1882
1888
|
const normalized = this.normalizePath(filePath);
|
|
1883
1889
|
if (!normalized.endsWith("/package.json") || normalized.includes("/node_modules/")) return;
|
|
1884
1890
|
if (!this.isInCheckout(normalized)) return;
|
|
1885
1891
|
configurationFiles.add(normalized);
|
|
1886
1892
|
};
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
},
|
|
1893
|
-
readFile: (filePath) => {
|
|
1894
|
-
recordConfigurationFile(filePath);
|
|
1895
|
-
return resolutionHost.readFile?.(filePath);
|
|
1893
|
+
this.#resolver ??= (0, _bamboocss_ts_ast.createResolver)({
|
|
1894
|
+
cwd: project.getCurrentDirectory(),
|
|
1895
|
+
fs: {
|
|
1896
|
+
fileExists: (filePath) => project.fileExists(filePath),
|
|
1897
|
+
readFile: (filePath) => project.readFile(filePath)
|
|
1896
1898
|
}
|
|
1897
|
-
};
|
|
1899
|
+
});
|
|
1900
|
+
const configured = this.#sourceFiles.projectOptions.compilerOptions ?? compilerOptions;
|
|
1898
1901
|
this.resolutionWork.moduleResolutionsAttempted++;
|
|
1899
|
-
const resolved =
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
const
|
|
1902
|
+
const resolved = this.#resolver(moduleName, {
|
|
1903
|
+
importer: (0, _bamboocss_ts_ast.pathOf)(from),
|
|
1904
|
+
baseUrl: configured?.baseUrl,
|
|
1905
|
+
paths: configured?.paths
|
|
1906
|
+
});
|
|
1907
|
+
for (const filePath of resolved.affectingFiles) recordConfigurationFile(filePath);
|
|
1908
|
+
const pendingCandidates = this.getLocalFailedLookupCandidates(resolved.failedLookups);
|
|
1909
|
+
const module = resolved.path ? {
|
|
1910
|
+
resolvedFileName: resolved.path,
|
|
1911
|
+
isExternalLibraryImport: resolved.path.includes("/node_modules/")
|
|
1912
|
+
} : void 0;
|
|
1905
1913
|
if (!module) return {
|
|
1906
1914
|
configurationFiles: [...configurationFiles].sort(),
|
|
1907
1915
|
local: this.isUnresolvedLocalSpecifier(moduleName, pendingCandidates) || moduleName.startsWith("#"),
|
|
@@ -1918,7 +1926,7 @@ var Project = class {
|
|
|
1918
1926
|
local: this.isUnresolvedLocalSpecifier(moduleName, pendingCandidates),
|
|
1919
1927
|
pendingCandidates
|
|
1920
1928
|
};
|
|
1921
|
-
const existing = project.getSourceFile(name);
|
|
1929
|
+
const existing = this.project.has(name) ? project.getSourceFile(name) : void 0;
|
|
1922
1930
|
if (existing) {
|
|
1923
1931
|
this.removedSourcePaths.delete(name);
|
|
1924
1932
|
return {
|
|
@@ -1937,12 +1945,10 @@ var Project = class {
|
|
|
1937
1945
|
try {
|
|
1938
1946
|
this.resolutionWork.sourceFilesRead++;
|
|
1939
1947
|
const content = project.getFileSystem().readFileSync(name);
|
|
1940
|
-
const sourceFile = project.createSourceFile(name, content, {
|
|
1941
|
-
|
|
1942
|
-
scriptKind: scriptKindFor(name)
|
|
1943
|
-
});
|
|
1948
|
+
const sourceFile = project.createSourceFile(name, content, { scriptKind: scriptKindFor(name) });
|
|
1949
|
+
if (!sourceFile) throw new Error(`bamboo: resolved ${name} but the project produced no source file`);
|
|
1944
1950
|
this.resolutionWork.sourceFilesAdded++;
|
|
1945
|
-
this.canonicalPaths.set(name, this.normalizePath(
|
|
1951
|
+
this.canonicalPaths.set(name, this.normalizePath((0, _bamboocss_ts_ast.pathOf)(sourceFile)));
|
|
1946
1952
|
return {
|
|
1947
1953
|
configurationFiles: [...configurationFiles].sort(),
|
|
1948
1954
|
local: true,
|
|
@@ -1996,28 +2002,28 @@ var Project = class {
|
|
|
1996
2002
|
};
|
|
1997
2003
|
ensureResolutionFacts = (sourceFile) => {
|
|
1998
2004
|
this.#assertNotLoading();
|
|
1999
|
-
const importer = this.normalizePath(
|
|
2005
|
+
const importer = this.normalizePath((0, _bamboocss_ts_ast.pathOf)(sourceFile));
|
|
2000
2006
|
const text = sourceFile.getFullText();
|
|
2001
2007
|
const cached = this.resolutionsByImporter.get(importer);
|
|
2002
2008
|
if (cached?.sourceFile === sourceFile && cached.text === text && cached.treeRevision === this.#fileTreeRevision) return cached;
|
|
2003
|
-
const declarations = [...
|
|
2009
|
+
const declarations = [...(0, _bamboocss_ts_ast.getImportDeclarations)(sourceFile).map((declaration) => ({
|
|
2004
2010
|
declaration,
|
|
2005
2011
|
kind: "import"
|
|
2006
|
-
})), ...
|
|
2012
|
+
})), ...(0, _bamboocss_ts_ast.getExportDeclarations)(sourceFile).map((declaration) => ({
|
|
2007
2013
|
declaration,
|
|
2008
2014
|
kind: "export"
|
|
2009
|
-
}))].filter(({ declaration }) =>
|
|
2015
|
+
}))].filter(({ declaration }) => (0, _bamboocss_ts_ast.getModuleSpecifierValue)(declaration) !== void 0).sort((left, right) => left.declaration.getStart() - right.declaration.getStart());
|
|
2010
2016
|
const facts = [];
|
|
2011
2017
|
const pendingCandidates = [];
|
|
2012
2018
|
const configurationFiles = [];
|
|
2013
2019
|
for (const [ordinal, { declaration, kind }] of declarations.entries()) {
|
|
2014
|
-
const specifier =
|
|
2020
|
+
const specifier = (0, _bamboocss_ts_ast.getModuleSpecifierValue)(declaration);
|
|
2015
2021
|
if (!specifier) continue;
|
|
2016
2022
|
const resolved = this.resolveSpecifier(specifier, sourceFile);
|
|
2017
2023
|
if (!resolved.local) continue;
|
|
2018
2024
|
facts.push(Object.freeze({
|
|
2019
2025
|
importer,
|
|
2020
|
-
target: resolved.sourceFile ? this.normalizePath(resolved.sourceFile
|
|
2026
|
+
target: resolved.sourceFile ? this.normalizePath((0, _bamboocss_ts_ast.pathOf)(resolved.sourceFile)) : null,
|
|
2021
2027
|
specifier,
|
|
2022
2028
|
kind,
|
|
2023
2029
|
ordinal
|
|
@@ -2042,22 +2048,22 @@ var Project = class {
|
|
|
2042
2048
|
};
|
|
2043
2049
|
/** The sole cross-file source resolver supplied to parser and extractor. */
|
|
2044
2050
|
resolveModule = (specifier, from) => {
|
|
2045
|
-
const target = this.ensureResolutionFacts(from).facts.find((fact) => fact.specifier === specifier)?.target;
|
|
2051
|
+
const target = this.ensureResolutionFacts(from).facts.find((fact) => fact.specifier === specifier)?.target ?? (specifier.startsWith("/") ? specifier : void 0);
|
|
2046
2052
|
if (!target) return;
|
|
2047
2053
|
const sourceFile = this.project.getSourceFile(target);
|
|
2048
2054
|
if (!sourceFile) return;
|
|
2049
|
-
this.prepareEffectiveSource(
|
|
2055
|
+
this.prepareEffectiveSource((0, _bamboocss_ts_ast.pathOf)(sourceFile), sourceFile);
|
|
2050
2056
|
return sourceFile;
|
|
2051
2057
|
};
|
|
2052
2058
|
trackDependencies = (filePath, sourceFile) => {
|
|
2053
2059
|
this.#assertNotLoading();
|
|
2054
|
-
const importer = this.normalizePath(
|
|
2060
|
+
const importer = this.normalizePath((0, _bamboocss_ts_ast.pathOf)(sourceFile));
|
|
2055
2061
|
this.canonicalPaths.set(this.normalizePath(filePath), importer);
|
|
2056
2062
|
this.canonicalPaths.set(importer, importer);
|
|
2057
2063
|
this.ensureResolutionFacts(sourceFile);
|
|
2058
2064
|
};
|
|
2059
2065
|
invalidateSourcePreparation = (filePath, sourceFile) => {
|
|
2060
|
-
const sourcePath = this.normalizePath(
|
|
2066
|
+
const sourcePath = this.normalizePath((0, _bamboocss_ts_ast.pathOf)(sourceFile) ?? filePath);
|
|
2061
2067
|
const preparation = this.sourcePreparations.get(sourcePath);
|
|
2062
2068
|
if (preparation?.state === "preparing") preparation.invalidated = true;
|
|
2063
2069
|
this.sourcePreparations.delete(sourcePath);
|
|
@@ -2073,7 +2079,7 @@ var Project = class {
|
|
|
2073
2079
|
*/
|
|
2074
2080
|
prepareEffectiveSource = (filePath, sourceFile, hookFilePath = filePath) => {
|
|
2075
2081
|
this.#assertNotLoading();
|
|
2076
|
-
const sourcePath = this.normalizePath(
|
|
2082
|
+
const sourcePath = this.normalizePath((0, _bamboocss_ts_ast.pathOf)(sourceFile));
|
|
2077
2083
|
const currentText = sourceFile.getFullText();
|
|
2078
2084
|
const current = this.sourcePreparations.get(sourcePath);
|
|
2079
2085
|
if (current?.state === "ready" && current.sourceFile === sourceFile && current.effectiveText === currentText) {
|
|
@@ -2118,7 +2124,7 @@ var Project = class {
|
|
|
2118
2124
|
assertTransaction(currentText);
|
|
2119
2125
|
const transformed = custom ?? this.transformFile(hookFilePath, currentText);
|
|
2120
2126
|
assertTransaction(currentText);
|
|
2121
|
-
if (currentText !== transformed) sourceFile.
|
|
2127
|
+
if (currentText !== transformed) sourceFile = this.project.addSourceFile(filePath, transformed) ?? sourceFile;
|
|
2122
2128
|
assertTransaction(transformed);
|
|
2123
2129
|
this.trackDependencies(filePath, sourceFile);
|
|
2124
2130
|
assertTransaction(transformed);
|
|
@@ -2135,7 +2141,7 @@ var Project = class {
|
|
|
2135
2141
|
if (this.sourcePreparations.get(sourcePath) === transaction) this.sourcePreparations.delete(sourcePath);
|
|
2136
2142
|
this.retractImporter(sourcePath);
|
|
2137
2143
|
try {
|
|
2138
|
-
if (sourceFile.getFullText() !== currentText)
|
|
2144
|
+
if (sourceFile.getFullText() !== currentText) this.project.addSourceFile(filePath, currentText);
|
|
2139
2145
|
} catch {}
|
|
2140
2146
|
throw error;
|
|
2141
2147
|
}
|
|
@@ -2162,7 +2168,7 @@ var Project = class {
|
|
|
2162
2168
|
this.retractImporter(target);
|
|
2163
2169
|
this.removedSourcePaths.add(target);
|
|
2164
2170
|
this.canonicalPaths.set(target, target);
|
|
2165
|
-
this.canonicalPaths.set(this.normalizePath(
|
|
2171
|
+
this.canonicalPaths.set(this.normalizePath((0, _bamboocss_ts_ast.pathOf)(sourceFile)), target);
|
|
2166
2172
|
};
|
|
2167
2173
|
/**
|
|
2168
2174
|
* Every file that transitively imports `filePath`, so a watcher can re-parse the
|
|
@@ -2171,7 +2177,7 @@ var Project = class {
|
|
|
2171
2177
|
getDependents = (filePath) => {
|
|
2172
2178
|
this.#assertNotLoading();
|
|
2173
2179
|
const given = this.normalizePath(filePath);
|
|
2174
|
-
const resolved = this.project.getSourceFile(filePath)
|
|
2180
|
+
const resolved = (0, _bamboocss_ts_ast.pathOf)(this.project.getSourceFile(filePath));
|
|
2175
2181
|
const start = resolved ? this.normalizePath(resolved) : this.canonicalPaths.get(given) ?? given;
|
|
2176
2182
|
const seen = /* @__PURE__ */ new Set();
|
|
2177
2183
|
const queue = [start];
|
|
@@ -2199,7 +2205,7 @@ var Project = class {
|
|
|
2199
2205
|
getDependencies = (filePath, targets) => {
|
|
2200
2206
|
this.#assertNotLoading();
|
|
2201
2207
|
const given = this.normalizePath(filePath);
|
|
2202
|
-
const resolved = this.project.getSourceFile(filePath)
|
|
2208
|
+
const resolved = (0, _bamboocss_ts_ast.pathOf)(this.project.getSourceFile(filePath));
|
|
2203
2209
|
const start = resolved ? this.normalizePath(resolved) : this.canonicalPaths.get(given) ?? given;
|
|
2204
2210
|
const seen = /* @__PURE__ */ new Set();
|
|
2205
2211
|
const importersByDependency = /* @__PURE__ */ new Map();
|
|
@@ -2220,7 +2226,7 @@ var Project = class {
|
|
|
2220
2226
|
const selected = /* @__PURE__ */ new Set();
|
|
2221
2227
|
const reverse = Array.from(targets, (target) => {
|
|
2222
2228
|
const normalized = this.normalizePath(target);
|
|
2223
|
-
const source = this.project.getSourceFile(target)
|
|
2229
|
+
const source = (0, _bamboocss_ts_ast.pathOf)(this.project.getSourceFile(target));
|
|
2224
2230
|
return source ? this.normalizePath(source) : this.canonicalPaths.get(normalized) ?? normalized;
|
|
2225
2231
|
}).filter((target) => seen.has(target));
|
|
2226
2232
|
let reverseCursor = 0;
|
|
@@ -2246,7 +2252,7 @@ var Project = class {
|
|
|
2246
2252
|
const selected = new Set(dependencies);
|
|
2247
2253
|
const retained = new Set([...previous?.dependencies ?? [], ...previous?.pendingCandidates ?? []]);
|
|
2248
2254
|
const given = this.normalizePath(filePath);
|
|
2249
|
-
const resolved = this.project.getSourceFile(filePath)
|
|
2255
|
+
const resolved = (0, _bamboocss_ts_ast.pathOf)(this.project.getSourceFile(filePath));
|
|
2250
2256
|
const start = resolved ? this.normalizePath(resolved) : this.canonicalPaths.get(given) ?? given;
|
|
2251
2257
|
const pendingCandidates = /* @__PURE__ */ new Set();
|
|
2252
2258
|
for (const importer of [start, ...dependencies]) {
|
|
@@ -2279,7 +2285,7 @@ var Project = class {
|
|
|
2279
2285
|
const selected = new Set(dependencies);
|
|
2280
2286
|
const retained = new Set(Array.from(previous, (file) => this.normalizePath(file)));
|
|
2281
2287
|
const given = this.normalizePath(filePath);
|
|
2282
|
-
const resolved = this.project.getSourceFile(filePath)
|
|
2288
|
+
const resolved = (0, _bamboocss_ts_ast.pathOf)(this.project.getSourceFile(filePath));
|
|
2283
2289
|
const start = resolved ? this.normalizePath(resolved) : this.canonicalPaths.get(given) ?? given;
|
|
2284
2290
|
const files = /* @__PURE__ */ new Set();
|
|
2285
2291
|
let hasSemanticFact = false;
|
|
@@ -2306,10 +2312,9 @@ var Project = class {
|
|
|
2306
2312
|
this.invalidateSourcePreparation(filePath, existing);
|
|
2307
2313
|
this.removedSourcePaths.delete(this.normalizePath(filePath));
|
|
2308
2314
|
this.invalidate();
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
});
|
|
2315
|
+
const created = this.project.createSourceFile(filePath, content, { scriptKind: scriptKindFor(filePath) });
|
|
2316
|
+
if (!created) throw new Error(`bamboo: could not add ${filePath} to the project`);
|
|
2317
|
+
return created;
|
|
2313
2318
|
};
|
|
2314
2319
|
createSourceFiles = () => {
|
|
2315
2320
|
this.#assertNotLoading();
|
|
@@ -2348,17 +2353,15 @@ var Project = class {
|
|
|
2348
2353
|
* matches its own source, falls through, and is overwritten exactly as before.
|
|
2349
2354
|
*/
|
|
2350
2355
|
if (existing && existing.getFullText() === content) {
|
|
2351
|
-
this.markAuxiliary(
|
|
2356
|
+
this.markAuxiliary((0, _bamboocss_ts_ast.pathOf)(existing), options.auxiliary);
|
|
2352
2357
|
return existing;
|
|
2353
2358
|
}
|
|
2354
2359
|
this.invalidateSourcePreparation(filePath, existing);
|
|
2355
2360
|
this.removedSourcePaths.delete(this.normalizePath(filePath));
|
|
2356
|
-
this.invalidate(!existing,
|
|
2357
|
-
const sourceFile = this.project.createSourceFile(filePath, content, {
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
});
|
|
2361
|
-
this.markAuxiliary(sourceFile.getFilePath(), options.auxiliary);
|
|
2361
|
+
this.invalidate(!existing, (0, _bamboocss_ts_ast.pathOf)(existing));
|
|
2362
|
+
const sourceFile = this.project.createSourceFile(filePath, content, { scriptKind: scriptKindFor(filePath) });
|
|
2363
|
+
if (!sourceFile) throw new Error(`bamboo: could not add ${filePath} to the project`);
|
|
2364
|
+
this.markAuxiliary((0, _bamboocss_ts_ast.pathOf)(sourceFile), options.auxiliary);
|
|
2362
2365
|
return sourceFile;
|
|
2363
2366
|
};
|
|
2364
2367
|
/** Claim or release compiler ownership of one source, in the ledger's own spelling. */
|
|
@@ -2374,10 +2377,10 @@ var Project = class {
|
|
|
2374
2377
|
if (sourceFile) {
|
|
2375
2378
|
this.invalidate();
|
|
2376
2379
|
this.invalidateSourcePreparation(filePath, sourceFile);
|
|
2377
|
-
this.markTargetRemoved(this.normalizePath(
|
|
2378
|
-
this.options.parserOptions.encoder.releaseFile(
|
|
2379
|
-
this.auxiliarySources.delete(this.normalizePath(
|
|
2380
|
-
return this.project.removeSourceFile(sourceFile);
|
|
2380
|
+
this.markTargetRemoved(this.normalizePath((0, _bamboocss_ts_ast.pathOf)(sourceFile)), sourceFile);
|
|
2381
|
+
this.options.parserOptions.encoder.releaseFile((0, _bamboocss_ts_ast.pathOf)(sourceFile));
|
|
2382
|
+
this.auxiliarySources.delete(this.normalizePath((0, _bamboocss_ts_ast.pathOf)(sourceFile)));
|
|
2383
|
+
return this.project.removeSourceFile((0, _bamboocss_ts_ast.pathOf)(sourceFile));
|
|
2381
2384
|
}
|
|
2382
2385
|
return false;
|
|
2383
2386
|
};
|
|
@@ -2396,10 +2399,10 @@ var Project = class {
|
|
|
2396
2399
|
this.#assertNotLoading();
|
|
2397
2400
|
this.#ensureSourceFiles();
|
|
2398
2401
|
const sourceFile = this.getSourceFile(filePath);
|
|
2399
|
-
this.invalidate(false,
|
|
2402
|
+
this.invalidate(false, (0, _bamboocss_ts_ast.pathOf)(sourceFile));
|
|
2400
2403
|
if (!sourceFile) return;
|
|
2401
2404
|
this.invalidateSourcePreparation(filePath, sourceFile);
|
|
2402
|
-
return
|
|
2405
|
+
return this.project.reloadSourceFile(filePath);
|
|
2403
2406
|
};
|
|
2404
2407
|
reloadSourceFiles = () => {
|
|
2405
2408
|
this.#assertNotLoading();
|
|
@@ -2410,7 +2413,7 @@ var Project = class {
|
|
|
2410
2413
|
const source = this.getSourceFile(file);
|
|
2411
2414
|
if (source) {
|
|
2412
2415
|
this.invalidateSourcePreparation(file, source);
|
|
2413
|
-
|
|
2416
|
+
this.project.reloadSourceFile(file);
|
|
2414
2417
|
} else {
|
|
2415
2418
|
this.invalidateSourcePreparation(file);
|
|
2416
2419
|
this.removedSourcePaths.delete(this.normalizePath(file));
|
|
@@ -2452,10 +2455,12 @@ var Project = class {
|
|
|
2452
2455
|
const { hooks } = this.options;
|
|
2453
2456
|
const hookFilePath = options.hookFilePath ?? filePath;
|
|
2454
2457
|
if (filePath.endsWith(".json")) return this.parseJson(filePath, encoder);
|
|
2455
|
-
|
|
2458
|
+
let sourceFile = this.project.getSourceFile(filePath);
|
|
2456
2459
|
if (!sourceFile) return;
|
|
2457
|
-
const
|
|
2458
|
-
const
|
|
2460
|
+
const prepared = this.prepareEffectiveSource(filePath, sourceFile, hookFilePath);
|
|
2461
|
+
const parserOptions = prepared.options;
|
|
2462
|
+
sourceFile = prepared.sourceFile ?? sourceFile;
|
|
2463
|
+
const result = (encoder ?? this.options.parserOptions.encoder).withOwner("parse", (0, _bamboocss_ts_ast.pathOf)(sourceFile), () => this.parser(sourceFile, encoder, parserOptions, this.resolveModule))?.setFilePath(filePath);
|
|
2459
2464
|
hooks["parser:after"]?.({
|
|
2460
2465
|
filePath: hookFilePath,
|
|
2461
2466
|
result
|