Merge pull request #3532 from Microsoft/exportSpecifierScoping
Make resolveName ignore export specifiers without calling getSymbol
This commit is contained in:
commit
ab61bf2a6d
22 changed files with 303 additions and 8 deletions
|
@ -344,21 +344,38 @@ module ts {
|
|||
case SyntaxKind.SourceFile:
|
||||
if (!isExternalModule(<SourceFile>location)) break;
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
if (result = getSymbol(getSymbolOfNode(location).exports, name, meaning & SymbolFlags.ModuleMember)) {
|
||||
if (result.flags & meaning || !(result.flags & SymbolFlags.Alias && getDeclarationOfAliasSymbol(result).kind === SyntaxKind.ExportSpecifier)) {
|
||||
break loop;
|
||||
}
|
||||
result = undefined;
|
||||
}
|
||||
else if (location.kind === SyntaxKind.SourceFile ||
|
||||
let moduleExports = getSymbolOfNode(location).exports;
|
||||
if (location.kind === SyntaxKind.SourceFile ||
|
||||
(location.kind === SyntaxKind.ModuleDeclaration && (<ModuleDeclaration>location).name.kind === SyntaxKind.StringLiteral)) {
|
||||
result = getSymbolOfNode(location).exports["default"];
|
||||
|
||||
// It's an external module. Because of module/namespace merging, a module's exports are in scope,
|
||||
// yet we never want to treat an export specifier as putting a member in scope. Therefore,
|
||||
// if the name we find is purely an export specifier, it is not actually considered in scope.
|
||||
// Two things to note about this:
|
||||
// 1. We have to check this without calling getSymbol. The problem with calling getSymbol
|
||||
// on an export specifier is that it might find the export specifier itself, and try to
|
||||
// resolve it as an alias. This will cause the checker to consider the export specifier
|
||||
// a circular alias reference when it might not be.
|
||||
// 2. We check === SymbolFlags.Alias in order to check that the symbol is *purely*
|
||||
// an alias. If we used &, we'd be throwing out symbols that have non alias aspects,
|
||||
// which is not the desired behavior.
|
||||
if (hasProperty(moduleExports, name) &&
|
||||
moduleExports[name].flags === SymbolFlags.Alias &&
|
||||
getDeclarationOfKind(moduleExports[name], SyntaxKind.ExportSpecifier)) {
|
||||
break;
|
||||
}
|
||||
|
||||
result = moduleExports["default"];
|
||||
let localSymbol = getLocalSymbolForExportDefault(result);
|
||||
if (result && localSymbol && (result.flags & meaning) && localSymbol.name === name) {
|
||||
break loop;
|
||||
}
|
||||
result = undefined;
|
||||
}
|
||||
|
||||
if (result = getSymbol(moduleExports, name, meaning & SymbolFlags.ModuleMember)) {
|
||||
break loop;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
if (result = getSymbol(getSymbolOfNode(location).exports, name, meaning & SymbolFlags.EnumMember)) {
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
//// [exportSpecifierAndExportedMemberDeclaration.ts]
|
||||
declare module "m2" {
|
||||
export module X {
|
||||
interface I { }
|
||||
}
|
||||
function Y();
|
||||
export { Y as X };
|
||||
function Z(): X.I;
|
||||
}
|
||||
|
||||
declare module "m2" {
|
||||
function Z2(): X.I;
|
||||
}
|
||||
|
||||
//// [exportSpecifierAndExportedMemberDeclaration.js]
|
|
@ -0,0 +1,27 @@
|
|||
=== tests/cases/compiler/exportSpecifierAndExportedMemberDeclaration.ts ===
|
||||
declare module "m2" {
|
||||
export module X {
|
||||
>X : Symbol(X, Decl(exportSpecifierAndExportedMemberDeclaration.ts, 0, 21), Decl(exportSpecifierAndExportedMemberDeclaration.ts, 5, 12))
|
||||
|
||||
interface I { }
|
||||
>I : Symbol(I, Decl(exportSpecifierAndExportedMemberDeclaration.ts, 1, 21))
|
||||
}
|
||||
function Y();
|
||||
>Y : Symbol(Y, Decl(exportSpecifierAndExportedMemberDeclaration.ts, 3, 5))
|
||||
|
||||
export { Y as X };
|
||||
>Y : Symbol(X, Decl(exportSpecifierAndExportedMemberDeclaration.ts, 0, 21), Decl(exportSpecifierAndExportedMemberDeclaration.ts, 5, 12))
|
||||
>X : Symbol(X, Decl(exportSpecifierAndExportedMemberDeclaration.ts, 0, 21), Decl(exportSpecifierAndExportedMemberDeclaration.ts, 5, 12))
|
||||
|
||||
function Z(): X.I;
|
||||
>Z : Symbol(Z, Decl(exportSpecifierAndExportedMemberDeclaration.ts, 5, 22))
|
||||
>X : Symbol(X, Decl(exportSpecifierAndExportedMemberDeclaration.ts, 0, 21), Decl(exportSpecifierAndExportedMemberDeclaration.ts, 5, 12))
|
||||
>I : Symbol(X.I, Decl(exportSpecifierAndExportedMemberDeclaration.ts, 1, 21))
|
||||
}
|
||||
|
||||
declare module "m2" {
|
||||
function Z2(): X.I;
|
||||
>Z2 : Symbol(Z2, Decl(exportSpecifierAndExportedMemberDeclaration.ts, 9, 21))
|
||||
>X : Symbol(X, Decl(exportSpecifierAndExportedMemberDeclaration.ts, 0, 21), Decl(exportSpecifierAndExportedMemberDeclaration.ts, 5, 12))
|
||||
>I : Symbol(X.I, Decl(exportSpecifierAndExportedMemberDeclaration.ts, 1, 21))
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
=== tests/cases/compiler/exportSpecifierAndExportedMemberDeclaration.ts ===
|
||||
declare module "m2" {
|
||||
export module X {
|
||||
>X : () => any
|
||||
|
||||
interface I { }
|
||||
>I : I
|
||||
}
|
||||
function Y();
|
||||
>Y : () => any
|
||||
|
||||
export { Y as X };
|
||||
>Y : () => any
|
||||
>X : () => any
|
||||
|
||||
function Z(): X.I;
|
||||
>Z : () => X.I
|
||||
>X : any
|
||||
>I : X.I
|
||||
}
|
||||
|
||||
declare module "m2" {
|
||||
function Z2(): X.I;
|
||||
>Z2 : () => X.I
|
||||
>X : any
|
||||
>I : X.I
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
tests/cases/compiler/exportSpecifierAndLocalMemberDeclaration.ts(11,20): error TS2503: Cannot find namespace 'X'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/exportSpecifierAndLocalMemberDeclaration.ts (1 errors) ====
|
||||
declare module "m2" {
|
||||
module X {
|
||||
interface I { }
|
||||
}
|
||||
function Y();
|
||||
export { Y as X };
|
||||
function Z(): X.I;
|
||||
}
|
||||
|
||||
declare module "m2" {
|
||||
function Z2(): X.I;
|
||||
~
|
||||
!!! error TS2503: Cannot find namespace 'X'.
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
//// [exportSpecifierAndLocalMemberDeclaration.ts]
|
||||
declare module "m2" {
|
||||
module X {
|
||||
interface I { }
|
||||
}
|
||||
function Y();
|
||||
export { Y as X };
|
||||
function Z(): X.I;
|
||||
}
|
||||
|
||||
declare module "m2" {
|
||||
function Z2(): X.I;
|
||||
}
|
||||
|
||||
//// [exportSpecifierAndLocalMemberDeclaration.js]
|
|
@ -0,0 +1,8 @@
|
|||
//// [exportSpecifierReferencingOuterDeclaration1.ts]
|
||||
declare module X { export interface bar { } }
|
||||
declare module "m" {
|
||||
export { X };
|
||||
export function foo(): X.bar;
|
||||
}
|
||||
|
||||
//// [exportSpecifierReferencingOuterDeclaration1.js]
|
|
@ -0,0 +1,14 @@
|
|||
=== tests/cases/compiler/exportSpecifierReferencingOuterDeclaration1.ts ===
|
||||
declare module X { export interface bar { } }
|
||||
>X : Symbol(X, Decl(exportSpecifierReferencingOuterDeclaration1.ts, 0, 0))
|
||||
>bar : Symbol(bar, Decl(exportSpecifierReferencingOuterDeclaration1.ts, 0, 18))
|
||||
|
||||
declare module "m" {
|
||||
export { X };
|
||||
>X : Symbol(X, Decl(exportSpecifierReferencingOuterDeclaration1.ts, 2, 12))
|
||||
|
||||
export function foo(): X.bar;
|
||||
>foo : Symbol(foo, Decl(exportSpecifierReferencingOuterDeclaration1.ts, 2, 17))
|
||||
>X : Symbol(X, Decl(exportSpecifierReferencingOuterDeclaration1.ts, 0, 0))
|
||||
>bar : Symbol(X.bar, Decl(exportSpecifierReferencingOuterDeclaration1.ts, 0, 18))
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
=== tests/cases/compiler/exportSpecifierReferencingOuterDeclaration1.ts ===
|
||||
declare module X { export interface bar { } }
|
||||
>X : any
|
||||
>bar : bar
|
||||
|
||||
declare module "m" {
|
||||
export { X };
|
||||
>X : any
|
||||
|
||||
export function foo(): X.bar;
|
||||
>foo : () => X.bar
|
||||
>X : any
|
||||
>bar : X.bar
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
//// [tests/cases/compiler/exportSpecifierReferencingOuterDeclaration2.ts] ////
|
||||
|
||||
//// [exportSpecifierReferencingOuterDeclaration2_A.ts]
|
||||
declare module X { export interface bar { } }
|
||||
|
||||
//// [exportSpecifierReferencingOuterDeclaration2_B.ts]
|
||||
export { X };
|
||||
export declare function foo(): X.bar;
|
||||
|
||||
//// [exportSpecifierReferencingOuterDeclaration2_A.js]
|
||||
//// [exportSpecifierReferencingOuterDeclaration2_B.js]
|
|
@ -0,0 +1,14 @@
|
|||
=== tests/cases/compiler/exportSpecifierReferencingOuterDeclaration2_A.ts ===
|
||||
declare module X { export interface bar { } }
|
||||
>X : Symbol(X, Decl(exportSpecifierReferencingOuterDeclaration2_A.ts, 0, 0))
|
||||
>bar : Symbol(bar, Decl(exportSpecifierReferencingOuterDeclaration2_A.ts, 0, 18))
|
||||
|
||||
=== tests/cases/compiler/exportSpecifierReferencingOuterDeclaration2_B.ts ===
|
||||
export { X };
|
||||
>X : Symbol(X, Decl(exportSpecifierReferencingOuterDeclaration2_B.ts, 0, 8))
|
||||
|
||||
export declare function foo(): X.bar;
|
||||
>foo : Symbol(foo, Decl(exportSpecifierReferencingOuterDeclaration2_B.ts, 0, 13))
|
||||
>X : Symbol(X, Decl(exportSpecifierReferencingOuterDeclaration2_A.ts, 0, 0))
|
||||
>bar : Symbol(X.bar, Decl(exportSpecifierReferencingOuterDeclaration2_A.ts, 0, 18))
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
=== tests/cases/compiler/exportSpecifierReferencingOuterDeclaration2_A.ts ===
|
||||
declare module X { export interface bar { } }
|
||||
>X : any
|
||||
>bar : bar
|
||||
|
||||
=== tests/cases/compiler/exportSpecifierReferencingOuterDeclaration2_B.ts ===
|
||||
export { X };
|
||||
>X : any
|
||||
|
||||
export declare function foo(): X.bar;
|
||||
>foo : () => X.bar
|
||||
>X : any
|
||||
>bar : X.bar
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
tests/cases/compiler/exportSpecifierReferencingOuterDeclaration3.ts(6,30): error TS2305: Module 'X' has no exported member 'bar'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/exportSpecifierReferencingOuterDeclaration3.ts (1 errors) ====
|
||||
declare module X { export interface bar { } }
|
||||
declare module "m" {
|
||||
module X { export interface foo { } }
|
||||
export { X };
|
||||
export function foo(): X.foo;
|
||||
export function bar(): X.bar; // error
|
||||
~~~
|
||||
!!! error TS2305: Module 'X' has no exported member 'bar'.
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
//// [exportSpecifierReferencingOuterDeclaration3.ts]
|
||||
declare module X { export interface bar { } }
|
||||
declare module "m" {
|
||||
module X { export interface foo { } }
|
||||
export { X };
|
||||
export function foo(): X.foo;
|
||||
export function bar(): X.bar; // error
|
||||
}
|
||||
|
||||
//// [exportSpecifierReferencingOuterDeclaration3.js]
|
|
@ -0,0 +1,13 @@
|
|||
tests/cases/compiler/exportSpecifierReferencingOuterDeclaration2_B.ts(4,34): error TS2305: Module 'X' has no exported member 'bar'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/exportSpecifierReferencingOuterDeclaration2_A.ts (0 errors) ====
|
||||
declare module X { export interface bar { } }
|
||||
|
||||
==== tests/cases/compiler/exportSpecifierReferencingOuterDeclaration2_B.ts (1 errors) ====
|
||||
declare module X { export interface foo { } }
|
||||
export { X };
|
||||
export declare function foo(): X.foo;
|
||||
export declare function bar(): X.bar; // error
|
||||
~~~
|
||||
!!! error TS2305: Module 'X' has no exported member 'bar'.
|
|
@ -0,0 +1,13 @@
|
|||
//// [tests/cases/compiler/exportSpecifierReferencingOuterDeclaration4.ts] ////
|
||||
|
||||
//// [exportSpecifierReferencingOuterDeclaration2_A.ts]
|
||||
declare module X { export interface bar { } }
|
||||
|
||||
//// [exportSpecifierReferencingOuterDeclaration2_B.ts]
|
||||
declare module X { export interface foo { } }
|
||||
export { X };
|
||||
export declare function foo(): X.foo;
|
||||
export declare function bar(): X.bar; // error
|
||||
|
||||
//// [exportSpecifierReferencingOuterDeclaration2_A.js]
|
||||
//// [exportSpecifierReferencingOuterDeclaration2_B.js]
|
|
@ -0,0 +1,12 @@
|
|||
declare module "m2" {
|
||||
export module X {
|
||||
interface I { }
|
||||
}
|
||||
function Y();
|
||||
export { Y as X };
|
||||
function Z(): X.I;
|
||||
}
|
||||
|
||||
declare module "m2" {
|
||||
function Z2(): X.I;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
declare module "m2" {
|
||||
module X {
|
||||
interface I { }
|
||||
}
|
||||
function Y();
|
||||
export { Y as X };
|
||||
function Z(): X.I;
|
||||
}
|
||||
|
||||
declare module "m2" {
|
||||
function Z2(): X.I;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
declare module X { export interface bar { } }
|
||||
declare module "m" {
|
||||
export { X };
|
||||
export function foo(): X.bar;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
// @module: commonjs
|
||||
// @Filename: exportSpecifierReferencingOuterDeclaration2_A.ts
|
||||
declare module X { export interface bar { } }
|
||||
|
||||
// @Filename: exportSpecifierReferencingOuterDeclaration2_B.ts
|
||||
export { X };
|
||||
export declare function foo(): X.bar;
|
|
@ -0,0 +1,7 @@
|
|||
declare module X { export interface bar { } }
|
||||
declare module "m" {
|
||||
module X { export interface foo { } }
|
||||
export { X };
|
||||
export function foo(): X.foo;
|
||||
export function bar(): X.bar; // error
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
// @module: commonjs
|
||||
// @Filename: exportSpecifierReferencingOuterDeclaration2_A.ts
|
||||
declare module X { export interface bar { } }
|
||||
|
||||
// @Filename: exportSpecifierReferencingOuterDeclaration2_B.ts
|
||||
declare module X { export interface foo { } }
|
||||
export { X };
|
||||
export declare function foo(): X.foo;
|
||||
export declare function bar(): X.bar; // error
|
Loading…
Reference in a new issue