Fix instantiated generic mixin declaration emit (#19144)

* Fix #18545, dont use declared type of class expression

* Accept API Baselines

* Add thus far unused flag from node builder

* Accept baseline update
This commit is contained in:
Wesley Wigham 2017-10-16 14:17:55 -07:00 committed by GitHub
parent 63074bcba0
commit aea7e9a7a8
5 changed files with 339 additions and 1 deletions

View File

@ -3398,7 +3398,7 @@ namespace ts {
else if (flags & TypeFormatFlags.WriteClassExpressionAsTypeLiteral &&
type.symbol.valueDeclaration &&
type.symbol.valueDeclaration.kind === SyntaxKind.ClassExpression) {
writeAnonymousType(getDeclaredTypeOfClassOrInterface(type.symbol), flags);
writeAnonymousType(type, flags);
}
else {
// Write the type reference in the format f<A>.g<B>.C<X, Y> where A and B are type arguments

View File

@ -0,0 +1,125 @@
//// [declarationNoDanglingGenerics.ts]
const kindCache: { [kind: string]: boolean } = {};
function register(kind: string): void | never {
if (kindCache[kind]) {
throw new Error(`Class with kind "${kind}" is already registered.`);
}
kindCache[kind] = true;
}
function ClassFactory<TKind extends string>(kind: TKind) {
register(kind);
return class {
static readonly THE_KIND: TKind = kind;
readonly kind: TKind = kind;
};
}
class Kinds {
static readonly A = "A";
static readonly B = "B";
static readonly C = "C";
}
export class AKind extends ClassFactory(Kinds.A) {
}
export class BKind extends ClassFactory(Kinds.B) {
}
export class CKind extends ClassFactory(Kinds.C) {
}
//// [declarationNoDanglingGenerics.js]
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
exports.__esModule = true;
var kindCache = {};
function register(kind) {
if (kindCache[kind]) {
throw new Error("Class with kind \"" + kind + "\" is already registered.");
}
kindCache[kind] = true;
}
function ClassFactory(kind) {
register(kind);
return _a = /** @class */ (function () {
function class_1() {
this.kind = kind;
}
return class_1;
}()),
_a.THE_KIND = kind,
_a;
var _a;
}
var Kinds = /** @class */ (function () {
function Kinds() {
}
Kinds.A = "A";
Kinds.B = "B";
Kinds.C = "C";
return Kinds;
}());
var AKind = /** @class */ (function (_super) {
__extends(AKind, _super);
function AKind() {
return _super !== null && _super.apply(this, arguments) || this;
}
return AKind;
}(ClassFactory(Kinds.A)));
exports.AKind = AKind;
var BKind = /** @class */ (function (_super) {
__extends(BKind, _super);
function BKind() {
return _super !== null && _super.apply(this, arguments) || this;
}
return BKind;
}(ClassFactory(Kinds.B)));
exports.BKind = BKind;
var CKind = /** @class */ (function (_super) {
__extends(CKind, _super);
function CKind() {
return _super !== null && _super.apply(this, arguments) || this;
}
return CKind;
}(ClassFactory(Kinds.C)));
exports.CKind = CKind;
//// [declarationNoDanglingGenerics.d.ts]
declare const AKind_base: {
new (): {
readonly kind: "A";
};
readonly THE_KIND: "A";
};
export declare class AKind extends AKind_base {
}
declare const BKind_base: {
new (): {
readonly kind: "B";
};
readonly THE_KIND: "B";
};
export declare class BKind extends BKind_base {
}
declare const CKind_base: {
new (): {
readonly kind: "C";
};
readonly THE_KIND: "C";
};
export declare class CKind extends CKind_base {
}

View File

@ -0,0 +1,82 @@
=== tests/cases/compiler/declarationNoDanglingGenerics.ts ===
const kindCache: { [kind: string]: boolean } = {};
>kindCache : Symbol(kindCache, Decl(declarationNoDanglingGenerics.ts, 0, 5))
>kind : Symbol(kind, Decl(declarationNoDanglingGenerics.ts, 0, 20))
function register(kind: string): void | never {
>register : Symbol(register, Decl(declarationNoDanglingGenerics.ts, 0, 50))
>kind : Symbol(kind, Decl(declarationNoDanglingGenerics.ts, 2, 18))
if (kindCache[kind]) {
>kindCache : Symbol(kindCache, Decl(declarationNoDanglingGenerics.ts, 0, 5))
>kind : Symbol(kind, Decl(declarationNoDanglingGenerics.ts, 2, 18))
throw new Error(`Class with kind "${kind}" is already registered.`);
>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>kind : Symbol(kind, Decl(declarationNoDanglingGenerics.ts, 2, 18))
}
kindCache[kind] = true;
>kindCache : Symbol(kindCache, Decl(declarationNoDanglingGenerics.ts, 0, 5))
>kind : Symbol(kind, Decl(declarationNoDanglingGenerics.ts, 2, 18))
}
function ClassFactory<TKind extends string>(kind: TKind) {
>ClassFactory : Symbol(ClassFactory, Decl(declarationNoDanglingGenerics.ts, 7, 1))
>TKind : Symbol(TKind, Decl(declarationNoDanglingGenerics.ts, 9, 22))
>kind : Symbol(kind, Decl(declarationNoDanglingGenerics.ts, 9, 44))
>TKind : Symbol(TKind, Decl(declarationNoDanglingGenerics.ts, 9, 22))
register(kind);
>register : Symbol(register, Decl(declarationNoDanglingGenerics.ts, 0, 50))
>kind : Symbol(kind, Decl(declarationNoDanglingGenerics.ts, 9, 44))
return class {
static readonly THE_KIND: TKind = kind;
>THE_KIND : Symbol((Anonymous class).THE_KIND, Decl(declarationNoDanglingGenerics.ts, 12, 16))
>TKind : Symbol(TKind, Decl(declarationNoDanglingGenerics.ts, 9, 22))
>kind : Symbol(kind, Decl(declarationNoDanglingGenerics.ts, 9, 44))
readonly kind: TKind = kind;
>kind : Symbol((Anonymous class).kind, Decl(declarationNoDanglingGenerics.ts, 13, 43))
>TKind : Symbol(TKind, Decl(declarationNoDanglingGenerics.ts, 9, 22))
>kind : Symbol(kind, Decl(declarationNoDanglingGenerics.ts, 9, 44))
};
}
class Kinds {
>Kinds : Symbol(Kinds, Decl(declarationNoDanglingGenerics.ts, 16, 1))
static readonly A = "A";
>A : Symbol(Kinds.A, Decl(declarationNoDanglingGenerics.ts, 18, 13))
static readonly B = "B";
>B : Symbol(Kinds.B, Decl(declarationNoDanglingGenerics.ts, 19, 26))
static readonly C = "C";
>C : Symbol(Kinds.C, Decl(declarationNoDanglingGenerics.ts, 20, 26))
}
export class AKind extends ClassFactory(Kinds.A) {
>AKind : Symbol(AKind, Decl(declarationNoDanglingGenerics.ts, 22, 1))
>ClassFactory : Symbol(ClassFactory, Decl(declarationNoDanglingGenerics.ts, 7, 1))
>Kinds.A : Symbol(Kinds.A, Decl(declarationNoDanglingGenerics.ts, 18, 13))
>Kinds : Symbol(Kinds, Decl(declarationNoDanglingGenerics.ts, 16, 1))
>A : Symbol(Kinds.A, Decl(declarationNoDanglingGenerics.ts, 18, 13))
}
export class BKind extends ClassFactory(Kinds.B) {
>BKind : Symbol(BKind, Decl(declarationNoDanglingGenerics.ts, 25, 1))
>ClassFactory : Symbol(ClassFactory, Decl(declarationNoDanglingGenerics.ts, 7, 1))
>Kinds.B : Symbol(Kinds.B, Decl(declarationNoDanglingGenerics.ts, 19, 26))
>Kinds : Symbol(Kinds, Decl(declarationNoDanglingGenerics.ts, 16, 1))
>B : Symbol(Kinds.B, Decl(declarationNoDanglingGenerics.ts, 19, 26))
}
export class CKind extends ClassFactory(Kinds.C) {
>CKind : Symbol(CKind, Decl(declarationNoDanglingGenerics.ts, 28, 1))
>ClassFactory : Symbol(ClassFactory, Decl(declarationNoDanglingGenerics.ts, 7, 1))
>Kinds.C : Symbol(Kinds.C, Decl(declarationNoDanglingGenerics.ts, 20, 26))
>Kinds : Symbol(Kinds, Decl(declarationNoDanglingGenerics.ts, 16, 1))
>C : Symbol(Kinds.C, Decl(declarationNoDanglingGenerics.ts, 20, 26))
}

View File

@ -0,0 +1,98 @@
=== tests/cases/compiler/declarationNoDanglingGenerics.ts ===
const kindCache: { [kind: string]: boolean } = {};
>kindCache : { [kind: string]: boolean; }
>kind : string
>{} : {}
function register(kind: string): void | never {
>register : (kind: string) => void
>kind : string
if (kindCache[kind]) {
>kindCache[kind] : boolean
>kindCache : { [kind: string]: boolean; }
>kind : string
throw new Error(`Class with kind "${kind}" is already registered.`);
>new Error(`Class with kind "${kind}" is already registered.`) : Error
>Error : ErrorConstructor
>`Class with kind "${kind}" is already registered.` : string
>kind : string
}
kindCache[kind] = true;
>kindCache[kind] = true : true
>kindCache[kind] : boolean
>kindCache : { [kind: string]: boolean; }
>kind : string
>true : true
}
function ClassFactory<TKind extends string>(kind: TKind) {
>ClassFactory : <TKind extends string>(kind: TKind) => typeof (Anonymous class)
>TKind : TKind
>kind : TKind
>TKind : TKind
register(kind);
>register(kind) : void
>register : (kind: string) => void
>kind : TKind
return class {
>class { static readonly THE_KIND: TKind = kind; readonly kind: TKind = kind; } : typeof (Anonymous class)
static readonly THE_KIND: TKind = kind;
>THE_KIND : TKind
>TKind : TKind
>kind : TKind
readonly kind: TKind = kind;
>kind : TKind
>TKind : TKind
>kind : TKind
};
}
class Kinds {
>Kinds : Kinds
static readonly A = "A";
>A : "A"
>"A" : "A"
static readonly B = "B";
>B : "B"
>"B" : "B"
static readonly C = "C";
>C : "C"
>"C" : "C"
}
export class AKind extends ClassFactory(Kinds.A) {
>AKind : AKind
>ClassFactory(Kinds.A) : ClassFactory<"A">.(Anonymous class)
>ClassFactory : <TKind extends string>(kind: TKind) => typeof (Anonymous class)
>Kinds.A : "A"
>Kinds : typeof Kinds
>A : "A"
}
export class BKind extends ClassFactory(Kinds.B) {
>BKind : BKind
>ClassFactory(Kinds.B) : ClassFactory<"B">.(Anonymous class)
>ClassFactory : <TKind extends string>(kind: TKind) => typeof (Anonymous class)
>Kinds.B : "B"
>Kinds : typeof Kinds
>B : "B"
}
export class CKind extends ClassFactory(Kinds.C) {
>CKind : CKind
>ClassFactory(Kinds.C) : ClassFactory<"C">.(Anonymous class)
>ClassFactory : <TKind extends string>(kind: TKind) => typeof (Anonymous class)
>Kinds.C : "C"
>Kinds : typeof Kinds
>C : "C"
}

View File

@ -0,0 +1,33 @@
// @declaration: true
const kindCache: { [kind: string]: boolean } = {};
function register(kind: string): void | never {
if (kindCache[kind]) {
throw new Error(`Class with kind "${kind}" is already registered.`);
}
kindCache[kind] = true;
}
function ClassFactory<TKind extends string>(kind: TKind) {
register(kind);
return class {
static readonly THE_KIND: TKind = kind;
readonly kind: TKind = kind;
};
}
class Kinds {
static readonly A = "A";
static readonly B = "B";
static readonly C = "C";
}
export class AKind extends ClassFactory(Kinds.A) {
}
export class BKind extends ClassFactory(Kinds.B) {
}
export class CKind extends ClassFactory(Kinds.C) {
}