Skip to content

Commit a535460

Browse files
committed
Merge pull request #7392 from Microsoft/declarationEmitFixes
Declaration emit fixes
2 parents 311f8dd + 1564049 commit a535460

28 files changed

+739
-3
lines changed

src/compiler/checker.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1642,7 +1642,7 @@ namespace ts {
16421642
function isEntityNameVisible(entityName: EntityName | Expression, enclosingDeclaration: Node): SymbolVisibilityResult {
16431643
// get symbol of the first identifier of the entityName
16441644
let meaning: SymbolFlags;
1645-
if (entityName.parent.kind === SyntaxKind.TypeQuery) {
1645+
if (entityName.parent.kind === SyntaxKind.TypeQuery || isExpressionWithTypeArgumentsInClassExtendsClause(entityName.parent)) {
16461646
// Typeof value
16471647
meaning = SymbolFlags.Value | SymbolFlags.ExportValue;
16481648
}
@@ -2429,7 +2429,7 @@ namespace ts {
24292429
return false;
24302430

24312431
default:
2432-
Debug.fail("isDeclarationVisible unknown: SyntaxKind: " + node.kind);
2432+
return false;
24332433
}
24342434
}
24352435
}
@@ -16250,10 +16250,17 @@ namespace ts {
1625016250
}
1625116251

1625216252
function writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter) {
16253-
const type = getTypeOfExpression(expr);
16253+
const type = getWidenedType(getTypeOfExpression(expr));
1625416254
getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags);
1625516255
}
1625616256

16257+
function writeBaseConstructorTypeOfClass(node: ClassLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter) {
16258+
const classType = <InterfaceType>getDeclaredTypeOfSymbol(getSymbolOfNode(node));
16259+
resolveBaseTypesOfClass(classType);
16260+
const baseType = classType.resolvedBaseTypes.length ? classType.resolvedBaseTypes[0] : unknownType;
16261+
getSymbolDisplayBuilder().buildTypeDisplay(baseType, writer, enclosingDeclaration, flags);
16262+
}
16263+
1625716264
function hasGlobalName(name: string): boolean {
1625816265
return hasProperty(globals, name);
1625916266
}
@@ -16286,6 +16293,7 @@ namespace ts {
1628616293
writeTypeOfDeclaration,
1628716294
writeReturnTypeOfSignatureDeclaration,
1628816295
writeTypeOfExpression,
16296+
writeBaseConstructorTypeOfClass,
1628916297
isSymbolAccessible,
1629016298
isEntityNameVisible,
1629116299
getConstantValue,

src/compiler/declarationEmitter.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -987,6 +987,10 @@ namespace ts {
987987
else if (!isImplementsList && node.expression.kind === SyntaxKind.NullKeyword) {
988988
write("null");
989989
}
990+
else {
991+
writer.getSymbolAccessibilityDiagnostic = getHeritageClauseVisibilityError;
992+
resolver.writeBaseConstructorTypeOfClass(<ClassLikeDeclaration>enclosingDeclaration, enclosingDeclaration, TypeFormatFlags.UseTypeOfFunction, writer);
993+
}
990994

991995
function getHeritageClauseVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic {
992996
let diagnosticMessage: DiagnosticMessage;

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1889,6 +1889,7 @@ namespace ts {
18891889
writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
18901890
writeReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
18911891
writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
1892+
writeBaseConstructorTypeOfClass(node: ClassLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
18921893
isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags): SymbolAccessibilityResult;
18931894
isEntityNameVisible(entityName: EntityName | Expression, enclosingDeclaration: Node): SymbolVisibilityResult;
18941895
// Returns the constant value this property access resolves to, or 'undefined' for a non-constant
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//// [declarationEmit_expressionInExtends.ts]
2+
3+
var x: {
4+
new<T>(s: any): Q;
5+
}
6+
7+
class Q {
8+
s: string;
9+
}
10+
11+
class B extends x<string> {
12+
}
13+
14+
var q: B;
15+
q.s;
16+
17+
//// [declarationEmit_expressionInExtends.js]
18+
var __extends = (this && this.__extends) || function (d, b) {
19+
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
20+
function __() { this.constructor = d; }
21+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
22+
};
23+
var x;
24+
var Q = (function () {
25+
function Q() {
26+
}
27+
return Q;
28+
}());
29+
var B = (function (_super) {
30+
__extends(B, _super);
31+
function B() {
32+
_super.apply(this, arguments);
33+
}
34+
return B;
35+
}(x));
36+
var q;
37+
q.s;
38+
39+
40+
//// [declarationEmit_expressionInExtends.d.ts]
41+
declare var x: {
42+
new <T>(s: any): Q;
43+
};
44+
declare class Q {
45+
s: string;
46+
}
47+
declare class B extends x<string> {
48+
}
49+
declare var q: B;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
=== tests/cases/compiler/declarationEmit_expressionInExtends.ts ===
2+
3+
var x: {
4+
>x : Symbol(x, Decl(declarationEmit_expressionInExtends.ts, 1, 3))
5+
6+
new<T>(s: any): Q;
7+
>T : Symbol(T, Decl(declarationEmit_expressionInExtends.ts, 2, 8))
8+
>s : Symbol(s, Decl(declarationEmit_expressionInExtends.ts, 2, 11))
9+
>Q : Symbol(Q, Decl(declarationEmit_expressionInExtends.ts, 3, 1))
10+
}
11+
12+
class Q {
13+
>Q : Symbol(Q, Decl(declarationEmit_expressionInExtends.ts, 3, 1))
14+
15+
s: string;
16+
>s : Symbol(s, Decl(declarationEmit_expressionInExtends.ts, 5, 9))
17+
}
18+
19+
class B extends x<string> {
20+
>B : Symbol(B, Decl(declarationEmit_expressionInExtends.ts, 7, 1))
21+
>x : Symbol(x, Decl(declarationEmit_expressionInExtends.ts, 1, 3))
22+
}
23+
24+
var q: B;
25+
>q : Symbol(q, Decl(declarationEmit_expressionInExtends.ts, 12, 3))
26+
>B : Symbol(B, Decl(declarationEmit_expressionInExtends.ts, 7, 1))
27+
28+
q.s;
29+
>q.s : Symbol(Q.s, Decl(declarationEmit_expressionInExtends.ts, 5, 9))
30+
>q : Symbol(q, Decl(declarationEmit_expressionInExtends.ts, 12, 3))
31+
>s : Symbol(Q.s, Decl(declarationEmit_expressionInExtends.ts, 5, 9))
32+
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
=== tests/cases/compiler/declarationEmit_expressionInExtends.ts ===
2+
3+
var x: {
4+
>x : new <T>(s: any) => Q
5+
6+
new<T>(s: any): Q;
7+
>T : T
8+
>s : any
9+
>Q : Q
10+
}
11+
12+
class Q {
13+
>Q : Q
14+
15+
s: string;
16+
>s : string
17+
}
18+
19+
class B extends x<string> {
20+
>B : B
21+
>x : Q
22+
}
23+
24+
var q: B;
25+
>q : B
26+
>B : B
27+
28+
q.s;
29+
>q.s : string
30+
>q : B
31+
>s : string
32+
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//// [declarationEmit_expressionInExtends2.ts]
2+
3+
class C<T, U> {
4+
x: T;
5+
y: U;
6+
}
7+
8+
function getClass<T>(c: T) {
9+
return C;
10+
}
11+
12+
class MyClass extends getClass(2) <string, number> {
13+
}
14+
15+
//// [declarationEmit_expressionInExtends2.js]
16+
var __extends = (this && this.__extends) || function (d, b) {
17+
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
18+
function __() { this.constructor = d; }
19+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
20+
};
21+
var C = (function () {
22+
function C() {
23+
}
24+
return C;
25+
}());
26+
function getClass(c) {
27+
return C;
28+
}
29+
var MyClass = (function (_super) {
30+
__extends(MyClass, _super);
31+
function MyClass() {
32+
_super.apply(this, arguments);
33+
}
34+
return MyClass;
35+
}(getClass(2)));
36+
37+
38+
//// [declarationEmit_expressionInExtends2.d.ts]
39+
declare class C<T, U> {
40+
x: T;
41+
y: U;
42+
}
43+
declare function getClass<T>(c: T): typeof C;
44+
declare class MyClass extends C<string, number> {
45+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
=== tests/cases/compiler/declarationEmit_expressionInExtends2.ts ===
2+
3+
class C<T, U> {
4+
>C : Symbol(C, Decl(declarationEmit_expressionInExtends2.ts, 0, 0))
5+
>T : Symbol(T, Decl(declarationEmit_expressionInExtends2.ts, 1, 8))
6+
>U : Symbol(U, Decl(declarationEmit_expressionInExtends2.ts, 1, 10))
7+
8+
x: T;
9+
>x : Symbol(x, Decl(declarationEmit_expressionInExtends2.ts, 1, 15))
10+
>T : Symbol(T, Decl(declarationEmit_expressionInExtends2.ts, 1, 8))
11+
12+
y: U;
13+
>y : Symbol(y, Decl(declarationEmit_expressionInExtends2.ts, 2, 9))
14+
>U : Symbol(U, Decl(declarationEmit_expressionInExtends2.ts, 1, 10))
15+
}
16+
17+
function getClass<T>(c: T) {
18+
>getClass : Symbol(getClass, Decl(declarationEmit_expressionInExtends2.ts, 4, 1))
19+
>T : Symbol(T, Decl(declarationEmit_expressionInExtends2.ts, 6, 18))
20+
>c : Symbol(c, Decl(declarationEmit_expressionInExtends2.ts, 6, 21))
21+
>T : Symbol(T, Decl(declarationEmit_expressionInExtends2.ts, 6, 18))
22+
23+
return C;
24+
>C : Symbol(C, Decl(declarationEmit_expressionInExtends2.ts, 0, 0))
25+
}
26+
27+
class MyClass extends getClass(2) <string, number> {
28+
>MyClass : Symbol(MyClass, Decl(declarationEmit_expressionInExtends2.ts, 8, 1))
29+
>getClass : Symbol(getClass, Decl(declarationEmit_expressionInExtends2.ts, 4, 1))
30+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
=== tests/cases/compiler/declarationEmit_expressionInExtends2.ts ===
2+
3+
class C<T, U> {
4+
>C : C<T, U>
5+
>T : T
6+
>U : U
7+
8+
x: T;
9+
>x : T
10+
>T : T
11+
12+
y: U;
13+
>y : U
14+
>U : U
15+
}
16+
17+
function getClass<T>(c: T) {
18+
>getClass : <T>(c: T) => typeof C
19+
>T : T
20+
>c : T
21+
>T : T
22+
23+
return C;
24+
>C : typeof C
25+
}
26+
27+
class MyClass extends getClass(2) <string, number> {
28+
>MyClass : MyClass
29+
>getClass(2) : C<string, number>
30+
>getClass : <T>(c: T) => typeof C
31+
>2 : number
32+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
tests/cases/compiler/declarationEmit_expressionInExtends3.ts(29,30): error TS4020: Extends clause of exported class 'MyClass' has or is using private name 'LocalClass'.
2+
tests/cases/compiler/declarationEmit_expressionInExtends3.ts(37,31): error TS4020: Extends clause of exported class 'MyClass3' has or is using private name 'LocalInterface'.
3+
4+
5+
==== tests/cases/compiler/declarationEmit_expressionInExtends3.ts (2 errors) ====
6+
7+
export class ExportedClass<T> {
8+
x: T;
9+
}
10+
11+
class LocalClass<T, U> {
12+
x: T;
13+
y: U;
14+
}
15+
16+
export interface ExportedInterface {
17+
x: number;
18+
}
19+
20+
interface LocalInterface {
21+
x: number;
22+
}
23+
24+
function getLocalClass<T>(c: T) {
25+
return LocalClass;
26+
}
27+
28+
function getExportedClass<T>(c: T) {
29+
return ExportedClass;
30+
}
31+
32+
33+
34+
export class MyClass extends getLocalClass<LocalInterface>(undefined)<string, number> { // error LocalClass is inaccisible
35+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
36+
!!! error TS4020: Extends clause of exported class 'MyClass' has or is using private name 'LocalClass'.
37+
}
38+
39+
40+
export class MyClass2 extends getExportedClass<LocalInterface>(undefined)<string> { // OK
41+
}
42+
43+
44+
export class MyClass3 extends getExportedClass<LocalInterface>(undefined)<LocalInterface> { // Error LocalInterface is inaccisble
45+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
46+
!!! error TS4020: Extends clause of exported class 'MyClass3' has or is using private name 'LocalInterface'.
47+
}
48+
49+
50+
export class MyClass4 extends getExportedClass<LocalInterface>(undefined)<ExportedInterface> { // OK
51+
}
52+

0 commit comments

Comments
 (0)