@bamboocss/parser 1.49.0 → 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 +200 -208
- package/dist/index.d.cts +11 -3
- package/dist/index.d.mts +11 -3
- package/dist/index.mjs +166 -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);
|
|
@@ -1174,10 +1161,10 @@ const combineResult = (unboxed) => {
|
|
|
1174
1161
|
};
|
|
1175
1162
|
/** The exact binding token accounting visits for a token call. */
|
|
1176
1163
|
const tokenCalleeRange = (call) => {
|
|
1177
|
-
if (!
|
|
1178
|
-
let current = call.
|
|
1179
|
-
while (
|
|
1180
|
-
if (!
|
|
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;
|
|
1181
1168
|
return {
|
|
1182
1169
|
start: current.getStart(),
|
|
1183
1170
|
end: current.getEnd()
|
|
@@ -1196,23 +1183,23 @@ function createParser(context) {
|
|
|
1196
1183
|
const { jsx, imports, recipes } = context;
|
|
1197
1184
|
return function parse(sourceFile, encoder, options, resolveModule) {
|
|
1198
1185
|
if (!sourceFile) return;
|
|
1199
|
-
const importDeclarations = getImportDeclarations(context, sourceFile);
|
|
1186
|
+
const importDeclarations = getImportDeclarations$1(context, sourceFile);
|
|
1200
1187
|
const file = imports.file(importDeclarations);
|
|
1201
|
-
const filePath =
|
|
1188
|
+
const filePath = (0, _bamboocss_ts_ast.pathOf)(sourceFile);
|
|
1202
1189
|
_bamboocss_logger.logger.debug("ast:import", !file.isEmpty() ? `Found import { ${file.toString()} } in ${filePath}` : `No import found in ${filePath}`);
|
|
1203
1190
|
const parserResult = new ParserResult(context, encoder);
|
|
1204
1191
|
const importedRecipes = resolveModule ? importedRecipeBindings(sourceFile, imports, resolveModule) : /* @__PURE__ */ new Map();
|
|
1205
1192
|
if (file.isEmpty() && !jsx.isEnabled && importedRecipes.size === 0) return parserResult;
|
|
1206
1193
|
parserResult.importedRecipes = importedRecipes;
|
|
1207
1194
|
for (const binding of importedRecipes.keys()) file.addLocalRecipe(binding);
|
|
1208
|
-
if (file.importsRecipeFactory()) for (const statement of sourceFile.
|
|
1209
|
-
if (!
|
|
1210
|
-
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;
|
|
1211
1198
|
for (const declaration of statement.declarationList.declarations) {
|
|
1212
1199
|
const initializer = declaration.initializer;
|
|
1213
|
-
if (!initializer || !
|
|
1200
|
+
if (!initializer || !_bamboocss_ts_ast.ts.isCallExpression(initializer)) continue;
|
|
1214
1201
|
const callee = initializer.expression;
|
|
1215
|
-
if (!
|
|
1202
|
+
if (!_bamboocss_ts_ast.ts.isIdentifier(callee) || !_bamboocss_ts_ast.ts.isIdentifier(declaration.name)) continue;
|
|
1216
1203
|
const imported = file.getName(callee.text);
|
|
1217
1204
|
if (imported !== "cva" && imported !== "sva") continue;
|
|
1218
1205
|
if (!file.matchFn(callee.text)) continue;
|
|
@@ -1230,7 +1217,7 @@ function createParser(context) {
|
|
|
1230
1217
|
* Defined out here rather than inside `getEvaluateOptions`, which runs per call node.
|
|
1231
1218
|
*/
|
|
1232
1219
|
const reportUnresolvedRaw = (base, at) => {
|
|
1233
|
-
const { line, column } =
|
|
1220
|
+
const { line, column } = (0, _bamboocss_ts_ast.getLineAndColumnAtPos)(sourceFile, at.getStart());
|
|
1234
1221
|
parserResult.unresolved.push({
|
|
1235
1222
|
kind: "atomic",
|
|
1236
1223
|
prop: base,
|
|
@@ -1272,14 +1259,14 @@ function createParser(context) {
|
|
|
1272
1259
|
matchArg: () => true
|
|
1273
1260
|
},
|
|
1274
1261
|
getEvaluateOptions: (node) => {
|
|
1275
|
-
if (!
|
|
1276
|
-
const propAccessExpr = node.
|
|
1277
|
-
if (
|
|
1262
|
+
if (!_bamboocss_ts_ast.Node.isCallExpression(node)) return evaluateOptions;
|
|
1263
|
+
const propAccessExpr = node.expression;
|
|
1264
|
+
if (_bamboocss_ts_ast.Node.isIdentifier(propAccessExpr)) {
|
|
1278
1265
|
const local = propAccessExpr.getText();
|
|
1279
1266
|
if (!file.match(local) || file.getName(local) !== "fallback") return evaluateOptions;
|
|
1280
1267
|
return { environment: Object.assign({}, defaultEnv, { extra: { [local]: fallbackImpl } }) };
|
|
1281
1268
|
}
|
|
1282
|
-
if (!
|
|
1269
|
+
if (!_bamboocss_ts_ast.Node.isPropertyAccessExpression(propAccessExpr)) return evaluateOptions;
|
|
1283
1270
|
let name = propAccessExpr.getText();
|
|
1284
1271
|
const rawBase = name.endsWith(".raw") ? name.slice(0, -4) : void 0;
|
|
1285
1272
|
if (rawBase && file.isLocalRecipe(rawBase)) {
|
|
@@ -1348,7 +1335,7 @@ function createParser(context) {
|
|
|
1348
1335
|
});
|
|
1349
1336
|
}).when(file.isValidPattern, (name) => {
|
|
1350
1337
|
result.queryList.forEach((query) => {
|
|
1351
|
-
if (query.kind === "call-expression") parserResult.setPattern(name, {
|
|
1338
|
+
if (query.kind === "call-expression") parserResult.setPattern(name ?? "", {
|
|
1352
1339
|
name,
|
|
1353
1340
|
box: query.box.value[0] ?? _bamboocss_extractor.box.fallback(query.box),
|
|
1354
1341
|
data: combineResult((0, _bamboocss_extractor.unbox)(query.box.value[0]))
|
|
@@ -1356,7 +1343,7 @@ function createParser(context) {
|
|
|
1356
1343
|
});
|
|
1357
1344
|
}).when(file.isValidRecipe, (name) => {
|
|
1358
1345
|
result.queryList.forEach((query) => {
|
|
1359
|
-
if (query.kind === "call-expression") parserResult.setRecipe(name, {
|
|
1346
|
+
if (query.kind === "call-expression") parserResult.setRecipe(name ?? "", {
|
|
1360
1347
|
name,
|
|
1361
1348
|
box: query.box.value[0] ?? _bamboocss_extractor.box.fallback(query.box),
|
|
1362
1349
|
data: combineResult((0, _bamboocss_extractor.unbox)(query.box.value[0]))
|
|
@@ -1374,8 +1361,8 @@ function createParser(context) {
|
|
|
1374
1361
|
} else if (jsx.isEnabled && result.kind === "component") result.queryList.forEach((query) => {
|
|
1375
1362
|
const data = combineResult((0, _bamboocss_extractor.unbox)(query.box));
|
|
1376
1363
|
for (const tag of [name, alias]) {
|
|
1377
|
-
if (!jsx.isJsxTagRecipe(tag)) continue;
|
|
1378
|
-
recipes.filter(tag).forEach((recipe) => {
|
|
1364
|
+
if (!jsx.isJsxTagRecipe(tag ?? "")) continue;
|
|
1365
|
+
recipes.filter(tag ?? "").forEach((recipe) => {
|
|
1379
1366
|
parserResult.setRecipe(recipe.baseName, {
|
|
1380
1367
|
type: "jsx-recipe",
|
|
1381
1368
|
name: tag,
|
|
@@ -1388,19 +1375,16 @@ function createParser(context) {
|
|
|
1388
1375
|
});
|
|
1389
1376
|
});
|
|
1390
1377
|
parserResult.deadCalls = file.getDeadCalls();
|
|
1391
|
-
if (exportReadPairs.size) {
|
|
1392
|
-
const
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
};
|
|
1402
|
-
}));
|
|
1403
|
-
}
|
|
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
|
+
}));
|
|
1404
1388
|
return parserResult;
|
|
1405
1389
|
};
|
|
1406
1390
|
}
|
|
@@ -1417,11 +1401,16 @@ const invalidateResolutions = () => {
|
|
|
1417
1401
|
(0, _bamboocss_extractor.clearBoxNodeCache)();
|
|
1418
1402
|
clearImportedRecipeCache();
|
|
1419
1403
|
};
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
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 ?? {};
|
|
1425
1414
|
/** Snapshot the JSON-shaped ts-morph options while retaining opaque hosts and callbacks. */
|
|
1426
1415
|
const snapshotProjectOption = (value) => {
|
|
1427
1416
|
if (Array.isArray(value)) return value.map(snapshotProjectOption);
|
|
@@ -1451,7 +1440,7 @@ const prepareTsProjectOptions = (options, snapshotNested = false, compilerOption
|
|
|
1451
1440
|
}
|
|
1452
1441
|
};
|
|
1453
1442
|
};
|
|
1454
|
-
const createTsProject = (options) => new
|
|
1443
|
+
const createTsProject = (options) => new _bamboocss_ts_ast.Project(options);
|
|
1455
1444
|
/** Filesystem errors proving a lexical candidate cannot name a resolvable file. */
|
|
1456
1445
|
const isMissingPathShapeError = (error) => {
|
|
1457
1446
|
const code = error?.code;
|
|
@@ -1495,7 +1484,7 @@ const setProjectOnReceiver = (receiver, project) => {
|
|
|
1495
1484
|
*/
|
|
1496
1485
|
const scriptKindFor = (filePath) => {
|
|
1497
1486
|
const extension = filePath.slice(filePath.lastIndexOf(".")).toLowerCase();
|
|
1498
|
-
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;
|
|
1499
1488
|
};
|
|
1500
1489
|
var Project = class {
|
|
1501
1490
|
/**
|
|
@@ -1632,32 +1621,33 @@ var Project = class {
|
|
|
1632
1621
|
this.#assertSourceFilesAccessor();
|
|
1633
1622
|
const revision = this.#sourceFiles.revision;
|
|
1634
1623
|
this.#sourceFiles.phase = "loading";
|
|
1624
|
+
let candidate;
|
|
1635
1625
|
try {
|
|
1636
|
-
|
|
1626
|
+
candidate = createTsProject(this.#sourceFiles.projectOptions);
|
|
1637
1627
|
this.#assertSourceFilesTransaction(revision);
|
|
1638
1628
|
let loaded = 0;
|
|
1629
|
+
const entries = [];
|
|
1639
1630
|
for (const [index, file] of this.#sourceFiles.initialFiles.entries()) try {
|
|
1640
1631
|
const content = read(file, index);
|
|
1641
1632
|
this.#assertSourceFilesTransaction(revision);
|
|
1642
|
-
|
|
1643
|
-
overwrite: true,
|
|
1644
|
-
scriptKind: scriptKindFor(file)
|
|
1645
|
-
});
|
|
1633
|
+
entries.push([file, content]);
|
|
1646
1634
|
this.#assertSourceFilesTransaction(revision);
|
|
1647
1635
|
loaded++;
|
|
1648
1636
|
} catch (error) {
|
|
1649
1637
|
this.#assertSourceFilesTransaction(revision);
|
|
1650
1638
|
if (!skipMissing || error?.code !== "ENOENT") throw error;
|
|
1651
1639
|
}
|
|
1640
|
+
candidate.addSourceFiles(entries);
|
|
1652
1641
|
this.#assertSourceFilesTransaction(revision);
|
|
1653
1642
|
if (loaded > 0) invalidateResolutions();
|
|
1654
|
-
this.#
|
|
1643
|
+
this.#resolver = void 0;
|
|
1655
1644
|
this.#fileTreeRevision++;
|
|
1656
1645
|
this.#assertSourceFilesTransaction(revision);
|
|
1657
1646
|
this.#sourceFiles.project = candidate;
|
|
1658
1647
|
this.#sourceFiles.phase = "ready";
|
|
1659
1648
|
return;
|
|
1660
1649
|
} catch (error) {
|
|
1650
|
+
candidate?.dispose();
|
|
1661
1651
|
this.#sourceFiles.project = void 0;
|
|
1662
1652
|
this.#sourceFiles.phase = "pending";
|
|
1663
1653
|
throw error;
|
|
@@ -1730,7 +1720,7 @@ var Project = class {
|
|
|
1730
1720
|
sourceFilesRead: 0
|
|
1731
1721
|
};
|
|
1732
1722
|
resetResolutionState = () => {
|
|
1733
|
-
this.#
|
|
1723
|
+
this.#resolver = void 0;
|
|
1734
1724
|
this.#fileTreeRevision++;
|
|
1735
1725
|
this.dependents = /* @__PURE__ */ new Map();
|
|
1736
1726
|
this.dependencies = /* @__PURE__ */ new Map();
|
|
@@ -1771,12 +1761,24 @@ var Project = class {
|
|
|
1771
1761
|
};
|
|
1772
1762
|
getSourceFile = (filePath) => {
|
|
1773
1763
|
this.#assertNotLoading();
|
|
1764
|
+
if (!this.project.has(filePath)) return void 0;
|
|
1774
1765
|
return this.project.getSourceFile(filePath);
|
|
1775
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
|
+
};
|
|
1776
1778
|
/** ts-morph reports forward slashes; normalize callers' paths to match on Windows. */
|
|
1777
1779
|
normalizePath = (filePath) => filePath.replaceAll("\\", "/");
|
|
1778
1780
|
/** Shared filesystem-only resolution cache; no type checker is constructed. */
|
|
1779
|
-
#
|
|
1781
|
+
#resolver;
|
|
1780
1782
|
/**
|
|
1781
1783
|
* Everything memoized against the shape of the file tree, including the negative half.
|
|
1782
1784
|
*
|
|
@@ -1809,7 +1811,7 @@ var Project = class {
|
|
|
1809
1811
|
}
|
|
1810
1812
|
invalidateResolutions();
|
|
1811
1813
|
if (fileTreeChanged) {
|
|
1812
|
-
this.#
|
|
1814
|
+
this.#resolver = void 0;
|
|
1813
1815
|
this.#fileTreeRevision++;
|
|
1814
1816
|
}
|
|
1815
1817
|
};
|
|
@@ -1832,17 +1834,10 @@ var Project = class {
|
|
|
1832
1834
|
...this.#sourceFiles.projectOptions,
|
|
1833
1835
|
compilerOptions: snapshotProjectOption(next)
|
|
1834
1836
|
};
|
|
1835
|
-
|
|
1836
|
-
const current = this.project.getCompilerOptions();
|
|
1837
|
-
const cleared = Object.fromEntries(Object.keys(current).map((key) => [key, void 0]));
|
|
1838
|
-
this.project.compilerOptions.set({
|
|
1839
|
-
...cleared,
|
|
1840
|
-
...next
|
|
1841
|
-
});
|
|
1842
|
-
}
|
|
1837
|
+
this.#sourceFiles.project?.setCompilerOptions(next);
|
|
1843
1838
|
}
|
|
1844
1839
|
invalidateResolutions();
|
|
1845
|
-
this.#
|
|
1840
|
+
this.#resolver = void 0;
|
|
1846
1841
|
this.#fileTreeRevision++;
|
|
1847
1842
|
this.sourcePreparations.clear();
|
|
1848
1843
|
};
|
|
@@ -1888,33 +1883,33 @@ var Project = class {
|
|
|
1888
1883
|
this.#assertNotLoading();
|
|
1889
1884
|
const project = this.project;
|
|
1890
1885
|
const compilerOptions = project.getCompilerOptions();
|
|
1891
|
-
this.#moduleResolutionCache ??= ts_morph.ts.createModuleResolutionCache(project.getFileSystem().getCurrentDirectory(), (f) => f, compilerOptions);
|
|
1892
1886
|
const configurationFiles = /* @__PURE__ */ new Set();
|
|
1893
|
-
const resolutionHost = project.getModuleResolutionHost();
|
|
1894
1887
|
const recordConfigurationFile = (filePath) => {
|
|
1895
1888
|
const normalized = this.normalizePath(filePath);
|
|
1896
1889
|
if (!normalized.endsWith("/package.json") || normalized.includes("/node_modules/")) return;
|
|
1897
1890
|
if (!this.isInCheckout(normalized)) return;
|
|
1898
1891
|
configurationFiles.add(normalized);
|
|
1899
1892
|
};
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
},
|
|
1906
|
-
readFile: (filePath) => {
|
|
1907
|
-
recordConfigurationFile(filePath);
|
|
1908
|
-
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)
|
|
1909
1898
|
}
|
|
1910
|
-
};
|
|
1899
|
+
});
|
|
1900
|
+
const configured = this.#sourceFiles.projectOptions.compilerOptions ?? compilerOptions;
|
|
1911
1901
|
this.resolutionWork.moduleResolutionsAttempted++;
|
|
1912
|
-
const resolved =
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
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;
|
|
1918
1913
|
if (!module) return {
|
|
1919
1914
|
configurationFiles: [...configurationFiles].sort(),
|
|
1920
1915
|
local: this.isUnresolvedLocalSpecifier(moduleName, pendingCandidates) || moduleName.startsWith("#"),
|
|
@@ -1931,7 +1926,7 @@ var Project = class {
|
|
|
1931
1926
|
local: this.isUnresolvedLocalSpecifier(moduleName, pendingCandidates),
|
|
1932
1927
|
pendingCandidates
|
|
1933
1928
|
};
|
|
1934
|
-
const existing = project.getSourceFile(name);
|
|
1929
|
+
const existing = this.project.has(name) ? project.getSourceFile(name) : void 0;
|
|
1935
1930
|
if (existing) {
|
|
1936
1931
|
this.removedSourcePaths.delete(name);
|
|
1937
1932
|
return {
|
|
@@ -1950,12 +1945,10 @@ var Project = class {
|
|
|
1950
1945
|
try {
|
|
1951
1946
|
this.resolutionWork.sourceFilesRead++;
|
|
1952
1947
|
const content = project.getFileSystem().readFileSync(name);
|
|
1953
|
-
const sourceFile = project.createSourceFile(name, content, {
|
|
1954
|
-
|
|
1955
|
-
scriptKind: scriptKindFor(name)
|
|
1956
|
-
});
|
|
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`);
|
|
1957
1950
|
this.resolutionWork.sourceFilesAdded++;
|
|
1958
|
-
this.canonicalPaths.set(name, this.normalizePath(
|
|
1951
|
+
this.canonicalPaths.set(name, this.normalizePath((0, _bamboocss_ts_ast.pathOf)(sourceFile)));
|
|
1959
1952
|
return {
|
|
1960
1953
|
configurationFiles: [...configurationFiles].sort(),
|
|
1961
1954
|
local: true,
|
|
@@ -2009,28 +2002,28 @@ var Project = class {
|
|
|
2009
2002
|
};
|
|
2010
2003
|
ensureResolutionFacts = (sourceFile) => {
|
|
2011
2004
|
this.#assertNotLoading();
|
|
2012
|
-
const importer = this.normalizePath(
|
|
2005
|
+
const importer = this.normalizePath((0, _bamboocss_ts_ast.pathOf)(sourceFile));
|
|
2013
2006
|
const text = sourceFile.getFullText();
|
|
2014
2007
|
const cached = this.resolutionsByImporter.get(importer);
|
|
2015
2008
|
if (cached?.sourceFile === sourceFile && cached.text === text && cached.treeRevision === this.#fileTreeRevision) return cached;
|
|
2016
|
-
const declarations = [...
|
|
2009
|
+
const declarations = [...(0, _bamboocss_ts_ast.getImportDeclarations)(sourceFile).map((declaration) => ({
|
|
2017
2010
|
declaration,
|
|
2018
2011
|
kind: "import"
|
|
2019
|
-
})), ...
|
|
2012
|
+
})), ...(0, _bamboocss_ts_ast.getExportDeclarations)(sourceFile).map((declaration) => ({
|
|
2020
2013
|
declaration,
|
|
2021
2014
|
kind: "export"
|
|
2022
|
-
}))].filter(({ declaration }) =>
|
|
2015
|
+
}))].filter(({ declaration }) => (0, _bamboocss_ts_ast.getModuleSpecifierValue)(declaration) !== void 0).sort((left, right) => left.declaration.getStart() - right.declaration.getStart());
|
|
2023
2016
|
const facts = [];
|
|
2024
2017
|
const pendingCandidates = [];
|
|
2025
2018
|
const configurationFiles = [];
|
|
2026
2019
|
for (const [ordinal, { declaration, kind }] of declarations.entries()) {
|
|
2027
|
-
const specifier =
|
|
2020
|
+
const specifier = (0, _bamboocss_ts_ast.getModuleSpecifierValue)(declaration);
|
|
2028
2021
|
if (!specifier) continue;
|
|
2029
2022
|
const resolved = this.resolveSpecifier(specifier, sourceFile);
|
|
2030
2023
|
if (!resolved.local) continue;
|
|
2031
2024
|
facts.push(Object.freeze({
|
|
2032
2025
|
importer,
|
|
2033
|
-
target: resolved.sourceFile ? this.normalizePath(resolved.sourceFile
|
|
2026
|
+
target: resolved.sourceFile ? this.normalizePath((0, _bamboocss_ts_ast.pathOf)(resolved.sourceFile)) : null,
|
|
2034
2027
|
specifier,
|
|
2035
2028
|
kind,
|
|
2036
2029
|
ordinal
|
|
@@ -2055,22 +2048,22 @@ var Project = class {
|
|
|
2055
2048
|
};
|
|
2056
2049
|
/** The sole cross-file source resolver supplied to parser and extractor. */
|
|
2057
2050
|
resolveModule = (specifier, from) => {
|
|
2058
|
-
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);
|
|
2059
2052
|
if (!target) return;
|
|
2060
2053
|
const sourceFile = this.project.getSourceFile(target);
|
|
2061
2054
|
if (!sourceFile) return;
|
|
2062
|
-
this.prepareEffectiveSource(
|
|
2055
|
+
this.prepareEffectiveSource((0, _bamboocss_ts_ast.pathOf)(sourceFile), sourceFile);
|
|
2063
2056
|
return sourceFile;
|
|
2064
2057
|
};
|
|
2065
2058
|
trackDependencies = (filePath, sourceFile) => {
|
|
2066
2059
|
this.#assertNotLoading();
|
|
2067
|
-
const importer = this.normalizePath(
|
|
2060
|
+
const importer = this.normalizePath((0, _bamboocss_ts_ast.pathOf)(sourceFile));
|
|
2068
2061
|
this.canonicalPaths.set(this.normalizePath(filePath), importer);
|
|
2069
2062
|
this.canonicalPaths.set(importer, importer);
|
|
2070
2063
|
this.ensureResolutionFacts(sourceFile);
|
|
2071
2064
|
};
|
|
2072
2065
|
invalidateSourcePreparation = (filePath, sourceFile) => {
|
|
2073
|
-
const sourcePath = this.normalizePath(
|
|
2066
|
+
const sourcePath = this.normalizePath((0, _bamboocss_ts_ast.pathOf)(sourceFile) ?? filePath);
|
|
2074
2067
|
const preparation = this.sourcePreparations.get(sourcePath);
|
|
2075
2068
|
if (preparation?.state === "preparing") preparation.invalidated = true;
|
|
2076
2069
|
this.sourcePreparations.delete(sourcePath);
|
|
@@ -2086,7 +2079,7 @@ var Project = class {
|
|
|
2086
2079
|
*/
|
|
2087
2080
|
prepareEffectiveSource = (filePath, sourceFile, hookFilePath = filePath) => {
|
|
2088
2081
|
this.#assertNotLoading();
|
|
2089
|
-
const sourcePath = this.normalizePath(
|
|
2082
|
+
const sourcePath = this.normalizePath((0, _bamboocss_ts_ast.pathOf)(sourceFile));
|
|
2090
2083
|
const currentText = sourceFile.getFullText();
|
|
2091
2084
|
const current = this.sourcePreparations.get(sourcePath);
|
|
2092
2085
|
if (current?.state === "ready" && current.sourceFile === sourceFile && current.effectiveText === currentText) {
|
|
@@ -2131,7 +2124,7 @@ var Project = class {
|
|
|
2131
2124
|
assertTransaction(currentText);
|
|
2132
2125
|
const transformed = custom ?? this.transformFile(hookFilePath, currentText);
|
|
2133
2126
|
assertTransaction(currentText);
|
|
2134
|
-
if (currentText !== transformed) sourceFile.
|
|
2127
|
+
if (currentText !== transformed) sourceFile = this.project.addSourceFile(filePath, transformed) ?? sourceFile;
|
|
2135
2128
|
assertTransaction(transformed);
|
|
2136
2129
|
this.trackDependencies(filePath, sourceFile);
|
|
2137
2130
|
assertTransaction(transformed);
|
|
@@ -2148,7 +2141,7 @@ var Project = class {
|
|
|
2148
2141
|
if (this.sourcePreparations.get(sourcePath) === transaction) this.sourcePreparations.delete(sourcePath);
|
|
2149
2142
|
this.retractImporter(sourcePath);
|
|
2150
2143
|
try {
|
|
2151
|
-
if (sourceFile.getFullText() !== currentText)
|
|
2144
|
+
if (sourceFile.getFullText() !== currentText) this.project.addSourceFile(filePath, currentText);
|
|
2152
2145
|
} catch {}
|
|
2153
2146
|
throw error;
|
|
2154
2147
|
}
|
|
@@ -2175,7 +2168,7 @@ var Project = class {
|
|
|
2175
2168
|
this.retractImporter(target);
|
|
2176
2169
|
this.removedSourcePaths.add(target);
|
|
2177
2170
|
this.canonicalPaths.set(target, target);
|
|
2178
|
-
this.canonicalPaths.set(this.normalizePath(
|
|
2171
|
+
this.canonicalPaths.set(this.normalizePath((0, _bamboocss_ts_ast.pathOf)(sourceFile)), target);
|
|
2179
2172
|
};
|
|
2180
2173
|
/**
|
|
2181
2174
|
* Every file that transitively imports `filePath`, so a watcher can re-parse the
|
|
@@ -2184,7 +2177,7 @@ var Project = class {
|
|
|
2184
2177
|
getDependents = (filePath) => {
|
|
2185
2178
|
this.#assertNotLoading();
|
|
2186
2179
|
const given = this.normalizePath(filePath);
|
|
2187
|
-
const resolved = this.project.getSourceFile(filePath)
|
|
2180
|
+
const resolved = (0, _bamboocss_ts_ast.pathOf)(this.project.getSourceFile(filePath));
|
|
2188
2181
|
const start = resolved ? this.normalizePath(resolved) : this.canonicalPaths.get(given) ?? given;
|
|
2189
2182
|
const seen = /* @__PURE__ */ new Set();
|
|
2190
2183
|
const queue = [start];
|
|
@@ -2212,7 +2205,7 @@ var Project = class {
|
|
|
2212
2205
|
getDependencies = (filePath, targets) => {
|
|
2213
2206
|
this.#assertNotLoading();
|
|
2214
2207
|
const given = this.normalizePath(filePath);
|
|
2215
|
-
const resolved = this.project.getSourceFile(filePath)
|
|
2208
|
+
const resolved = (0, _bamboocss_ts_ast.pathOf)(this.project.getSourceFile(filePath));
|
|
2216
2209
|
const start = resolved ? this.normalizePath(resolved) : this.canonicalPaths.get(given) ?? given;
|
|
2217
2210
|
const seen = /* @__PURE__ */ new Set();
|
|
2218
2211
|
const importersByDependency = /* @__PURE__ */ new Map();
|
|
@@ -2233,7 +2226,7 @@ var Project = class {
|
|
|
2233
2226
|
const selected = /* @__PURE__ */ new Set();
|
|
2234
2227
|
const reverse = Array.from(targets, (target) => {
|
|
2235
2228
|
const normalized = this.normalizePath(target);
|
|
2236
|
-
const source = this.project.getSourceFile(target)
|
|
2229
|
+
const source = (0, _bamboocss_ts_ast.pathOf)(this.project.getSourceFile(target));
|
|
2237
2230
|
return source ? this.normalizePath(source) : this.canonicalPaths.get(normalized) ?? normalized;
|
|
2238
2231
|
}).filter((target) => seen.has(target));
|
|
2239
2232
|
let reverseCursor = 0;
|
|
@@ -2259,7 +2252,7 @@ var Project = class {
|
|
|
2259
2252
|
const selected = new Set(dependencies);
|
|
2260
2253
|
const retained = new Set([...previous?.dependencies ?? [], ...previous?.pendingCandidates ?? []]);
|
|
2261
2254
|
const given = this.normalizePath(filePath);
|
|
2262
|
-
const resolved = this.project.getSourceFile(filePath)
|
|
2255
|
+
const resolved = (0, _bamboocss_ts_ast.pathOf)(this.project.getSourceFile(filePath));
|
|
2263
2256
|
const start = resolved ? this.normalizePath(resolved) : this.canonicalPaths.get(given) ?? given;
|
|
2264
2257
|
const pendingCandidates = /* @__PURE__ */ new Set();
|
|
2265
2258
|
for (const importer of [start, ...dependencies]) {
|
|
@@ -2292,7 +2285,7 @@ var Project = class {
|
|
|
2292
2285
|
const selected = new Set(dependencies);
|
|
2293
2286
|
const retained = new Set(Array.from(previous, (file) => this.normalizePath(file)));
|
|
2294
2287
|
const given = this.normalizePath(filePath);
|
|
2295
|
-
const resolved = this.project.getSourceFile(filePath)
|
|
2288
|
+
const resolved = (0, _bamboocss_ts_ast.pathOf)(this.project.getSourceFile(filePath));
|
|
2296
2289
|
const start = resolved ? this.normalizePath(resolved) : this.canonicalPaths.get(given) ?? given;
|
|
2297
2290
|
const files = /* @__PURE__ */ new Set();
|
|
2298
2291
|
let hasSemanticFact = false;
|
|
@@ -2319,10 +2312,9 @@ var Project = class {
|
|
|
2319
2312
|
this.invalidateSourcePreparation(filePath, existing);
|
|
2320
2313
|
this.removedSourcePaths.delete(this.normalizePath(filePath));
|
|
2321
2314
|
this.invalidate();
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
});
|
|
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;
|
|
2326
2318
|
};
|
|
2327
2319
|
createSourceFiles = () => {
|
|
2328
2320
|
this.#assertNotLoading();
|
|
@@ -2361,17 +2353,15 @@ var Project = class {
|
|
|
2361
2353
|
* matches its own source, falls through, and is overwritten exactly as before.
|
|
2362
2354
|
*/
|
|
2363
2355
|
if (existing && existing.getFullText() === content) {
|
|
2364
|
-
this.markAuxiliary(
|
|
2356
|
+
this.markAuxiliary((0, _bamboocss_ts_ast.pathOf)(existing), options.auxiliary);
|
|
2365
2357
|
return existing;
|
|
2366
2358
|
}
|
|
2367
2359
|
this.invalidateSourcePreparation(filePath, existing);
|
|
2368
2360
|
this.removedSourcePaths.delete(this.normalizePath(filePath));
|
|
2369
|
-
this.invalidate(!existing,
|
|
2370
|
-
const sourceFile = this.project.createSourceFile(filePath, content, {
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
});
|
|
2374
|
-
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);
|
|
2375
2365
|
return sourceFile;
|
|
2376
2366
|
};
|
|
2377
2367
|
/** Claim or release compiler ownership of one source, in the ledger's own spelling. */
|
|
@@ -2387,10 +2377,10 @@ var Project = class {
|
|
|
2387
2377
|
if (sourceFile) {
|
|
2388
2378
|
this.invalidate();
|
|
2389
2379
|
this.invalidateSourcePreparation(filePath, sourceFile);
|
|
2390
|
-
this.markTargetRemoved(this.normalizePath(
|
|
2391
|
-
this.options.parserOptions.encoder.releaseFile(
|
|
2392
|
-
this.auxiliarySources.delete(this.normalizePath(
|
|
2393
|
-
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));
|
|
2394
2384
|
}
|
|
2395
2385
|
return false;
|
|
2396
2386
|
};
|
|
@@ -2409,10 +2399,10 @@ var Project = class {
|
|
|
2409
2399
|
this.#assertNotLoading();
|
|
2410
2400
|
this.#ensureSourceFiles();
|
|
2411
2401
|
const sourceFile = this.getSourceFile(filePath);
|
|
2412
|
-
this.invalidate(false,
|
|
2402
|
+
this.invalidate(false, (0, _bamboocss_ts_ast.pathOf)(sourceFile));
|
|
2413
2403
|
if (!sourceFile) return;
|
|
2414
2404
|
this.invalidateSourcePreparation(filePath, sourceFile);
|
|
2415
|
-
return
|
|
2405
|
+
return this.project.reloadSourceFile(filePath);
|
|
2416
2406
|
};
|
|
2417
2407
|
reloadSourceFiles = () => {
|
|
2418
2408
|
this.#assertNotLoading();
|
|
@@ -2423,7 +2413,7 @@ var Project = class {
|
|
|
2423
2413
|
const source = this.getSourceFile(file);
|
|
2424
2414
|
if (source) {
|
|
2425
2415
|
this.invalidateSourcePreparation(file, source);
|
|
2426
|
-
|
|
2416
|
+
this.project.reloadSourceFile(file);
|
|
2427
2417
|
} else {
|
|
2428
2418
|
this.invalidateSourcePreparation(file);
|
|
2429
2419
|
this.removedSourcePaths.delete(this.normalizePath(file));
|
|
@@ -2465,10 +2455,12 @@ var Project = class {
|
|
|
2465
2455
|
const { hooks } = this.options;
|
|
2466
2456
|
const hookFilePath = options.hookFilePath ?? filePath;
|
|
2467
2457
|
if (filePath.endsWith(".json")) return this.parseJson(filePath, encoder);
|
|
2468
|
-
|
|
2458
|
+
let sourceFile = this.project.getSourceFile(filePath);
|
|
2469
2459
|
if (!sourceFile) return;
|
|
2470
|
-
const
|
|
2471
|
-
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);
|
|
2472
2464
|
hooks["parser:after"]?.({
|
|
2473
2465
|
filePath: hookFilePath,
|
|
2474
2466
|
result
|