diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 1e8f8b403cc..4837b673132 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -265,6 +265,7 @@ namespace ts { return "export="; case SpecialPropertyAssignmentKind.ExportsProperty: case SpecialPropertyAssignmentKind.ThisProperty: + case SpecialPropertyAssignmentKind.Property: // exports.x = ... or this.y = ... return ((node as BinaryExpression).left as PropertyAccessExpression).name.text; case SpecialPropertyAssignmentKind.PrototypeProperty: @@ -1051,8 +1052,8 @@ namespace ts { // second -> edge that represents post-finally flow. // these edges are used in following scenario: // let a; (1) - // try { a = someOperation(); (2)} - // finally { (3) console.log(a) } (4) + // try { a = someOperation(); (2)} + // finally { (3) console.log(a) } (4) // (5) a // flow graph for this case looks roughly like this (arrows show ): @@ -1064,11 +1065,11 @@ namespace ts { // In case when we walk the flow starting from inside the finally block we want to take edge '*****' into account // since it ensures that finally is always reachable. However when we start outside the finally block and go through label (5) // then edge '*****' should be discarded because label 4 is only reachable if post-finally label-4 is reachable - // Simply speaking code inside finally block is treated as reachable as pre-try-flow + // Simply speaking code inside finally block is treated as reachable as pre-try-flow // since we conservatively assume that any line in try block can throw or return in which case we'll enter finally. // However code after finally is reachable only if control flow was not abrupted in try/catch or finally blocks - it should be composed from // final flows of these blocks without taking pre-try flow into account. - // + // // extra edges that we inject allows to control this behavior // if when walking the flow we step on post-finally edge - we can mark matching pre-finally edge as locked so it will be skipped. const preFinallyFlow: PreFinallyFlow = { flags: FlowFlags.PreFinally, antecedent: preTryFlow, lock: {} }; @@ -1969,6 +1970,9 @@ namespace ts { case SpecialPropertyAssignmentKind.ThisProperty: bindThisPropertyAssignment(node); break; + case SpecialPropertyAssignmentKind.Property: + bindStaticPropertyAssignment(node); + break; case SpecialPropertyAssignmentKind.None: // Nothing to do break; @@ -2265,18 +2269,41 @@ namespace ts { constructorFunction.parent = classPrototype; classPrototype.parent = leftSideOfAssignment; - const funcSymbol = container.locals.get(constructorFunction.text); - if (!funcSymbol || !(funcSymbol.flags & SymbolFlags.Function || isDeclarationOfFunctionExpression(funcSymbol))) { + bindPropertyAssignment(constructorFunction.text, leftSideOfAssignment, /*isPrototypeProperty*/ true); + } + + function bindStaticPropertyAssignment(node: BinaryExpression) { + // We saw a node of the form 'x.y = z'. Declare a 'member' y on x if x was a function. + + // Look up the function in the local scope, since prototype assignments should + // follow the function declaration + const leftSideOfAssignment = node.left as PropertyAccessExpression; + const target = leftSideOfAssignment.expression as Identifier; + + // Fix up parent pointers since we're going to use these nodes before we bind into them + leftSideOfAssignment.parent = node; + target.parent = leftSideOfAssignment; + + bindPropertyAssignment(target.text, leftSideOfAssignment, /*isPrototypeProperty*/ false); + } + + function bindPropertyAssignment(functionName: string, propertyAccessExpression: PropertyAccessExpression, isPrototypeProperty: boolean) { + let targetSymbol = container.locals.get(functionName); + if (targetSymbol && isDeclarationOfFunctionOrClassExpression(targetSymbol)) { + targetSymbol = (targetSymbol.valueDeclaration as VariableDeclaration).initializer.symbol; + } + + if (!targetSymbol || !(targetSymbol.flags & (SymbolFlags.Function | SymbolFlags.Class))) { return; } // Set up the members collection if it doesn't exist already - if (!funcSymbol.members) { - funcSymbol.members = createMap(); - } + const symbolTable = isPrototypeProperty ? + (targetSymbol.members || (targetSymbol.members = createMap())) : + (targetSymbol.exports || (targetSymbol.exports = createMap())); // Declare the method/property - declareSymbol(funcSymbol.members, funcSymbol, leftSideOfAssignment, SymbolFlags.Property, SymbolFlags.PropertyExcludes); + declareSymbol(symbolTable, targetSymbol, propertyAccessExpression, SymbolFlags.Property, SymbolFlags.PropertyExcludes); } function bindCallExpression(node: CallExpression) { diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b6d0fbdef33..8e084d91409 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -95,6 +95,8 @@ namespace ts { getSignaturesOfType, getIndexTypeOfType, getBaseTypes, + getBaseTypeOfLiteralType, + getWidenedType, getTypeFromTypeNode: node => { node = getParseTreeNode(node, isTypeNode); return node ? getTypeFromTypeNode(node) : unknownType; @@ -2247,13 +2249,15 @@ namespace ts { return type.flags & TypeFlags.StringLiteral ? `"${escapeString((type).text)}"` : (type).text; } - function getNameOfSymbol(symbol: Symbol): string { if (symbol.declarations && symbol.declarations.length) { const declaration = symbol.declarations[0]; if (declaration.name) { return declarationNameToString(declaration.name); } + if (declaration.parent && declaration.parent.kind === SyntaxKind.VariableDeclaration) { + return declarationNameToString((declaration.parent).name); + } switch (declaration.kind) { case SyntaxKind.ClassExpression: return "(Anonymous class)"; @@ -4755,7 +4759,7 @@ namespace ts { // Combinations of function, class, enum and module let members = emptySymbols; let constructSignatures: Signature[] = emptyArray; - if (symbol.flags & SymbolFlags.HasExports) { + if (symbol.exports) { members = getExportsOfSymbol(symbol); } if (symbol.flags & SymbolFlags.Class) { @@ -14640,10 +14644,13 @@ namespace ts { // in a JS file // Note:JS inferred classes might come from a variable declaration instead of a function declaration. // In this case, using getResolvedSymbol directly is required to avoid losing the members from the declaration. - const funcSymbol = node.expression.kind === SyntaxKind.Identifier ? + let funcSymbol = node.expression.kind === SyntaxKind.Identifier ? getResolvedSymbol(node.expression as Identifier) : checkExpression(node.expression).symbol; - if (funcSymbol && funcSymbol.members && (funcSymbol.flags & SymbolFlags.Function || isDeclarationOfFunctionExpression(funcSymbol))) { + if (funcSymbol && isDeclarationOfFunctionOrClassExpression(funcSymbol)) { + funcSymbol = getSymbolOfNode((funcSymbol.valueDeclaration).initializer); + } + if (funcSymbol && funcSymbol.members && funcSymbol.flags & SymbolFlags.Function) { return getInferredClassType(funcSymbol); } else if (compilerOptions.noImplicitAny) { @@ -20692,22 +20699,29 @@ namespace ts { return getLeftSideOfImportEqualsOrExportAssignment(node) !== undefined; } + function getSpecialPropertyAssignmentSymbolFromEntityName(entityName: EntityName | PropertyAccessExpression) { + const specialPropertyAssignmentKind = getSpecialPropertyAssignmentKind(entityName.parent.parent); + switch (specialPropertyAssignmentKind) { + case SpecialPropertyAssignmentKind.ExportsProperty: + case SpecialPropertyAssignmentKind.PrototypeProperty: + return getSymbolOfNode(entityName.parent); + case SpecialPropertyAssignmentKind.ThisProperty: + case SpecialPropertyAssignmentKind.ModuleExports: + case SpecialPropertyAssignmentKind.Property: + return getSymbolOfNode(entityName.parent.parent); + } + } + function getSymbolOfEntityNameOrPropertyAccessExpression(entityName: EntityName | PropertyAccessExpression): Symbol | undefined { if (isDeclarationName(entityName)) { return getSymbolOfNode(entityName.parent); } if (isInJavaScriptFile(entityName) && entityName.parent.kind === SyntaxKind.PropertyAccessExpression) { - const specialPropertyAssignmentKind = getSpecialPropertyAssignmentKind(entityName.parent.parent); - switch (specialPropertyAssignmentKind) { - case SpecialPropertyAssignmentKind.ExportsProperty: - case SpecialPropertyAssignmentKind.PrototypeProperty: - return getSymbolOfNode(entityName.parent); - case SpecialPropertyAssignmentKind.ThisProperty: - case SpecialPropertyAssignmentKind.ModuleExports: - return getSymbolOfNode(entityName.parent.parent); - default: - // Fall through if it is not a special property assignment + // Check if this is a special property assignment + const specialPropertyAssignmentSymbol = getSpecialPropertyAssignmentSymbolFromEntityName(entityName); + if (specialPropertyAssignmentSymbol) { + return specialPropertyAssignmentSymbol; } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 3be35036144..db4bf23d785 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3315,6 +3315,14 @@ "category": "Message", "code": 90015 }, + "Add declaration for missing property '{0}'": { + "category": "Message", + "code": 90016 + }, + "Add index signature for missing property '{0}'": { + "category": "Message", + "code": 90017 + }, "Octal literal types must use ES2015 syntax. Use the syntax '{0}'.": { "category": "Error", "code": 8017 diff --git a/src/compiler/types.ts b/src/compiler/types.ts index c87ed85504f..5058dc91486 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2402,6 +2402,8 @@ getSignaturesOfType(type: Type, kind: SignatureKind): Signature[]; getIndexTypeOfType(type: Type, kind: IndexKind): Type; getBaseTypes(type: InterfaceType): BaseType[]; + getBaseTypeOfLiteralType(type: Type): Type; + getWidenedType(type: Type): Type; getReturnTypeOfSignature(signature: Signature): Type; /** * Gets the type of a parameter at a given position in a signature. @@ -3194,7 +3196,9 @@ /// className.prototype.name = expr PrototypeProperty, /// this.name = expr - ThisProperty + ThisProperty, + // F.name = expr + Property } export interface JsFileExtensionInfo { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index d4ba916ab9a..dea334acdc7 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1417,10 +1417,10 @@ namespace ts { * Returns true if the node is a variable declaration whose initializer is a function expression. * This function does not test if the node is in a JavaScript file or not. */ - export function isDeclarationOfFunctionExpression(s: Symbol) { + export function isDeclarationOfFunctionOrClassExpression(s: Symbol) { if (s.valueDeclaration && s.valueDeclaration.kind === SyntaxKind.VariableDeclaration) { const declaration = s.valueDeclaration as VariableDeclaration; - return declaration.initializer && declaration.initializer.kind === SyntaxKind.FunctionExpression; + return declaration.initializer && (declaration.initializer.kind === SyntaxKind.FunctionExpression || declaration.initializer.kind === SyntaxKind.ClassExpression); } return false; } @@ -1449,6 +1449,10 @@ namespace ts { // module.exports = expr return SpecialPropertyAssignmentKind.ModuleExports; } + else { + // F.x = expr + return SpecialPropertyAssignmentKind.Property; + } } else if (lhs.expression.kind === SyntaxKind.ThisKeyword) { return SpecialPropertyAssignmentKind.ThisProperty; @@ -1468,6 +1472,7 @@ namespace ts { } } + return SpecialPropertyAssignmentKind.None; } diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 34aa9580d6d..49d1336c874 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -2122,7 +2122,7 @@ namespace FourSlash { * Because codefixes are only applied on the working file, it is unsafe * to apply this more than once (consider a refactoring across files). */ - public verifyRangeAfterCodeFix(expectedText: string, errorCode?: number, includeWhiteSpace?: boolean) { + public verifyRangeAfterCodeFix(expectedText: string, includeWhiteSpace?: boolean, errorCode?: number, index?: number) { const ranges = this.getRanges(); if (ranges.length !== 1) { this.raiseError("Exactly one range should be specified in the testfile."); @@ -2130,7 +2130,7 @@ namespace FourSlash { const fileName = this.activeFile.fileName; - this.applyCodeFixActions(fileName, this.getCodeFixActions(fileName, errorCode)); + this.applyCodeAction(fileName, this.getCodeFixActions(fileName, errorCode), index); const actualText = this.rangeText(ranges[0]); @@ -2155,7 +2155,7 @@ namespace FourSlash { public verifyFileAfterCodeFix(expectedContents: string, fileName?: string) { fileName = fileName ? fileName : this.activeFile.fileName; - this.applyCodeFixActions(fileName, this.getCodeFixActions(fileName)); + this.applyCodeAction(fileName, this.getCodeFixActions(fileName)); const actualContents: string = this.getFileContent(fileName); if (this.removeWhitespace(actualContents) !== this.removeWhitespace(expectedContents)) { @@ -2193,12 +2193,20 @@ namespace FourSlash { return actions; } - private applyCodeFixActions(fileName: string, actions: ts.CodeAction[]): void { - if (!(actions && actions.length === 1)) { - this.raiseError(`Should find exactly one codefix, but ${actions ? actions.length : "none"} found.`); + private applyCodeAction(fileName: string, actions: ts.CodeAction[], index?: number): void { + if (index === undefined) { + if (!(actions && actions.length === 1)) { + this.raiseError(`Should find exactly one codefix, but ${actions ? actions.length : "none"} found.`); + } + index = 0; + } + else { + if (!(actions && actions.length >= index + 1)) { + this.raiseError(`Should find at least ${index + 1} codefix(es), but ${actions ? actions.length : "none"} found.`); + } } - const fileChanges = ts.find(actions[0].changes, change => change.fileName === fileName); + const fileChanges = ts.find(actions[index].changes, change => change.fileName === fileName); if (!fileChanges) { this.raiseError("The CodeFix found doesn't provide any changes in this file."); } @@ -3535,8 +3543,8 @@ namespace FourSlashInterface { this.DocCommentTemplate(/*expectedText*/ undefined, /*expectedOffset*/ undefined, /*empty*/ true); } - public rangeAfterCodeFix(expectedText: string, errorCode?: number, includeWhiteSpace?: boolean): void { - this.state.verifyRangeAfterCodeFix(expectedText, errorCode, includeWhiteSpace); + public rangeAfterCodeFix(expectedText: string, includeWhiteSpace?: boolean, errorCode?: number, index?: number): void { + this.state.verifyRangeAfterCodeFix(expectedText, includeWhiteSpace, errorCode, index); } public importFixAtPosition(expectedTextArray: string[], errorCode?: number): void { diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts new file mode 100644 index 00000000000..6ae2ba3f51c --- /dev/null +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -0,0 +1,67 @@ +/* @internal */ +namespace ts.codefix { + registerCodeFix({ + errorCodes: [Diagnostics.Property_0_does_not_exist_on_type_1.code], + getCodeActions: getActionsForAddMissingMember + }); + + function getActionsForAddMissingMember(context: CodeFixContext): CodeAction[] | undefined { + + const sourceFile = context.sourceFile; + const start = context.span.start; + // This is the identifier of the missing property. eg: + // this.missing = 1; + // ^^^^^^^ + const token = getTokenAtPosition(sourceFile, start); + + if (token.kind != SyntaxKind.Identifier) { + return undefined; + } + + const classDeclaration = getContainingClass(token); + if (!classDeclaration) { + return undefined; + } + + if (!(token.parent && token.parent.kind === SyntaxKind.PropertyAccessExpression)) { + return undefined; + } + + if ((token.parent as PropertyAccessExpression).expression.kind !== SyntaxKind.ThisKeyword) { + return undefined; + } + + let typeString = "any"; + + if (token.parent.parent.kind === SyntaxKind.BinaryExpression) { + const binaryExpression = token.parent.parent as BinaryExpression; + + const checker = context.program.getTypeChecker(); + const widenedType = checker.getWidenedType(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(binaryExpression.right))); + typeString = checker.typeToString(widenedType); + } + + const startPos = classDeclaration.members.pos; + + return [{ + description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_declaration_for_missing_property_0), [token.getText()]), + changes: [{ + fileName: sourceFile.fileName, + textChanges: [{ + span: { start: startPos, length: 0 }, + newText: `${token.getFullText(sourceFile)}: ${typeString};` + }] + }] + }, + { + description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_index_signature_for_missing_property_0), [token.getText()]), + changes: [{ + fileName: sourceFile.fileName, + textChanges: [{ + span: { start: startPos, length: 0 }, + newText: `[name: string]: ${typeString};` + }] + }] + }]; + } +} \ No newline at end of file diff --git a/src/services/codefixes/fixes.ts b/src/services/codefixes/fixes.ts index 3bd173e04f6..76be34c67cd 100644 --- a/src/services/codefixes/fixes.ts +++ b/src/services/codefixes/fixes.ts @@ -1,4 +1,5 @@ /// +/// /// /// /// diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 7bee4f5a0ed..3eab994f84c 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -32,7 +32,7 @@ namespace ts.codefix { const declaration = declarations[0] as Declaration; const name = declaration.name ? declaration.name.getText() : undefined; - const visibility = getVisibilityPrefix(getModifierFlags(declaration)); + const visibility = getVisibilityPrefixWithSpace(getModifierFlags(declaration)); switch (declaration.kind) { case SyntaxKind.GetAccessor: @@ -58,7 +58,7 @@ namespace ts.codefix { if (declarations.length === 1) { Debug.assert(signatures.length === 1); const sigString = checker.signatureToString(signatures[0], enclosingDeclaration, TypeFormatFlags.SuppressAnyReturnType, SignatureKind.Call); - return `${visibility}${name}${sigString}${getMethodBodyStub(newlineChar)}`; + return getStubbedMethod(visibility, name, sigString, newlineChar); } let result = ""; @@ -78,7 +78,7 @@ namespace ts.codefix { bodySig = createBodySignatureWithAnyTypes(signatures, enclosingDeclaration, checker); } const sigString = checker.signatureToString(bodySig, enclosingDeclaration, TypeFormatFlags.SuppressAnyReturnType, SignatureKind.Call); - result += `${visibility}${name}${sigString}${getMethodBodyStub(newlineChar)}`; + result += getStubbedMethod(visibility, name, sigString, newlineChar); return result; default: @@ -138,11 +138,15 @@ namespace ts.codefix { } } - function getMethodBodyStub(newLineChar: string) { - return ` {${newLineChar}throw new Error('Method not implemented.');${newLineChar}}${newLineChar}`; + export function getStubbedMethod(visibility: string, name: string, sigString = "()", newlineChar: string): string { + return `${visibility}${name}${sigString}${getMethodBodyStub(newlineChar)}`; } - function getVisibilityPrefix(flags: ModifierFlags): string { + function getMethodBodyStub(newlineChar: string) { + return ` {${newlineChar}throw new Error('Method not implemented.');${newlineChar}}${newlineChar}`; + } + + function getVisibilityPrefixWithSpace(flags: ModifierFlags): string { if (flags & ModifierFlags.Public) { return "public "; } diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 111ea98417d..24d7d648272 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -154,7 +154,7 @@ namespace ts.FindAllReferences { const importDecl = importSpecifier.parent as ts.ImportDeclaration; Debug.assert(importDecl.moduleSpecifier === importSpecifier); const defaultName = importDecl.importClause.name; - const defaultReferencedSymbol = checker.getAliasedSymbol(checker.getSymbolAtLocation(defaultName)); + const defaultReferencedSymbol = defaultName && checker.getAliasedSymbol(checker.getSymbolAtLocation(defaultName)); if (symbol === defaultReferencedSymbol) { return defaultName.text; } diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index 9bebdb6932e..ae2150d981d 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -79,6 +79,7 @@ "formatting/smartIndenter.ts", "formatting/tokenRange.ts", "codeFixProvider.ts", + "codefixes/fixAddMissingMember.ts", "codefixes/fixExtendsInterfaceBecomesImplements.ts", "codefixes/fixClassIncorrectlyImplementsInterface.ts", "codefixes/fixClassDoesntImplementInheritedAbstractMember.ts", diff --git a/tests/baselines/reference/classExpression3.symbols b/tests/baselines/reference/classExpression3.symbols index bc1b263a000..fbd5f7b5331 100644 --- a/tests/baselines/reference/classExpression3.symbols +++ b/tests/baselines/reference/classExpression3.symbols @@ -3,7 +3,7 @@ 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)) +>c : Symbol(C.c, Decl(classExpression3.ts, 0, 63)) let c = new C(); >c : Symbol(c, Decl(classExpression3.ts, 1, 3)) @@ -20,7 +20,7 @@ c.b; >b : Symbol((Anonymous class).b, Decl(classExpression3.ts, 0, 53)) c.c; ->c.c : Symbol((Anonymous class).c, Decl(classExpression3.ts, 0, 63)) +>c.c : Symbol(C.c, Decl(classExpression3.ts, 0, 63)) >c : Symbol(c, Decl(classExpression3.ts, 1, 3)) ->c : Symbol((Anonymous class).c, Decl(classExpression3.ts, 0, 63)) +>c : Symbol(C.c, Decl(classExpression3.ts, 0, 63)) diff --git a/tests/baselines/reference/classExpression3.types b/tests/baselines/reference/classExpression3.types index 51798f300d4..713407fa8d4 100644 --- a/tests/baselines/reference/classExpression3.types +++ b/tests/baselines/reference/classExpression3.types @@ -1,7 +1,7 @@ === 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) +>C : typeof C +>class extends class extends class { a = 1 } { b = 2 } { c = 3 } : typeof C >class extends class { a = 1 } { b = 2 } : (Anonymous class) >class { a = 1 } : (Anonymous class) >a : number @@ -12,22 +12,22 @@ let C = class extends class extends class { a = 1 } { b = 2 } { c = 3 }; >3 : 3 let c = new C(); ->c : (Anonymous class) ->new C() : (Anonymous class) ->C : typeof (Anonymous class) +>c : C +>new C() : C +>C : typeof C c.a; >c.a : number ->c : (Anonymous class) +>c : C >a : number c.b; >c.b : number ->c : (Anonymous class) +>c : C >b : number c.c; >c.c : number ->c : (Anonymous class) +>c : C >c : number diff --git a/tests/baselines/reference/classExpression4.symbols b/tests/baselines/reference/classExpression4.symbols index 4df5302cecc..47a03bc4c96 100644 --- a/tests/baselines/reference/classExpression4.symbols +++ b/tests/baselines/reference/classExpression4.symbols @@ -3,7 +3,7 @@ let C = class { >C : Symbol(C, Decl(classExpression4.ts, 0, 3)) foo() { ->foo : Symbol((Anonymous class).foo, Decl(classExpression4.ts, 0, 15)) +>foo : Symbol(C.foo, Decl(classExpression4.ts, 0, 15)) return new C(); >C : Symbol(C, Decl(classExpression4.ts, 0, 3)) @@ -11,7 +11,7 @@ let C = class { }; 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)) +>(new C).foo : Symbol(C.foo, Decl(classExpression4.ts, 0, 15)) >C : Symbol(C, Decl(classExpression4.ts, 0, 3)) ->foo : Symbol((Anonymous class).foo, Decl(classExpression4.ts, 0, 15)) +>foo : Symbol(C.foo, Decl(classExpression4.ts, 0, 15)) diff --git a/tests/baselines/reference/classExpression4.types b/tests/baselines/reference/classExpression4.types index 066f169ae74..849a7459bbe 100644 --- a/tests/baselines/reference/classExpression4.types +++ b/tests/baselines/reference/classExpression4.types @@ -1,22 +1,22 @@ === tests/cases/conformance/classes/classExpressions/classExpression4.ts === let C = class { ->C : typeof (Anonymous class) ->class { foo() { return new C(); }} : typeof (Anonymous class) +>C : typeof C +>class { foo() { return new C(); }} : typeof C foo() { ->foo : () => (Anonymous class) +>foo : () => C return new C(); ->new C() : (Anonymous class) ->C : typeof (Anonymous class) +>new C() : C +>C : typeof C } }; 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) +>x : C +>(new C).foo() : C +>(new C).foo : () => C +>(new C) : C +>new C : C +>C : typeof C +>foo : () => C diff --git a/tests/baselines/reference/classExpressionES63.symbols b/tests/baselines/reference/classExpressionES63.symbols index 4e52d5ee9dd..f74b2893f73 100644 --- a/tests/baselines/reference/classExpressionES63.symbols +++ b/tests/baselines/reference/classExpressionES63.symbols @@ -3,7 +3,7 @@ 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)) +>c : Symbol(C.c, Decl(classExpressionES63.ts, 0, 63)) let c = new C(); >c : Symbol(c, Decl(classExpressionES63.ts, 1, 3)) @@ -20,7 +20,7 @@ c.b; >b : Symbol((Anonymous class).b, Decl(classExpressionES63.ts, 0, 53)) c.c; ->c.c : Symbol((Anonymous class).c, Decl(classExpressionES63.ts, 0, 63)) +>c.c : Symbol(C.c, Decl(classExpressionES63.ts, 0, 63)) >c : Symbol(c, Decl(classExpressionES63.ts, 1, 3)) ->c : Symbol((Anonymous class).c, Decl(classExpressionES63.ts, 0, 63)) +>c : Symbol(C.c, Decl(classExpressionES63.ts, 0, 63)) diff --git a/tests/baselines/reference/classExpressionES63.types b/tests/baselines/reference/classExpressionES63.types index c5c8de91c17..f597edab9db 100644 --- a/tests/baselines/reference/classExpressionES63.types +++ b/tests/baselines/reference/classExpressionES63.types @@ -1,7 +1,7 @@ === 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) +>C : typeof C +>class extends class extends class { a = 1 } { b = 2 } { c = 3 } : typeof C >class extends class { a = 1 } { b = 2 } : (Anonymous class) >class { a = 1 } : (Anonymous class) >a : number @@ -12,22 +12,22 @@ let C = class extends class extends class { a = 1 } { b = 2 } { c = 3 }; >3 : 3 let c = new C(); ->c : (Anonymous class) ->new C() : (Anonymous class) ->C : typeof (Anonymous class) +>c : C +>new C() : C +>C : typeof C c.a; >c.a : number ->c : (Anonymous class) +>c : C >a : number c.b; >c.b : number ->c : (Anonymous class) +>c : C >b : number c.c; >c.c : number ->c : (Anonymous class) +>c : C >c : number diff --git a/tests/baselines/reference/functionsInClassExpressions.symbols b/tests/baselines/reference/functionsInClassExpressions.symbols index a1da3a3175c..4aa62da8e33 100644 --- a/tests/baselines/reference/functionsInClassExpressions.symbols +++ b/tests/baselines/reference/functionsInClassExpressions.symbols @@ -4,24 +4,24 @@ let Foo = class { constructor() { this.bar++; ->this.bar : Symbol((Anonymous class).bar, Decl(functionsInClassExpressions.ts, 3, 5)) ->this : Symbol((Anonymous class), Decl(functionsInClassExpressions.ts, 0, 9)) ->bar : Symbol((Anonymous class).bar, Decl(functionsInClassExpressions.ts, 3, 5)) +>this.bar : Symbol(Foo.bar, Decl(functionsInClassExpressions.ts, 3, 5)) +>this : Symbol(Foo, Decl(functionsInClassExpressions.ts, 0, 9)) +>bar : Symbol(Foo.bar, Decl(functionsInClassExpressions.ts, 3, 5)) } bar = 0; ->bar : Symbol((Anonymous class).bar, Decl(functionsInClassExpressions.ts, 3, 5)) +>bar : Symbol(Foo.bar, Decl(functionsInClassExpressions.ts, 3, 5)) inc = () => { ->inc : Symbol((Anonymous class).inc, Decl(functionsInClassExpressions.ts, 4, 12)) +>inc : Symbol(Foo.inc, Decl(functionsInClassExpressions.ts, 4, 12)) this.bar++; ->this.bar : Symbol((Anonymous class).bar, Decl(functionsInClassExpressions.ts, 3, 5)) ->this : Symbol((Anonymous class), Decl(functionsInClassExpressions.ts, 0, 9)) ->bar : Symbol((Anonymous class).bar, Decl(functionsInClassExpressions.ts, 3, 5)) +>this.bar : Symbol(Foo.bar, Decl(functionsInClassExpressions.ts, 3, 5)) +>this : Symbol(Foo, Decl(functionsInClassExpressions.ts, 0, 9)) +>bar : Symbol(Foo.bar, Decl(functionsInClassExpressions.ts, 3, 5)) } m() { return this.bar; } ->m : Symbol((Anonymous class).m, Decl(functionsInClassExpressions.ts, 7, 5)) ->this.bar : Symbol((Anonymous class).bar, Decl(functionsInClassExpressions.ts, 3, 5)) ->this : Symbol((Anonymous class), Decl(functionsInClassExpressions.ts, 0, 9)) ->bar : Symbol((Anonymous class).bar, Decl(functionsInClassExpressions.ts, 3, 5)) +>m : Symbol(Foo.m, Decl(functionsInClassExpressions.ts, 7, 5)) +>this.bar : Symbol(Foo.bar, Decl(functionsInClassExpressions.ts, 3, 5)) +>this : Symbol(Foo, Decl(functionsInClassExpressions.ts, 0, 9)) +>bar : Symbol(Foo.bar, Decl(functionsInClassExpressions.ts, 3, 5)) } diff --git a/tests/baselines/reference/functionsInClassExpressions.types b/tests/baselines/reference/functionsInClassExpressions.types index b00f3df3490..7352f6e6b12 100644 --- a/tests/baselines/reference/functionsInClassExpressions.types +++ b/tests/baselines/reference/functionsInClassExpressions.types @@ -1,7 +1,7 @@ === tests/cases/compiler/functionsInClassExpressions.ts === let Foo = class { ->Foo : typeof (Anonymous class) ->class { constructor() { this.bar++; } bar = 0; inc = () => { this.bar++; } m() { return this.bar; }} : typeof (Anonymous class) +>Foo : typeof Foo +>class { constructor() { this.bar++; } bar = 0; inc = () => { this.bar++; } m() { return this.bar; }} : typeof Foo constructor() { this.bar++; diff --git a/tests/baselines/reference/implementsInClassExpression.symbols b/tests/baselines/reference/implementsInClassExpression.symbols index 48a44d91e9c..bf3b3ef9337 100644 --- a/tests/baselines/reference/implementsInClassExpression.symbols +++ b/tests/baselines/reference/implementsInClassExpression.symbols @@ -11,5 +11,5 @@ let cls = class implements Foo { >Foo : Symbol(Foo, Decl(implementsInClassExpression.ts, 0, 0)) doThing() { } ->doThing : Symbol((Anonymous class).doThing, Decl(implementsInClassExpression.ts, 4, 32)) +>doThing : Symbol(cls.doThing, Decl(implementsInClassExpression.ts, 4, 32)) } diff --git a/tests/baselines/reference/implementsInClassExpression.types b/tests/baselines/reference/implementsInClassExpression.types index d3647c30ff1..0734f8b8b78 100644 --- a/tests/baselines/reference/implementsInClassExpression.types +++ b/tests/baselines/reference/implementsInClassExpression.types @@ -7,8 +7,8 @@ interface Foo { } let cls = class implements Foo { ->cls : typeof (Anonymous class) ->class implements Foo { doThing() { }} : typeof (Anonymous class) +>cls : typeof cls +>class implements Foo { doThing() { }} : typeof cls >Foo : Foo doThing() { } diff --git a/tests/baselines/reference/multipleDeclarations.symbols b/tests/baselines/reference/multipleDeclarations.symbols index 9e49c2fc00c..4fc8f8a5f28 100644 --- a/tests/baselines/reference/multipleDeclarations.symbols +++ b/tests/baselines/reference/multipleDeclarations.symbols @@ -30,7 +30,7 @@ class X { >this : Symbol(X, Decl(input.js, 5, 1)) this.mistake = 'frankly, complete nonsense'; ->this.mistake : Symbol(X.mistake, Decl(input.js, 12, 5)) +>this.mistake : Symbol(X.mistake, Decl(input.js, 12, 5), Decl(input.js, 16, 16)) >this : Symbol(X, Decl(input.js, 5, 1)) >mistake : Symbol(X.mistake, Decl(input.js, 8, 35)) } @@ -38,7 +38,7 @@ class X { >m : Symbol(X.m, Decl(input.js, 10, 5)) } mistake() { ->mistake : Symbol(X.mistake, Decl(input.js, 12, 5)) +>mistake : Symbol(X.mistake, Decl(input.js, 12, 5), Decl(input.js, 16, 16)) } } let x = new X(); @@ -46,9 +46,11 @@ let x = new X(); >X : Symbol(X, Decl(input.js, 5, 1)) X.prototype.mistake = false; ->X.prototype.mistake : Symbol(X.mistake, Decl(input.js, 12, 5)) +>X.prototype.mistake : Symbol(X.mistake, Decl(input.js, 12, 5), Decl(input.js, 16, 16)) +>X.prototype : Symbol(X.mistake, Decl(input.js, 12, 5), Decl(input.js, 16, 16)) >X : Symbol(X, Decl(input.js, 5, 1)) >prototype : Symbol(X.prototype) +>mistake : Symbol(X.mistake, Decl(input.js, 12, 5), Decl(input.js, 16, 16)) x.m(); >x.m : Symbol(X.m, Decl(input.js, 10, 5)) @@ -56,15 +58,15 @@ x.m(); >m : Symbol(X.m, Decl(input.js, 10, 5)) x.mistake; ->x.mistake : Symbol(X.mistake, Decl(input.js, 12, 5)) +>x.mistake : Symbol(X.mistake, Decl(input.js, 12, 5), Decl(input.js, 16, 16)) >x : Symbol(x, Decl(input.js, 16, 3)) ->mistake : Symbol(X.mistake, Decl(input.js, 12, 5)) +>mistake : Symbol(X.mistake, Decl(input.js, 12, 5), Decl(input.js, 16, 16)) class Y { >Y : Symbol(Y, Decl(input.js, 19, 10)) mistake() { ->mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35)) +>mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35), Decl(input.js, 29, 1)) } m() { >m : Symbol(Y.m, Decl(input.js, 22, 5), Decl(input.js, 25, 19)) @@ -80,15 +82,17 @@ class Y { >this : Symbol(Y, Decl(input.js, 19, 10)) this.mistake = 'even more nonsense'; ->this.mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35)) +>this.mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35), Decl(input.js, 29, 1)) >this : Symbol(Y, Decl(input.js, 19, 10)) ->mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35)) +>mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35), Decl(input.js, 29, 1)) } } Y.prototype.mistake = true; ->Y.prototype.mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35)) +>Y.prototype.mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35), Decl(input.js, 29, 1)) +>Y.prototype : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35), Decl(input.js, 29, 1)) >Y : Symbol(Y, Decl(input.js, 19, 10)) >prototype : Symbol(Y.prototype) +>mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35), Decl(input.js, 29, 1)) let y = new Y(); >y : Symbol(y, Decl(input.js, 31, 3)) @@ -100,7 +104,7 @@ y.m(); >m : Symbol(Y.m, Decl(input.js, 22, 5), Decl(input.js, 25, 19)) y.mistake(); ->y.mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35)) +>y.mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35), Decl(input.js, 29, 1)) >y : Symbol(y, Decl(input.js, 31, 3)) ->mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35)) +>mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35), Decl(input.js, 29, 1)) diff --git a/tests/baselines/reference/multipleDeclarations.types b/tests/baselines/reference/multipleDeclarations.types index 195bdc2ad0d..b82cdbe05ed 100644 --- a/tests/baselines/reference/multipleDeclarations.types +++ b/tests/baselines/reference/multipleDeclarations.types @@ -43,16 +43,16 @@ class X { this.mistake = 'frankly, complete nonsense'; >this.mistake = 'frankly, complete nonsense' : "frankly, complete nonsense" ->this.mistake : () => void +>this.mistake : any >this : this ->mistake : () => void +>mistake : any >'frankly, complete nonsense' : "frankly, complete nonsense" } m() { >m : () => void } mistake() { ->mistake : () => void +>mistake : any } } let x = new X(); @@ -62,11 +62,11 @@ let x = new X(); X.prototype.mistake = false; >X.prototype.mistake = false : false ->X.prototype.mistake : () => void +>X.prototype.mistake : any >X.prototype : X >X : typeof X >prototype : X ->mistake : () => void +>mistake : any >false : false x.m(); @@ -76,9 +76,9 @@ x.m(); >m : () => void x.mistake; ->x.mistake : () => void +>x.mistake : any >x : X ->mistake : () => void +>mistake : any class Y { >Y : Y diff --git a/tests/baselines/reference/staticPropertyNameConflicts.errors.txt b/tests/baselines/reference/staticPropertyNameConflicts.errors.txt index 4c051ace0ac..1b22bbbf759 100644 --- a/tests/baselines/reference/staticPropertyNameConflicts.errors.txt +++ b/tests/baselines/reference/staticPropertyNameConflicts.errors.txt @@ -9,17 +9,17 @@ tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameCon tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(41,12): error TS2699: Static property 'caller' conflicts with built-in property 'Function.caller' of constructor function 'StaticCallerFn'. tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(47,12): error TS2699: Static property 'arguments' conflicts with built-in property 'Function.arguments' of constructor function 'StaticArguments'. tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(52,12): error TS2699: Static property 'arguments' conflicts with built-in property 'Function.arguments' of constructor function 'StaticArgumentsFn'. -tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(62,12): error TS2699: Static property 'name' conflicts with built-in property 'Function.name' of constructor function '(Anonymous class)'. -tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(67,12): error TS2699: Static property 'name' conflicts with built-in property 'Function.name' of constructor function '(Anonymous class)'. -tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(73,12): error TS2699: Static property 'length' conflicts with built-in property 'Function.length' of constructor function '(Anonymous class)'. -tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(78,12): error TS2699: Static property 'length' conflicts with built-in property 'Function.length' of constructor function '(Anonymous class)'. -tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(84,12): error TS2699: Static property 'prototype' conflicts with built-in property 'Function.prototype' of constructor function '(Anonymous class)'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(62,12): error TS2699: Static property 'name' conflicts with built-in property 'Function.name' of constructor function 'StaticName_Anonymous'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(67,12): error TS2699: Static property 'name' conflicts with built-in property 'Function.name' of constructor function 'StaticNameFn_Anonymous'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(73,12): error TS2699: Static property 'length' conflicts with built-in property 'Function.length' of constructor function 'StaticLength_Anonymous'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(78,12): error TS2699: Static property 'length' conflicts with built-in property 'Function.length' of constructor function 'StaticLengthFn_Anonymous'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(84,12): error TS2699: Static property 'prototype' conflicts with built-in property 'Function.prototype' of constructor function 'StaticPrototype_Anonymous'. tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(89,12): error TS2300: Duplicate identifier 'prototype'. -tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(89,12): error TS2699: Static property 'prototype' conflicts with built-in property 'Function.prototype' of constructor function '(Anonymous class)'. -tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(95,12): error TS2699: Static property 'caller' conflicts with built-in property 'Function.caller' of constructor function '(Anonymous class)'. -tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(100,12): error TS2699: Static property 'caller' conflicts with built-in property 'Function.caller' of constructor function '(Anonymous class)'. -tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(106,12): error TS2699: Static property 'arguments' conflicts with built-in property 'Function.arguments' of constructor function '(Anonymous class)'. -tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(111,12): error TS2699: Static property 'arguments' conflicts with built-in property 'Function.arguments' of constructor function '(Anonymous class)'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(89,12): error TS2699: Static property 'prototype' conflicts with built-in property 'Function.prototype' of constructor function 'StaticPrototypeFn_Anonymous'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(95,12): error TS2699: Static property 'caller' conflicts with built-in property 'Function.caller' of constructor function 'StaticCaller_Anonymous'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(100,12): error TS2699: Static property 'caller' conflicts with built-in property 'Function.caller' of constructor function 'StaticCallerFn_Anonymous'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(106,12): error TS2699: Static property 'arguments' conflicts with built-in property 'Function.arguments' of constructor function 'StaticArguments_Anonymous'. +tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(111,12): error TS2699: Static property 'arguments' conflicts with built-in property 'Function.arguments' of constructor function 'StaticArgumentsFn_Anonymous'. tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(121,16): error TS2699: Static property 'name' conflicts with built-in property 'Function.name' of constructor function 'StaticName'. tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(128,16): error TS2699: Static property 'name' conflicts with built-in property 'Function.name' of constructor function 'StaticNameFn'. tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflicts.ts(136,16): error TS2699: Static property 'length' conflicts with built-in property 'Function.length' of constructor function 'StaticLength'. @@ -119,14 +119,14 @@ tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameCon var StaticName_Anonymous = class { static name: number; // error ~~~~ -!!! error TS2699: Static property 'name' conflicts with built-in property 'Function.name' of constructor function '(Anonymous class)'. +!!! error TS2699: Static property 'name' conflicts with built-in property 'Function.name' of constructor function 'StaticName_Anonymous'. name: string; // ok } var StaticNameFn_Anonymous = class { static name() {} // error ~~~~ -!!! error TS2699: Static property 'name' conflicts with built-in property 'Function.name' of constructor function '(Anonymous class)'. +!!! error TS2699: Static property 'name' conflicts with built-in property 'Function.name' of constructor function 'StaticNameFn_Anonymous'. name() {} // ok } @@ -134,14 +134,14 @@ tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameCon var StaticLength_Anonymous = class { static length: number; // error ~~~~~~ -!!! error TS2699: Static property 'length' conflicts with built-in property 'Function.length' of constructor function '(Anonymous class)'. +!!! error TS2699: Static property 'length' conflicts with built-in property 'Function.length' of constructor function 'StaticLength_Anonymous'. length: string; // ok } var StaticLengthFn_Anonymous = class { static length() {} // error ~~~~~~ -!!! error TS2699: Static property 'length' conflicts with built-in property 'Function.length' of constructor function '(Anonymous class)'. +!!! error TS2699: Static property 'length' conflicts with built-in property 'Function.length' of constructor function 'StaticLengthFn_Anonymous'. length() {} // ok } @@ -149,7 +149,7 @@ tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameCon var StaticPrototype_Anonymous = class { static prototype: number; // error ~~~~~~~~~ -!!! error TS2699: Static property 'prototype' conflicts with built-in property 'Function.prototype' of constructor function '(Anonymous class)'. +!!! error TS2699: Static property 'prototype' conflicts with built-in property 'Function.prototype' of constructor function 'StaticPrototype_Anonymous'. prototype: string; // ok } @@ -158,7 +158,7 @@ tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameCon ~~~~~~~~~ !!! error TS2300: Duplicate identifier 'prototype'. ~~~~~~~~~ -!!! error TS2699: Static property 'prototype' conflicts with built-in property 'Function.prototype' of constructor function '(Anonymous class)'. +!!! error TS2699: Static property 'prototype' conflicts with built-in property 'Function.prototype' of constructor function 'StaticPrototypeFn_Anonymous'. prototype() {} // ok } @@ -166,14 +166,14 @@ tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameCon var StaticCaller_Anonymous = class { static caller: number; // error ~~~~~~ -!!! error TS2699: Static property 'caller' conflicts with built-in property 'Function.caller' of constructor function '(Anonymous class)'. +!!! error TS2699: Static property 'caller' conflicts with built-in property 'Function.caller' of constructor function 'StaticCaller_Anonymous'. caller: string; // ok } var StaticCallerFn_Anonymous = class { static caller() {} // error ~~~~~~ -!!! error TS2699: Static property 'caller' conflicts with built-in property 'Function.caller' of constructor function '(Anonymous class)'. +!!! error TS2699: Static property 'caller' conflicts with built-in property 'Function.caller' of constructor function 'StaticCallerFn_Anonymous'. caller() {} // ok } @@ -181,14 +181,14 @@ tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameCon var StaticArguments_Anonymous = class { static arguments: number; // error ~~~~~~~~~ -!!! error TS2699: Static property 'arguments' conflicts with built-in property 'Function.arguments' of constructor function '(Anonymous class)'. +!!! error TS2699: Static property 'arguments' conflicts with built-in property 'Function.arguments' of constructor function 'StaticArguments_Anonymous'. arguments: string; // ok } var StaticArgumentsFn_Anonymous = class { static arguments() {} // error ~~~~~~~~~ -!!! error TS2699: Static property 'arguments' conflicts with built-in property 'Function.arguments' of constructor function '(Anonymous class)'. +!!! error TS2699: Static property 'arguments' conflicts with built-in property 'Function.arguments' of constructor function 'StaticArgumentsFn_Anonymous'. arguments() {} // ok } diff --git a/tests/baselines/reference/transformsElideNullUndefinedType.types b/tests/baselines/reference/transformsElideNullUndefinedType.types index 7f48d8a00e9..ffc26ddaa60 100644 --- a/tests/baselines/reference/transformsElideNullUndefinedType.types +++ b/tests/baselines/reference/transformsElideNullUndefinedType.types @@ -140,14 +140,14 @@ class C5 { } var C6 = class { constructor(p12: null) { } } ->C6 : typeof (Anonymous class) ->class { constructor(p12: null) { } } : typeof (Anonymous class) +>C6 : typeof C6 +>class { constructor(p12: null) { } } : typeof C6 >p12 : null >null : null var C7 = class { constructor(p13: undefined) { } } ->C7 : typeof (Anonymous class) ->class { constructor(p13: undefined) { } } : typeof (Anonymous class) +>C7 : typeof C7 +>class { constructor(p13: undefined) { } } : typeof C7 >p13 : undefined declare function fn(); diff --git a/tests/cases/fourslash/codeFixUndeclaredClassInstance.ts b/tests/cases/fourslash/codeFixUndeclaredClassInstance.ts new file mode 100644 index 00000000000..024ec144092 --- /dev/null +++ b/tests/cases/fourslash/codeFixUndeclaredClassInstance.ts @@ -0,0 +1,22 @@ +/// + +//// class A { +//// a: number; +//// b: string; +//// constructor(public x: any) {} +//// } +//// [|class B { +//// constructor() { +//// this.x = new A(3); +//// } +//// }|] + +verify.rangeAfterCodeFix(` +class B { + x: A; + + constructor() { + this.x = new A(3); + } +} +`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixUndeclaredClassInstanceWithTypeParams.ts b/tests/cases/fourslash/codeFixUndeclaredClassInstanceWithTypeParams.ts new file mode 100644 index 00000000000..34e359feea8 --- /dev/null +++ b/tests/cases/fourslash/codeFixUndeclaredClassInstanceWithTypeParams.ts @@ -0,0 +1,22 @@ +/// + +//// class A { +//// a: number; +//// b: string; +//// constructor(public x: T) {} +//// } +//// [|class B { +//// constructor() { +//// this.x = new A(3); +//// } +//// }|] + +verify.rangeAfterCodeFix(` +class B { + x: A; + + constructor() { + this.x = new A(3); + } +} +`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixUndeclaredIndexSignatureNumericLiteral.ts b/tests/cases/fourslash/codeFixUndeclaredIndexSignatureNumericLiteral.ts new file mode 100644 index 00000000000..2e49a8184eb --- /dev/null +++ b/tests/cases/fourslash/codeFixUndeclaredIndexSignatureNumericLiteral.ts @@ -0,0 +1,17 @@ +/// + +//// [|class A { +//// constructor() { +//// this.x = 10; +//// } +//// }|] + +verify.rangeAfterCodeFix(` +class A { + [name: string]: number; + + constructor() { + this.x = 10; + } +} +`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 1); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixUndeclaredPropertyFunctionEmptyClass.ts b/tests/cases/fourslash/codeFixUndeclaredPropertyFunctionEmptyClass.ts new file mode 100644 index 00000000000..6f0a5de3557 --- /dev/null +++ b/tests/cases/fourslash/codeFixUndeclaredPropertyFunctionEmptyClass.ts @@ -0,0 +1,20 @@ +/// + +//// [|class A { +//// constructor() { +//// this.x = function(x: number, y?: A){ +//// return x > 0 ? x : y; +//// } +//// } +//// }|] + +verify.rangeAfterCodeFix(` +class A { + x: (x: number, y?: A) => A; + constructor() { + this.x = function(x: number, y?: A){ + return x > 0 ? x : y; + } + } +} +`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); diff --git a/tests/cases/fourslash/codeFixUndeclaredPropertyFunctionNonEmptyClass.ts b/tests/cases/fourslash/codeFixUndeclaredPropertyFunctionNonEmptyClass.ts new file mode 100644 index 00000000000..b05fb0d42b5 --- /dev/null +++ b/tests/cases/fourslash/codeFixUndeclaredPropertyFunctionNonEmptyClass.ts @@ -0,0 +1,22 @@ +/// + +//// [|class A { +//// y: number; +//// constructor(public a: number) { +//// this.x = function(x: number, y?: A){ +//// return x > 0 ? x : y; +//// } +//// } +//// }|] + +verify.rangeAfterCodeFix(` +class A { + x: (x: number, y?: A) => number | A; + y: number; + constructor(public a: number) { + this.x = function(x: number, y?: A){ + return x > 0 ? x : y; + } + } +} +`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); diff --git a/tests/cases/fourslash/codeFixUndeclaredPropertyNumericLiteral.ts b/tests/cases/fourslash/codeFixUndeclaredPropertyNumericLiteral.ts new file mode 100644 index 00000000000..eaae355904b --- /dev/null +++ b/tests/cases/fourslash/codeFixUndeclaredPropertyNumericLiteral.ts @@ -0,0 +1,17 @@ +/// + +//// [|class A { +//// constructor() { +//// this.x = 10; +//// } +//// }|] + +verify.rangeAfterCodeFix(` +class A { + x: number; + + constructor() { + this.x = 10; + } +} +`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixUndeclaredPropertyObjectLiteral.ts b/tests/cases/fourslash/codeFixUndeclaredPropertyObjectLiteral.ts new file mode 100644 index 00000000000..a2647c5a21e --- /dev/null +++ b/tests/cases/fourslash/codeFixUndeclaredPropertyObjectLiteral.ts @@ -0,0 +1,19 @@ +/// + +//// [|class A { +//// constructor() { +//// let e: any = 10; +//// this.x = { a: 10, b: "hello", c: undefined, d: null, e: e }; +//// } +//// }|] + +verify.rangeAfterCodeFix(` +class A { + x: { a: number; b: string; c: any; d: any; e: any; }; + + constructor() { + let e: any = 10; + this.x = { a: 10, b: "hello", c: undefined, d: null, e: e }; + } +} +`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); diff --git a/tests/cases/fourslash/codeFixUndeclaredPropertyObjectLiteralStrictNullChecks.ts b/tests/cases/fourslash/codeFixUndeclaredPropertyObjectLiteralStrictNullChecks.ts new file mode 100644 index 00000000000..0b0ab8cdd59 --- /dev/null +++ b/tests/cases/fourslash/codeFixUndeclaredPropertyObjectLiteralStrictNullChecks.ts @@ -0,0 +1,21 @@ +/// + +// @strictNullChecks: true + +//// [|class A { +//// constructor() { +//// let e: any = 10; +//// this.x = { a: 10, b: "hello", c: undefined, d: null, e: e }; +//// } +//// }|] + +verify.rangeAfterCodeFix(` +class A { + x: { a: number; b: string; c: undefined; d: null; e: any; }; + + constructor() { + let e: any = 10; + this.x = { a: 10, b: "hello", c: undefined, d: null, e: e }; + } +} +`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixUndeclaredPropertyThisType.ts b/tests/cases/fourslash/codeFixUndeclaredPropertyThisType.ts new file mode 100644 index 00000000000..56f9b34d809 --- /dev/null +++ b/tests/cases/fourslash/codeFixUndeclaredPropertyThisType.ts @@ -0,0 +1,17 @@ +/// + +//// [|class A { +//// constructor() { +//// this.mythis = this; +//// } +//// }|] + +verify.rangeAfterCodeFix(` +class A { + mythis: this; + + constructor() { + this.mythis = this; + } +} +`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); diff --git a/tests/cases/fourslash/findAllRefsForDefaultExport.ts b/tests/cases/fourslash/findAllRefsForDefaultExport.ts index c518bb8f59e..98e74e281ad 100644 --- a/tests/cases/fourslash/findAllRefsForDefaultExport.ts +++ b/tests/cases/fourslash/findAllRefsForDefaultExport.ts @@ -7,5 +7,8 @@ ////import [|{| "isWriteAccess": true, "isDefinition": true |}g|] from "./a"; /////*ref*/[|g|](); +// @Filename: c.ts +////import { f } from "./a"; + verify.singleReferenceGroup("function f(): void"); verify.goToDefinition("ref", "def"); diff --git a/tests/cases/fourslash/findAllRefsForVariableInExtendsClause01.ts b/tests/cases/fourslash/findAllRefsForVariableInExtendsClause01.ts index d40cb009f1e..a61f925c97e 100644 --- a/tests/cases/fourslash/findAllRefsForVariableInExtendsClause01.ts +++ b/tests/cases/fourslash/findAllRefsForVariableInExtendsClause01.ts @@ -3,4 +3,4 @@ ////var [|{| "isWriteAccess": true, "isDefinition": true |}Base|] = class { }; ////class C extends [|Base|] { } -verify.singleReferenceGroup("var Base: typeof (Anonymous class)"); +verify.singleReferenceGroup("var Base: typeof Base"); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 661d7cba6a4..34afb71ec85 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -225,7 +225,7 @@ declare namespace FourSlashInterface { noMatchingBracePositionInCurrentFile(bracePosition: number): void; DocCommentTemplate(expectedText: string, expectedOffset: number, empty?: boolean): void; noDocCommentTemplate(): void; - rangeAfterCodeFix(expectedText: string, errorCode?: number, includeWhiteSpace?: boolean): void; + rangeAfterCodeFix(expectedText: string, includeWhiteSpace?: boolean, errorCode?: number, index?: number): void; importFixAtPosition(expectedTextArray: string[], errorCode?: number): void; navigationBar(json: any): void; diff --git a/tests/cases/fourslash/getJavaScriptCompletions20.ts b/tests/cases/fourslash/getJavaScriptCompletions20.ts index 3ca27fa288a..ec2bcef161b 100644 --- a/tests/cases/fourslash/getJavaScriptCompletions20.ts +++ b/tests/cases/fourslash/getJavaScriptCompletions20.ts @@ -18,4 +18,4 @@ //// Person.getNa/**/ = 10; goTo.marker(); -verify.not.completionListContains('getNa'); +verify.completionListContains('getName'); diff --git a/tests/cases/fourslash/renameJsPropertyAssignment.ts b/tests/cases/fourslash/renameJsPropertyAssignment.ts new file mode 100644 index 00000000000..fd1ba47569d --- /dev/null +++ b/tests/cases/fourslash/renameJsPropertyAssignment.ts @@ -0,0 +1,11 @@ +/// + +// @allowJs: true +// @Filename: a.js +////function bar() { +////} +////bar.[|foo|] = "foo"; +////console.log(bar./**/[|foo|]); + +goTo.marker(); +verify.renameLocations( /*findInStrings*/ false, /*findInComments*/ false); \ No newline at end of file diff --git a/tests/cases/fourslash/renameJsPropertyAssignment2.ts b/tests/cases/fourslash/renameJsPropertyAssignment2.ts new file mode 100644 index 00000000000..39831d4ae1b --- /dev/null +++ b/tests/cases/fourslash/renameJsPropertyAssignment2.ts @@ -0,0 +1,11 @@ +/// + +// @allowJs: true +// @Filename: a.js +////class Minimatch { +////} +////Minimatch.[|staticProperty|] = "string"; +////console.log(Minimatch./**/[|staticProperty|]); + +goTo.marker(); +verify.renameLocations( /*findInStrings*/ false, /*findInComments*/ false); \ No newline at end of file diff --git a/tests/cases/fourslash/renameJsPropertyAssignment3.ts b/tests/cases/fourslash/renameJsPropertyAssignment3.ts new file mode 100644 index 00000000000..5871010d6f4 --- /dev/null +++ b/tests/cases/fourslash/renameJsPropertyAssignment3.ts @@ -0,0 +1,11 @@ +/// + +// @allowJs: true +// @Filename: a.js +////var C = class { +////} +////C.[|staticProperty|] = "string"; +////console.log(C./**/[|staticProperty|]); + +goTo.marker(); +verify.renameLocations( /*findInStrings*/ false, /*findInComments*/ false); \ No newline at end of file diff --git a/tests/cases/fourslash/renameJsThisProperty05.ts b/tests/cases/fourslash/renameJsThisProperty05.ts new file mode 100644 index 00000000000..c1408d6aff1 --- /dev/null +++ b/tests/cases/fourslash/renameJsThisProperty05.ts @@ -0,0 +1,15 @@ +/// + +// @allowJs: true +// @Filename: a.js +////class C { +//// constructor(y) { +//// this.x = y; +//// } +////} +////C.prototype.[|z|] = 1; +////var t = new C(12); +////t./**/[|z|] = 11; + +goTo.marker(); +verify.renameLocations( /*findInStrings*/ false, /*findInComments*/ false); diff --git a/tests/cases/fourslash/renameJsThisProperty06.ts b/tests/cases/fourslash/renameJsThisProperty06.ts new file mode 100644 index 00000000000..63a16b68a4f --- /dev/null +++ b/tests/cases/fourslash/renameJsThisProperty06.ts @@ -0,0 +1,15 @@ +/// + +// @allowJs: true +// @Filename: a.js +////var C = class { +//// constructor(y) { +//// this.x = y; +//// } +////} +////C.prototype.[|z|] = 1; +////var t = new C(12); +////t./**/[|z|] = 11; + +goTo.marker(); +verify.renameLocations( /*findInStrings*/ false, /*findInComments*/ false); diff --git a/tests/cases/fourslash/unusedImports2FS.ts b/tests/cases/fourslash/unusedImports2FS.ts index 53875693362..8865dea56a6 100644 --- a/tests/cases/fourslash/unusedImports2FS.ts +++ b/tests/cases/fourslash/unusedImports2FS.ts @@ -16,4 +16,4 @@ //// //// } -verify.rangeAfterCodeFix(`import {Calculator} from "./file1"`, /*errorCode*/ undefined, /*includeWhiteSpace*/ true); +verify.rangeAfterCodeFix(`import {Calculator} from "./file1"`, /*includeWhiteSpace*/ true, /*errorCode*/ undefined); diff --git a/tests/cases/fourslash/unusedLocalsInFunction3.ts b/tests/cases/fourslash/unusedLocalsInFunction3.ts index 7aa9b20a33c..0164873acd8 100644 --- a/tests/cases/fourslash/unusedLocalsInFunction3.ts +++ b/tests/cases/fourslash/unusedLocalsInFunction3.ts @@ -7,4 +7,4 @@ //// z+1; ////} -verify.rangeAfterCodeFix("var x,z = 1;", 6133); +verify.rangeAfterCodeFix("var x,z = 1;", /*includeWhiteSpace*/ undefined, 6133);