@beignet/cli 0.0.51 → 0.0.53
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/CHANGELOG.md +46 -0
- package/README.md +182 -19
- package/dist/analysis/layers.d.ts +2 -0
- package/dist/analysis/layers.d.ts.map +1 -1
- package/dist/analysis/layers.js +9 -2
- package/dist/analysis/layers.js.map +1 -1
- package/dist/analysis/port-wiring.d.ts +4 -2
- package/dist/analysis/port-wiring.d.ts.map +1 -1
- package/dist/analysis/port-wiring.js +41 -11
- package/dist/analysis/port-wiring.js.map +1 -1
- package/dist/analysis/source-files.d.ts +15 -0
- package/dist/analysis/source-files.d.ts.map +1 -0
- package/dist/analysis/source-files.js +52 -0
- package/dist/analysis/source-files.js.map +1 -0
- package/dist/analysis/source-index.d.ts +2 -1
- package/dist/analysis/source-index.d.ts.map +1 -1
- package/dist/analysis/source-index.js +34 -5
- package/dist/analysis/source-index.js.map +1 -1
- package/dist/analysis/workspace-routes.d.ts +8 -0
- package/dist/analysis/workspace-routes.d.ts.map +1 -0
- package/dist/analysis/workspace-routes.js +291 -0
- package/dist/analysis/workspace-routes.js.map +1 -0
- package/dist/analysis/workspace.d.ts +24 -3
- package/dist/analysis/workspace.d.ts.map +1 -1
- package/dist/analysis/workspace.js +184 -43
- package/dist/analysis/workspace.js.map +1 -1
- package/dist/app-map-changes.d.ts.map +1 -1
- package/dist/app-map-changes.js +24 -14
- package/dist/app-map-changes.js.map +1 -1
- package/dist/app-map.d.ts.map +1 -1
- package/dist/app-map.js +87 -81
- package/dist/app-map.js.map +1 -1
- package/dist/check.d.ts +12 -0
- package/dist/check.d.ts.map +1 -1
- package/dist/check.js +92 -25
- package/dist/check.js.map +1 -1
- package/dist/config.d.ts +7 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +19 -0
- package/dist/config.js.map +1 -1
- package/dist/git-changes.d.ts +17 -1
- package/dist/git-changes.d.ts.map +1 -1
- package/dist/git-changes.js +118 -84
- package/dist/git-changes.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -3
- package/dist/index.js.map +1 -1
- package/dist/inspect.d.ts.map +1 -1
- package/dist/inspect.js +424 -129
- package/dist/inspect.js.map +1 -1
- package/dist/lint.d.ts.map +1 -1
- package/dist/lint.js +108 -43
- package/dist/lint.js.map +1 -1
- package/dist/make/shared.js +1 -1
- package/dist/make.js +18 -1
- package/dist/make.js.map +1 -1
- package/dist/mcp.js +1 -1
- package/dist/mcp.js.map +1 -1
- package/dist/provider-add.js +2 -2
- package/dist/provider-add.js.map +1 -1
- package/dist/provider-audit.d.ts.map +1 -1
- package/dist/provider-audit.js +22 -6
- package/dist/provider-audit.js.map +1 -1
- package/dist/templates/agents.d.ts.map +1 -1
- package/dist/templates/agents.js +36 -13
- package/dist/templates/agents.js.map +1 -1
- package/dist/templates/base.js +5 -5
- package/dist/templates/db/mysql.d.ts.map +1 -1
- package/dist/templates/db/mysql.js +51 -22
- package/dist/templates/db/mysql.js.map +1 -1
- package/dist/templates/db/postgres.d.ts.map +1 -1
- package/dist/templates/db/postgres.js +60 -20
- package/dist/templates/db/postgres.js.map +1 -1
- package/dist/templates/db/sqlite.d.ts.map +1 -1
- package/dist/templates/db/sqlite.js +51 -23
- package/dist/templates/db/sqlite.js.map +1 -1
- package/dist/templates/shadcn.js +1 -1
- package/dist/templates/shadcn.js.map +1 -1
- package/dist/templates/shared.js +6 -6
- package/dist/templates/shared.js.map +1 -1
- package/dist/templates/testing.d.ts.map +1 -1
- package/dist/templates/testing.js +7 -19
- package/dist/templates/testing.js.map +1 -1
- package/dist/test-discovery.d.ts +9 -0
- package/dist/test-discovery.d.ts.map +1 -0
- package/dist/test-discovery.js +40 -0
- package/dist/test-discovery.js.map +1 -0
- package/package.json +8 -5
- package/skills/app-structure/SKILL.md +74 -7
- package/src/analysis/layers.ts +13 -2
- package/src/analysis/port-wiring.ts +68 -11
- package/src/analysis/source-files.ts +61 -0
- package/src/analysis/source-index.ts +56 -4
- package/src/analysis/workspace-routes.ts +385 -0
- package/src/analysis/workspace.ts +302 -59
- package/src/app-map-changes.ts +41 -13
- package/src/app-map.ts +114 -103
- package/src/check.ts +115 -25
- package/src/config.ts +33 -0
- package/src/git-changes.ts +218 -86
- package/src/index.ts +33 -5
- package/src/inspect.ts +608 -156
- package/src/lint.ts +152 -48
- package/src/make/shared.ts +1 -1
- package/src/make.ts +31 -1
- package/src/mcp.ts +1 -1
- package/src/provider-add.ts +2 -2
- package/src/provider-audit.ts +30 -10
- package/src/templates/agents.ts +36 -13
- package/src/templates/base.ts +5 -5
- package/src/templates/db/mysql.ts +51 -22
- package/src/templates/db/postgres.ts +60 -20
- package/src/templates/db/sqlite.ts +51 -23
- package/src/templates/shadcn.ts +1 -1
- package/src/templates/shared.ts +6 -6
- package/src/templates/testing.ts +12 -19
- package/src/test-discovery.ts +53 -0
|
@@ -2,7 +2,16 @@ import { readFile } from "node:fs/promises";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import ts from "typescript";
|
|
4
4
|
import type { ResolvedBeignetConfig } from "../config.js";
|
|
5
|
-
import
|
|
5
|
+
import { sourceFileScriptKind } from "./source-files.js";
|
|
6
|
+
import {
|
|
7
|
+
createSourceIndex,
|
|
8
|
+
type ResolvedSourceReference,
|
|
9
|
+
type SourceIndex,
|
|
10
|
+
} from "./source-index.js";
|
|
11
|
+
import {
|
|
12
|
+
type AnalysisWorkspace,
|
|
13
|
+
createAnalysisWorkspace,
|
|
14
|
+
} from "./workspace.js";
|
|
6
15
|
|
|
7
16
|
type PortAnalysisWorkspace = Pick<
|
|
8
17
|
AnalysisWorkspace,
|
|
@@ -13,6 +22,7 @@ export type PortWiringAnalysis = {
|
|
|
13
22
|
portsFileExists: boolean;
|
|
14
23
|
portWiringFileExists: boolean;
|
|
15
24
|
properties: Map<string, ts.PropertySignature>;
|
|
25
|
+
propertyFiles: Map<string, string>;
|
|
16
26
|
declared: Set<string>;
|
|
17
27
|
bound: Set<string>;
|
|
18
28
|
deferred: Set<string>;
|
|
@@ -23,6 +33,7 @@ export type PortWiringAnalysis = {
|
|
|
23
33
|
|
|
24
34
|
export async function analyzePortWiring(
|
|
25
35
|
workspace: PortAnalysisWorkspace,
|
|
36
|
+
sourceIndex?: SourceIndex,
|
|
26
37
|
): Promise<PortWiringAnalysis> {
|
|
27
38
|
const result: PortWiringAnalysis = {
|
|
28
39
|
portsFileExists: workspace.fileSet.has(workspace.config.paths.ports),
|
|
@@ -30,6 +41,7 @@ export async function analyzePortWiring(
|
|
|
30
41
|
workspace.config.paths.portWiring,
|
|
31
42
|
),
|
|
32
43
|
properties: new Map(),
|
|
44
|
+
propertyFiles: new Map(),
|
|
33
45
|
declared: new Set(),
|
|
34
46
|
bound: new Set(),
|
|
35
47
|
deferred: new Set(),
|
|
@@ -39,20 +51,31 @@ export async function analyzePortWiring(
|
|
|
39
51
|
};
|
|
40
52
|
|
|
41
53
|
let inferredAppPortsName: string | undefined;
|
|
54
|
+
let inferredAppPortsReference: ResolvedSourceReference | undefined;
|
|
42
55
|
if (result.portsFileExists) {
|
|
43
|
-
const
|
|
56
|
+
const reference = await sourceIndex?.resolveExport(
|
|
44
57
|
workspace.config.paths.ports,
|
|
58
|
+
"AppPorts",
|
|
45
59
|
);
|
|
60
|
+
const portsFile = reference?.file ?? workspace.config.paths.ports;
|
|
61
|
+
const portsName = reference?.exportName ?? "AppPorts";
|
|
62
|
+
const sourceFile = await workspace.readSourceFile(portsFile);
|
|
46
63
|
const declarations = collectTypeDeclarations(sourceFile);
|
|
47
|
-
inferredAppPortsName = inferredTypeQueryName(
|
|
64
|
+
inferredAppPortsName = inferredTypeQueryName(portsName, declarations);
|
|
65
|
+
if (inferredAppPortsName)
|
|
66
|
+
inferredAppPortsReference = await sourceIndex?.resolveName(
|
|
67
|
+
portsFile,
|
|
68
|
+
inferredAppPortsName,
|
|
69
|
+
);
|
|
48
70
|
const collection = inferredAppPortsName
|
|
49
71
|
? { properties: [], indeterminate: false }
|
|
50
|
-
: collectNamedTypeProperties(
|
|
72
|
+
: collectNamedTypeProperties(portsName, declarations, !sourceIndex);
|
|
51
73
|
result.declarationIndeterminate = collection.indeterminate;
|
|
52
74
|
for (const property of collection.properties) {
|
|
53
75
|
const name = propertyName(property.name);
|
|
54
76
|
if (name && !result.properties.has(name)) {
|
|
55
77
|
result.properties.set(name, property);
|
|
78
|
+
result.propertyFiles.set(name, portsFile);
|
|
56
79
|
result.declared.add(name);
|
|
57
80
|
}
|
|
58
81
|
}
|
|
@@ -62,12 +85,27 @@ export async function analyzePortWiring(
|
|
|
62
85
|
if (inferredAppPortsName) result.declarationIndeterminate = true;
|
|
63
86
|
return result;
|
|
64
87
|
}
|
|
65
|
-
const
|
|
88
|
+
const wiringReference = await sourceIndex?.resolveExport(
|
|
66
89
|
workspace.config.paths.portWiring,
|
|
90
|
+
"initialPorts",
|
|
91
|
+
);
|
|
92
|
+
const sourceFile = await workspace.readSourceFile(
|
|
93
|
+
wiringReference?.file ?? workspace.config.paths.portWiring,
|
|
67
94
|
);
|
|
68
95
|
const values = collectVariableInitializers(sourceFile);
|
|
69
|
-
const definitions = portDefinitionCalls(
|
|
70
|
-
|
|
96
|
+
const definitions = portDefinitionCalls(
|
|
97
|
+
sourceFile,
|
|
98
|
+
wiringReference?.declaration &&
|
|
99
|
+
ts.isVariableDeclaration(wiringReference.declaration) &&
|
|
100
|
+
ts.isIdentifier(wiringReference.declaration.name)
|
|
101
|
+
? wiringReference.declaration.name.text
|
|
102
|
+
: wiringReference?.exportName,
|
|
103
|
+
);
|
|
104
|
+
if (
|
|
105
|
+
definitions.indeterminate ||
|
|
106
|
+
(sourceIndex && definitions.calls.length === 0)
|
|
107
|
+
)
|
|
108
|
+
result.indeterminate = true;
|
|
71
109
|
|
|
72
110
|
for (const call of definitions.calls) {
|
|
73
111
|
const objectArgument = call.arguments
|
|
@@ -123,7 +161,13 @@ export async function analyzePortWiring(
|
|
|
123
161
|
if (inferredAppPortsName) {
|
|
124
162
|
if (
|
|
125
163
|
!definitions.indeterminate &&
|
|
126
|
-
|
|
164
|
+
(sourceIndex
|
|
165
|
+
? Boolean(
|
|
166
|
+
inferredAppPortsReference?.declaration &&
|
|
167
|
+
inferredAppPortsReference.declaration ===
|
|
168
|
+
wiringReference?.declaration,
|
|
169
|
+
)
|
|
170
|
+
: definitions.name === inferredAppPortsName)
|
|
127
171
|
) {
|
|
128
172
|
result.appPortsInferredFromWiring = true;
|
|
129
173
|
for (const name of result.bound) result.declared.add(name);
|
|
@@ -136,7 +180,10 @@ export async function analyzePortWiring(
|
|
|
136
180
|
return result;
|
|
137
181
|
}
|
|
138
182
|
|
|
139
|
-
function portDefinitionCalls(
|
|
183
|
+
function portDefinitionCalls(
|
|
184
|
+
sourceFile: ts.SourceFile,
|
|
185
|
+
preferredName?: string,
|
|
186
|
+
): {
|
|
140
187
|
calls: ts.CallExpression[];
|
|
141
188
|
name?: string;
|
|
142
189
|
indeterminate: boolean;
|
|
@@ -171,8 +218,12 @@ function portDefinitionCalls(sourceFile: ts.SourceFile): {
|
|
|
171
218
|
}
|
|
172
219
|
|
|
173
220
|
const canonical = candidates.filter(
|
|
174
|
-
(candidate) =>
|
|
221
|
+
(candidate) =>
|
|
222
|
+
candidate.name === (preferredName ?? "initialPorts") &&
|
|
223
|
+
candidate.exported,
|
|
175
224
|
);
|
|
225
|
+
if (preferredName && canonical.length === 0)
|
|
226
|
+
return { calls: [], indeterminate: true };
|
|
176
227
|
const exported = candidates.filter((candidate) => candidate.exported);
|
|
177
228
|
const selected =
|
|
178
229
|
canonical.length > 0
|
|
@@ -229,6 +280,12 @@ export async function analyzePortWiringFiles(options: {
|
|
|
229
280
|
files: readonly string[];
|
|
230
281
|
config: ResolvedBeignetConfig;
|
|
231
282
|
}): Promise<PortWiringAnalysis> {
|
|
283
|
+
if (options.config.workspace.packages.length > 0) {
|
|
284
|
+
const workspace = await createAnalysisWorkspace(options.targetDir, {
|
|
285
|
+
config: options.config,
|
|
286
|
+
});
|
|
287
|
+
return analyzePortWiring(workspace, createSourceIndex(workspace));
|
|
288
|
+
}
|
|
232
289
|
const sourceFiles = new Map<string, ts.SourceFile>();
|
|
233
290
|
return analyzePortWiring({
|
|
234
291
|
config: options.config,
|
|
@@ -241,7 +298,7 @@ export async function analyzePortWiringFiles(options: {
|
|
|
241
298
|
await readFile(path.join(options.targetDir, file), "utf8"),
|
|
242
299
|
ts.ScriptTarget.Latest,
|
|
243
300
|
true,
|
|
244
|
-
file
|
|
301
|
+
sourceFileScriptKind(file),
|
|
245
302
|
);
|
|
246
303
|
sourceFiles.set(file, sourceFile);
|
|
247
304
|
return sourceFile;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import ts from "typescript";
|
|
3
|
+
|
|
4
|
+
export const typescriptAnalysisSourceFileExtensions = [
|
|
5
|
+
".ts",
|
|
6
|
+
".tsx",
|
|
7
|
+
".mts",
|
|
8
|
+
".cts",
|
|
9
|
+
] as const;
|
|
10
|
+
|
|
11
|
+
export const javascriptAnalysisSourceFileExtensions = [
|
|
12
|
+
".js",
|
|
13
|
+
".jsx",
|
|
14
|
+
".mjs",
|
|
15
|
+
".cjs",
|
|
16
|
+
] as const;
|
|
17
|
+
|
|
18
|
+
export const analysisSourceFileExtensions = [
|
|
19
|
+
...typescriptAnalysisSourceFileExtensions,
|
|
20
|
+
...javascriptAnalysisSourceFileExtensions,
|
|
21
|
+
] as const;
|
|
22
|
+
|
|
23
|
+
const sourceFileExtensions = new Set<string>(analysisSourceFileExtensions);
|
|
24
|
+
const javascriptSourceFileExtensions = new Set<string>(
|
|
25
|
+
javascriptAnalysisSourceFileExtensions,
|
|
26
|
+
);
|
|
27
|
+
const declarationFilePattern = /\.d\.(?:ts|mts|cts)$/;
|
|
28
|
+
|
|
29
|
+
/** Whether an extension belongs to the JavaScript/TypeScript source family. */
|
|
30
|
+
export function isAnalysisSourceFileExtension(extension: string): boolean {
|
|
31
|
+
return sourceFileExtensions.has(extension);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Whether a project file can participate in Beignet source analysis. */
|
|
35
|
+
export function isAnalysisSourceFile(file: string): boolean {
|
|
36
|
+
return (
|
|
37
|
+
isAnalysisSourceFileExtension(path.posix.extname(file)) &&
|
|
38
|
+
!declarationFilePattern.test(file)
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Remove a JavaScript or TypeScript source extension from a path. */
|
|
43
|
+
export function stripSourceFileExtension(file: string): string {
|
|
44
|
+
const extension = path.posix.extname(file);
|
|
45
|
+
return isAnalysisSourceFileExtension(extension)
|
|
46
|
+
? file.slice(0, -extension.length)
|
|
47
|
+
: file;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Whether a source file uses JavaScript rather than TypeScript syntax. */
|
|
51
|
+
export function isJavaScriptSourceFile(file: string): boolean {
|
|
52
|
+
return javascriptSourceFileExtensions.has(path.posix.extname(file));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Select the TypeScript parser mode for a JavaScript or TypeScript file. */
|
|
56
|
+
export function sourceFileScriptKind(file: string): ts.ScriptKind {
|
|
57
|
+
if (file.endsWith(".tsx")) return ts.ScriptKind.TSX;
|
|
58
|
+
if (file.endsWith(".jsx")) return ts.ScriptKind.JSX;
|
|
59
|
+
if (isJavaScriptSourceFile(file)) return ts.ScriptKind.JS;
|
|
60
|
+
return ts.ScriptKind.TS;
|
|
61
|
+
}
|
|
@@ -53,6 +53,12 @@ export type SourceIndex = {
|
|
|
53
53
|
resolveExpression(
|
|
54
54
|
file: string,
|
|
55
55
|
expression: ts.Expression,
|
|
56
|
+
locals?: ReadonlyMap<string, ts.Declaration>,
|
|
57
|
+
): Promise<ResolvedSourceReference | undefined>;
|
|
58
|
+
resolveValue(
|
|
59
|
+
file: string,
|
|
60
|
+
expression: ts.Expression,
|
|
61
|
+
locals?: ReadonlyMap<string, ts.Declaration>,
|
|
56
62
|
): Promise<ResolvedSourceReference | undefined>;
|
|
57
63
|
resolveExport(
|
|
58
64
|
file: string,
|
|
@@ -131,7 +137,6 @@ export function createSourceIndex(workspace: AnalysisWorkspace): SourceIndex {
|
|
|
131
137
|
ts.isNamedExports(statement.exportClause)
|
|
132
138
|
) {
|
|
133
139
|
for (const element of statement.exportClause.elements) {
|
|
134
|
-
if (statement.isTypeOnly || element.isTypeOnly) continue;
|
|
135
140
|
index.localExports.set(
|
|
136
141
|
element.name.text,
|
|
137
142
|
element.propertyName?.text ?? element.name.text,
|
|
@@ -208,6 +213,9 @@ export function createSourceIndex(workspace: AnalysisWorkspace): SourceIndex {
|
|
|
208
213
|
if (localDeclaration) {
|
|
209
214
|
return { file, exportName, declaration: localDeclaration };
|
|
210
215
|
}
|
|
216
|
+
const imported = localName ? index.imports.get(localName) : undefined;
|
|
217
|
+
if (imported?.kind === "named")
|
|
218
|
+
return resolveExport(imported.file, imported.exportName, visited);
|
|
211
219
|
|
|
212
220
|
const reexport = index.reexports.get(exportName);
|
|
213
221
|
if (reexport) {
|
|
@@ -227,7 +235,7 @@ export function createSourceIndex(workspace: AnalysisWorkspace): SourceIndex {
|
|
|
227
235
|
return undefined;
|
|
228
236
|
};
|
|
229
237
|
|
|
230
|
-
|
|
238
|
+
const sourceIndex: SourceIndex = {
|
|
231
239
|
async resolveName(file, name) {
|
|
232
240
|
const index = await readIndex(file);
|
|
233
241
|
const local = index.locals.get(name);
|
|
@@ -244,11 +252,12 @@ export function createSourceIndex(workspace: AnalysisWorkspace): SourceIndex {
|
|
|
244
252
|
}
|
|
245
253
|
);
|
|
246
254
|
},
|
|
247
|
-
async resolveExpression(file, rawExpression) {
|
|
255
|
+
async resolveExpression(file, rawExpression, locals) {
|
|
248
256
|
const expression = unwrapExpression(rawExpression);
|
|
249
257
|
const index = await readIndex(file);
|
|
250
258
|
if (ts.isIdentifier(expression)) {
|
|
251
|
-
const local =
|
|
259
|
+
const local =
|
|
260
|
+
locals?.get(expression.text) ?? index.locals.get(expression.text);
|
|
252
261
|
if (local) {
|
|
253
262
|
return { file, exportName: expression.text, declaration: local };
|
|
254
263
|
}
|
|
@@ -267,6 +276,11 @@ export function createSourceIndex(workspace: AnalysisWorkspace): SourceIndex {
|
|
|
267
276
|
ts.isPropertyAccessExpression(expression) &&
|
|
268
277
|
ts.isIdentifier(expression.expression)
|
|
269
278
|
) {
|
|
279
|
+
if (
|
|
280
|
+
locals?.has(expression.expression.text) ||
|
|
281
|
+
index.locals.has(expression.expression.text)
|
|
282
|
+
)
|
|
283
|
+
return undefined;
|
|
270
284
|
const binding = index.imports.get(expression.expression.text);
|
|
271
285
|
if (binding?.kind !== "namespace") return undefined;
|
|
272
286
|
return (
|
|
@@ -279,6 +293,43 @@ export function createSourceIndex(workspace: AnalysisWorkspace): SourceIndex {
|
|
|
279
293
|
|
|
280
294
|
return undefined;
|
|
281
295
|
},
|
|
296
|
+
async resolveValue(file, expression, locals) {
|
|
297
|
+
const visited = new Set<ts.Declaration>();
|
|
298
|
+
async function follow(
|
|
299
|
+
file: string,
|
|
300
|
+
rawExpression: ts.Expression,
|
|
301
|
+
locals?: ReadonlyMap<string, ts.Declaration>,
|
|
302
|
+
): Promise<ResolvedSourceReference | undefined> {
|
|
303
|
+
const expression = unwrapExpression(rawExpression);
|
|
304
|
+
const reference = await sourceIndex.resolveExpression(
|
|
305
|
+
file,
|
|
306
|
+
expression,
|
|
307
|
+
locals,
|
|
308
|
+
);
|
|
309
|
+
const declaration = reference?.declaration;
|
|
310
|
+
if (!reference || !declaration || visited.has(declaration))
|
|
311
|
+
return undefined;
|
|
312
|
+
visited.add(declaration);
|
|
313
|
+
if (!ts.isVariableDeclaration(declaration) || !declaration.initializer)
|
|
314
|
+
return reference;
|
|
315
|
+
if (
|
|
316
|
+
!ts.isVariableDeclarationList(declaration.parent) ||
|
|
317
|
+
!(declaration.parent.flags & ts.NodeFlags.Const)
|
|
318
|
+
)
|
|
319
|
+
return undefined;
|
|
320
|
+
const initializer = unwrapExpression(declaration.initializer);
|
|
321
|
+
if (
|
|
322
|
+
!ts.isIdentifier(initializer) &&
|
|
323
|
+
!ts.isPropertyAccessExpression(initializer)
|
|
324
|
+
)
|
|
325
|
+
return reference;
|
|
326
|
+
const local =
|
|
327
|
+
ts.isIdentifier(expression) &&
|
|
328
|
+
locals?.get(expression.text) === declaration;
|
|
329
|
+
return follow(reference.file, initializer, local ? locals : undefined);
|
|
330
|
+
}
|
|
331
|
+
return follow(file, expression, locals);
|
|
332
|
+
},
|
|
282
333
|
resolveExport(file, exportName) {
|
|
283
334
|
return resolveExport(file, exportName);
|
|
284
335
|
},
|
|
@@ -295,6 +346,7 @@ export function createSourceIndex(workspace: AnalysisWorkspace): SourceIndex {
|
|
|
295
346
|
};
|
|
296
347
|
},
|
|
297
348
|
};
|
|
349
|
+
return sourceIndex;
|
|
298
350
|
}
|
|
299
351
|
|
|
300
352
|
export function exportedVariableDeclarations(
|