diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 65768332360..813a7e2cd43 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -130,7 +130,9 @@ namespace ts { symbol.members = {}; } - if (symbolFlags & SymbolFlags.Value && !symbol.valueDeclaration) { + if (symbolFlags & SymbolFlags.Value && + (!symbol.valueDeclaration || symbol.valueDeclaration.kind === SyntaxKind.ModuleDeclaration)) { + // other kinds of value declarations take precedence over modules symbol.valueDeclaration = node; } } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6c233a57ef4..d22266d951f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -293,7 +293,11 @@ namespace ts { target.constEnumOnlyModule = false; } target.flags |= source.flags; - if (!target.valueDeclaration && source.valueDeclaration) target.valueDeclaration = source.valueDeclaration; + if (source.valueDeclaration && + (!target.valueDeclaration || target.valueDeclaration.kind === SyntaxKind.ModuleDeclaration)) { + // other kinds of value declarations take precedence over modules + target.valueDeclaration = source.valueDeclaration; + } forEach(source.declarations, node => { target.declarations.push(node); }); @@ -2766,9 +2770,7 @@ namespace ts { } function getBaseTypeNodeOfClass(type: InterfaceType): ExpressionWithTypeArguments { - let classDeclaration = - getDeclarationOfKind(type.symbol, SyntaxKind.ClassDeclaration) || type.symbol.valueDeclaration; - return getClassExtendsHeritageClauseElement(classDeclaration as ClassLikeDeclaration); + return getClassExtendsHeritageClauseElement(type.symbol.valueDeclaration); } function getConstructorsForTypeArguments(type: ObjectType, typeArgumentNodes: TypeNode[]): Signature[] { diff --git a/tests/baselines/reference/ambientClassDeclarationWithExtends.js b/tests/baselines/reference/ambientClassDeclarationWithExtends.js index 5a31486bcf0..940efb8899f 100644 --- a/tests/baselines/reference/ambientClassDeclarationWithExtends.js +++ b/tests/baselines/reference/ambientClassDeclarationWithExtends.js @@ -1,4 +1,6 @@ -//// [ambientClassDeclarationWithExtends.ts] +//// [tests/cases/compiler/ambientClassDeclarationWithExtends.ts] //// + +//// [ambientClassDeclarationExtends_singleFile.ts] declare class A { } declare class B extends A { } @@ -10,10 +12,29 @@ declare class D extends C { } var d: C = new D(); +//// [ambientClassDeclarationExtends_file1.ts] + +declare class E { + public bar; +} +namespace F { var y; } -//// [ambientClassDeclarationWithExtends.js] +//// [ambientClassDeclarationExtends_file2.ts] + +declare class F extends E { } +var f: E = new F(); + + +//// [ambientClassDeclarationExtends_singleFile.js] var D; (function (D) { var x; })(D || (D = {})); var d = new D(); +//// [ambientClassDeclarationExtends_file1.js] +var F; +(function (F) { + var y; +})(F || (F = {})); +//// [ambientClassDeclarationExtends_file2.js] +var f = new F(); diff --git a/tests/baselines/reference/ambientClassDeclarationWithExtends.symbols b/tests/baselines/reference/ambientClassDeclarationWithExtends.symbols index ba678910a9c..023ae6bf582 100644 --- a/tests/baselines/reference/ambientClassDeclarationWithExtends.symbols +++ b/tests/baselines/reference/ambientClassDeclarationWithExtends.symbols @@ -1,27 +1,50 @@ -=== tests/cases/compiler/ambientClassDeclarationWithExtends.ts === +=== tests/cases/compiler/ambientClassDeclarationExtends_singleFile.ts === declare class A { } ->A : Symbol(A, Decl(ambientClassDeclarationWithExtends.ts, 0, 0)) +>A : Symbol(A, Decl(ambientClassDeclarationExtends_singleFile.ts, 0, 0)) declare class B extends A { } ->B : Symbol(B, Decl(ambientClassDeclarationWithExtends.ts, 0, 19)) ->A : Symbol(A, Decl(ambientClassDeclarationWithExtends.ts, 0, 0)) +>B : Symbol(B, Decl(ambientClassDeclarationExtends_singleFile.ts, 0, 19)) +>A : Symbol(A, Decl(ambientClassDeclarationExtends_singleFile.ts, 0, 0)) declare class C { ->C : Symbol(C, Decl(ambientClassDeclarationWithExtends.ts, 1, 29)) +>C : Symbol(C, Decl(ambientClassDeclarationExtends_singleFile.ts, 1, 29)) public foo; ->foo : Symbol(foo, Decl(ambientClassDeclarationWithExtends.ts, 3, 17)) +>foo : Symbol(foo, Decl(ambientClassDeclarationExtends_singleFile.ts, 3, 17)) } namespace D { var x; } ->D : Symbol(D, Decl(ambientClassDeclarationWithExtends.ts, 5, 1), Decl(ambientClassDeclarationWithExtends.ts, 6, 22)) ->x : Symbol(x, Decl(ambientClassDeclarationWithExtends.ts, 6, 17)) +>D : Symbol(D, Decl(ambientClassDeclarationExtends_singleFile.ts, 5, 1), Decl(ambientClassDeclarationExtends_singleFile.ts, 6, 22)) +>x : Symbol(x, Decl(ambientClassDeclarationExtends_singleFile.ts, 6, 17)) declare class D extends C { } ->D : Symbol(D, Decl(ambientClassDeclarationWithExtends.ts, 5, 1), Decl(ambientClassDeclarationWithExtends.ts, 6, 22)) ->C : Symbol(C, Decl(ambientClassDeclarationWithExtends.ts, 1, 29)) +>D : Symbol(D, Decl(ambientClassDeclarationExtends_singleFile.ts, 5, 1), Decl(ambientClassDeclarationExtends_singleFile.ts, 6, 22)) +>C : Symbol(C, Decl(ambientClassDeclarationExtends_singleFile.ts, 1, 29)) var d: C = new D(); ->d : Symbol(d, Decl(ambientClassDeclarationWithExtends.ts, 9, 3)) ->C : Symbol(C, Decl(ambientClassDeclarationWithExtends.ts, 1, 29)) ->D : Symbol(D, Decl(ambientClassDeclarationWithExtends.ts, 5, 1), Decl(ambientClassDeclarationWithExtends.ts, 6, 22)) +>d : Symbol(d, Decl(ambientClassDeclarationExtends_singleFile.ts, 9, 3)) +>C : Symbol(C, Decl(ambientClassDeclarationExtends_singleFile.ts, 1, 29)) +>D : Symbol(D, Decl(ambientClassDeclarationExtends_singleFile.ts, 5, 1), Decl(ambientClassDeclarationExtends_singleFile.ts, 6, 22)) + +=== tests/cases/compiler/ambientClassDeclarationExtends_file1.ts === + +declare class E { +>E : Symbol(E, Decl(ambientClassDeclarationExtends_file1.ts, 0, 0)) + + public bar; +>bar : Symbol(bar, Decl(ambientClassDeclarationExtends_file1.ts, 1, 17)) +} +namespace F { var y; } +>F : Symbol(F, Decl(ambientClassDeclarationExtends_file1.ts, 3, 1), Decl(ambientClassDeclarationExtends_file2.ts, 0, 0)) +>y : Symbol(y, Decl(ambientClassDeclarationExtends_file1.ts, 4, 17)) + +=== tests/cases/compiler/ambientClassDeclarationExtends_file2.ts === + +declare class F extends E { } +>F : Symbol(F, Decl(ambientClassDeclarationExtends_file1.ts, 3, 1), Decl(ambientClassDeclarationExtends_file2.ts, 0, 0)) +>E : Symbol(E, Decl(ambientClassDeclarationExtends_file1.ts, 0, 0)) + +var f: E = new F(); +>f : Symbol(f, Decl(ambientClassDeclarationExtends_file2.ts, 2, 3)) +>E : Symbol(E, Decl(ambientClassDeclarationExtends_file1.ts, 0, 0)) +>F : Symbol(F, Decl(ambientClassDeclarationExtends_file1.ts, 3, 1), Decl(ambientClassDeclarationExtends_file2.ts, 0, 0)) diff --git a/tests/baselines/reference/ambientClassDeclarationWithExtends.types b/tests/baselines/reference/ambientClassDeclarationWithExtends.types index 528496e753d..c7f22eeb65f 100644 --- a/tests/baselines/reference/ambientClassDeclarationWithExtends.types +++ b/tests/baselines/reference/ambientClassDeclarationWithExtends.types @@ -1,4 +1,4 @@ -=== tests/cases/compiler/ambientClassDeclarationWithExtends.ts === +=== tests/cases/compiler/ambientClassDeclarationExtends_singleFile.ts === declare class A { } >A : A @@ -26,3 +26,27 @@ var d: C = new D(); >new D() : D >D : typeof D +=== tests/cases/compiler/ambientClassDeclarationExtends_file1.ts === + +declare class E { +>E : E + + public bar; +>bar : any +} +namespace F { var y; } +>F : typeof F +>y : any + +=== tests/cases/compiler/ambientClassDeclarationExtends_file2.ts === + +declare class F extends E { } +>F : F +>E : E + +var f: E = new F(); +>f : E +>E : E +>new F() : F +>F : typeof F + diff --git a/tests/cases/compiler/ambientClassDeclarationWithExtends.ts b/tests/cases/compiler/ambientClassDeclarationWithExtends.ts index 554a436c5ef..ca26f1b2a44 100644 --- a/tests/cases/compiler/ambientClassDeclarationWithExtends.ts +++ b/tests/cases/compiler/ambientClassDeclarationWithExtends.ts @@ -1,3 +1,4 @@ +// @Filename: ambientClassDeclarationExtends_singleFile.ts declare class A { } declare class B extends A { } @@ -8,3 +9,15 @@ namespace D { var x; } declare class D extends C { } var d: C = new D(); + +// @Filename: ambientClassDeclarationExtends_file1.ts + +declare class E { + public bar; +} +namespace F { var y; } + +// @Filename: ambientClassDeclarationExtends_file2.ts + +declare class F extends E { } +var f: E = new F();