Skip to content

Commit 3b04406

Browse files
committed
Add language service API to get the compile and runtime dependencies of a source file
1 parent fe46122 commit 3b04406

File tree

1 file changed

+71
-3
lines changed

1 file changed

+71
-3
lines changed

src/services/services.ts

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,9 +1027,11 @@ namespace ts {
10271027
getFormattingEditsForRange(fileName: string, start: number, end: number, options: FormatCodeOptions): TextChange[];
10281028
getFormattingEditsForDocument(fileName: string, options: FormatCodeOptions): TextChange[];
10291029
getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: FormatCodeOptions): TextChange[];
1030+
1031+
getDependencies(fileName: string): DependencyInfo;
10301032

10311033
getEmitOutput(fileName: string): EmitOutput;
1032-
1034+
10331035
getProgram(): Program;
10341036

10351037
getSourceFile(fileName: string): SourceFile;
@@ -1267,11 +1269,20 @@ namespace ts {
12671269
autoCollapse: boolean;
12681270
}
12691271

1272+
export interface DependencyInfo {
1273+
/** The file name of the dependency information */
1274+
fileName: string;
1275+
/** The compile time dependencies of a file */
1276+
compileTime: string[];
1277+
/** The runtime dependencies of a file */
1278+
runtime: string[];
1279+
}
1280+
12701281
export interface EmitOutput {
12711282
outputFiles: OutputFile[];
12721283
emitSkipped: boolean;
12731284
}
1274-
1285+
12751286
export const enum OutputFileType {
12761287
JavaScript,
12771288
SourceMap,
@@ -5762,6 +5773,62 @@ namespace ts {
57625773
return forEach(diagnostics, diagnostic => diagnostic.category === DiagnosticCategory.Error);
57635774
}
57645775

5776+
function getDependencies(fileName: string): DependencyInfo {
5777+
synchronizeHostData();
5778+
5779+
let sourceFile = getValidSourceFile(fileName);
5780+
if (!sourceFile) {
5781+
return undefined;
5782+
}
5783+
5784+
let resolver = program.getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile);
5785+
5786+
let runtime: string[] = [];
5787+
let compileTime: string[] = [];
5788+
for (let node of sourceFile.amdDependencies) {
5789+
runtime.push(node.path);
5790+
}
5791+
5792+
function getModuleNameText(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration): string {
5793+
let moduleName = getExternalModuleName(node);
5794+
return (<LiteralExpression>moduleName).text;
5795+
}
5796+
5797+
for (let node of sourceFile.statements) {
5798+
switch (node.kind) {
5799+
case SyntaxKind.ImportDeclaration:
5800+
let importDeclaration = <ImportDeclaration>node;
5801+
if (!importDeclaration.importClause || resolver.isReferencedAliasDeclaration(importDeclaration.importClause, /*checkChildren*/ true)) {
5802+
runtime.push(getModuleNameText(importDeclaration));
5803+
} else {
5804+
compileTime.push(getModuleNameText(importDeclaration));
5805+
}
5806+
break;
5807+
case SyntaxKind.ImportEqualsDeclaration:
5808+
let importEqualsDeclaration = <ImportEqualsDeclaration>node;
5809+
if (importEqualsDeclaration.moduleReference.kind === SyntaxKind.ExternalModuleReference && resolver.isReferencedAliasDeclaration(importEqualsDeclaration)) {
5810+
runtime.push(getModuleNameText(importEqualsDeclaration));
5811+
} else {
5812+
compileTime.push(getModuleNameText(importEqualsDeclaration));
5813+
}
5814+
break;
5815+
case SyntaxKind.ExportDeclaration:
5816+
let exportDeclaration = <ExportDeclaration>node;
5817+
if (exportDeclaration.moduleSpecifier && (!exportDeclaration.exportClause || resolver.isValueAliasDeclaration(exportDeclaration))) {
5818+
// export * as mod from 'mod' && export {x , y } from 'mod'
5819+
runtime.push(getModuleNameText(exportDeclaration));
5820+
}
5821+
// export { x, y } does neither generate a runtime nor a compile time dependency
5822+
break;
5823+
}
5824+
}
5825+
return {
5826+
fileName: sourceFile.fileName,
5827+
compileTime: compileTime,
5828+
runtime: runtime
5829+
}
5830+
}
5831+
57655832
function getEmitOutput(fileName: string): EmitOutput {
57665833
synchronizeHostData();
57675834

@@ -5783,7 +5850,7 @@ namespace ts {
57835850
emitSkipped: emitOutput.emitSkipped
57845851
};
57855852
}
5786-
5853+
57875854
function getMeaningFromDeclaration(node: Node): SemanticMeaning {
57885855
switch (node.kind) {
57895856
case SyntaxKind.Parameter:
@@ -6810,6 +6877,7 @@ namespace ts {
68106877
getFormattingEditsForRange,
68116878
getFormattingEditsForDocument,
68126879
getFormattingEditsAfterKeystroke,
6880+
getDependencies,
68136881
getEmitOutput,
68146882
getSourceFile,
68156883
getProgram

0 commit comments

Comments
 (0)