Skip to content

Commit 0f57e97

Browse files
author
Andy Hanson
committed
Refactor findAllReferences. Now supports renamed exports and imports.
1 parent 2fc634f commit 0f57e97

File tree

131 files changed

+2224
-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

+2224
-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,
@@ -1140,14 +1142,14 @@ namespace ts {
11401142
return find<Declaration>(symbol.declarations, isAliasSymbolDeclaration);
11411143
}
11421144

1143-
function getTargetOfImportEqualsDeclaration(node: ImportEqualsDeclaration): Symbol {
1145+
function getTargetOfImportEqualsDeclaration(node: ImportEqualsDeclaration, dontResolveAlias: boolean): Symbol {
11441146
if (node.moduleReference.kind === SyntaxKind.ExternalModuleReference) {
11451147
return resolveExternalModuleSymbol(resolveExternalModuleName(node, getExternalModuleImportEqualsDeclarationExpression(node)));
11461148
}
1147-
return getSymbolOfPartOfRightHandSideOfImportEquals(<EntityName>node.moduleReference);
1149+
return getSymbolOfPartOfRightHandSideOfImportEquals(<EntityName>node.moduleReference, dontResolveAlias);
11481150
}
11491151

1150-
function getTargetOfImportClause(node: ImportClause): Symbol {
1152+
function getTargetOfImportClause(node: ImportClause, dontResolveAlias: boolean): Symbol {
11511153
const moduleSymbol = resolveExternalModuleName(node, (<ImportDeclaration>node.parent).moduleSpecifier);
11521154

11531155
if (moduleSymbol) {
@@ -1159,22 +1161,22 @@ namespace ts {
11591161
const exportValue = moduleSymbol.exports.get("export=");
11601162
exportDefaultSymbol = exportValue
11611163
? getPropertyOfType(getTypeOfSymbol(exportValue), "default")
1162-
: resolveSymbol(moduleSymbol.exports.get("default"));
1164+
: resolveSymbol(moduleSymbol.exports.get("default"), dontResolveAlias);
11631165
}
11641166

11651167
if (!exportDefaultSymbol && !allowSyntheticDefaultImports) {
11661168
error(node.name, Diagnostics.Module_0_has_no_default_export, symbolToString(moduleSymbol));
11671169
}
11681170
else if (!exportDefaultSymbol && allowSyntheticDefaultImports) {
1169-
return resolveExternalModuleSymbol(moduleSymbol) || resolveSymbol(moduleSymbol);
1171+
return resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
11701172
}
11711173
return exportDefaultSymbol;
11721174
}
11731175
}
11741176

1175-
function getTargetOfNamespaceImport(node: NamespaceImport): Symbol {
1177+
function getTargetOfNamespaceImport(node: NamespaceImport, dontResolveAlias: boolean): Symbol {
11761178
const moduleSpecifier = (<ImportDeclaration>node.parent.parent).moduleSpecifier;
1177-
return resolveESModuleSymbol(resolveExternalModuleName(node, moduleSpecifier), moduleSpecifier);
1179+
return resolveESModuleSymbol(resolveExternalModuleName(node, moduleSpecifier), moduleSpecifier, dontResolveAlias);
11781180
}
11791181

11801182
// This function creates a synthetic symbol that combines the value side of one symbol with the
@@ -1208,12 +1210,9 @@ namespace ts {
12081210
return result;
12091211
}
12101212

1211-
function getExportOfModule(symbol: Symbol, name: string): Symbol {
1213+
function getExportOfModule(symbol: Symbol, name: string, dontResolveAlias: boolean): Symbol {
12121214
if (symbol.flags & SymbolFlags.Module) {
1213-
const exportedSymbol = getExportsOfSymbol(symbol).get(name);
1214-
if (exportedSymbol) {
1215-
return resolveSymbol(exportedSymbol);
1216-
}
1215+
return resolveSymbol(getExportsOfSymbol(symbol).get(name), dontResolveAlias);
12171216
}
12181217
}
12191218

@@ -1226,9 +1225,9 @@ namespace ts {
12261225
}
12271226
}
12281227

1229-
function getExternalModuleMember(node: ImportDeclaration | ExportDeclaration, specifier: ImportOrExportSpecifier): Symbol {
1228+
function getExternalModuleMember(node: ImportDeclaration | ExportDeclaration, specifier: ImportOrExportSpecifier, dontResolveAlias?: boolean): Symbol {
12301229
const moduleSymbol = resolveExternalModuleName(node, node.moduleSpecifier);
1231-
const targetSymbol = resolveESModuleSymbol(moduleSymbol, node.moduleSpecifier);
1230+
const targetSymbol = resolveESModuleSymbol(moduleSymbol, node.moduleSpecifier, dontResolveAlias);
12321231
if (targetSymbol) {
12331232
const name = specifier.propertyName || specifier.name;
12341233
if (name.text) {
@@ -1245,11 +1244,11 @@ namespace ts {
12451244
symbolFromVariable = getPropertyOfVariable(targetSymbol, name.text);
12461245
}
12471246
// if symbolFromVariable is export - get its final target
1248-
symbolFromVariable = resolveSymbol(symbolFromVariable);
1249-
let symbolFromModule = getExportOfModule(targetSymbol, name.text);
1247+
symbolFromVariable = resolveSymbol(symbolFromVariable, dontResolveAlias);
1248+
let symbolFromModule = getExportOfModule(targetSymbol, name.text, dontResolveAlias);
12501249
// 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
12511250
if (!symbolFromModule && allowSyntheticDefaultImports && name.text === "default") {
1252-
symbolFromModule = resolveExternalModuleSymbol(moduleSymbol) || resolveSymbol(moduleSymbol);
1251+
symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
12531252
}
12541253
const symbol = symbolFromModule && symbolFromVariable ?
12551254
combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) :
@@ -1262,45 +1261,58 @@ namespace ts {
12621261
}
12631262
}
12641263

1265-
function getTargetOfImportSpecifier(node: ImportSpecifier): Symbol {
1266-
return getExternalModuleMember(<ImportDeclaration>node.parent.parent.parent, node);
1264+
function getTargetOfImportSpecifier(node: ImportSpecifier, dontResolveAlias: boolean): Symbol {
1265+
return getExternalModuleMember(<ImportDeclaration>node.parent.parent.parent, node, dontResolveAlias);
12671266
}
12681267

1269-
function getTargetOfNamespaceExportDeclaration(node: NamespaceExportDeclaration): Symbol {
1270-
return resolveExternalModuleSymbol(node.parent.symbol);
1268+
function getTargetOfNamespaceExportDeclaration(node: NamespaceExportDeclaration, dontResolveAlias: boolean): Symbol {
1269+
return resolveExternalModuleSymbol(node.parent.symbol, dontResolveAlias);
12711270
}
12721271

1273-
function getTargetOfExportSpecifier(node: ExportSpecifier): Symbol {
1272+
function getTargetOfExportSpecifier(node: ExportSpecifier, dontResolveAlias?: boolean): Symbol {
12741273
return (<ExportDeclaration>node.parent.parent).moduleSpecifier ?
1275-
getExternalModuleMember(<ExportDeclaration>node.parent.parent, node) :
1276-
resolveEntityName(node.propertyName || node.name, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace);
1274+
getExternalModuleMember(<ExportDeclaration>node.parent.parent, node, dontResolveAlias) :
1275+
resolveEntityName(node.propertyName || node.name, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace, /*ignoreErrors*/false, dontResolveAlias);
12771276
}
12781277

1279-
function getTargetOfExportAssignment(node: ExportAssignment): Symbol {
1280-
return resolveEntityName(<EntityNameExpression>node.expression, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace);
1278+
function getTargetOfExportAssignment(node: ExportAssignment, dontResolveAlias: boolean): Symbol {
1279+
return resolveEntityName(<EntityNameExpression>node.expression, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace, /*ignoreErrors*/false, dontResolveAlias);
12811280
}
12821281

1283-
function getTargetOfAliasDeclaration(node: Declaration): Symbol {
1282+
function getTargetOfAliasDeclaration(node: Declaration, dontRecursivelyResolve?: boolean): Symbol {
12841283
switch (node.kind) {
12851284
case SyntaxKind.ImportEqualsDeclaration:
1286-
return getTargetOfImportEqualsDeclaration(<ImportEqualsDeclaration>node);
1285+
return getTargetOfImportEqualsDeclaration(<ImportEqualsDeclaration>node, dontRecursivelyResolve);
12871286
case SyntaxKind.ImportClause:
1288-
return getTargetOfImportClause(<ImportClause>node);
1287+
return getTargetOfImportClause(<ImportClause>node, dontRecursivelyResolve);
12891288
case SyntaxKind.NamespaceImport:
1290-
return getTargetOfNamespaceImport(<NamespaceImport>node);
1289+
return getTargetOfNamespaceImport(<NamespaceImport>node, dontRecursivelyResolve);
12911290
case SyntaxKind.ImportSpecifier:
1292-
return getTargetOfImportSpecifier(<ImportSpecifier>node);
1291+
return getTargetOfImportSpecifier(<ImportSpecifier>node, dontRecursivelyResolve);
12931292
case SyntaxKind.ExportSpecifier:
1294-
return getTargetOfExportSpecifier(<ExportSpecifier>node);
1293+
return getTargetOfExportSpecifier(<ExportSpecifier>node, dontRecursivelyResolve);
12951294
case SyntaxKind.ExportAssignment:
1296-
return getTargetOfExportAssignment(<ExportAssignment>node);
1295+
return getTargetOfExportAssignment(<ExportAssignment>node, dontRecursivelyResolve);
12971296
case SyntaxKind.NamespaceExportDeclaration:
1298-
return getTargetOfNamespaceExportDeclaration(<NamespaceExportDeclaration>node);
1297+
return getTargetOfNamespaceExportDeclaration(<NamespaceExportDeclaration>node, dontRecursivelyResolve);
12991298
}
13001299
}
13011300

1302-
function resolveSymbol(symbol: Symbol): Symbol {
1303-
return symbol && symbol.flags & SymbolFlags.Alias && !(symbol.flags & (SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace)) ? resolveAlias(symbol) : symbol;
1301+
function resolveSymbol(symbol: Symbol, dontResolveAlias?: boolean): Symbol {
1302+
const shouldResolve = !dontResolveAlias && symbol && symbol.flags & SymbolFlags.Alias && !(symbol.flags & (SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace));
1303+
return shouldResolve ? resolveAlias(symbol) : symbol;
1304+
}
1305+
1306+
function getImmediateAliasedSymbol(symbol: Symbol): Symbol {
1307+
Debug.assert((symbol.flags & SymbolFlags.Alias) !== 0, "Should only get Alias here.");
1308+
const links = getSymbolLinks(symbol);
1309+
if (!links.immediateTarget) {
1310+
const node = getDeclarationOfAliasSymbol(symbol);
1311+
Debug.assert(!!node);
1312+
links.immediateTarget = getTargetOfAliasDeclaration(node, /*dontRecursivelyResolve*/true);
1313+
}
1314+
1315+
return links.immediateTarget;
13041316
}
13051317

13061318
function resolveAlias(symbol: Symbol): Symbol {
@@ -1517,16 +1529,16 @@ namespace ts {
15171529

15181530
// An external module with an 'export =' declaration resolves to the target of the 'export =' declaration,
15191531
// and an external module with no 'export =' declaration resolves to the module itself.
1520-
function resolveExternalModuleSymbol(moduleSymbol: Symbol): Symbol {
1521-
return moduleSymbol && getMergedSymbol(resolveSymbol(moduleSymbol.exports.get("export="))) || moduleSymbol;
1532+
function resolveExternalModuleSymbol(moduleSymbol: Symbol, dontResolveAlias?: boolean): Symbol {
1533+
return moduleSymbol && getMergedSymbol(resolveSymbol(moduleSymbol.exports.get("export="), dontResolveAlias)) || moduleSymbol;
15221534
}
15231535

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

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[];
@@ -2709,6 +2718,7 @@
27092718

27102719
/* @internal */
27112720
export interface SymbolLinks {
2721+
immediateTarget?: Symbol; // Immediate target of an alias. May be another alias. Do not access directly, use `checker.getImmediateAliasedSymbol` instead.
27122722
target?: Symbol; // Resolved (non-alias) target of an alias
27132723
type?: Type; // Type of value symbol
27142724
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)