Skip to content

Commit 72feaad

Browse files
author
Andy
authored
Merge pull request #14001 from Microsoft/refactor_findallrefs
Refactor findAllReferences. Now supports renamed exports and imports.
2 parents ecd772d + c7d51a3 commit 72feaad

File tree

149 files changed

+2583
-1391
lines changed

Some content is hidden

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

149 files changed

+2583
-1391
lines changed

Gulpfile.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ const cmdLineOptions = minimist(process.argv.slice(2), {
4141
boolean: ["debug", "inspect", "light", "colors", "lint", "soft"],
4242
string: ["browser", "tests", "host", "reporter", "stackTraceLimit"],
4343
alias: {
44+
b: "browser",
4445
d: "debug",
4546
t: "tests",
4647
test: "tests",

src/compiler/checker.ts

Lines changed: 51 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ namespace ts {
8181
isUndefinedSymbol: symbol => symbol === undefinedSymbol,
8282
isArgumentsSymbol: symbol => symbol === argumentsSymbol,
8383
isUnknownSymbol: symbol => symbol === unknownSymbol,
84+
getMergedSymbol,
8485
getDiagnostics,
8586
getGlobalDiagnostics,
8687
getTypeOfSymbolAtLocation: (symbol, location) => {
@@ -172,6 +173,17 @@ namespace ts {
172173
node = getParseTreeNode(node, isFunctionLike);
173174
return node ? isImplementationOfOverload(node) : undefined;
174175
},
176+
getImmediateAliasedSymbol: symbol => {
177+
Debug.assert((symbol.flags & SymbolFlags.Alias) !== 0, "Should only get Alias here.");
178+
const links = getSymbolLinks(symbol);
179+
if (!links.immediateTarget) {
180+
const node = getDeclarationOfAliasSymbol(symbol);
181+
Debug.assert(!!node);
182+
links.immediateTarget = getTargetOfAliasDeclaration(node, /*dontRecursivelyResolve*/ true);
183+
}
184+
185+
return links.immediateTarget;
186+
},
175187
getAliasedSymbol: resolveAlias,
176188
getEmitResolver,
177189
getExportsOfModule: getExportsOfModuleAsArray,
@@ -1272,14 +1284,14 @@ namespace ts {
12721284
return find<Declaration>(symbol.declarations, isAliasSymbolDeclaration);
12731285
}
12741286

1275-
function getTargetOfImportEqualsDeclaration(node: ImportEqualsDeclaration): Symbol {
1287+
function getTargetOfImportEqualsDeclaration(node: ImportEqualsDeclaration, dontResolveAlias: boolean): Symbol {
12761288
if (node.moduleReference.kind === SyntaxKind.ExternalModuleReference) {
12771289
return resolveExternalModuleSymbol(resolveExternalModuleName(node, getExternalModuleImportEqualsDeclarationExpression(node)));
12781290
}
1279-
return getSymbolOfPartOfRightHandSideOfImportEquals(<EntityName>node.moduleReference);
1291+
return getSymbolOfPartOfRightHandSideOfImportEquals(<EntityName>node.moduleReference, dontResolveAlias);
12801292
}
12811293

1282-
function getTargetOfImportClause(node: ImportClause): Symbol {
1294+
function getTargetOfImportClause(node: ImportClause, dontResolveAlias: boolean): Symbol {
12831295
const moduleSymbol = resolveExternalModuleName(node, (<ImportDeclaration>node.parent).moduleSpecifier);
12841296

12851297
if (moduleSymbol) {
@@ -1291,22 +1303,22 @@ namespace ts {
12911303
const exportValue = moduleSymbol.exports.get("export=");
12921304
exportDefaultSymbol = exportValue
12931305
? getPropertyOfType(getTypeOfSymbol(exportValue), "default")
1294-
: resolveSymbol(moduleSymbol.exports.get("default"));
1306+
: resolveSymbol(moduleSymbol.exports.get("default"), dontResolveAlias);
12951307
}
12961308

12971309
if (!exportDefaultSymbol && !allowSyntheticDefaultImports) {
12981310
error(node.name, Diagnostics.Module_0_has_no_default_export, symbolToString(moduleSymbol));
12991311
}
13001312
else if (!exportDefaultSymbol && allowSyntheticDefaultImports) {
1301-
return resolveExternalModuleSymbol(moduleSymbol) || resolveSymbol(moduleSymbol);
1313+
return resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
13021314
}
13031315
return exportDefaultSymbol;
13041316
}
13051317
}
13061318

1307-
function getTargetOfNamespaceImport(node: NamespaceImport): Symbol {
1319+
function getTargetOfNamespaceImport(node: NamespaceImport, dontResolveAlias: boolean): Symbol {
13081320
const moduleSpecifier = (<ImportDeclaration>node.parent.parent).moduleSpecifier;
1309-
return resolveESModuleSymbol(resolveExternalModuleName(node, moduleSpecifier), moduleSpecifier);
1321+
return resolveESModuleSymbol(resolveExternalModuleName(node, moduleSpecifier), moduleSpecifier, dontResolveAlias);
13101322
}
13111323

13121324
// This function creates a synthetic symbol that combines the value side of one symbol with the
@@ -1340,12 +1352,9 @@ namespace ts {
13401352
return result;
13411353
}
13421354

1343-
function getExportOfModule(symbol: Symbol, name: string): Symbol {
1355+
function getExportOfModule(symbol: Symbol, name: string, dontResolveAlias: boolean): Symbol {
13441356
if (symbol.flags & SymbolFlags.Module) {
1345-
const exportedSymbol = getExportsOfSymbol(symbol).get(name);
1346-
if (exportedSymbol) {
1347-
return resolveSymbol(exportedSymbol);
1348-
}
1357+
return resolveSymbol(getExportsOfSymbol(symbol).get(name), dontResolveAlias);
13491358
}
13501359
}
13511360

@@ -1358,9 +1367,9 @@ namespace ts {
13581367
}
13591368
}
13601369

1361-
function getExternalModuleMember(node: ImportDeclaration | ExportDeclaration, specifier: ImportOrExportSpecifier): Symbol {
1370+
function getExternalModuleMember(node: ImportDeclaration | ExportDeclaration, specifier: ImportOrExportSpecifier, dontResolveAlias?: boolean): Symbol {
13621371
const moduleSymbol = resolveExternalModuleName(node, node.moduleSpecifier);
1363-
const targetSymbol = resolveESModuleSymbol(moduleSymbol, node.moduleSpecifier);
1372+
const targetSymbol = resolveESModuleSymbol(moduleSymbol, node.moduleSpecifier, dontResolveAlias);
13641373
if (targetSymbol) {
13651374
const name = specifier.propertyName || specifier.name;
13661375
if (name.text) {
@@ -1377,11 +1386,11 @@ namespace ts {
13771386
symbolFromVariable = getPropertyOfVariable(targetSymbol, name.text);
13781387
}
13791388
// if symbolFromVariable is export - get its final target
1380-
symbolFromVariable = resolveSymbol(symbolFromVariable);
1381-
let symbolFromModule = getExportOfModule(targetSymbol, name.text);
1389+
symbolFromVariable = resolveSymbol(symbolFromVariable, dontResolveAlias);
1390+
let symbolFromModule = getExportOfModule(targetSymbol, name.text, dontResolveAlias);
13821391
// 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
13831392
if (!symbolFromModule && allowSyntheticDefaultImports && name.text === "default") {
1384-
symbolFromModule = resolveExternalModuleSymbol(moduleSymbol) || resolveSymbol(moduleSymbol);
1393+
symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
13851394
}
13861395
const symbol = symbolFromModule && symbolFromVariable ?
13871396
combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) :
@@ -1394,45 +1403,46 @@ namespace ts {
13941403
}
13951404
}
13961405

1397-
function getTargetOfImportSpecifier(node: ImportSpecifier): Symbol {
1398-
return getExternalModuleMember(<ImportDeclaration>node.parent.parent.parent, node);
1406+
function getTargetOfImportSpecifier(node: ImportSpecifier, dontResolveAlias: boolean): Symbol {
1407+
return getExternalModuleMember(<ImportDeclaration>node.parent.parent.parent, node, dontResolveAlias);
13991408
}
14001409

1401-
function getTargetOfNamespaceExportDeclaration(node: NamespaceExportDeclaration): Symbol {
1402-
return resolveExternalModuleSymbol(node.parent.symbol);
1410+
function getTargetOfNamespaceExportDeclaration(node: NamespaceExportDeclaration, dontResolveAlias: boolean): Symbol {
1411+
return resolveExternalModuleSymbol(node.parent.symbol, dontResolveAlias);
14031412
}
14041413

1405-
function getTargetOfExportSpecifier(node: ExportSpecifier): Symbol {
1414+
function getTargetOfExportSpecifier(node: ExportSpecifier, dontResolveAlias?: boolean): Symbol {
14061415
return (<ExportDeclaration>node.parent.parent).moduleSpecifier ?
1407-
getExternalModuleMember(<ExportDeclaration>node.parent.parent, node) :
1408-
resolveEntityName(node.propertyName || node.name, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace);
1416+
getExternalModuleMember(<ExportDeclaration>node.parent.parent, node, dontResolveAlias) :
1417+
resolveEntityName(node.propertyName || node.name, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace, /*ignoreErrors*/ false, dontResolveAlias);
14091418
}
14101419

1411-
function getTargetOfExportAssignment(node: ExportAssignment): Symbol {
1412-
return resolveEntityName(<EntityNameExpression>node.expression, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace);
1420+
function getTargetOfExportAssignment(node: ExportAssignment, dontResolveAlias: boolean): Symbol {
1421+
return resolveEntityName(<EntityNameExpression>node.expression, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace, /*ignoreErrors*/ false, dontResolveAlias);
14131422
}
14141423

1415-
function getTargetOfAliasDeclaration(node: Declaration): Symbol {
1424+
function getTargetOfAliasDeclaration(node: Declaration, dontRecursivelyResolve?: boolean): Symbol {
14161425
switch (node.kind) {
14171426
case SyntaxKind.ImportEqualsDeclaration:
1418-
return getTargetOfImportEqualsDeclaration(<ImportEqualsDeclaration>node);
1427+
return getTargetOfImportEqualsDeclaration(<ImportEqualsDeclaration>node, dontRecursivelyResolve);
14191428
case SyntaxKind.ImportClause:
1420-
return getTargetOfImportClause(<ImportClause>node);
1429+
return getTargetOfImportClause(<ImportClause>node, dontRecursivelyResolve);
14211430
case SyntaxKind.NamespaceImport:
1422-
return getTargetOfNamespaceImport(<NamespaceImport>node);
1431+
return getTargetOfNamespaceImport(<NamespaceImport>node, dontRecursivelyResolve);
14231432
case SyntaxKind.ImportSpecifier:
1424-
return getTargetOfImportSpecifier(<ImportSpecifier>node);
1433+
return getTargetOfImportSpecifier(<ImportSpecifier>node, dontRecursivelyResolve);
14251434
case SyntaxKind.ExportSpecifier:
1426-
return getTargetOfExportSpecifier(<ExportSpecifier>node);
1435+
return getTargetOfExportSpecifier(<ExportSpecifier>node, dontRecursivelyResolve);
14271436
case SyntaxKind.ExportAssignment:
1428-
return getTargetOfExportAssignment(<ExportAssignment>node);
1437+
return getTargetOfExportAssignment(<ExportAssignment>node, dontRecursivelyResolve);
14291438
case SyntaxKind.NamespaceExportDeclaration:
1430-
return getTargetOfNamespaceExportDeclaration(<NamespaceExportDeclaration>node);
1439+
return getTargetOfNamespaceExportDeclaration(<NamespaceExportDeclaration>node, dontRecursivelyResolve);
14311440
}
14321441
}
14331442

1434-
function resolveSymbol(symbol: Symbol): Symbol {
1435-
return symbol && symbol.flags & SymbolFlags.Alias && !(symbol.flags & (SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace)) ? resolveAlias(symbol) : symbol;
1443+
function resolveSymbol(symbol: Symbol, dontResolveAlias?: boolean): Symbol {
1444+
const shouldResolve = !dontResolveAlias && symbol && symbol.flags & SymbolFlags.Alias && !(symbol.flags & (SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace));
1445+
return shouldResolve ? resolveAlias(symbol) : symbol;
14361446
}
14371447

14381448
function resolveAlias(symbol: Symbol): Symbol {
@@ -1672,16 +1682,16 @@ namespace ts {
16721682

16731683
// An external module with an 'export =' declaration resolves to the target of the 'export =' declaration,
16741684
// and an external module with no 'export =' declaration resolves to the module itself.
1675-
function resolveExternalModuleSymbol(moduleSymbol: Symbol): Symbol {
1676-
return moduleSymbol && getMergedSymbol(resolveSymbol(moduleSymbol.exports.get("export="))) || moduleSymbol;
1685+
function resolveExternalModuleSymbol(moduleSymbol: Symbol, dontResolveAlias?: boolean): Symbol {
1686+
return moduleSymbol && getMergedSymbol(resolveSymbol(moduleSymbol.exports.get("export="), dontResolveAlias)) || moduleSymbol;
16771687
}
16781688

16791689
// An external module with an 'export =' declaration may be referenced as an ES6 module provided the 'export ='
16801690
// references a symbol that is at least declared as a module or a variable. The target of the 'export =' may
16811691
// combine other declarations with the module or variable (e.g. a class/module, function/module, interface/variable).
1682-
function resolveESModuleSymbol(moduleSymbol: Symbol, moduleReferenceExpression: Expression): Symbol {
1683-
let symbol = resolveExternalModuleSymbol(moduleSymbol);
1684-
if (symbol && !(symbol.flags & (SymbolFlags.Module | SymbolFlags.Variable))) {
1692+
function resolveESModuleSymbol(moduleSymbol: Symbol, moduleReferenceExpression: Expression, dontResolveAlias: boolean): Symbol {
1693+
let symbol = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias);
1694+
if (!dontResolveAlias && symbol && !(symbol.flags & (SymbolFlags.Module | SymbolFlags.Variable))) {
16851695
error(moduleReferenceExpression, Diagnostics.Module_0_resolves_to_a_non_module_entity_and_cannot_be_imported_using_this_construct, symbolToString(moduleSymbol));
16861696
symbol = undefined;
16871697
}

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

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

src/compiler/types.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1886,6 +1886,7 @@ namespace ts {
18861886
kind: SyntaxKind.ImportDeclaration;
18871887
parent?: SourceFile | ModuleBlock;
18881888
importClause?: ImportClause;
1889+
/** If this is not a StringLiteral it will be a grammar error. */
18891890
moduleSpecifier: Expression;
18901891
}
18911892

@@ -1919,6 +1920,7 @@ namespace ts {
19191920
kind: SyntaxKind.ExportDeclaration;
19201921
parent?: SourceFile | ModuleBlock;
19211922
exportClause?: NamedExports;
1923+
/** If this is not a StringLiteral it will be a grammar error. */
19221924
moduleSpecifier?: Expression;
19231925
}
19241926

@@ -2305,8 +2307,8 @@ namespace ts {
23052307
// Content of this field should never be used directly - use getResolvedModuleFileName/setResolvedModuleFileName functions instead
23062308
/* @internal */ resolvedModules: Map<ResolvedModuleFull>;
23072309
/* @internal */ resolvedTypeReferenceDirectiveNames: Map<ResolvedTypeReferenceDirective>;
2308-
/* @internal */ imports: LiteralExpression[];
2309-
/* @internal */ moduleAugmentations: LiteralExpression[];
2310+
/* @internal */ imports: StringLiteral[];
2311+
/* @internal */ moduleAugmentations: StringLiteral[];
23102312
/* @internal */ patternAmbientModules?: PatternAmbientModule[];
23112313
/* @internal */ ambientModuleNames: string[];
23122314
/* @internal */ checkJsDirective: CheckJsDirective | undefined;
@@ -2522,10 +2524,14 @@ namespace ts {
25222524
isUndefinedSymbol(symbol: Symbol): boolean;
25232525
isArgumentsSymbol(symbol: Symbol): boolean;
25242526
isUnknownSymbol(symbol: Symbol): boolean;
2527+
/* @internal */ getMergedSymbol(symbol: Symbol): Symbol;
25252528

25262529
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number;
25272530
isValidPropertyAccess(node: PropertyAccessExpression | QualifiedName, propertyName: string): boolean;
2531+
/** Follow all aliases to get the original symbol. */
25282532
getAliasedSymbol(symbol: Symbol): Symbol;
2533+
/** Follow a *single* alias to get the immediately aliased symbol. */
2534+
/* @internal */ getImmediateAliasedSymbol(symbol: Symbol): Symbol;
25292535
getExportsOfModule(moduleSymbol: Symbol): Symbol[];
25302536
/** Unlike `getExportsOfModule`, this includes properties of an `export =` value. */
25312537
/* @internal */ getExportsAndPropertiesOfModule(moduleSymbol: Symbol): Symbol[];
@@ -2841,6 +2847,7 @@ namespace ts {
28412847

28422848
/* @internal */
28432849
export interface SymbolLinks {
2850+
immediateTarget?: Symbol; // Immediate target of an alias. May be another alias. Do not access directly, use `checker.getImmediateAliasedSymbol` instead.
28442851
target?: Symbol; // Resolved (non-alias) target of an alias
28452852
type?: Type; // Type of value symbol
28462853
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
@@ -3134,7 +3134,7 @@ namespace ts {
31343134
return isExportDefaultSymbol(symbol) ? symbol.valueDeclaration.localSymbol : undefined;
31353135
}
31363136

3137-
export function isExportDefaultSymbol(symbol: Symbol): boolean {
3137+
function isExportDefaultSymbol(symbol: Symbol): boolean {
31383138
return symbol && symbol.valueDeclaration && hasModifier(symbol.valueDeclaration, ModifierFlags.Default);
31393139
}
31403140

0 commit comments

Comments
 (0)