mirror of
https://github.com/murashit/codex-panel.git
synced 2026-07-22 06:57:10 +00:00
Ignore type-only import cycles
This commit is contained in:
parent
328832a68e
commit
87cac9ee85
2 changed files with 42 additions and 3 deletions
|
|
@ -75,11 +75,16 @@ function importEdges(sourceFile) {
|
|||
const edges = [];
|
||||
|
||||
for (const statement of sourceFile.statements) {
|
||||
if (ts.isImportDeclaration(statement) && stringLiteralText(statement.moduleSpecifier)) {
|
||||
if (ts.isImportDeclaration(statement) && hasRuntimeImportEdge(statement) && stringLiteralText(statement.moduleSpecifier)) {
|
||||
edges.push({
|
||||
specifier: stringLiteralText(statement.moduleSpecifier),
|
||||
});
|
||||
} else if (ts.isExportDeclaration(statement) && statement.moduleSpecifier && stringLiteralText(statement.moduleSpecifier)) {
|
||||
} else if (
|
||||
ts.isExportDeclaration(statement) &&
|
||||
hasRuntimeExportEdge(statement) &&
|
||||
statement.moduleSpecifier &&
|
||||
stringLiteralText(statement.moduleSpecifier)
|
||||
) {
|
||||
edges.push({
|
||||
specifier: stringLiteralText(statement.moduleSpecifier),
|
||||
});
|
||||
|
|
@ -89,6 +94,27 @@ function importEdges(sourceFile) {
|
|||
return edges;
|
||||
}
|
||||
|
||||
function hasRuntimeImportEdge(statement) {
|
||||
const importClause = statement.importClause;
|
||||
if (!importClause) return true;
|
||||
if (importClause.isTypeOnly) return false;
|
||||
if (importClause.name) return true;
|
||||
|
||||
const namedBindings = importClause.namedBindings;
|
||||
if (!namedBindings) return false;
|
||||
if (ts.isNamespaceImport(namedBindings)) return true;
|
||||
return namedBindings.elements.some((element) => !element.isTypeOnly);
|
||||
}
|
||||
|
||||
function hasRuntimeExportEdge(statement) {
|
||||
if (statement.isTypeOnly) return false;
|
||||
|
||||
const exportClause = statement.exportClause;
|
||||
if (!exportClause) return true;
|
||||
if (ts.isNamespaceExport(exportClause)) return true;
|
||||
return exportClause.elements.some((element) => !element.isTypeOnly);
|
||||
}
|
||||
|
||||
function stringLiteralText(node) {
|
||||
return ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node) ? node.text : null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ describe("development scripts", () => {
|
|||
expect(result.stderr).toContain("src/a.ts -> src/b.ts -> src/a.ts");
|
||||
});
|
||||
|
||||
it("detects type-only import cycles", async () => {
|
||||
it("ignores type-only import cycles", async () => {
|
||||
const cwd = await tempWorkspace();
|
||||
await writeImportCycleFixture(cwd, {
|
||||
"src/a.ts": 'import type { B } from "./b";\nexport interface A { b?: B }\n',
|
||||
|
|
@ -180,6 +180,19 @@ describe("development scripts", () => {
|
|||
|
||||
const result = runNodeScript("scripts/check-import-cycles.mjs", [], cwd);
|
||||
|
||||
expect(result.status).toBe(0);
|
||||
expect(result.stdout).toContain("No import cycles found.");
|
||||
});
|
||||
|
||||
it("detects import cycles when mixed imports include runtime values", async () => {
|
||||
const cwd = await tempWorkspace();
|
||||
await writeImportCycleFixture(cwd, {
|
||||
"src/a.ts": 'import { type B, b } from "./b";\nexport interface A { b?: B }\nexport const a = b;\n',
|
||||
"src/b.ts": 'import { a, type A } from "./a";\nexport interface B { a?: A }\nexport const b = a;\n',
|
||||
});
|
||||
|
||||
const result = runNodeScript("scripts/check-import-cycles.mjs", [], cwd);
|
||||
|
||||
expect(result.status).toBe(1);
|
||||
expect(result.stderr).toContain("found 1 cycle");
|
||||
expect(result.stderr).toContain("src/a.ts -> src/b.ts -> src/a.ts");
|
||||
|
|
|
|||
Loading…
Reference in a new issue