diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index eaad8593eee86..e403ed994e566 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -630,7 +630,7 @@ namespace ts { function getStrictModeIdentifierMessage(node: Node) { // Provide specialized messages to help the user understand why we think they're in // strict mode. - if (getAncestor(node, SyntaxKind.ClassDeclaration) || getAncestor(node, SyntaxKind.ClassExpression)) { + if (getContainingClass(node)) { return Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode; } @@ -688,7 +688,7 @@ namespace ts { function getStrictModeEvalOrArgumentsMessage(node: Node) { // Provide specialized messages to help the user understand why we think they're in // strict mode. - if (getAncestor(node, SyntaxKind.ClassDeclaration) || getAncestor(node, SyntaxKind.ClassExpression)) { + if (getContainingClass(node)) { return Diagnostics.Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode; } @@ -1031,7 +1031,7 @@ namespace ts { // containing class. if (node.flags & NodeFlags.AccessibilityModifier && node.parent.kind === SyntaxKind.Constructor && - (node.parent.parent.kind === SyntaxKind.ClassDeclaration || node.parent.parent.kind === SyntaxKind.ClassExpression)) { + isClassLike(node.parent.parent)) { let classDeclaration = node.parent.parent; declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes); diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index efc3e32166e57..9d3dc53da78bc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -386,8 +386,8 @@ namespace ts { // local variables of the constructor. This effectively means that entities from outer scopes // by the same name as a constructor parameter or local variable are inaccessible // in initializer expressions for instance member variables. - if (location.parent.kind === SyntaxKind.ClassDeclaration && !(location.flags & NodeFlags.Static)) { - let ctor = findConstructorDeclaration(location.parent); + if (isClassLike(location.parent) && !(location.flags & NodeFlags.Static)) { + let ctor = findConstructorDeclaration(location.parent); if (ctor && ctor.locals) { if (getSymbol(ctor.locals, name, meaning & SymbolFlags.Value)) { // Remember the property node, it will be used later to report appropriate error @@ -397,6 +397,7 @@ namespace ts { } break; case SyntaxKind.ClassDeclaration: + case SyntaxKind.ClassExpression: case SyntaxKind.InterfaceDeclaration: if (result = getSymbol(getSymbolOfNode(location).members, name, meaning & SymbolFlags.Type)) { if (lastLocation && lastLocation.flags & NodeFlags.Static) { @@ -408,6 +409,13 @@ namespace ts { } break loop; } + if (location.kind === SyntaxKind.ClassExpression && meaning & SymbolFlags.Class) { + let className = (location).name; + if (className && name === className.text) { + result = location.symbol; + break loop; + } + } break; // It is not legal to reference a class's own type parameters from a computed property name that @@ -420,7 +428,7 @@ namespace ts { // case SyntaxKind.ComputedPropertyName: grandparent = location.parent.parent; - if (grandparent.kind === SyntaxKind.ClassDeclaration || grandparent.kind === SyntaxKind.InterfaceDeclaration) { + if (isClassLike(grandparent) || grandparent.kind === SyntaxKind.InterfaceDeclaration) { // A reference to this grandparent's type parameters would be an error if (result = getSymbol(getSymbolOfNode(grandparent).members, name, meaning & SymbolFlags.Type)) { error(errorLocation, Diagnostics.A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type); @@ -454,15 +462,6 @@ namespace ts { } } break; - case SyntaxKind.ClassExpression: - if (meaning & SymbolFlags.Class) { - let className = (location).name; - if (className && name === className.text) { - result = location.symbol; - break loop; - } - } - break; case SyntaxKind.Decorator: // Decorators are resolved at the class declaration. Resolving at the parameter // or member would result in looking up locals in the method. @@ -1009,7 +1008,7 @@ namespace ts { return false; } - function findConstructorDeclaration(node: ClassDeclaration): ConstructorDeclaration { + function findConstructorDeclaration(node: ClassLikeDeclaration): ConstructorDeclaration { let members = node.members; for (let member of members) { if (member.kind === SyntaxKind.Constructor && nodeIsPresent((member).body)) { @@ -1396,20 +1395,30 @@ namespace ts { // This is for caching the result of getSymbolDisplayBuilder. Do not access directly. let _displayBuilder: SymbolDisplayBuilder; function getSymbolDisplayBuilder(): SymbolDisplayBuilder { - /** - * Writes only the name of the symbol out to the writer. Uses the original source text - * for the name of the symbol if it is available to match how the user inputted the name. - */ - function appendSymbolNameOnly(symbol: Symbol, writer: SymbolWriter): void { - if (symbol.declarations && symbol.declarations.length > 0) { + + function getNameOfSymbol(symbol: Symbol): string { + if (symbol.declarations && symbol.declarations.length) { let declaration = symbol.declarations[0]; if (declaration.name) { - writer.writeSymbol(declarationNameToString(declaration.name), symbol); - return; + return declarationNameToString(declaration.name); + } + switch (declaration.kind) { + case SyntaxKind.ClassExpression: + return "(Anonymous class)"; + case SyntaxKind.FunctionExpression: + case SyntaxKind.ArrowFunction: + return "(Anonymous function)"; } } + return symbol.name; + } - writer.writeSymbol(symbol.name, symbol); + /** + * Writes only the name of the symbol out to the writer. Uses the original source text + * for the name of the symbol if it is available to match how the user inputted the name. + */ + function appendSymbolNameOnly(symbol: Symbol, writer: SymbolWriter): void { + writer.writeSymbol(getNameOfSymbol(symbol), symbol); } /** @@ -2562,10 +2571,10 @@ namespace ts { if (!node) { return typeParameters; } - if (node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.FunctionDeclaration || - node.kind === SyntaxKind.FunctionExpression || node.kind === SyntaxKind.MethodDeclaration || - node.kind === SyntaxKind.ArrowFunction) { - let declarations = (node).typeParameters; + if (node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression || + node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.FunctionExpression || + node.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.ArrowFunction) { + let declarations = (node).typeParameters; if (declarations) { return appendTypeParameters(appendOuterTypeParameters(typeParameters, node), declarations); } @@ -2575,8 +2584,8 @@ namespace ts { // The outer type parameters are those defined by enclosing generic classes, methods, or functions. function getOuterTypeParametersOfClassOrInterface(symbol: Symbol): TypeParameter[] { - var kind = symbol.flags & SymbolFlags.Class ? SyntaxKind.ClassDeclaration : SyntaxKind.InterfaceDeclaration; - return appendOuterTypeParameters(undefined, getDeclarationOfKind(symbol, kind)); + var declaration = symbol.flags & SymbolFlags.Class ? symbol.valueDeclaration : getDeclarationOfKind(symbol, SyntaxKind.InterfaceDeclaration); + return appendOuterTypeParameters(undefined, declaration); } // The local type parameters are the combined set of type parameters from all declarations of the class, @@ -2584,7 +2593,8 @@ namespace ts { function getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol: Symbol): TypeParameter[] { let result: TypeParameter[]; for (let node of symbol.declarations) { - if (node.kind === SyntaxKind.InterfaceDeclaration || node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.TypeAliasDeclaration) { + if (node.kind === SyntaxKind.InterfaceDeclaration || node.kind === SyntaxKind.ClassDeclaration || + node.kind === SyntaxKind.ClassExpression || node.kind === SyntaxKind.TypeAliasDeclaration) { let declaration = node; if (declaration.typeParameters) { result = appendTypeParameters(result, declaration.typeParameters); @@ -5884,9 +5894,9 @@ namespace ts { } function captureLexicalThis(node: Node, container: Node): void { - let classNode = container.parent && container.parent.kind === SyntaxKind.ClassDeclaration ? container.parent : undefined; getNodeLinks(node).flags |= NodeCheckFlags.LexicalThis; if (container.kind === SyntaxKind.PropertyDeclaration || container.kind === SyntaxKind.Constructor) { + let classNode = container.parent; getNodeLinks(classNode).flags |= NodeCheckFlags.CaptureThis; } else { @@ -5939,9 +5949,8 @@ namespace ts { captureLexicalThis(node, container); } - let classNode = container.parent && container.parent.kind === SyntaxKind.ClassDeclaration ? container.parent : undefined; - if (classNode) { - let symbol = getSymbolOfNode(classNode); + if (isClassLike(container.parent)) { + let symbol = getSymbolOfNode(container.parent); return container.flags & NodeFlags.Static ? getTypeOfSymbol(symbol) : getDeclaredTypeOfSymbol(symbol); } return anyType; @@ -5958,7 +5967,7 @@ namespace ts { function checkSuperExpression(node: Node): Type { let isCallExpression = node.parent.kind === SyntaxKind.CallExpression && (node.parent).expression === node; - let classDeclaration = getAncestor(node, SyntaxKind.ClassDeclaration); + let classDeclaration = getContainingClass(node); let classType = classDeclaration && getDeclaredTypeOfSymbol(getSymbolOfNode(classDeclaration)); let baseClassType = classType && getBaseTypes(classType)[0]; @@ -5993,7 +6002,7 @@ namespace ts { } // topmost container must be something that is directly nested in the class declaration - if (container && container.parent && container.parent.kind === SyntaxKind.ClassDeclaration) { + if (container && isClassLike(container.parent)) { if (container.flags & NodeFlags.Static) { canUseSuperExpression = container.kind === SyntaxKind.MethodDeclaration || @@ -6652,7 +6661,7 @@ namespace ts { } // Property is known to be private or protected at this point // Get the declaring and enclosing class instance types - let enclosingClassDeclaration = getAncestor(node, SyntaxKind.ClassDeclaration); + let enclosingClassDeclaration = getContainingClass(node); let enclosingClass = enclosingClassDeclaration ? getDeclaredTypeOfSymbol(getSymbolOfNode(enclosingClassDeclaration)) : undefined; let declaringClass = getDeclaredTypeOfSymbol(prop.parent); // Private property is accessible if declaring and enclosing class are the same @@ -7426,7 +7435,7 @@ namespace ts { if (superType !== unknownType) { // In super call, the candidate signatures are the matching arity signatures of the base constructor function instantiated // with the type arguments specified in the extends clause. - let baseTypeNode = getClassExtendsHeritageClauseElement(getAncestor(node, SyntaxKind.ClassDeclaration)); + let baseTypeNode = getClassExtendsHeritageClauseElement(getContainingClass(node)); let baseConstructors = getInstantiatedConstructorsForTypeArguments(superType, baseTypeNode.typeArguments); return resolveCall(node, baseConstructors, candidatesOutArray); } @@ -7856,7 +7865,7 @@ namespace ts { if (node.type) { checkTypeAssignableTo(exprType, getTypeFromTypeNode(node.type), node.body, /*headMessage*/ undefined); } - checkFunctionExpressionBodies(node.body); + checkFunctionAndClassExpressionBodies(node.body); } } } @@ -8354,7 +8363,7 @@ namespace ts { if (isFunctionLike(parent) && current === (parent).body) { return false; } - else if (current.kind === SyntaxKind.ClassDeclaration || current.kind === SyntaxKind.ClassExpression) { + else if (isClassLike(current)) { return true; } @@ -9572,7 +9581,7 @@ namespace ts { forEach(node.statements, checkSourceElement); if (isFunctionBlock(node) || node.kind === SyntaxKind.ModuleBlock) { - checkFunctionExpressionBodies(node); + checkFunctionAndClassExpressionBodies(node); } } @@ -9648,7 +9657,7 @@ namespace ts { } // bubble up and find containing type - let enclosingClass = getAncestor(node, SyntaxKind.ClassDeclaration); + let enclosingClass = getContainingClass(node); // if containing type was not found or it is ambient - exit (no codegen) if (!enclosingClass || isInAmbientContext(enclosingClass)) { return; @@ -10456,8 +10465,8 @@ namespace ts { checkIndexConstraintForProperty(prop, propType, type, declaredNumberIndexer, numberIndexType, IndexKind.Number); }); - if (type.flags & TypeFlags.Class && type.symbol.valueDeclaration.kind === SyntaxKind.ClassDeclaration) { - let classDeclaration = type.symbol.valueDeclaration; + if (type.flags & TypeFlags.Class && isClassLike(type.symbol.valueDeclaration)) { + let classDeclaration = type.symbol.valueDeclaration; for (let member of classDeclaration.members) { // Only process instance properties with computed names here. // Static properties cannot be in conflict with indexers, @@ -10563,17 +10572,19 @@ namespace ts { } function checkClassExpression(node: ClassExpression): Type { - grammarErrorOnNode(node, Diagnostics.class_expressions_are_not_currently_supported); - forEach(node.members, checkSourceElement); - return unknownType; + checkClassLikeDeclaration(node); + return getTypeOfSymbol(getSymbolOfNode(node)); } function checkClassDeclaration(node: ClassDeclaration) { - // Grammar checking if (!node.name && !(node.flags & NodeFlags.Default)) { grammarErrorOnFirstToken(node, Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name); } + checkClassLikeDeclaration(node); + forEach(node.members, checkSourceElement); + } + function checkClassLikeDeclaration(node: ClassLikeDeclaration) { checkGrammarClassDeclarationHeritageClauses(node); checkDecorators(node); if (node.name) { @@ -10641,7 +10652,6 @@ namespace ts { }); } - forEach(node.members, checkSourceElement); if (produceDiagnostics) { checkIndexConstraints(type); checkTypeForDuplicateIndexSignatures(node); @@ -11514,8 +11524,8 @@ namespace ts { } } - // Function expression bodies are checked after all statements in the enclosing body. This is to ensure - // constructs like the following are permitted: + // Function and class expression bodies are checked after all statements in the enclosing body. This is + // to ensure constructs like the following are permitted: // let foo = function () { // let s = foo(); // return "hello"; @@ -11523,17 +11533,20 @@ namespace ts { // Here, performing a full type check of the body of the function expression whilst in the process of // determining the type of foo would cause foo to be given type any because of the recursive reference. // Delaying the type check of the body ensures foo has been assigned a type. - function checkFunctionExpressionBodies(node: Node): void { + function checkFunctionAndClassExpressionBodies(node: Node): void { switch (node.kind) { case SyntaxKind.FunctionExpression: case SyntaxKind.ArrowFunction: - forEach((node).parameters, checkFunctionExpressionBodies); + forEach((node).parameters, checkFunctionAndClassExpressionBodies); checkFunctionExpressionOrObjectLiteralMethodBody(node); break; + case SyntaxKind.ClassExpression: + forEach((node).members, checkSourceElement); + break; case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: - forEach(node.decorators, checkFunctionExpressionBodies); - forEach((node).parameters, checkFunctionExpressionBodies); + forEach(node.decorators, checkFunctionAndClassExpressionBodies); + forEach((node).parameters, checkFunctionAndClassExpressionBodies); if (isObjectLiteralMethod(node)) { checkFunctionExpressionOrObjectLiteralMethodBody(node); } @@ -11542,10 +11555,10 @@ namespace ts { case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: case SyntaxKind.FunctionDeclaration: - forEach((node).parameters, checkFunctionExpressionBodies); + forEach((node).parameters, checkFunctionAndClassExpressionBodies); break; case SyntaxKind.WithStatement: - checkFunctionExpressionBodies((node).expression); + checkFunctionAndClassExpressionBodies((node).expression); break; case SyntaxKind.Decorator: case SyntaxKind.Parameter: @@ -11602,7 +11615,7 @@ namespace ts { case SyntaxKind.EnumMember: case SyntaxKind.ExportAssignment: case SyntaxKind.SourceFile: - forEachChild(node, checkFunctionExpressionBodies); + forEachChild(node, checkFunctionAndClassExpressionBodies); break; } } @@ -11634,7 +11647,7 @@ namespace ts { potentialThisCollisions.length = 0; forEach(node.statements, checkSourceElement); - checkFunctionExpressionBodies(node); + checkFunctionAndClassExpressionBodies(node); if (isExternalModule(node)) { checkExternalModuleExports(node); @@ -11727,6 +11740,11 @@ namespace ts { case SyntaxKind.EnumDeclaration: copySymbols(getSymbolOfNode(location).exports, meaning & SymbolFlags.EnumMember); break; + case SyntaxKind.ClassExpression: + if ((location).name) { + copySymbol(location.symbol, meaning); + } + // Fall through case SyntaxKind.ClassDeclaration: case SyntaxKind.InterfaceDeclaration: if (!(memberFlags & NodeFlags.Static)) { @@ -11766,42 +11784,6 @@ namespace ts { } } } - - if (isInsideWithStatementBody(location)) { - // We cannot answer semantic questions within a with block, do not proceed any further - return []; - } - - while (location) { - if (location.locals && !isGlobalSourceFile(location)) { - copySymbols(location.locals, meaning); - } - switch (location.kind) { - case SyntaxKind.SourceFile: - if (!isExternalModule(location)) break; - case SyntaxKind.ModuleDeclaration: - copySymbols(getSymbolOfNode(location).exports, meaning & SymbolFlags.ModuleMember); - break; - case SyntaxKind.EnumDeclaration: - copySymbols(getSymbolOfNode(location).exports, meaning & SymbolFlags.EnumMember); - break; - case SyntaxKind.ClassDeclaration: - case SyntaxKind.InterfaceDeclaration: - if (!(memberFlags & NodeFlags.Static)) { - copySymbols(getSymbolOfNode(location).members, meaning & SymbolFlags.Type); - } - break; - case SyntaxKind.FunctionExpression: - if ((location).name) { - copySymbol(location.symbol, meaning); - } - break; - } - memberFlags = location.flags; - location = location.parent; - } - copySymbols(globals, meaning); - return symbolsToArray(symbols); } function isTypeDeclarationName(name: Node): boolean { @@ -12950,7 +12932,7 @@ namespace ts { } } - function checkGrammarClassDeclarationHeritageClauses(node: ClassDeclaration) { + function checkGrammarClassDeclarationHeritageClauses(node: ClassLikeDeclaration) { let seenExtendsClause = false; let seenImplementsClause = false; @@ -13213,7 +13195,7 @@ namespace ts { } } - if (node.parent.kind === SyntaxKind.ClassDeclaration) { + if (isClassLike(node.parent)) { if (checkGrammarForInvalidQuestionMark(node, node.questionToken, Diagnostics.A_class_member_cannot_be_declared_optional)) { return true; } @@ -13505,7 +13487,7 @@ namespace ts { } function checkGrammarProperty(node: PropertyDeclaration) { - if (node.parent.kind === SyntaxKind.ClassDeclaration) { + if (isClassLike(node.parent)) { if (checkGrammarForInvalidQuestionMark(node, node.questionToken, Diagnostics.A_class_member_cannot_be_declared_optional) || checkGrammarForNonSymbolComputedProperty(node.name, Diagnostics.A_computed_property_name_in_a_class_property_declaration_must_directly_refer_to_a_built_in_symbol)) { return true; diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 09b009711fee2..bfe103757c5ab 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -567,7 +567,5 @@ namespace ts { enum_declarations_can_only_be_used_in_a_ts_file: { code: 8015, category: DiagnosticCategory.Error, key: "'enum declarations' can only be used in a .ts file." }, type_assertion_expressions_can_only_be_used_in_a_ts_file: { code: 8016, category: DiagnosticCategory.Error, key: "'type assertion expressions' can only be used in a .ts file." }, decorators_can_only_be_used_in_a_ts_file: { code: 8017, category: DiagnosticCategory.Error, key: "'decorators' can only be used in a .ts file." }, - Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_class_extends_clauses: { code: 9002, category: DiagnosticCategory.Error, key: "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clauses." }, - class_expressions_are_not_currently_supported: { code: 9003, category: DiagnosticCategory.Error, key: "'class' expressions are not currently supported." }, }; } \ No newline at end of file diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index fee46a84c1e4e..3e4ef26507fb3 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2259,14 +2259,5 @@ "'decorators' can only be used in a .ts file.": { "category": "Error", "code": 8017 - }, - - "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clauses.": { - "category": "Error", - "code": 9002 - }, - "'class' expressions are not currently supported.": { - "category": "Error", - "code": 9003 } } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 469b13294addf..8e4a038dde4a4 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -264,6 +264,10 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { return makeUniqueName("default"); } + function generateNameForClassExpression() { + return makeUniqueName("class"); + } + function generateNameForNode(node: Node) { switch (node.kind) { case SyntaxKind.Identifier: @@ -276,9 +280,10 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { return generateNameForImportOrExportDeclaration(node); case SyntaxKind.FunctionDeclaration: case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: case SyntaxKind.ExportAssignment: return generateNameForExportDefault(); + case SyntaxKind.ClassExpression: + return generateNameForClassExpression(); } } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index e0fc5fc0269f4..c820c5886892f 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -542,6 +542,7 @@ namespace ts { case SyntaxKind.ModuleDeclaration: case SyntaxKind.TypeAliasDeclaration: case SyntaxKind.ClassDeclaration: + case SyntaxKind.ClassExpression: // These are not allowed inside a generator now, but eventually they may be allowed // as local types. Regardless, any yield statements contained within them should be // skipped in this traversal. @@ -579,26 +580,15 @@ namespace ts { return true; } } - return false; } export function isAccessor(node: Node): boolean { - if (node) { - switch (node.kind) { - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - return true; - } - } - - return false; + return node && (node.kind === SyntaxKind.GetAccessor || node.kind === SyntaxKind.SetAccessor); } export function isClassLike(node: Node): boolean { - if (node) { - return node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression; - } + return node && (node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression); } export function isFunctionLike(node: Node): boolean { @@ -620,7 +610,6 @@ namespace ts { return true; } } - return false; } @@ -641,6 +630,15 @@ namespace ts { } } + export function getContainingClass(node: Node): ClassLikeDeclaration { + while (true) { + node = node.parent; + if (!node || isClassLike(node)) { + return node; + } + } + } + export function getThisContainer(node: Node, includeArrowFunctions: boolean): Node { while (true) { node = node.parent; @@ -653,7 +651,7 @@ namespace ts { // then the computed property is not a 'this' container. // A computed property name in a class needs to be a this container // so that we can error on it. - if (node.parent.parent.kind === SyntaxKind.ClassDeclaration) { + if (isClassLike(node.parent.parent)) { return node; } // If this is a computed property, then the parent should not @@ -708,7 +706,7 @@ namespace ts { // then the computed property is not a 'super' container. // A computed property name in a class needs to be a super container // so that we can error on it. - if (node.parent.parent.kind === SyntaxKind.ClassDeclaration) { + if (isClassLike(node.parent.parent)) { return node; } // If this is a computed property, then the parent should not @@ -1087,6 +1085,7 @@ namespace ts { case SyntaxKind.ArrowFunction: case SyntaxKind.BindingElement: case SyntaxKind.ClassDeclaration: + case SyntaxKind.ClassExpression: case SyntaxKind.Constructor: case SyntaxKind.EnumDeclaration: case SyntaxKind.EnumMember: @@ -1235,7 +1234,7 @@ namespace ts { return heritageClause && heritageClause.types.length > 0 ? heritageClause.types[0] : undefined; } - export function getClassImplementsHeritageClauseElements(node: ClassDeclaration) { + export function getClassImplementsHeritageClauseElements(node: ClassLikeDeclaration) { let heritageClause = getHeritageClause(node.heritageClauses, SyntaxKind.ImplementsKeyword); return heritageClause ? heritageClause.types : undefined; } @@ -1917,7 +1916,7 @@ namespace ts { export function isExpressionWithTypeArgumentsInClassExtendsClause(node: Node): boolean { return node.kind === SyntaxKind.ExpressionWithTypeArguments && (node.parent).token === SyntaxKind.ExtendsKeyword && - node.parent.parent.kind === SyntaxKind.ClassDeclaration; + isClassLike(node.parent.parent); } // Returns false if this heritage clause element's expression contains something unsupported diff --git a/tests/baselines/reference/anonymousClassExpression1.errors.txt b/tests/baselines/reference/anonymousClassExpression1.errors.txt deleted file mode 100644 index db4c5b4ce3da1..0000000000000 --- a/tests/baselines/reference/anonymousClassExpression1.errors.txt +++ /dev/null @@ -1,9 +0,0 @@ -tests/cases/compiler/anonymousClassExpression1.ts(2,19): error TS9003: 'class' expressions are not currently supported. - - -==== tests/cases/compiler/anonymousClassExpression1.ts (1 errors) ==== - function f() { - return typeof class {} === "function"; - ~~~~~ -!!! error TS9003: 'class' expressions are not currently supported. - } \ No newline at end of file diff --git a/tests/baselines/reference/anonymousClassExpression1.js b/tests/baselines/reference/anonymousClassExpression1.js index 78cf5b05c51fb..5ced5120979fc 100644 --- a/tests/baselines/reference/anonymousClassExpression1.js +++ b/tests/baselines/reference/anonymousClassExpression1.js @@ -6,8 +6,8 @@ function f() { //// [anonymousClassExpression1.js] function f() { return typeof (function () { - function default_1() { + function class_1() { } - return default_1; + return class_1; })() === "function"; } diff --git a/tests/baselines/reference/anonymousClassExpression1.symbols b/tests/baselines/reference/anonymousClassExpression1.symbols new file mode 100644 index 0000000000000..114bfc96097a2 --- /dev/null +++ b/tests/baselines/reference/anonymousClassExpression1.symbols @@ -0,0 +1,6 @@ +=== tests/cases/compiler/anonymousClassExpression1.ts === +function f() { +>f : Symbol(f, Decl(anonymousClassExpression1.ts, 0, 0)) + + return typeof class {} === "function"; +} diff --git a/tests/baselines/reference/anonymousClassExpression1.types b/tests/baselines/reference/anonymousClassExpression1.types new file mode 100644 index 0000000000000..1e38399f01ed7 --- /dev/null +++ b/tests/baselines/reference/anonymousClassExpression1.types @@ -0,0 +1,10 @@ +=== tests/cases/compiler/anonymousClassExpression1.ts === +function f() { +>f : () => boolean + + return typeof class {} === "function"; +>typeof class {} === "function" : boolean +>typeof class {} : string +>class {} : typeof (Anonymous class) +>"function" : string +} diff --git a/tests/baselines/reference/classExpression.errors.txt b/tests/baselines/reference/classExpression.errors.txt deleted file mode 100644 index c8266d0e87953..0000000000000 --- a/tests/baselines/reference/classExpression.errors.txt +++ /dev/null @@ -1,24 +0,0 @@ -tests/cases/conformance/classes/classExpression.ts(1,15): error TS9003: 'class' expressions are not currently supported. -tests/cases/conformance/classes/classExpression.ts(5,16): error TS9003: 'class' expressions are not currently supported. -tests/cases/conformance/classes/classExpression.ts(10,19): error TS9003: 'class' expressions are not currently supported. - - -==== tests/cases/conformance/classes/classExpression.ts (3 errors) ==== - var x = class C { - ~ -!!! error TS9003: 'class' expressions are not currently supported. - } - - var y = { - foo: class C2 { - ~~ -!!! error TS9003: 'class' expressions are not currently supported. - } - } - - module M { - var z = class C4 { - ~~ -!!! error TS9003: 'class' expressions are not currently supported. - } - } \ No newline at end of file diff --git a/tests/baselines/reference/classExpression.symbols b/tests/baselines/reference/classExpression.symbols new file mode 100644 index 0000000000000..f4d4423649983 --- /dev/null +++ b/tests/baselines/reference/classExpression.symbols @@ -0,0 +1,23 @@ +=== tests/cases/conformance/classes/classExpression.ts === +var x = class C { +>x : Symbol(x, Decl(classExpression.ts, 0, 3)) +>C : Symbol(C, Decl(classExpression.ts, 0, 7)) +} + +var y = { +>y : Symbol(y, Decl(classExpression.ts, 3, 3)) + + foo: class C2 { +>foo : Symbol(foo, Decl(classExpression.ts, 3, 9)) +>C2 : Symbol(C2, Decl(classExpression.ts, 4, 8)) + } +} + +module M { +>M : Symbol(M, Decl(classExpression.ts, 6, 1)) + + var z = class C4 { +>z : Symbol(z, Decl(classExpression.ts, 9, 7)) +>C4 : Symbol(C4, Decl(classExpression.ts, 9, 11)) + } +} diff --git a/tests/baselines/reference/classExpression.types b/tests/baselines/reference/classExpression.types new file mode 100644 index 0000000000000..1c55ce895447e --- /dev/null +++ b/tests/baselines/reference/classExpression.types @@ -0,0 +1,27 @@ +=== tests/cases/conformance/classes/classExpression.ts === +var x = class C { +>x : typeof C +>class C {} : typeof C +>C : typeof C +} + +var y = { +>y : { foo: typeof C2; } +>{ foo: class C2 { }} : { foo: typeof C2; } + + foo: class C2 { +>foo : typeof C2 +>class C2 { } : typeof C2 +>C2 : typeof C2 + } +} + +module M { +>M : typeof M + + var z = class C4 { +>z : typeof C4 +>class C4 { } : typeof C4 +>C4 : typeof C4 + } +} diff --git a/tests/baselines/reference/classExpression1.errors.txt b/tests/baselines/reference/classExpression1.errors.txt deleted file mode 100644 index 9d7d14d857103..0000000000000 --- a/tests/baselines/reference/classExpression1.errors.txt +++ /dev/null @@ -1,7 +0,0 @@ -tests/cases/conformance/classes/classExpressions/classExpression1.ts(1,15): error TS9003: 'class' expressions are not currently supported. - - -==== tests/cases/conformance/classes/classExpressions/classExpression1.ts (1 errors) ==== - var v = class C {}; - ~ -!!! error TS9003: 'class' expressions are not currently supported. \ No newline at end of file diff --git a/tests/baselines/reference/classExpression1.symbols b/tests/baselines/reference/classExpression1.symbols new file mode 100644 index 0000000000000..8d3bad269b4f4 --- /dev/null +++ b/tests/baselines/reference/classExpression1.symbols @@ -0,0 +1,5 @@ +=== tests/cases/conformance/classes/classExpressions/classExpression1.ts === +var v = class C {}; +>v : Symbol(v, Decl(classExpression1.ts, 0, 3)) +>C : Symbol(C, Decl(classExpression1.ts, 0, 7)) + diff --git a/tests/baselines/reference/classExpression1.types b/tests/baselines/reference/classExpression1.types new file mode 100644 index 0000000000000..4bea3183118ac --- /dev/null +++ b/tests/baselines/reference/classExpression1.types @@ -0,0 +1,6 @@ +=== tests/cases/conformance/classes/classExpressions/classExpression1.ts === +var v = class C {}; +>v : typeof C +>class C {} : typeof C +>C : typeof C + diff --git a/tests/baselines/reference/classExpression2.errors.txt b/tests/baselines/reference/classExpression2.errors.txt deleted file mode 100644 index e2f3ccd77cdff..0000000000000 --- a/tests/baselines/reference/classExpression2.errors.txt +++ /dev/null @@ -1,8 +0,0 @@ -tests/cases/conformance/classes/classExpressions/classExpression2.ts(2,15): error TS9003: 'class' expressions are not currently supported. - - -==== tests/cases/conformance/classes/classExpressions/classExpression2.ts (1 errors) ==== - class D { } - var v = class C extends D {}; - ~ -!!! error TS9003: 'class' expressions are not currently supported. \ No newline at end of file diff --git a/tests/baselines/reference/classExpression2.js b/tests/baselines/reference/classExpression2.js index 4220b88fb11ee..f74bb8bd5e24a 100644 --- a/tests/baselines/reference/classExpression2.js +++ b/tests/baselines/reference/classExpression2.js @@ -3,6 +3,11 @@ class D { } var v = class C extends D {}; //// [classExpression2.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; var D = (function () { function D() { } diff --git a/tests/baselines/reference/classExpression2.symbols b/tests/baselines/reference/classExpression2.symbols new file mode 100644 index 0000000000000..11c78a2cad2b0 --- /dev/null +++ b/tests/baselines/reference/classExpression2.symbols @@ -0,0 +1,9 @@ +=== tests/cases/conformance/classes/classExpressions/classExpression2.ts === +class D { } +>D : Symbol(D, Decl(classExpression2.ts, 0, 0)) + +var v = class C extends D {}; +>v : Symbol(v, Decl(classExpression2.ts, 1, 3)) +>C : Symbol(C, Decl(classExpression2.ts, 1, 7)) +>D : Symbol(D, Decl(classExpression2.ts, 0, 0)) + diff --git a/tests/baselines/reference/classExpression2.types b/tests/baselines/reference/classExpression2.types new file mode 100644 index 0000000000000..4dd6595fb493c --- /dev/null +++ b/tests/baselines/reference/classExpression2.types @@ -0,0 +1,10 @@ +=== tests/cases/conformance/classes/classExpressions/classExpression2.ts === +class D { } +>D : D + +var v = class C extends D {}; +>v : typeof C +>class C extends D {} : typeof C +>C : typeof C +>D : D + diff --git a/tests/baselines/reference/classExpression3.js b/tests/baselines/reference/classExpression3.js new file mode 100644 index 0000000000000..ec9581eaf396c --- /dev/null +++ b/tests/baselines/reference/classExpression3.js @@ -0,0 +1,38 @@ +//// [classExpression3.ts] +let C = class extends class extends class { a = 1 } { b = 2 } { c = 3 }; +let c = new C(); +c.a; +c.b; +c.c; + + +//// [classExpression3.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var C = (function (_super) { + __extends(class_1, _super); + function class_1() { + _super.apply(this, arguments); + this.c = 3; + } + return class_1; +})((function (_super) { + __extends(class_2, _super); + function class_2() { + _super.apply(this, arguments); + this.b = 2; + } + return class_2; +})((function () { + function class_3() { + this.a = 1; + } + return class_3; +})())); +var c = new C(); +c.a; +c.b; +c.c; diff --git a/tests/baselines/reference/classExpression3.symbols b/tests/baselines/reference/classExpression3.symbols new file mode 100644 index 0000000000000..bc1b263a00044 --- /dev/null +++ b/tests/baselines/reference/classExpression3.symbols @@ -0,0 +1,26 @@ +=== tests/cases/conformance/classes/classExpressions/classExpression3.ts === +let C = class extends class extends class { a = 1 } { b = 2 } { c = 3 }; +>C : Symbol(C, Decl(classExpression3.ts, 0, 3)) +>a : Symbol((Anonymous class).a, Decl(classExpression3.ts, 0, 43)) +>b : Symbol((Anonymous class).b, Decl(classExpression3.ts, 0, 53)) +>c : Symbol((Anonymous class).c, Decl(classExpression3.ts, 0, 63)) + +let c = new C(); +>c : Symbol(c, Decl(classExpression3.ts, 1, 3)) +>C : Symbol(C, Decl(classExpression3.ts, 0, 3)) + +c.a; +>c.a : Symbol((Anonymous class).a, Decl(classExpression3.ts, 0, 43)) +>c : Symbol(c, Decl(classExpression3.ts, 1, 3)) +>a : Symbol((Anonymous class).a, Decl(classExpression3.ts, 0, 43)) + +c.b; +>c.b : Symbol((Anonymous class).b, Decl(classExpression3.ts, 0, 53)) +>c : Symbol(c, Decl(classExpression3.ts, 1, 3)) +>b : Symbol((Anonymous class).b, Decl(classExpression3.ts, 0, 53)) + +c.c; +>c.c : Symbol((Anonymous class).c, Decl(classExpression3.ts, 0, 63)) +>c : Symbol(c, Decl(classExpression3.ts, 1, 3)) +>c : Symbol((Anonymous class).c, Decl(classExpression3.ts, 0, 63)) + diff --git a/tests/baselines/reference/classExpression3.types b/tests/baselines/reference/classExpression3.types new file mode 100644 index 0000000000000..87423ecf0bd60 --- /dev/null +++ b/tests/baselines/reference/classExpression3.types @@ -0,0 +1,33 @@ +=== tests/cases/conformance/classes/classExpressions/classExpression3.ts === +let C = class extends class extends class { a = 1 } { b = 2 } { c = 3 }; +>C : typeof (Anonymous class) +>class extends class extends class { a = 1 } { b = 2 } { c = 3 } : typeof (Anonymous class) +>class extends class { a = 1 } { b = 2 } : (Anonymous class) +>class { a = 1 } : (Anonymous class) +>a : number +>1 : number +>b : number +>2 : number +>c : number +>3 : number + +let c = new C(); +>c : (Anonymous class) +>new C() : (Anonymous class) +>C : typeof (Anonymous class) + +c.a; +>c.a : number +>c : (Anonymous class) +>a : number + +c.b; +>c.b : number +>c : (Anonymous class) +>b : number + +c.c; +>c.c : number +>c : (Anonymous class) +>c : number + diff --git a/tests/baselines/reference/classExpression4.js b/tests/baselines/reference/classExpression4.js new file mode 100644 index 0000000000000..c2ead0474e25b --- /dev/null +++ b/tests/baselines/reference/classExpression4.js @@ -0,0 +1,19 @@ +//// [classExpression4.ts] +let C = class { + foo() { + return new C(); + } +}; +let x = (new C).foo(); + + +//// [classExpression4.js] +var C = (function () { + function class_1() { + } + class_1.prototype.foo = function () { + return new C(); + }; + return class_1; +})(); +var x = (new C).foo(); diff --git a/tests/baselines/reference/classExpression4.symbols b/tests/baselines/reference/classExpression4.symbols new file mode 100644 index 0000000000000..4df5302cecc56 --- /dev/null +++ b/tests/baselines/reference/classExpression4.symbols @@ -0,0 +1,17 @@ +=== tests/cases/conformance/classes/classExpressions/classExpression4.ts === +let C = class { +>C : Symbol(C, Decl(classExpression4.ts, 0, 3)) + + foo() { +>foo : Symbol((Anonymous class).foo, Decl(classExpression4.ts, 0, 15)) + + return new C(); +>C : Symbol(C, Decl(classExpression4.ts, 0, 3)) + } +}; +let x = (new C).foo(); +>x : Symbol(x, Decl(classExpression4.ts, 5, 3)) +>(new C).foo : Symbol((Anonymous class).foo, Decl(classExpression4.ts, 0, 15)) +>C : Symbol(C, Decl(classExpression4.ts, 0, 3)) +>foo : Symbol((Anonymous class).foo, Decl(classExpression4.ts, 0, 15)) + diff --git a/tests/baselines/reference/classExpression4.types b/tests/baselines/reference/classExpression4.types new file mode 100644 index 0000000000000..066f169ae7405 --- /dev/null +++ b/tests/baselines/reference/classExpression4.types @@ -0,0 +1,22 @@ +=== tests/cases/conformance/classes/classExpressions/classExpression4.ts === +let C = class { +>C : typeof (Anonymous class) +>class { foo() { return new C(); }} : typeof (Anonymous class) + + foo() { +>foo : () => (Anonymous class) + + return new C(); +>new C() : (Anonymous class) +>C : typeof (Anonymous class) + } +}; +let x = (new C).foo(); +>x : (Anonymous class) +>(new C).foo() : (Anonymous class) +>(new C).foo : () => (Anonymous class) +>(new C) : (Anonymous class) +>new C : (Anonymous class) +>C : typeof (Anonymous class) +>foo : () => (Anonymous class) + diff --git a/tests/baselines/reference/classExpressionES61.errors.txt b/tests/baselines/reference/classExpressionES61.errors.txt deleted file mode 100644 index abaa5ab893ce2..0000000000000 --- a/tests/baselines/reference/classExpressionES61.errors.txt +++ /dev/null @@ -1,7 +0,0 @@ -tests/cases/conformance/es6/classExpressions/classExpressionES61.ts(1,15): error TS9003: 'class' expressions are not currently supported. - - -==== tests/cases/conformance/es6/classExpressions/classExpressionES61.ts (1 errors) ==== - var v = class C {}; - ~ -!!! error TS9003: 'class' expressions are not currently supported. \ No newline at end of file diff --git a/tests/baselines/reference/classExpressionES61.symbols b/tests/baselines/reference/classExpressionES61.symbols new file mode 100644 index 0000000000000..1f49229fbc738 --- /dev/null +++ b/tests/baselines/reference/classExpressionES61.symbols @@ -0,0 +1,5 @@ +=== tests/cases/conformance/es6/classExpressions/classExpressionES61.ts === +var v = class C {}; +>v : Symbol(v, Decl(classExpressionES61.ts, 0, 3)) +>C : Symbol(C, Decl(classExpressionES61.ts, 0, 7)) + diff --git a/tests/baselines/reference/classExpressionES61.types b/tests/baselines/reference/classExpressionES61.types new file mode 100644 index 0000000000000..e04570308e82a --- /dev/null +++ b/tests/baselines/reference/classExpressionES61.types @@ -0,0 +1,6 @@ +=== tests/cases/conformance/es6/classExpressions/classExpressionES61.ts === +var v = class C {}; +>v : typeof C +>class C {} : typeof C +>C : typeof C + diff --git a/tests/baselines/reference/classExpressionES62.errors.txt b/tests/baselines/reference/classExpressionES62.errors.txt deleted file mode 100644 index 1e28367a17eb1..0000000000000 --- a/tests/baselines/reference/classExpressionES62.errors.txt +++ /dev/null @@ -1,8 +0,0 @@ -tests/cases/conformance/es6/classExpressions/classExpressionES62.ts(2,15): error TS9003: 'class' expressions are not currently supported. - - -==== tests/cases/conformance/es6/classExpressions/classExpressionES62.ts (1 errors) ==== - class D { } - var v = class C extends D {}; - ~ -!!! error TS9003: 'class' expressions are not currently supported. \ No newline at end of file diff --git a/tests/baselines/reference/classExpressionES62.symbols b/tests/baselines/reference/classExpressionES62.symbols new file mode 100644 index 0000000000000..18e1a48ca30d7 --- /dev/null +++ b/tests/baselines/reference/classExpressionES62.symbols @@ -0,0 +1,9 @@ +=== tests/cases/conformance/es6/classExpressions/classExpressionES62.ts === +class D { } +>D : Symbol(D, Decl(classExpressionES62.ts, 0, 0)) + +var v = class C extends D {}; +>v : Symbol(v, Decl(classExpressionES62.ts, 1, 3)) +>C : Symbol(C, Decl(classExpressionES62.ts, 1, 7)) +>D : Symbol(D, Decl(classExpressionES62.ts, 0, 0)) + diff --git a/tests/baselines/reference/classExpressionES62.types b/tests/baselines/reference/classExpressionES62.types new file mode 100644 index 0000000000000..8bb4e1a39ff3f --- /dev/null +++ b/tests/baselines/reference/classExpressionES62.types @@ -0,0 +1,10 @@ +=== tests/cases/conformance/es6/classExpressions/classExpressionES62.ts === +class D { } +>D : D + +var v = class C extends D {}; +>v : typeof C +>class C extends D {} : typeof C +>C : typeof C +>D : D + diff --git a/tests/baselines/reference/classExpressionES63.js b/tests/baselines/reference/classExpressionES63.js new file mode 100644 index 0000000000000..6d357af7c5a9b --- /dev/null +++ b/tests/baselines/reference/classExpressionES63.js @@ -0,0 +1,31 @@ +//// [classExpressionES63.ts] +let C = class extends class extends class { a = 1 } { b = 2 } { c = 3 }; +let c = new C(); +c.a; +c.b; +c.c; + + +//// [classExpressionES63.js] +let C = class class_1 extends class class_2 extends class class_3 { + constructor() { + this.a = 1; + } +} + { + constructor(...args) { + super(...args); + this.b = 2; + } +} + { + constructor(...args) { + super(...args); + this.c = 3; + } +} +; +let c = new C(); +c.a; +c.b; +c.c; diff --git a/tests/baselines/reference/classExpressionES63.symbols b/tests/baselines/reference/classExpressionES63.symbols new file mode 100644 index 0000000000000..4e52d5ee9ddc1 --- /dev/null +++ b/tests/baselines/reference/classExpressionES63.symbols @@ -0,0 +1,26 @@ +=== tests/cases/conformance/es6/classExpressions/classExpressionES63.ts === +let C = class extends class extends class { a = 1 } { b = 2 } { c = 3 }; +>C : Symbol(C, Decl(classExpressionES63.ts, 0, 3)) +>a : Symbol((Anonymous class).a, Decl(classExpressionES63.ts, 0, 43)) +>b : Symbol((Anonymous class).b, Decl(classExpressionES63.ts, 0, 53)) +>c : Symbol((Anonymous class).c, Decl(classExpressionES63.ts, 0, 63)) + +let c = new C(); +>c : Symbol(c, Decl(classExpressionES63.ts, 1, 3)) +>C : Symbol(C, Decl(classExpressionES63.ts, 0, 3)) + +c.a; +>c.a : Symbol((Anonymous class).a, Decl(classExpressionES63.ts, 0, 43)) +>c : Symbol(c, Decl(classExpressionES63.ts, 1, 3)) +>a : Symbol((Anonymous class).a, Decl(classExpressionES63.ts, 0, 43)) + +c.b; +>c.b : Symbol((Anonymous class).b, Decl(classExpressionES63.ts, 0, 53)) +>c : Symbol(c, Decl(classExpressionES63.ts, 1, 3)) +>b : Symbol((Anonymous class).b, Decl(classExpressionES63.ts, 0, 53)) + +c.c; +>c.c : Symbol((Anonymous class).c, Decl(classExpressionES63.ts, 0, 63)) +>c : Symbol(c, Decl(classExpressionES63.ts, 1, 3)) +>c : Symbol((Anonymous class).c, Decl(classExpressionES63.ts, 0, 63)) + diff --git a/tests/baselines/reference/classExpressionES63.types b/tests/baselines/reference/classExpressionES63.types new file mode 100644 index 0000000000000..5b07bf79692b0 --- /dev/null +++ b/tests/baselines/reference/classExpressionES63.types @@ -0,0 +1,33 @@ +=== tests/cases/conformance/es6/classExpressions/classExpressionES63.ts === +let C = class extends class extends class { a = 1 } { b = 2 } { c = 3 }; +>C : typeof (Anonymous class) +>class extends class extends class { a = 1 } { b = 2 } { c = 3 } : typeof (Anonymous class) +>class extends class { a = 1 } { b = 2 } : (Anonymous class) +>class { a = 1 } : (Anonymous class) +>a : number +>1 : number +>b : number +>2 : number +>c : number +>3 : number + +let c = new C(); +>c : (Anonymous class) +>new C() : (Anonymous class) +>C : typeof (Anonymous class) + +c.a; +>c.a : number +>c : (Anonymous class) +>a : number + +c.b; +>c.b : number +>c : (Anonymous class) +>b : number + +c.c; +>c.c : number +>c : (Anonymous class) +>c : number + diff --git a/tests/baselines/reference/classExpressionTest2.errors.txt b/tests/baselines/reference/classExpressionTest2.errors.txt deleted file mode 100644 index 424eb59061135..0000000000000 --- a/tests/baselines/reference/classExpressionTest2.errors.txt +++ /dev/null @@ -1,21 +0,0 @@ -tests/cases/compiler/classExpressionTest2.ts(2,19): error TS9003: 'class' expressions are not currently supported. -tests/cases/compiler/classExpressionTest2.ts(5,20): error TS2304: Cannot find name 'X'. - - -==== tests/cases/compiler/classExpressionTest2.ts (2 errors) ==== - function M() { - var m = class C { - ~ -!!! error TS9003: 'class' expressions are not currently supported. - f() { - var t: T; - var x: X; - ~ -!!! error TS2304: Cannot find name 'X'. - return { t, x }; - } - } - - var v = new m(); - return v.f(); - } \ No newline at end of file diff --git a/tests/baselines/reference/classExpressionTest2.symbols b/tests/baselines/reference/classExpressionTest2.symbols new file mode 100644 index 0000000000000..62143cf0b9f08 --- /dev/null +++ b/tests/baselines/reference/classExpressionTest2.symbols @@ -0,0 +1,36 @@ +=== tests/cases/compiler/classExpressionTest2.ts === +function M() { +>M : Symbol(M, Decl(classExpressionTest2.ts, 0, 0)) + + var m = class C { +>m : Symbol(m, Decl(classExpressionTest2.ts, 1, 7)) +>C : Symbol(C, Decl(classExpressionTest2.ts, 1, 11)) +>X : Symbol(X, Decl(classExpressionTest2.ts, 1, 20)) + + f() { +>f : Symbol(C.f, Decl(classExpressionTest2.ts, 1, 24)) +>T : Symbol(T, Decl(classExpressionTest2.ts, 2, 10)) + + var t: T; +>t : Symbol(t, Decl(classExpressionTest2.ts, 3, 15)) +>T : Symbol(T, Decl(classExpressionTest2.ts, 2, 10)) + + var x: X; +>x : Symbol(x, Decl(classExpressionTest2.ts, 4, 15)) +>X : Symbol(X, Decl(classExpressionTest2.ts, 1, 20)) + + return { t, x }; +>t : Symbol(t, Decl(classExpressionTest2.ts, 5, 20)) +>x : Symbol(x, Decl(classExpressionTest2.ts, 5, 23)) + } + } + + var v = new m(); +>v : Symbol(v, Decl(classExpressionTest2.ts, 9, 7)) +>m : Symbol(m, Decl(classExpressionTest2.ts, 1, 7)) + + return v.f(); +>v.f : Symbol(C.f, Decl(classExpressionTest2.ts, 1, 24)) +>v : Symbol(v, Decl(classExpressionTest2.ts, 9, 7)) +>f : Symbol(C.f, Decl(classExpressionTest2.ts, 1, 24)) +} diff --git a/tests/baselines/reference/classExpressionTest2.types b/tests/baselines/reference/classExpressionTest2.types new file mode 100644 index 0000000000000..5586b451d3a55 --- /dev/null +++ b/tests/baselines/reference/classExpressionTest2.types @@ -0,0 +1,40 @@ +=== tests/cases/compiler/classExpressionTest2.ts === +function M() { +>M : () => { t: string; x: number; } + + var m = class C { +>m : typeof C +>class C { f() { var t: T; var x: X; return { t, x }; } } : typeof C +>C : typeof C +>X : X + + f() { +>f : () => { t: T; x: X; } +>T : T + + var t: T; +>t : T +>T : T + + var x: X; +>x : X +>X : X + + return { t, x }; +>{ t, x } : { t: T; x: X; } +>t : T +>x : X + } + } + + var v = new m(); +>v : +>new m() : +>m : typeof C + + return v.f(); +>v.f() : { t: string; x: number; } +>v.f : () => { t: T; x: number; } +>v : +>f : () => { t: T; x: number; } +} diff --git a/tests/baselines/reference/classExpressionWithResolutionOfNamespaceOfSameName01.errors.txt b/tests/baselines/reference/classExpressionWithResolutionOfNamespaceOfSameName01.errors.txt deleted file mode 100644 index 8edc1d8f74ba3..0000000000000 --- a/tests/baselines/reference/classExpressionWithResolutionOfNamespaceOfSameName01.errors.txt +++ /dev/null @@ -1,14 +0,0 @@ -tests/cases/compiler/classExpressionWithResolutionOfNamespaceOfSameName01.ts(6,15): error TS9003: 'class' expressions are not currently supported. - - -==== tests/cases/compiler/classExpressionWithResolutionOfNamespaceOfSameName01.ts (1 errors) ==== - namespace C { - export interface type { - } - } - - var x = class C { - ~ -!!! error TS9003: 'class' expressions are not currently supported. - prop: C.type; - } \ No newline at end of file diff --git a/tests/baselines/reference/classExpressionWithResolutionOfNamespaceOfSameName01.symbols b/tests/baselines/reference/classExpressionWithResolutionOfNamespaceOfSameName01.symbols new file mode 100644 index 0000000000000..fcd4f0388db3e --- /dev/null +++ b/tests/baselines/reference/classExpressionWithResolutionOfNamespaceOfSameName01.symbols @@ -0,0 +1,18 @@ +=== tests/cases/compiler/classExpressionWithResolutionOfNamespaceOfSameName01.ts === +namespace C { +>C : Symbol(C, Decl(classExpressionWithResolutionOfNamespaceOfSameName01.ts, 0, 0)) + + export interface type { +>type : Symbol(type, Decl(classExpressionWithResolutionOfNamespaceOfSameName01.ts, 0, 13)) + } +} + +var x = class C { +>x : Symbol(x, Decl(classExpressionWithResolutionOfNamespaceOfSameName01.ts, 5, 3)) +>C : Symbol(C, Decl(classExpressionWithResolutionOfNamespaceOfSameName01.ts, 5, 7)) + + prop: C.type; +>prop : Symbol(C.prop, Decl(classExpressionWithResolutionOfNamespaceOfSameName01.ts, 5, 17)) +>C : Symbol(C, Decl(classExpressionWithResolutionOfNamespaceOfSameName01.ts, 0, 0)) +>type : Symbol(C.type, Decl(classExpressionWithResolutionOfNamespaceOfSameName01.ts, 0, 13)) +} diff --git a/tests/baselines/reference/classExpressionWithResolutionOfNamespaceOfSameName01.types b/tests/baselines/reference/classExpressionWithResolutionOfNamespaceOfSameName01.types new file mode 100644 index 0000000000000..643cf65d2e0d1 --- /dev/null +++ b/tests/baselines/reference/classExpressionWithResolutionOfNamespaceOfSameName01.types @@ -0,0 +1,19 @@ +=== tests/cases/compiler/classExpressionWithResolutionOfNamespaceOfSameName01.ts === +namespace C { +>C : any + + export interface type { +>type : type + } +} + +var x = class C { +>x : typeof C +>class C { prop: C.type;} : typeof C +>C : typeof C + + prop: C.type; +>prop : C.type +>C : any +>type : C.type +} diff --git a/tests/baselines/reference/classExpressionWithStaticProperties1.errors.txt b/tests/baselines/reference/classExpressionWithStaticProperties1.errors.txt deleted file mode 100644 index 28e42dd33f1ea..0000000000000 --- a/tests/baselines/reference/classExpressionWithStaticProperties1.errors.txt +++ /dev/null @@ -1,7 +0,0 @@ -tests/cases/compiler/classExpressionWithStaticProperties1.ts(1,15): error TS9003: 'class' expressions are not currently supported. - - -==== tests/cases/compiler/classExpressionWithStaticProperties1.ts (1 errors) ==== - var v = class C { static a = 1; static b = 2 }; - ~ -!!! error TS9003: 'class' expressions are not currently supported. \ No newline at end of file diff --git a/tests/baselines/reference/classExpressionWithStaticProperties1.symbols b/tests/baselines/reference/classExpressionWithStaticProperties1.symbols new file mode 100644 index 0000000000000..d4c811daebec3 --- /dev/null +++ b/tests/baselines/reference/classExpressionWithStaticProperties1.symbols @@ -0,0 +1,7 @@ +=== tests/cases/compiler/classExpressionWithStaticProperties1.ts === +var v = class C { static a = 1; static b = 2 }; +>v : Symbol(v, Decl(classExpressionWithStaticProperties1.ts, 0, 3)) +>C : Symbol(C, Decl(classExpressionWithStaticProperties1.ts, 0, 7)) +>a : Symbol(C.a, Decl(classExpressionWithStaticProperties1.ts, 0, 17)) +>b : Symbol(C.b, Decl(classExpressionWithStaticProperties1.ts, 0, 31)) + diff --git a/tests/baselines/reference/classExpressionWithStaticProperties1.types b/tests/baselines/reference/classExpressionWithStaticProperties1.types new file mode 100644 index 0000000000000..b014f78abf712 --- /dev/null +++ b/tests/baselines/reference/classExpressionWithStaticProperties1.types @@ -0,0 +1,10 @@ +=== tests/cases/compiler/classExpressionWithStaticProperties1.ts === +var v = class C { static a = 1; static b = 2 }; +>v : typeof C +>class C { static a = 1; static b = 2 } : typeof C +>C : typeof C +>a : number +>1 : number +>b : number +>2 : number + diff --git a/tests/baselines/reference/classExpressionWithStaticProperties2.errors.txt b/tests/baselines/reference/classExpressionWithStaticProperties2.errors.txt deleted file mode 100644 index 9a915f7019350..0000000000000 --- a/tests/baselines/reference/classExpressionWithStaticProperties2.errors.txt +++ /dev/null @@ -1,7 +0,0 @@ -tests/cases/compiler/classExpressionWithStaticProperties2.ts(1,15): error TS9003: 'class' expressions are not currently supported. - - -==== tests/cases/compiler/classExpressionWithStaticProperties2.ts (1 errors) ==== - var v = class C { static a = 1; static b }; - ~ -!!! error TS9003: 'class' expressions are not currently supported. \ No newline at end of file diff --git a/tests/baselines/reference/classExpressionWithStaticProperties2.symbols b/tests/baselines/reference/classExpressionWithStaticProperties2.symbols new file mode 100644 index 0000000000000..480123a1c3bfb --- /dev/null +++ b/tests/baselines/reference/classExpressionWithStaticProperties2.symbols @@ -0,0 +1,7 @@ +=== tests/cases/compiler/classExpressionWithStaticProperties2.ts === +var v = class C { static a = 1; static b }; +>v : Symbol(v, Decl(classExpressionWithStaticProperties2.ts, 0, 3)) +>C : Symbol(C, Decl(classExpressionWithStaticProperties2.ts, 0, 7)) +>a : Symbol(C.a, Decl(classExpressionWithStaticProperties2.ts, 0, 17)) +>b : Symbol(C.b, Decl(classExpressionWithStaticProperties2.ts, 0, 31)) + diff --git a/tests/baselines/reference/classExpressionWithStaticProperties2.types b/tests/baselines/reference/classExpressionWithStaticProperties2.types new file mode 100644 index 0000000000000..9bfd6732350d2 --- /dev/null +++ b/tests/baselines/reference/classExpressionWithStaticProperties2.types @@ -0,0 +1,9 @@ +=== tests/cases/compiler/classExpressionWithStaticProperties2.ts === +var v = class C { static a = 1; static b }; +>v : typeof C +>class C { static a = 1; static b } : typeof C +>C : typeof C +>a : number +>1 : number +>b : any + diff --git a/tests/baselines/reference/classExpressionWithStaticPropertiesES61.errors.txt b/tests/baselines/reference/classExpressionWithStaticPropertiesES61.errors.txt deleted file mode 100644 index bc015a3d8f066..0000000000000 --- a/tests/baselines/reference/classExpressionWithStaticPropertiesES61.errors.txt +++ /dev/null @@ -1,7 +0,0 @@ -tests/cases/compiler/classExpressionWithStaticPropertiesES61.ts(1,15): error TS9003: 'class' expressions are not currently supported. - - -==== tests/cases/compiler/classExpressionWithStaticPropertiesES61.ts (1 errors) ==== - var v = class C { static a = 1; static b = 2 }; - ~ -!!! error TS9003: 'class' expressions are not currently supported. \ No newline at end of file diff --git a/tests/baselines/reference/classExpressionWithStaticPropertiesES61.symbols b/tests/baselines/reference/classExpressionWithStaticPropertiesES61.symbols new file mode 100644 index 0000000000000..c5f53e19bffb1 --- /dev/null +++ b/tests/baselines/reference/classExpressionWithStaticPropertiesES61.symbols @@ -0,0 +1,7 @@ +=== tests/cases/compiler/classExpressionWithStaticPropertiesES61.ts === +var v = class C { static a = 1; static b = 2 }; +>v : Symbol(v, Decl(classExpressionWithStaticPropertiesES61.ts, 0, 3)) +>C : Symbol(C, Decl(classExpressionWithStaticPropertiesES61.ts, 0, 7)) +>a : Symbol(C.a, Decl(classExpressionWithStaticPropertiesES61.ts, 0, 17)) +>b : Symbol(C.b, Decl(classExpressionWithStaticPropertiesES61.ts, 0, 31)) + diff --git a/tests/baselines/reference/classExpressionWithStaticPropertiesES61.types b/tests/baselines/reference/classExpressionWithStaticPropertiesES61.types new file mode 100644 index 0000000000000..02c385b7525df --- /dev/null +++ b/tests/baselines/reference/classExpressionWithStaticPropertiesES61.types @@ -0,0 +1,10 @@ +=== tests/cases/compiler/classExpressionWithStaticPropertiesES61.ts === +var v = class C { static a = 1; static b = 2 }; +>v : typeof C +>class C { static a = 1; static b = 2 } : typeof C +>C : typeof C +>a : number +>1 : number +>b : number +>2 : number + diff --git a/tests/baselines/reference/classExpressionWithStaticPropertiesES62.errors.txt b/tests/baselines/reference/classExpressionWithStaticPropertiesES62.errors.txt deleted file mode 100644 index bed4b2c01aa39..0000000000000 --- a/tests/baselines/reference/classExpressionWithStaticPropertiesES62.errors.txt +++ /dev/null @@ -1,7 +0,0 @@ -tests/cases/compiler/classExpressionWithStaticPropertiesES62.ts(1,15): error TS9003: 'class' expressions are not currently supported. - - -==== tests/cases/compiler/classExpressionWithStaticPropertiesES62.ts (1 errors) ==== - var v = class C { static a = 1; static b }; - ~ -!!! error TS9003: 'class' expressions are not currently supported. \ No newline at end of file diff --git a/tests/baselines/reference/classExpressionWithStaticPropertiesES62.symbols b/tests/baselines/reference/classExpressionWithStaticPropertiesES62.symbols new file mode 100644 index 0000000000000..be57a289f533b --- /dev/null +++ b/tests/baselines/reference/classExpressionWithStaticPropertiesES62.symbols @@ -0,0 +1,7 @@ +=== tests/cases/compiler/classExpressionWithStaticPropertiesES62.ts === +var v = class C { static a = 1; static b }; +>v : Symbol(v, Decl(classExpressionWithStaticPropertiesES62.ts, 0, 3)) +>C : Symbol(C, Decl(classExpressionWithStaticPropertiesES62.ts, 0, 7)) +>a : Symbol(C.a, Decl(classExpressionWithStaticPropertiesES62.ts, 0, 17)) +>b : Symbol(C.b, Decl(classExpressionWithStaticPropertiesES62.ts, 0, 31)) + diff --git a/tests/baselines/reference/classExpressionWithStaticPropertiesES62.types b/tests/baselines/reference/classExpressionWithStaticPropertiesES62.types new file mode 100644 index 0000000000000..e8ded1422f1e4 --- /dev/null +++ b/tests/baselines/reference/classExpressionWithStaticPropertiesES62.types @@ -0,0 +1,9 @@ +=== tests/cases/compiler/classExpressionWithStaticPropertiesES62.ts === +var v = class C { static a = 1; static b }; +>v : typeof C +>class C { static a = 1; static b } : typeof C +>C : typeof C +>a : number +>1 : number +>b : any + diff --git a/tests/baselines/reference/exportAssignNonIdentifier.errors.txt b/tests/baselines/reference/exportAssignNonIdentifier.errors.txt index 09e86ec12c477..c3d58c9b36fc8 100644 --- a/tests/baselines/reference/exportAssignNonIdentifier.errors.txt +++ b/tests/baselines/reference/exportAssignNonIdentifier.errors.txt @@ -1,5 +1,4 @@ tests/cases/conformance/externalModules/foo1.ts(2,1): error TS1148: Cannot compile modules unless the '--module' flag is provided. -tests/cases/conformance/externalModules/foo3.ts(1,16): error TS9003: 'class' expressions are not currently supported. tests/cases/conformance/externalModules/foo6.ts(1,14): error TS1109: Expression expected. @@ -12,10 +11,8 @@ tests/cases/conformance/externalModules/foo6.ts(1,14): error TS1109: Expression ==== tests/cases/conformance/externalModules/foo2.ts (0 errors) ==== export = "sausages"; // Ok -==== tests/cases/conformance/externalModules/foo3.ts (1 errors) ==== +==== tests/cases/conformance/externalModules/foo3.ts (0 errors) ==== export = class Foo3 {}; // Error, not an expression - ~~~~ -!!! error TS9003: 'class' expressions are not currently supported. ==== tests/cases/conformance/externalModules/foo4.ts (0 errors) ==== export = true; // Ok diff --git a/tests/baselines/reference/generatorTypeCheck55.errors.txt b/tests/baselines/reference/generatorTypeCheck55.errors.txt index 0846d1c28adaa..854c1801efddc 100644 --- a/tests/baselines/reference/generatorTypeCheck55.errors.txt +++ b/tests/baselines/reference/generatorTypeCheck55.errors.txt @@ -1,9 +1,12 @@ -tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck55.ts(2,19): error TS9003: 'class' expressions are not currently supported. +tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck55.ts(2,29): error TS2507: Type 'any' is not a constructor function type. +tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck55.ts(2,30): error TS1163: A 'yield' expression is only allowed in a generator body. -==== tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck55.ts (1 errors) ==== +==== tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck55.ts (2 errors) ==== function* g() { var x = class C extends (yield) {}; - ~ -!!! error TS9003: 'class' expressions are not currently supported. + ~~~~~~~ +!!! error TS2507: Type 'any' is not a constructor function type. + ~~~~~ +!!! error TS1163: A 'yield' expression is only allowed in a generator body. } \ No newline at end of file diff --git a/tests/baselines/reference/generatorTypeCheck56.errors.txt b/tests/baselines/reference/generatorTypeCheck56.errors.txt index 99e3b00de41f1..2096193580759 100644 --- a/tests/baselines/reference/generatorTypeCheck56.errors.txt +++ b/tests/baselines/reference/generatorTypeCheck56.errors.txt @@ -1,12 +1,9 @@ -tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck56.ts(2,19): error TS9003: 'class' expressions are not currently supported. tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck56.ts(3,11): error TS1163: A 'yield' expression is only allowed in a generator body. -==== tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck56.ts (2 errors) ==== +==== tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck56.ts (1 errors) ==== function* g() { var x = class C { - ~ -!!! error TS9003: 'class' expressions are not currently supported. *[yield 0]() { ~~~~~ !!! error TS1163: A 'yield' expression is only allowed in a generator body. diff --git a/tests/baselines/reference/strictModeReservedWord.errors.txt b/tests/baselines/reference/strictModeReservedWord.errors.txt index b6e9161ce7e14..6f6a387429d41 100644 --- a/tests/baselines/reference/strictModeReservedWord.errors.txt +++ b/tests/baselines/reference/strictModeReservedWord.errors.txt @@ -17,8 +17,8 @@ tests/cases/compiler/strictModeReservedWord.ts(13,11): error TS1212: Identifier tests/cases/compiler/strictModeReservedWord.ts(13,20): error TS1212: Identifier expected. 'public' is a reserved word in strict mode tests/cases/compiler/strictModeReservedWord.ts(13,28): error TS1212: Identifier expected. 'package' is a reserved word in strict mode tests/cases/compiler/strictModeReservedWord.ts(15,25): error TS1213: Identifier expected. 'package' is a reserved word in strict mode. Class definitions are automatically in strict mode. -tests/cases/compiler/strictModeReservedWord.ts(15,25): error TS9003: 'class' expressions are not currently supported. tests/cases/compiler/strictModeReservedWord.ts(15,41): error TS1213: Identifier expected. 'public' is a reserved word in strict mode. Class definitions are automatically in strict mode. +tests/cases/compiler/strictModeReservedWord.ts(15,41): error TS2507: Type 'number' is not a constructor function type. tests/cases/compiler/strictModeReservedWord.ts(17,9): error TS2300: Duplicate identifier 'b'. tests/cases/compiler/strictModeReservedWord.ts(17,12): error TS1212: Identifier expected. 'public' is a reserved word in strict mode tests/cases/compiler/strictModeReservedWord.ts(17,12): error TS2503: Cannot find namespace 'public'. @@ -95,10 +95,10 @@ tests/cases/compiler/strictModeReservedWord.ts(24,5): error TS2349: Cannot invok var myClass = class package extends public {} ~~~~~~~ !!! error TS1213: Identifier expected. 'package' is a reserved word in strict mode. Class definitions are automatically in strict mode. - ~~~~~~~ -!!! error TS9003: 'class' expressions are not currently supported. ~~~~~~ !!! error TS1213: Identifier expected. 'public' is a reserved word in strict mode. Class definitions are automatically in strict mode. + ~~~~~~ +!!! error TS2507: Type 'number' is not a constructor function type. var b: public.bar; ~ diff --git a/tests/baselines/reference/strictModeReservedWord.js b/tests/baselines/reference/strictModeReservedWord.js index 9be21b20ae626..bec159dee6f6b 100644 --- a/tests/baselines/reference/strictModeReservedWord.js +++ b/tests/baselines/reference/strictModeReservedWord.js @@ -28,6 +28,11 @@ function foo() { //// [strictModeReservedWord.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; var let = 10; function foo() { "use strict"; diff --git a/tests/cases/conformance/classes/classExpressions/classExpression3.ts b/tests/cases/conformance/classes/classExpressions/classExpression3.ts new file mode 100644 index 0000000000000..4267429f759ae --- /dev/null +++ b/tests/cases/conformance/classes/classExpressions/classExpression3.ts @@ -0,0 +1,5 @@ +let C = class extends class extends class { a = 1 } { b = 2 } { c = 3 }; +let c = new C(); +c.a; +c.b; +c.c; diff --git a/tests/cases/conformance/classes/classExpressions/classExpression4.ts b/tests/cases/conformance/classes/classExpressions/classExpression4.ts new file mode 100644 index 0000000000000..9365475fd877e --- /dev/null +++ b/tests/cases/conformance/classes/classExpressions/classExpression4.ts @@ -0,0 +1,6 @@ +let C = class { + foo() { + return new C(); + } +}; +let x = (new C).foo(); diff --git a/tests/cases/conformance/es6/classExpressions/classExpressionES63.ts b/tests/cases/conformance/es6/classExpressions/classExpressionES63.ts new file mode 100644 index 0000000000000..cbbe0927c3061 --- /dev/null +++ b/tests/cases/conformance/es6/classExpressions/classExpressionES63.ts @@ -0,0 +1,6 @@ +// @target: es6 +let C = class extends class extends class { a = 1 } { b = 2 } { c = 3 }; +let c = new C(); +c.a; +c.b; +c.c;