diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7c8a0b7337f9b..dff8953e913b6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2465,7 +2465,8 @@ namespace ts { const symbol = type.symbol; if (symbol) { // Always use 'typeof T' for type of class, enum, and module objects - if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Enum | SymbolFlags.ValueModule)) { + if (symbol.flags & SymbolFlags.Class && !getBaseTypeVariableOfClass(symbol) || + symbol.flags & (SymbolFlags.Enum | SymbolFlags.ValueModule)) { writeTypeOfSymbol(type, flags); } else if (shouldWriteTypeOfFunctionSymbol()) { @@ -3639,6 +3640,11 @@ namespace ts { return links.type; } + function getBaseTypeVariableOfClass(symbol: Symbol) { + const baseConstructorType = getBaseConstructorTypeOfClass(getDeclaredTypeOfClassOrInterface(symbol)); + return baseConstructorType.flags & TypeFlags.TypeVariable ? baseConstructorType : undefined; + } + function getTypeOfFuncClassEnumModule(symbol: Symbol): Type { const links = getSymbolLinks(symbol); if (!links.type) { @@ -3647,8 +3653,13 @@ namespace ts { } else { const type = createObjectType(ObjectFlags.Anonymous, symbol); - links.type = strictNullChecks && symbol.flags & SymbolFlags.Optional ? - includeFalsyTypes(type, TypeFlags.Undefined) : type; + if (symbol.flags & SymbolFlags.Class) { + const baseTypeVariable = getBaseTypeVariableOfClass(symbol); + links.type = baseTypeVariable ? getIntersectionType([type, baseTypeVariable]) : type; + } + else { + links.type = strictNullChecks && symbol.flags & SymbolFlags.Optional ? includeFalsyTypes(type, TypeFlags.Undefined) : type; + } } } return links.type; @@ -3812,8 +3823,26 @@ namespace ts { return concatenate(getOuterTypeParametersOfClassOrInterface(symbol), getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol)); } + // A type is a mixin constructor if it has a single construct signature taking no type parameters and a single + // rest parameter of type any[]. + function isMixinConstructorType(type: Type) { + const signatures = getSignaturesOfType(type, SignatureKind.Construct); + if (signatures.length === 1) { + const s = signatures[0]; + return !s.typeParameters && s.parameters.length === 1 && s.hasRestParameter && getTypeOfParameter(s.parameters[0]) === anyArrayType; + } + return false; + } + function isConstructorType(type: Type): boolean { - return isValidBaseType(type) && getSignaturesOfType(type, SignatureKind.Construct).length > 0; + if (isValidBaseType(type) && getSignaturesOfType(type, SignatureKind.Construct).length > 0) { + return true; + } + if (type.flags & TypeFlags.TypeVariable) { + const constraint = getBaseConstraintOfType(type); + return isValidBaseType(constraint) && isMixinConstructorType(constraint); + } + return false; } function getBaseTypeNodeOfClass(type: InterfaceType): ExpressionWithTypeArguments { @@ -3892,7 +3921,7 @@ namespace ts { function resolveBaseTypesOfClass(type: InterfaceType): void { type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray; - const baseConstructorType = getBaseConstructorTypeOfClass(type); + const baseConstructorType = getApparentType(getBaseConstructorTypeOfClass(type)); if (!(baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection))) { return; } @@ -4542,16 +4571,47 @@ namespace ts { getUnionType([info1.type, info2.type]), info1.isReadonly || info2.isReadonly); } + function includeMixinType(type: Type, types: Type[], index: number): Type { + const mixedTypes: Type[] = []; + for (let i = 0; i < types.length; i++) { + if (i === index) { + mixedTypes.push(type); + } + else if (isMixinConstructorType(types[i])) { + mixedTypes.push(getReturnTypeOfSignature(getSignaturesOfType(types[i], SignatureKind.Construct)[0])); + } + } + return getIntersectionType(mixedTypes); + } + function resolveIntersectionTypeMembers(type: IntersectionType) { // The members and properties collections are empty for intersection types. To get all properties of an // intersection type use getPropertiesOfType (only the language service uses this). let callSignatures: Signature[] = emptyArray; let constructSignatures: Signature[] = emptyArray; - let stringIndexInfo: IndexInfo = undefined; - let numberIndexInfo: IndexInfo = undefined; - for (const t of type.types) { + let stringIndexInfo: IndexInfo; + let numberIndexInfo: IndexInfo; + const types = type.types; + const mixinCount = countWhere(types, isMixinConstructorType); + for (let i = 0; i < types.length; i++) { + const t = type.types[i]; + // When an intersection type contains mixin constructor types, the construct signatures from + // those types are discarded and their return types are mixed into the return types of all + // other construct signatures in the intersection type. For example, the intersection type + // '{ new(...args: any[]) => A } & { new(s: string) => B }' has a single construct signature + // 'new(s: string) => A & B'. + if (mixinCount === 0 || mixinCount === types.length && i === 0 || !isMixinConstructorType(t)) { + let signatures = getSignaturesOfType(t, SignatureKind.Construct); + if (signatures.length && mixinCount > 0) { + signatures = map(signatures, s => { + const clone = cloneSignature(s); + clone.resolvedReturnType = includeMixinType(getReturnTypeOfSignature(s), types, i); + return clone; + }); + } + constructSignatures = concatenate(constructSignatures, signatures); + } callSignatures = concatenate(callSignatures, getSignaturesOfType(t, SignatureKind.Call)); - constructSignatures = concatenate(constructSignatures, getSignaturesOfType(t, SignatureKind.Construct)); stringIndexInfo = intersectIndexInfos(stringIndexInfo, getIndexInfoOfType(t, IndexKind.String)); numberIndexInfo = intersectIndexInfos(numberIndexInfo, getIndexInfoOfType(t, IndexKind.Number)); } @@ -4593,7 +4653,7 @@ namespace ts { constructSignatures = getDefaultConstructSignatures(classType); } const baseConstructorType = getBaseConstructorTypeOfClass(classType); - if (baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection)) { + if (baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection | TypeFlags.TypeVariable)) { members = createSymbolTable(getNamedMembers(members)); addInheritedMembers(members, getPropertiesOfType(baseConstructorType)); } @@ -4890,6 +4950,7 @@ namespace ts { function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: string): Symbol { const types = containingType.types; + const excludeModifiers = containingType.flags & TypeFlags.Union ? ModifierFlags.Private | ModifierFlags.Protected : 0; let props: Symbol[]; // Flags we want to propagate to the result if they exist in all source symbols let commonFlags = (containingType.flags & TypeFlags.Intersection) ? SymbolFlags.Optional : SymbolFlags.None; @@ -4899,7 +4960,7 @@ namespace ts { const type = getApparentType(current); if (type !== unknownType) { const prop = getPropertyOfType(type, name); - if (prop && !(getDeclarationModifierFlagsFromSymbol(prop) & (ModifierFlags.Private | ModifierFlags.Protected))) { + if (prop && !(getDeclarationModifierFlagsFromSymbol(prop) & excludeModifiers)) { commonFlags &= prop.flags; if (!props) { props = [prop]; @@ -6965,9 +7026,12 @@ namespace ts { result.properties = resolved.properties; result.callSignatures = emptyArray; result.constructSignatures = emptyArray; - type = result; + return result; } } + else if (type.flags & TypeFlags.Intersection) { + return getIntersectionType(map((type).types, getTypeWithoutSignatures)); + } return type; } @@ -18387,7 +18451,8 @@ namespace ts { const baseTypes = getBaseTypes(type); if (baseTypes.length && produceDiagnostics) { const baseType = baseTypes[0]; - const staticBaseType = getBaseConstructorTypeOfClass(type); + const baseConstructorType = getBaseConstructorTypeOfClass(type); + const staticBaseType = getApparentType(baseConstructorType); checkBaseTypeAccessibility(staticBaseType, baseTypeNode); checkSourceElement(baseTypeNode.expression); if (baseTypeNode.typeArguments) { @@ -18401,6 +18466,9 @@ namespace ts { checkTypeAssignableTo(typeWithThis, getTypeWithThisArgument(baseType, type.thisType), node.name || node, Diagnostics.Class_0_incorrectly_extends_base_class_1); checkTypeAssignableTo(staticType, getTypeWithoutSignatures(staticBaseType), node.name || node, Diagnostics.Class_static_side_0_incorrectly_extends_base_class_static_side_1); + if (baseConstructorType.flags & TypeFlags.TypeVariable && !isMixinConstructorType(staticType)) { + error(node.name || node, Diagnostics.A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any); + } if (baseType.symbol && baseType.symbol.valueDeclaration && !isInAmbientContext(baseType.symbol.valueDeclaration) && @@ -18410,7 +18478,7 @@ namespace ts { } } - if (!(staticBaseType.symbol && staticBaseType.symbol.flags & SymbolFlags.Class)) { + if (!(staticBaseType.symbol && staticBaseType.symbol.flags & SymbolFlags.Class) && !(baseConstructorType.flags & TypeFlags.TypeVariable)) { // When the static base type is a "class-like" constructor function (but not actually a class), we verify // that all instantiated base constructor signatures return the same type. We can simply compare the type // references (as opposed to checking the structure of the types) because elsewhere we have already checked diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 43a9cce4de6e6..3fa399d3d3819 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1783,6 +1783,10 @@ "category": "Error", "code": 2544 }, + "A mixin class must have a constructor with a single rest parameter of type 'any[]'.": { + "category": "Error", + "code": 2545 + }, "JSX element attributes type '{0}' may not be a union type.": { "category": "Error", "code": 2600 diff --git a/tests/baselines/reference/mixinClassesAnnotated.js b/tests/baselines/reference/mixinClassesAnnotated.js new file mode 100644 index 0000000000000..e3a781033ff47 --- /dev/null +++ b/tests/baselines/reference/mixinClassesAnnotated.js @@ -0,0 +1,183 @@ +//// [mixinClassesAnnotated.ts] + +type Constructor = new(...args: any[]) => T; + +class Base { + constructor(public x: number, public y: number) {} +} + +class Derived extends Base { + constructor(x: number, y: number, public z: number) { + super(x, y); + } +} + +interface Printable { + print(): void; +} + +const Printable = >(superClass: T): Constructor & { message: string } & T => + class extends superClass { + static message = "hello"; + print() { + const output = this.x + "," + this.y; + } + } + +interface Tagged { + _tag: string; +} + +function Tagged>(superClass: T): Constructor & T { + class C extends superClass { + _tag: string; + constructor(...args: any[]) { + super(...args); + this._tag = "hello"; + } + } + return C; +} + +const Thing1 = Tagged(Derived); +const Thing2 = Tagged(Printable(Derived)); +Thing2.message; + +function f1() { + const thing = new Thing1(1, 2, 3); + thing.x; + thing._tag; +} + +function f2() { + const thing = new Thing2(1, 2, 3); + thing.x; + thing._tag; + thing.print(); +} + +class Thing3 extends Thing2 { + constructor(tag: string) { + super(10, 20, 30); + this._tag = tag; + } + test() { + this.print(); + } +} + + +//// [mixinClassesAnnotated.js] +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 __()); + }; +})(); +var Base = (function () { + function Base(x, y) { + this.x = x; + this.y = y; + } + return Base; +}()); +var Derived = (function (_super) { + __extends(Derived, _super); + function Derived(x, y, z) { + var _this = _super.call(this, x, y) || this; + _this.z = z; + return _this; + } + return Derived; +}(Base)); +var Printable = function (superClass) { return _a = (function (_super) { + __extends(class_1, _super); + function class_1() { + return _super !== null && _super.apply(this, arguments) || this; + } + class_1.prototype.print = function () { + var output = this.x + "," + this.y; + }; + return class_1; + }(superClass)), + _a.message = "hello", + _a; var _a; }; +function Tagged(superClass) { + var C = (function (_super) { + __extends(C, _super); + function C() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + var _this = _super.apply(this, args) || this; + _this._tag = "hello"; + return _this; + } + return C; + }(superClass)); + return C; +} +var Thing1 = Tagged(Derived); +var Thing2 = Tagged(Printable(Derived)); +Thing2.message; +function f1() { + var thing = new Thing1(1, 2, 3); + thing.x; + thing._tag; +} +function f2() { + var thing = new Thing2(1, 2, 3); + thing.x; + thing._tag; + thing.print(); +} +var Thing3 = (function (_super) { + __extends(Thing3, _super); + function Thing3(tag) { + var _this = _super.call(this, 10, 20, 30) || this; + _this._tag = tag; + return _this; + } + Thing3.prototype.test = function () { + this.print(); + }; + return Thing3; +}(Thing2)); + + +//// [mixinClassesAnnotated.d.ts] +declare type Constructor = new (...args: any[]) => T; +declare class Base { + x: number; + y: number; + constructor(x: number, y: number); +} +declare class Derived extends Base { + z: number; + constructor(x: number, y: number, z: number); +} +interface Printable { + print(): void; +} +declare const Printable: >(superClass: T) => Constructor & { + message: string; +} & T; +interface Tagged { + _tag: string; +} +declare function Tagged>(superClass: T): Constructor & T; +declare const Thing1: Constructor & typeof Derived; +declare const Thing2: Constructor & Constructor & { + message: string; +} & typeof Derived; +declare function f1(): void; +declare function f2(): void; +declare class Thing3 extends Thing2 { + constructor(tag: string); + test(): void; +} diff --git a/tests/baselines/reference/mixinClassesAnnotated.symbols b/tests/baselines/reference/mixinClassesAnnotated.symbols new file mode 100644 index 0000000000000..5a03789e2e672 --- /dev/null +++ b/tests/baselines/reference/mixinClassesAnnotated.symbols @@ -0,0 +1,193 @@ +=== tests/cases/conformance/classes/mixinClassesAnnotated.ts === + +type Constructor = new(...args: any[]) => T; +>Constructor : Symbol(Constructor, Decl(mixinClassesAnnotated.ts, 0, 0)) +>T : Symbol(T, Decl(mixinClassesAnnotated.ts, 1, 17)) +>args : Symbol(args, Decl(mixinClassesAnnotated.ts, 1, 26)) +>T : Symbol(T, Decl(mixinClassesAnnotated.ts, 1, 17)) + +class Base { +>Base : Symbol(Base, Decl(mixinClassesAnnotated.ts, 1, 47)) + + constructor(public x: number, public y: number) {} +>x : Symbol(Base.x, Decl(mixinClassesAnnotated.ts, 4, 16)) +>y : Symbol(Base.y, Decl(mixinClassesAnnotated.ts, 4, 33)) +} + +class Derived extends Base { +>Derived : Symbol(Derived, Decl(mixinClassesAnnotated.ts, 5, 1)) +>Base : Symbol(Base, Decl(mixinClassesAnnotated.ts, 1, 47)) + + constructor(x: number, y: number, public z: number) { +>x : Symbol(x, Decl(mixinClassesAnnotated.ts, 8, 16)) +>y : Symbol(y, Decl(mixinClassesAnnotated.ts, 8, 26)) +>z : Symbol(Derived.z, Decl(mixinClassesAnnotated.ts, 8, 37)) + + super(x, y); +>super : Symbol(Base, Decl(mixinClassesAnnotated.ts, 1, 47)) +>x : Symbol(x, Decl(mixinClassesAnnotated.ts, 8, 16)) +>y : Symbol(y, Decl(mixinClassesAnnotated.ts, 8, 26)) + } +} + +interface Printable { +>Printable : Symbol(Printable, Decl(mixinClassesAnnotated.ts, 11, 1), Decl(mixinClassesAnnotated.ts, 17, 5)) + + print(): void; +>print : Symbol(Printable.print, Decl(mixinClassesAnnotated.ts, 13, 21)) +} + +const Printable = >(superClass: T): Constructor & { message: string } & T => +>Printable : Symbol(Printable, Decl(mixinClassesAnnotated.ts, 11, 1), Decl(mixinClassesAnnotated.ts, 17, 5)) +>T : Symbol(T, Decl(mixinClassesAnnotated.ts, 17, 19)) +>Constructor : Symbol(Constructor, Decl(mixinClassesAnnotated.ts, 0, 0)) +>Base : Symbol(Base, Decl(mixinClassesAnnotated.ts, 1, 47)) +>superClass : Symbol(superClass, Decl(mixinClassesAnnotated.ts, 17, 48)) +>T : Symbol(T, Decl(mixinClassesAnnotated.ts, 17, 19)) +>Constructor : Symbol(Constructor, Decl(mixinClassesAnnotated.ts, 0, 0)) +>Printable : Symbol(Printable, Decl(mixinClassesAnnotated.ts, 11, 1), Decl(mixinClassesAnnotated.ts, 17, 5)) +>message : Symbol(message, Decl(mixinClassesAnnotated.ts, 17, 90)) +>T : Symbol(T, Decl(mixinClassesAnnotated.ts, 17, 19)) + + class extends superClass { +>superClass : Symbol(superClass, Decl(mixinClassesAnnotated.ts, 17, 48)) + + static message = "hello"; +>message : Symbol((Anonymous class).message, Decl(mixinClassesAnnotated.ts, 18, 30)) + + print() { +>print : Symbol((Anonymous class).print, Decl(mixinClassesAnnotated.ts, 19, 33)) + + const output = this.x + "," + this.y; +>output : Symbol(output, Decl(mixinClassesAnnotated.ts, 21, 17)) +>this.x : Symbol(Base.x, Decl(mixinClassesAnnotated.ts, 4, 16)) +>this : Symbol((Anonymous class), Decl(mixinClassesAnnotated.ts, 17, 115)) +>x : Symbol(Base.x, Decl(mixinClassesAnnotated.ts, 4, 16)) +>this.y : Symbol(Base.y, Decl(mixinClassesAnnotated.ts, 4, 33)) +>this : Symbol((Anonymous class), Decl(mixinClassesAnnotated.ts, 17, 115)) +>y : Symbol(Base.y, Decl(mixinClassesAnnotated.ts, 4, 33)) + } + } + +interface Tagged { +>Tagged : Symbol(Tagged, Decl(mixinClassesAnnotated.ts, 23, 5), Decl(mixinClassesAnnotated.ts, 27, 1)) + + _tag: string; +>_tag : Symbol(Tagged._tag, Decl(mixinClassesAnnotated.ts, 25, 18)) +} + +function Tagged>(superClass: T): Constructor & T { +>Tagged : Symbol(Tagged, Decl(mixinClassesAnnotated.ts, 23, 5), Decl(mixinClassesAnnotated.ts, 27, 1)) +>T : Symbol(T, Decl(mixinClassesAnnotated.ts, 29, 16)) +>Constructor : Symbol(Constructor, Decl(mixinClassesAnnotated.ts, 0, 0)) +>superClass : Symbol(superClass, Decl(mixinClassesAnnotated.ts, 29, 43)) +>T : Symbol(T, Decl(mixinClassesAnnotated.ts, 29, 16)) +>Constructor : Symbol(Constructor, Decl(mixinClassesAnnotated.ts, 0, 0)) +>Tagged : Symbol(Tagged, Decl(mixinClassesAnnotated.ts, 23, 5), Decl(mixinClassesAnnotated.ts, 27, 1)) +>T : Symbol(T, Decl(mixinClassesAnnotated.ts, 29, 16)) + + class C extends superClass { +>C : Symbol(C, Decl(mixinClassesAnnotated.ts, 29, 84)) +>superClass : Symbol(superClass, Decl(mixinClassesAnnotated.ts, 29, 43)) + + _tag: string; +>_tag : Symbol(C._tag, Decl(mixinClassesAnnotated.ts, 30, 32)) + + constructor(...args: any[]) { +>args : Symbol(args, Decl(mixinClassesAnnotated.ts, 32, 20)) + + super(...args); +>super : Symbol(T, Decl(mixinClassesAnnotated.ts, 29, 16)) +>args : Symbol(args, Decl(mixinClassesAnnotated.ts, 32, 20)) + + this._tag = "hello"; +>this._tag : Symbol(C._tag, Decl(mixinClassesAnnotated.ts, 30, 32)) +>this : Symbol(C, Decl(mixinClassesAnnotated.ts, 29, 84)) +>_tag : Symbol(C._tag, Decl(mixinClassesAnnotated.ts, 30, 32)) + } + } + return C; +>C : Symbol(C, Decl(mixinClassesAnnotated.ts, 29, 84)) +} + +const Thing1 = Tagged(Derived); +>Thing1 : Symbol(Thing1, Decl(mixinClassesAnnotated.ts, 40, 5)) +>Tagged : Symbol(Tagged, Decl(mixinClassesAnnotated.ts, 23, 5), Decl(mixinClassesAnnotated.ts, 27, 1)) +>Derived : Symbol(Derived, Decl(mixinClassesAnnotated.ts, 5, 1)) + +const Thing2 = Tagged(Printable(Derived)); +>Thing2 : Symbol(Thing2, Decl(mixinClassesAnnotated.ts, 41, 5)) +>Tagged : Symbol(Tagged, Decl(mixinClassesAnnotated.ts, 23, 5), Decl(mixinClassesAnnotated.ts, 27, 1)) +>Printable : Symbol(Printable, Decl(mixinClassesAnnotated.ts, 11, 1), Decl(mixinClassesAnnotated.ts, 17, 5)) +>Derived : Symbol(Derived, Decl(mixinClassesAnnotated.ts, 5, 1)) + +Thing2.message; +>Thing2.message : Symbol(message, Decl(mixinClassesAnnotated.ts, 17, 90)) +>Thing2 : Symbol(Thing2, Decl(mixinClassesAnnotated.ts, 41, 5)) +>message : Symbol(message, Decl(mixinClassesAnnotated.ts, 17, 90)) + +function f1() { +>f1 : Symbol(f1, Decl(mixinClassesAnnotated.ts, 42, 15)) + + const thing = new Thing1(1, 2, 3); +>thing : Symbol(thing, Decl(mixinClassesAnnotated.ts, 45, 9)) +>Thing1 : Symbol(Thing1, Decl(mixinClassesAnnotated.ts, 40, 5)) + + thing.x; +>thing.x : Symbol(Base.x, Decl(mixinClassesAnnotated.ts, 4, 16)) +>thing : Symbol(thing, Decl(mixinClassesAnnotated.ts, 45, 9)) +>x : Symbol(Base.x, Decl(mixinClassesAnnotated.ts, 4, 16)) + + thing._tag; +>thing._tag : Symbol(Tagged._tag, Decl(mixinClassesAnnotated.ts, 25, 18)) +>thing : Symbol(thing, Decl(mixinClassesAnnotated.ts, 45, 9)) +>_tag : Symbol(Tagged._tag, Decl(mixinClassesAnnotated.ts, 25, 18)) +} + +function f2() { +>f2 : Symbol(f2, Decl(mixinClassesAnnotated.ts, 48, 1)) + + const thing = new Thing2(1, 2, 3); +>thing : Symbol(thing, Decl(mixinClassesAnnotated.ts, 51, 9)) +>Thing2 : Symbol(Thing2, Decl(mixinClassesAnnotated.ts, 41, 5)) + + thing.x; +>thing.x : Symbol(Base.x, Decl(mixinClassesAnnotated.ts, 4, 16)) +>thing : Symbol(thing, Decl(mixinClassesAnnotated.ts, 51, 9)) +>x : Symbol(Base.x, Decl(mixinClassesAnnotated.ts, 4, 16)) + + thing._tag; +>thing._tag : Symbol(Tagged._tag, Decl(mixinClassesAnnotated.ts, 25, 18)) +>thing : Symbol(thing, Decl(mixinClassesAnnotated.ts, 51, 9)) +>_tag : Symbol(Tagged._tag, Decl(mixinClassesAnnotated.ts, 25, 18)) + + thing.print(); +>thing.print : Symbol(Printable.print, Decl(mixinClassesAnnotated.ts, 13, 21)) +>thing : Symbol(thing, Decl(mixinClassesAnnotated.ts, 51, 9)) +>print : Symbol(Printable.print, Decl(mixinClassesAnnotated.ts, 13, 21)) +} + +class Thing3 extends Thing2 { +>Thing3 : Symbol(Thing3, Decl(mixinClassesAnnotated.ts, 55, 1)) +>Thing2 : Symbol(Thing2, Decl(mixinClassesAnnotated.ts, 41, 5)) + + constructor(tag: string) { +>tag : Symbol(tag, Decl(mixinClassesAnnotated.ts, 58, 16)) + + super(10, 20, 30); + this._tag = tag; +>this._tag : Symbol(Tagged._tag, Decl(mixinClassesAnnotated.ts, 25, 18)) +>this : Symbol(Thing3, Decl(mixinClassesAnnotated.ts, 55, 1)) +>_tag : Symbol(Tagged._tag, Decl(mixinClassesAnnotated.ts, 25, 18)) +>tag : Symbol(tag, Decl(mixinClassesAnnotated.ts, 58, 16)) + } + test() { +>test : Symbol(Thing3.test, Decl(mixinClassesAnnotated.ts, 61, 5)) + + this.print(); +>this.print : Symbol(Printable.print, Decl(mixinClassesAnnotated.ts, 13, 21)) +>this : Symbol(Thing3, Decl(mixinClassesAnnotated.ts, 55, 1)) +>print : Symbol(Printable.print, Decl(mixinClassesAnnotated.ts, 13, 21)) + } +} + diff --git a/tests/baselines/reference/mixinClassesAnnotated.types b/tests/baselines/reference/mixinClassesAnnotated.types new file mode 100644 index 0000000000000..afaf4c4d25ec1 --- /dev/null +++ b/tests/baselines/reference/mixinClassesAnnotated.types @@ -0,0 +1,224 @@ +=== tests/cases/conformance/classes/mixinClassesAnnotated.ts === + +type Constructor = new(...args: any[]) => T; +>Constructor : Constructor +>T : T +>args : any[] +>T : T + +class Base { +>Base : Base + + constructor(public x: number, public y: number) {} +>x : number +>y : number +} + +class Derived extends Base { +>Derived : Derived +>Base : Base + + constructor(x: number, y: number, public z: number) { +>x : number +>y : number +>z : number + + super(x, y); +>super(x, y) : void +>super : typeof Base +>x : number +>y : number + } +} + +interface Printable { +>Printable : Printable + + print(): void; +>print : () => void +} + +const Printable = >(superClass: T): Constructor & { message: string } & T => +>Printable : >(superClass: T) => Constructor & { message: string; } & T +>>(superClass: T): Constructor & { message: string } & T => class extends superClass { static message = "hello"; print() { const output = this.x + "," + this.y; } } : >(superClass: T) => Constructor & { message: string; } & T +>T : T +>Constructor : Constructor +>Base : Base +>superClass : T +>T : T +>Constructor : Constructor +>Printable : Printable +>message : string +>T : T + + class extends superClass { +>class extends superClass { static message = "hello"; print() { const output = this.x + "," + this.y; } } : { new (...args: any[]): (Anonymous class); prototype: .(Anonymous class); message: string; } & T +>superClass : Base + + static message = "hello"; +>message : string +>"hello" : "hello" + + print() { +>print : () => void + + const output = this.x + "," + this.y; +>output : string +>this.x + "," + this.y : string +>this.x + "," : string +>this.x : number +>this : this +>x : number +>"," : "," +>this.y : number +>this : this +>y : number + } + } + +interface Tagged { +>Tagged : Tagged + + _tag: string; +>_tag : string +} + +function Tagged>(superClass: T): Constructor & T { +>Tagged : >(superClass: T) => Constructor & T +>T : T +>Constructor : Constructor +>superClass : T +>T : T +>Constructor : Constructor +>Tagged : Tagged +>T : T + + class C extends superClass { +>C : C +>superClass : {} + + _tag: string; +>_tag : string + + constructor(...args: any[]) { +>args : any[] + + super(...args); +>super(...args) : void +>super : T +>...args : any +>args : any[] + + this._tag = "hello"; +>this._tag = "hello" : "hello" +>this._tag : string +>this : this +>_tag : string +>"hello" : "hello" + } + } + return C; +>C : { new (...args: any[]): C; prototype: Tagged.C; } & T +} + +const Thing1 = Tagged(Derived); +>Thing1 : Constructor & typeof Derived +>Tagged(Derived) : Constructor & typeof Derived +>Tagged : >(superClass: T) => Constructor & T +>Derived : typeof Derived + +const Thing2 = Tagged(Printable(Derived)); +>Thing2 : Constructor & Constructor & { message: string; } & typeof Derived +>Tagged(Printable(Derived)) : Constructor & Constructor & { message: string; } & typeof Derived +>Tagged : >(superClass: T) => Constructor & T +>Printable(Derived) : Constructor & { message: string; } & typeof Derived +>Printable : >(superClass: T) => Constructor & { message: string; } & T +>Derived : typeof Derived + +Thing2.message; +>Thing2.message : string +>Thing2 : Constructor & Constructor & { message: string; } & typeof Derived +>message : string + +function f1() { +>f1 : () => void + + const thing = new Thing1(1, 2, 3); +>thing : Tagged & Derived +>new Thing1(1, 2, 3) : Tagged & Derived +>Thing1 : Constructor & typeof Derived +>1 : 1 +>2 : 2 +>3 : 3 + + thing.x; +>thing.x : number +>thing : Tagged & Derived +>x : number + + thing._tag; +>thing._tag : string +>thing : Tagged & Derived +>_tag : string +} + +function f2() { +>f2 : () => void + + const thing = new Thing2(1, 2, 3); +>thing : Tagged & Printable & Derived +>new Thing2(1, 2, 3) : Tagged & Printable & Derived +>Thing2 : Constructor & Constructor & { message: string; } & typeof Derived +>1 : 1 +>2 : 2 +>3 : 3 + + thing.x; +>thing.x : number +>thing : Tagged & Printable & Derived +>x : number + + thing._tag; +>thing._tag : string +>thing : Tagged & Printable & Derived +>_tag : string + + thing.print(); +>thing.print() : void +>thing.print : () => void +>thing : Tagged & Printable & Derived +>print : () => void +} + +class Thing3 extends Thing2 { +>Thing3 : Thing3 +>Thing2 : Tagged & Printable & Derived + + constructor(tag: string) { +>tag : string + + super(10, 20, 30); +>super(10, 20, 30) : void +>super : Constructor & Constructor & { message: string; } & typeof Derived +>10 : 10 +>20 : 20 +>30 : 30 + + this._tag = tag; +>this._tag = tag : string +>this._tag : string +>this : this +>_tag : string +>tag : string + } + test() { +>test : () => void + + this.print(); +>this.print() : void +>this.print : () => void +>this : this +>print : () => void + } +} + diff --git a/tests/baselines/reference/mixinClassesAnonymous.js b/tests/baselines/reference/mixinClassesAnonymous.js new file mode 100644 index 0000000000000..c7b8ab5fd63a2 --- /dev/null +++ b/tests/baselines/reference/mixinClassesAnonymous.js @@ -0,0 +1,140 @@ +//// [mixinClassesAnonymous.ts] +type Constructor = new(...args: any[]) => T; + +class Base { + constructor(public x: number, public y: number) {} +} + +class Derived extends Base { + constructor(x: number, y: number, public z: number) { + super(x, y); + } +} + +const Printable = >(superClass: T) => class extends superClass { + static message = "hello"; + print() { + const output = this.x + "," + this.y; + } +} + +function Tagged>(superClass: T) { + class C extends superClass { + _tag: string; + constructor(...args: any[]) { + super(...args); + this._tag = "hello"; + } + } + return C; +} + +const Thing1 = Tagged(Derived); +const Thing2 = Tagged(Printable(Derived)); +Thing2.message; + +function f1() { + const thing = new Thing1(1, 2, 3); + thing.x; + thing._tag; +} + +function f2() { + const thing = new Thing2(1, 2, 3); + thing.x; + thing._tag; + thing.print(); +} + +class Thing3 extends Thing2 { + constructor(tag: string) { + super(10, 20, 30); + this._tag = tag; + } + test() { + this.print(); + } +} + + +//// [mixinClassesAnonymous.js] +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 __()); + }; +})(); +var Base = (function () { + function Base(x, y) { + this.x = x; + this.y = y; + } + return Base; +}()); +var Derived = (function (_super) { + __extends(Derived, _super); + function Derived(x, y, z) { + var _this = _super.call(this, x, y) || this; + _this.z = z; + return _this; + } + return Derived; +}(Base)); +var Printable = function (superClass) { return _a = (function (_super) { + __extends(class_1, _super); + function class_1() { + return _super !== null && _super.apply(this, arguments) || this; + } + class_1.prototype.print = function () { + var output = this.x + "," + this.y; + }; + return class_1; + }(superClass)), + _a.message = "hello", + _a; var _a; }; +function Tagged(superClass) { + var C = (function (_super) { + __extends(C, _super); + function C() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + var _this = _super.apply(this, args) || this; + _this._tag = "hello"; + return _this; + } + return C; + }(superClass)); + return C; +} +var Thing1 = Tagged(Derived); +var Thing2 = Tagged(Printable(Derived)); +Thing2.message; +function f1() { + var thing = new Thing1(1, 2, 3); + thing.x; + thing._tag; +} +function f2() { + var thing = new Thing2(1, 2, 3); + thing.x; + thing._tag; + thing.print(); +} +var Thing3 = (function (_super) { + __extends(Thing3, _super); + function Thing3(tag) { + var _this = _super.call(this, 10, 20, 30) || this; + _this._tag = tag; + return _this; + } + Thing3.prototype.test = function () { + this.print(); + }; + return Thing3; +}(Thing2)); diff --git a/tests/baselines/reference/mixinClassesAnonymous.symbols b/tests/baselines/reference/mixinClassesAnonymous.symbols new file mode 100644 index 0000000000000..204d9c589fda9 --- /dev/null +++ b/tests/baselines/reference/mixinClassesAnonymous.symbols @@ -0,0 +1,169 @@ +=== tests/cases/conformance/classes/mixinClassesAnonymous.ts === +type Constructor = new(...args: any[]) => T; +>Constructor : Symbol(Constructor, Decl(mixinClassesAnonymous.ts, 0, 0)) +>T : Symbol(T, Decl(mixinClassesAnonymous.ts, 0, 17)) +>args : Symbol(args, Decl(mixinClassesAnonymous.ts, 0, 26)) +>T : Symbol(T, Decl(mixinClassesAnonymous.ts, 0, 17)) + +class Base { +>Base : Symbol(Base, Decl(mixinClassesAnonymous.ts, 0, 47)) + + constructor(public x: number, public y: number) {} +>x : Symbol(Base.x, Decl(mixinClassesAnonymous.ts, 3, 16)) +>y : Symbol(Base.y, Decl(mixinClassesAnonymous.ts, 3, 33)) +} + +class Derived extends Base { +>Derived : Symbol(Derived, Decl(mixinClassesAnonymous.ts, 4, 1)) +>Base : Symbol(Base, Decl(mixinClassesAnonymous.ts, 0, 47)) + + constructor(x: number, y: number, public z: number) { +>x : Symbol(x, Decl(mixinClassesAnonymous.ts, 7, 16)) +>y : Symbol(y, Decl(mixinClassesAnonymous.ts, 7, 26)) +>z : Symbol(Derived.z, Decl(mixinClassesAnonymous.ts, 7, 37)) + + super(x, y); +>super : Symbol(Base, Decl(mixinClassesAnonymous.ts, 0, 47)) +>x : Symbol(x, Decl(mixinClassesAnonymous.ts, 7, 16)) +>y : Symbol(y, Decl(mixinClassesAnonymous.ts, 7, 26)) + } +} + +const Printable = >(superClass: T) => class extends superClass { +>Printable : Symbol(Printable, Decl(mixinClassesAnonymous.ts, 12, 5)) +>T : Symbol(T, Decl(mixinClassesAnonymous.ts, 12, 19)) +>Constructor : Symbol(Constructor, Decl(mixinClassesAnonymous.ts, 0, 0)) +>Base : Symbol(Base, Decl(mixinClassesAnonymous.ts, 0, 47)) +>superClass : Symbol(superClass, Decl(mixinClassesAnonymous.ts, 12, 48)) +>T : Symbol(T, Decl(mixinClassesAnonymous.ts, 12, 19)) +>superClass : Symbol(superClass, Decl(mixinClassesAnonymous.ts, 12, 48)) + + static message = "hello"; +>message : Symbol((Anonymous class).message, Decl(mixinClassesAnonymous.ts, 12, 92)) + + print() { +>print : Symbol((Anonymous class).print, Decl(mixinClassesAnonymous.ts, 13, 29)) + + const output = this.x + "," + this.y; +>output : Symbol(output, Decl(mixinClassesAnonymous.ts, 15, 13)) +>this.x : Symbol(Base.x, Decl(mixinClassesAnonymous.ts, 3, 16)) +>this : Symbol((Anonymous class), Decl(mixinClassesAnonymous.ts, 12, 65)) +>x : Symbol(Base.x, Decl(mixinClassesAnonymous.ts, 3, 16)) +>this.y : Symbol(Base.y, Decl(mixinClassesAnonymous.ts, 3, 33)) +>this : Symbol((Anonymous class), Decl(mixinClassesAnonymous.ts, 12, 65)) +>y : Symbol(Base.y, Decl(mixinClassesAnonymous.ts, 3, 33)) + } +} + +function Tagged>(superClass: T) { +>Tagged : Symbol(Tagged, Decl(mixinClassesAnonymous.ts, 17, 1)) +>T : Symbol(T, Decl(mixinClassesAnonymous.ts, 19, 16)) +>Constructor : Symbol(Constructor, Decl(mixinClassesAnonymous.ts, 0, 0)) +>superClass : Symbol(superClass, Decl(mixinClassesAnonymous.ts, 19, 43)) +>T : Symbol(T, Decl(mixinClassesAnonymous.ts, 19, 16)) + + class C extends superClass { +>C : Symbol(C, Decl(mixinClassesAnonymous.ts, 19, 59)) +>superClass : Symbol(superClass, Decl(mixinClassesAnonymous.ts, 19, 43)) + + _tag: string; +>_tag : Symbol(C._tag, Decl(mixinClassesAnonymous.ts, 20, 32)) + + constructor(...args: any[]) { +>args : Symbol(args, Decl(mixinClassesAnonymous.ts, 22, 20)) + + super(...args); +>super : Symbol(T, Decl(mixinClassesAnonymous.ts, 19, 16)) +>args : Symbol(args, Decl(mixinClassesAnonymous.ts, 22, 20)) + + this._tag = "hello"; +>this._tag : Symbol(C._tag, Decl(mixinClassesAnonymous.ts, 20, 32)) +>this : Symbol(C, Decl(mixinClassesAnonymous.ts, 19, 59)) +>_tag : Symbol(C._tag, Decl(mixinClassesAnonymous.ts, 20, 32)) + } + } + return C; +>C : Symbol(C, Decl(mixinClassesAnonymous.ts, 19, 59)) +} + +const Thing1 = Tagged(Derived); +>Thing1 : Symbol(Thing1, Decl(mixinClassesAnonymous.ts, 30, 5)) +>Tagged : Symbol(Tagged, Decl(mixinClassesAnonymous.ts, 17, 1)) +>Derived : Symbol(Derived, Decl(mixinClassesAnonymous.ts, 4, 1)) + +const Thing2 = Tagged(Printable(Derived)); +>Thing2 : Symbol(Thing2, Decl(mixinClassesAnonymous.ts, 31, 5)) +>Tagged : Symbol(Tagged, Decl(mixinClassesAnonymous.ts, 17, 1)) +>Printable : Symbol(Printable, Decl(mixinClassesAnonymous.ts, 12, 5)) +>Derived : Symbol(Derived, Decl(mixinClassesAnonymous.ts, 4, 1)) + +Thing2.message; +>Thing2.message : Symbol((Anonymous class).message, Decl(mixinClassesAnonymous.ts, 12, 92)) +>Thing2 : Symbol(Thing2, Decl(mixinClassesAnonymous.ts, 31, 5)) +>message : Symbol((Anonymous class).message, Decl(mixinClassesAnonymous.ts, 12, 92)) + +function f1() { +>f1 : Symbol(f1, Decl(mixinClassesAnonymous.ts, 32, 15)) + + const thing = new Thing1(1, 2, 3); +>thing : Symbol(thing, Decl(mixinClassesAnonymous.ts, 35, 9)) +>Thing1 : Symbol(Thing1, Decl(mixinClassesAnonymous.ts, 30, 5)) + + thing.x; +>thing.x : Symbol(Base.x, Decl(mixinClassesAnonymous.ts, 3, 16)) +>thing : Symbol(thing, Decl(mixinClassesAnonymous.ts, 35, 9)) +>x : Symbol(Base.x, Decl(mixinClassesAnonymous.ts, 3, 16)) + + thing._tag; +>thing._tag : Symbol(C._tag, Decl(mixinClassesAnonymous.ts, 20, 32)) +>thing : Symbol(thing, Decl(mixinClassesAnonymous.ts, 35, 9)) +>_tag : Symbol(C._tag, Decl(mixinClassesAnonymous.ts, 20, 32)) +} + +function f2() { +>f2 : Symbol(f2, Decl(mixinClassesAnonymous.ts, 38, 1)) + + const thing = new Thing2(1, 2, 3); +>thing : Symbol(thing, Decl(mixinClassesAnonymous.ts, 41, 9)) +>Thing2 : Symbol(Thing2, Decl(mixinClassesAnonymous.ts, 31, 5)) + + thing.x; +>thing.x : Symbol(Base.x, Decl(mixinClassesAnonymous.ts, 3, 16)) +>thing : Symbol(thing, Decl(mixinClassesAnonymous.ts, 41, 9)) +>x : Symbol(Base.x, Decl(mixinClassesAnonymous.ts, 3, 16)) + + thing._tag; +>thing._tag : Symbol(C._tag, Decl(mixinClassesAnonymous.ts, 20, 32)) +>thing : Symbol(thing, Decl(mixinClassesAnonymous.ts, 41, 9)) +>_tag : Symbol(C._tag, Decl(mixinClassesAnonymous.ts, 20, 32)) + + thing.print(); +>thing.print : Symbol((Anonymous class).print, Decl(mixinClassesAnonymous.ts, 13, 29)) +>thing : Symbol(thing, Decl(mixinClassesAnonymous.ts, 41, 9)) +>print : Symbol((Anonymous class).print, Decl(mixinClassesAnonymous.ts, 13, 29)) +} + +class Thing3 extends Thing2 { +>Thing3 : Symbol(Thing3, Decl(mixinClassesAnonymous.ts, 45, 1)) +>Thing2 : Symbol(Thing2, Decl(mixinClassesAnonymous.ts, 31, 5)) + + constructor(tag: string) { +>tag : Symbol(tag, Decl(mixinClassesAnonymous.ts, 48, 16)) + + super(10, 20, 30); + this._tag = tag; +>this._tag : Symbol(C._tag, Decl(mixinClassesAnonymous.ts, 20, 32)) +>this : Symbol(Thing3, Decl(mixinClassesAnonymous.ts, 45, 1)) +>_tag : Symbol(C._tag, Decl(mixinClassesAnonymous.ts, 20, 32)) +>tag : Symbol(tag, Decl(mixinClassesAnonymous.ts, 48, 16)) + } + test() { +>test : Symbol(Thing3.test, Decl(mixinClassesAnonymous.ts, 51, 5)) + + this.print(); +>this.print : Symbol((Anonymous class).print, Decl(mixinClassesAnonymous.ts, 13, 29)) +>this : Symbol(Thing3, Decl(mixinClassesAnonymous.ts, 45, 1)) +>print : Symbol((Anonymous class).print, Decl(mixinClassesAnonymous.ts, 13, 29)) + } +} + diff --git a/tests/baselines/reference/mixinClassesAnonymous.types b/tests/baselines/reference/mixinClassesAnonymous.types new file mode 100644 index 0000000000000..54b1c2c3819b7 --- /dev/null +++ b/tests/baselines/reference/mixinClassesAnonymous.types @@ -0,0 +1,200 @@ +=== tests/cases/conformance/classes/mixinClassesAnonymous.ts === +type Constructor = new(...args: any[]) => T; +>Constructor : Constructor +>T : T +>args : any[] +>T : T + +class Base { +>Base : Base + + constructor(public x: number, public y: number) {} +>x : number +>y : number +} + +class Derived extends Base { +>Derived : Derived +>Base : Base + + constructor(x: number, y: number, public z: number) { +>x : number +>y : number +>z : number + + super(x, y); +>super(x, y) : void +>super : typeof Base +>x : number +>y : number + } +} + +const Printable = >(superClass: T) => class extends superClass { +>Printable : >(superClass: T) => { new (...args: any[]): (Anonymous class); prototype: .(Anonymous class); message: string; } & T +>>(superClass: T) => class extends superClass { static message = "hello"; print() { const output = this.x + "," + this.y; }} : >(superClass: T) => { new (...args: any[]): (Anonymous class); prototype: .(Anonymous class); message: string; } & T +>T : T +>Constructor : Constructor +>Base : Base +>superClass : T +>T : T +>class extends superClass { static message = "hello"; print() { const output = this.x + "," + this.y; }} : { new (...args: any[]): (Anonymous class); prototype: .(Anonymous class); message: string; } & T +>superClass : Base + + static message = "hello"; +>message : string +>"hello" : "hello" + + print() { +>print : () => void + + const output = this.x + "," + this.y; +>output : string +>this.x + "," + this.y : string +>this.x + "," : string +>this.x : number +>this : this +>x : number +>"," : "," +>this.y : number +>this : this +>y : number + } +} + +function Tagged>(superClass: T) { +>Tagged : >(superClass: T) => { new (...args: any[]): C; prototype: Tagged.C; } & T +>T : T +>Constructor : Constructor +>superClass : T +>T : T + + class C extends superClass { +>C : C +>superClass : {} + + _tag: string; +>_tag : string + + constructor(...args: any[]) { +>args : any[] + + super(...args); +>super(...args) : void +>super : T +>...args : any +>args : any[] + + this._tag = "hello"; +>this._tag = "hello" : "hello" +>this._tag : string +>this : this +>_tag : string +>"hello" : "hello" + } + } + return C; +>C : { new (...args: any[]): C; prototype: Tagged.C; } & T +} + +const Thing1 = Tagged(Derived); +>Thing1 : { new (...args: any[]): Tagged.C; prototype: Tagged.C; } & typeof Derived +>Tagged(Derived) : { new (...args: any[]): Tagged.C; prototype: Tagged.C; } & typeof Derived +>Tagged : >(superClass: T) => { new (...args: any[]): C; prototype: Tagged.C; } & T +>Derived : typeof Derived + +const Thing2 = Tagged(Printable(Derived)); +>Thing2 : { new (...args: any[]): Tagged<{ new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived>.C; prototype: Tagged.C; } & { new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived +>Tagged(Printable(Derived)) : { new (...args: any[]): Tagged<{ new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived>.C; prototype: Tagged.C; } & { new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived +>Tagged : >(superClass: T) => { new (...args: any[]): C; prototype: Tagged.C; } & T +>Printable(Derived) : { new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived +>Printable : >(superClass: T) => { new (...args: any[]): (Anonymous class); prototype: .(Anonymous class); message: string; } & T +>Derived : typeof Derived + +Thing2.message; +>Thing2.message : string +>Thing2 : { new (...args: any[]): Tagged<{ new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived>.C; prototype: Tagged.C; } & { new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived +>message : string + +function f1() { +>f1 : () => void + + const thing = new Thing1(1, 2, 3); +>thing : Tagged.C & Derived +>new Thing1(1, 2, 3) : Tagged.C & Derived +>Thing1 : { new (...args: any[]): Tagged.C; prototype: Tagged.C; } & typeof Derived +>1 : 1 +>2 : 2 +>3 : 3 + + thing.x; +>thing.x : number +>thing : Tagged.C & Derived +>x : number + + thing._tag; +>thing._tag : string +>thing : Tagged.C & Derived +>_tag : string +} + +function f2() { +>f2 : () => void + + const thing = new Thing2(1, 2, 3); +>thing : Tagged<{ new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived>.C & .(Anonymous class) & Derived +>new Thing2(1, 2, 3) : Tagged<{ new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived>.C & .(Anonymous class) & Derived +>Thing2 : { new (...args: any[]): Tagged<{ new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived>.C; prototype: Tagged.C; } & { new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived +>1 : 1 +>2 : 2 +>3 : 3 + + thing.x; +>thing.x : number +>thing : Tagged<{ new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived>.C & .(Anonymous class) & Derived +>x : number + + thing._tag; +>thing._tag : string +>thing : Tagged<{ new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived>.C & .(Anonymous class) & Derived +>_tag : string + + thing.print(); +>thing.print() : void +>thing.print : () => void +>thing : Tagged<{ new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived>.C & .(Anonymous class) & Derived +>print : () => void +} + +class Thing3 extends Thing2 { +>Thing3 : Thing3 +>Thing2 : Tagged<{ new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived>.C & .(Anonymous class) & Derived + + constructor(tag: string) { +>tag : string + + super(10, 20, 30); +>super(10, 20, 30) : void +>super : { new (...args: any[]): Tagged<{ new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived>.C; prototype: Tagged.C; } & { new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); message: string; } & typeof Derived +>10 : 10 +>20 : 20 +>30 : 30 + + this._tag = tag; +>this._tag = tag : string +>this._tag : string +>this : this +>_tag : string +>tag : string + } + test() { +>test : () => void + + this.print(); +>this.print() : void +>this.print : () => void +>this : this +>print : () => void + } +} + diff --git a/tests/baselines/reference/mixinClassesMembers.js b/tests/baselines/reference/mixinClassesMembers.js new file mode 100644 index 0000000000000..01fc1bb003295 --- /dev/null +++ b/tests/baselines/reference/mixinClassesMembers.js @@ -0,0 +1,220 @@ +//// [mixinClassesMembers.ts] + +declare class C1 { + public a: number; + protected b: number; + private c: number; + constructor(s: string); + constructor(n: number); +} + +declare class M1 { + constructor(...args: any[]); + p: number; + static p: number; +} + +declare class M2 { + constructor(...args: any[]); + f(): number; + static f(): number; +} + +declare const Mixed1: typeof M1 & typeof C1; +declare const Mixed2: typeof C1 & typeof M1; +declare const Mixed3: typeof M2 & typeof M1 & typeof C1; +declare const Mixed4: typeof C1 & typeof M1 & typeof M2; +declare const Mixed5: typeof M1 & typeof M2; + +function f1() { + let x1 = new Mixed1("hello"); + let x2 = new Mixed1(42); + let x3 = new Mixed2("hello"); + let x4 = new Mixed2(42); + let x5 = new Mixed3("hello"); + let x6 = new Mixed3(42); + let x7 = new Mixed4("hello"); + let x8 = new Mixed4(42); + let x9 = new Mixed5(); +} + +function f2() { + let x = new Mixed1("hello"); + x.a; + x.p; + Mixed1.p; +} + +function f3() { + let x = new Mixed2("hello"); + x.a; + x.p; + Mixed2.p; +} + +function f4() { + let x = new Mixed3("hello"); + x.a; + x.p; + x.f(); + Mixed3.p; + Mixed3.f(); +} + +function f5() { + let x = new Mixed4("hello"); + x.a; + x.p; + x.f(); + Mixed4.p; + Mixed4.f(); +} + +function f6() { + let x = new Mixed5(); + x.p; + x.f(); + Mixed5.p; + Mixed5.f(); +} + +class C2 extends Mixed1 { + constructor() { + super("hello"); + this.a; + this.b; + this.p; + } +} + +class C3 extends Mixed3 { + constructor() { + super(42); + this.a; + this.b; + this.p; + this.f(); + } + f() { return super.f(); } +} + + +//// [mixinClassesMembers.js] +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 __()); + }; +})(); +function f1() { + var x1 = new Mixed1("hello"); + var x2 = new Mixed1(42); + var x3 = new Mixed2("hello"); + var x4 = new Mixed2(42); + var x5 = new Mixed3("hello"); + var x6 = new Mixed3(42); + var x7 = new Mixed4("hello"); + var x8 = new Mixed4(42); + var x9 = new Mixed5(); +} +function f2() { + var x = new Mixed1("hello"); + x.a; + x.p; + Mixed1.p; +} +function f3() { + var x = new Mixed2("hello"); + x.a; + x.p; + Mixed2.p; +} +function f4() { + var x = new Mixed3("hello"); + x.a; + x.p; + x.f(); + Mixed3.p; + Mixed3.f(); +} +function f5() { + var x = new Mixed4("hello"); + x.a; + x.p; + x.f(); + Mixed4.p; + Mixed4.f(); +} +function f6() { + var x = new Mixed5(); + x.p; + x.f(); + Mixed5.p; + Mixed5.f(); +} +var C2 = (function (_super) { + __extends(C2, _super); + function C2() { + var _this = _super.call(this, "hello") || this; + _this.a; + _this.b; + _this.p; + return _this; + } + return C2; +}(Mixed1)); +var C3 = (function (_super) { + __extends(C3, _super); + function C3() { + var _this = _super.call(this, 42) || this; + _this.a; + _this.b; + _this.p; + _this.f(); + return _this; + } + C3.prototype.f = function () { return _super.prototype.f.call(this); }; + return C3; +}(Mixed3)); + + +//// [mixinClassesMembers.d.ts] +declare class C1 { + a: number; + protected b: number; + private c; + constructor(s: string); + constructor(n: number); +} +declare class M1 { + constructor(...args: any[]); + p: number; + static p: number; +} +declare class M2 { + constructor(...args: any[]); + f(): number; + static f(): number; +} +declare const Mixed1: typeof M1 & typeof C1; +declare const Mixed2: typeof C1 & typeof M1; +declare const Mixed3: typeof M2 & typeof M1 & typeof C1; +declare const Mixed4: typeof C1 & typeof M1 & typeof M2; +declare const Mixed5: typeof M1 & typeof M2; +declare function f1(): void; +declare function f2(): void; +declare function f3(): void; +declare function f4(): void; +declare function f5(): void; +declare function f6(): void; +declare class C2 extends Mixed1 { + constructor(); +} +declare class C3 extends Mixed3 { + constructor(); + f(): number; +} diff --git a/tests/baselines/reference/mixinClassesMembers.symbols b/tests/baselines/reference/mixinClassesMembers.symbols new file mode 100644 index 0000000000000..fabfe7e6d8630 --- /dev/null +++ b/tests/baselines/reference/mixinClassesMembers.symbols @@ -0,0 +1,309 @@ +=== tests/cases/conformance/classes/mixinClassesMembers.ts === + +declare class C1 { +>C1 : Symbol(C1, Decl(mixinClassesMembers.ts, 0, 0)) + + public a: number; +>a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18)) + + protected b: number; +>b : Symbol(C1.b, Decl(mixinClassesMembers.ts, 2, 21)) + + private c: number; +>c : Symbol(C1.c, Decl(mixinClassesMembers.ts, 3, 24)) + + constructor(s: string); +>s : Symbol(s, Decl(mixinClassesMembers.ts, 5, 16)) + + constructor(n: number); +>n : Symbol(n, Decl(mixinClassesMembers.ts, 6, 16)) +} + +declare class M1 { +>M1 : Symbol(M1, Decl(mixinClassesMembers.ts, 7, 1)) + + constructor(...args: any[]); +>args : Symbol(args, Decl(mixinClassesMembers.ts, 10, 16)) + + p: number; +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) + + static p: number; +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14)) +} + +declare class M2 { +>M2 : Symbol(M2, Decl(mixinClassesMembers.ts, 13, 1)) + + constructor(...args: any[]); +>args : Symbol(args, Decl(mixinClassesMembers.ts, 16, 16)) + + f(): number; +>f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 16, 32)) + + static f(): number; +>f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 17, 16)) +} + +declare const Mixed1: typeof M1 & typeof C1; +>Mixed1 : Symbol(Mixed1, Decl(mixinClassesMembers.ts, 21, 13)) +>M1 : Symbol(M1, Decl(mixinClassesMembers.ts, 7, 1)) +>C1 : Symbol(C1, Decl(mixinClassesMembers.ts, 0, 0)) + +declare const Mixed2: typeof C1 & typeof M1; +>Mixed2 : Symbol(Mixed2, Decl(mixinClassesMembers.ts, 22, 13)) +>C1 : Symbol(C1, Decl(mixinClassesMembers.ts, 0, 0)) +>M1 : Symbol(M1, Decl(mixinClassesMembers.ts, 7, 1)) + +declare const Mixed3: typeof M2 & typeof M1 & typeof C1; +>Mixed3 : Symbol(Mixed3, Decl(mixinClassesMembers.ts, 23, 13)) +>M2 : Symbol(M2, Decl(mixinClassesMembers.ts, 13, 1)) +>M1 : Symbol(M1, Decl(mixinClassesMembers.ts, 7, 1)) +>C1 : Symbol(C1, Decl(mixinClassesMembers.ts, 0, 0)) + +declare const Mixed4: typeof C1 & typeof M1 & typeof M2; +>Mixed4 : Symbol(Mixed4, Decl(mixinClassesMembers.ts, 24, 13)) +>C1 : Symbol(C1, Decl(mixinClassesMembers.ts, 0, 0)) +>M1 : Symbol(M1, Decl(mixinClassesMembers.ts, 7, 1)) +>M2 : Symbol(M2, Decl(mixinClassesMembers.ts, 13, 1)) + +declare const Mixed5: typeof M1 & typeof M2; +>Mixed5 : Symbol(Mixed5, Decl(mixinClassesMembers.ts, 25, 13)) +>M1 : Symbol(M1, Decl(mixinClassesMembers.ts, 7, 1)) +>M2 : Symbol(M2, Decl(mixinClassesMembers.ts, 13, 1)) + +function f1() { +>f1 : Symbol(f1, Decl(mixinClassesMembers.ts, 25, 44)) + + let x1 = new Mixed1("hello"); +>x1 : Symbol(x1, Decl(mixinClassesMembers.ts, 28, 7)) +>Mixed1 : Symbol(Mixed1, Decl(mixinClassesMembers.ts, 21, 13)) + + let x2 = new Mixed1(42); +>x2 : Symbol(x2, Decl(mixinClassesMembers.ts, 29, 7)) +>Mixed1 : Symbol(Mixed1, Decl(mixinClassesMembers.ts, 21, 13)) + + let x3 = new Mixed2("hello"); +>x3 : Symbol(x3, Decl(mixinClassesMembers.ts, 30, 7)) +>Mixed2 : Symbol(Mixed2, Decl(mixinClassesMembers.ts, 22, 13)) + + let x4 = new Mixed2(42); +>x4 : Symbol(x4, Decl(mixinClassesMembers.ts, 31, 7)) +>Mixed2 : Symbol(Mixed2, Decl(mixinClassesMembers.ts, 22, 13)) + + let x5 = new Mixed3("hello"); +>x5 : Symbol(x5, Decl(mixinClassesMembers.ts, 32, 7)) +>Mixed3 : Symbol(Mixed3, Decl(mixinClassesMembers.ts, 23, 13)) + + let x6 = new Mixed3(42); +>x6 : Symbol(x6, Decl(mixinClassesMembers.ts, 33, 7)) +>Mixed3 : Symbol(Mixed3, Decl(mixinClassesMembers.ts, 23, 13)) + + let x7 = new Mixed4("hello"); +>x7 : Symbol(x7, Decl(mixinClassesMembers.ts, 34, 7)) +>Mixed4 : Symbol(Mixed4, Decl(mixinClassesMembers.ts, 24, 13)) + + let x8 = new Mixed4(42); +>x8 : Symbol(x8, Decl(mixinClassesMembers.ts, 35, 7)) +>Mixed4 : Symbol(Mixed4, Decl(mixinClassesMembers.ts, 24, 13)) + + let x9 = new Mixed5(); +>x9 : Symbol(x9, Decl(mixinClassesMembers.ts, 36, 7)) +>Mixed5 : Symbol(Mixed5, Decl(mixinClassesMembers.ts, 25, 13)) +} + +function f2() { +>f2 : Symbol(f2, Decl(mixinClassesMembers.ts, 37, 1)) + + let x = new Mixed1("hello"); +>x : Symbol(x, Decl(mixinClassesMembers.ts, 40, 7)) +>Mixed1 : Symbol(Mixed1, Decl(mixinClassesMembers.ts, 21, 13)) + + x.a; +>x.a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18)) +>x : Symbol(x, Decl(mixinClassesMembers.ts, 40, 7)) +>a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18)) + + x.p; +>x.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) +>x : Symbol(x, Decl(mixinClassesMembers.ts, 40, 7)) +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) + + Mixed1.p; +>Mixed1.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14)) +>Mixed1 : Symbol(Mixed1, Decl(mixinClassesMembers.ts, 21, 13)) +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14)) +} + +function f3() { +>f3 : Symbol(f3, Decl(mixinClassesMembers.ts, 44, 1)) + + let x = new Mixed2("hello"); +>x : Symbol(x, Decl(mixinClassesMembers.ts, 47, 7)) +>Mixed2 : Symbol(Mixed2, Decl(mixinClassesMembers.ts, 22, 13)) + + x.a; +>x.a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18)) +>x : Symbol(x, Decl(mixinClassesMembers.ts, 47, 7)) +>a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18)) + + x.p; +>x.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) +>x : Symbol(x, Decl(mixinClassesMembers.ts, 47, 7)) +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) + + Mixed2.p; +>Mixed2.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14)) +>Mixed2 : Symbol(Mixed2, Decl(mixinClassesMembers.ts, 22, 13)) +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14)) +} + +function f4() { +>f4 : Symbol(f4, Decl(mixinClassesMembers.ts, 51, 1)) + + let x = new Mixed3("hello"); +>x : Symbol(x, Decl(mixinClassesMembers.ts, 54, 7)) +>Mixed3 : Symbol(Mixed3, Decl(mixinClassesMembers.ts, 23, 13)) + + x.a; +>x.a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18)) +>x : Symbol(x, Decl(mixinClassesMembers.ts, 54, 7)) +>a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18)) + + x.p; +>x.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) +>x : Symbol(x, Decl(mixinClassesMembers.ts, 54, 7)) +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) + + x.f(); +>x.f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 16, 32)) +>x : Symbol(x, Decl(mixinClassesMembers.ts, 54, 7)) +>f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 16, 32)) + + Mixed3.p; +>Mixed3.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14)) +>Mixed3 : Symbol(Mixed3, Decl(mixinClassesMembers.ts, 23, 13)) +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14)) + + Mixed3.f(); +>Mixed3.f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 17, 16)) +>Mixed3 : Symbol(Mixed3, Decl(mixinClassesMembers.ts, 23, 13)) +>f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 17, 16)) +} + +function f5() { +>f5 : Symbol(f5, Decl(mixinClassesMembers.ts, 60, 1)) + + let x = new Mixed4("hello"); +>x : Symbol(x, Decl(mixinClassesMembers.ts, 63, 7)) +>Mixed4 : Symbol(Mixed4, Decl(mixinClassesMembers.ts, 24, 13)) + + x.a; +>x.a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18)) +>x : Symbol(x, Decl(mixinClassesMembers.ts, 63, 7)) +>a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18)) + + x.p; +>x.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) +>x : Symbol(x, Decl(mixinClassesMembers.ts, 63, 7)) +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) + + x.f(); +>x.f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 16, 32)) +>x : Symbol(x, Decl(mixinClassesMembers.ts, 63, 7)) +>f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 16, 32)) + + Mixed4.p; +>Mixed4.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14)) +>Mixed4 : Symbol(Mixed4, Decl(mixinClassesMembers.ts, 24, 13)) +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14)) + + Mixed4.f(); +>Mixed4.f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 17, 16)) +>Mixed4 : Symbol(Mixed4, Decl(mixinClassesMembers.ts, 24, 13)) +>f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 17, 16)) +} + +function f6() { +>f6 : Symbol(f6, Decl(mixinClassesMembers.ts, 69, 1)) + + let x = new Mixed5(); +>x : Symbol(x, Decl(mixinClassesMembers.ts, 72, 7)) +>Mixed5 : Symbol(Mixed5, Decl(mixinClassesMembers.ts, 25, 13)) + + x.p; +>x.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) +>x : Symbol(x, Decl(mixinClassesMembers.ts, 72, 7)) +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) + + x.f(); +>x.f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 16, 32)) +>x : Symbol(x, Decl(mixinClassesMembers.ts, 72, 7)) +>f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 16, 32)) + + Mixed5.p; +>Mixed5.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14)) +>Mixed5 : Symbol(Mixed5, Decl(mixinClassesMembers.ts, 25, 13)) +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 11, 14)) + + Mixed5.f(); +>Mixed5.f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 17, 16)) +>Mixed5 : Symbol(Mixed5, Decl(mixinClassesMembers.ts, 25, 13)) +>f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 17, 16)) +} + +class C2 extends Mixed1 { +>C2 : Symbol(C2, Decl(mixinClassesMembers.ts, 77, 1)) +>Mixed1 : Symbol(Mixed1, Decl(mixinClassesMembers.ts, 21, 13)) + + constructor() { + super("hello"); + this.a; +>this.a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18)) +>this : Symbol(C2, Decl(mixinClassesMembers.ts, 77, 1)) +>a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18)) + + this.b; +>this.b : Symbol(C1.b, Decl(mixinClassesMembers.ts, 2, 21)) +>this : Symbol(C2, Decl(mixinClassesMembers.ts, 77, 1)) +>b : Symbol(C1.b, Decl(mixinClassesMembers.ts, 2, 21)) + + this.p; +>this.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) +>this : Symbol(C2, Decl(mixinClassesMembers.ts, 77, 1)) +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) + } +} + +class C3 extends Mixed3 { +>C3 : Symbol(C3, Decl(mixinClassesMembers.ts, 86, 1)) +>Mixed3 : Symbol(Mixed3, Decl(mixinClassesMembers.ts, 23, 13)) + + constructor() { + super(42); + this.a; +>this.a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18)) +>this : Symbol(C3, Decl(mixinClassesMembers.ts, 86, 1)) +>a : Symbol(C1.a, Decl(mixinClassesMembers.ts, 1, 18)) + + this.b; +>this.b : Symbol(C1.b, Decl(mixinClassesMembers.ts, 2, 21)) +>this : Symbol(C3, Decl(mixinClassesMembers.ts, 86, 1)) +>b : Symbol(C1.b, Decl(mixinClassesMembers.ts, 2, 21)) + + this.p; +>this.p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) +>this : Symbol(C3, Decl(mixinClassesMembers.ts, 86, 1)) +>p : Symbol(M1.p, Decl(mixinClassesMembers.ts, 10, 32)) + + this.f(); +>this.f : Symbol(C3.f, Decl(mixinClassesMembers.ts, 95, 5)) +>this : Symbol(C3, Decl(mixinClassesMembers.ts, 86, 1)) +>f : Symbol(C3.f, Decl(mixinClassesMembers.ts, 95, 5)) + } + f() { return super.f(); } +>f : Symbol(C3.f, Decl(mixinClassesMembers.ts, 95, 5)) +>super.f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 16, 32)) +>f : Symbol(M2.f, Decl(mixinClassesMembers.ts, 16, 32)) +} + diff --git a/tests/baselines/reference/mixinClassesMembers.types b/tests/baselines/reference/mixinClassesMembers.types new file mode 100644 index 0000000000000..c8b291754158d --- /dev/null +++ b/tests/baselines/reference/mixinClassesMembers.types @@ -0,0 +1,352 @@ +=== tests/cases/conformance/classes/mixinClassesMembers.ts === + +declare class C1 { +>C1 : C1 + + public a: number; +>a : number + + protected b: number; +>b : number + + private c: number; +>c : number + + constructor(s: string); +>s : string + + constructor(n: number); +>n : number +} + +declare class M1 { +>M1 : M1 + + constructor(...args: any[]); +>args : any[] + + p: number; +>p : number + + static p: number; +>p : number +} + +declare class M2 { +>M2 : M2 + + constructor(...args: any[]); +>args : any[] + + f(): number; +>f : () => number + + static f(): number; +>f : () => number +} + +declare const Mixed1: typeof M1 & typeof C1; +>Mixed1 : typeof M1 & typeof C1 +>M1 : typeof M1 +>C1 : typeof C1 + +declare const Mixed2: typeof C1 & typeof M1; +>Mixed2 : typeof C1 & typeof M1 +>C1 : typeof C1 +>M1 : typeof M1 + +declare const Mixed3: typeof M2 & typeof M1 & typeof C1; +>Mixed3 : typeof M2 & typeof M1 & typeof C1 +>M2 : typeof M2 +>M1 : typeof M1 +>C1 : typeof C1 + +declare const Mixed4: typeof C1 & typeof M1 & typeof M2; +>Mixed4 : typeof C1 & typeof M1 & typeof M2 +>C1 : typeof C1 +>M1 : typeof M1 +>M2 : typeof M2 + +declare const Mixed5: typeof M1 & typeof M2; +>Mixed5 : typeof M1 & typeof M2 +>M1 : typeof M1 +>M2 : typeof M2 + +function f1() { +>f1 : () => void + + let x1 = new Mixed1("hello"); +>x1 : M1 & C1 +>new Mixed1("hello") : M1 & C1 +>Mixed1 : typeof M1 & typeof C1 +>"hello" : "hello" + + let x2 = new Mixed1(42); +>x2 : M1 & C1 +>new Mixed1(42) : M1 & C1 +>Mixed1 : typeof M1 & typeof C1 +>42 : 42 + + let x3 = new Mixed2("hello"); +>x3 : C1 & M1 +>new Mixed2("hello") : C1 & M1 +>Mixed2 : typeof C1 & typeof M1 +>"hello" : "hello" + + let x4 = new Mixed2(42); +>x4 : C1 & M1 +>new Mixed2(42) : C1 & M1 +>Mixed2 : typeof C1 & typeof M1 +>42 : 42 + + let x5 = new Mixed3("hello"); +>x5 : M2 & M1 & C1 +>new Mixed3("hello") : M2 & M1 & C1 +>Mixed3 : typeof M2 & typeof M1 & typeof C1 +>"hello" : "hello" + + let x6 = new Mixed3(42); +>x6 : M2 & M1 & C1 +>new Mixed3(42) : M2 & M1 & C1 +>Mixed3 : typeof M2 & typeof M1 & typeof C1 +>42 : 42 + + let x7 = new Mixed4("hello"); +>x7 : C1 & M1 & M2 +>new Mixed4("hello") : C1 & M1 & M2 +>Mixed4 : typeof C1 & typeof M1 & typeof M2 +>"hello" : "hello" + + let x8 = new Mixed4(42); +>x8 : C1 & M1 & M2 +>new Mixed4(42) : C1 & M1 & M2 +>Mixed4 : typeof C1 & typeof M1 & typeof M2 +>42 : 42 + + let x9 = new Mixed5(); +>x9 : M1 & M2 +>new Mixed5() : M1 & M2 +>Mixed5 : typeof M1 & typeof M2 +} + +function f2() { +>f2 : () => void + + let x = new Mixed1("hello"); +>x : M1 & C1 +>new Mixed1("hello") : M1 & C1 +>Mixed1 : typeof M1 & typeof C1 +>"hello" : "hello" + + x.a; +>x.a : number +>x : M1 & C1 +>a : number + + x.p; +>x.p : number +>x : M1 & C1 +>p : number + + Mixed1.p; +>Mixed1.p : number +>Mixed1 : typeof M1 & typeof C1 +>p : number +} + +function f3() { +>f3 : () => void + + let x = new Mixed2("hello"); +>x : C1 & M1 +>new Mixed2("hello") : C1 & M1 +>Mixed2 : typeof C1 & typeof M1 +>"hello" : "hello" + + x.a; +>x.a : number +>x : C1 & M1 +>a : number + + x.p; +>x.p : number +>x : C1 & M1 +>p : number + + Mixed2.p; +>Mixed2.p : number +>Mixed2 : typeof C1 & typeof M1 +>p : number +} + +function f4() { +>f4 : () => void + + let x = new Mixed3("hello"); +>x : M2 & M1 & C1 +>new Mixed3("hello") : M2 & M1 & C1 +>Mixed3 : typeof M2 & typeof M1 & typeof C1 +>"hello" : "hello" + + x.a; +>x.a : number +>x : M2 & M1 & C1 +>a : number + + x.p; +>x.p : number +>x : M2 & M1 & C1 +>p : number + + x.f(); +>x.f() : number +>x.f : () => number +>x : M2 & M1 & C1 +>f : () => number + + Mixed3.p; +>Mixed3.p : number +>Mixed3 : typeof M2 & typeof M1 & typeof C1 +>p : number + + Mixed3.f(); +>Mixed3.f() : number +>Mixed3.f : () => number +>Mixed3 : typeof M2 & typeof M1 & typeof C1 +>f : () => number +} + +function f5() { +>f5 : () => void + + let x = new Mixed4("hello"); +>x : C1 & M1 & M2 +>new Mixed4("hello") : C1 & M1 & M2 +>Mixed4 : typeof C1 & typeof M1 & typeof M2 +>"hello" : "hello" + + x.a; +>x.a : number +>x : C1 & M1 & M2 +>a : number + + x.p; +>x.p : number +>x : C1 & M1 & M2 +>p : number + + x.f(); +>x.f() : number +>x.f : () => number +>x : C1 & M1 & M2 +>f : () => number + + Mixed4.p; +>Mixed4.p : number +>Mixed4 : typeof C1 & typeof M1 & typeof M2 +>p : number + + Mixed4.f(); +>Mixed4.f() : number +>Mixed4.f : () => number +>Mixed4 : typeof C1 & typeof M1 & typeof M2 +>f : () => number +} + +function f6() { +>f6 : () => void + + let x = new Mixed5(); +>x : M1 & M2 +>new Mixed5() : M1 & M2 +>Mixed5 : typeof M1 & typeof M2 + + x.p; +>x.p : number +>x : M1 & M2 +>p : number + + x.f(); +>x.f() : number +>x.f : () => number +>x : M1 & M2 +>f : () => number + + Mixed5.p; +>Mixed5.p : number +>Mixed5 : typeof M1 & typeof M2 +>p : number + + Mixed5.f(); +>Mixed5.f() : number +>Mixed5.f : () => number +>Mixed5 : typeof M1 & typeof M2 +>f : () => number +} + +class C2 extends Mixed1 { +>C2 : C2 +>Mixed1 : M1 & C1 + + constructor() { + super("hello"); +>super("hello") : void +>super : typeof M1 & typeof C1 +>"hello" : "hello" + + this.a; +>this.a : number +>this : this +>a : number + + this.b; +>this.b : number +>this : this +>b : number + + this.p; +>this.p : number +>this : this +>p : number + } +} + +class C3 extends Mixed3 { +>C3 : C3 +>Mixed3 : M2 & M1 & C1 + + constructor() { + super(42); +>super(42) : void +>super : typeof M2 & typeof M1 & typeof C1 +>42 : 42 + + this.a; +>this.a : number +>this : this +>a : number + + this.b; +>this.b : number +>this : this +>b : number + + this.p; +>this.p : number +>this : this +>p : number + + this.f(); +>this.f() : number +>this.f : () => number +>this : this +>f : () => number + } + f() { return super.f(); } +>f : () => number +>super.f() : number +>super.f : () => number +>super : M2 & M1 & C1 +>f : () => number +} + diff --git a/tests/cases/conformance/classes/mixinClassesAnnotated.ts b/tests/cases/conformance/classes/mixinClassesAnnotated.ts new file mode 100644 index 0000000000000..62f5e30c9a00d --- /dev/null +++ b/tests/cases/conformance/classes/mixinClassesAnnotated.ts @@ -0,0 +1,67 @@ +// @declaration: true + +type Constructor = new(...args: any[]) => T; + +class Base { + constructor(public x: number, public y: number) {} +} + +class Derived extends Base { + constructor(x: number, y: number, public z: number) { + super(x, y); + } +} + +interface Printable { + print(): void; +} + +const Printable = >(superClass: T): Constructor & { message: string } & T => + class extends superClass { + static message = "hello"; + print() { + const output = this.x + "," + this.y; + } + } + +interface Tagged { + _tag: string; +} + +function Tagged>(superClass: T): Constructor & T { + class C extends superClass { + _tag: string; + constructor(...args: any[]) { + super(...args); + this._tag = "hello"; + } + } + return C; +} + +const Thing1 = Tagged(Derived); +const Thing2 = Tagged(Printable(Derived)); +Thing2.message; + +function f1() { + const thing = new Thing1(1, 2, 3); + thing.x; + thing._tag; +} + +function f2() { + const thing = new Thing2(1, 2, 3); + thing.x; + thing._tag; + thing.print(); +} + +class Thing3 extends Thing2 { + constructor(tag: string) { + super(10, 20, 30); + this._tag = tag; + } + test() { + this.print(); + } +} diff --git a/tests/cases/conformance/classes/mixinClassesAnonymous.ts b/tests/cases/conformance/classes/mixinClassesAnonymous.ts new file mode 100644 index 0000000000000..24289b61e3eb7 --- /dev/null +++ b/tests/cases/conformance/classes/mixinClassesAnonymous.ts @@ -0,0 +1,56 @@ +type Constructor = new(...args: any[]) => T; + +class Base { + constructor(public x: number, public y: number) {} +} + +class Derived extends Base { + constructor(x: number, y: number, public z: number) { + super(x, y); + } +} + +const Printable = >(superClass: T) => class extends superClass { + static message = "hello"; + print() { + const output = this.x + "," + this.y; + } +} + +function Tagged>(superClass: T) { + class C extends superClass { + _tag: string; + constructor(...args: any[]) { + super(...args); + this._tag = "hello"; + } + } + return C; +} + +const Thing1 = Tagged(Derived); +const Thing2 = Tagged(Printable(Derived)); +Thing2.message; + +function f1() { + const thing = new Thing1(1, 2, 3); + thing.x; + thing._tag; +} + +function f2() { + const thing = new Thing2(1, 2, 3); + thing.x; + thing._tag; + thing.print(); +} + +class Thing3 extends Thing2 { + constructor(tag: string) { + super(10, 20, 30); + this._tag = tag; + } + test() { + this.print(); + } +} diff --git a/tests/cases/conformance/classes/mixinClassesMembers.ts b/tests/cases/conformance/classes/mixinClassesMembers.ts new file mode 100644 index 0000000000000..905518c88f8ef --- /dev/null +++ b/tests/cases/conformance/classes/mixinClassesMembers.ts @@ -0,0 +1,99 @@ +// @declaration: true + +declare class C1 { + public a: number; + protected b: number; + private c: number; + constructor(s: string); + constructor(n: number); +} + +declare class M1 { + constructor(...args: any[]); + p: number; + static p: number; +} + +declare class M2 { + constructor(...args: any[]); + f(): number; + static f(): number; +} + +declare const Mixed1: typeof M1 & typeof C1; +declare const Mixed2: typeof C1 & typeof M1; +declare const Mixed3: typeof M2 & typeof M1 & typeof C1; +declare const Mixed4: typeof C1 & typeof M1 & typeof M2; +declare const Mixed5: typeof M1 & typeof M2; + +function f1() { + let x1 = new Mixed1("hello"); + let x2 = new Mixed1(42); + let x3 = new Mixed2("hello"); + let x4 = new Mixed2(42); + let x5 = new Mixed3("hello"); + let x6 = new Mixed3(42); + let x7 = new Mixed4("hello"); + let x8 = new Mixed4(42); + let x9 = new Mixed5(); +} + +function f2() { + let x = new Mixed1("hello"); + x.a; + x.p; + Mixed1.p; +} + +function f3() { + let x = new Mixed2("hello"); + x.a; + x.p; + Mixed2.p; +} + +function f4() { + let x = new Mixed3("hello"); + x.a; + x.p; + x.f(); + Mixed3.p; + Mixed3.f(); +} + +function f5() { + let x = new Mixed4("hello"); + x.a; + x.p; + x.f(); + Mixed4.p; + Mixed4.f(); +} + +function f6() { + let x = new Mixed5(); + x.p; + x.f(); + Mixed5.p; + Mixed5.f(); +} + +class C2 extends Mixed1 { + constructor() { + super("hello"); + this.a; + this.b; + this.p; + } +} + +class C3 extends Mixed3 { + constructor() { + super(42); + this.a; + this.b; + this.p; + this.f(); + } + f() { return super.f(); } +}