From baa040115e4855d7c61223f7a0937113e15282c0 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Thu, 3 Mar 2016 15:42:47 -0800 Subject: [PATCH 1/5] Fix #7173: Widen the type do the defualt export expression before writing it out. --- src/compiler/checker.ts | 2 +- ...eclarationEmit_inferedDefaultExportType.js | 26 +++++++++++++++++++ ...ationEmit_inferedDefaultExportType.symbols | 14 ++++++++++ ...arationEmit_inferedDefaultExportType.types | 18 +++++++++++++ ...clarationEmit_inferedDefaultExportType2.js | 25 ++++++++++++++++++ ...tionEmit_inferedDefaultExportType2.symbols | 14 ++++++++++ ...rationEmit_inferedDefaultExportType2.types | 18 +++++++++++++ ...eclarationEmit_inferedDefaultExportType.ts | 9 +++++++ ...clarationEmit_inferedDefaultExportType2.ts | 9 +++++++ 9 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/declarationEmit_inferedDefaultExportType.js create mode 100644 tests/baselines/reference/declarationEmit_inferedDefaultExportType.symbols create mode 100644 tests/baselines/reference/declarationEmit_inferedDefaultExportType.types create mode 100644 tests/baselines/reference/declarationEmit_inferedDefaultExportType2.js create mode 100644 tests/baselines/reference/declarationEmit_inferedDefaultExportType2.symbols create mode 100644 tests/baselines/reference/declarationEmit_inferedDefaultExportType2.types create mode 100644 tests/cases/compiler/declarationEmit_inferedDefaultExportType.ts create mode 100644 tests/cases/compiler/declarationEmit_inferedDefaultExportType2.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b56033e42ea..a55f17f8aac 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16240,7 +16240,7 @@ namespace ts { } function writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter) { - const type = getTypeOfExpression(expr); + const type = getWidenedType(getTypeOfExpression(expr)); getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags); } diff --git a/tests/baselines/reference/declarationEmit_inferedDefaultExportType.js b/tests/baselines/reference/declarationEmit_inferedDefaultExportType.js new file mode 100644 index 00000000000..ee80738a269 --- /dev/null +++ b/tests/baselines/reference/declarationEmit_inferedDefaultExportType.js @@ -0,0 +1,26 @@ +//// [declarationEmit_inferedDefaultExportType.ts] + +// test.ts +export default { + foo: [], + bar: undefined, + baz: null +} + +//// [declarationEmit_inferedDefaultExportType.js] +"use strict"; +exports.__esModule = true; +exports["default"] = { + foo: [], + bar: undefined, + baz: null +}; + + +//// [declarationEmit_inferedDefaultExportType.d.ts] +declare var _default: { + foo: any[]; + bar: any; + baz: any; +}; +export default _default; diff --git a/tests/baselines/reference/declarationEmit_inferedDefaultExportType.symbols b/tests/baselines/reference/declarationEmit_inferedDefaultExportType.symbols new file mode 100644 index 00000000000..7e8cdea2c75 --- /dev/null +++ b/tests/baselines/reference/declarationEmit_inferedDefaultExportType.symbols @@ -0,0 +1,14 @@ +=== tests/cases/compiler/declarationEmit_inferedDefaultExportType.ts === + +// test.ts +export default { + foo: [], +>foo : Symbol(foo, Decl(declarationEmit_inferedDefaultExportType.ts, 2, 16)) + + bar: undefined, +>bar : Symbol(bar, Decl(declarationEmit_inferedDefaultExportType.ts, 3, 10)) +>undefined : Symbol(undefined) + + baz: null +>baz : Symbol(baz, Decl(declarationEmit_inferedDefaultExportType.ts, 4, 17)) +} diff --git a/tests/baselines/reference/declarationEmit_inferedDefaultExportType.types b/tests/baselines/reference/declarationEmit_inferedDefaultExportType.types new file mode 100644 index 00000000000..0f5d0ceed91 --- /dev/null +++ b/tests/baselines/reference/declarationEmit_inferedDefaultExportType.types @@ -0,0 +1,18 @@ +=== tests/cases/compiler/declarationEmit_inferedDefaultExportType.ts === + +// test.ts +export default { +>{ foo: [], bar: undefined, baz: null} : { foo: undefined[]; bar: undefined; baz: null; } + + foo: [], +>foo : undefined[] +>[] : undefined[] + + bar: undefined, +>bar : undefined +>undefined : undefined + + baz: null +>baz : null +>null : null +} diff --git a/tests/baselines/reference/declarationEmit_inferedDefaultExportType2.js b/tests/baselines/reference/declarationEmit_inferedDefaultExportType2.js new file mode 100644 index 00000000000..617d4a9966b --- /dev/null +++ b/tests/baselines/reference/declarationEmit_inferedDefaultExportType2.js @@ -0,0 +1,25 @@ +//// [declarationEmit_inferedDefaultExportType2.ts] + +// test.ts +export = { + foo: [], + bar: undefined, + baz: null +} + +//// [declarationEmit_inferedDefaultExportType2.js] +"use strict"; +module.exports = { + foo: [], + bar: undefined, + baz: null +}; + + +//// [declarationEmit_inferedDefaultExportType2.d.ts] +declare var _default: { + foo: any[]; + bar: any; + baz: any; +}; +export = _default; diff --git a/tests/baselines/reference/declarationEmit_inferedDefaultExportType2.symbols b/tests/baselines/reference/declarationEmit_inferedDefaultExportType2.symbols new file mode 100644 index 00000000000..d04c50c0d7c --- /dev/null +++ b/tests/baselines/reference/declarationEmit_inferedDefaultExportType2.symbols @@ -0,0 +1,14 @@ +=== tests/cases/compiler/declarationEmit_inferedDefaultExportType2.ts === + +// test.ts +export = { + foo: [], +>foo : Symbol(foo, Decl(declarationEmit_inferedDefaultExportType2.ts, 2, 10)) + + bar: undefined, +>bar : Symbol(bar, Decl(declarationEmit_inferedDefaultExportType2.ts, 3, 10)) +>undefined : Symbol(undefined) + + baz: null +>baz : Symbol(baz, Decl(declarationEmit_inferedDefaultExportType2.ts, 4, 17)) +} diff --git a/tests/baselines/reference/declarationEmit_inferedDefaultExportType2.types b/tests/baselines/reference/declarationEmit_inferedDefaultExportType2.types new file mode 100644 index 00000000000..5c8cbbb158c --- /dev/null +++ b/tests/baselines/reference/declarationEmit_inferedDefaultExportType2.types @@ -0,0 +1,18 @@ +=== tests/cases/compiler/declarationEmit_inferedDefaultExportType2.ts === + +// test.ts +export = { +>{ foo: [], bar: undefined, baz: null} : { foo: undefined[]; bar: undefined; baz: null; } + + foo: [], +>foo : undefined[] +>[] : undefined[] + + bar: undefined, +>bar : undefined +>undefined : undefined + + baz: null +>baz : null +>null : null +} diff --git a/tests/cases/compiler/declarationEmit_inferedDefaultExportType.ts b/tests/cases/compiler/declarationEmit_inferedDefaultExportType.ts new file mode 100644 index 00000000000..3c3adc1af2f --- /dev/null +++ b/tests/cases/compiler/declarationEmit_inferedDefaultExportType.ts @@ -0,0 +1,9 @@ +// @declaration: true +// @module: commonjs + +// test.ts +export default { + foo: [], + bar: undefined, + baz: null +} \ No newline at end of file diff --git a/tests/cases/compiler/declarationEmit_inferedDefaultExportType2.ts b/tests/cases/compiler/declarationEmit_inferedDefaultExportType2.ts new file mode 100644 index 00000000000..274996cbe12 --- /dev/null +++ b/tests/cases/compiler/declarationEmit_inferedDefaultExportType2.ts @@ -0,0 +1,9 @@ +// @declaration: true +// @module: commonjs + +// test.ts +export = { + foo: [], + bar: undefined, + baz: null +} \ No newline at end of file From c98c76324375a02cf9af56a68fd6ace1287c41b9 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Thu, 3 Mar 2016 21:47:11 -0800 Subject: [PATCH 2/5] Fix #5651: Get the correct meaning for expressions in extends clauses --- src/compiler/checker.ts | 2 +- .../declarationEmit_expressionInExtends.js | 49 +++++++++++++++++++ ...eclarationEmit_expressionInExtends.symbols | 32 ++++++++++++ .../declarationEmit_expressionInExtends.types | 32 ++++++++++++ .../declarationEmit_expressionInExtends.ts | 15 ++++++ 5 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/declarationEmit_expressionInExtends.js create mode 100644 tests/baselines/reference/declarationEmit_expressionInExtends.symbols create mode 100644 tests/baselines/reference/declarationEmit_expressionInExtends.types create mode 100644 tests/cases/compiler/declarationEmit_expressionInExtends.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a55f17f8aac..041ea6dbfd6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1642,7 +1642,7 @@ namespace ts { function isEntityNameVisible(entityName: EntityName | Expression, enclosingDeclaration: Node): SymbolVisibilityResult { // get symbol of the first identifier of the entityName let meaning: SymbolFlags; - if (entityName.parent.kind === SyntaxKind.TypeQuery) { + if (entityName.parent.kind === SyntaxKind.TypeQuery || isExpressionWithTypeArgumentsInClassExtendsClause(entityName.parent)) { // Typeof value meaning = SymbolFlags.Value | SymbolFlags.ExportValue; } diff --git a/tests/baselines/reference/declarationEmit_expressionInExtends.js b/tests/baselines/reference/declarationEmit_expressionInExtends.js new file mode 100644 index 00000000000..061042aa34b --- /dev/null +++ b/tests/baselines/reference/declarationEmit_expressionInExtends.js @@ -0,0 +1,49 @@ +//// [declarationEmit_expressionInExtends.ts] + +var x: { + new(s: any): Q; +} + +class Q { + s: string; +} + +class B extends x { +} + +var q: B; +q.s; + +//// [declarationEmit_expressionInExtends.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var x; +var Q = (function () { + function Q() { + } + return Q; +}()); +var B = (function (_super) { + __extends(B, _super); + function B() { + _super.apply(this, arguments); + } + return B; +}(x)); +var q; +q.s; + + +//// [declarationEmit_expressionInExtends.d.ts] +declare var x: { + new (s: any): Q; +}; +declare class Q { + s: string; +} +declare class B extends x { +} +declare var q: B; diff --git a/tests/baselines/reference/declarationEmit_expressionInExtends.symbols b/tests/baselines/reference/declarationEmit_expressionInExtends.symbols new file mode 100644 index 00000000000..2120ad4ddde --- /dev/null +++ b/tests/baselines/reference/declarationEmit_expressionInExtends.symbols @@ -0,0 +1,32 @@ +=== tests/cases/compiler/declarationEmit_expressionInExtends.ts === + +var x: { +>x : Symbol(x, Decl(declarationEmit_expressionInExtends.ts, 1, 3)) + + new(s: any): Q; +>T : Symbol(T, Decl(declarationEmit_expressionInExtends.ts, 2, 8)) +>s : Symbol(s, Decl(declarationEmit_expressionInExtends.ts, 2, 11)) +>Q : Symbol(Q, Decl(declarationEmit_expressionInExtends.ts, 3, 1)) +} + +class Q { +>Q : Symbol(Q, Decl(declarationEmit_expressionInExtends.ts, 3, 1)) + + s: string; +>s : Symbol(s, Decl(declarationEmit_expressionInExtends.ts, 5, 9)) +} + +class B extends x { +>B : Symbol(B, Decl(declarationEmit_expressionInExtends.ts, 7, 1)) +>x : Symbol(x, Decl(declarationEmit_expressionInExtends.ts, 1, 3)) +} + +var q: B; +>q : Symbol(q, Decl(declarationEmit_expressionInExtends.ts, 12, 3)) +>B : Symbol(B, Decl(declarationEmit_expressionInExtends.ts, 7, 1)) + +q.s; +>q.s : Symbol(Q.s, Decl(declarationEmit_expressionInExtends.ts, 5, 9)) +>q : Symbol(q, Decl(declarationEmit_expressionInExtends.ts, 12, 3)) +>s : Symbol(Q.s, Decl(declarationEmit_expressionInExtends.ts, 5, 9)) + diff --git a/tests/baselines/reference/declarationEmit_expressionInExtends.types b/tests/baselines/reference/declarationEmit_expressionInExtends.types new file mode 100644 index 00000000000..2e810fccf68 --- /dev/null +++ b/tests/baselines/reference/declarationEmit_expressionInExtends.types @@ -0,0 +1,32 @@ +=== tests/cases/compiler/declarationEmit_expressionInExtends.ts === + +var x: { +>x : new (s: any) => Q + + new(s: any): Q; +>T : T +>s : any +>Q : Q +} + +class Q { +>Q : Q + + s: string; +>s : string +} + +class B extends x { +>B : B +>x : Q +} + +var q: B; +>q : B +>B : B + +q.s; +>q.s : string +>q : B +>s : string + diff --git a/tests/cases/compiler/declarationEmit_expressionInExtends.ts b/tests/cases/compiler/declarationEmit_expressionInExtends.ts new file mode 100644 index 00000000000..8544ca20d92 --- /dev/null +++ b/tests/cases/compiler/declarationEmit_expressionInExtends.ts @@ -0,0 +1,15 @@ +// @declaration: true + +var x: { + new(s: any): Q; +} + +class Q { + s: string; +} + +class B extends x { +} + +var q: B; +q.s; \ No newline at end of file From 3bb2c57264265551fb8628e1dbd42f48c14d3adb Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Thu, 3 Mar 2016 22:35:30 -0800 Subject: [PATCH 3/5] Fix #3810: Handel expressions in extends clauses --- src/compiler/checker.ts | 10 ++ src/compiler/declarationEmitter.ts | 4 + src/compiler/types.ts | 1 + .../declarationEmit_expressionInExtends2.js | 45 ++++++++ ...clarationEmit_expressionInExtends2.symbols | 30 ++++++ ...declarationEmit_expressionInExtends2.types | 32 ++++++ ...rationEmit_expressionInExtends3.errors.txt | 52 +++++++++ .../declarationEmit_expressionInExtends3.js | 101 ++++++++++++++++++ .../declarationEmit_expressionInExtends2.ts | 13 +++ .../declarationEmit_expressionInExtends3.ts | 43 ++++++++ 10 files changed, 331 insertions(+) create mode 100644 tests/baselines/reference/declarationEmit_expressionInExtends2.js create mode 100644 tests/baselines/reference/declarationEmit_expressionInExtends2.symbols create mode 100644 tests/baselines/reference/declarationEmit_expressionInExtends2.types create mode 100644 tests/baselines/reference/declarationEmit_expressionInExtends3.errors.txt create mode 100644 tests/baselines/reference/declarationEmit_expressionInExtends3.js create mode 100644 tests/cases/compiler/declarationEmit_expressionInExtends2.ts create mode 100644 tests/cases/compiler/declarationEmit_expressionInExtends3.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 041ea6dbfd6..976bd6d64e9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16244,6 +16244,15 @@ namespace ts { getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags); } + function writeBaseConstructorTypeOfClass(node: ClassLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter) { + const classType = getDeclaredTypeOfSymbol(getSymbolOfNode(node)); + resolveBaseTypesOfClass(classType); + const baseType = classType.resolvedBaseTypes[0]; + if (baseType) { + getSymbolDisplayBuilder().buildTypeDisplay(baseType, writer, enclosingDeclaration, flags); + } + } + function hasGlobalName(name: string): boolean { return hasProperty(globals, name); } @@ -16276,6 +16285,7 @@ namespace ts { writeTypeOfDeclaration, writeReturnTypeOfSignatureDeclaration, writeTypeOfExpression, + writeBaseConstructorTypeOfClass, isSymbolAccessible, isEntityNameVisible, getConstantValue, diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 0b5ffca4b53..c758d658888 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -987,6 +987,10 @@ namespace ts { else if (!isImplementsList && node.expression.kind === SyntaxKind.NullKeyword) { write("null"); } + else { + writer.getSymbolAccessibilityDiagnostic = getHeritageClauseVisibilityError; + resolver.writeBaseConstructorTypeOfClass(enclosingDeclaration, enclosingDeclaration, TypeFormatFlags.UseTypeOfFunction, writer); + } function getHeritageClauseVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic { let diagnosticMessage: DiagnosticMessage; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 2d53d5addad..0b0a1cbe61c 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1889,6 +1889,7 @@ namespace ts { writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; writeReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; + writeBaseConstructorTypeOfClass(node: ClassLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags): SymbolAccessibilityResult; isEntityNameVisible(entityName: EntityName | Expression, enclosingDeclaration: Node): SymbolVisibilityResult; // Returns the constant value this property access resolves to, or 'undefined' for a non-constant diff --git a/tests/baselines/reference/declarationEmit_expressionInExtends2.js b/tests/baselines/reference/declarationEmit_expressionInExtends2.js new file mode 100644 index 00000000000..da0478e26d0 --- /dev/null +++ b/tests/baselines/reference/declarationEmit_expressionInExtends2.js @@ -0,0 +1,45 @@ +//// [declarationEmit_expressionInExtends2.ts] + +class C { + x: T; + y: U; +} + +function getClass(c: T) { + return C; +} + +class MyClass extends getClass(2) { +} + +//// [declarationEmit_expressionInExtends2.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var C = (function () { + function C() { + } + return C; +}()); +function getClass(c) { + return C; +} +var MyClass = (function (_super) { + __extends(MyClass, _super); + function MyClass() { + _super.apply(this, arguments); + } + return MyClass; +}(getClass(2))); + + +//// [declarationEmit_expressionInExtends2.d.ts] +declare class C { + x: T; + y: U; +} +declare function getClass(c: T): typeof C; +declare class MyClass extends C { +} diff --git a/tests/baselines/reference/declarationEmit_expressionInExtends2.symbols b/tests/baselines/reference/declarationEmit_expressionInExtends2.symbols new file mode 100644 index 00000000000..8cd166852ac --- /dev/null +++ b/tests/baselines/reference/declarationEmit_expressionInExtends2.symbols @@ -0,0 +1,30 @@ +=== tests/cases/compiler/declarationEmit_expressionInExtends2.ts === + +class C { +>C : Symbol(C, Decl(declarationEmit_expressionInExtends2.ts, 0, 0)) +>T : Symbol(T, Decl(declarationEmit_expressionInExtends2.ts, 1, 8)) +>U : Symbol(U, Decl(declarationEmit_expressionInExtends2.ts, 1, 10)) + + x: T; +>x : Symbol(x, Decl(declarationEmit_expressionInExtends2.ts, 1, 15)) +>T : Symbol(T, Decl(declarationEmit_expressionInExtends2.ts, 1, 8)) + + y: U; +>y : Symbol(y, Decl(declarationEmit_expressionInExtends2.ts, 2, 9)) +>U : Symbol(U, Decl(declarationEmit_expressionInExtends2.ts, 1, 10)) +} + +function getClass(c: T) { +>getClass : Symbol(getClass, Decl(declarationEmit_expressionInExtends2.ts, 4, 1)) +>T : Symbol(T, Decl(declarationEmit_expressionInExtends2.ts, 6, 18)) +>c : Symbol(c, Decl(declarationEmit_expressionInExtends2.ts, 6, 21)) +>T : Symbol(T, Decl(declarationEmit_expressionInExtends2.ts, 6, 18)) + + return C; +>C : Symbol(C, Decl(declarationEmit_expressionInExtends2.ts, 0, 0)) +} + +class MyClass extends getClass(2) { +>MyClass : Symbol(MyClass, Decl(declarationEmit_expressionInExtends2.ts, 8, 1)) +>getClass : Symbol(getClass, Decl(declarationEmit_expressionInExtends2.ts, 4, 1)) +} diff --git a/tests/baselines/reference/declarationEmit_expressionInExtends2.types b/tests/baselines/reference/declarationEmit_expressionInExtends2.types new file mode 100644 index 00000000000..77a1539267d --- /dev/null +++ b/tests/baselines/reference/declarationEmit_expressionInExtends2.types @@ -0,0 +1,32 @@ +=== tests/cases/compiler/declarationEmit_expressionInExtends2.ts === + +class C { +>C : C +>T : T +>U : U + + x: T; +>x : T +>T : T + + y: U; +>y : U +>U : U +} + +function getClass(c: T) { +>getClass : (c: T) => typeof C +>T : T +>c : T +>T : T + + return C; +>C : typeof C +} + +class MyClass extends getClass(2) { +>MyClass : MyClass +>getClass(2) : C +>getClass : (c: T) => typeof C +>2 : number +} diff --git a/tests/baselines/reference/declarationEmit_expressionInExtends3.errors.txt b/tests/baselines/reference/declarationEmit_expressionInExtends3.errors.txt new file mode 100644 index 00000000000..2783810c568 --- /dev/null +++ b/tests/baselines/reference/declarationEmit_expressionInExtends3.errors.txt @@ -0,0 +1,52 @@ +tests/cases/compiler/declarationEmit_expressionInExtends3.ts(29,30): error TS4020: Extends clause of exported class 'MyClass' has or is using private name 'LocalClass'. +tests/cases/compiler/declarationEmit_expressionInExtends3.ts(37,31): error TS4020: Extends clause of exported class 'MyClass3' has or is using private name 'LocalInterface'. + + +==== tests/cases/compiler/declarationEmit_expressionInExtends3.ts (2 errors) ==== + + export class ExportedClass { + x: T; + } + + class LocalClass { + x: T; + y: U; + } + + export interface ExportedInterface { + x: number; + } + + interface LocalInterface { + x: number; + } + + function getLocalClass(c: T) { + return LocalClass; + } + + function getExportedClass(c: T) { + return ExportedClass; + } + + + + export class MyClass extends getLocalClass(undefined) { // error LocalClass is inaccisible + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS4020: Extends clause of exported class 'MyClass' has or is using private name 'LocalClass'. + } + + + export class MyClass2 extends getExportedClass(undefined) { // OK + } + + + export class MyClass3 extends getExportedClass(undefined) { // Error LocalInterface is inaccisble + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS4020: Extends clause of exported class 'MyClass3' has or is using private name 'LocalInterface'. + } + + + export class MyClass4 extends getExportedClass(undefined) { // OK + } + \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmit_expressionInExtends3.js b/tests/baselines/reference/declarationEmit_expressionInExtends3.js new file mode 100644 index 00000000000..10ef42d6838 --- /dev/null +++ b/tests/baselines/reference/declarationEmit_expressionInExtends3.js @@ -0,0 +1,101 @@ +//// [declarationEmit_expressionInExtends3.ts] + +export class ExportedClass { + x: T; +} + +class LocalClass { + x: T; + y: U; +} + +export interface ExportedInterface { + x: number; +} + +interface LocalInterface { + x: number; +} + +function getLocalClass(c: T) { + return LocalClass; +} + +function getExportedClass(c: T) { + return ExportedClass; +} + + + +export class MyClass extends getLocalClass(undefined) { // error LocalClass is inaccisible +} + + +export class MyClass2 extends getExportedClass(undefined) { // OK +} + + +export class MyClass3 extends getExportedClass(undefined) { // Error LocalInterface is inaccisble +} + + +export class MyClass4 extends getExportedClass(undefined) { // OK +} + + +//// [declarationEmit_expressionInExtends3.js] +"use strict"; +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var ExportedClass = (function () { + function ExportedClass() { + } + return ExportedClass; +}()); +exports.ExportedClass = ExportedClass; +var LocalClass = (function () { + function LocalClass() { + } + return LocalClass; +}()); +function getLocalClass(c) { + return LocalClass; +} +function getExportedClass(c) { + return ExportedClass; +} +var MyClass = (function (_super) { + __extends(MyClass, _super); + function MyClass() { + _super.apply(this, arguments); + } + return MyClass; +}(getLocalClass(undefined))); +exports.MyClass = MyClass; +var MyClass2 = (function (_super) { + __extends(MyClass2, _super); + function MyClass2() { + _super.apply(this, arguments); + } + return MyClass2; +}(getExportedClass(undefined))); +exports.MyClass2 = MyClass2; +var MyClass3 = (function (_super) { + __extends(MyClass3, _super); + function MyClass3() { + _super.apply(this, arguments); + } + return MyClass3; +}(getExportedClass(undefined))); +exports.MyClass3 = MyClass3; +var MyClass4 = (function (_super) { + __extends(MyClass4, _super); + function MyClass4() { + _super.apply(this, arguments); + } + return MyClass4; +}(getExportedClass(undefined))); +exports.MyClass4 = MyClass4; diff --git a/tests/cases/compiler/declarationEmit_expressionInExtends2.ts b/tests/cases/compiler/declarationEmit_expressionInExtends2.ts new file mode 100644 index 00000000000..0b2ccab8385 --- /dev/null +++ b/tests/cases/compiler/declarationEmit_expressionInExtends2.ts @@ -0,0 +1,13 @@ +// @declaration: true + +class C { + x: T; + y: U; +} + +function getClass(c: T) { + return C; +} + +class MyClass extends getClass(2) { +} \ No newline at end of file diff --git a/tests/cases/compiler/declarationEmit_expressionInExtends3.ts b/tests/cases/compiler/declarationEmit_expressionInExtends3.ts new file mode 100644 index 00000000000..348d0d188f7 --- /dev/null +++ b/tests/cases/compiler/declarationEmit_expressionInExtends3.ts @@ -0,0 +1,43 @@ +// @declaration: true + +export class ExportedClass { + x: T; +} + +class LocalClass { + x: T; + y: U; +} + +export interface ExportedInterface { + x: number; +} + +interface LocalInterface { + x: number; +} + +function getLocalClass(c: T) { + return LocalClass; +} + +function getExportedClass(c: T) { + return ExportedClass; +} + + + +export class MyClass extends getLocalClass(undefined) { // error LocalClass is inaccisible +} + + +export class MyClass2 extends getExportedClass(undefined) { // OK +} + + +export class MyClass3 extends getExportedClass(undefined) { // Error LocalInterface is inaccisble +} + + +export class MyClass4 extends getExportedClass(undefined) { // OK +} From 15f07e6231f19df7d69248859253c5a0ad437acf Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Thu, 3 Mar 2016 23:01:46 -0800 Subject: [PATCH 4/5] Fix #4506: Remove assert to allow for invalid patterns already flagged erlier by the checker --- src/compiler/checker.ts | 2 +- .../declarationEmit_invalidExport.errors.txt | 19 +++++++++++++++++++ .../declarationEmit_invalidExport.js | 14 ++++++++++++++ .../compiler/declarationEmit_invalidExport.ts | 7 +++++++ 4 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/declarationEmit_invalidExport.errors.txt create mode 100644 tests/baselines/reference/declarationEmit_invalidExport.js create mode 100644 tests/cases/compiler/declarationEmit_invalidExport.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 976bd6d64e9..628d5eb6e47 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2429,7 +2429,7 @@ namespace ts { return false; default: - Debug.fail("isDeclarationVisible unknown: SyntaxKind: " + node.kind); + return false; } } } diff --git a/tests/baselines/reference/declarationEmit_invalidExport.errors.txt b/tests/baselines/reference/declarationEmit_invalidExport.errors.txt new file mode 100644 index 00000000000..19d650d6d6f --- /dev/null +++ b/tests/baselines/reference/declarationEmit_invalidExport.errors.txt @@ -0,0 +1,19 @@ +tests/cases/compiler/declarationEmit_invalidExport.ts(3,3): error TS7027: Unreachable code detected. +tests/cases/compiler/declarationEmit_invalidExport.ts(5,30): error TS4081: Exported type alias 'MyClass' has or is using private name 'myClass'. +tests/cases/compiler/declarationEmit_invalidExport.ts(6,1): error TS1128: Declaration or statement expected. + + +==== tests/cases/compiler/declarationEmit_invalidExport.ts (3 errors) ==== + + if (false) { + export var myClass = 0; + ~~~~~~ +!!! error TS7027: Unreachable code detected. + } + export type MyClass = typeof myClass; + ~~~~~~~ +!!! error TS4081: Exported type alias 'MyClass' has or is using private name 'myClass'. + } + ~ +!!! error TS1128: Declaration or statement expected. + \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmit_invalidExport.js b/tests/baselines/reference/declarationEmit_invalidExport.js new file mode 100644 index 00000000000..61682ca5642 --- /dev/null +++ b/tests/baselines/reference/declarationEmit_invalidExport.js @@ -0,0 +1,14 @@ +//// [declarationEmit_invalidExport.ts] + +if (false) { + export var myClass = 0; +} +export type MyClass = typeof myClass; +} + + +//// [declarationEmit_invalidExport.js] +"use strict"; +if (false) { + exports.myClass = 0; +} diff --git a/tests/cases/compiler/declarationEmit_invalidExport.ts b/tests/cases/compiler/declarationEmit_invalidExport.ts new file mode 100644 index 00000000000..8b0826dbf96 --- /dev/null +++ b/tests/cases/compiler/declarationEmit_invalidExport.ts @@ -0,0 +1,7 @@ +// @declaration: true + +if (false) { + export var myClass = 0; +} +export type MyClass = typeof myClass; +} From 15640492c482fd2ebabeb42ca0730e2ff3a8d79e Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Fri, 4 Mar 2016 14:21:31 -0800 Subject: [PATCH 5/5] Code review comments --- src/compiler/checker.ts | 6 +-- ...rationEmit_expressionInExtends4.errors.txt | 35 ++++++++++++ .../declarationEmit_expressionInExtends4.js | 53 +++++++++++++++++++ .../declarationEmit_expressionInExtends4.ts | 18 +++++++ 4 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 tests/baselines/reference/declarationEmit_expressionInExtends4.errors.txt create mode 100644 tests/baselines/reference/declarationEmit_expressionInExtends4.js create mode 100644 tests/cases/compiler/declarationEmit_expressionInExtends4.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 628d5eb6e47..dcf37d86595 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16247,10 +16247,8 @@ namespace ts { function writeBaseConstructorTypeOfClass(node: ClassLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter) { const classType = getDeclaredTypeOfSymbol(getSymbolOfNode(node)); resolveBaseTypesOfClass(classType); - const baseType = classType.resolvedBaseTypes[0]; - if (baseType) { - getSymbolDisplayBuilder().buildTypeDisplay(baseType, writer, enclosingDeclaration, flags); - } + const baseType = classType.resolvedBaseTypes.length ? classType.resolvedBaseTypes[0] : unknownType; + getSymbolDisplayBuilder().buildTypeDisplay(baseType, writer, enclosingDeclaration, flags); } function hasGlobalName(name: string): boolean { diff --git a/tests/baselines/reference/declarationEmit_expressionInExtends4.errors.txt b/tests/baselines/reference/declarationEmit_expressionInExtends4.errors.txt new file mode 100644 index 00000000000..df3a6533260 --- /dev/null +++ b/tests/baselines/reference/declarationEmit_expressionInExtends4.errors.txt @@ -0,0 +1,35 @@ +tests/cases/compiler/declarationEmit_expressionInExtends4.ts(2,10): error TS4060: Return type of exported function has or is using private name 'D'. +tests/cases/compiler/declarationEmit_expressionInExtends4.ts(6,17): error TS2315: Type 'D' is not generic. +tests/cases/compiler/declarationEmit_expressionInExtends4.ts(10,18): error TS2304: Cannot find name 'SomeUndefinedFunction'. +tests/cases/compiler/declarationEmit_expressionInExtends4.ts(15,18): error TS2304: Cannot find name 'SomeUndefinedFunction'. +tests/cases/compiler/declarationEmit_expressionInExtends4.ts(15,18): error TS4020: Extends clause of exported class 'C3' has or is using private name 'SomeUndefinedFunction'. + + +==== tests/cases/compiler/declarationEmit_expressionInExtends4.ts (5 errors) ==== + + function getSomething() { + ~~~~~~~~~~~~ +!!! error TS4060: Return type of exported function has or is using private name 'D'. + return class D { } + } + + class C extends getSomething() { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2315: Type 'D' is not generic. + + } + + class C2 extends SomeUndefinedFunction() { + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'SomeUndefinedFunction'. + + } + + + class C3 extends SomeUndefinedFunction { + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'SomeUndefinedFunction'. + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS4020: Extends clause of exported class 'C3' has or is using private name 'SomeUndefinedFunction'. + + } \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmit_expressionInExtends4.js b/tests/baselines/reference/declarationEmit_expressionInExtends4.js new file mode 100644 index 00000000000..39ee7ce1e69 --- /dev/null +++ b/tests/baselines/reference/declarationEmit_expressionInExtends4.js @@ -0,0 +1,53 @@ +//// [declarationEmit_expressionInExtends4.ts] + +function getSomething() { + return class D { } +} + +class C extends getSomething() { + +} + +class C2 extends SomeUndefinedFunction() { + +} + + +class C3 extends SomeUndefinedFunction { + +} + +//// [declarationEmit_expressionInExtends4.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +function getSomething() { + return (function () { + function D() { + } + return D; + }()); +} +var C = (function (_super) { + __extends(C, _super); + function C() { + _super.apply(this, arguments); + } + return C; +}(getSomething())); +var C2 = (function (_super) { + __extends(C2, _super); + function C2() { + _super.apply(this, arguments); + } + return C2; +}(SomeUndefinedFunction())); +var C3 = (function (_super) { + __extends(C3, _super); + function C3() { + _super.apply(this, arguments); + } + return C3; +}(SomeUndefinedFunction)); diff --git a/tests/cases/compiler/declarationEmit_expressionInExtends4.ts b/tests/cases/compiler/declarationEmit_expressionInExtends4.ts new file mode 100644 index 00000000000..6b3044f227f --- /dev/null +++ b/tests/cases/compiler/declarationEmit_expressionInExtends4.ts @@ -0,0 +1,18 @@ +// @declaration: true + +function getSomething() { + return class D { } +} + +class C extends getSomething() { + +} + +class C2 extends SomeUndefinedFunction() { + +} + + +class C3 extends SomeUndefinedFunction { + +} \ No newline at end of file