Merge branch 'master' into genericDefaults

This commit is contained in:
Ron Buckton 2017-02-03 14:13:16 -08:00
commit 6ffcbf5b9c
64 changed files with 4044 additions and 747 deletions

View File

@ -8,11 +8,14 @@ Alexander Rusakov <a_s_rusakov@mail.ru>
Alex Eagle <alexeagle@google.com>
Anatoly Ressin <anatoly.ressin@icloud.com>
Anders Hejlsberg <andersh@microsoft.com> unknown <andersh@AndersX1.NOE.Nokia.com> unknown <andersh@andersh-yoga.redmond.corp.microsoft.com>
about-code <about-code@users.noreply.github.com> # Andreas Martin
Andrej Baran <andrej.baran@gmail.com>
Andrew Ochsner <andrew.ochsner@wipro.com>
Andrew Z Allen <me@andrewzallen.com>
Andy Hanson <anhans@microsoft.com> Andy <anhans@microsoft.com>
Anil Anar <anilanar@hotmail.com>
Anton Tolmachev <myste@mail.ru>
Anubha Mathur <anubmat@microsoft.com> anubmat <anubmat@microsoft.com>
Arnavion <arnavion@gmail.com> # Arnav Singh
Arthur Ozga <aozgaa@umich.edu> Arthur Ozga <t-arthoz@microsoft.com> Arthur Ozga <aozgaa-ms@outlook.com> Arthur Ozga <aozgaa@users.noreply.github.com> Arthur Ozga <arozga@microsoft.com>
Asad Saeeduddin <masaeedu@gmail.com>
@ -37,6 +40,7 @@ Dan Corder <dev@dancorder.com>
Dan Quirk <danquirk@microsoft.com> Dan Quirk <danquirk@users.noreply.github.com> nknown <danquirk@DANQUIRK1.redmond.corp.microsoft.com>
Daniel Rosenwasser <drosen@microsoft.com> Daniel Rosenwasser <DanielRosenwasser@users.noreply.github.com> Daniel Rosenwasser <DanielRosenwasser@gmail.com> Daniel Rosenwasser <Daniel.Rosenwasser@microsoft.com> Daniel Rosenwasser <DanielRosenwasser@microsoft.com>
David Li <jiawei.davidli@gmail.com>
David Sheldrick <david@futurice.com>
David Souther <davidsouther@gmail.com>
Denis Nedelyaev <denvned@gmail.com>
Dick van den Brink <d_vandenbrink@outlook.com> unknown <d_vandenbrink@outlook.com> unknown <d_vandenbrink@live.com>
@ -52,6 +56,7 @@ Evan Sebastian <evanlhoini@gmail.com>
Eyas <eyas.sharaiha@gmail.com> # Eyas Sharaiha
Fabian Cook <faybecook@gmail.com>
falsandtru <falsandtru@users.noreply.github.com> # @falsandtru
flowmemo <flowmemo@outlook.com> # @flowmemo
Frank Wallis <fwallis@outlook.com>
František Žiacik <fziacik@gratex.com> František Žiacik <ziacik@gmail.com>
Gabe Moothart <gmoothart@gmail.com>
@ -62,6 +67,7 @@ Graeme Wicksted <graeme.wicksted@gmail.com>
Guillaume Salles <guillaume.salles@me.com>
Guy Bedford <guybedford@gmail.com> guybedford <guybedford@gmail.com>
Harald Niesche <harald@niesche.de>
Homa Wong <homawong@gmail.com>
Iain Monro <iain.monro@softwire.com>
Ingvar Stepanyan <me@rreverser.com>
impinball <impinball@gmail.com> # Isiah Meadows
@ -81,6 +87,7 @@ Jonathan Park <jpark@daptiv.com>
Jonathan Turner <jont@microsoft.com> Jonathan Turner <probata@hotmail.com>
Jonathan Toland <toland@dnalot.com>
Jesse Schalken <me@jesseschalken.com>
Joel Day <joelday@gmail.com>
Josh Abernathy <joshaber@gmail.com> joshaber <joshaber@gmail.com>
Josh Kalderimis <josh.kalderimis@gmail.com>
Josh Soref <jsoref@users.noreply.github.com>
@ -95,10 +102,12 @@ Kanchalai Tanglertsampan <yuisu@microsoft.com> Yui T <yuisu@microsoft.com>
Kanchalai Tanglertsampan <yuisu@microsoft.com> Yui <yuit@users.noreply.github.com>
Kanchalai Tanglertsampan <yuisu@microsoft.com> Yui <yuisu@microsoft.com>
Kanchalai Tanglertsampan <yuisu@microsoft.com> yui T <yuisu@microsoft.com>
Kārlis Gaņģis <Knagis@users.noreply.github.com>
Keith Mashinter <kmashint@yahoo.com> kmashint <kmashint@yahoo.com>
Ken Howard <ken@simplicatedweb.com>
Kevin Lang <klang2012@gmail.com>
kimamula <kenji.imamula@gmail.com> # Kenji Imamula
Klaus Meinhardt <klaus.meinhardt1@gmail.com>
Kyle Kelley <rgbkrk@gmail.com>
Lorant Pinter <lorant.pinter@prezi.com>
Lucien Greathouse <me@lpghatguy.com>
@ -107,6 +116,7 @@ Martin Vseticka <vseticka.martin@gmail.com> Martin Všeticka <vseticka.martin@gm
gcnew <gcnew@abv.bg> # Marin Marinov
vvakame <vvakame+dev@gmail.com> # Masahiro Wakame
Matt McCutchen <rmccutch@mit.edu>
MANISH-GIRI <manish.giri.me@gmail.com> # Manish Giri
Max Deepfield <maxdeepfield@absolutefreakout.com>
Micah Zoltu <micah@zoltu.net>
Michael <maykelchiche@gmail.com>
@ -213,4 +223,6 @@ Tim Perry <tim.perry@softwire.com>
Vidar Tonaas Fauske <vidartf@gmail.com>
Viktor Zozulyak <zozulyakviktor@gmail.com>
rix <rix@rixs-MacBook-Pro.local> # Richard Sentino
rohitverma007 <rohitverma@live.ca> # Rohit Verma
rohitverma007 <rohitverma@live.ca> # Rohit Verma
rdosanjh <me@rajdeep.io> # Raj Dosanjh
gdh1995 <gdh1995@qq.com> # Dahan Gong

View File

@ -12,13 +12,16 @@ TypeScript is authored by:
* Aliaksandr Radzivanovich
* Anatoly Ressin
* Anders Hejlsberg
* Andreas Martin
* Andrej Baran
* Andrew Ochsner
* Andrew Z Allen
* András Parditka
* Andy Hanson
* Anil Anar
* Anton Khlynovskiy
* Anton Tolmachev
* Anubha Mathur
* Arnav Singh
* Arthur Ozga
* Asad Saeeduddin
@ -42,12 +45,14 @@ TypeScript is authored by:
* Cotton Hou
* Cyrus Najmabadi
* Dafrok Zhang
* Dahan Gong
* Dan Corder
* Dan Quirk
* Daniel Hollocher
* Daniel Rosenwasser
* David Kmenta
* David Li
* David Sheldrick
* David Souther
* Denis Nedelyaev
* Dick van den Brink
@ -66,6 +71,7 @@ TypeScript is authored by:
* Eyas Sharaiha
* Fabian Cook
* @falsandtru
* @flowmemo
* Frank Wallis
* Franklin Tse
* František Žiacik
@ -79,6 +85,7 @@ TypeScript is authored by:
* Guy Bedford
* Harald Niesche
* Herrington Darkholme
* Homa Wong
* Iain Monro
* Ingvar Stepanyan
* Isiah Meadows
@ -93,6 +100,7 @@ TypeScript is authored by:
* Jeffrey Morlan
* Jesse Schalken
* Jiri Tobisek
* Joel Day
* Joey Wilson
* Johannes Rieken
* John Vilk
@ -114,10 +122,13 @@ TypeScript is authored by:
* Ken Howard
* Kenji Imamula
* Kevin Lang
* Klaus Meinhardt
* Kyle Kelley
* Kārlis Gaņģis
* Lorant Pinter
* Lucien Greathouse
* Lukas Elmer
* Manish Giri
* Marin Marinov
* Marius Schulz
* Martin Vseticka
@ -155,6 +166,7 @@ TypeScript is authored by:
* @progre
* Punya Biswal
* Rado Kirov
* Raj Dosanjh
* Richard Knoll
* Richard Sentino
* Robert Coie

View File

@ -269,6 +269,7 @@ var harnessSources = harnessCoreSources.concat([
"projectErrors.ts",
"matchFiles.ts",
"initializeTSConfig.ts",
"printer.ts",
].map(function (f) {
return path.join(unittestsDirectory, f);
})).concat([

View File

@ -2480,7 +2480,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()) {
@ -3661,6 +3662,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) {
@ -3669,8 +3675,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;
@ -3834,8 +3845,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(<TypeVariable>type);
return isValidBaseType(constraint) && isMixinConstructorType(constraint);
}
return false;
}
function getBaseTypeNodeOfClass(type: InterfaceType): ExpressionWithTypeArguments {
@ -3914,7 +3943,7 @@ namespace ts {
function resolveBaseTypesOfClass(type: InterfaceType): void {
type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray;
const baseConstructorType = <ObjectType>getBaseConstructorTypeOfClass(type);
const baseConstructorType = getApparentType(getBaseConstructorTypeOfClass(type));
if (!(baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection))) {
return;
}
@ -3984,7 +4013,7 @@ namespace ts {
// A valid base type is any non-generic object type or intersection of non-generic
// object types.
function isValidBaseType(type: Type): boolean {
return type.flags & TypeFlags.Object && !isGenericMappedType(type) ||
return type.flags & (TypeFlags.Object | TypeFlags.NonPrimitive) && !isGenericMappedType(type) ||
type.flags & TypeFlags.Intersection && !forEach((<IntersectionType>type).types, t => !isValidBaseType(t));
}
@ -4565,16 +4594,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));
}
@ -4616,7 +4676,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));
}
@ -4892,7 +4952,7 @@ namespace ts {
}
function getApparentTypeOfIntersectionType(type: IntersectionType) {
return type.resolvedIndexType || (type.resolvedApparentType = getTypeWithThisArgument(type, type));
return type.resolvedApparentType || (type.resolvedApparentType = getTypeWithThisArgument(type, type));
}
/**
@ -4930,12 +4990,13 @@ namespace ts {
t.flags & TypeFlags.NumberLike ? globalNumberType :
t.flags & TypeFlags.BooleanLike ? globalBooleanType :
t.flags & TypeFlags.ESSymbol ? getGlobalESSymbolType() :
t.flags & TypeFlags.NonPrimitive ? globalObjectType :
t.flags & TypeFlags.NonPrimitive ? emptyObjectType :
t;
}
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;
@ -4945,7 +5006,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];
@ -6926,6 +6987,11 @@ namespace ts {
}
}
break;
case SyntaxKind.MappedType:
if (contains(mappedTypes, getDeclaredTypeOfTypeParameter(getSymbolOfNode((<MappedTypeNode>node).typeParameter)))) {
return true;
}
break;
case SyntaxKind.JSDocFunctionType:
const func = node as JSDocFunctionType;
for (const p of func.parameters) {
@ -7088,9 +7154,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((<IntersectionType>type).types, getTypeWithoutSignatures));
}
return type;
}
@ -7741,7 +7810,7 @@ namespace ts {
function isKnownProperty(type: Type, name: string): boolean {
if (type.flags & TypeFlags.Object) {
const resolved = resolveStructuredTypeMembers(<ObjectType>type);
if ((relation === assignableRelation || relation === comparableRelation) && (type === globalObjectType || isEmptyObjectType(resolved)) ||
if ((relation === assignableRelation || relation === comparableRelation) && (type === globalObjectType || isEmptyResolvedType(resolved)) ||
resolved.stringIndexInfo ||
(resolved.numberIndexInfo && isNumericLiteralName(name)) ||
getPropertyOfType(type, name)) {
@ -7758,7 +7827,7 @@ namespace ts {
return false;
}
function isEmptyObjectType(t: ResolvedType) {
function isEmptyResolvedType(t: ResolvedType) {
return t.properties.length === 0 &&
t.callSignatures.length === 0 &&
t.constructSignatures.length === 0 &&
@ -7766,6 +7835,10 @@ namespace ts {
!t.numberIndexInfo;
}
function isEmptyObjectType(type: Type) {
return type.flags & TypeFlags.Object && isEmptyResolvedType(resolveStructuredTypeMembers(<ObjectType>type));
}
function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean {
if (maybeTypeOfKind(target, TypeFlags.Object) && !(getObjectFlags(target) & ObjectFlags.ObjectLiteralPatternWithComputedProperties)) {
for (const prop of getPropertiesOfObjectType(source)) {
@ -7979,10 +8052,14 @@ namespace ts {
}
}
}
else if ((<MappedType>target).declaration.questionToken && isEmptyObjectType(source)) {
return Ternary.True;
}
}
else if (relation !== identityRelation) {
const resolved = resolveStructuredTypeMembers(<ObjectType>target);
if (isEmptyObjectType(resolved) || resolved.stringIndexInfo && resolved.stringIndexInfo.type.flags & TypeFlags.Any) {
if (isEmptyResolvedType(resolved) || resolved.stringIndexInfo && resolved.stringIndexInfo.type.flags & TypeFlags.Any) {
return Ternary.True;
}
}
@ -18637,7 +18714,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) {
@ -18651,6 +18729,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) &&
@ -18660,7 +18741,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

View File

@ -5,17 +5,16 @@ namespace ts {
export interface CommentWriter {
reset(): void;
setSourceFile(sourceFile: SourceFile): void;
emitNodeWithComments(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void;
setWriter(writer: EmitTextWriter): void;
emitNodeWithComments(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
emitBodyWithDetachedComments(node: Node, detachedRange: TextRange, emitCallback: (node: Node) => void): void;
emitTrailingCommentsOfPosition(pos: number): void;
}
export function createCommentWriter(host: EmitHost, writer: EmitTextWriter, sourceMap: SourceMapWriter): CommentWriter {
const compilerOptions = host.getCompilerOptions();
const extendedDiagnostics = compilerOptions.extendedDiagnostics;
const newLine = host.getNewLine();
const { emitPos } = sourceMap;
export function createCommentWriter(printerOptions: PrinterOptions, emitPos: ((pos: number) => void) | undefined): CommentWriter {
const extendedDiagnostics = printerOptions.extendedDiagnostics;
const newLine = getNewLineCharacter(printerOptions);
let writer: EmitTextWriter;
let containerPos = -1;
let containerEnd = -1;
let declarationListContainerEnd = -1;
@ -24,19 +23,20 @@ namespace ts {
let currentLineMap: number[];
let detachedCommentsInfo: { nodePos: number, detachedCommentEndPos: number}[];
let hasWrittenComment = false;
let disabled: boolean = compilerOptions.removeComments;
let disabled: boolean = printerOptions.removeComments;
return {
reset,
setWriter,
setSourceFile,
emitNodeWithComments,
emitBodyWithDetachedComments,
emitTrailingCommentsOfPosition,
};
function emitNodeWithComments(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
function emitNodeWithComments(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
if (disabled) {
emitCallback(emitContext, node);
emitCallback(hint, node);
return;
}
@ -47,11 +47,11 @@ namespace ts {
// Both pos and end are synthesized, so just emit the node without comments.
if (emitFlags & EmitFlags.NoNestedComments) {
disabled = true;
emitCallback(emitContext, node);
emitCallback(hint, node);
disabled = false;
}
else {
emitCallback(emitContext, node);
emitCallback(hint, node);
}
}
else {
@ -94,11 +94,11 @@ namespace ts {
if (emitFlags & EmitFlags.NoNestedComments) {
disabled = true;
emitCallback(emitContext, node);
emitCallback(hint, node);
disabled = false;
}
else {
emitCallback(emitContext, node);
emitCallback(hint, node);
}
if (extendedDiagnostics) {
@ -198,9 +198,9 @@ namespace ts {
}
// Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
emitPos(commentPos);
if (emitPos) emitPos(commentPos);
writeCommentRange(currentText, currentLineMap, writer, commentPos, commentEnd, newLine);
emitPos(commentEnd);
if (emitPos) emitPos(commentEnd);
if (hasTrailingNewLine) {
writer.writeLine();
@ -220,9 +220,9 @@ namespace ts {
writer.write(" ");
}
emitPos(commentPos);
if (emitPos) emitPos(commentPos);
writeCommentRange(currentText, currentLineMap, writer, commentPos, commentEnd, newLine);
emitPos(commentEnd);
if (emitPos) emitPos(commentEnd);
if (hasTrailingNewLine) {
writer.writeLine();
@ -248,9 +248,9 @@ namespace ts {
function emitTrailingCommentOfPosition(commentPos: number, commentEnd: number, _kind: SyntaxKind, hasTrailingNewLine: boolean) {
// trailing comments of a position are emitted at /*trailing comment1 */space/*trailing comment*/space
emitPos(commentPos);
if (emitPos) emitPos(commentPos);
writeCommentRange(currentText, currentLineMap, writer, commentPos, commentEnd, newLine);
emitPos(commentEnd);
if (emitPos) emitPos(commentEnd);
if (hasTrailingNewLine) {
writer.writeLine();
@ -286,6 +286,10 @@ namespace ts {
detachedCommentsInfo = undefined;
}
function setWriter(output: EmitTextWriter): void {
writer = output;
}
function setSourceFile(sourceFile: SourceFile) {
currentSourceFile = sourceFile;
currentText = currentSourceFile.text;
@ -323,9 +327,9 @@ namespace ts {
}
function writeComment(text: string, lineMap: number[], writer: EmitTextWriter, commentPos: number, commentEnd: number, newLine: string) {
emitPos(commentPos);
if (emitPos) emitPos(commentPos);
writeCommentRange(text, lineMap, writer, commentPos, commentEnd, newLine);
emitPos(commentEnd);
if (emitPos) emitPos(commentEnd);
}
/**

View File

@ -1447,7 +1447,7 @@ namespace ts {
return /^\.\.?($|[\\/])/.test(moduleName);
}
export function getEmitScriptTarget(compilerOptions: CompilerOptions) {
export function getEmitScriptTarget(compilerOptions: CompilerOptions | PrinterOptions) {
return compilerOptions.target || ScriptTarget.ES3;
}

View File

@ -35,13 +35,15 @@ namespace ts {
forEachEmittedFile(host, getDeclarationDiagnosticsFromFile, targetSourceFile);
return declarationDiagnostics.getDiagnostics(targetSourceFile ? targetSourceFile.fileName : undefined);
function getDeclarationDiagnosticsFromFile({ declarationFilePath }: EmitFileNames, sources: SourceFile[], isBundledEmit: boolean) {
emitDeclarations(host, resolver, declarationDiagnostics, declarationFilePath, sources, isBundledEmit, /*emitOnlyDtsFiles*/ false);
function getDeclarationDiagnosticsFromFile({ declarationFilePath }: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle) {
emitDeclarations(host, resolver, declarationDiagnostics, declarationFilePath, sourceFileOrBundle, /*emitOnlyDtsFiles*/ false);
}
}
function emitDeclarations(host: EmitHost, resolver: EmitResolver, emitterDiagnostics: DiagnosticCollection, declarationFilePath: string,
sourceFiles: SourceFile[], isBundledEmit: boolean, emitOnlyDtsFiles: boolean): DeclarationEmit {
sourceFileOrBundle: SourceFile | Bundle, emitOnlyDtsFiles: boolean): DeclarationEmit {
const sourceFiles = sourceFileOrBundle.kind === SyntaxKind.Bundle ? sourceFileOrBundle.sourceFiles : [sourceFileOrBundle];
const isBundledEmit = sourceFileOrBundle.kind === SyntaxKind.Bundle;
const newLine = host.getNewLine();
const compilerOptions = host.getCompilerOptions();
@ -1820,8 +1822,9 @@ namespace ts {
}
return addedBundledEmitReference;
function getDeclFileName(emitFileNames: EmitFileNames, _sourceFiles: SourceFile[], isBundledEmit: boolean) {
function getDeclFileName(emitFileNames: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle) {
// Dont add reference path to this file if it is a bundled emit and caller asked not emit bundled file path
const isBundledEmit = sourceFileOrBundle.kind === SyntaxKind.Bundle;
if (isBundledEmit && !addBundledFileReference) {
return;
}
@ -1834,10 +1837,11 @@ namespace ts {
}
/* @internal */
export function writeDeclarationFile(declarationFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean, host: EmitHost, resolver: EmitResolver, emitterDiagnostics: DiagnosticCollection, emitOnlyDtsFiles: boolean) {
const emitDeclarationResult = emitDeclarations(host, resolver, emitterDiagnostics, declarationFilePath, sourceFiles, isBundledEmit, emitOnlyDtsFiles);
export function writeDeclarationFile(declarationFilePath: string, sourceFileOrBundle: SourceFile | Bundle, host: EmitHost, resolver: EmitResolver, emitterDiagnostics: DiagnosticCollection, emitOnlyDtsFiles: boolean) {
const emitDeclarationResult = emitDeclarations(host, resolver, emitterDiagnostics, declarationFilePath, sourceFileOrBundle, emitOnlyDtsFiles);
const emitSkipped = emitDeclarationResult.reportedDeclarationError || host.isEmitBlocked(declarationFilePath) || host.getCompilerOptions().noEmit;
if (!emitSkipped) {
const sourceFiles = sourceFileOrBundle.kind === SyntaxKind.Bundle ? sourceFileOrBundle.sourceFiles : [sourceFileOrBundle];
const declarationOutput = emitDeclarationResult.referencesOutput
+ getDeclarationOutput(emitDeclarationResult.synchronousDeclarationOutput, emitDeclarationResult.moduleElementDeclarationEmitInfo);
writeFile(host, emitterDiagnostics, declarationFilePath, declarationOutput, host.getCompilerOptions().emitBOM, sourceFiles);

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -1530,6 +1530,19 @@ namespace ts {
return node;
}
export function createBundle(sourceFiles: SourceFile[]) {
const node = <Bundle>createNode(SyntaxKind.Bundle);
node.sourceFiles = sourceFiles;
return node;
}
export function updateBundle(node: Bundle, sourceFiles: SourceFile[]) {
if (node.sourceFiles !== sourceFiles) {
return createBundle(sourceFiles);
}
return node;
}
// Compound nodes
export function createComma(left: Expression, right: Expression) {

View File

@ -8,10 +8,9 @@ namespace ts {
*
* @param filePath The path to the generated output file.
* @param sourceMapFilePath The path to the output source map file.
* @param sourceFiles The input source files for the program.
* @param isBundledEmit A value indicating whether the generated output file is a bundle.
* @param sourceFileOrBundle The input source file or bundle for the program.
*/
initialize(filePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean): void;
initialize(filePath: string, sourceMapFilePath: string, sourceFileOrBundle: SourceFile | Bundle): void;
/**
* Reset the SourceMapWriter to an empty state.
@ -38,11 +37,11 @@ namespace ts {
/**
* Emits a node with possible leading and trailing source maps.
*
* @param emitContext The current emit context
* @param hint The current emit context
* @param node The node to emit.
* @param emitCallback The callback used to emit the node.
*/
emitNodeWithSourceMap(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void;
emitNodeWithSourceMap(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
/**
* Emits a token of a node node with possible leading and trailing source maps.
@ -115,10 +114,9 @@ namespace ts {
*
* @param filePath The path to the generated output file.
* @param sourceMapFilePath The path to the output source map file.
* @param sourceFiles The input source files for the program.
* @param isBundledEmit A value indicating whether the generated output file is a bundle.
* @param sourceFileOrBundle The input source file or bundle for the program.
*/
function initialize(filePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean) {
function initialize(filePath: string, sourceMapFilePath: string, sourceFileOrBundle: SourceFile | Bundle) {
if (disabled) {
return;
}
@ -161,11 +159,10 @@ namespace ts {
if (compilerOptions.mapRoot) {
sourceMapDir = normalizeSlashes(compilerOptions.mapRoot);
if (!isBundledEmit) { // emitting single module file
Debug.assert(sourceFiles.length === 1);
if (sourceFileOrBundle.kind === SyntaxKind.SourceFile) { // emitting single module file
// For modules or multiple emit files the mapRoot will have directory structure like the sources
// So if src\a.ts and src\lib\b.ts are compiled together user would be moving the maps into mapRoot\a.js.map and mapRoot\lib\b.js.map
sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(sourceFiles[0], host, sourceMapDir));
sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(sourceFileOrBundle, host, sourceMapDir));
}
if (!isRootedDiskPath(sourceMapDir) && !isUrl(sourceMapDir)) {
@ -311,12 +308,13 @@ namespace ts {
/**
* Emits a node with possible leading and trailing source maps.
*
* @param hint A hint as to the intended usage of the node.
* @param node The node to emit.
* @param emitCallback The callback used to emit the node.
*/
function emitNodeWithSourceMap(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
function emitNodeWithSourceMap(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
if (disabled) {
return emitCallback(emitContext, node);
return emitCallback(hint, node);
}
if (node) {
@ -332,11 +330,11 @@ namespace ts {
if (emitFlags & EmitFlags.NoNestedSourceMaps) {
disabled = true;
emitCallback(emitContext, node);
emitCallback(hint, node);
disabled = false;
}
else {
emitCallback(emitContext, node);
emitCallback(hint, node);
}
if (node.kind !== SyntaxKind.NotEmittedStatement

View File

@ -105,14 +105,16 @@ namespace ts {
hoistFunctionDeclaration,
requestEmitHelper,
readEmitHelpers,
onSubstituteNode: (_emitContext, node) => node,
onSubstituteNode: (_, node) => node,
enableSubstitution,
isSubstitutionEnabled,
onEmitNode: (node, emitContext, emitCallback) => emitCallback(node, emitContext),
onEmitNode: (hint, node, callback) => callback(hint, node),
enableEmitNotification,
isEmitNotificationEnabled
};
performance.mark("beforeTransform");
// Chain together and initialize each transformer.
const transformation = chain(...transformers)(context);
@ -122,6 +124,9 @@ namespace ts {
// Disable modification of the lexical environment.
lexicalEnvironmentDisabled = true;
performance.mark("afterTransform");
performance.measure("transformTime", "beforeTransform", "afterTransform");
return {
transformed,
emitNodeWithSubstitution,
@ -159,21 +164,16 @@ namespace ts {
/**
* Emits a node with possible substitution.
*
* @param emitContext The current emit context.
* @param hint A hint as to the intended usage of the node.
* @param node The node to emit.
* @param emitCallback The callback used to emit the node or its substitute.
*/
function emitNodeWithSubstitution(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
function emitNodeWithSubstitution(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
if (node) {
if (isSubstitutionEnabled(node)) {
const substitute = context.onSubstituteNode(emitContext, node);
if (substitute && substitute !== node) {
emitCallback(emitContext, substitute);
return;
}
node = context.onSubstituteNode(hint, node) || node;
}
emitCallback(emitContext, node);
emitCallback(hint, node);
}
}
@ -196,17 +196,17 @@ namespace ts {
/**
* Emits a node with possible emit notification.
*
* @param emitContext The current emit context.
* @param hint A hint as to the intended usage of the node.
* @param node The node to emit.
* @param emitCallback The callback used to emit the node.
*/
function emitNodeWithNotification(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
function emitNodeWithNotification(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
if (node) {
if (isEmitNotificationEnabled(node)) {
context.onEmitNode(emitContext, node, emitCallback);
context.onEmitNode(hint, node, emitCallback);
}
else {
emitCallback(emitContext, node);
emitCallback(hint, node);
}
}
}

View File

@ -3435,9 +3435,11 @@ namespace ts {
/**
* Called by the printer just before a node is printed.
*
* @param hint A hint as to the intended usage of the node.
* @param node The node to be printed.
* @param emitCallback The callback used to emit the node.
*/
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
if (enabledSubstitutions & ES2015SubstitutionFlags.CapturedThis && isFunctionLike(node)) {
// If we are tracking a captured `this`, keep track of the enclosing function.
const ancestorFacts = enterSubtree(
@ -3445,11 +3447,11 @@ namespace ts {
getEmitFlags(node) & EmitFlags.CapturesThis
? HierarchyFacts.FunctionIncludes | HierarchyFacts.CapturesThis
: HierarchyFacts.FunctionIncludes);
previousOnEmitNode(emitContext, node, emitCallback);
previousOnEmitNode(hint, node, emitCallback);
exitSubtree(ancestorFacts, HierarchyFacts.None, HierarchyFacts.None);
return;
}
previousOnEmitNode(emitContext, node, emitCallback);
previousOnEmitNode(hint, node, emitCallback);
}
/**
@ -3484,13 +3486,13 @@ namespace ts {
/**
* Hooks node substitutions.
*
* @param emitContext The context for the emitter.
* @param hint The context for the emitter.
* @param node The node to substitute.
*/
function onSubstituteNode(emitContext: EmitContext, node: Node) {
node = previousOnSubstituteNode(emitContext, node);
function onSubstituteNode(hint: EmitHint, node: Node) {
node = previousOnSubstituteNode(hint, node);
if (emitContext === EmitContext.Expression) {
if (hint === EmitHint.Expression) {
return substituteExpression(node);
}

View File

@ -396,33 +396,33 @@ namespace ts {
/**
* Hook for node emit.
*
* @param hint A hint as to the intended usage of the node.
* @param node The node to emit.
* @param emit A callback used to emit the node in the printer.
*/
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void {
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void {
// If we need to support substitutions for `super` in an async method,
// we should track it here.
if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper && isSuperContainer(node)) {
const savedCurrentSuperContainer = currentSuperContainer;
currentSuperContainer = node;
previousOnEmitNode(emitContext, node, emitCallback);
previousOnEmitNode(hint, node, emitCallback);
currentSuperContainer = savedCurrentSuperContainer;
}
else {
previousOnEmitNode(emitContext, node, emitCallback);
previousOnEmitNode(hint, node, emitCallback);
}
}
/**
* Hooks node substitutions.
*
* @param hint A hint as to the intended usage of the node.
* @param node The node to substitute.
* @param isExpression A value indicating whether the node is to be used in an expression
* position.
*/
function onSubstituteNode(emitContext: EmitContext, node: Node) {
node = previousOnSubstituteNode(emitContext, node);
if (emitContext === EmitContext.Expression) {
function onSubstituteNode(hint: EmitHint, node: Node) {
node = previousOnSubstituteNode(hint, node);
if (hint === EmitHint.Expression) {
return substituteExpression(<Expression>node);
}

View File

@ -12,7 +12,7 @@ namespace ts {
const compilerOptions = context.getCompilerOptions();
// enable emit notification only if using --jsx preserve or react-native
let previousOnEmitNode: (emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) => void;
let previousOnEmitNode: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void;
let noSubstitution: boolean[];
if (compilerOptions.jsx === JsxEmit.Preserve || compilerOptions.jsx === JsxEmit.ReactNative) {
previousOnEmitNode = context.onEmitNode;
@ -41,9 +41,11 @@ namespace ts {
/**
* Called by the printer just before a node is printed.
*
* @param node The node to be printed.
* @param hint A hint as to the intended usage of the node.
* @param node The node to emit.
* @param emitCallback A callback used to emit the node.
*/
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (emitContext: EmitHint, node: Node) => void) {
switch (node.kind) {
case SyntaxKind.JsxOpeningElement:
case SyntaxKind.JsxClosingElement:
@ -53,21 +55,21 @@ namespace ts {
break;
}
previousOnEmitNode(emitContext, node, emitCallback);
previousOnEmitNode(hint, node, emitCallback);
}
/**
* Hooks node substitutions.
*
* @param emitContext The context for the emitter.
* @param hint A hint as to the intended usage of the node.
* @param node The node to substitute.
*/
function onSubstituteNode(emitContext: EmitContext, node: Node) {
function onSubstituteNode(hint: EmitHint, node: Node) {
if (node.id && noSubstitution && noSubstitution[node.id]) {
return previousOnSubstituteNode(emitContext, node);
return previousOnSubstituteNode(hint, node);
}
node = previousOnSubstituteNode(emitContext, node);
node = previousOnSubstituteNode(hint, node);
if (isPropertyAccessExpression(node)) {
return substitutePropertyAccessExpression(node);
}

View File

@ -1909,9 +1909,9 @@ namespace ts {
return -1;
}
function onSubstituteNode(emitContext: EmitContext, node: Node): Node {
node = previousOnSubstituteNode(emitContext, node);
if (emitContext === EmitContext.Expression) {
function onSubstituteNode(hint: EmitHint, node: Node): Node {
node = previousOnSubstituteNode(hint, node);
if (hint === EmitHint.Expression) {
return substituteExpression(<Expression>node);
}
return node;

View File

@ -71,18 +71,18 @@ namespace ts {
/**
* Hook for node emit.
*
* @param emitContext A context hint for the emitter.
* @param hint A hint as to the intended usage of the node.
* @param node The node to emit.
* @param emit A callback used to emit the node in the printer.
*/
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void {
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void {
if (isSourceFile(node)) {
currentSourceFile = node;
previousOnEmitNode(emitContext, node, emitCallback);
previousOnEmitNode(hint, node, emitCallback);
currentSourceFile = undefined;
}
else {
previousOnEmitNode(emitContext, node, emitCallback);
previousOnEmitNode(hint, node, emitCallback);
}
}
@ -93,12 +93,12 @@ namespace ts {
/**
* Hooks node substitutions.
*
* @param emitContext A context hint for the emitter.
* @param hint A hint as to the intended usage of the node.
* @param node The node to substitute.
*/
function onSubstituteNode(emitContext: EmitContext, node: Node) {
node = previousOnSubstituteNode(emitContext, node);
if (isIdentifier(node) && emitContext === EmitContext.Expression) {
function onSubstituteNode(hint: EmitHint, node: Node) {
node = previousOnSubstituteNode(hint, node);
if (isIdentifier(node) && hint === EmitHint.Expression) {
return substituteExpressionIdentifier(node);
}
return node;

View File

@ -1207,24 +1207,24 @@ namespace ts {
/**
* Hook for node emit notifications.
*
* @param emitContext A context hint for the emitter.
* @param hint A hint as to the intended usage of the node.
* @param node The node to emit.
* @param emit A callback used to emit the node in the printer.
*/
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void {
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void {
if (node.kind === SyntaxKind.SourceFile) {
currentSourceFile = <SourceFile>node;
currentModuleInfo = moduleInfoMap[getOriginalNodeId(currentSourceFile)];
noSubstitution = [];
previousOnEmitNode(emitContext, node, emitCallback);
previousOnEmitNode(hint, node, emitCallback);
currentSourceFile = undefined;
currentModuleInfo = undefined;
noSubstitution = undefined;
}
else {
previousOnEmitNode(emitContext, node, emitCallback);
previousOnEmitNode(hint, node, emitCallback);
}
}
@ -1235,16 +1235,16 @@ namespace ts {
/**
* Hooks node substitutions.
*
* @param emitContext A context hint for the emitter.
* @param hint A hint as to the intended usage of the node.
* @param node The node to substitute.
*/
function onSubstituteNode(emitContext: EmitContext, node: Node) {
node = previousOnSubstituteNode(emitContext, node);
function onSubstituteNode(hint: EmitHint, node: Node) {
node = previousOnSubstituteNode(hint, node);
if (node.id && noSubstitution[node.id]) {
return node;
}
if (emitContext === EmitContext.Expression) {
if (hint === EmitHint.Expression) {
return substituteExpression(<Expression>node);
}
else if (isShorthandPropertyAssignment(node)) {

View File

@ -1548,11 +1548,11 @@ namespace ts {
/**
* Hook for node emit notifications.
*
* @param emitContext A context hint for the emitter.
* @param hint A hint as to the intended usage of the node.
* @param node The node to emit.
* @param emit A callback used to emit the node in the printer.
* @param emitCallback A callback used to emit the node in the printer.
*/
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void {
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void {
if (node.kind === SyntaxKind.SourceFile) {
const id = getOriginalNodeId(node);
currentSourceFile = <SourceFile>node;
@ -1564,7 +1564,7 @@ namespace ts {
delete noSubstitutionMap[id];
}
previousOnEmitNode(emitContext, node, emitCallback);
previousOnEmitNode(hint, node, emitCallback);
currentSourceFile = undefined;
moduleInfo = undefined;
@ -1572,7 +1572,7 @@ namespace ts {
noSubstitution = undefined;
}
else {
previousOnEmitNode(emitContext, node, emitCallback);
previousOnEmitNode(hint, node, emitCallback);
}
}
@ -1583,16 +1583,16 @@ namespace ts {
/**
* Hooks node substitutions.
*
* @param emitContext A context hint for the emitter.
* @param hint A hint as to the intended usage of the node.
* @param node The node to substitute.
*/
function onSubstituteNode(emitContext: EmitContext, node: Node) {
node = previousOnSubstituteNode(emitContext, node);
function onSubstituteNode(hint: EmitHint, node: Node) {
node = previousOnSubstituteNode(hint, node);
if (isSubstitutionPrevented(node)) {
return node;
}
if (emitContext === EmitContext.Expression) {
if (hint === EmitHint.Expression) {
return substituteExpression(<Expression>node);
}

View File

@ -3154,11 +3154,11 @@ namespace ts {
/**
* Hook for node emit.
*
* @param emitContext A context hint for the emitter.
* @param hint A hint as to the intended usage of the node.
* @param node The node to emit.
* @param emit A callback used to emit the node in the printer.
*/
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void {
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void {
const savedApplicableSubstitutions = applicableSubstitutions;
if (enabledSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports && isTransformedModuleDeclaration(node)) {
@ -3169,7 +3169,7 @@ namespace ts {
applicableSubstitutions |= TypeScriptSubstitutionFlags.NonQualifiedEnumMembers;
}
previousOnEmitNode(emitContext, node, emitCallback);
previousOnEmitNode(hint, node, emitCallback);
applicableSubstitutions = savedApplicableSubstitutions;
}
@ -3177,12 +3177,12 @@ namespace ts {
/**
* Hooks node substitutions.
*
* @param emitContext A context hint for the emitter.
* @param hint A hint as to the intended usage of the node.
* @param node The node to substitute.
*/
function onSubstituteNode(emitContext: EmitContext, node: Node) {
node = previousOnSubstituteNode(emitContext, node);
if (emitContext === EmitContext.Expression) {
function onSubstituteNode(hint: EmitHint, node: Node) {
node = previousOnSubstituteNode(hint, node);
if (hint === EmitHint.Expression) {
return substituteExpression(<Expression>node);
}
else if (isShorthandPropertyAssignment(node)) {

View File

@ -348,6 +348,7 @@
EnumMember,
// Top-level nodes
SourceFile,
Bundle,
// JSDoc nodes
JSDocTypeExpression,
@ -2202,6 +2203,11 @@
/* @internal */ ambientModuleNames: string[];
}
export interface Bundle extends Node {
kind: SyntaxKind.Bundle;
sourceFiles: SourceFile[];
}
export interface ScriptReferenceHost {
getCompilerOptions(): CompilerOptions;
getSourceFile(fileName: string): SourceFile;
@ -3784,8 +3790,7 @@
LastEmitHelper = Generator
}
/* @internal */
export const enum EmitContext {
export const enum EmitHint {
SourceFile, // Emitting a SourceFile
Expression, // Emitting an Expression
IdentifierName, // Emitting an IdentifierName
@ -3860,7 +3865,7 @@
* Hook used by transformers to substitute expressions just before they
* are emitted by the pretty printer.
*/
onSubstituteNode?: (emitContext: EmitContext, node: Node) => Node;
onSubstituteNode?: (hint: EmitHint, node: Node) => Node;
/**
* Enables before/after emit notifications in the pretty printer for the provided
@ -3878,7 +3883,7 @@
* Hook used to allow transformers to capture state before or after
* the printer emits a node.
*/
onEmitNode?: (emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) => void;
onEmitNode?: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void;
}
/* @internal */
@ -3891,25 +3896,132 @@
/**
* Emits the substitute for a node, if one is available; otherwise, emits the node.
*
* @param emitContext The current emit context.
* @param hint A hint as to the intended usage of the node.
* @param node The node to substitute.
* @param emitCallback A callback used to emit the node or its substitute.
*/
emitNodeWithSubstitution(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void;
emitNodeWithSubstitution(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
/**
* Emits a node with possible notification.
*
* @param emitContext The current emit context.
* @param hint A hint as to the intended usage of the node.
* @param node The node to emit.
* @param emitCallback A callback used to emit the node.
*/
emitNodeWithNotification(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void;
emitNodeWithNotification(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
}
/* @internal */
export type Transformer = (context: TransformationContext) => (node: SourceFile) => SourceFile;
export interface Printer {
/**
* Print a node and its subtree as-is, without any emit transformations.
* @param hint A value indicating the purpose of a node. This is primarily used to
* distinguish between an `Identifier` used in an expression position, versus an
* `Identifier` used as an `IdentifierName` as part of a declaration. For most nodes you
* should just pass `Unspecified`.
* @param node The node to print. The node and its subtree are printed as-is, without any
* emit transformations.
* @param sourceFile A source file that provides context for the node. The source text of
* the file is used to emit the original source content for literals and identifiers, while
* the identifiers of the source file are used when generating unique names to avoid
* collisions.
*/
printNode(hint: EmitHint, node: Node, sourceFile: SourceFile): string;
/**
* Prints a source file as-is, without any emit transformations.
*/
printFile(sourceFile: SourceFile): string;
/**
* Prints a bundle of source files as-is, without any emit transformations.
*/
printBundle(bundle: Bundle): string;
/*@internal*/ writeNode(hint: EmitHint, node: Node, sourceFile: SourceFile, writer: EmitTextWriter): void;
/*@internal*/ writeFile(sourceFile: SourceFile, writer: EmitTextWriter): void;
/*@internal*/ writeBundle(bundle: Bundle, writer: EmitTextWriter): void;
}
export interface PrintHandlers {
/**
* A hook used by the Printer when generating unique names to avoid collisions with
* globally defined names that exist outside of the current source file.
*/
hasGlobalName?(name: string): boolean;
/**
* A hook used by the Printer to provide notifications prior to emitting a node. A
* compatible implementation **must** invoke `emitCallback` with the provided `hint` and
* `node` values.
* @param hint A hint indicating the intended purpose of the node.
* @param node The node to emit.
* @param emitCallback A callback that, when invoked, will emit the node.
* @example
* ```ts
* var printer = createPrinter(printerOptions, {
* onEmitNode(hint, node, emitCallback) {
* // set up or track state prior to emitting the node...
* emitCallback(hint, node);
* // restore state after emitting the node...
* }
* });
* ```
*/
onEmitNode?(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
/**
* A hook used by the Printer to perform just-in-time substitution of a node. This is
* primarily used by node transformations that need to substitute one node for another,
* such as replacing `myExportedVar` with `exports.myExportedVar`. A compatible
* implementation **must** invoke `emitCallback` eith the provided `hint` and either
* the provided `node`, or its substitute.
* @param hint A hint indicating the intended purpose of the node.
* @param node The node to emit.
* @param emitCallback A callback that, when invoked, will emit the node.
* @example
* ```ts
* var printer = createPrinter(printerOptions, {
* onSubstituteNode(hint, node, emitCallback) {
* // perform substitution if necessary...
* emitCallback(hint, node);
* }
* });
* ```
*/
onSubstituteNode?(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
/*@internal*/ onEmitSourceMapOfNode?: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void;
/*@internal*/ onEmitSourceMapOfToken?: (node: Node, token: SyntaxKind, pos: number, emitCallback: (token: SyntaxKind, pos: number) => number) => number;
/*@internal*/ onEmitSourceMapOfPosition?: (pos: number) => void;
/*@internal*/ onEmitHelpers?: (node: Node, writeLines: (text: string) => void) => void;
/*@internal*/ onSetSourceFile?: (node: SourceFile) => void;
}
export interface PrinterOptions {
target?: ScriptTarget;
removeComments?: boolean;
newLine?: NewLineKind;
/*@internal*/ sourceMap?: boolean;
/*@internal*/ inlineSourceMap?: boolean;
/*@internal*/ extendedDiagnostics?: boolean;
}
/*@internal*/
export interface EmitTextWriter {
write(s: string): void;
writeTextOfNode(text: string, node: Node): void;
writeLine(): void;
increaseIndent(): void;
decreaseIndent(): void;
getText(): string;
rawWrite(s: string): void;
writeLiteral(s: string): void;
getTextPos(): number;
getLine(): number;
getColumn(): number;
getIndent(): number;
isAtStartOfLine(): boolean;
reset(): void;
}
export interface TextSpan {
start: number;
length: number;

View File

@ -2107,16 +2107,19 @@ namespace ts {
return undefined;
}
export function getOriginalSourceFiles(sourceFiles: SourceFile[]) {
const originalSourceFiles: SourceFile[] = [];
for (const sourceFile of sourceFiles) {
const originalSourceFile = getParseTreeNode(sourceFile, isSourceFile);
if (originalSourceFile) {
originalSourceFiles.push(originalSourceFile);
}
export function getOriginalSourceFileOrBundle(sourceFileOrBundle: SourceFile | Bundle) {
if (sourceFileOrBundle.kind === SyntaxKind.Bundle) {
return updateBundle(sourceFileOrBundle, sameMap(sourceFileOrBundle.sourceFiles, getOriginalSourceFile));
}
return getOriginalSourceFile(sourceFileOrBundle);
}
return originalSourceFiles;
function getOriginalSourceFile(sourceFile: SourceFile) {
return getParseTreeNode(sourceFile, isSourceFile) || sourceFile;
}
export function getOriginalSourceFiles(sourceFiles: SourceFile[]) {
return sameMap(sourceFiles, getOriginalSourceFile);
}
export function getOriginalNodeId(node: Node) {
@ -2455,23 +2458,6 @@ namespace ts {
s;
}
export interface EmitTextWriter {
write(s: string): void;
writeTextOfNode(text: string, node: Node): void;
writeLine(): void;
increaseIndent(): void;
decreaseIndent(): void;
getText(): string;
rawWrite(s: string): void;
writeLiteral(s: string): void;
getTextPos(): number;
getLine(): number;
getColumn(): number;
getIndent(): number;
isAtStartOfLine(): boolean;
reset(): void;
}
const indentStrings: string[] = ["", " "];
export function getIndentString(level: number) {
if (indentStrings[level] === undefined) {
@ -2654,7 +2640,7 @@ namespace ts {
* Else, calls `getSourceFilesToEmit` with the (optional) target source file to determine the list of source files to emit.
*/
export function forEachEmittedFile(
host: EmitHost, action: (emitFileNames: EmitFileNames, sourceFiles: SourceFile[], isBundledEmit: boolean, emitOnlyDtsFiles: boolean) => void,
host: EmitHost, action: (emitFileNames: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle, emitOnlyDtsFiles: boolean) => void,
sourceFilesOrTargetSourceFile?: SourceFile[] | SourceFile,
emitOnlyDtsFiles?: boolean) {
@ -2665,7 +2651,7 @@ namespace ts {
const jsFilePath = options.outFile || options.out;
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
const declarationFilePath = options.declaration ? removeFileExtension(jsFilePath) + ".d.ts" : undefined;
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, sourceFiles, /*isBundledEmit*/true, emitOnlyDtsFiles);
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, createBundle(sourceFiles), emitOnlyDtsFiles);
}
}
else {
@ -2673,7 +2659,7 @@ namespace ts {
const jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, getOutputExtension(sourceFile, options));
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
const declarationFilePath = !isSourceFileJavaScript(sourceFile) && (emitOnlyDtsFiles || options.declaration) ? getDeclarationEmitOutputFilePath(sourceFile, host) : undefined;
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, [sourceFile], /*isBundledEmit*/false, emitOnlyDtsFiles);
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, sourceFile, emitOnlyDtsFiles);
}
}
}
@ -3248,7 +3234,7 @@ namespace ts {
const carriageReturnLineFeed = "\r\n";
const lineFeed = "\n";
export function getNewLineCharacter(options: CompilerOptions): string {
export function getNewLineCharacter(options: CompilerOptions | PrinterOptions): string {
if (options.newLine === NewLineKind.CarriageReturnLineFeed) {
return carriageReturnLineFeed;
}

View File

@ -118,6 +118,7 @@
"./unittests/initializeTSConfig.ts",
"./unittests/compileOnSave.ts",
"./unittests/typingsInstaller.ts",
"./unittests/projectErrors.ts"
"./unittests/projectErrors.ts",
"./unittests/printer.ts"
]
}

View File

@ -0,0 +1,97 @@
/// <reference path="..\..\compiler\emitter.ts" />
/// <reference path="..\harness.ts" />
namespace ts {
describe("PrinterAPI", () => {
function makePrintsCorrectly(prefix: string) {
return function printsCorrectly(name: string, options: PrinterOptions, printCallback: (printer: Printer) => string) {
it(name, () => {
Harness.Baseline.runBaseline(`printerApi/${prefix}.${name}.js`, () =>
printCallback(createPrinter({ newLine: NewLineKind.CarriageReturnLineFeed, ...options })));
});
}
}
describe("printFile", () => {
const printsCorrectly = makePrintsCorrectly("printsFileCorrectly");
const sourceFile = createSourceFile("source.ts", `
interface A<T> {
// comment1
readonly prop?: T;
// comment2
method(): void;
// comment3
new <T>(): A<T>;
// comment4
<T>(): A<T>;
}
// comment5
type B = number | string | object;
type C = A<number> & { x: string; }; // comment6
// comment7
enum E1 {
// comment8
first
}
const enum E2 {
second
}
// comment9
console.log(1 + 2);
`, ScriptTarget.ES2015);
printsCorrectly("default", {}, printer => printer.printFile(sourceFile));
printsCorrectly("removeComments", { removeComments: true }, printer => printer.printFile(sourceFile));
});
describe("printBundle", () => {
const printsCorrectly = makePrintsCorrectly("printsBundleCorrectly");
const bundle = createBundle([
createSourceFile("a.ts", `
/*! [a.ts] */
// comment0
const a = 1;
`, ScriptTarget.ES2015),
createSourceFile("b.ts", `
/*! [b.ts] */
// comment1
const b = 2;
`, ScriptTarget.ES2015)
]);
printsCorrectly("default", {}, printer => printer.printBundle(bundle));
printsCorrectly("removeComments", { removeComments: true }, printer => printer.printBundle(bundle));
});
describe("printNode", () => {
const printsCorrectly = makePrintsCorrectly("printsNodeCorrectly");
const sourceFile = createSourceFile("source.ts", "", ScriptTarget.ES2015);
const syntheticNode = createClassDeclaration(
undefined,
undefined,
/*name*/ createIdentifier("C"),
undefined,
undefined,
createNodeArray([
createProperty(
undefined,
createNodeArray([createToken(SyntaxKind.PublicKeyword)]),
createIdentifier("prop"),
undefined,
undefined,
undefined
)
])
);
printsCorrectly("class", {}, printer => printer.printNode(EmitHint.Unspecified, syntheticNode, sourceFile));
});
});
}

View File

@ -44,6 +44,8 @@ namespace ts.projectSystem {
});
}
import typingsName = server.typingsInstaller.typingsName;
describe("typingsInstaller", () => {
it("configured projects (typings installed) 1", () => {
const file1 = {
@ -519,32 +521,32 @@ namespace ts.projectSystem {
const commander = {
path: "/a/data/node_modules/@types/commander/index.d.ts",
content: "declare const commander: { x: number }",
typings: "@types/commander"
typings: typingsName("commander")
};
const jquery = {
path: "/a/data/node_modules/@types/jquery/index.d.ts",
content: "declare const jquery: { x: number }",
typings: "@types/jquery"
typings: typingsName("jquery")
};
const lodash = {
path: "/a/data/node_modules/@types/lodash/index.d.ts",
content: "declare const lodash: { x: number }",
typings: "@types/lodash"
typings: typingsName("lodash")
};
const cordova = {
path: "/a/data/node_modules/@types/cordova/index.d.ts",
content: "declare const cordova: { x: number }",
typings: "@types/cordova"
typings: typingsName("cordova")
};
const grunt = {
path: "/a/data/node_modules/@types/grunt/index.d.ts",
content: "declare const grunt: { x: number }",
typings: "@types/grunt"
typings: typingsName("grunt")
};
const gulp = {
path: "/a/data/node_modules/@types/gulp/index.d.ts",
content: "declare const gulp: { x: number }",
typings: "@types/gulp"
typings: typingsName("gulp")
};
const host = createServerHost([lodashJs, commanderJs, file3]);
@ -554,7 +556,7 @@ namespace ts.projectSystem {
}
installWorker(_requestId: number, args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
let typingFiles: (FileOrFolder & { typings: string })[] = [];
if (args.indexOf("@types/commander") >= 0) {
if (args.indexOf(typingsName("commander")) >= 0) {
typingFiles = [commander, jquery, lodash, cordova];
}
else {
@ -982,7 +984,7 @@ namespace ts.projectSystem {
return;
}
if (response.kind === server.EventEndInstallTypes) {
assert.deepEqual(response.packagesToInstall, ["@types/commander"]);
assert.deepEqual(response.packagesToInstall, [typingsName("commander")]);
seenTelemetryEvent = true;
return;
}

View File

@ -295,8 +295,7 @@ namespace ts.server.typingsInstaller {
this.log.writeLine(`Installing typings ${JSON.stringify(typingsToInstall)}`);
}
const filteredTypings = this.filterTypings(typingsToInstall);
const scopedTypings = filteredTypings.map(x => `@types/${x}`);
if (scopedTypings.length === 0) {
if (filteredTypings.length === 0) {
if (this.log.isEnabled()) {
this.log.writeLine(`All typings are known to be missing or invalid - no need to go any further`);
}
@ -316,6 +315,7 @@ namespace ts.server.typingsInstaller {
projectName: req.projectName
});
const scopedTypings = filteredTypings.map(typingsName);
this.installTypingsAsync(requestId, scopedTypings, cachePath, ok => {
try {
if (!ok) {
@ -429,4 +429,10 @@ namespace ts.server.typingsInstaller {
protected abstract installWorker(requestId: number, args: string[], cwd: string, onRequestCompleted: RequestCompletedAction): void;
protected abstract sendResponse(response: SetTypings | InvalidateCachedTypings | BeginInstallTypes | EndInstallTypes): void;
}
/* @internal */
export function typingsName(packageName: string): string {
return `@types/${packageName}@ts${versionMajorMinor}`;
}
const versionMajorMinor = version.split(".").slice(0, 2).join(".");
}

View File

@ -115,6 +115,7 @@ namespace ts.codefix {
registerCodeFix({
errorCodes: [
Diagnostics.Cannot_find_name_0.code,
Diagnostics.Cannot_find_namespace_0.code,
Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code
],
getCodeActions: (context: CodeFixContext) => {
@ -416,8 +417,8 @@ namespace ts.codefix {
);
function getModuleSpecifierForNewImport() {
const fileName = sourceFile.path;
const moduleFileName = moduleSymbol.valueDeclaration.getSourceFile().path;
const fileName = sourceFile.fileName;
const moduleFileName = moduleSymbol.valueDeclaration.getSourceFile().fileName;
const sourceDirectory = getDirectoryPath(fileName);
const options = context.program.getCompilerOptions();
@ -439,8 +440,7 @@ namespace ts.codefix {
return undefined;
}
const normalizedBaseUrl = toPath(options.baseUrl, getDirectoryPath(options.baseUrl), getCanonicalFileName);
let relativeName = tryRemoveParentDirectoryName(moduleFileName, normalizedBaseUrl);
let relativeName = getRelativePathIfInDirectory(moduleFileName, options.baseUrl);
if (!relativeName) {
return undefined;
}
@ -477,9 +477,8 @@ namespace ts.codefix {
function tryGetModuleNameFromRootDirs() {
if (options.rootDirs) {
const normalizedRootDirs = map(options.rootDirs, rootDir => toPath(rootDir, /*basePath*/ undefined, getCanonicalFileName));
const normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, normalizedRootDirs);
const normalizedSourcePath = getPathRelativeToRootDirs(sourceDirectory, normalizedRootDirs);
const normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, options.rootDirs);
const normalizedSourcePath = getPathRelativeToRootDirs(sourceDirectory, options.rootDirs);
if (normalizedTargetPath !== undefined) {
const relativePath = normalizedSourcePath !== undefined ? getRelativePath(normalizedTargetPath, normalizedSourcePath) : normalizedTargetPath;
return removeFileExtension(relativePath);
@ -546,9 +545,9 @@ namespace ts.codefix {
}
}
function getPathRelativeToRootDirs(path: Path, rootDirs: Path[]) {
function getPathRelativeToRootDirs(path: string, rootDirs: string[]) {
for (const rootDir of rootDirs) {
const relativeName = tryRemoveParentDirectoryName(path, rootDir);
const relativeName = getRelativePathIfInDirectory(path, rootDir);
if (relativeName !== undefined) {
return relativeName;
}
@ -564,20 +563,15 @@ namespace ts.codefix {
return fileName;
}
function getRelativePathIfInDirectory(path: string, directoryPath: string) {
const relativePath = getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, false);
return isRootedDiskPath(relativePath) || startsWith(relativePath, "..") ? undefined : relativePath;
}
function getRelativePath(path: string, directoryPath: string) {
const relativePath = getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, false);
return moduleHasNonRelativeName(relativePath) ? "./" + relativePath : relativePath;
}
function tryRemoveParentDirectoryName(path: Path, parentDirectory: Path) {
const index = path.indexOf(parentDirectory);
if (index === 0) {
return endsWith(parentDirectory, directorySeparator)
? path.substring(parentDirectory.length)
: path.substring(parentDirectory.length + 1);
}
return undefined;
}
}
}

View File

@ -25,7 +25,7 @@ namespace ts.codefix {
const forStatement = <ForStatement>token.parent.parent.parent;
const forInitializer = <VariableDeclarationList>forStatement.initializer;
if (forInitializer.declarations.length === 1) {
return createCodeFix("", forInitializer.pos, forInitializer.end - forInitializer.pos);
return createCodeFixToRemoveNode(forInitializer);
}
else {
return removeSingleItem(forInitializer.declarations, token);
@ -35,7 +35,7 @@ namespace ts.codefix {
const forOfStatement = <ForOfStatement>token.parent.parent.parent;
if (forOfStatement.initializer.kind === SyntaxKind.VariableDeclarationList) {
const forOfInitializer = <VariableDeclarationList>forOfStatement.initializer;
return createCodeFix("{}", forOfInitializer.declarations[0].pos, forOfInitializer.declarations[0].end - forOfInitializer.declarations[0].pos);
return createCodeFix("{}", forOfInitializer.declarations[0].getStart(), forOfInitializer.declarations[0].getWidth());
}
break;
@ -47,12 +47,12 @@ namespace ts.codefix {
case SyntaxKind.CatchClause:
const catchClause = <CatchClause>token.parent.parent;
const parameter = catchClause.variableDeclaration.getChildren()[0];
return createCodeFix("", parameter.pos, parameter.end - parameter.pos);
return createCodeFixToRemoveNode(parameter);
default:
const variableStatement = <VariableStatement>token.parent.parent.parent;
if (variableStatement.declarationList.declarations.length === 1) {
return createCodeFix("", variableStatement.pos, variableStatement.end - variableStatement.pos);
return createCodeFixToRemoveNode(variableStatement);
}
else {
const declarations = variableStatement.declarationList.declarations;
@ -72,7 +72,7 @@ namespace ts.codefix {
case ts.SyntaxKind.Parameter:
const functionDeclaration = <FunctionDeclaration>token.parent.parent;
if (functionDeclaration.parameters.length === 1) {
return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos);
return createCodeFixToRemoveNode(token.parent);
}
else {
return removeSingleItem(functionDeclaration.parameters, token);
@ -81,14 +81,14 @@ namespace ts.codefix {
// handle case where 'import a = A;'
case SyntaxKind.ImportEqualsDeclaration:
const importEquals = findImportDeclaration(token);
return createCodeFix("", importEquals.pos, importEquals.end - importEquals.pos);
return createCodeFixToRemoveNode(importEquals);
case SyntaxKind.ImportSpecifier:
const namedImports = <NamedImports>token.parent.parent;
if (namedImports.elements.length === 1) {
// Only 1 import and it is unused. So the entire declaration should be removed.
const importSpec = findImportDeclaration(token);
return createCodeFix("", importSpec.pos, importSpec.end - importSpec.pos);
return createCodeFixToRemoveNode(importSpec);
}
else {
return removeSingleItem(namedImports.elements, token);
@ -100,17 +100,24 @@ namespace ts.codefix {
const importClause = <ImportClause>token.parent;
if (!importClause.namedBindings) { // |import d from './file'| or |import * as ns from './file'|
const importDecl = findImportDeclaration(importClause);
return createCodeFix("", importDecl.pos, importDecl.end - importDecl.pos);
return createCodeFixToRemoveNode(importDecl);
}
else { // import |d,| * as ns from './file'
return createCodeFix("", importClause.name.pos, importClause.namedBindings.pos - importClause.name.pos);
else {
// import |d,| * as ns from './file'
const start = importClause.name.getStart();
let end = findFirstNonSpaceCharPosStarting(importClause.name.end);
if (sourceFile.text.charCodeAt(end) === CharacterCodes.comma) {
end = findFirstNonSpaceCharPosStarting(end + 1);
}
return createCodeFix("", start, end - start);
}
case SyntaxKind.NamespaceImport:
const namespaceImport = <NamespaceImport>token.parent;
if (namespaceImport.name == token && !(<ImportClause>namespaceImport.parent).name) {
const importDecl = findImportDeclaration(namespaceImport);
return createCodeFix("", importDecl.pos, importDecl.end - importDecl.pos);
return createCodeFixToRemoveNode(importDecl);
}
else {
const start = (<ImportClause>namespaceImport.parent).name.end;
@ -120,16 +127,14 @@ namespace ts.codefix {
break;
case SyntaxKind.PropertyDeclaration:
return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos);
case SyntaxKind.NamespaceImport:
return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos);
return createCodeFixToRemoveNode(token.parent);
}
if (isDeclarationName(token)) {
return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos);
return createCodeFixToRemoveNode(token.parent);
}
else if (isLiteralComputedPropertyDeclarationName(token)) {
return createCodeFix("", token.parent.parent.pos, token.parent.parent.end - token.parent.parent.pos);
return createCodeFixToRemoveNode(token.parent.parent);
}
else {
return undefined;
@ -144,6 +149,17 @@ namespace ts.codefix {
return importDecl;
}
function createCodeFixToRemoveNode(node: Node) {
return createCodeFix("", node.getStart(), node.getWidth());
}
function findFirstNonSpaceCharPosStarting(start: number) {
while (isWhiteSpace(sourceFile.text.charCodeAt(start))) {
start += 1;
}
return start;
}
function createCodeFix(newText: string, start: number, length: number): CodeAction[] {
return [{
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Remove_declaration_for_Colon_0), { 0: token.getText() }),

View File

@ -173,6 +173,18 @@ namespace ts.Completions {
// var y = require("/*completion position*/");
return getStringLiteralCompletionEntriesFromModuleNames(<StringLiteral>node, compilerOptions, host, typeChecker);
}
else if (isEqualityExpression(node.parent)) {
// Get completions from the type of the other operand
// i.e. switch (a) {
// case '/*completion position*/'
// }
return getStringLiteralCompletionEntriesFromType(typeChecker.getTypeAtLocation(node.parent.left === node ? node.parent.right : node.parent.left), typeChecker);
}
else if (isCaseOrDefaultClause(node.parent)) {
// Get completions from the type of the switch expression
// i.e. x === '/*completion position'
return getStringLiteralCompletionEntriesFromType(typeChecker.getTypeAtLocation((<SwitchStatement>node.parent.parent.parent).expression), typeChecker);
}
else {
const argumentInfo = SignatureHelp.getImmediatelyContainingArgumentInfo(node, position, sourceFile);
if (argumentInfo) {
@ -184,7 +196,7 @@ namespace ts.Completions {
// Get completion for string literal from string literal type
// i.e. var x: "hi" | "hello" = "/*completion position*/"
return getStringLiteralCompletionEntriesFromContextualType(<StringLiteral>node, typeChecker);
return getStringLiteralCompletionEntriesFromType(typeChecker.getContextualType(<StringLiteral>node), typeChecker);
}
}
@ -228,8 +240,7 @@ namespace ts.Completions {
return undefined;
}
function getStringLiteralCompletionEntriesFromContextualType(node: StringLiteral, typeChecker: TypeChecker): CompletionInfo | undefined {
const type = typeChecker.getContextualType(node);
function getStringLiteralCompletionEntriesFromType(type: Type, typeChecker: TypeChecker): CompletionInfo | undefined {
if (type) {
const entries: CompletionEntry[] = [];
addStringLiteralCompletionsFromType(type, entries, typeChecker);
@ -1756,4 +1767,15 @@ namespace ts.Completions {
catch (e) {}
return undefined;
}
function isEqualityExpression(node: Node): node is BinaryExpression {
return isBinaryExpression(node) && isEqualityOperatorKind(node.operatorToken.kind);
}
function isEqualityOperatorKind(kind: SyntaxKind) {
return kind == SyntaxKind.EqualsEqualsToken ||
kind === SyntaxKind.ExclamationEqualsToken ||
kind === SyntaxKind.EqualsEqualsEqualsToken ||
kind === SyntaxKind.ExclamationEqualsEqualsToken;
}
}

View File

@ -516,6 +516,43 @@ class B extends A<{ x: number}> {
p.x;
}
}
// Repro from #13749
class Form<T> {
private childFormFactories: {[K in keyof T]: (v: T[K]) => Form<T[K]>}
public set<K extends keyof T>(prop: K, value: T[K]) {
this.childFormFactories[prop](value)
}
}
// Repro from #13787
class SampleClass<P> {
public props: Readonly<P>;
constructor(props: P) {
this.props = Object.freeze(props);
}
}
interface Foo {
foo: string;
}
declare function merge<T, U>(obj1: T, obj2: U): T & U;
class AnotherSampleClass<T> extends SampleClass<T & Foo> {
constructor(props: T) {
const foo: Foo = { foo: "bar" };
super(merge(props, foo));
}
public brokenMethod() {
this.props.foo.concat;
}
}
new AnotherSampleClass({});
//// [keyofAndIndexedAccess.js]
@ -862,6 +899,36 @@ var B = (function (_super) {
};
return B;
}(A));
// Repro from #13749
var Form = (function () {
function Form() {
}
Form.prototype.set = function (prop, value) {
this.childFormFactories[prop](value);
};
return Form;
}());
// Repro from #13787
var SampleClass = (function () {
function SampleClass(props) {
this.props = Object.freeze(props);
}
return SampleClass;
}());
var AnotherSampleClass = (function (_super) {
__extends(AnotherSampleClass, _super);
function AnotherSampleClass(props) {
var _this = this;
var foo = { foo: "bar" };
_this = _super.call(this, merge(props, foo)) || this;
return _this;
}
AnotherSampleClass.prototype.brokenMethod = function () {
this.props.foo.concat;
};
return AnotherSampleClass;
}(SampleClass));
new AnotherSampleClass({});
//// [keyofAndIndexedAccess.d.ts]
@ -1104,3 +1171,19 @@ declare class B extends A<{
}> {
f(p: this["props"]): void;
}
declare class Form<T> {
private childFormFactories;
set<K extends keyof T>(prop: K, value: T[K]): void;
}
declare class SampleClass<P> {
props: Readonly<P>;
constructor(props: P);
}
interface Foo {
foo: string;
}
declare function merge<T, U>(obj1: T, obj2: U): T & U;
declare class AnotherSampleClass<T> extends SampleClass<T & Foo> {
constructor(props: T);
brokenMethod(): void;
}

View File

@ -1844,3 +1844,122 @@ class B extends A<{ x: number}> {
}
}
// Repro from #13749
class Form<T> {
>Form : Symbol(Form, Decl(keyofAndIndexedAccess.ts, 516, 1))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 520, 11))
private childFormFactories: {[K in keyof T]: (v: T[K]) => Form<T[K]>}
>childFormFactories : Symbol(Form.childFormFactories, Decl(keyofAndIndexedAccess.ts, 520, 15))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 521, 34))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 520, 11))
>v : Symbol(v, Decl(keyofAndIndexedAccess.ts, 521, 50))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 520, 11))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 521, 34))
>Form : Symbol(Form, Decl(keyofAndIndexedAccess.ts, 516, 1))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 520, 11))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 521, 34))
public set<K extends keyof T>(prop: K, value: T[K]) {
>set : Symbol(Form.set, Decl(keyofAndIndexedAccess.ts, 521, 73))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 523, 15))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 520, 11))
>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 523, 34))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 523, 15))
>value : Symbol(value, Decl(keyofAndIndexedAccess.ts, 523, 42))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 520, 11))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 523, 15))
this.childFormFactories[prop](value)
>this.childFormFactories : Symbol(Form.childFormFactories, Decl(keyofAndIndexedAccess.ts, 520, 15))
>this : Symbol(Form, Decl(keyofAndIndexedAccess.ts, 516, 1))
>childFormFactories : Symbol(Form.childFormFactories, Decl(keyofAndIndexedAccess.ts, 520, 15))
>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 523, 34))
>value : Symbol(value, Decl(keyofAndIndexedAccess.ts, 523, 42))
}
}
// Repro from #13787
class SampleClass<P> {
>SampleClass : Symbol(SampleClass, Decl(keyofAndIndexedAccess.ts, 526, 1))
>P : Symbol(P, Decl(keyofAndIndexedAccess.ts, 530, 18))
public props: Readonly<P>;
>props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 530, 22))
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
>P : Symbol(P, Decl(keyofAndIndexedAccess.ts, 530, 18))
constructor(props: P) {
>props : Symbol(props, Decl(keyofAndIndexedAccess.ts, 532, 16))
>P : Symbol(P, Decl(keyofAndIndexedAccess.ts, 530, 18))
this.props = Object.freeze(props);
>this.props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 530, 22))
>this : Symbol(SampleClass, Decl(keyofAndIndexedAccess.ts, 526, 1))
>props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 530, 22))
>Object.freeze : Symbol(ObjectConstructor.freeze, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>freeze : Symbol(ObjectConstructor.freeze, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>props : Symbol(props, Decl(keyofAndIndexedAccess.ts, 532, 16))
}
}
interface Foo {
>Foo : Symbol(Foo, Decl(keyofAndIndexedAccess.ts, 535, 1))
foo: string;
>foo : Symbol(Foo.foo, Decl(keyofAndIndexedAccess.ts, 537, 15))
}
declare function merge<T, U>(obj1: T, obj2: U): T & U;
>merge : Symbol(merge, Decl(keyofAndIndexedAccess.ts, 539, 1))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 541, 23))
>U : Symbol(U, Decl(keyofAndIndexedAccess.ts, 541, 25))
>obj1 : Symbol(obj1, Decl(keyofAndIndexedAccess.ts, 541, 29))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 541, 23))
>obj2 : Symbol(obj2, Decl(keyofAndIndexedAccess.ts, 541, 37))
>U : Symbol(U, Decl(keyofAndIndexedAccess.ts, 541, 25))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 541, 23))
>U : Symbol(U, Decl(keyofAndIndexedAccess.ts, 541, 25))
class AnotherSampleClass<T> extends SampleClass<T & Foo> {
>AnotherSampleClass : Symbol(AnotherSampleClass, Decl(keyofAndIndexedAccess.ts, 541, 54))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 543, 25))
>SampleClass : Symbol(SampleClass, Decl(keyofAndIndexedAccess.ts, 526, 1))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 543, 25))
>Foo : Symbol(Foo, Decl(keyofAndIndexedAccess.ts, 535, 1))
constructor(props: T) {
>props : Symbol(props, Decl(keyofAndIndexedAccess.ts, 544, 16))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 543, 25))
const foo: Foo = { foo: "bar" };
>foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 545, 13))
>Foo : Symbol(Foo, Decl(keyofAndIndexedAccess.ts, 535, 1))
>foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 545, 26))
super(merge(props, foo));
>super : Symbol(SampleClass, Decl(keyofAndIndexedAccess.ts, 526, 1))
>merge : Symbol(merge, Decl(keyofAndIndexedAccess.ts, 539, 1))
>props : Symbol(props, Decl(keyofAndIndexedAccess.ts, 544, 16))
>foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 545, 13))
}
public brokenMethod() {
>brokenMethod : Symbol(AnotherSampleClass.brokenMethod, Decl(keyofAndIndexedAccess.ts, 547, 5))
this.props.foo.concat;
>this.props.foo.concat : Symbol(String.concat, Decl(lib.d.ts, --, --))
>this.props.foo : Symbol(foo)
>this.props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 530, 22))
>this : Symbol(AnotherSampleClass, Decl(keyofAndIndexedAccess.ts, 541, 54))
>props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 530, 22))
>foo : Symbol(foo)
>concat : Symbol(String.concat, Decl(lib.d.ts, --, --))
}
}
new AnotherSampleClass({});
>AnotherSampleClass : Symbol(AnotherSampleClass, Decl(keyofAndIndexedAccess.ts, 541, 54))

View File

@ -2166,3 +2166,132 @@ class B extends A<{ x: number}> {
}
}
// Repro from #13749
class Form<T> {
>Form : Form<T>
>T : T
private childFormFactories: {[K in keyof T]: (v: T[K]) => Form<T[K]>}
>childFormFactories : { [K in keyof T]: (v: T[K]) => Form<T[K]>; }
>K : K
>T : T
>v : T[K]
>T : T
>K : K
>Form : Form<T>
>T : T
>K : K
public set<K extends keyof T>(prop: K, value: T[K]) {
>set : <K extends keyof T>(prop: K, value: T[K]) => void
>K : K
>T : T
>prop : K
>K : K
>value : T[K]
>T : T
>K : K
this.childFormFactories[prop](value)
>this.childFormFactories[prop](value) : Form<T[K]>
>this.childFormFactories[prop] : (v: T[K]) => Form<T[K]>
>this.childFormFactories : { [K in keyof T]: (v: T[K]) => Form<T[K]>; }
>this : this
>childFormFactories : { [K in keyof T]: (v: T[K]) => Form<T[K]>; }
>prop : K
>value : T[K]
}
}
// Repro from #13787
class SampleClass<P> {
>SampleClass : SampleClass<P>
>P : P
public props: Readonly<P>;
>props : Readonly<P>
>Readonly : Readonly<T>
>P : P
constructor(props: P) {
>props : P
>P : P
this.props = Object.freeze(props);
>this.props = Object.freeze(props) : Readonly<P>
>this.props : Readonly<P>
>this : this
>props : Readonly<P>
>Object.freeze(props) : Readonly<P>
>Object.freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>Object : ObjectConstructor
>freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>props : P
}
}
interface Foo {
>Foo : Foo
foo: string;
>foo : string
}
declare function merge<T, U>(obj1: T, obj2: U): T & U;
>merge : <T, U>(obj1: T, obj2: U) => T & U
>T : T
>U : U
>obj1 : T
>T : T
>obj2 : U
>U : U
>T : T
>U : U
class AnotherSampleClass<T> extends SampleClass<T & Foo> {
>AnotherSampleClass : AnotherSampleClass<T>
>T : T
>SampleClass : SampleClass<T & Foo>
>T : T
>Foo : Foo
constructor(props: T) {
>props : T
>T : T
const foo: Foo = { foo: "bar" };
>foo : Foo
>Foo : Foo
>{ foo: "bar" } : { foo: string; }
>foo : string
>"bar" : "bar"
super(merge(props, foo));
>super(merge(props, foo)) : void
>super : typeof SampleClass
>merge(props, foo) : T & Foo
>merge : <T, U>(obj1: T, obj2: U) => T & U
>props : T
>foo : Foo
}
public brokenMethod() {
>brokenMethod : () => void
this.props.foo.concat;
>this.props.foo.concat : (...strings: string[]) => string
>this.props.foo : (T & Foo)["foo"]
>this.props : Readonly<T & Foo>
>this : this
>props : Readonly<T & Foo>
>foo : (T & Foo)["foo"]
>concat : (...strings: string[]) => string
}
}
new AnotherSampleClass({});
>new AnotherSampleClass({}) : AnotherSampleClass<{}>
>AnotherSampleClass : typeof AnotherSampleClass
>{} : {}

View File

@ -12,26 +12,37 @@ function f2<T>(x: Partial<T>, y: Readonly<T>) {
obj = y;
}
function f3<T>(x: Partial<T>) {
x = {};
}
// Repro from #12900
interface Base {
foo: { [key: string]: any };
bar: any;
baz: any;
foo: { [key: string]: any };
bar: any;
baz: any;
}
interface E1<T> extends Base {
foo: T;
foo: T;
}
interface Something { name: string, value: string };
interface E2 extends Base {
foo: Partial<Something>; // or other mapped type
foo: Partial<Something>; // or other mapped type
}
interface E3<T> extends Base {
foo: Partial<T>; // or other mapped type
}
foo: Partial<T>; // or other mapped type
}
// Repro from #13747
class Form<T> {
private values: {[P in keyof T]?: T[P]} = {}
}
//// [mappedTypesAndObjects.js]
function f1(x, y) {
@ -44,12 +55,23 @@ function f2(x, y) {
obj = x;
obj = y;
}
function f3(x) {
x = {};
}
;
// Repro from #13747
var Form = (function () {
function Form() {
this.values = {};
}
return Form;
}());
//// [mappedTypesAndObjects.d.ts]
declare function f1<T>(x: Partial<T>, y: Readonly<T>): void;
declare function f2<T>(x: Partial<T>, y: Readonly<T>): void;
declare function f3<T>(x: Partial<T>): void;
interface Base {
foo: {
[key: string]: any;
@ -70,3 +92,6 @@ interface E2 extends Base {
interface E3<T> extends Base {
foo: Partial<T>;
}
declare class Form<T> {
private values;
}

View File

@ -45,54 +45,80 @@ function f2<T>(x: Partial<T>, y: Readonly<T>) {
>y : Symbol(y, Decl(mappedTypesAndObjects.ts, 7, 29))
}
function f3<T>(x: Partial<T>) {
>f3 : Symbol(f3, Decl(mappedTypesAndObjects.ts, 11, 1))
>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 13, 12))
>x : Symbol(x, Decl(mappedTypesAndObjects.ts, 13, 15))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 13, 12))
x = {};
>x : Symbol(x, Decl(mappedTypesAndObjects.ts, 13, 15))
}
// Repro from #12900
interface Base {
>Base : Symbol(Base, Decl(mappedTypesAndObjects.ts, 11, 1))
>Base : Symbol(Base, Decl(mappedTypesAndObjects.ts, 15, 1))
foo: { [key: string]: any };
>foo : Symbol(Base.foo, Decl(mappedTypesAndObjects.ts, 15, 16))
>key : Symbol(key, Decl(mappedTypesAndObjects.ts, 16, 11))
foo: { [key: string]: any };
>foo : Symbol(Base.foo, Decl(mappedTypesAndObjects.ts, 19, 16))
>key : Symbol(key, Decl(mappedTypesAndObjects.ts, 20, 12))
bar: any;
>bar : Symbol(Base.bar, Decl(mappedTypesAndObjects.ts, 16, 31))
bar: any;
>bar : Symbol(Base.bar, Decl(mappedTypesAndObjects.ts, 20, 32))
baz: any;
>baz : Symbol(Base.baz, Decl(mappedTypesAndObjects.ts, 17, 12))
baz: any;
>baz : Symbol(Base.baz, Decl(mappedTypesAndObjects.ts, 21, 13))
}
interface E1<T> extends Base {
>E1 : Symbol(E1, Decl(mappedTypesAndObjects.ts, 19, 1))
>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 21, 13))
>Base : Symbol(Base, Decl(mappedTypesAndObjects.ts, 11, 1))
>E1 : Symbol(E1, Decl(mappedTypesAndObjects.ts, 23, 1))
>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 25, 13))
>Base : Symbol(Base, Decl(mappedTypesAndObjects.ts, 15, 1))
foo: T;
>foo : Symbol(E1.foo, Decl(mappedTypesAndObjects.ts, 21, 30))
>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 21, 13))
foo: T;
>foo : Symbol(E1.foo, Decl(mappedTypesAndObjects.ts, 25, 30))
>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 25, 13))
}
interface Something { name: string, value: string };
>Something : Symbol(Something, Decl(mappedTypesAndObjects.ts, 23, 1))
>name : Symbol(Something.name, Decl(mappedTypesAndObjects.ts, 25, 21))
>value : Symbol(Something.value, Decl(mappedTypesAndObjects.ts, 25, 35))
>Something : Symbol(Something, Decl(mappedTypesAndObjects.ts, 27, 1))
>name : Symbol(Something.name, Decl(mappedTypesAndObjects.ts, 29, 21))
>value : Symbol(Something.value, Decl(mappedTypesAndObjects.ts, 29, 35))
interface E2 extends Base {
>E2 : Symbol(E2, Decl(mappedTypesAndObjects.ts, 25, 52))
>Base : Symbol(Base, Decl(mappedTypesAndObjects.ts, 11, 1))
>E2 : Symbol(E2, Decl(mappedTypesAndObjects.ts, 29, 52))
>Base : Symbol(Base, Decl(mappedTypesAndObjects.ts, 15, 1))
foo: Partial<Something>; // or other mapped type
>foo : Symbol(E2.foo, Decl(mappedTypesAndObjects.ts, 26, 27))
foo: Partial<Something>; // or other mapped type
>foo : Symbol(E2.foo, Decl(mappedTypesAndObjects.ts, 30, 27))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>Something : Symbol(Something, Decl(mappedTypesAndObjects.ts, 23, 1))
>Something : Symbol(Something, Decl(mappedTypesAndObjects.ts, 27, 1))
}
interface E3<T> extends Base {
>E3 : Symbol(E3, Decl(mappedTypesAndObjects.ts, 28, 1))
>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 30, 13))
>Base : Symbol(Base, Decl(mappedTypesAndObjects.ts, 11, 1))
>E3 : Symbol(E3, Decl(mappedTypesAndObjects.ts, 32, 1))
>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 34, 13))
>Base : Symbol(Base, Decl(mappedTypesAndObjects.ts, 15, 1))
foo: Partial<T>; // or other mapped type
>foo : Symbol(E3.foo, Decl(mappedTypesAndObjects.ts, 30, 30))
foo: Partial<T>; // or other mapped type
>foo : Symbol(E3.foo, Decl(mappedTypesAndObjects.ts, 34, 30))
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 30, 13))
>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 34, 13))
}
// Repro from #13747
class Form<T> {
>Form : Symbol(Form, Decl(mappedTypesAndObjects.ts, 36, 1))
>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 40, 11))
private values: {[P in keyof T]?: T[P]} = {}
>values : Symbol(Form.values, Decl(mappedTypesAndObjects.ts, 40, 15))
>P : Symbol(P, Decl(mappedTypesAndObjects.ts, 41, 22))
>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 40, 11))
>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 40, 11))
>P : Symbol(P, Decl(mappedTypesAndObjects.ts, 41, 22))
}

View File

@ -49,19 +49,32 @@ function f2<T>(x: Partial<T>, y: Readonly<T>) {
>y : Readonly<T>
}
function f3<T>(x: Partial<T>) {
>f3 : <T>(x: Partial<T>) => void
>T : T
>x : Partial<T>
>Partial : Partial<T>
>T : T
x = {};
>x = {} : {}
>x : Partial<T>
>{} : {}
}
// Repro from #12900
interface Base {
>Base : Base
foo: { [key: string]: any };
foo: { [key: string]: any };
>foo : { [key: string]: any; }
>key : string
bar: any;
bar: any;
>bar : any
baz: any;
baz: any;
>baz : any
}
@ -70,7 +83,7 @@ interface E1<T> extends Base {
>T : T
>Base : Base
foo: T;
foo: T;
>foo : T
>T : T
}
@ -84,7 +97,7 @@ interface E2 extends Base {
>E2 : E2
>Base : Base
foo: Partial<Something>; // or other mapped type
foo: Partial<Something>; // or other mapped type
>foo : Partial<Something>
>Partial : Partial<T>
>Something : Something
@ -95,8 +108,24 @@ interface E3<T> extends Base {
>T : T
>Base : Base
foo: Partial<T>; // or other mapped type
foo: Partial<T>; // or other mapped type
>foo : Partial<T>
>Partial : Partial<T>
>T : T
}
// Repro from #13747
class Form<T> {
>Form : Form<T>
>T : T
private values: {[P in keyof T]?: T[P]} = {}
>values : { [P in keyof T]?: T[P] | undefined; }
>P : P
>T : T
>T : T
>P : P
>{} : {}
}

View File

@ -0,0 +1,183 @@
//// [mixinClassesAnnotated.ts]
type Constructor<T> = 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 = <T extends Constructor<Base>>(superClass: T): Constructor<Printable> & { message: string } & T =>
class extends superClass {
static message = "hello";
print() {
const output = this.x + "," + this.y;
}
}
interface Tagged {
_tag: string;
}
function Tagged<T extends Constructor<{}>>(superClass: T): Constructor<Tagged> & 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<T> = 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: <T extends Constructor<Base>>(superClass: T) => Constructor<Printable> & {
message: string;
} & T;
interface Tagged {
_tag: string;
}
declare function Tagged<T extends Constructor<{}>>(superClass: T): Constructor<Tagged> & T;
declare const Thing1: Constructor<Tagged> & typeof Derived;
declare const Thing2: Constructor<Tagged> & Constructor<Printable> & {
message: string;
} & typeof Derived;
declare function f1(): void;
declare function f2(): void;
declare class Thing3 extends Thing2 {
constructor(tag: string);
test(): void;
}

View File

@ -0,0 +1,193 @@
=== tests/cases/conformance/classes/mixinClassesAnnotated.ts ===
type Constructor<T> = 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 = <T extends Constructor<Base>>(superClass: T): Constructor<Printable> & { 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<T extends Constructor<{}>>(superClass: T): Constructor<Tagged> & 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))
}
}

View File

@ -0,0 +1,224 @@
=== tests/cases/conformance/classes/mixinClassesAnnotated.ts ===
type Constructor<T> = new(...args: any[]) => T;
>Constructor : Constructor<T>
>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 = <T extends Constructor<Base>>(superClass: T): Constructor<Printable> & { message: string } & T =>
>Printable : <T extends Constructor<Base>>(superClass: T) => Constructor<Printable> & { message: string; } & T
><T extends Constructor<Base>>(superClass: T): Constructor<Printable> & { message: string } & T => class extends superClass { static message = "hello"; print() { const output = this.x + "," + this.y; } } : <T extends Constructor<Base>>(superClass: T) => Constructor<Printable> & { message: string; } & T
>T : T
>Constructor : Constructor<T>
>Base : Base
>superClass : T
>T : T
>Constructor : Constructor<T>
>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: <any>.(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<T extends Constructor<{}>>(superClass: T): Constructor<Tagged> & T {
>Tagged : <T extends Constructor<{}>>(superClass: T) => Constructor<Tagged> & T
>T : T
>Constructor : Constructor<T>
>superClass : T
>T : T
>Constructor : Constructor<T>
>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<any>.C; } & T
}
const Thing1 = Tagged(Derived);
>Thing1 : Constructor<Tagged> & typeof Derived
>Tagged(Derived) : Constructor<Tagged> & typeof Derived
>Tagged : <T extends Constructor<{}>>(superClass: T) => Constructor<Tagged> & T
>Derived : typeof Derived
const Thing2 = Tagged(Printable(Derived));
>Thing2 : Constructor<Tagged> & Constructor<Printable> & { message: string; } & typeof Derived
>Tagged(Printable(Derived)) : Constructor<Tagged> & Constructor<Printable> & { message: string; } & typeof Derived
>Tagged : <T extends Constructor<{}>>(superClass: T) => Constructor<Tagged> & T
>Printable(Derived) : Constructor<Printable> & { message: string; } & typeof Derived
>Printable : <T extends Constructor<Base>>(superClass: T) => Constructor<Printable> & { message: string; } & T
>Derived : typeof Derived
Thing2.message;
>Thing2.message : string
>Thing2 : Constructor<Tagged> & Constructor<Printable> & { 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<Tagged> & 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<Tagged> & Constructor<Printable> & { 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<Tagged> & Constructor<Printable> & { 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
}
}

View File

@ -0,0 +1,160 @@
//// [mixinClassesAnonymous.ts]
type Constructor<T> = 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 = <T extends Constructor<Base>>(superClass: T) => class extends superClass {
static message = "hello";
print() {
const output = this.x + "," + this.y;
}
}
function Tagged<T extends Constructor<{}>>(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();
}
}
// Repro from #13805
const Timestamped = <CT extends Constructor<object>>(Base: CT) => {
return class extends Base {
timestamp = new Date();
};
}
//// [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));
// Repro from #13805
var Timestamped = function (Base) {
return (function (_super) {
__extends(class_2, _super);
function class_2() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.timestamp = new Date();
return _this;
}
return class_2;
}(Base));
};

View File

@ -0,0 +1,188 @@
=== tests/cases/conformance/classes/mixinClassesAnonymous.ts ===
type Constructor<T> = 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 = <T extends Constructor<Base>>(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<T extends Constructor<{}>>(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))
}
}
// Repro from #13805
const Timestamped = <CT extends Constructor<object>>(Base: CT) => {
>Timestamped : Symbol(Timestamped, Decl(mixinClassesAnonymous.ts, 59, 5))
>CT : Symbol(CT, Decl(mixinClassesAnonymous.ts, 59, 21))
>Constructor : Symbol(Constructor, Decl(mixinClassesAnonymous.ts, 0, 0))
>Base : Symbol(Base, Decl(mixinClassesAnonymous.ts, 59, 53))
>CT : Symbol(CT, Decl(mixinClassesAnonymous.ts, 59, 21))
return class extends Base {
>Base : Symbol(Base, Decl(mixinClassesAnonymous.ts, 59, 53))
timestamp = new Date();
>timestamp : Symbol((Anonymous class).timestamp, Decl(mixinClassesAnonymous.ts, 60, 31))
>Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
};
}

View File

@ -0,0 +1,222 @@
=== tests/cases/conformance/classes/mixinClassesAnonymous.ts ===
type Constructor<T> = new(...args: any[]) => T;
>Constructor : Constructor<T>
>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 = <T extends Constructor<Base>>(superClass: T) => class extends superClass {
>Printable : <T extends Constructor<Base>>(superClass: T) => { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); message: string; } & T
><T extends Constructor<Base>>(superClass: T) => class extends superClass { static message = "hello"; print() { const output = this.x + "," + this.y; }} : <T extends Constructor<Base>>(superClass: T) => { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); message: string; } & T
>T : T
>Constructor : Constructor<T>
>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: <any>.(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<T extends Constructor<{}>>(superClass: T) {
>Tagged : <T extends Constructor<{}>>(superClass: T) => { new (...args: any[]): C; prototype: Tagged<any>.C; } & T
>T : T
>Constructor : Constructor<T>
>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<any>.C; } & T
}
const Thing1 = Tagged(Derived);
>Thing1 : { new (...args: any[]): Tagged<typeof Derived>.C; prototype: Tagged<any>.C; } & typeof Derived
>Tagged(Derived) : { new (...args: any[]): Tagged<typeof Derived>.C; prototype: Tagged<any>.C; } & typeof Derived
>Tagged : <T extends Constructor<{}>>(superClass: T) => { new (...args: any[]): C; prototype: Tagged<any>.C; } & T
>Derived : typeof Derived
const Thing2 = Tagged(Printable(Derived));
>Thing2 : { new (...args: any[]): Tagged<{ new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived>.C; prototype: Tagged<any>.C; } & { new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived
>Tagged(Printable(Derived)) : { new (...args: any[]): Tagged<{ new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived>.C; prototype: Tagged<any>.C; } & { new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived
>Tagged : <T extends Constructor<{}>>(superClass: T) => { new (...args: any[]): C; prototype: Tagged<any>.C; } & T
>Printable(Derived) : { new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived
>Printable : <T extends Constructor<Base>>(superClass: T) => { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); message: string; } & T
>Derived : typeof Derived
Thing2.message;
>Thing2.message : string
>Thing2 : { new (...args: any[]): Tagged<{ new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived>.C; prototype: Tagged<any>.C; } & { new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived
>message : string
function f1() {
>f1 : () => void
const thing = new Thing1(1, 2, 3);
>thing : Tagged<typeof Derived>.C & Derived
>new Thing1(1, 2, 3) : Tagged<typeof Derived>.C & Derived
>Thing1 : { new (...args: any[]): Tagged<typeof Derived>.C; prototype: Tagged<any>.C; } & typeof Derived
>1 : 1
>2 : 2
>3 : 3
thing.x;
>thing.x : number
>thing : Tagged<typeof Derived>.C & Derived
>x : number
thing._tag;
>thing._tag : string
>thing : Tagged<typeof Derived>.C & Derived
>_tag : string
}
function f2() {
>f2 : () => void
const thing = new Thing2(1, 2, 3);
>thing : Tagged<{ new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived>.C & <typeof Derived>.(Anonymous class) & Derived
>new Thing2(1, 2, 3) : Tagged<{ new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived>.C & <typeof Derived>.(Anonymous class) & Derived
>Thing2 : { new (...args: any[]): Tagged<{ new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived>.C; prototype: Tagged<any>.C; } & { new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived
>1 : 1
>2 : 2
>3 : 3
thing.x;
>thing.x : number
>thing : Tagged<{ new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived>.C & <typeof Derived>.(Anonymous class) & Derived
>x : number
thing._tag;
>thing._tag : string
>thing : Tagged<{ new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived>.C & <typeof Derived>.(Anonymous class) & Derived
>_tag : string
thing.print();
>thing.print() : void
>thing.print : () => void
>thing : Tagged<{ new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived>.C & <typeof Derived>.(Anonymous class) & Derived
>print : () => void
}
class Thing3 extends Thing2 {
>Thing3 : Thing3
>Thing2 : Tagged<{ new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived>.C & <typeof Derived>.(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[]): <typeof Derived>.(Anonymous class); prototype: <any>.(Anonymous class); message: string; } & typeof Derived>.C; prototype: Tagged<any>.C; } & { new (...args: any[]): <typeof Derived>.(Anonymous class); prototype: <any>.(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
}
}
// Repro from #13805
const Timestamped = <CT extends Constructor<object>>(Base: CT) => {
>Timestamped : <CT extends Constructor<object>>(Base: CT) => { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); } & CT
><CT extends Constructor<object>>(Base: CT) => { return class extends Base { timestamp = new Date(); };} : <CT extends Constructor<object>>(Base: CT) => { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); } & CT
>CT : CT
>Constructor : Constructor<T>
>Base : CT
>CT : CT
return class extends Base {
>class extends Base { timestamp = new Date(); } : { new (...args: any[]): (Anonymous class); prototype: <any>.(Anonymous class); } & CT
>Base : object
timestamp = new Date();
>timestamp : Date
>new Date() : Date
>Date : DateConstructor
};
}

View File

@ -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;
}

View File

@ -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))
}

View File

@ -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
}

View File

@ -1,5 +1,5 @@
tests/cases/conformance/types/nonPrimitive/nonPrimitiveAssignError.ts(5,1): error TS2322: Type 'object' is not assignable to type '{ foo: string; }'.
Property 'foo' is missing in type 'Object'.
Property 'foo' is missing in type '{}'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveAssignError.ts(13,1): error TS2322: Type 'number' is not assignable to type 'object'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveAssignError.ts(14,1): error TS2322: Type 'true' is not assignable to type 'object'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveAssignError.ts(15,1): error TS2322: Type 'string' is not assignable to type 'object'.
@ -16,7 +16,7 @@ tests/cases/conformance/types/nonPrimitive/nonPrimitiveAssignError.ts(19,1): err
y = a; // expect error
~
!!! error TS2322: Type 'object' is not assignable to type '{ foo: string; }'.
!!! error TS2322: Property 'foo' is missing in type 'Object'.
!!! error TS2322: Property 'foo' is missing in type '{}'.
a = x;
a = y;

View File

@ -0,0 +1,6 @@
/*! [a.ts] */
// comment0
const a = 1;
/*! [b.ts] */
// comment1
const b = 2;

View File

@ -0,0 +1,4 @@
/*! [a.ts] */
const a = 1;
/*! [b.ts] */
const b = 2;

View File

@ -0,0 +1,25 @@
interface A<T> {
// comment1
readonly prop?: T;
// comment2
method(): void;
// comment3
new <T>(): A<T>;
// comment4
<T>(): A<T>;
}
// comment5
type B = number | string | object;
type C = A<number> & {
x: string;
}; // comment6
// comment7
enum E1 {
// comment8
first
}
const enum E2 {
second
}
// comment9
console.log(1 + 2);

View File

@ -0,0 +1,17 @@
interface A<T> {
readonly prop?: T;
method(): void;
new <T>(): A<T>;
<T>(): A<T>;
}
type B = number | string | object;
type C = A<number> & {
x: string;
};
enum E1 {
first
}
const enum E2 {
second
}
console.log(1 + 2);

View File

@ -0,0 +1,3 @@
class C {
public prop;
}

View File

@ -0,0 +1,67 @@
// @declaration: true
type Constructor<T> = 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 = <T extends Constructor<Base>>(superClass: T): Constructor<Printable> & { message: string } & T =>
class extends superClass {
static message = "hello";
print() {
const output = this.x + "," + this.y;
}
}
interface Tagged {
_tag: string;
}
function Tagged<T extends Constructor<{}>>(superClass: T): Constructor<Tagged> & 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();
}
}

View File

@ -0,0 +1,64 @@
type Constructor<T> = 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 = <T extends Constructor<Base>>(superClass: T) => class extends superClass {
static message = "hello";
print() {
const output = this.x + "," + this.y;
}
}
function Tagged<T extends Constructor<{}>>(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();
}
}
// Repro from #13805
const Timestamped = <CT extends Constructor<object>>(Base: CT) => {
return class extends Base {
timestamp = new Date();
};
}

View File

@ -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(); }
}

View File

@ -517,3 +517,40 @@ class B extends A<{ x: number}> {
p.x;
}
}
// Repro from #13749
class Form<T> {
private childFormFactories: {[K in keyof T]: (v: T[K]) => Form<T[K]>}
public set<K extends keyof T>(prop: K, value: T[K]) {
this.childFormFactories[prop](value)
}
}
// Repro from #13787
class SampleClass<P> {
public props: Readonly<P>;
constructor(props: P) {
this.props = Object.freeze(props);
}
}
interface Foo {
foo: string;
}
declare function merge<T, U>(obj1: T, obj2: U): T & U;
class AnotherSampleClass<T> extends SampleClass<T & Foo> {
constructor(props: T) {
const foo: Foo = { foo: "bar" };
super(merge(props, foo));
}
public brokenMethod() {
this.props.foo.concat;
}
}
new AnotherSampleClass({});

View File

@ -13,23 +13,33 @@ function f2<T>(x: Partial<T>, y: Readonly<T>) {
obj = y;
}
function f3<T>(x: Partial<T>) {
x = {};
}
// Repro from #12900
interface Base {
foo: { [key: string]: any };
bar: any;
baz: any;
foo: { [key: string]: any };
bar: any;
baz: any;
}
interface E1<T> extends Base {
foo: T;
foo: T;
}
interface Something { name: string, value: string };
interface E2 extends Base {
foo: Partial<Something>; // or other mapped type
foo: Partial<Something>; // or other mapped type
}
interface E3<T> extends Base {
foo: Partial<T>; // or other mapped type
}
foo: Partial<T>; // or other mapped type
}
// Repro from #13747
class Form<T> {
private values: {[P in keyof T]?: T[P]} = {}
}

View File

@ -0,0 +1,12 @@
/// <reference path='fourslash.ts'/>
////type As = 'arf' | 'abacus' | 'abaddon';
////let a: As;
////if ('/**/' != a
goTo.marker();
verify.completionListContains("arf");
verify.completionListContains("abacus");
verify.completionListContains("abaddon");
verify.completionListCount(3);

View File

@ -0,0 +1,14 @@
/// <reference path='fourslash.ts'/>
////type As = 'arf' | 'abacus' | 'abaddon';
////let a: As;
////switch (a) {
//// case '/**/
////}
goTo.marker();
verify.completionListContains("arf");
verify.completionListContains("abacus");
verify.completionListContains("abaddon");
verify.completionListCount(3);

View File

@ -0,0 +1,12 @@
/// <reference path='fourslash.ts'/>
////type As = 'arf' | 'abacus' | 'abaddon';
////let a: As;
////if (a === '/**/
goTo.marker();
verify.completionListContains("arf");
verify.completionListContains("abacus");
verify.completionListContains("abaddon");
verify.completionListCount(3);

View File

@ -1,6 +0,0 @@
/// <reference path='fourslash.ts' />
////function /*def*/f() {}
/////*use*/f(123);
verify.goToDefinition("use", "def");

View File

@ -3,7 +3,7 @@
//// [|/// <reference path="./tripleSlashReference.ts" />
//// f1/*0*/();|]
// @Filename: module.ts
// @Filename: Module.ts
//// export function f1() {}
//// export var v1 = 5;
@ -12,7 +12,7 @@
verify.importFixAtPosition([
`/// <reference path="./tripleSlashReference.ts" />
import { f1 } from "./module";
import { f1 } from "./Module";
f1();`
]);

View File

@ -0,0 +1,15 @@
/// <reference path="fourslash.ts" />
//// [|let t: XXX/*0*/.I;|]
// @Filename: ./module.ts
//// export module XXX {
//// export interface I {
//// }
//// }
verify.importFixAtPosition([
`import { XXX } from "./module";
let t: XXX.I;`
]);

View File

@ -0,0 +1,16 @@
/// <reference path="fourslash.ts" />
//// [|let t: A/*0*/.B.I;|]
// @Filename: ./module.ts
//// export namespace A {
//// export namespace B {
//// export interface I { }
//// }
//// }
verify.importFixAtPosition([
`import { A } from "./module";
let t: A.B.I;`
]);

View File

@ -2,9 +2,11 @@
// @noUnusedLocals: true
//// [| namespace greeter {
//// // some legit comments
//// function function1() {
//// }/*1*/
//// } |]
verify.rangeAfterCodeFix(`namespace greeter {
// some legit comments
}`);

View File

@ -2,7 +2,7 @@
// @noUnusedLocals: true
// @Filename: file2.ts
////[| import {Calculator, test, test2} from "./file1" |]
////[| import {Calculator, /*some comments*/ test, test2} from "./file1" |]
//// test();
//// test2();
@ -20,5 +20,5 @@
////
//// }
verify.rangeAfterCodeFix(`import {test, test2} from "./file1"`);
verify.rangeAfterCodeFix(`import {/*some comments*/ test, test2} from "./file1"`);