Skip to content

Commit 8b1cf07

Browse files
author
Andy Hanson
committed
Refactor findAllReferences. Now supports renamed exports and imports.
1 parent 7cd0e1a commit 8b1cf07

File tree

131 files changed

+2221
-1012
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

131 files changed

+2221
-1012
lines changed

Gulpfile.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ const cmdLineOptions = minimist(process.argv.slice(2), {
4444
boolean: ["debug", "light", "colors", "lint", "soft"],
4545
string: ["browser", "tests", "host", "reporter", "stackTraceLimit"],
4646
alias: {
47+
b: "browser",
4748
d: "debug",
4849
t: "tests",
4950
test: "tests",

src/compiler/checker.ts

Lines changed: 53 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ namespace ts {
7272
isUndefinedSymbol: symbol => symbol === undefinedSymbol,
7373
isArgumentsSymbol: symbol => symbol === argumentsSymbol,
7474
isUnknownSymbol: symbol => symbol === unknownSymbol,
75+
getMergedSymbol,
7576
getDiagnostics,
7677
getGlobalDiagnostics,
7778
getTypeOfSymbolAtLocation,
@@ -106,6 +107,7 @@ namespace ts {
106107
isValidPropertyAccess,
107108
getSignatureFromDeclaration,
108109
isImplementationOfOverload,
110+
getImmediateAliasedSymbol,
109111
getAliasedSymbol: resolveAlias,
110112
getEmitResolver,
111113
getExportsOfModule: getExportsOfModuleAsArray,
@@ -1146,14 +1148,14 @@ namespace ts {
11461148
return find<Declaration>(symbol.declarations, isAliasSymbolDeclaration);
11471149
}
11481150

1149-
function getTargetOfImportEqualsDeclaration(node: ImportEqualsDeclaration): Symbol {
1151+
function getTargetOfImportEqualsDeclaration(node: ImportEqualsDeclaration, dontResolveAlias: boolean): Symbol {
11501152
if (node.moduleReference.kind === SyntaxKind.ExternalModuleReference) {
11511153
return resolveExternalModuleSymbol(resolveExternalModuleName(node, getExternalModuleImportEqualsDeclarationExpression(node)));
11521154
}
1153-
return getSymbolOfPartOfRightHandSideOfImportEquals(<EntityName>node.moduleReference);
1155+
return getSymbolOfPartOfRightHandSideOfImportEquals(<EntityName>node.moduleReference, dontResolveAlias);
11541156
}
11551157

1156-
function getTargetOfImportClause(node: ImportClause): Symbol {
1158+
function getTargetOfImportClause(node: ImportClause, dontResolveAlias: boolean): Symbol {
11571159
const moduleSymbol = resolveExternalModuleName(node, (<ImportDeclaration>node.parent).moduleSpecifier);
11581160

11591161
if (moduleSymbol) {
@@ -1165,22 +1167,22 @@ namespace ts {
11651167
const exportValue = moduleSymbol.exports.get("export=");
11661168
exportDefaultSymbol = exportValue
11671169
? getPropertyOfType(getTypeOfSymbol(exportValue), "default")
1168-
: resolveSymbol(moduleSymbol.exports.get("default"));
1170+
: resolveSymbol(moduleSymbol.exports.get("default"), dontResolveAlias);
11691171
}
11701172

11711173
if (!exportDefaultSymbol && !allowSyntheticDefaultImports) {
11721174
error(node.name, Diagnostics.Module_0_has_no_default_export, symbolToString(moduleSymbol));
11731175
}
11741176
else if (!exportDefaultSymbol && allowSyntheticDefaultImports) {
1175-
return resolveExternalModuleSymbol(moduleSymbol) || resolveSymbol(moduleSymbol);
1177+
return resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
11761178
}
11771179
return exportDefaultSymbol;
11781180
}
11791181
}
11801182

1181-
function getTargetOfNamespaceImport(node: NamespaceImport): Symbol {
1183+
function getTargetOfNamespaceImport(node: NamespaceImport, dontResolveAlias: boolean): Symbol {
11821184
const moduleSpecifier = (<ImportDeclaration>node.parent.parent).moduleSpecifier;
1183-
return resolveESModuleSymbol(resolveExternalModuleName(node, moduleSpecifier), moduleSpecifier);
1185+
return resolveESModuleSymbol(resolveExternalModuleName(node, moduleSpecifier), moduleSpecifier, dontResolveAlias);
11841186
}
11851187

11861188
// This function creates a synthetic symbol that combines the value side of one symbol with the
@@ -1214,12 +1216,9 @@ namespace ts {
12141216
return result;
12151217
}
12161218

1217-
function getExportOfModule(symbol: Symbol, name: string): Symbol {
1219+
function getExportOfModule(symbol: Symbol, name: string, dontResolveAlias: boolean): Symbol {
12181220
if (symbol.flags & SymbolFlags.Module) {
1219-
const exportedSymbol = getExportsOfSymbol(symbol).get(name);
1220-
if (exportedSymbol) {
1221-
return resolveSymbol(exportedSymbol);
1222-
}
1221+
return resolveSymbol(getExportsOfSymbol(symbol).get(name), dontResolveAlias);
12231222
}
12241223
}
12251224

@@ -1232,9 +1231,9 @@ namespace ts {
12321231
}
12331232
}
12341233

1235-
function getExternalModuleMember(node: ImportDeclaration | ExportDeclaration, specifier: ImportOrExportSpecifier): Symbol {
1234+
function getExternalModuleMember(node: ImportDeclaration | ExportDeclaration, specifier: ImportOrExportSpecifier, dontResolveAlias?: boolean): Symbol {
12361235
const moduleSymbol = resolveExternalModuleName(node, node.moduleSpecifier);
1237-
const targetSymbol = resolveESModuleSymbol(moduleSymbol, node.moduleSpecifier);
1236+
const targetSymbol = resolveESModuleSymbol(moduleSymbol, node.moduleSpecifier, dontResolveAlias);
12381237
if (targetSymbol) {
12391238
const name = specifier.propertyName || specifier.name;
12401239
if (name.text) {
@@ -1251,11 +1250,11 @@ namespace ts {
12511250
symbolFromVariable = getPropertyOfVariable(targetSymbol, name.text);
12521251
}
12531252
// if symbolFromVariable is export - get its final target
1254-
symbolFromVariable = resolveSymbol(symbolFromVariable);
1255-
let symbolFromModule = getExportOfModule(targetSymbol, name.text);
1253+
symbolFromVariable = resolveSymbol(symbolFromVariable, dontResolveAlias);
1254+
let symbolFromModule = getExportOfModule(targetSymbol, name.text, dontResolveAlias);
12561255
// If the export member we're looking for is default, and there is no real default but allowSyntheticDefaultImports is on, return the entire module as the default
12571256
if (!symbolFromModule && allowSyntheticDefaultImports && name.text === "default") {
1258-
symbolFromModule = resolveExternalModuleSymbol(moduleSymbol) || resolveSymbol(moduleSymbol);
1257+
symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
12591258
}
12601259
const symbol = symbolFromModule && symbolFromVariable ?
12611260
combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) :
@@ -1268,45 +1267,58 @@ namespace ts {
12681267
}
12691268
}
12701269

1271-
function getTargetOfImportSpecifier(node: ImportSpecifier): Symbol {
1272-
return getExternalModuleMember(<ImportDeclaration>node.parent.parent.parent, node);
1270+
function getTargetOfImportSpecifier(node: ImportSpecifier, dontResolveAlias: boolean): Symbol {
1271+
return getExternalModuleMember(<ImportDeclaration>node.parent.parent.parent, node, dontResolveAlias);
12731272
}
12741273

1275-
function getTargetOfNamespaceExportDeclaration(node: NamespaceExportDeclaration): Symbol {
1276-
return resolveExternalModuleSymbol(node.parent.symbol);
1274+
function getTargetOfNamespaceExportDeclaration(node: NamespaceExportDeclaration, dontResolveAlias: boolean): Symbol {
1275+
return resolveExternalModuleSymbol(node.parent.symbol, dontResolveAlias);
12771276
}
12781277

1279-
function getTargetOfExportSpecifier(node: ExportSpecifier): Symbol {
1278+
function getTargetOfExportSpecifier(node: ExportSpecifier, dontResolveAlias?: boolean): Symbol {
12801279
return (<ExportDeclaration>node.parent.parent).moduleSpecifier ?
1281-
getExternalModuleMember(<ExportDeclaration>node.parent.parent, node) :
1282-
resolveEntityName(node.propertyName || node.name, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace);
1280+
getExternalModuleMember(<ExportDeclaration>node.parent.parent, node, dontResolveAlias) :
1281+
resolveEntityName(node.propertyName || node.name, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace, /*ignoreErrors*/false, dontResolveAlias);
12831282
}
12841283

1285-
function getTargetOfExportAssignment(node: ExportAssignment): Symbol {
1286-
return resolveEntityName(<EntityNameExpression>node.expression, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace);
1284+
function getTargetOfExportAssignment(node: ExportAssignment, dontResolveAlias: boolean): Symbol {
1285+
return resolveEntityName(<EntityNameExpression>node.expression, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace, /*ignoreErrors*/false, dontResolveAlias);
12871286
}
12881287

1289-
function getTargetOfAliasDeclaration(node: Declaration): Symbol {
1288+
function getTargetOfAliasDeclaration(node: Declaration, dontRecursivelyResolve?: boolean): Symbol {
12901289
switch (node.kind) {
12911290
case SyntaxKind.ImportEqualsDeclaration:
1292-
return getTargetOfImportEqualsDeclaration(<ImportEqualsDeclaration>node);
1291+
return getTargetOfImportEqualsDeclaration(<ImportEqualsDeclaration>node, dontRecursivelyResolve);
12931292
case SyntaxKind.ImportClause:
1294-
return getTargetOfImportClause(<ImportClause>node);
1293+
return getTargetOfImportClause(<ImportClause>node, dontRecursivelyResolve);
12951294
case SyntaxKind.NamespaceImport:
1296-
return getTargetOfNamespaceImport(<NamespaceImport>node);
1295+
return getTargetOfNamespaceImport(<NamespaceImport>node, dontRecursivelyResolve);
12971296
case SyntaxKind.ImportSpecifier:
1298-
return getTargetOfImportSpecifier(<ImportSpecifier>node);
1297+
return getTargetOfImportSpecifier(<ImportSpecifier>node, dontRecursivelyResolve);
12991298
case SyntaxKind.ExportSpecifier:
1300-
return getTargetOfExportSpecifier(<ExportSpecifier>node);
1299+
return getTargetOfExportSpecifier(<ExportSpecifier>node, dontRecursivelyResolve);
13011300
case SyntaxKind.ExportAssignment:
1302-
return getTargetOfExportAssignment(<ExportAssignment>node);
1301+
return getTargetOfExportAssignment(<ExportAssignment>node, dontRecursivelyResolve);
13031302
case SyntaxKind.NamespaceExportDeclaration:
1304-
return getTargetOfNamespaceExportDeclaration(<NamespaceExportDeclaration>node);
1303+
return getTargetOfNamespaceExportDeclaration(<NamespaceExportDeclaration>node, dontRecursivelyResolve);
13051304
}
13061305
}
13071306

1308-
function resolveSymbol(symbol: Symbol): Symbol {
1309-
return symbol && symbol.flags & SymbolFlags.Alias && !(symbol.flags & (SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace)) ? resolveAlias(symbol) : symbol;
1307+
function resolveSymbol(symbol: Symbol, dontResolveAlias?: boolean): Symbol {
1308+
const shouldResolve = !dontResolveAlias && symbol && symbol.flags & SymbolFlags.Alias && !(symbol.flags & (SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace));
1309+
return shouldResolve ? resolveAlias(symbol) : symbol;
1310+
}
1311+
1312+
function getImmediateAliasedSymbol(symbol: Symbol): Symbol {
1313+
Debug.assert((symbol.flags & SymbolFlags.Alias) !== 0, "Should only get Alias here.");
1314+
const links = getSymbolLinks(symbol);
1315+
if (!links.immediateTarget) {
1316+
const node = getDeclarationOfAliasSymbol(symbol);
1317+
Debug.assert(!!node);
1318+
links.immediateTarget = getTargetOfAliasDeclaration(node, /*dontRecursivelyResolve*/true);
1319+
}
1320+
1321+
return links.immediateTarget;
13101322
}
13111323

13121324
function resolveAlias(symbol: Symbol): Symbol {
@@ -1523,16 +1535,16 @@ namespace ts {
15231535

15241536
// An external module with an 'export =' declaration resolves to the target of the 'export =' declaration,
15251537
// and an external module with no 'export =' declaration resolves to the module itself.
1526-
function resolveExternalModuleSymbol(moduleSymbol: Symbol): Symbol {
1527-
return moduleSymbol && getMergedSymbol(resolveSymbol(moduleSymbol.exports.get("export="))) || moduleSymbol;
1538+
function resolveExternalModuleSymbol(moduleSymbol: Symbol, dontResolveAlias?: boolean): Symbol {
1539+
return moduleSymbol && getMergedSymbol(resolveSymbol(moduleSymbol.exports.get("export="), dontResolveAlias)) || moduleSymbol;
15281540
}
15291541

15301542
// An external module with an 'export =' declaration may be referenced as an ES6 module provided the 'export ='
15311543
// references a symbol that is at least declared as a module or a variable. The target of the 'export =' may
15321544
// combine other declarations with the module or variable (e.g. a class/module, function/module, interface/variable).
1533-
function resolveESModuleSymbol(moduleSymbol: Symbol, moduleReferenceExpression: Expression): Symbol {
1534-
let symbol = resolveExternalModuleSymbol(moduleSymbol);
1535-
if (symbol && !(symbol.flags & (SymbolFlags.Module | SymbolFlags.Variable))) {
1545+
function resolveESModuleSymbol(moduleSymbol: Symbol, moduleReferenceExpression: Expression, dontResolveAlias: boolean): Symbol {
1546+
let symbol = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias);
1547+
if (!dontResolveAlias && symbol && !(symbol.flags & (SymbolFlags.Module | SymbolFlags.Variable))) {
15361548
error(moduleReferenceExpression, Diagnostics.Module_0_resolves_to_a_non_module_entity_and_cannot_be_imported_using_this_construct, symbolToString(moduleSymbol));
15371549
symbol = undefined;
15381550
}

src/compiler/core.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -887,10 +887,12 @@ namespace ts {
887887
}
888888

889889
/** Shims `Array.from`. */
890-
export function arrayFrom<T>(iterator: Iterator<T>): T[] {
891-
const result: T[] = [];
890+
export function arrayFrom<T, U>(iterator: Iterator<T>, map: (t: T) => U): U[];
891+
export function arrayFrom<T>(iterator: Iterator<T>): T[];
892+
export function arrayFrom(iterator: Iterator<any>, map?: (t: any) => any): any[] {
893+
const result: any[] = [];
892894
for (let { value, done } = iterator.next(); !done; { value, done } = iterator.next()) {
893-
result.push(value);
895+
result.push(map ? map(value) : value);
894896
}
895897
return result;
896898
}

src/compiler/parser.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,7 @@ namespace ts {
454454
return Parser.parseIsolatedEntityName(text, languageVersion);
455455
}
456456

457+
// See also `isExternalOrCommonJsModule` in utilities.ts
457458
export function isExternalModule(file: SourceFile): boolean {
458459
return file.externalModuleIndicator !== undefined;
459460
}

src/compiler/types.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1812,6 +1812,7 @@
18121812
}
18131813

18141814
export interface ExternalModuleReference extends Node {
1815+
parent: ImportEqualsDeclaration;
18151816
kind: SyntaxKind.ExternalModuleReference;
18161817
expression?: Expression;
18171818
}
@@ -1823,6 +1824,7 @@
18231824
export interface ImportDeclaration extends Statement {
18241825
kind: SyntaxKind.ImportDeclaration;
18251826
importClause?: ImportClause;
1827+
/** If this is not a StringLiteral it will be a grammar error. */
18261828
moduleSpecifier: Expression;
18271829
}
18281830

@@ -1854,6 +1856,7 @@
18541856
export interface ExportDeclaration extends DeclarationStatement {
18551857
kind: SyntaxKind.ExportDeclaration;
18561858
exportClause?: NamedExports;
1859+
/** If this is not a StringLiteral it will be a grammar error. */
18571860
moduleSpecifier?: Expression;
18581861
}
18591862

@@ -1863,6 +1866,7 @@
18631866
}
18641867

18651868
export interface NamedExports extends Node {
1869+
parent: ExportDeclaration;
18661870
kind: SyntaxKind.NamedExports;
18671871
elements: NodeArray<ExportSpecifier>;
18681872
}
@@ -1876,6 +1880,7 @@
18761880
}
18771881

18781882
export interface ExportSpecifier extends Declaration {
1883+
parent: NamedExports;
18791884
kind: SyntaxKind.ExportSpecifier;
18801885
propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent)
18811886
name: Identifier; // Declared name
@@ -2198,8 +2203,8 @@
21982203
// Content of this field should never be used directly - use getResolvedModuleFileName/setResolvedModuleFileName functions instead
21992204
/* @internal */ resolvedModules: Map<ResolvedModuleFull>;
22002205
/* @internal */ resolvedTypeReferenceDirectiveNames: Map<ResolvedTypeReferenceDirective>;
2201-
/* @internal */ imports: LiteralExpression[];
2202-
/* @internal */ moduleAugmentations: LiteralExpression[];
2206+
/* @internal */ imports: StringLiteral[];
2207+
/* @internal */ moduleAugmentations: StringLiteral[];
22032208
/* @internal */ patternAmbientModules?: PatternAmbientModule[];
22042209
/* @internal */ ambientModuleNames: string[];
22052210
}
@@ -2397,10 +2402,14 @@
23972402
isUndefinedSymbol(symbol: Symbol): boolean;
23982403
isArgumentsSymbol(symbol: Symbol): boolean;
23992404
isUnknownSymbol(symbol: Symbol): boolean;
2405+
/* @internal */ getMergedSymbol(symbol: Symbol): Symbol;
24002406

24012407
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number;
24022408
isValidPropertyAccess(node: PropertyAccessExpression | QualifiedName, propertyName: string): boolean;
2409+
/** Follow all aliases to get the original symbol. */
24032410
getAliasedSymbol(symbol: Symbol): Symbol;
2411+
/** Follow a *single* alias to get the immediately aliased symbol. */
2412+
/* @internal */ getImmediateAliasedSymbol(symbol: Symbol): Symbol;
24042413
getExportsOfModule(moduleSymbol: Symbol): Symbol[];
24052414
/** Unlike `getExportsOfModule`, this includes properties of an `export =` value. */
24062415
/* @internal */ getExportsAndPropertiesOfModule(moduleSymbol: Symbol): Symbol[];
@@ -2704,6 +2713,7 @@
27042713

27052714
/* @internal */
27062715
export interface SymbolLinks {
2716+
immediateTarget?: Symbol; // Immediate target of an alias. May be another alias. Do not access directly, use `checker.getImmediateAliasedSymbol` instead.
27072717
target?: Symbol; // Resolved (non-alias) target of an alias
27082718
type?: Type; // Type of value symbol
27092719
declaredType?: Type; // Type of class, interface, enum, type alias, or type parameter

src/compiler/utilities.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3088,7 +3088,7 @@ namespace ts {
30883088
return isExportDefaultSymbol(symbol) ? symbol.valueDeclaration.localSymbol : undefined;
30893089
}
30903090

3091-
export function isExportDefaultSymbol(symbol: Symbol): boolean {
3091+
function isExportDefaultSymbol(symbol: Symbol): boolean {
30923092
return symbol && symbol.valueDeclaration && hasModifier(symbol.valueDeclaration, ModifierFlags.Default);
30933093
}
30943094

0 commit comments

Comments
 (0)