Skip to content

Commit 2f0e341

Browse files
authored
Merge pull request microsoft#15740 from Microsoft/emit-expression-in-extends-nested
Correctly emit expression in extends in namespace
2 parents 8321b81 + 1225c4e commit 2f0e341

5 files changed

+163
-8
lines changed

src/compiler/declarationEmitter.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ namespace ts {
6767
let errorNameNode: DeclarationName;
6868
const emitJsDocComments = compilerOptions.removeComments ? noop : writeJsDocComments;
6969
const emit = compilerOptions.stripInternal ? stripInternal : emitNode;
70-
let noDeclare: boolean;
70+
let needsDeclare = true;
7171

7272
let moduleElementDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[] = [];
7373
let asynchronousSubModuleDeclarationEmitInfo: ModuleElementDeclarationEmitInfo[];
@@ -110,11 +110,11 @@ namespace ts {
110110

111111
resultHasExternalModuleIndicator = false;
112112
if (!isBundledEmit || !isExternalModule(sourceFile)) {
113-
noDeclare = false;
113+
needsDeclare = true;
114114
emitSourceFile(sourceFile);
115115
}
116116
else if (isExternalModule(sourceFile)) {
117-
noDeclare = true;
117+
needsDeclare = false;
118118
write(`declare module "${getResolvedExternalModuleName(host, sourceFile)}" {`);
119119
writeLine();
120120
increaseIndent();
@@ -612,9 +612,9 @@ namespace ts {
612612
}
613613
}
614614

615-
function emitTempVariableDeclaration(expr: Expression, baseName: string, diagnostic: SymbolAccessibilityDiagnostic): string {
615+
function emitTempVariableDeclaration(expr: Expression, baseName: string, diagnostic: SymbolAccessibilityDiagnostic, needsDeclare: boolean): string {
616616
const tempVarName = getExportTempVariableName(baseName);
617-
if (!noDeclare) {
617+
if (needsDeclare) {
618618
write("declare ");
619619
}
620620
write("const ");
@@ -636,7 +636,7 @@ namespace ts {
636636
const tempVarName = emitTempVariableDeclaration(node.expression, "_default", {
637637
diagnosticMessage: Diagnostics.Default_export_of_the_module_has_or_is_using_private_name_0,
638638
errorNode: node
639-
});
639+
}, needsDeclare);
640640
write(node.isExportEquals ? "export = " : "export default ");
641641
write(tempVarName);
642642
}
@@ -728,7 +728,7 @@ namespace ts {
728728
if (modifiers & ModifierFlags.Default) {
729729
write("default ");
730730
}
731-
else if (node.kind !== SyntaxKind.InterfaceDeclaration && !noDeclare) {
731+
else if (node.kind !== SyntaxKind.InterfaceDeclaration && needsDeclare) {
732732
write("declare ");
733733
}
734734
}
@@ -1155,7 +1155,7 @@ namespace ts {
11551155
diagnosticMessage: Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1,
11561156
errorNode: baseTypeNode,
11571157
typeName: node.name
1158-
});
1158+
}, !findAncestor(node, n => n.kind === SyntaxKind.ModuleDeclaration));
11591159
}
11601160

11611161
emitJsDocComments(node);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//// [declarationEmitExpressionInExtends5.ts]
2+
namespace Test
3+
{
4+
export interface IFace
5+
{
6+
}
7+
8+
export class SomeClass implements IFace
9+
{
10+
}
11+
12+
export class Derived extends getClass<IFace>()
13+
{
14+
}
15+
16+
export function getClass<T>() : new() => T
17+
{
18+
return SomeClass as (new() => T);
19+
}
20+
}
21+
22+
23+
//// [declarationEmitExpressionInExtends5.js]
24+
var __extends = (this && this.__extends) || (function () {
25+
var extendStatics = Object.setPrototypeOf ||
26+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
27+
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
28+
return function (d, b) {
29+
extendStatics(d, b);
30+
function __() { this.constructor = d; }
31+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
32+
};
33+
})();
34+
var Test;
35+
(function (Test) {
36+
var SomeClass = (function () {
37+
function SomeClass() {
38+
}
39+
return SomeClass;
40+
}());
41+
Test.SomeClass = SomeClass;
42+
var Derived = (function (_super) {
43+
__extends(Derived, _super);
44+
function Derived() {
45+
return _super !== null && _super.apply(this, arguments) || this;
46+
}
47+
return Derived;
48+
}(getClass()));
49+
Test.Derived = Derived;
50+
function getClass() {
51+
return SomeClass;
52+
}
53+
Test.getClass = getClass;
54+
})(Test || (Test = {}));
55+
56+
57+
//// [declarationEmitExpressionInExtends5.d.ts]
58+
declare namespace Test {
59+
interface IFace {
60+
}
61+
class SomeClass implements IFace {
62+
}
63+
const Derived_base: new () => IFace;
64+
class Derived extends Derived_base {
65+
}
66+
function getClass<T>(): new () => T;
67+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
=== tests/cases/compiler/declarationEmitExpressionInExtends5.ts ===
2+
namespace Test
3+
>Test : Symbol(Test, Decl(declarationEmitExpressionInExtends5.ts, 0, 0))
4+
{
5+
export interface IFace
6+
>IFace : Symbol(IFace, Decl(declarationEmitExpressionInExtends5.ts, 1, 1))
7+
{
8+
}
9+
10+
export class SomeClass implements IFace
11+
>SomeClass : Symbol(SomeClass, Decl(declarationEmitExpressionInExtends5.ts, 4, 2))
12+
>IFace : Symbol(IFace, Decl(declarationEmitExpressionInExtends5.ts, 1, 1))
13+
{
14+
}
15+
16+
export class Derived extends getClass<IFace>()
17+
>Derived : Symbol(Derived, Decl(declarationEmitExpressionInExtends5.ts, 8, 2))
18+
>getClass : Symbol(getClass, Decl(declarationEmitExpressionInExtends5.ts, 12, 2))
19+
>IFace : Symbol(IFace, Decl(declarationEmitExpressionInExtends5.ts, 1, 1))
20+
{
21+
}
22+
23+
export function getClass<T>() : new() => T
24+
>getClass : Symbol(getClass, Decl(declarationEmitExpressionInExtends5.ts, 12, 2))
25+
>T : Symbol(T, Decl(declarationEmitExpressionInExtends5.ts, 14, 26))
26+
>T : Symbol(T, Decl(declarationEmitExpressionInExtends5.ts, 14, 26))
27+
{
28+
return SomeClass as (new() => T);
29+
>SomeClass : Symbol(SomeClass, Decl(declarationEmitExpressionInExtends5.ts, 4, 2))
30+
>T : Symbol(T, Decl(declarationEmitExpressionInExtends5.ts, 14, 26))
31+
}
32+
}
33+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
=== tests/cases/compiler/declarationEmitExpressionInExtends5.ts ===
2+
namespace Test
3+
>Test : typeof Test
4+
{
5+
export interface IFace
6+
>IFace : IFace
7+
{
8+
}
9+
10+
export class SomeClass implements IFace
11+
>SomeClass : SomeClass
12+
>IFace : IFace
13+
{
14+
}
15+
16+
export class Derived extends getClass<IFace>()
17+
>Derived : Derived
18+
>getClass<IFace>() : IFace
19+
>getClass : <T>() => new () => T
20+
>IFace : IFace
21+
{
22+
}
23+
24+
export function getClass<T>() : new() => T
25+
>getClass : <T>() => new () => T
26+
>T : T
27+
>T : T
28+
{
29+
return SomeClass as (new() => T);
30+
>SomeClass as (new() => T) : new () => T
31+
>SomeClass : typeof SomeClass
32+
>T : T
33+
}
34+
}
35+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// @declaration: true
2+
namespace Test
3+
{
4+
export interface IFace
5+
{
6+
}
7+
8+
export class SomeClass implements IFace
9+
{
10+
}
11+
12+
export class Derived extends getClass<IFace>()
13+
{
14+
}
15+
16+
export function getClass<T>() : new() => T
17+
{
18+
return SomeClass as (new() => T);
19+
}
20+
}

0 commit comments

Comments
 (0)