Skip to content

Commit 42a832a

Browse files
author
Andy Hanson
committed
Refactor findAllReferences. Now supports renamed exports and imports.
1 parent 593ee68 commit 42a832a

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,
@@ -1161,14 +1163,14 @@ namespace ts {
11611163
return find<Declaration>(symbol.declarations, isAliasSymbolDeclaration);
11621164
}
11631165

1164-
function getTargetOfImportEqualsDeclaration(node: ImportEqualsDeclaration): Symbol {
1166+
function getTargetOfImportEqualsDeclaration(node: ImportEqualsDeclaration, dontResolveAlias: boolean): Symbol {
11651167
if (node.moduleReference.kind === SyntaxKind.ExternalModuleReference) {
11661168
return resolveExternalModuleSymbol(resolveExternalModuleName(node, getExternalModuleImportEqualsDeclarationExpression(node)));
11671169
}
1168-
return getSymbolOfPartOfRightHandSideOfImportEquals(<EntityName>node.moduleReference);
1170+
return getSymbolOfPartOfRightHandSideOfImportEquals(<EntityName>node.moduleReference, dontResolveAlias);
11691171
}
11701172

1171-
function getTargetOfImportClause(node: ImportClause): Symbol {
1173+
function getTargetOfImportClause(node: ImportClause, dontResolveAlias: boolean): Symbol {
11721174
const moduleSymbol = resolveExternalModuleName(node, (<ImportDeclaration>node.parent).moduleSpecifier);
11731175

11741176
if (moduleSymbol) {
@@ -1180,22 +1182,22 @@ namespace ts {
11801182
const exportValue = moduleSymbol.exports.get("export=");
11811183
exportDefaultSymbol = exportValue
11821184
? getPropertyOfType(getTypeOfSymbol(exportValue), "default")
1183-
: resolveSymbol(moduleSymbol.exports.get("default"));
1185+
: resolveSymbol(moduleSymbol.exports.get("default"), dontResolveAlias);
11841186
}
11851187

11861188
if (!exportDefaultSymbol && !allowSyntheticDefaultImports) {
11871189
error(node.name, Diagnostics.Module_0_has_no_default_export, symbolToString(moduleSymbol));
11881190
}
11891191
else if (!exportDefaultSymbol && allowSyntheticDefaultImports) {
1190-
return resolveExternalModuleSymbol(moduleSymbol) || resolveSymbol(moduleSymbol);
1192+
return resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
11911193
}
11921194
return exportDefaultSymbol;
11931195
}
11941196
}
11951197

1196-
function getTargetOfNamespaceImport(node: NamespaceImport): Symbol {
1198+
function getTargetOfNamespaceImport(node: NamespaceImport, dontResolveAlias: boolean): Symbol {
11971199
const moduleSpecifier = (<ImportDeclaration>node.parent.parent).moduleSpecifier;
1198-
return resolveESModuleSymbol(resolveExternalModuleName(node, moduleSpecifier), moduleSpecifier);
1200+
return resolveESModuleSymbol(resolveExternalModuleName(node, moduleSpecifier), moduleSpecifier, dontResolveAlias);
11991201
}
12001202

12011203
// This function creates a synthetic symbol that combines the value side of one symbol with the
@@ -1229,12 +1231,9 @@ namespace ts {
12291231
return result;
12301232
}
12311233

1232-
function getExportOfModule(symbol: Symbol, name: string): Symbol {
1234+
function getExportOfModule(symbol: Symbol, name: string, dontResolveAlias: boolean): Symbol {
12331235
if (symbol.flags & SymbolFlags.Module) {
1234-
const exportedSymbol = getExportsOfSymbol(symbol).get(name);
1235-
if (exportedSymbol) {
1236-
return resolveSymbol(exportedSymbol);
1237-
}
1236+
return resolveSymbol(getExportsOfSymbol(symbol).get(name), dontResolveAlias);
12381237
}
12391238
}
12401239

@@ -1247,9 +1246,9 @@ namespace ts {
12471246
}
12481247
}
12491248

1250-
function getExternalModuleMember(node: ImportDeclaration | ExportDeclaration, specifier: ImportOrExportSpecifier): Symbol {
1249+
function getExternalModuleMember(node: ImportDeclaration | ExportDeclaration, specifier: ImportOrExportSpecifier, dontResolveAlias?: boolean): Symbol {
12511250
const moduleSymbol = resolveExternalModuleName(node, node.moduleSpecifier);
1252-
const targetSymbol = resolveESModuleSymbol(moduleSymbol, node.moduleSpecifier);
1251+
const targetSymbol = resolveESModuleSymbol(moduleSymbol, node.moduleSpecifier, dontResolveAlias);
12531252
if (targetSymbol) {
12541253
const name = specifier.propertyName || specifier.name;
12551254
if (name.text) {
@@ -1266,11 +1265,11 @@ namespace ts {
12661265
symbolFromVariable = getPropertyOfVariable(targetSymbol, name.text);
12671266
}
12681267
// if symbolFromVariable is export - get its final target
1269-
symbolFromVariable = resolveSymbol(symbolFromVariable);
1270-
let symbolFromModule = getExportOfModule(targetSymbol, name.text);
1268+
symbolFromVariable = resolveSymbol(symbolFromVariable, dontResolveAlias);
1269+
let symbolFromModule = getExportOfModule(targetSymbol, name.text, dontResolveAlias);
12711270
// 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
12721271
if (!symbolFromModule && allowSyntheticDefaultImports && name.text === "default") {
1273-
symbolFromModule = resolveExternalModuleSymbol(moduleSymbol) || resolveSymbol(moduleSymbol);
1272+
symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
12741273
}
12751274
const symbol = symbolFromModule && symbolFromVariable ?
12761275
combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) :
@@ -1283,45 +1282,58 @@ namespace ts {
12831282
}
12841283
}
12851284

1286-
function getTargetOfImportSpecifier(node: ImportSpecifier): Symbol {
1287-
return getExternalModuleMember(<ImportDeclaration>node.parent.parent.parent, node);
1285+
function getTargetOfImportSpecifier(node: ImportSpecifier, dontResolveAlias: boolean): Symbol {
1286+
return getExternalModuleMember(<ImportDeclaration>node.parent.parent.parent, node, dontResolveAlias);
12881287
}
12891288

1290-
function getTargetOfNamespaceExportDeclaration(node: NamespaceExportDeclaration): Symbol {
1291-
return resolveExternalModuleSymbol(node.parent.symbol);
1289+
function getTargetOfNamespaceExportDeclaration(node: NamespaceExportDeclaration, dontResolveAlias: boolean): Symbol {
1290+
return resolveExternalModuleSymbol(node.parent.symbol, dontResolveAlias);
12921291
}
12931292

1294-
function getTargetOfExportSpecifier(node: ExportSpecifier): Symbol {
1293+
function getTargetOfExportSpecifier(node: ExportSpecifier, dontResolveAlias?: boolean): Symbol {
12951294
return (<ExportDeclaration>node.parent.parent).moduleSpecifier ?
1296-
getExternalModuleMember(<ExportDeclaration>node.parent.parent, node) :
1297-
resolveEntityName(node.propertyName || node.name, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace);
1295+
getExternalModuleMember(<ExportDeclaration>node.parent.parent, node, dontResolveAlias) :
1296+
resolveEntityName(node.propertyName || node.name, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace, /*ignoreErrors*/false, dontResolveAlias);
12981297
}
12991298

1300-
function getTargetOfExportAssignment(node: ExportAssignment): Symbol {
1301-
return resolveEntityName(<EntityNameExpression>node.expression, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace);
1299+
function getTargetOfExportAssignment(node: ExportAssignment, dontResolveAlias: boolean): Symbol {
1300+
return resolveEntityName(<EntityNameExpression>node.expression, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace, /*ignoreErrors*/false, dontResolveAlias);
13021301
}
13031302

1304-
function getTargetOfAliasDeclaration(node: Declaration): Symbol {
1303+
function getTargetOfAliasDeclaration(node: Declaration, dontRecursivelyResolve?: boolean): Symbol {
13051304
switch (node.kind) {
13061305
case SyntaxKind.ImportEqualsDeclaration:
1307-
return getTargetOfImportEqualsDeclaration(<ImportEqualsDeclaration>node);
1306+
return getTargetOfImportEqualsDeclaration(<ImportEqualsDeclaration>node, dontRecursivelyResolve);
13081307
case SyntaxKind.ImportClause:
1309-
return getTargetOfImportClause(<ImportClause>node);
1308+
return getTargetOfImportClause(<ImportClause>node, dontRecursivelyResolve);
13101309
case SyntaxKind.NamespaceImport:
1311-
return getTargetOfNamespaceImport(<NamespaceImport>node);
1310+
return getTargetOfNamespaceImport(<NamespaceImport>node, dontRecursivelyResolve);
13121311
case SyntaxKind.ImportSpecifier:
1313-
return getTargetOfImportSpecifier(<ImportSpecifier>node);
1312+
return getTargetOfImportSpecifier(<ImportSpecifier>node, dontRecursivelyResolve);
13141313
case SyntaxKind.ExportSpecifier:
1315-
return getTargetOfExportSpecifier(<ExportSpecifier>node);
1314+
return getTargetOfExportSpecifier(<ExportSpecifier>node, dontRecursivelyResolve);
13161315
case SyntaxKind.ExportAssignment:
1317-
return getTargetOfExportAssignment(<ExportAssignment>node);
1316+
return getTargetOfExportAssignment(<ExportAssignment>node, dontRecursivelyResolve);
13181317
case SyntaxKind.NamespaceExportDeclaration:
1319-
return getTargetOfNamespaceExportDeclaration(<NamespaceExportDeclaration>node);
1318+
return getTargetOfNamespaceExportDeclaration(<NamespaceExportDeclaration>node, dontRecursivelyResolve);
13201319
}
13211320
}
13221321

1323-
function resolveSymbol(symbol: Symbol): Symbol {
1324-
return symbol && symbol.flags & SymbolFlags.Alias && !(symbol.flags & (SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace)) ? resolveAlias(symbol) : symbol;
1322+
function resolveSymbol(symbol: Symbol, dontResolveAlias?: boolean): Symbol {
1323+
const shouldResolve = !dontResolveAlias && symbol && symbol.flags & SymbolFlags.Alias && !(symbol.flags & (SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace));
1324+
return shouldResolve ? resolveAlias(symbol) : symbol;
1325+
}
1326+
1327+
function getImmediateAliasedSymbol(symbol: Symbol): Symbol {
1328+
Debug.assert((symbol.flags & SymbolFlags.Alias) !== 0, "Should only get Alias here.");
1329+
const links = getSymbolLinks(symbol);
1330+
if (!links.immediateTarget) {
1331+
const node = getDeclarationOfAliasSymbol(symbol);
1332+
Debug.assert(!!node);
1333+
links.immediateTarget = getTargetOfAliasDeclaration(node, /*dontRecursivelyResolve*/true);
1334+
}
1335+
1336+
return links.immediateTarget;
13251337
}
13261338

13271339
function resolveAlias(symbol: Symbol): Symbol {
@@ -1538,16 +1550,16 @@ namespace ts {
15381550

15391551
// An external module with an 'export =' declaration resolves to the target of the 'export =' declaration,
15401552
// and an external module with no 'export =' declaration resolves to the module itself.
1541-
function resolveExternalModuleSymbol(moduleSymbol: Symbol): Symbol {
1542-
return moduleSymbol && getMergedSymbol(resolveSymbol(moduleSymbol.exports.get("export="))) || moduleSymbol;
1553+
function resolveExternalModuleSymbol(moduleSymbol: Symbol, dontResolveAlias?: boolean): Symbol {
1554+
return moduleSymbol && getMergedSymbol(resolveSymbol(moduleSymbol.exports.get("export="), dontResolveAlias)) || moduleSymbol;
15431555
}
15441556

15451557
// An external module with an 'export =' declaration may be referenced as an ES6 module provided the 'export ='
15461558
// references a symbol that is at least declared as a module or a variable. The target of the 'export =' may
15471559
// combine other declarations with the module or variable (e.g. a class/module, function/module, interface/variable).
1548-
function resolveESModuleSymbol(moduleSymbol: Symbol, moduleReferenceExpression: Expression): Symbol {
1549-
let symbol = resolveExternalModuleSymbol(moduleSymbol);
1550-
if (symbol && !(symbol.flags & (SymbolFlags.Module | SymbolFlags.Variable))) {
1560+
function resolveESModuleSymbol(moduleSymbol: Symbol, moduleReferenceExpression: Expression, dontResolveAlias: boolean): Symbol {
1561+
let symbol = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias);
1562+
if (!dontResolveAlias && symbol && !(symbol.flags & (SymbolFlags.Module | SymbolFlags.Variable))) {
15511563
error(moduleReferenceExpression, Diagnostics.Module_0_resolves_to_a_non_module_entity_and_cannot_be_imported_using_this_construct, symbolToString(moduleSymbol));
15521564
symbol = undefined;
15531565
}

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
@@ -457,6 +457,7 @@ namespace ts {
457457
return Parser.parseIsolatedEntityName(text, languageVersion);
458458
}
459459

460+
// See also `isExternalOrCommonJsModule` in utilities.ts
460461
export function isExternalModule(file: SourceFile): boolean {
461462
return file.externalModuleIndicator !== undefined;
462463
}

src/compiler/types.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1818,6 +1818,7 @@
18181818
}
18191819

18201820
export interface ExternalModuleReference extends Node {
1821+
parent: ImportEqualsDeclaration;
18211822
kind: SyntaxKind.ExternalModuleReference;
18221823
expression?: Expression;
18231824
}
@@ -1829,6 +1830,7 @@
18291830
export interface ImportDeclaration extends Statement {
18301831
kind: SyntaxKind.ImportDeclaration;
18311832
importClause?: ImportClause;
1833+
/** If this is not a StringLiteral it will be a grammar error. */
18321834
moduleSpecifier: Expression;
18331835
}
18341836

@@ -1860,6 +1862,7 @@
18601862
export interface ExportDeclaration extends DeclarationStatement {
18611863
kind: SyntaxKind.ExportDeclaration;
18621864
exportClause?: NamedExports;
1865+
/** If this is not a StringLiteral it will be a grammar error. */
18631866
moduleSpecifier?: Expression;
18641867
}
18651868

@@ -1869,6 +1872,7 @@
18691872
}
18701873

18711874
export interface NamedExports extends Node {
1875+
parent: ExportDeclaration;
18721876
kind: SyntaxKind.NamedExports;
18731877
elements: NodeArray<ExportSpecifier>;
18741878
}
@@ -1882,6 +1886,7 @@
18821886
}
18831887

18841888
export interface ExportSpecifier extends Declaration {
1889+
parent: NamedExports;
18851890
kind: SyntaxKind.ExportSpecifier;
18861891
propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent)
18871892
name: Identifier; // Declared name
@@ -2219,8 +2224,8 @@
22192224
// Content of this field should never be used directly - use getResolvedModuleFileName/setResolvedModuleFileName functions instead
22202225
/* @internal */ resolvedModules: Map<ResolvedModuleFull>;
22212226
/* @internal */ resolvedTypeReferenceDirectiveNames: Map<ResolvedTypeReferenceDirective>;
2222-
/* @internal */ imports: LiteralExpression[];
2223-
/* @internal */ moduleAugmentations: LiteralExpression[];
2227+
/* @internal */ imports: StringLiteral[];
2228+
/* @internal */ moduleAugmentations: StringLiteral[];
22242229
/* @internal */ patternAmbientModules?: PatternAmbientModule[];
22252230
/* @internal */ ambientModuleNames: string[];
22262231
}
@@ -2418,10 +2423,14 @@
24182423
isUndefinedSymbol(symbol: Symbol): boolean;
24192424
isArgumentsSymbol(symbol: Symbol): boolean;
24202425
isUnknownSymbol(symbol: Symbol): boolean;
2426+
/* @internal */ getMergedSymbol(symbol: Symbol): Symbol;
24212427

24222428
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number;
24232429
isValidPropertyAccess(node: PropertyAccessExpression | QualifiedName, propertyName: string): boolean;
2430+
/** Follow all aliases to get the original symbol. */
24242431
getAliasedSymbol(symbol: Symbol): Symbol;
2432+
/** Follow a *single* alias to get the immediately aliased symbol. */
2433+
/* @internal */ getImmediateAliasedSymbol(symbol: Symbol): Symbol;
24252434
getExportsOfModule(moduleSymbol: Symbol): Symbol[];
24262435
/** Unlike `getExportsOfModule`, this includes properties of an `export =` value. */
24272436
/* @internal */ getExportsAndPropertiesOfModule(moduleSymbol: Symbol): Symbol[];
@@ -2728,6 +2737,7 @@
27282737

27292738
/* @internal */
27302739
export interface SymbolLinks {
2740+
immediateTarget?: Symbol; // Immediate target of an alias. May be another alias. Do not access directly, use `checker.getImmediateAliasedSymbol` instead.
27312741
target?: Symbol; // Resolved (non-alias) target of an alias
27322742
type?: Type; // Type of value symbol
27332743
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
@@ -3103,7 +3103,7 @@ namespace ts {
31033103
return isExportDefaultSymbol(symbol) ? symbol.valueDeclaration.localSymbol : undefined;
31043104
}
31053105

3106-
export function isExportDefaultSymbol(symbol: Symbol): boolean {
3106+
function isExportDefaultSymbol(symbol: Symbol): boolean {
31073107
return symbol && symbol.valueDeclaration && hasModifier(symbol.valueDeclaration, ModifierFlags.Default);
31083108
}
31093109

0 commit comments

Comments
 (0)