@lucasacoutinho/archer 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +144 -387
- package/dist/analyzer/Analyzer.d.ts +17 -0
- package/dist/analyzer/Analyzer.d.ts.map +1 -0
- package/dist/analyzer/Analyzer.js +15 -0
- package/dist/analyzer/Analyzer.js.map +1 -0
- package/dist/analyzer/bindings.d.ts +26 -0
- package/dist/analyzer/bindings.d.ts.map +1 -0
- package/dist/analyzer/bindings.js +61 -0
- package/dist/analyzer/bindings.js.map +1 -0
- package/dist/analyzer/errors.d.ts +34 -0
- package/dist/analyzer/errors.d.ts.map +1 -0
- package/dist/analyzer/errors.js +20 -0
- package/dist/analyzer/errors.js.map +1 -0
- package/dist/analyzer/graph-file.d.ts +13 -0
- package/dist/analyzer/graph-file.d.ts.map +1 -0
- package/dist/analyzer/graph-file.js +22 -0
- package/dist/analyzer/graph-file.js.map +1 -0
- package/dist/analyzer/paths.d.ts +12 -0
- package/dist/analyzer/paths.d.ts.map +1 -0
- package/dist/analyzer/paths.js +26 -0
- package/dist/analyzer/paths.js.map +1 -0
- package/dist/analyzer/server-exit.d.ts +19 -0
- package/dist/analyzer/server-exit.d.ts.map +1 -0
- package/dist/analyzer/server-exit.js +70 -0
- package/dist/analyzer/server-exit.js.map +1 -0
- package/dist/analyzer/source.d.ts +29 -0
- package/dist/analyzer/source.d.ts.map +1 -0
- package/dist/analyzer/source.js +58 -0
- package/dist/analyzer/source.js.map +1 -0
- package/dist/analyzer/syntax.d.ts +29 -0
- package/dist/analyzer/syntax.d.ts.map +1 -0
- package/dist/analyzer/syntax.js +226 -0
- package/dist/analyzer/syntax.js.map +1 -0
- package/dist/analyzer/targets.d.ts +26 -0
- package/dist/analyzer/targets.d.ts.map +1 -0
- package/dist/analyzer/targets.js +84 -0
- package/dist/analyzer/targets.js.map +1 -0
- package/dist/analyzer/typescript.d.ts +5 -0
- package/dist/analyzer/typescript.d.ts.map +1 -0
- package/dist/analyzer/typescript.js +221 -0
- package/dist/analyzer/typescript.js.map +1 -0
- package/dist/analyzer/workspace.d.ts +24 -0
- package/dist/analyzer/workspace.d.ts.map +1 -0
- package/dist/analyzer/workspace.js +9 -0
- package/dist/analyzer/workspace.js.map +1 -0
- package/dist/cli/explain.d.ts +3 -0
- package/dist/cli/explain.d.ts.map +1 -0
- package/dist/cli/explain.js +21 -0
- package/dist/cli/explain.js.map +1 -0
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/cli/main.js +159 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/config/input.d.ts +59 -0
- package/dist/config/input.d.ts.map +1 -0
- package/dist/config/input.js +115 -0
- package/dist/config/input.js.map +1 -0
- package/dist/config/rules.d.ts +94 -0
- package/dist/config/rules.d.ts.map +1 -0
- package/dist/config/rules.js +130 -0
- package/dist/config/rules.js.map +1 -0
- package/dist/core/baseline.d.ts +16 -0
- package/dist/core/baseline.d.ts.map +1 -0
- package/dist/core/baseline.js +25 -0
- package/dist/core/baseline.js.map +1 -0
- package/dist/core/check.d.ts +16 -0
- package/dist/core/check.d.ts.map +1 -0
- package/dist/core/check.js +271 -0
- package/dist/core/check.js.map +1 -0
- package/dist/core/config.d.ts +72 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +78 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/fingerprint.d.ts +54 -0
- package/dist/core/fingerprint.d.ts.map +1 -0
- package/dist/core/fingerprint.js +182 -0
- package/dist/core/fingerprint.js.map +1 -0
- package/dist/core/keys.d.ts +10 -0
- package/dist/core/keys.d.ts.map +1 -0
- package/dist/core/keys.js +16 -0
- package/dist/core/keys.js.map +1 -0
- package/dist/core/lower.d.ts +13 -0
- package/dist/core/lower.d.ts.map +1 -0
- package/dist/core/lower.js +82 -0
- package/dist/core/lower.js.map +1 -0
- package/dist/core/model.d.ts +155 -0
- package/dist/core/model.d.ts.map +1 -0
- package/dist/core/model.js +116 -0
- package/dist/core/model.js.map +1 -0
- package/dist/core/pattern.d.ts +13 -0
- package/dist/core/pattern.d.ts.map +1 -0
- package/dist/core/pattern.js +29 -0
- package/dist/core/pattern.js.map +1 -0
- package/dist/core/reach.d.ts +10 -0
- package/dist/core/reach.d.ts.map +1 -0
- package/dist/core/reach.js +81 -0
- package/dist/core/reach.js.map +1 -0
- package/dist/core/rule.d.ts +200 -0
- package/dist/core/rule.d.ts.map +1 -0
- package/dist/core/rule.js +162 -0
- package/dist/core/rule.js.map +1 -0
- package/dist/core/selector.d.ts +7 -0
- package/dist/core/selector.d.ts.map +1 -0
- package/dist/core/selector.js +27 -0
- package/dist/core/selector.js.map +1 -0
- package/dist/core/structural.d.ts +10 -0
- package/dist/core/structural.d.ts.map +1 -0
- package/dist/core/structural.js +24 -0
- package/dist/core/structural.js.map +1 -0
- package/dist/core/text.d.ts +26 -0
- package/dist/core/text.d.ts.map +1 -0
- package/dist/core/text.js +144 -0
- package/dist/core/text.js.map +1 -0
- package/dist/effect.d.ts +19 -0
- package/dist/effect.d.ts.map +1 -0
- package/dist/effect.js +21 -0
- package/dist/effect.js.map +1 -0
- package/dist/index.d.ts +24 -44
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +59 -52
- package/dist/index.js.map +1 -0
- package/dist/report/agent.d.ts +3 -0
- package/dist/report/agent.d.ts.map +1 -0
- package/dist/report/agent.js +35 -0
- package/dist/report/agent.js.map +1 -0
- package/dist/report/dot.d.ts +4 -0
- package/dist/report/dot.d.ts.map +1 -0
- package/dist/report/dot.js +15 -0
- package/dist/report/dot.js.map +1 -0
- package/dist/report/github.d.ts +3 -0
- package/dist/report/github.d.ts.map +1 -0
- package/dist/report/github.js +18 -0
- package/dist/report/github.js.map +1 -0
- package/dist/report/json.d.ts +3 -0
- package/dist/report/json.d.ts.map +1 -0
- package/dist/report/json.js +4 -0
- package/dist/report/json.js.map +1 -0
- package/dist/report/message.d.ts +20 -0
- package/dist/report/message.d.ts.map +1 -0
- package/dist/report/message.js +73 -0
- package/dist/report/message.js.map +1 -0
- package/dist/report/pretty.d.ts +8 -0
- package/dist/report/pretty.d.ts.map +1 -0
- package/dist/report/pretty.js +89 -0
- package/dist/report/pretty.js.map +1 -0
- package/dist/report/render.d.ts +9 -0
- package/dist/report/render.d.ts.map +1 -0
- package/dist/report/render.js +10 -0
- package/dist/report/render.js.map +1 -0
- package/dist/report/report.d.ts +44 -0
- package/dist/report/report.d.ts.map +1 -0
- package/dist/report/report.js +49 -0
- package/dist/report/report.js.map +1 -0
- package/dist/report/sarif.d.ts +3 -0
- package/dist/report/sarif.d.ts.map +1 -0
- package/dist/report/sarif.js +68 -0
- package/dist/report/sarif.js.map +1 -0
- package/dist/run.d.ts +49 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +87 -0
- package/dist/run.js.map +1 -0
- package/dist/shell/baseline-file.d.ts +20 -0
- package/dist/shell/baseline-file.d.ts.map +1 -0
- package/dist/shell/baseline-file.js +46 -0
- package/dist/shell/baseline-file.js.map +1 -0
- package/dist/shell/load-config.d.ts +19 -0
- package/dist/shell/load-config.d.ts.map +1 -0
- package/dist/shell/load-config.js +39 -0
- package/dist/shell/load-config.js.map +1 -0
- package/package.json +29 -177
- package/skills/archer/SKILL.md +127 -45
- package/skills/archer/agents/openai.yaml +2 -2
- package/skills/archer/references/rules.md +267 -54
- package/dist/bun/plugin.cjs +0 -85
- package/dist/bun/plugin.d.cts +0 -7
- package/dist/bun/plugin.d.ts +0 -7
- package/dist/bun/plugin.js +0 -11
- package/dist/bun.cjs +0 -2238
- package/dist/bun.d.cts +0 -13
- package/dist/bun.d.ts +0 -13
- package/dist/bun.js +0 -28
- package/dist/chunk-2AKMBLHG.js +0 -2165
- package/dist/chunk-67YEOTXP.js +0 -25
- package/dist/chunk-IDVLHNL2.js +0 -46
- package/dist/chunk-ZZ6TR4PO.js +0 -201
- package/dist/cli.js +0 -2643
- package/dist/index.cjs +0 -2484
- package/dist/index.d.cts +0 -45
- package/dist/jest/plugin.cjs +0 -85
- package/dist/jest/plugin.d.cts +0 -7
- package/dist/jest/plugin.d.ts +0 -7
- package/dist/jest/plugin.js +0 -11
- package/dist/jest.cjs +0 -2237
- package/dist/jest.d.cts +0 -13
- package/dist/jest.d.ts +0 -13
- package/dist/jest.js +0 -27
- package/dist/matchers-Cqnbsyxe.d.cts +0 -11
- package/dist/matchers-Cqnbsyxe.d.ts +0 -11
- package/dist/node.cjs +0 -2237
- package/dist/node.d.cts +0 -13
- package/dist/node.d.ts +0 -13
- package/dist/node.js +0 -27
- package/dist/reporters-BbAXMpuW.d.cts +0 -6
- package/dist/reporters-xh-HQneS.d.ts +0 -6
- package/dist/suite-BwnPDCvU.d.cts +0 -337
- package/dist/suite-BwnPDCvU.d.ts +0 -337
- package/dist/vitest/plugin.cjs +0 -85
- package/dist/vitest/plugin.d.cts +0 -7
- package/dist/vitest/plugin.d.ts +0 -7
- package/dist/vitest/plugin.js +0 -11
- package/dist/vitest.cjs +0 -2531
- package/dist/vitest.d.cts +0 -37
- package/dist/vitest.d.ts +0 -37
- package/dist/vitest.js +0 -139
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { Match } from "effect";
|
|
2
|
+
import { isArrayBindingPattern, isBinaryExpression, isCallExpression, isClassDeclaration, isConstructorDeclaration, isDecorator, isElementAccessExpression, isEnumDeclaration, isExportAssignment, isExportDeclaration, isExternalModuleReference, isFunctionDeclaration, isIdentifier, isImportDeclaration, isImportEqualsDeclaration, isImportTypeNode, isInterfaceDeclaration, isLiteralTypeNode, isMethodDeclaration, isMethodSignatureDeclaration, isNamedExports, isObjectBindingPattern, isParameterDeclaration, isPrivateIdentifier, isPropertyAccessExpression, isPropertyDeclaration, isPropertySignatureDeclaration, isStringLiteralLikeNode, isTypeAliasDeclaration, isVariableStatement, ModifierFlags, ScriptKind, SyntaxKind, } from "typescript/unstable/ast";
|
|
3
|
+
export const locationOf = (sourceFile, node) => {
|
|
4
|
+
const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
|
|
5
|
+
return { line: line + 1, column: character + 1 };
|
|
6
|
+
};
|
|
7
|
+
/** A trailing newline ends the last line instead of starting another; an empty file has no lines. */
|
|
8
|
+
export const countLines = (text) => {
|
|
9
|
+
if (text === "") {
|
|
10
|
+
return 0;
|
|
11
|
+
}
|
|
12
|
+
let lines = text.endsWith("\n") ? 0 : 1;
|
|
13
|
+
for (let at = text.indexOf("\n"); at >= 0; at = text.indexOf("\n", at + 1)) {
|
|
14
|
+
lines++;
|
|
15
|
+
}
|
|
16
|
+
return lines;
|
|
17
|
+
};
|
|
18
|
+
const hasFlag = (node, flag) => (node.modifierFlags & flag) !== 0;
|
|
19
|
+
const memberOf = (object, member) => isIdentifier(object) && member !== undefined ? { _tag: "Member", root: object, member } : { _tag: "Other" };
|
|
20
|
+
const calleeOf = Match.type().pipe(Match.when(isIdentifier, (identifier) => ({ _tag: "Name", identifier })), Match.when(isPropertyAccessExpression, (access) => memberOf(access.expression, propertyName(access))), Match.when(isElementAccessExpression, (access) => memberOf(access.expression, isStringLiteralLikeNode(access.argumentExpression) ? access.argumentExpression.text : undefined)), Match.when((node) => node.kind === SyntaxKind.ImportKeyword, () => ({ _tag: "ImportKeyword" })), Match.orElse(() => ({ _tag: "Other" })));
|
|
21
|
+
const propertyName = (access) => isIdentifier(access.name) ? access.name.text : undefined;
|
|
22
|
+
/** An empty `import {} from` still runs the module, so it is not type-only. */
|
|
23
|
+
const importsOnlyTypes = (declaration) => {
|
|
24
|
+
const clause = declaration.importClause;
|
|
25
|
+
if (clause === undefined) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
if (clause.phaseModifier === SyntaxKind.TypeKeyword) {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
const bindings = clause.namedBindings;
|
|
32
|
+
return (clause.name === undefined &&
|
|
33
|
+
bindings !== undefined &&
|
|
34
|
+
bindings.kind === SyntaxKind.NamedImports &&
|
|
35
|
+
bindings.elements.length > 0 &&
|
|
36
|
+
bindings.elements.every((element) => element.isTypeOnly));
|
|
37
|
+
};
|
|
38
|
+
const exportsOnlyTypes = (declaration) => {
|
|
39
|
+
const clause = declaration.exportClause;
|
|
40
|
+
return (declaration.isTypeOnly ||
|
|
41
|
+
(clause !== undefined &&
|
|
42
|
+
isNamedExports(clause) &&
|
|
43
|
+
clause.elements.length > 0 &&
|
|
44
|
+
clause.elements.every((element) => element.isTypeOnly)));
|
|
45
|
+
};
|
|
46
|
+
export const scanSource = (sourceFile) => {
|
|
47
|
+
const sites = [];
|
|
48
|
+
const calls = [];
|
|
49
|
+
const looseEqualities = [];
|
|
50
|
+
const scripted = sourceFile.scriptKind === ScriptKind.JS || sourceFile.scriptKind === ScriptKind.JSX;
|
|
51
|
+
const addLiteral = (kind, node, checkable) => {
|
|
52
|
+
if (node !== undefined && isStringLiteralLikeNode(node)) {
|
|
53
|
+
sites.push({ kind, node, specifier: node.text, computed: false, checkable });
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
const addArgument = (kind, argument, checkable) => {
|
|
57
|
+
if (isStringLiteralLikeNode(argument)) {
|
|
58
|
+
addLiteral(kind, argument, checkable);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
sites.push({ kind, node: argument, specifier: argument.getText(sourceFile), computed: true, checkable: false });
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
const addCall = (call) => {
|
|
65
|
+
const [first] = call.arguments;
|
|
66
|
+
Match.valueTags(calleeOf(call.expression), {
|
|
67
|
+
ImportKeyword: () => {
|
|
68
|
+
if (first !== undefined) {
|
|
69
|
+
addArgument("dynamic", first, true);
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
Name: ({ identifier }) => {
|
|
73
|
+
if (identifier.text === "require" && call.arguments.length === 1 && first !== undefined) {
|
|
74
|
+
addArgument("require", first, scripted);
|
|
75
|
+
}
|
|
76
|
+
calls.push({ name: identifier.text, root: identifier, member: undefined, callee: identifier });
|
|
77
|
+
},
|
|
78
|
+
Member: ({ root, member }) => {
|
|
79
|
+
calls.push({ name: `${root.text}.${member}`, root, member, callee: call.expression });
|
|
80
|
+
},
|
|
81
|
+
Other: () => undefined,
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
const read = Match.type().pipe(Match.when(isImportDeclaration, (node) => {
|
|
85
|
+
addLiteral(importsOnlyTypes(node) ? "type" : "static", node.moduleSpecifier, true);
|
|
86
|
+
return false;
|
|
87
|
+
}), Match.when(isExportDeclaration, (node) => {
|
|
88
|
+
addLiteral(exportsOnlyTypes(node) ? "type" : "static", node.moduleSpecifier, true);
|
|
89
|
+
return false;
|
|
90
|
+
}), Match.when(isImportEqualsDeclaration, (node) => {
|
|
91
|
+
if (isExternalModuleReference(node.moduleReference)) {
|
|
92
|
+
addLiteral(node.isTypeOnly ? "type" : "require", node.moduleReference.expression, true);
|
|
93
|
+
}
|
|
94
|
+
return false;
|
|
95
|
+
}), Match.when(isCallExpression, (node) => {
|
|
96
|
+
addCall(node);
|
|
97
|
+
return true;
|
|
98
|
+
}), Match.when(isImportTypeNode, (node) => {
|
|
99
|
+
addLiteral("type", isLiteralTypeNode(node.argument) ? node.argument.literal : undefined, true);
|
|
100
|
+
return true;
|
|
101
|
+
}), Match.when(isBinaryExpression, (node) => {
|
|
102
|
+
if (node.operatorToken.kind === SyntaxKind.EqualsEqualsToken || node.operatorToken.kind === SyntaxKind.ExclamationEqualsToken) {
|
|
103
|
+
looseEqualities.push(node.operatorToken);
|
|
104
|
+
}
|
|
105
|
+
return true;
|
|
106
|
+
}), Match.orElse(() => true));
|
|
107
|
+
const visit = (node) => {
|
|
108
|
+
if (read(node)) {
|
|
109
|
+
node.forEachChild(visit);
|
|
110
|
+
}
|
|
111
|
+
return undefined;
|
|
112
|
+
};
|
|
113
|
+
sourceFile.forEachChild(visit);
|
|
114
|
+
return { sites, calls, looseEqualities };
|
|
115
|
+
};
|
|
116
|
+
export const requiredModule = (node) => node !== undefined &&
|
|
117
|
+
isCallExpression(node) &&
|
|
118
|
+
isIdentifier(node.expression) &&
|
|
119
|
+
node.expression.text === "require" &&
|
|
120
|
+
node.arguments.length === 1 &&
|
|
121
|
+
node.arguments[0] !== undefined &&
|
|
122
|
+
isStringLiteralLikeNode(node.arguments[0])
|
|
123
|
+
? node.arguments[0].text
|
|
124
|
+
: undefined;
|
|
125
|
+
const memberName = (name) => isIdentifier(name) || isPrivateIdentifier(name) || isStringLiteralLikeNode(name) ? name.text : name.getText();
|
|
126
|
+
const visibilityOf = (flags, name) => Match.value(flags).pipe(Match.when((value) => (value & ModifierFlags.Private) !== 0 || isPrivateIdentifier(name), () => "private"), Match.when((value) => (value & ModifierFlags.Protected) !== 0, () => "protected"), Match.orElse(() => "public"));
|
|
127
|
+
const methodOf = (member) => isMethodDeclaration(member) || isMethodSignatureDeclaration(member)
|
|
128
|
+
? {
|
|
129
|
+
name: memberName(member.name),
|
|
130
|
+
visibility: visibilityOf(member.modifierFlags, member.name),
|
|
131
|
+
isStatic: hasFlag(member, ModifierFlags.Static),
|
|
132
|
+
}
|
|
133
|
+
: undefined;
|
|
134
|
+
/** Overload signatures collapse into one entry. */
|
|
135
|
+
const methodsOf = (members) => {
|
|
136
|
+
const seen = new Set();
|
|
137
|
+
const methods = [];
|
|
138
|
+
for (const member of members) {
|
|
139
|
+
const method = methodOf(member);
|
|
140
|
+
const key = method === undefined ? "" : `${method.visibility}|${method.isStatic}|${method.name}`;
|
|
141
|
+
if (method !== undefined && !seen.has(key)) {
|
|
142
|
+
seen.add(key);
|
|
143
|
+
methods.push(method);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return methods;
|
|
147
|
+
};
|
|
148
|
+
const parameterPropertyFlags = ModifierFlags.Public | ModifierFlags.Private | ModifierFlags.Protected | ModifierFlags.Readonly;
|
|
149
|
+
/** Constructor parameter properties count as properties. */
|
|
150
|
+
const hasOnlyReadonlyProperties = (members) => {
|
|
151
|
+
const properties = members.flatMap((member) => isPropertyDeclaration(member) || isPropertySignatureDeclaration(member)
|
|
152
|
+
? [member]
|
|
153
|
+
: isConstructorDeclaration(member)
|
|
154
|
+
? member.parameters.filter((parameter) => isParameterDeclaration(parameter) && (parameter.modifierFlags & parameterPropertyFlags) !== 0)
|
|
155
|
+
: []);
|
|
156
|
+
return properties.length > 0 && properties.every((property) => hasFlag(property, ModifierFlags.Readonly));
|
|
157
|
+
};
|
|
158
|
+
/** `Controller` for `@Controller` and `@Controller()`. */
|
|
159
|
+
const decoratorNames = (sourceFile, node) => (isClassDeclaration(node) ? (node.modifiers ?? []) : []).flatMap((modifier) => isDecorator(modifier)
|
|
160
|
+
? [(isCallExpression(modifier.expression) ? modifier.expression.expression : modifier.expression).getText(sourceFile)]
|
|
161
|
+
: []);
|
|
162
|
+
const heritageNames = (sourceFile, node, token) => (node.heritageClauses ?? [])
|
|
163
|
+
.filter((clause) => clause.token === token)
|
|
164
|
+
.flatMap((clause) => clause.types.map((type) => type.expression.getText(sourceFile)));
|
|
165
|
+
const boundNames = (name) => Match.value(name).pipe(Match.when(isIdentifier, (identifier) => [identifier.text]), Match.when(isObjectBindingPattern, (pattern) => pattern.elements.flatMap((element) => (element.name === undefined ? [] : boundNames(element.name)))), Match.when(isArrayBindingPattern, (pattern) => pattern.elements.flatMap((element) => (element.kind === SyntaxKind.BindingElement && element.name !== undefined ? boundNames(element.name) : []))), Match.orElse(() => []));
|
|
166
|
+
/** Names exported by `export { a as b }` and `export default a` instead of by a modifier. */
|
|
167
|
+
const exportedLocalNames = (sourceFile) => {
|
|
168
|
+
const names = new Set();
|
|
169
|
+
for (const statement of sourceFile.statements) {
|
|
170
|
+
if (isExportDeclaration(statement) && statement.moduleSpecifier === undefined && statement.exportClause !== undefined && isNamedExports(statement.exportClause)) {
|
|
171
|
+
for (const element of statement.exportClause.elements) {
|
|
172
|
+
names.add((element.propertyName ?? element.name).text);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
else if (isExportAssignment(statement) && isIdentifier(statement.expression)) {
|
|
176
|
+
names.add(statement.expression.text);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return names;
|
|
180
|
+
};
|
|
181
|
+
/** A variable statement gives one declaration per bound name, all at the statement's location. */
|
|
182
|
+
export const declarationsOf = (sourceFile) => {
|
|
183
|
+
const exportedNames = exportedLocalNames(sourceFile);
|
|
184
|
+
const base = (node, name) => ({
|
|
185
|
+
name,
|
|
186
|
+
exported: hasFlag(node, ModifierFlags.Export) || exportedNames.has(name),
|
|
187
|
+
abstract: hasFlag(node, ModifierFlags.Abstract),
|
|
188
|
+
location: locationOf(sourceFile, node),
|
|
189
|
+
});
|
|
190
|
+
const plain = { extended: [], implemented: [], decorators: [], methods: [], readonlyProperties: false };
|
|
191
|
+
const read = Match.type().pipe(Match.when(isClassDeclaration, (node) => [
|
|
192
|
+
{
|
|
193
|
+
...base(node, node.name?.text ?? "default"),
|
|
194
|
+
kind: "class",
|
|
195
|
+
extended: heritageNames(sourceFile, node, SyntaxKind.ExtendsKeyword),
|
|
196
|
+
implemented: heritageNames(sourceFile, node, SyntaxKind.ImplementsKeyword),
|
|
197
|
+
decorators: decoratorNames(sourceFile, node),
|
|
198
|
+
methods: methodsOf(node.members),
|
|
199
|
+
readonlyProperties: hasOnlyReadonlyProperties(node.members),
|
|
200
|
+
},
|
|
201
|
+
]), Match.when(isInterfaceDeclaration, (node) => [
|
|
202
|
+
{
|
|
203
|
+
...base(node, node.name.text),
|
|
204
|
+
kind: "interface",
|
|
205
|
+
extended: heritageNames(sourceFile, node, SyntaxKind.ExtendsKeyword),
|
|
206
|
+
implemented: [],
|
|
207
|
+
decorators: [],
|
|
208
|
+
methods: methodsOf(node.members),
|
|
209
|
+
readonlyProperties: hasOnlyReadonlyProperties(node.members),
|
|
210
|
+
},
|
|
211
|
+
]), Match.when(isEnumDeclaration, (node) => [{ ...base(node, node.name.text), kind: "enum", ...plain }]), Match.when(isFunctionDeclaration, (node) => [
|
|
212
|
+
{ ...base(node, node.name?.text ?? "default"), kind: "function", ...plain },
|
|
213
|
+
]), Match.when(isTypeAliasDeclaration, (node) => [{ ...base(node, node.name.text), kind: "type", ...plain }]), Match.when(isVariableStatement, (node) => node.declarationList.declarations
|
|
214
|
+
.flatMap((declaration) => boundNames(declaration.name))
|
|
215
|
+
.map((name) => ({ ...base(node, name), kind: "variable", ...plain }))), Match.orElse(() => []));
|
|
216
|
+
const functions = new Set();
|
|
217
|
+
return sourceFile.statements.flatMap(read).filter((declaration) => {
|
|
218
|
+
if (declaration.kind !== "function") {
|
|
219
|
+
return true;
|
|
220
|
+
}
|
|
221
|
+
const fresh = !functions.has(declaration.name);
|
|
222
|
+
functions.add(declaration.name);
|
|
223
|
+
return fresh;
|
|
224
|
+
});
|
|
225
|
+
};
|
|
226
|
+
//# sourceMappingURL=syntax.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"syntax.js","sourceRoot":"","sources":["../../src/analyzer/syntax.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Target } from "../core/model.ts";
|
|
2
|
+
/**
|
|
3
|
+
* `node:fs` and `fs` give `Builtin(node, "fs")`, `bun:test` gives
|
|
4
|
+
* `Builtin(bun, "test")`. The prefix alone makes a built-in, as at runtime;
|
|
5
|
+
* a bare name must be in Node's own list, so `node:test` is one and `test` is not.
|
|
6
|
+
*/
|
|
7
|
+
export declare const builtinTarget: (specifier: string) => Target | undefined;
|
|
8
|
+
export interface PackageName {
|
|
9
|
+
readonly name: string;
|
|
10
|
+
readonly subpath: ReadonlyArray<string>;
|
|
11
|
+
}
|
|
12
|
+
/** Scope-aware: `@scope/pkg/sub/path` is `@scope/pkg` with subpath `["sub", "path"]`. */
|
|
13
|
+
export declare const specifierPackage: (specifier: string) => PackageName | undefined;
|
|
14
|
+
/** The segment after the last `node_modules`, so nested and pnpm layouts both name the right package. */
|
|
15
|
+
export declare const installedPackage: (segments: ReadonlyArray<string>) => PackageName | undefined;
|
|
16
|
+
export declare const isInstalled: (segments: ReadonlyArray<string>) => boolean;
|
|
17
|
+
/**
|
|
18
|
+
* The specifier names the package when it is a package specifier for the
|
|
19
|
+
* package that was found: `picomatch` stays `picomatch` when the file is in
|
|
20
|
+
* `@types/picomatch`, and `react/jsx-runtime` keeps its subpath. Otherwise the
|
|
21
|
+
* file's own package decides, as for a path alias or a `#` import.
|
|
22
|
+
*/
|
|
23
|
+
export declare const packageTarget: (specifier: string, installed: PackageName | undefined) => Target | undefined;
|
|
24
|
+
/** The files a relative `require` can mean, in lookup order. */
|
|
25
|
+
export declare const fileCandidates: (base: string) => ReadonlyArray<string>;
|
|
26
|
+
//# sourceMappingURL=targets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"targets.d.ts","sourceRoot":"","sources":["../../src/analyzer/targets.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAQ9C;;;;GAIG;AACH,eAAO,MAAM,aAAa,cAAe,MAAM,KAAG,MAAM,GAAG,SAU1D,CAAA;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CACxC;AAwBD,yFAAyF;AACzF,eAAO,MAAM,gBAAgB,cAAe,MAAM,KAAG,WAAW,GAAG,SACU,CAAA;AAE7E,yGAAyG;AACzG,eAAO,MAAM,gBAAgB,aAAc,aAAa,CAAC,MAAM,CAAC,KAAG,WAAW,GAAG,SAGhF,CAAA;AAED,eAAO,MAAM,WAAW,aAAc,aAAa,CAAC,MAAM,CAAC,KAAG,OAA0C,CAAA;AAYxG;;;;;GAKG;AACH,eAAO,MAAM,aAAa,cAAe,MAAM,aAAa,WAAW,GAAG,SAAS,KAAG,MAAM,GAAG,SAO9F,CAAA;AAYD,gEAAgE;AAChE,eAAO,MAAM,cAAc,SAAU,MAAM,KAAG,aAAa,CAAC,MAAM,CAKjE,CAAA"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { builtinModules } from "node:module";
|
|
2
|
+
import { NODE_MODULES } from "./paths.js";
|
|
3
|
+
const bareNodeBuiltins = new Set(builtinModules.filter((name) => !name.startsWith("node:")));
|
|
4
|
+
const prefixed = (specifier, prefix) => specifier.startsWith(prefix) && specifier.length > prefix.length ? specifier.slice(prefix.length) : undefined;
|
|
5
|
+
/**
|
|
6
|
+
* `node:fs` and `fs` give `Builtin(node, "fs")`, `bun:test` gives
|
|
7
|
+
* `Builtin(bun, "test")`. The prefix alone makes a built-in, as at runtime;
|
|
8
|
+
* a bare name must be in Node's own list, so `node:test` is one and `test` is not.
|
|
9
|
+
*/
|
|
10
|
+
export const builtinTarget = (specifier) => {
|
|
11
|
+
const node = prefixed(specifier, "node:");
|
|
12
|
+
if (node !== undefined) {
|
|
13
|
+
return { _tag: "Builtin", runtime: "node", name: node };
|
|
14
|
+
}
|
|
15
|
+
const bun = prefixed(specifier, "bun:");
|
|
16
|
+
if (bun !== undefined) {
|
|
17
|
+
return { _tag: "Builtin", runtime: "bun", name: bun };
|
|
18
|
+
}
|
|
19
|
+
return bareNodeBuiltins.has(specifier) ? { _tag: "Builtin", runtime: "node", name: specifier } : undefined;
|
|
20
|
+
};
|
|
21
|
+
const isBareSpecifier = (specifier) => {
|
|
22
|
+
const first = specifier[0];
|
|
23
|
+
return (first !== undefined &&
|
|
24
|
+
first !== "." &&
|
|
25
|
+
first !== "/" &&
|
|
26
|
+
first !== "#" &&
|
|
27
|
+
first !== "~" &&
|
|
28
|
+
!specifier.includes(":") &&
|
|
29
|
+
!specifier.includes("\\"));
|
|
30
|
+
};
|
|
31
|
+
const splitPackage = (parts) => {
|
|
32
|
+
const scoped = parts[0]?.startsWith("@") === true;
|
|
33
|
+
const nameParts = parts.slice(0, scoped ? 2 : 1);
|
|
34
|
+
if (nameParts.length < (scoped ? 2 : 1) || nameParts.some((part) => part === "")) {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
return { name: nameParts.join("/"), subpath: parts.slice(nameParts.length).filter((part) => part !== "") };
|
|
38
|
+
};
|
|
39
|
+
/** Scope-aware: `@scope/pkg/sub/path` is `@scope/pkg` with subpath `["sub", "path"]`. */
|
|
40
|
+
export const specifierPackage = (specifier) => isBareSpecifier(specifier) ? splitPackage(specifier.split("/")) : undefined;
|
|
41
|
+
/** The segment after the last `node_modules`, so nested and pnpm layouts both name the right package. */
|
|
42
|
+
export const installedPackage = (segments) => {
|
|
43
|
+
const index = segments.lastIndexOf(NODE_MODULES);
|
|
44
|
+
return index < 0 ? undefined : splitPackage(segments.slice(index + 1));
|
|
45
|
+
};
|
|
46
|
+
export const isInstalled = (segments) => segments.includes(NODE_MODULES);
|
|
47
|
+
/** DefinitelyTyped names `@a/b` as `@types/a__b`. */
|
|
48
|
+
const runtimeName = (name) => {
|
|
49
|
+
const typed = prefixed(name, "@types/");
|
|
50
|
+
if (typed === undefined) {
|
|
51
|
+
return name;
|
|
52
|
+
}
|
|
53
|
+
const separator = typed.indexOf("__");
|
|
54
|
+
return separator < 0 ? typed : `@${typed.slice(0, separator)}/${typed.slice(separator + 2)}`;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* The specifier names the package when it is a package specifier for the
|
|
58
|
+
* package that was found: `picomatch` stays `picomatch` when the file is in
|
|
59
|
+
* `@types/picomatch`, and `react/jsx-runtime` keeps its subpath. Otherwise the
|
|
60
|
+
* file's own package decides, as for a path alias or a `#` import.
|
|
61
|
+
*/
|
|
62
|
+
export const packageTarget = (specifier, installed) => {
|
|
63
|
+
const written = specifierPackage(specifier);
|
|
64
|
+
const found = installed === undefined || (written !== undefined && [installed.name, runtimeName(installed.name)].includes(written.name))
|
|
65
|
+
? (written ?? installed)
|
|
66
|
+
: installed;
|
|
67
|
+
return found === undefined ? undefined : { _tag: "Package", name: found.name, subpath: found.subpath };
|
|
68
|
+
};
|
|
69
|
+
const sourceExtensions = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
|
|
70
|
+
/** `.js` in a specifier names the `.ts` file next to it. */
|
|
71
|
+
const extensionSubstitutes = [
|
|
72
|
+
[".js", [".ts", ".tsx"]],
|
|
73
|
+
[".jsx", [".tsx"]],
|
|
74
|
+
[".mjs", [".mts"]],
|
|
75
|
+
[".cjs", [".cts"]],
|
|
76
|
+
];
|
|
77
|
+
/** The files a relative `require` can mean, in lookup order. */
|
|
78
|
+
export const fileCandidates = (base) => [
|
|
79
|
+
base,
|
|
80
|
+
...extensionSubstitutes.flatMap(([from, to]) => (base.endsWith(from) ? to.map((ext) => base.slice(0, -from.length) + ext) : [])),
|
|
81
|
+
...sourceExtensions.map((ext) => base + ext),
|
|
82
|
+
...sourceExtensions.map((ext) => `${base}/index${ext}`),
|
|
83
|
+
];
|
|
84
|
+
//# sourceMappingURL=targets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"targets.js","sourceRoot":"","sources":["../../src/analyzer/targets.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** The TypeScript adapter of the Analyzer. Contract: docs/architecture.md#analyzer. */
|
|
2
|
+
import { Effect, FileSystem, Path, Scope } from "effect";
|
|
3
|
+
import type { AnalyzerShape } from "./workspace.ts";
|
|
4
|
+
export declare const makeTypescript: Effect.Effect<AnalyzerShape, never, FileSystem.FileSystem | Path.Path | Scope.Scope>;
|
|
5
|
+
//# sourceMappingURL=typescript.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typescript.d.ts","sourceRoot":"","sources":["../../src/analyzer/typescript.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,OAAO,EAAE,MAAM,EAAQ,UAAU,EAAS,IAAI,EAAO,KAAK,EAAa,MAAM,QAAQ,CAAA;AAGrF,OAAO,KAAK,EAAE,aAAa,EAAa,MAAM,gBAAgB,CAAA;AAsI9D,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAwN9G,CAAA"}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/** The TypeScript adapter of the Analyzer. Contract: docs/architecture.md#analyzer. */
|
|
2
|
+
import { Effect, Exit, FileSystem, Match, Path, Ref, Scope, Semaphore } from "effect";
|
|
3
|
+
import { API, DiagnosticCategory } from "typescript/unstable/async";
|
|
4
|
+
import { AnalyzerUnavailable, ProjectNotFound, ProjectParseFailed } from "./errors.js";
|
|
5
|
+
import { compareCodeUnits, isDeclarationFileName, isJsonFileName, NODE_MODULES, splitPath } from "./paths.js";
|
|
6
|
+
import { readSource } from "./source.js";
|
|
7
|
+
import { abandon, muteFailedWrites, serverExit } from "./server-exit.js";
|
|
8
|
+
import { builtinTarget, fileCandidates, installedPackage, isInstalled, packageTarget, specifierPackage } from "./targets.js";
|
|
9
|
+
const unavailable = (cause) => new AnalyzerUnavailable({ cause });
|
|
10
|
+
const attempt = (evaluate) => Effect.try({ try: evaluate, catch: unavailable });
|
|
11
|
+
const attemptPromise = (evaluate) => Effect.tryPromise({ try: evaluate, catch: unavailable });
|
|
12
|
+
/**
|
|
13
|
+
* The server starts on first use and stops with the layer's scope. A failure
|
|
14
|
+
* that makes the server unusable also stops it, so the next call starts a new one.
|
|
15
|
+
*/
|
|
16
|
+
const makeServer = Effect.gen(function* () {
|
|
17
|
+
const layerScope = yield* Effect.scope;
|
|
18
|
+
const current = yield* Ref.make(undefined);
|
|
19
|
+
const lock = yield* Semaphore.make(1);
|
|
20
|
+
const start = Effect.gen(function* () {
|
|
21
|
+
const scope = yield* Scope.fork(layerScope);
|
|
22
|
+
let exitedServer = false;
|
|
23
|
+
const api = yield* Effect.acquireRelease(attempt(() => new API()), (started) => exitedServer ? Effect.sync(() => abandon(started)) : attemptPromise(() => started.close()).pipe(Effect.ignore)).pipe(Scope.provide(scope), Effect.tapError(() => Scope.close(scope, Exit.void)));
|
|
24
|
+
yield* attemptPromise(() => api.updateSnapshot().then((snapshot) => snapshot.dispose())).pipe(Effect.tapError(() => Scope.close(scope, Exit.void)));
|
|
25
|
+
muteFailedWrites(api);
|
|
26
|
+
const exited = serverExit(api);
|
|
27
|
+
void exited.then(() => {
|
|
28
|
+
exitedServer = true;
|
|
29
|
+
});
|
|
30
|
+
const lost = () => exited.then(() => {
|
|
31
|
+
throw new Error("TypeScript server exited");
|
|
32
|
+
});
|
|
33
|
+
/** A request to a server known to be dead fails without writing to it. */
|
|
34
|
+
const request = (evaluate) => exitedServer
|
|
35
|
+
? Effect.fail(new AnalyzerUnavailable({ cause: new Error("TypeScript server exited") }))
|
|
36
|
+
: attemptPromise(() => Promise.race([evaluate(), lost()]));
|
|
37
|
+
const remote = { api, request };
|
|
38
|
+
const session = { remote, scope };
|
|
39
|
+
yield* Ref.set(current, session);
|
|
40
|
+
return session;
|
|
41
|
+
});
|
|
42
|
+
const stop = Effect.gen(function* () {
|
|
43
|
+
const session = yield* Ref.getAndSet(current, undefined);
|
|
44
|
+
if (session !== undefined) {
|
|
45
|
+
yield* Scope.close(session.scope, Exit.void);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
/** A request cannot be taken back, so an interrupted analysis finishes before the next one starts. */
|
|
49
|
+
const use = (run) => lock.withPermit(Effect.gen(function* () {
|
|
50
|
+
const session = (yield* Ref.get(current)) ?? (yield* start);
|
|
51
|
+
return yield* run(session.remote);
|
|
52
|
+
}).pipe(Effect.uninterruptible, Effect.tapError(Match.type().pipe(Match.tag("AnalyzerUnavailable", () => stop), Match.orElse(() => Effect.void)))));
|
|
53
|
+
return { use };
|
|
54
|
+
});
|
|
55
|
+
const READ_CONCURRENCY = 16;
|
|
56
|
+
const normalize = (file) => file.replaceAll("\\", "/");
|
|
57
|
+
const joined = (path) => path.join("/");
|
|
58
|
+
const isRelative = (specifier, isAbsolute) => specifier === "." || specifier === ".." || specifier.startsWith("./") || specifier.startsWith("../") || isAbsolute(specifier);
|
|
59
|
+
export const makeTypescript = Effect.gen(function* () {
|
|
60
|
+
const fs = yield* FileSystem.FileSystem;
|
|
61
|
+
const path = yield* Path.Path;
|
|
62
|
+
const server = yield* makeServer;
|
|
63
|
+
const platform = (effect) => effect.pipe(Effect.mapError(unavailable));
|
|
64
|
+
const describeDiagnostic = (root) => (diagnostic) => {
|
|
65
|
+
const relative = diagnostic.fileName === undefined ? undefined : path.relative(root, diagnostic.fileName);
|
|
66
|
+
const file = relative === undefined ? undefined : relative.startsWith("..") ? diagnostic.fileName : relative;
|
|
67
|
+
return `${file === undefined ? "" : `${file}: `}TS${diagnostic.code}: ${diagnostic.text}`;
|
|
68
|
+
};
|
|
69
|
+
const loadProject = (remote, snapshot, root, tsconfig) => Effect.gen(function* () {
|
|
70
|
+
const project = snapshot.getProject(path.join(root, tsconfig));
|
|
71
|
+
if (project === undefined) {
|
|
72
|
+
return yield* unavailable(new Error(`TypeScript did not open ${tsconfig}`));
|
|
73
|
+
}
|
|
74
|
+
const errors = (yield* remote.request(() => project.program.getConfigFileParsingDiagnostics())).filter((diagnostic) => diagnostic.category === DiagnosticCategory.Error);
|
|
75
|
+
if (errors.length > 0) {
|
|
76
|
+
return yield* new ProjectParseFailed({ tsconfig, diagnostics: errors.map(describeDiagnostic(root)) });
|
|
77
|
+
}
|
|
78
|
+
return { tsconfig, project };
|
|
79
|
+
});
|
|
80
|
+
const locate = (root, tsconfig) => Effect.gen(function* () {
|
|
81
|
+
if (!(yield* platform(fs.exists(path.resolve(root, tsconfig))))) {
|
|
82
|
+
return yield* new ProjectNotFound({ tsconfig });
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
const sourceSet = (root, projects) => Effect.gen(function* () {
|
|
86
|
+
const entries = new Map();
|
|
87
|
+
for (const { project } of projects) {
|
|
88
|
+
const candidates = project.rootFiles.filter((fileName) => !isDeclarationFileName(fileName) && !isJsonFileName(fileName) && !isInstalled(splitPath(fileName)));
|
|
89
|
+
const real = yield* Effect.forEach(candidates, (fileName) => platform(fs.realPath(fileName)), { concurrency: 16 });
|
|
90
|
+
candidates.forEach((fileName, index) => {
|
|
91
|
+
const realPath = normalize(real[index] ?? fileName);
|
|
92
|
+
const relative = path.relative(root, realPath);
|
|
93
|
+
const segments = splitPath(relative);
|
|
94
|
+
const inside = segments.length > 0 && segments[0] !== ".." && !path.isAbsolute(relative);
|
|
95
|
+
if (inside && !isInstalled(segments) && !entries.has(realPath)) {
|
|
96
|
+
entries.set(realPath, { path: segments, programFileName: fileName, realPath, project });
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
return [...entries.values()].toSorted((left, right) => compareCodeUnits(joined(left.path), joined(right.path)));
|
|
101
|
+
});
|
|
102
|
+
const makeTargets = (entries, caseSensitive) => {
|
|
103
|
+
const fold = (file) => (caseSensitive ? normalize(file) : normalize(file).toLowerCase());
|
|
104
|
+
const files = new Map(entries.map((entry) => [fold(entry.realPath), entry.path]));
|
|
105
|
+
const probes = new Map();
|
|
106
|
+
const through = new Map();
|
|
107
|
+
const hasPackage = (directory, name) => Effect.gen(function* () {
|
|
108
|
+
const key = `${directory}\0${name}`;
|
|
109
|
+
const known = probes.get(key);
|
|
110
|
+
if (known !== undefined) {
|
|
111
|
+
return known;
|
|
112
|
+
}
|
|
113
|
+
const parent = path.dirname(directory);
|
|
114
|
+
const found = (yield* platform(fs.exists(path.join(directory, NODE_MODULES, name)))) ||
|
|
115
|
+
(parent !== directory && (yield* hasPackage(parent, name)));
|
|
116
|
+
probes.set(key, found);
|
|
117
|
+
return found;
|
|
118
|
+
});
|
|
119
|
+
const probedPackage = (specifier, directory) => Effect.gen(function* () {
|
|
120
|
+
const written = specifierPackage(specifier);
|
|
121
|
+
return written !== undefined && (yield* hasPackage(directory, written.name))
|
|
122
|
+
? { _tag: "Package", name: written.name, subpath: written.subpath }
|
|
123
|
+
: { _tag: "Unresolved", specifier };
|
|
124
|
+
});
|
|
125
|
+
const relativeFile = (specifier, directory) => {
|
|
126
|
+
const hit = fileCandidates(path.resolve(directory, specifier)).find((candidate) => files.has(fold(candidate)));
|
|
127
|
+
const found = hit === undefined ? undefined : files.get(fold(hit));
|
|
128
|
+
return found === undefined ? { _tag: "Unresolved", specifier } : { _tag: "File", path: found };
|
|
129
|
+
};
|
|
130
|
+
const sourceFileAt = (modulePath) => {
|
|
131
|
+
const direct = files.get(fold(modulePath));
|
|
132
|
+
if (direct !== undefined || through.has(modulePath)) {
|
|
133
|
+
return Effect.succeed(direct ?? through.get(modulePath));
|
|
134
|
+
}
|
|
135
|
+
return fs.realPath(modulePath).pipe(Effect.map((real) => files.get(fold(real))), Effect.orElseSucceed(() => undefined), Effect.tap((found) => Effect.sync(() => through.set(modulePath, found))));
|
|
136
|
+
};
|
|
137
|
+
const moduleTarget = (specifier, module) => {
|
|
138
|
+
const unresolved = { _tag: "Unresolved", specifier };
|
|
139
|
+
const segments = splitPath(module.path);
|
|
140
|
+
return isInstalled(segments)
|
|
141
|
+
? Effect.succeed(packageTarget(specifier, installedPackage(segments)) ?? unresolved)
|
|
142
|
+
: module.isFile
|
|
143
|
+
? Effect.map(sourceFileAt(module.path), (found) => (found === undefined ? unresolved : { _tag: "File", path: found }))
|
|
144
|
+
: Effect.succeed(unresolved);
|
|
145
|
+
};
|
|
146
|
+
const orBuiltin = (specifier, otherwise) => {
|
|
147
|
+
const builtin = builtinTarget(specifier);
|
|
148
|
+
return builtin === undefined ? otherwise() : Effect.succeed(builtin);
|
|
149
|
+
};
|
|
150
|
+
const target = (dependency, directory) => Match.valueTags(dependency.resolution, {
|
|
151
|
+
Computed: () => Effect.succeed({ _tag: "Computed" }),
|
|
152
|
+
Module: (module) => orBuiltin(dependency.specifier, () => moduleTarget(dependency.specifier, module)),
|
|
153
|
+
Missing: () => orBuiltin(dependency.specifier, () => probedPackage(dependency.specifier, directory)),
|
|
154
|
+
Unchecked: () => orBuiltin(dependency.specifier, () => isRelative(dependency.specifier, path.isAbsolute)
|
|
155
|
+
? Effect.succeed(relativeFile(dependency.specifier, directory))
|
|
156
|
+
: probedPackage(dependency.specifier, directory)),
|
|
157
|
+
});
|
|
158
|
+
return { target };
|
|
159
|
+
};
|
|
160
|
+
const read = (remote, entry) => remote.request(async () => {
|
|
161
|
+
const sourceFile = await entry.project.program.getSourceFile(entry.programFileName);
|
|
162
|
+
if (sourceFile === undefined) {
|
|
163
|
+
throw new Error(`TypeScript did not load ${entry.programFileName}`);
|
|
164
|
+
}
|
|
165
|
+
return { raw: await readSource(entry.project, sourceFile), caseSensitive: sourceFile.path === normalize(sourceFile.fileName) };
|
|
166
|
+
});
|
|
167
|
+
const assemble = (entry, raw, targets) => Effect.gen(function* () {
|
|
168
|
+
const directory = path.dirname(entry.realPath);
|
|
169
|
+
const dependencies = yield* Effect.forEach(raw.dependencies, (dependency) => Effect.map(targets.target(dependency, directory), (target) => ({
|
|
170
|
+
target,
|
|
171
|
+
kind: dependency.kind,
|
|
172
|
+
specifier: dependency.specifier,
|
|
173
|
+
location: dependency.location,
|
|
174
|
+
})));
|
|
175
|
+
return {
|
|
176
|
+
path: entry.path,
|
|
177
|
+
dependencies,
|
|
178
|
+
declarations: raw.declarations,
|
|
179
|
+
exports: raw.exports,
|
|
180
|
+
uses: raw.uses,
|
|
181
|
+
lines: raw.lines,
|
|
182
|
+
};
|
|
183
|
+
});
|
|
184
|
+
/**
|
|
185
|
+
* The server keeps tsconfig file lists and file contents between snapshots.
|
|
186
|
+
* Closing the projects, invalidating, and reporting the tsconfigs as changed
|
|
187
|
+
* makes it list and read everything again; the client's copies must go too.
|
|
188
|
+
*/
|
|
189
|
+
const reset = ({ api, request }, configPaths) => request(async () => {
|
|
190
|
+
await (await api.updateSnapshot({ closeProjects: [...configPaths] })).dispose();
|
|
191
|
+
await (await api.updateSnapshot({ fileChanges: { invalidateAll: true } })).dispose();
|
|
192
|
+
await (await api.updateSnapshot({ fileChanges: { changed: [...configPaths] } })).dispose();
|
|
193
|
+
api.clearSourceFileCache();
|
|
194
|
+
});
|
|
195
|
+
const analyzeWith = (remote, root, tsconfigs) => {
|
|
196
|
+
const configPaths = tsconfigs.map((tsconfig) => path.join(root, tsconfig));
|
|
197
|
+
return Effect.acquireUseRelease(reset(remote, configPaths).pipe(Effect.andThen(remote.request(() => remote.api.updateSnapshot({ openProjects: [...configPaths] })))), (snapshot) => Effect.gen(function* () {
|
|
198
|
+
const projects = yield* Effect.forEach(tsconfigs, (tsconfig) => loadProject(remote, snapshot, root, tsconfig));
|
|
199
|
+
const entries = yield* sourceSet(root, projects);
|
|
200
|
+
const sources = yield* Effect.forEach(entries, (entry) => read(remote, entry), { concurrency: READ_CONCURRENCY });
|
|
201
|
+
const targets = makeTargets(entries, sources.every(({ caseSensitive }) => caseSensitive));
|
|
202
|
+
const files = yield* Effect.forEach(entries, (entry, index) => {
|
|
203
|
+
const source = sources[index];
|
|
204
|
+
return source === undefined
|
|
205
|
+
? Effect.fail(unavailable(new Error(`no source read for ${entry.programFileName}`)))
|
|
206
|
+
: assemble(entry, source.raw, targets);
|
|
207
|
+
});
|
|
208
|
+
return { files };
|
|
209
|
+
}), (snapshot) => remote.request(async () => {
|
|
210
|
+
await snapshot.dispose();
|
|
211
|
+
await (await remote.api.updateSnapshot({ closeProjects: [...configPaths] })).dispose();
|
|
212
|
+
}).pipe(Effect.ignore));
|
|
213
|
+
};
|
|
214
|
+
const analyze = Effect.fn("Analyzer.typescript.analyze")(function* (workspace) {
|
|
215
|
+
yield* Effect.forEach(workspace.projects, (tsconfig) => locate(workspace.root, tsconfig));
|
|
216
|
+
const root = normalize(yield* platform(fs.realPath(workspace.root)));
|
|
217
|
+
return yield* server.use((remote) => analyzeWith(remote, root, workspace.projects));
|
|
218
|
+
});
|
|
219
|
+
return { analyze };
|
|
220
|
+
});
|
|
221
|
+
//# sourceMappingURL=typescript.js.map
|