Skip to content

Commit e4a1c15

Browse files
committed
Merge pull request #2553 from Microsoft/exportDefaultReference
Ensure we find export default declaration targets if we search for them by name
2 parents 0afa459 + f75c1dd commit e4a1c15

12 files changed

+211
-8
lines changed

src/compiler/checker.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,14 @@ module ts {
349349
}
350350
result = undefined;
351351
}
352+
else if (location.kind === SyntaxKind.SourceFile) {
353+
result = getSymbol(getSymbolOfNode(location).exports, "default", meaning & SymbolFlags.ModuleMember);
354+
let localSymbol = getLocalSymbolForExportDefault(result);
355+
if (result && (result.flags & meaning) && localSymbol && localSymbol.name === name) {
356+
break loop;
357+
}
358+
result = undefined;
359+
}
352360
break;
353361
case SyntaxKind.EnumDeclaration:
354362
if (result = getSymbol(getSymbolOfNode(location).exports, name, meaning & SymbolFlags.EnumMember)) {

src/compiler/utilities.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ module ts {
145145

146146
return node.pos === node.end && node.kind !== SyntaxKind.EndOfFileToken;
147147
}
148-
148+
149149
export function nodeIsPresent(node: Node) {
150150
return !nodeIsMissing(node);
151151
}
@@ -296,7 +296,7 @@ module ts {
296296
errorNode = (<Declaration>node).name;
297297
break;
298298
}
299-
299+
300300
if (errorNode === undefined) {
301301
// If we don't have a better node, then just set the error on the first token of
302302
// construct.
@@ -642,7 +642,7 @@ module ts {
642642

643643
return false;
644644
}
645-
645+
646646
export function childIsDecorated(node: Node): boolean {
647647
switch (node.kind) {
648648
case SyntaxKind.ClassDeclaration:
@@ -754,7 +754,7 @@ module ts {
754754
export function isInstantiatedModule(node: ModuleDeclaration, preserveConstEnums: boolean) {
755755
let moduleState = getModuleInstanceState(node)
756756
return moduleState === ModuleInstanceState.Instantiated ||
757-
(preserveConstEnums && moduleState === ModuleInstanceState.ConstEnumOnly);
757+
(preserveConstEnums && moduleState === ModuleInstanceState.ConstEnumOnly);
758758
}
759759

760760
export function isExternalModuleImportEqualsDeclaration(node: Node) {
@@ -1170,7 +1170,7 @@ module ts {
11701170
export function createTextSpanFromBounds(start: number, end: number) {
11711171
return createTextSpan(start, end - start);
11721172
}
1173-
1173+
11741174
export function textChangeRangeNewSpan(range: TextChangeRange) {
11751175
return createTextSpan(range.span.start, range.newLength);
11761176
}
@@ -1444,13 +1444,13 @@ module ts {
14441444
return escapedCharsMap[c] || get16BitUnicodeEscapeSequence(c.charCodeAt(0));
14451445
}
14461446
}
1447-
1447+
14481448
function get16BitUnicodeEscapeSequence(charCode: number): string {
14491449
let hexCharCode = charCode.toString(16).toUpperCase();
14501450
let paddedHexCode = ("0000" + hexCharCode).slice(-4);
14511451
return "\\u" + paddedHexCode;
14521452
}
1453-
1453+
14541454
let nonAsciiCharacters = /[^\u0000-\u007F]/g;
14551455
export function escapeNonAsciiCharacters(s: string): string {
14561456
// Replace non-ASCII characters with '\uNNNN' escapes if any exist.
@@ -1799,4 +1799,8 @@ module ts {
17991799
return (node.parent.kind === SyntaxKind.QualifiedName && (<QualifiedName>node.parent).right === node) ||
18001800
(node.parent.kind === SyntaxKind.PropertyAccessExpression && (<PropertyAccessExpression>node.parent).name === node);
18011801
}
1802+
1803+
export function getLocalSymbolForExportDefault(symbol: Symbol) {
1804+
return symbol && symbol.valueDeclaration && (symbol.valueDeclaration.flags & NodeFlags.Default) ? symbol.valueDeclaration.localSymbol : undefined;
1805+
}
18021806
}

src/services/services.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2459,6 +2459,14 @@ module ts {
24592459
return undefined;
24602460
}
24612461

2462+
// If this is the default export, get the name of the declaration if it exists
2463+
if (displayName === "default") {
2464+
let localSymbol = getLocalSymbolForExportDefault(symbol);
2465+
if (localSymbol && localSymbol.name) {
2466+
displayName = symbol.valueDeclaration.localSymbol.name;
2467+
}
2468+
}
2469+
24622470
let firstCharCode = displayName.charCodeAt(0);
24632471
// First check of the displayName is not external module; if it is an external module, it is not valid entry
24642472
if ((symbol.flags & SymbolFlags.Namespace) && (firstCharCode === CharacterCodes.singleQuote || firstCharCode === CharacterCodes.doubleQuote)) {
@@ -2675,7 +2683,7 @@ module ts {
26752683
previousToken.getStart() :
26762684
position;
26772685

2678-
let scopeNode = getScopeNode(contextToken, adjustedPosition, sourceFile);
2686+
let scopeNode = getScopeNode(contextToken, adjustedPosition, sourceFile) || sourceFile;
26792687

26802688
/// TODO filter meaning based on the current context
26812689
let symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias;

tests/baselines/reference/APISample_linter.types.pull

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4984,6 +4984,27 @@ declare module "typescript" {
49844984
>CompilerHost : CompilerHost
49854985
>Program : Program
49864986
}
4987+
declare module "typescript" {
4988+
/**
4989+
* Read tsconfig.json file
4990+
* @param fileName The path to the config file
4991+
*/
4992+
function readConfigFile(fileName: string): any;
4993+
>readConfigFile : (fileName: string) => any
4994+
>fileName : string
4995+
4996+
/**
4997+
* Parse the contents of a config file (tsconfig.json).
4998+
* @param json The contents of the config file to parse
4999+
* @param basePath A root directory to resolve relative path entries in the config
5000+
* file to. e.g. outDir
5001+
*/
5002+
function parseConfigFile(json: any, basePath?: string): ParsedCommandLine;
5003+
>parseConfigFile : (json: any, basePath?: string) => ParsedCommandLine
5004+
>json : any
5005+
>basePath : string
5006+
>ParsedCommandLine : ParsedCommandLine
5007+
}
49875008
declare module "typescript" {
49885009
/** The version of the language service API */
49895010
let servicesVersion: string;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//// [es5ExportDefaultClassDeclaration3.ts]
2+
3+
var before: C = new C();
4+
5+
export default class C {
6+
method(): C {
7+
return new C();
8+
}
9+
}
10+
11+
var after: C = new C();
12+
13+
var t: typeof C = C;
14+
15+
16+
17+
//// [es5ExportDefaultClassDeclaration3.js]
18+
var before = new C();
19+
var C = (function () {
20+
function C() {
21+
}
22+
C.prototype.method = function () {
23+
return new C();
24+
};
25+
return C;
26+
})();
27+
exports.default = C;
28+
var after = new C();
29+
var t = C;
30+
31+
32+
//// [es5ExportDefaultClassDeclaration3.d.ts]
33+
export default class C {
34+
method(): C;
35+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
=== tests/cases/compiler/es5ExportDefaultClassDeclaration3.ts ===
2+
3+
var before: C = new C();
4+
>before : C
5+
>C : C
6+
>new C() : C
7+
>C : typeof C
8+
9+
export default class C {
10+
>C : C
11+
12+
method(): C {
13+
>method : () => C
14+
>C : C
15+
16+
return new C();
17+
>new C() : C
18+
>C : typeof C
19+
}
20+
}
21+
22+
var after: C = new C();
23+
>after : C
24+
>C : C
25+
>new C() : C
26+
>C : typeof C
27+
28+
var t: typeof C = C;
29+
>t : typeof C
30+
>C : typeof C
31+
>C : typeof C
32+
33+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//// [es5ExportDefaultFunctionDeclaration3.ts]
2+
3+
var before: typeof func = func();
4+
5+
export default function func(): typeof func {
6+
return func;
7+
}
8+
9+
var after: typeof func = func();
10+
11+
//// [es5ExportDefaultFunctionDeclaration3.js]
12+
var before = func();
13+
function func() {
14+
return func;
15+
}
16+
exports.default = func;
17+
var after = func();
18+
19+
20+
//// [es5ExportDefaultFunctionDeclaration3.d.ts]
21+
export default function func(): typeof func;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
=== tests/cases/compiler/es5ExportDefaultFunctionDeclaration3.ts ===
2+
3+
var before: typeof func = func();
4+
>before : () => typeof func
5+
>func : () => typeof func
6+
>func() : () => typeof func
7+
>func : () => typeof func
8+
9+
export default function func(): typeof func {
10+
>func : () => typeof func
11+
>func : () => typeof func
12+
13+
return func;
14+
>func : () => typeof func
15+
}
16+
17+
var after: typeof func = func();
18+
>after : () => typeof func
19+
>func : () => typeof func
20+
>func() : () => typeof func
21+
>func : () => typeof func
22+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// @target: es5
2+
// @module: commonjs
3+
// @declaration: true
4+
5+
var before: C = new C();
6+
7+
export default class C {
8+
method(): C {
9+
return new C();
10+
}
11+
}
12+
13+
var after: C = new C();
14+
15+
var t: typeof C = C;
16+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// @target: es5
2+
// @module: commonjs
3+
// @declaration: true
4+
5+
var before: typeof func = func();
6+
7+
export default function func(): typeof func {
8+
return func;
9+
}
10+
11+
var after: typeof func = func();

0 commit comments

Comments
 (0)