diff --git a/Jakefile.js b/Jakefile.js index 174be5e702f52..3c4dfbb55a9cf 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -96,7 +96,13 @@ var servicesSources = [ "formatting/rulesMap.ts", "formatting/rulesProvider.ts", "formatting/smartIndenter.ts", - "formatting/tokenRange.ts" + "formatting/tokenRange.ts", + "codeFixes/changeExtendsToImplementsFix.ts", + "codeFixes/codeFixProvider.ts", + "codeFixes/interfaceFixes.ts", + "codeFixes/references.ts", + "codeFixes/superFixes.ts", + "codeFixes/unusedIdentifierFixes.ts" ].map(function (f) { return path.join(servicesDirectory, f); })); diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 6c87ad82955c3..b07c21fa4cb6d 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -115,6 +115,15 @@ namespace ts { return -1; } + export function firstOrUndefined(array: T[], predicate: (x: T) => boolean): T { + for (let i = 0, len = array.length; i < len; i++) { + if (predicate(array[i])) { + return array[i]; + } + } + return undefined; + } + export function indexOfAnyCharCode(text: string, charCodes: number[], start?: number): number { for (let i = start || 0, len = text.length; i < len; i++) { if (contains(charCodes, text.charCodeAt(i))) { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 8126d5c605ea7..1dffc35c74c17 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3031,5 +3031,33 @@ "Unknown typing option '{0}'.": { "category": "Error", "code": 17010 + }, + "Add missing 'super()' call.": { + "category": "CodeFix", + "code": 90001 + }, + "Make 'super()' call the first statement in the constructor.": { + "category": "CodeFix", + "code": 90002 + }, + "Change 'extends' to 'implements'": { + "category": "CodeFix", + "code": 90003 + }, + "Remove unused identifiers": { + "category": "CodeFix", + "code": 90004 + }, + "Implement interface on reference": { + "category": "CodeFix", + "code": 90005 + }, + "Implement interface on class": { + "category": "CodeFix", + "code": 90006 + }, + "Implement inherited abstract class": { + "category": "CodeFix", + "code": 90007 } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 28ededebb0de1..e31a4b0ace188 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2547,6 +2547,7 @@ namespace ts { Warning, Error, Message, + CodeFix, } export enum ModuleResolutionKind { diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index a42abbbc60909..91597d7f5931e 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -384,7 +384,7 @@ namespace FourSlash { if (exists !== negative) { this.printErrorLog(negative, this.getAllDiagnostics()); - throw new Error("Failure between markers: " + startMarkerName + ", " + endMarkerName); + throw new Error(`Failure between markers: '${startMarkerName}', '${endMarkerName}'`); } } @@ -638,7 +638,6 @@ namespace FourSlash { } } - public verifyCompletionListAllowsNewIdentifier(negative: boolean) { const completions = this.getCompletionListAtCaret(); @@ -1479,7 +1478,7 @@ namespace FourSlash { if (isFormattingEdit) { const newContent = this.getFileContent(fileName); - if (newContent.replace(/\s/g, "") !== oldContent.replace(/\s/g, "")) { + if (this.removeWhitespace(newContent) !== this.removeWhitespace(oldContent)) { this.raiseError("Formatting operation destroyed non-whitespace content"); } } @@ -1545,6 +1544,10 @@ namespace FourSlash { } } + private removeWhitespace(text: string): string { + return text.replace(/\s/g, ""); + } + public goToBOF() { this.goToPosition(0); } @@ -1862,6 +1865,44 @@ namespace FourSlash { } } + public verifyCodeFixAtPosition(expectedText: string, errorCode?: number) { + + const ranges = this.getRanges(); + if (ranges.length == 0) { + this.raiseError("At least one range should be specified in the testfile."); + } + + const fileName = this.activeFile.fileName; + const diagnostics = this.getDiagnostics(fileName); + + if (diagnostics.length === 0) { + this.raiseError("Errors expected."); + } + + if (diagnostics.length > 1 && !errorCode) { + this.raiseError("When there's more than one error, you must specify the errror to fix."); + } + + const diagnostic = !errorCode ? diagnostics[0] : ts.firstOrUndefined(diagnostics, d => d.code == errorCode); + + const actual = this.languageService.getCodeFixesAtPosition(fileName, diagnostic.start, diagnostic.length, [`TS${diagnostic.code}`]); + + if (!actual || actual.length == 0) { + this.raiseError("No codefixes returned."); + } + + if (actual.length > 1) { + this.raiseError("More than 1 codefix returned."); + } + + this.applyEdits(actual[0].changes[0].fileName, actual[0].changes[0].textChanges, /*isFormattingEdit*/ false); + const actualText = this.rangeText(ranges[0]); + + if (this.removeWhitespace(actualText) !== this.removeWhitespace(expectedText)) { + this.raiseError(`Actual text doesn't match expected text. Actual: '${actualText}' Expected: '${expectedText}'`); + } + } + public verifyDocCommentTemplate(expected?: ts.TextInsertion) { const name = "verifyDocCommentTemplate"; const actual = this.languageService.getDocCommentTemplateAtPosition(this.activeFile.fileName, this.currentCaretPosition); @@ -3066,6 +3107,10 @@ namespace FourSlashInterface { this.DocCommentTemplate(/*expectedText*/ undefined, /*expectedOffset*/ undefined, /*empty*/ true); } + public codeFixAtPosition(expectedText: string, errorCode?: number): void { + this.state.verifyCodeFixAtPosition(expectedText, errorCode); + } + public navigationBar(json: any) { this.state.verifyNavigationBar(json); } diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index d7ed04b627f4f..d2219c3969d6e 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -453,6 +453,9 @@ namespace Harness.LanguageService { isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean { return unwrapJSONCallResult(this.shim.isValidBraceCompletionAtPosition(fileName, position, openingBrace)); } + getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: string[]): ts.CodeAction[] { + return unwrapJSONCallResult(this.shim.getCodeFixesAtPosition(fileName, start, end, JSON.stringify(errorCodes))); + } getEmitOutput(fileName: string): ts.EmitOutput { return unwrapJSONCallResult(this.shim.getEmitOutput(fileName)); } diff --git a/src/server/client.ts b/src/server/client.ts index f04dbd8dc0253..3c8a07c8cdf23 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -592,6 +592,10 @@ namespace ts.server { throw new Error("Not Implemented Yet."); } + getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: string[]): ts.CodeAction[] { + throw new Error("Not Implemented Yet."); + } + getBraceMatchingAtPosition(fileName: string, position: number): TextSpan[] { const lineOffset = this.positionToOneBasedLineOffset(fileName, position); const args: protocol.FileLocationRequestArgs = { diff --git a/src/services/codefixes/changeExtendsToImplementsFix.ts b/src/services/codefixes/changeExtendsToImplementsFix.ts new file mode 100644 index 0000000000000..ceabb20895196 --- /dev/null +++ b/src/services/codefixes/changeExtendsToImplementsFix.ts @@ -0,0 +1,35 @@ +/* @internal */ +namespace ts.codeFix { + registerCodeFix({ + name: "changeExtendsToImplementsFix", + errorCodes: ["TS2689"], + getCodeActions: (context: CodeFixContext) => { + const sourceFile = context.sourceFile; + const start = context.span.start; + const token = getTokenAtPosition(sourceFile, start); + + const textChanges: TextChange[] = []; + + if (token.kind === SyntaxKind.Identifier && token.parent.parent.kind === SyntaxKind.HeritageClause) { + const children = (token.parent.parent).getChildren(); + for (const child of children) { + if (child.kind === SyntaxKind.ExtendsKeyword) { + textChanges.push({ newText: " implements", span: { start: child.pos, length: child.end - child.pos } }); + } + } + } + + if (textChanges.length > 0) { + return [{ + description: getLocaleSpecificMessage(Diagnostics.Change_extends_to_implements), + changes: [{ + fileName: sourceFile.fileName, + textChanges: textChanges + }] + }]; + } + + Debug.fail("Failed to construct a fix."); + } + }); +} diff --git a/src/services/codefixes/codeFixProvider.ts b/src/services/codefixes/codeFixProvider.ts new file mode 100644 index 0000000000000..ca877aef46aca --- /dev/null +++ b/src/services/codefixes/codeFixProvider.ts @@ -0,0 +1,53 @@ +/* @internal */ +namespace ts { + export interface CodeFix { + name: string; + errorCodes: string[]; + getCodeActions(context: CodeFixContext): CodeAction[]; + } + + export interface CodeFixContext { + errorCode: string; + sourceFile: SourceFile; + span: TextSpan; + checker: TypeChecker; + newLineCharacter: string; + } + + export namespace codeFix { + const codeFixes: Map = {}; + + export function registerCodeFix(action: CodeFix) { + forEach(action.errorCodes, error => { + let fixes = codeFixes[error]; + if (!fixes) { + fixes = []; + codeFixes[error] = fixes; + } + fixes.push(action); + }); + } + + export class CodeFixProvider { + public static getSupportedErrorCodes() { + return getKeys(codeFixes); + } + + public getFixes(context: CodeFixContext): CodeAction[] { + const fixes = codeFixes[context.errorCode]; + let allActions: CodeAction[] = []; + + Debug.assert(fixes && fixes.length > 0, "No fixes found for error: '${errorCode}'."); + + forEach(fixes, f => { + const actions = f.getCodeActions(context); + if (actions && actions.length > 0) { + allActions = allActions.concat(actions); + } + }); + + return allActions; + } + } + } +} \ No newline at end of file diff --git a/src/services/codefixes/interfaceFixes.ts b/src/services/codefixes/interfaceFixes.ts new file mode 100644 index 0000000000000..6b8c9e028e43a --- /dev/null +++ b/src/services/codefixes/interfaceFixes.ts @@ -0,0 +1,266 @@ +/* @internal */ +namespace ts.codeFix { + registerCodeFix({ + name: "ImplementInterfaceOnReferenceFix", + errorCodes: ["TS2322"], + getCodeActions: (context: CodeFixContext) => { + const sourceFile = context.sourceFile; + const start = context.span.start; + const token = getTokenAtPosition(sourceFile, start); + let textChanges: TextChange[] = []; + + if (token.kind === SyntaxKind.Identifier && token.parent.kind === SyntaxKind.VariableDeclaration) { + const variableDeclaration = token.parent; + const membersAndStartPosObject = getMembersAndStartPosFromReference(variableDeclaration); + const variableMembers = membersAndStartPosObject.members; + const trackingAddedMembers: string[] = []; + const startPos: number = membersAndStartPosObject.startPos; + + if (variableDeclaration.type.kind === SyntaxKind.TypeReference) { + textChanges = textChanges.concat(getChanges(variableDeclaration.type, variableMembers, startPos, context.checker, /*reference*/ true, trackingAddedMembers, context.newLineCharacter)); + } + else if (variableDeclaration.type.kind === SyntaxKind.UnionType) { + const types = (variableDeclaration.type).types; + for (let i = 0; i < types.length; i++) { + textChanges = textChanges.concat(getChanges(types[i], variableMembers, startPos, context.checker, /*reference*/ true, trackingAddedMembers, context.newLineCharacter)); + } + } + } + + if (textChanges.length > 0) { + return [{ + description: getLocaleSpecificMessage(Diagnostics.Implement_interface_on_reference), + changes: [{ + fileName: sourceFile.fileName, + textChanges: textChanges + }] + }]; + } + + Debug.fail("No Quick Fix found"); + } + }); + + registerCodeFix({ + name: "ImplementInterfaceOnClassFix", + errorCodes: ["TS2420"], + getCodeActions: (context: CodeFixContext) => { + const sourceFile = context.sourceFile; + const start = context.span.start; + const token = getTokenAtPosition(sourceFile, start); + let textChanges: TextChange[] = []; + + if (token.kind === SyntaxKind.Identifier && token.parent.kind === SyntaxKind.ClassDeclaration) { + const classDeclaration = token.parent; + const startPos: number = classDeclaration.members.pos; + const classMembers = getClassMembers(classDeclaration); + const trackingAddedMembers: string[] = []; + const interfaceClauses = ts.getClassImplementsHeritageClauseElements(classDeclaration); + + for (let i = 0; interfaceClauses && i < interfaceClauses.length; i++) { + textChanges = textChanges.concat(getChanges(interfaceClauses[i], classMembers, startPos, context.checker, /*reference*/ false, trackingAddedMembers, context.newLineCharacter)); + } + } + + if (textChanges.length > 0) { + return [{ + description: getLocaleSpecificMessage(Diagnostics.Implement_interface_on_class), + changes: [{ + fileName: sourceFile.fileName, + textChanges: textChanges + }] + }]; + } + + Debug.fail("No Quick Fix found"); + } + }); + + registerCodeFix({ + name: "ImplementsInheritedAbstractClassFix", + errorCodes: ["TS2515"], + getCodeActions: (context: CodeFixContext) => { + const sourceFile = context.sourceFile; + const start = context.span.start; + const token = getTokenAtPosition(sourceFile, start); + let textChanges: TextChange[] = []; + + if (token.kind === SyntaxKind.Identifier && token.parent.kind === SyntaxKind.ClassDeclaration) { + const classDeclaration = token.parent; + const startPos = classDeclaration.members.pos; + const classMembers = getClassMembers(classDeclaration); + const trackingAddedMembers: string[] = []; + const extendsClause = ts.getClassExtendsHeritageClauseElement(classDeclaration); + textChanges = textChanges.concat(getChanges(extendsClause, classMembers, startPos, context.checker, /*reference*/ false, trackingAddedMembers, context.newLineCharacter)); + } + + if (textChanges.length > 0) { + return [{ + description: getLocaleSpecificMessage(Diagnostics.Implement_inherited_abstract_class), + changes: [{ + fileName: sourceFile.fileName, + textChanges: textChanges + }] + }]; + } + + Debug.fail("No Quick Fix found"); + } + }); + + function getChanges(interfaceClause: Node, existingMembers: string[], startPos: number, checker: TypeChecker, reference: boolean, trackingAddedMembers: string[], newLineCharacter: string): TextChange[] { + const type = checker.getTypeAtLocation(interfaceClause); + const changesArray: TextChange[] = []; + + if (type && type.symbol && type.symbol.declarations) { + const interfaceMembers = getMembers(type.symbol.declarations[0], checker); + for (let j = 0; interfaceMembers && j < interfaceMembers.length; j++) { + if (interfaceMembers[j].name && existingMembers.indexOf(interfaceMembers[j].name.getText()) === -1) { + if (interfaceMembers[j].kind === SyntaxKind.PropertySignature) { + const interfaceProperty = interfaceMembers[j]; + if (trackingAddedMembers.indexOf(interfaceProperty.name.getText()) === -1) { + let propertyText = ""; + if (reference) { + propertyText = `${interfaceProperty.name.getText()} : ${getDefaultValue(interfaceProperty.type.kind)},${newLineCharacter}`; + } + else { + propertyText = interfaceProperty.getText(); + const stringToAdd = !(propertyText.match(/;$/)) ? `;${newLineCharacter}` : newLineCharacter; + propertyText += stringToAdd; + } + changesArray.push({ newText: propertyText, span: { start: startPos, length: 0 } }); + trackingAddedMembers.push(interfaceProperty.name.getText()); + } + } + else if (interfaceMembers[j].kind === SyntaxKind.MethodSignature || interfaceMembers[j].kind === SyntaxKind.MethodDeclaration) { + const interfaceMethod = interfaceMembers[j]; + handleMethods(interfaceMethod, startPos, reference, trackingAddedMembers, changesArray, newLineCharacter); + } + } + } + } + + if (reference && existingMembers.length === 0 && changesArray.length > 0) { + let lastValue = changesArray[changesArray.length - 1].newText; + lastValue = `${lastValue.substr(0, lastValue.length - (newLineCharacter.length + 1))} ${newLineCharacter}`; + changesArray[changesArray.length - 1].newText = lastValue; + } + + return changesArray; + } + + function getMembers(declaration: InterfaceDeclaration, checker: TypeChecker): TypeElement[] { + const clauses = getInterfaceBaseTypeNodes(declaration); + let result: TypeElement[] = []; + for (let i = 0; clauses && i < clauses.length; i++) { + const type = checker.getTypeAtLocation(clauses[i]); + if (type && type.symbol && type.symbol.declarations) { + result = result.concat(getMembers(type.symbol.declarations[0], checker)); + } + } + + if (declaration.members) { + result = result.concat(declaration.members); + } + + return result; + } + + function getClassMembers(classDeclaration: ClassDeclaration): string[] { + const classMembers: string[] = []; + for (let i = 0; classDeclaration.members && i < classDeclaration.members.length; i++) { + if (classDeclaration.members[i].name) { + classMembers.push(classDeclaration.members[i].name.getText()); + } + } + return classMembers; + } + + function getMembersAndStartPosFromReference(variableDeclaration: VariableDeclaration): { startPos: number, members: string[] } { + const children = variableDeclaration.getChildren(); + const variableMembers: string[] = []; + let startPos = 0; + + for (let i = 0; i < children.length; i++) { + if (children[i].kind === SyntaxKind.ObjectLiteralExpression) { + const properties = (children[i]).properties; + if (properties) { + startPos = properties.pos; + } + for (let j = 0; properties && j < properties.length; j++) { + if (properties[j].name) { + variableMembers.push(properties[j].name.getText()); + } + } + } + } + + return { startPos: startPos, members: variableMembers }; + } + + function getDefaultValue(kind: SyntaxKind): string { + switch (kind) { + case SyntaxKind.StringKeyword: + return '""'; + case SyntaxKind.BooleanKeyword: + return "false"; + case SyntaxKind.NumberKeyword: + return "0"; + } + return "null"; + } + + function handleMethods(interfaceMethod: MethodSignature, startPos: number, isReference: boolean, trackingAddedMembers: string[], textChanges: TextChange[], newLineCharacter: string) { + + const methodBody = "throw new Error('Method not Implemented');"; + + if (trackingAddedMembers.indexOf(interfaceMethod.name.getText())) { + const methodName = interfaceMethod.name.getText(); + const typeParameterArray: string[] = []; + + for (let i = 0; interfaceMethod.typeParameters && i < interfaceMethod.typeParameters.length; i++) { + typeParameterArray.push(interfaceMethod.typeParameters[i].getText()); + } + + const parameterArray: string[] = []; + for (let j = 0; interfaceMethod.parameters && j < interfaceMethod.parameters.length; j++) { + parameterArray.push(interfaceMethod.parameters[j].getText()); + } + + let methodText = methodName; + if (typeParameterArray.length > 0) { + methodText += "<"; + } + + for (let k = 0; k < typeParameterArray.length; k++) { + methodText += typeParameterArray[k]; + if (k !== typeParameterArray.length - 1) { + methodText += ","; + } + } + + if (typeParameterArray.length > 0) { + methodText += ">"; + } + + methodText += "("; + for (let k = 0; k < parameterArray.length; k++) { + methodText += parameterArray[k]; + if (k !== parameterArray.length - 1) { + methodText += ","; + } + } + + methodText += `)`; + if (interfaceMethod.type) { + methodText += ":" + interfaceMethod.type.getText(); + } + + methodText += `{${newLineCharacter}${methodBody}${newLineCharacter}`; + methodText = isReference ? methodText.concat(`},${newLineCharacter}`) : methodText.concat(`}${newLineCharacter}`); + + textChanges.push({ newText: methodText, span: { start: startPos, length: 0 } }); + trackingAddedMembers.push(interfaceMethod.name.getText()); + } + } +} diff --git a/src/services/codefixes/references.ts b/src/services/codefixes/references.ts new file mode 100644 index 0000000000000..3675d626678e3 --- /dev/null +++ b/src/services/codefixes/references.ts @@ -0,0 +1,6 @@ +/// +/// +/// +/// +/// +/// diff --git a/src/services/codefixes/superFixes.ts b/src/services/codefixes/superFixes.ts new file mode 100644 index 0000000000000..2c6a67de513b2 --- /dev/null +++ b/src/services/codefixes/superFixes.ts @@ -0,0 +1,65 @@ +/* @internal */ +namespace ts.codeFix { + function getOpenBraceEnd(constructor: ConstructorDeclaration, sourceFile: SourceFile) { + // First token is the open curly, this is where we want to put the 'super' call. + return constructor.body.getFirstToken(sourceFile).getEnd(); + } + + registerCodeFix({ + name: "AddMissingSuperCallFix", + errorCodes: ["TS2377"], + getCodeActions: (context: CodeFixContext) => { + const sourceFile = context.sourceFile; + const token = getTokenAtPosition(sourceFile, context.span.start); + Debug.assert(token.kind === SyntaxKind.ConstructorKeyword, "Failed to find the constructor."); + + const newPosition = getOpenBraceEnd(token.parent, sourceFile); + return [{ + description: getLocaleSpecificMessage(Diagnostics.Add_missing_super_call), + changes: [{ fileName: sourceFile.fileName, textChanges: [{ newText: "super();", span: { start: newPosition, length: 0 } }] }] + }]; + } + }); + + registerCodeFix({ + name: "MakeSuperCallTheFirstStatementInTheConstructor", + errorCodes: ["TS17009"], + getCodeActions: (context: CodeFixContext) => { + const sourceFile = context.sourceFile; + + const token = getTokenAtPosition(sourceFile, context.span.start); + const constructor = getContainingFunction(token); + Debug.assert(constructor.kind === SyntaxKind.Constructor, "Failed to find the constructor."); + + const superCall = findSuperCall((constructor).body); + Debug.assert(!!superCall, "Failed to find super call."); + + const newPosition = getOpenBraceEnd(constructor, sourceFile); + const changes = [{ + fileName: sourceFile.fileName, textChanges: [{ + newText: superCall.getText(sourceFile), + span: { start: newPosition, length: 0 } + }, + { + newText: "", + span: { start: superCall.getStart(sourceFile), length: superCall.getWidth(sourceFile) } + }] + }]; + + return [{ + description: getLocaleSpecificMessage(Diagnostics.Make_super_call_the_first_statement_in_the_constructor), + changes + }]; + + function findSuperCall(n: Node): Node { + if (n.kind === SyntaxKind.ExpressionStatement && isSuperCallExpression((n).expression)) { + return n; + } + if (isFunctionLike(n)) { + return undefined; + } + return forEachChild(n, findSuperCall); + } + } + }); +} \ No newline at end of file diff --git a/src/services/codefixes/unusedIdentifierFixes.ts b/src/services/codefixes/unusedIdentifierFixes.ts new file mode 100644 index 0000000000000..e3b9a804c1302 --- /dev/null +++ b/src/services/codefixes/unusedIdentifierFixes.ts @@ -0,0 +1,151 @@ +/* @internal */ +namespace ts.codeFix { + registerCodeFix({ + name: "RemoveUnusedIdentifiersFix", + errorCodes: ["TS6133"], + getCodeActions: (context: CodeFixContext) => { + const sourceFile = context.sourceFile; + const start = context.span.start; + const token = getTokenAtPosition(sourceFile, start); + + if (token.kind === ts.SyntaxKind.Identifier) { + if (token.parent.kind === ts.SyntaxKind.VariableDeclaration) { + if (token.parent.parent.parent.kind === SyntaxKind.ForStatement) { + const forStatement = token.parent.parent.parent; + const initializer = forStatement.initializer; + if (initializer.declarations.length === 1) { + return createCodeFix("", initializer.pos, initializer.end - initializer.pos); + } + else { + if (initializer.declarations[0] === token.parent) { + return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos + 1); + } + else { + return createCodeFix("", token.parent.pos - 1, token.parent.end - token.parent.pos + 1); + } + } + } + else if (token.parent.parent.parent.kind === SyntaxKind.ForInStatement) { + const forInStatement = token.parent.parent.parent; + const initializer = forInStatement.initializer; + return createCodeFix("{}", initializer.declarations[0].pos, initializer.declarations[0].end - initializer.declarations[0].pos); + } + else if (token.parent.parent.parent.kind === SyntaxKind.ForOfStatement) { + const forOfStatement = token.parent.parent.parent; + const initializer = forOfStatement.initializer; + return createCodeFix("{}", initializer.declarations[0].pos, initializer.declarations[0].end - initializer.declarations[0].pos); + } + else if (token.parent.parent.kind === SyntaxKind.CatchClause) { + const catchClause = token.parent.parent; + const parameter = catchClause.variableDeclaration.getChildren()[0]; + return createCodeFix("", parameter.pos, parameter.end - parameter.pos); + } + else { + const variableStatement = token.parent.parent.parent; + if (variableStatement.declarationList.declarations.length === 1) { + return createCodeFix("", variableStatement.pos, variableStatement.end - variableStatement.pos); + } + else { + const declarations = variableStatement.declarationList.declarations; + if (declarations[0].name === token) { + return createCodeFix("", token.parent.pos + 1, token.parent.end - token.parent.pos); + } + else { + return createCodeFix("", token.parent.pos - 1, token.parent.end - token.parent.pos + 1); + } + } + } + } + + if (token.parent.kind === SyntaxKind.FunctionDeclaration || + token.parent.kind === SyntaxKind.ClassDeclaration || + token.parent.kind === SyntaxKind.InterfaceDeclaration || + token.parent.kind === SyntaxKind.MethodDeclaration || + token.parent.kind === SyntaxKind.ModuleDeclaration || + token.parent.kind === SyntaxKind.PropertyDeclaration || + token.parent.kind === SyntaxKind.ArrowFunction) { + return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); + } + + if (token.parent.kind === SyntaxKind.TypeParameter) { + const typeParameters = (token.parent.parent).typeParameters; + if (typeParameters.length === 1) { + return createCodeFix("", token.parent.pos - 1, token.parent.end - token.parent.pos + 2); + } + else { + if (typeParameters[0] === token.parent) { + return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos + 1); + } + else { + return createCodeFix("", token.parent.pos - 1, token.parent.end - token.parent.pos + 1); + } + } + } + + if (token.parent.kind === ts.SyntaxKind.Parameter) { + const functionDeclaration = token.parent.parent; + if (functionDeclaration.parameters.length === 1) { + return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); + } + else { + if (functionDeclaration.parameters[0] === token.parent) { + return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos + 1); + } + else { + return createCodeFix("", token.parent.pos - 1, token.parent.end - token.parent.pos + 1); + } + } + } + + if (token.parent.kind === SyntaxKind.ImportSpecifier) { + const namedImports = token.parent.parent; + const elements = namedImports.elements; + if (elements.length === 1) { + // Only 1 import and it is unused. So the entire line could be removed. + return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); + } + else { + if (elements[0] === token.parent) { + return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos + 1); + } + else { + return createCodeFix("", token.parent.pos - 1, token.parent.end - token.parent.pos + 1); + } + } + } + + if (token.parent.parent.kind === SyntaxKind.ImportClause || token.parent.parent.kind === SyntaxKind.ImportDeclaration) { + return createCodeFix("{}", token.parent.pos, token.parent.end - token.parent.pos); + } + + if (token.parent.kind === SyntaxKind.ImportEqualsDeclaration) { + return createCodeFix("{}", token.pos, token.end - token.pos); + } + + if (token.parent.kind === SyntaxKind.EnumDeclaration) { + return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); + } + } + + if (token.kind === SyntaxKind.PrivateKeyword && token.parent.kind === SyntaxKind.PropertyDeclaration) { + return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); + } + + if (token.kind === SyntaxKind.AsteriskToken && token.parent.kind === SyntaxKind.NamespaceImport) { + return createCodeFix("{}", token.parent.pos, token.parent.end - token.parent.pos); + } + + Debug.fail("No Quick fix found."); + + function createCodeFix(newText: string, start: number, length: number): CodeAction[] { + return [{ + description: getLocaleSpecificMessage(Diagnostics.Remove_unused_identifiers), + changes: [{ + fileName: sourceFile.fileName, + textChanges: [{ newText, span: { start, length } }] + }] + }]; + } + } + }); +} diff --git a/src/services/services.ts b/src/services/services.ts index aea4d5f872e03..b189a6375b72f 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -11,6 +11,7 @@ /// /// /// +/// namespace ts { /** The version of the language service API */ @@ -1237,6 +1238,8 @@ namespace ts { isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean; + getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: string[]): CodeAction[]; + getEmitOutput(fileName: string): EmitOutput; getProgram(): Program; @@ -1283,6 +1286,18 @@ namespace ts { newText: string; } + export interface FileTextChanges { + fileName: string; + textChanges: TextChange[]; + } + + export interface CodeAction { + /** Description of the code action to display in the UI of the editor */ + description: string; + /** Text changes to apply to each file as part of the code action */ + changes: FileTextChanges[]; + } + export interface TextInsertion { newText: string; /** The position in newText the caret should point to after the insertion. */ @@ -1886,9 +1901,13 @@ namespace ts { }; } - // Cache host information about script should be refreshed + export function getSupportedCodeFixes() { + return codeFix.CodeFixProvider.getSupportedErrorCodes(); + } + + // Cache host information about script Should be refreshed // at each language service public entry point, since we don't know when - // set of scripts handled by the host changes. + // the set of scripts handled by the host changes. class HostCache { private fileNameToEntry: FileMap; private _compilationSettings: CompilerOptions; @@ -3022,6 +3041,7 @@ namespace ts { documentRegistry: DocumentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory())): LanguageService { const syntaxTreeCache: SyntaxTreeCache = new SyntaxTreeCache(host); + const codeFixProvider: codeFix.CodeFixProvider = new codeFix.CodeFixProvider(); let ruleProvider: formatting.RulesProvider; let program: Program; let lastProjectVersion: string; @@ -7832,6 +7852,30 @@ namespace ts { return []; } + function getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: string[]): CodeAction[] { + synchronizeHostData(); + const sourceFile = getValidSourceFile(fileName); + const checker = program.getTypeChecker(); + let allFixes: CodeAction[] = []; + + forEach(errorCodes, error => { + const context = { + errorCode: error, + sourceFile: sourceFile, + span: { start, length: end - start }, + checker: checker, + newLineCharacter: getNewLineOrDefaultFromHost(host) + }; + + const fixes = codeFixProvider.getFixes(context); + if (fixes) { + allFixes = allFixes.concat(fixes); + } + }); + + return allFixes; + } + /** * Checks if position points to a valid position to add JSDoc comments, and if so, * returns the appropriate template. Otherwise returns an empty string. @@ -8302,6 +8346,7 @@ namespace ts { getFormattingEditsAfterKeystroke, getDocCommentTemplateAtPosition, isValidBraceCompletionAtPosition, + getCodeFixesAtPosition, getEmitOutput, getNonBoundSourceFile, getProgram diff --git a/src/services/shims.ts b/src/services/shims.ts index 45c4b284ae744..dfa34d29acca8 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -240,6 +240,8 @@ namespace ts { */ isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): string; + getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: string): string; + getEmitOutput(fileName: string): string; getEmitOutputObject(fileName: string): EmitOutput; } @@ -255,6 +257,7 @@ namespace ts { getTSConfigFileInfo(fileName: string, sourceText: IScriptSnapshot): string; getDefaultCompilationSettings(): string; discoverTypings(discoverTypingsJson: string): string; + getSupportedCodeFixes(): string; } function logInternalError(logger: Logger, err: Error) { @@ -901,6 +904,16 @@ namespace ts { ); } + public getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: string): string { + return this.forwardJSONCall( + `getCodeFixesAtPosition( '${fileName}', ${start}, ${end}, ${errorCodes}')`, + () => { + const localErrors: string[] = JSON.parse(errorCodes); + return this.languageService.getCodeFixesAtPosition(fileName, start, end, localErrors); + } + ); + } + /// NAVIGATE TO /** Return a list of symbols that are interesting to navigate to */ @@ -1109,6 +1122,12 @@ namespace ts { info.compilerOptions); }); } + + public getSupportedCodeFixes(): string { + return this.forwardJSONCall("getSupportedCodeFixes()", + () => getSupportedCodeFixes() + ); + } } export class TypeScriptServicesFactory implements ShimFactory { diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index cfeb7c2fcd582..70e7b53d0835d 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -52,6 +52,12 @@ "formatting/rulesMap.ts", "formatting/rulesProvider.ts", "formatting/smartIndenter.ts", - "formatting/tokenRange.ts" + "formatting/tokenRange.ts", + "codeFixes/changeExtendsToImplementsFix.ts", + "codeFixes/codeFixProvider.ts", + "codeFixes/interfaceFixes.ts", + "codeFixes/references.ts", + "codeFixes/superFixes.ts", + "codeFixes/unusedIdentifierFixes.ts" ] } diff --git a/tests/cases/fourslash/changeExtendsToImplementsFS1.ts b/tests/cases/fourslash/changeExtendsToImplementsFS1.ts new file mode 100644 index 0000000000000..a5b9a6375b6fa --- /dev/null +++ b/tests/cases/fourslash/changeExtendsToImplementsFS1.ts @@ -0,0 +1,6 @@ +/// + +//// interface I1 {} +//// [|class c1 extends I1|]{} + +verify.codeFixAtPosition("class c1 implements I1"); \ No newline at end of file diff --git a/tests/cases/fourslash/changeExtendsToImplementsFS2.ts b/tests/cases/fourslash/changeExtendsToImplementsFS2.ts new file mode 100644 index 0000000000000..b63ab3032eb9a --- /dev/null +++ b/tests/cases/fourslash/changeExtendsToImplementsFS2.ts @@ -0,0 +1,6 @@ +/// + +////interface I1 {} +////[|class c1 extends I1|]{} + +verify.codeFixAtPosition("class c1 implements I1"); \ No newline at end of file diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 9ce3197a46f73..ee0d4d100d3ca 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -192,6 +192,7 @@ declare namespace FourSlashInterface { noMatchingBracePositionInCurrentFile(bracePosition: number): void; DocCommentTemplate(expectedText: string, expectedOffset: number, empty?: boolean): void; noDocCommentTemplate(): void; + codeFixAtPosition(expectedText: string, errorCode?: number): void; navigationBar(json: any): void; navigationItemsListCount(count: number, searchValue: string, matchKind?: string): void; diff --git a/tests/cases/fourslash/superFix1.ts b/tests/cases/fourslash/superFix1.ts new file mode 100644 index 0000000000000..7fbe2cb4fd7bd --- /dev/null +++ b/tests/cases/fourslash/superFix1.ts @@ -0,0 +1,10 @@ +/// + +////class Base{ +////} +////class C extends Base{ +//// constructor() {[| |] +//// } +////} + +verify.codeFixAtPosition('super();'); diff --git a/tests/cases/fourslash/superFix2.ts b/tests/cases/fourslash/superFix2.ts new file mode 100644 index 0000000000000..880b5d43167c4 --- /dev/null +++ b/tests/cases/fourslash/superFix2.ts @@ -0,0 +1,13 @@ +/// + +////class Base{ +////} +////class C extends Base{ +//// private a:number; +//// constructor() {[| +//// this.a = 12; +//// super();|] +//// } +////} + +verify.codeFixAtPosition("super(); this.a = 12;"); \ No newline at end of file diff --git a/tests/cases/fourslash/unImplementedInterface1.ts b/tests/cases/fourslash/unImplementedInterface1.ts new file mode 100644 index 0000000000000..b07db08f12a81 --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface1.ts @@ -0,0 +1,18 @@ +/// + +//// namespace N1 { +//// export interface I1 { +//// f1(); +//// } +//// } +//// interface I1 { +//// f1(); +//// } +//// +//// class C1 implements N1.I1 {[| +//// |]} + +verify.codeFixAtPosition(`f1(){ + throw new Error('Method not Implemented'); +} +`); diff --git a/tests/cases/fourslash/unImplementedInterface10.ts b/tests/cases/fourslash/unImplementedInterface10.ts new file mode 100644 index 0000000000000..aa61cbc1836d7 --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface10.ts @@ -0,0 +1,18 @@ +/// + +//// interface I1 { +//// f1() +//// } +//// +//// interface I2 extends I1 { +//// +//// } +//// +//// +//// class C1 implements I2 {[| +//// |]} + +verify.codeFixAtPosition(`f1(){ + throw new Error('Method not Implemented'); +} +`); diff --git a/tests/cases/fourslash/unImplementedInterface11.ts b/tests/cases/fourslash/unImplementedInterface11.ts new file mode 100644 index 0000000000000..3c819f6b56e2c --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface11.ts @@ -0,0 +1,19 @@ +/// + +//// interface I1 { +//// +//// } +//// +//// interface I2 extends I1 { +//// f1(); +//// } +//// +//// interface I3 extends I2 {} +//// +//// class C1 implements I3 {[| +//// |]} + +verify.codeFixAtPosition(`f1(){ + throw new Error('Method not Implemented'); +} +`); diff --git a/tests/cases/fourslash/unImplementedInterface12.ts b/tests/cases/fourslash/unImplementedInterface12.ts new file mode 100644 index 0000000000000..4e9e428fd6d1d --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface12.ts @@ -0,0 +1,19 @@ +/// + +//// interface I1 { +//// +//// } +//// +//// interface I2 { +//// f1(); +//// } +//// +//// interface I3 extends I2, I1 {} +//// +//// class C1 implements I3 {[| +//// |]} + +verify.codeFixAtPosition(`f1(){ + throw new Error('Method not Implemented'); +} +`); diff --git a/tests/cases/fourslash/unImplementedInterface13.ts b/tests/cases/fourslash/unImplementedInterface13.ts new file mode 100644 index 0000000000000..fdb0fa1230c04 --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface13.ts @@ -0,0 +1,19 @@ +/// + +//// interface I1 { +//// f1(); +//// } +//// +//// interface I2 { +//// f1(); +//// } +//// +//// interface I3 extends I2, I1 {} +//// +//// class C1 implements I3 {[| +//// |]} + +verify.codeFixAtPosition(`f1(){ + throw new Error('Method not Implemented'); +} +`); diff --git a/tests/cases/fourslash/unImplementedInterface14.ts b/tests/cases/fourslash/unImplementedInterface14.ts new file mode 100644 index 0000000000000..ad55fef3cced4 --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface14.ts @@ -0,0 +1,16 @@ +/// + +//// interface I1 { +//// f1(); +//// f2(); +//// } +//// +//// +//// var x: I1 ={[| +//// |]f2() {} +//// } + +verify.codeFixAtPosition(`f1(){ + throw new Error('Method not Implemented'); +}, +`); diff --git a/tests/cases/fourslash/unImplementedInterface15.ts b/tests/cases/fourslash/unImplementedInterface15.ts new file mode 100644 index 0000000000000..e68f7171ee5a7 --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface15.ts @@ -0,0 +1,15 @@ +/// + +//// interface I1 { +//// f1(); +//// } +//// +//// var x: I1 = {[| +//// +//// |]} + +verify.codeFixAtPosition(` +f1(){ + throw new Error('Method not Implemented'); +} +`); diff --git a/tests/cases/fourslash/unImplementedInterface16.ts b/tests/cases/fourslash/unImplementedInterface16.ts new file mode 100644 index 0000000000000..ca992b1eb1e79 --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface16.ts @@ -0,0 +1,12 @@ +/// + +//// interface I1 { +//// x:string; +//// } +//// +//// +//// var x: I1 ={[| +//// |]} + +verify.codeFixAtPosition(`x : "" +`); diff --git a/tests/cases/fourslash/unImplementedInterface17.ts b/tests/cases/fourslash/unImplementedInterface17.ts new file mode 100644 index 0000000000000..e909b60f588ff --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface17.ts @@ -0,0 +1,11 @@ +/// + +//// interface I1 { +//// x:number; +//// } +//// +//// var x: I1 ={[| +//// |]} + +verify.codeFixAtPosition(`x : 0 +`); diff --git a/tests/cases/fourslash/unImplementedInterface18.ts b/tests/cases/fourslash/unImplementedInterface18.ts new file mode 100644 index 0000000000000..9e0f9888bf3c2 --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface18.ts @@ -0,0 +1,12 @@ +/// + +//// interface I1 { +//// x:boolean; +//// } +//// +//// var x: I1 ={[| +//// +//// |]} + +verify.codeFixAtPosition(`x : false +`); diff --git a/tests/cases/fourslash/unImplementedInterface19.ts b/tests/cases/fourslash/unImplementedInterface19.ts new file mode 100644 index 0000000000000..de484c282d833 --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface19.ts @@ -0,0 +1,13 @@ +/// + +//// interface I1 { +//// x:string; +//// f1(); +//// } +//// +//// var x: I1 ={[| +//// |]f1(){} +//// } + +verify.codeFixAtPosition(`x : "", +`); diff --git a/tests/cases/fourslash/unImplementedInterface2.ts b/tests/cases/fourslash/unImplementedInterface2.ts new file mode 100644 index 0000000000000..394c54d468724 --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface2.ts @@ -0,0 +1,16 @@ +/// + +//// namespace N1 { +//// export interface I1 { +//// x: number; +//// } +//// } +//// interface I1 { +//// f1(); +//// } +//// +//// class C1 implements N1.I1 {[| +//// |]} + +verify.codeFixAtPosition(`x: number; +`); diff --git a/tests/cases/fourslash/unImplementedInterface20.ts b/tests/cases/fourslash/unImplementedInterface20.ts new file mode 100644 index 0000000000000..56a707d21bad9 --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface20.ts @@ -0,0 +1,14 @@ +/// + +//// interface I1 { +//// x:number; +//// f1(); +//// } +//// +//// +//// var x: I1 ={[| +//// |]f1(){} +//// } + +verify.codeFixAtPosition(`x : 0, +`); diff --git a/tests/cases/fourslash/unImplementedInterface21.ts b/tests/cases/fourslash/unImplementedInterface21.ts new file mode 100644 index 0000000000000..867c697e595c2 --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface21.ts @@ -0,0 +1,14 @@ +/// + +//// interface I1 { +//// x:boolean; +//// f1(); +//// } +//// +//// +//// var x: I1 ={[| +//// |]f1(){} +//// } + +verify.codeFixAtPosition(`x : false, +`); diff --git a/tests/cases/fourslash/unImplementedInterface22.ts b/tests/cases/fourslash/unImplementedInterface22.ts new file mode 100644 index 0000000000000..8a51577261f5b --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface22.ts @@ -0,0 +1,12 @@ +/// + +//// interface I1 { +//// x:[string]; +//// } +//// +//// +//// var x: I1 ={[| +//// |]} + +verify.codeFixAtPosition(`x : null +`); diff --git a/tests/cases/fourslash/unImplementedInterface23.ts b/tests/cases/fourslash/unImplementedInterface23.ts new file mode 100644 index 0000000000000..8d00689a446ab --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface23.ts @@ -0,0 +1,14 @@ +/// + +//// interface I1 { +//// x:[string]; +//// f1(); +//// } +//// +//// +//// var x: I1 ={[| +//// |]f1(){} +//// } + +verify.codeFixAtPosition(`x : null, +`); diff --git a/tests/cases/fourslash/unImplementedInterface24.ts b/tests/cases/fourslash/unImplementedInterface24.ts new file mode 100644 index 0000000000000..c206789b7f2a4 --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface24.ts @@ -0,0 +1,12 @@ +/// + +//// interface I1 { +//// x:Array; +//// } +//// +//// +//// var x: I1 ={[| +//// |]} + +verify.codeFixAtPosition(`x : null +`); diff --git a/tests/cases/fourslash/unImplementedInterface25.ts b/tests/cases/fourslash/unImplementedInterface25.ts new file mode 100644 index 0000000000000..6b2b809efaa8c --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface25.ts @@ -0,0 +1,14 @@ +/// + +//// interface I1 { +//// x:Array; +//// f1(); +//// } +//// +//// +//// var x: I1 ={[| +//// |]f1(){} +//// } + +verify.codeFixAtPosition(`x : null, +`); diff --git a/tests/cases/fourslash/unImplementedInterface26.ts b/tests/cases/fourslash/unImplementedInterface26.ts new file mode 100644 index 0000000000000..a7136f0e70fc4 --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface26.ts @@ -0,0 +1,14 @@ +/// + +//// interface I1 { +//// x:T; +//// } +//// +//// class T {} +//// +//// +//// var x: I1 ={[| +//// |]} + +verify.codeFixAtPosition(`x : null +`); diff --git a/tests/cases/fourslash/unImplementedInterface27.ts b/tests/cases/fourslash/unImplementedInterface27.ts new file mode 100644 index 0000000000000..fc12cb57377fb --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface27.ts @@ -0,0 +1,16 @@ +/// + +//// interface I1 { +//// x:T; +//// f1(); +//// } +//// +//// class T {} +//// +//// +//// var x: I1 ={[| +//// |]f1(){} +//// } + +verify.codeFixAtPosition(`x : null, +`); diff --git a/tests/cases/fourslash/unImplementedInterface28.ts b/tests/cases/fourslash/unImplementedInterface28.ts new file mode 100644 index 0000000000000..16cbe47b26cbe --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface28.ts @@ -0,0 +1,21 @@ +/// + +//// interface I1 { +//// f1(); +//// } +//// +//// interface I2 { +//// f2(); +//// } +//// +//// var x: I1|I2 ={[| +//// +//// |]} + +verify.codeFixAtPosition(`f1(){ + throw new Error('Method not Implemented'); +} +f2(){ + throw new Error('Method not Implemented'); +} +`); diff --git a/tests/cases/fourslash/unImplementedInterface29.ts b/tests/cases/fourslash/unImplementedInterface29.ts new file mode 100644 index 0000000000000..c2719c2e7f94f --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface29.ts @@ -0,0 +1,14 @@ +/// + +//// abstract class C1 { +//// f1(){} +//// } +//// +//// class C2 implements C1 {[| +//// |]f2(){} +//// } + +verify.codeFixAtPosition(`f1(){ + throw new Error('Method not Implemented'); +} +`); diff --git a/tests/cases/fourslash/unImplementedInterface3.ts b/tests/cases/fourslash/unImplementedInterface3.ts new file mode 100644 index 0000000000000..19354ce1c948c --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface3.ts @@ -0,0 +1,16 @@ +/// + +//// namespace N1 { +//// export interface I1 { +//// x: number +//// } +//// } +//// interface I1 { +//// f1(); +//// } +//// +//// class C1 implements N1.I1 {[| +//// |]} + +verify.codeFixAtPosition(`x: number; +`); diff --git a/tests/cases/fourslash/unImplementedInterface30.ts b/tests/cases/fourslash/unImplementedInterface30.ts new file mode 100644 index 0000000000000..71addef195b48 --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface30.ts @@ -0,0 +1,18 @@ +/// + +//// abstract class C1 { +//// f1(){} +//// } +//// +//// abstract class C2 extends C1 { +//// +//// } +//// +//// class C3 implements C2 {[| +//// |]f2(){} +//// } + +verify.codeFixAtPosition(`f1(){ + throw new Error('Method not Implemented'); +} +`); diff --git a/tests/cases/fourslash/unImplementedInterface31.ts b/tests/cases/fourslash/unImplementedInterface31.ts new file mode 100644 index 0000000000000..d56e44911b533 --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface31.ts @@ -0,0 +1,18 @@ +/// + +//// abstract class C1 { +//// abstract f1(); +//// } +//// +//// abstract class C2 extends C1 { +//// +//// } +//// +//// class C3 implements C2 {[| +//// |]f2(){} +//// } + +verify.codeFixAtPosition(`f1(){ + throw new Error('Method not Implemented'); +} +`); diff --git a/tests/cases/fourslash/unImplementedInterface32.ts b/tests/cases/fourslash/unImplementedInterface32.ts new file mode 100644 index 0000000000000..825224f448b53 --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface32.ts @@ -0,0 +1,18 @@ +/// + +//// abstract class C1 { +//// abstract f1(); +//// } +//// +//// abstract class C2 extends C1 { +//// +//// } +//// +//// class C3 implements C2 {[| +//// |]f2(){} +//// } + +verify.codeFixAtPosition(`f1(){ + throw new Error('Method not Implemented'); +} +`); diff --git a/tests/cases/fourslash/unImplementedInterface33.ts b/tests/cases/fourslash/unImplementedInterface33.ts new file mode 100644 index 0000000000000..7c3a647ce40f8 --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface33.ts @@ -0,0 +1,18 @@ +/// + +//// abstract class C1 { +//// abstract f1(); +//// } +//// +//// abstract class C2 extends C1 { +//// +//// } +//// +//// class C3 implements C2 {[| +//// |]f2(){} +//// } + +verify.codeFixAtPosition(`f1(){ + throw new Error('Method not Implemented'); +} +`); diff --git a/tests/cases/fourslash/unImplementedInterface34.ts b/tests/cases/fourslash/unImplementedInterface34.ts new file mode 100644 index 0000000000000..ab7a4f30beadf --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface34.ts @@ -0,0 +1,14 @@ +/// + +//// abstract class C1 { +//// abstract f1(); +//// } +//// +//// class C2 extends C1 {[| +//// +//// |]} + +verify.codeFixAtPosition(`f1(){ + throw new Error('Method not Implemented'); +} +`); diff --git a/tests/cases/fourslash/unImplementedInterface35.ts b/tests/cases/fourslash/unImplementedInterface35.ts new file mode 100644 index 0000000000000..66d47491c4199 --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface35.ts @@ -0,0 +1,16 @@ +/// + +//// abstract class C1 { +//// abstract f1(); +//// } +//// +//// interface I1 extends C1 {} +//// +//// class C2 implements I1 {[| +//// +//// |]} + +verify.codeFixAtPosition(`f1(){ + throw new Error('Method not Implemented'); +} +`); diff --git a/tests/cases/fourslash/unImplementedInterface36.ts b/tests/cases/fourslash/unImplementedInterface36.ts new file mode 100644 index 0000000000000..3871414428efe --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface36.ts @@ -0,0 +1,20 @@ +/// + +//// abstract class C1 { +//// +//// } +//// +//// abstract class C2 { +//// abstract f1(); +//// } +//// +//// interface I1 extends C1, C2 {} +//// +//// class C3 implements I1 {[| +//// +//// |]} + +verify.codeFixAtPosition(`f1(){ + throw new Error('Method not Implemented'); +} +`); diff --git a/tests/cases/fourslash/unImplementedInterface37.ts b/tests/cases/fourslash/unImplementedInterface37.ts new file mode 100644 index 0000000000000..2032f2d346192 --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface37.ts @@ -0,0 +1,20 @@ +/// + +//// abstract class C1 { +//// abstract f1(); +//// } +//// +//// abstract class C2 extends C1{ +//// +//// } +//// +//// interface I1 extends C2 {} +//// +//// class C3 implements I1 {[| +//// +//// |]} + +verify.codeFixAtPosition(`f1(){ + throw new Error('Method not Implemented'); +} +`); diff --git a/tests/cases/fourslash/unImplementedInterface38.ts b/tests/cases/fourslash/unImplementedInterface38.ts new file mode 100644 index 0000000000000..c60b9922ef859 --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface38.ts @@ -0,0 +1,11 @@ +/// + +//// abstract class C2 { +//// abstract f1(); +//// } +//// +//// var x: C2 = {[| |]} + +verify.codeFixAtPosition(`f1(){ + throw new Error('Method not Implemented'); +}`); diff --git a/tests/cases/fourslash/unImplementedInterface39.ts b/tests/cases/fourslash/unImplementedInterface39.ts new file mode 100644 index 0000000000000..ae85d02b8a392 --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface39.ts @@ -0,0 +1,18 @@ +/// + +//// namespace N1 { +//// export interface I1 { +//// f1():string; +//// } +//// } +//// interface I1 { +//// f1(); +//// } +//// +//// class C1 implements N1.I1 {[| +//// |]} + +verify.codeFixAtPosition(`f1():string{ + throw new Error('Method not Implemented'); +} +`); diff --git a/tests/cases/fourslash/unImplementedInterface4.ts b/tests/cases/fourslash/unImplementedInterface4.ts new file mode 100644 index 0000000000000..6e4e64c18d108 --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface4.ts @@ -0,0 +1,18 @@ +/// + +//// namespace N1 { +//// export interface I1 { +//// f1() +//// } +//// } +//// interface I1 { +//// f1(); +//// } +//// +//// class C1 implements N1.I1 {[| +//// |]} + +verify.codeFixAtPosition(`f1(){ + throw new Error('Method not Implemented'); +} +`); diff --git a/tests/cases/fourslash/unImplementedInterface5.ts b/tests/cases/fourslash/unImplementedInterface5.ts new file mode 100644 index 0000000000000..59b3ba8519947 --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface5.ts @@ -0,0 +1,18 @@ +/// + +//// namespace N1 { +//// export interface I1 { +//// f1(x: number, y: string) +//// } +//// } +//// interface I1 { +//// f1(); +//// } +//// +//// class C1 implements N1.I1 {[| +//// |]} + +verify.codeFixAtPosition(`f1(x: number,y: string){ + throw new Error('Method not Implemented'); +} +`); diff --git a/tests/cases/fourslash/unImplementedInterface6.ts b/tests/cases/fourslash/unImplementedInterface6.ts new file mode 100644 index 0000000000000..2310e05fbb019 --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface6.ts @@ -0,0 +1,15 @@ +/// + +//// interface I1 { +//// f1(x: number, y: T); +//// } +//// +//// class T {} +//// +//// class C1 implements I1 {[| +//// |]} + +verify.codeFixAtPosition(`f1(x: number,y: T){ + throw new Error('Method not Implemented'); +} +`); diff --git a/tests/cases/fourslash/unImplementedInterface7.ts b/tests/cases/fourslash/unImplementedInterface7.ts new file mode 100644 index 0000000000000..125f3e1ffeb50 --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface7.ts @@ -0,0 +1,15 @@ +/// + +//// interface I1 { +//// f1(x: number, y: C2); +//// } +//// +//// class C2 {} +//// +//// class C1 implements I1 {[| +//// |]} + +verify.codeFixAtPosition(`f1(x: number,y: C2){ + throw new Error('Method not Implemented'); +} +`); diff --git a/tests/cases/fourslash/unImplementedInterface8.ts b/tests/cases/fourslash/unImplementedInterface8.ts new file mode 100644 index 0000000000000..2df93c6d7d915 --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface8.ts @@ -0,0 +1,15 @@ +/// + +//// interface I1 { +//// f1(x: number, y: C2); +//// } +//// +//// class C2 {} +//// +//// class C1 implements I1 {[| +//// |]} + +verify.codeFixAtPosition(`f1(x: number,y: C2){ + throw new Error('Method not Implemented'); +} +`); diff --git a/tests/cases/fourslash/unImplementedInterface9.ts b/tests/cases/fourslash/unImplementedInterface9.ts new file mode 100644 index 0000000000000..5c869996773ad --- /dev/null +++ b/tests/cases/fourslash/unImplementedInterface9.ts @@ -0,0 +1,17 @@ +/// + +//// interface I1 { +//// +//// } +//// +//// interface I2 extends I1 { +//// f1(); +//// } +//// +//// class C1 implements I2 {[| +//// |]} + +verify.codeFixAtPosition(`f1(){ + throw new Error('Method not Implemented'); +} +`); diff --git a/tests/cases/fourslash/unusedClassInNamespace1.ts b/tests/cases/fourslash/unusedClassInNamespace1.ts new file mode 100644 index 0000000000000..586202ab0c7d4 --- /dev/null +++ b/tests/cases/fourslash/unusedClassInNamespace1.ts @@ -0,0 +1,10 @@ +/// + +// @noUnusedLocals: true +//// [| namespace greeter { +//// class class1 { +//// } +//// } |] + +verify.codeFixAtPosition(`namespace greeter { +}`); diff --git a/tests/cases/fourslash/unusedClassInNamespace2.ts b/tests/cases/fourslash/unusedClassInNamespace2.ts new file mode 100644 index 0000000000000..c182f4e3655dc --- /dev/null +++ b/tests/cases/fourslash/unusedClassInNamespace2.ts @@ -0,0 +1,15 @@ +/// + +// @noUnusedLocals: true +//// [| namespace greeter { +//// export class class2 { +//// } +//// class class1 { +//// } +//// } |] + +verify.codeFixAtPosition(`namespace greeter { + export class class2 { + } +}`); + diff --git a/tests/cases/fourslash/unusedClassInNamespace3.ts b/tests/cases/fourslash/unusedClassInNamespace3.ts new file mode 100644 index 0000000000000..6102f744717d6 --- /dev/null +++ b/tests/cases/fourslash/unusedClassInNamespace3.ts @@ -0,0 +1,12 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters:true +//// [| namespace Validation { +//// class c1 { +//// +//// }/*1*/ +//// } |] + +verify.codeFixAtPosition(`namespace Validation { +}`); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedClassInNamespace4.ts b/tests/cases/fourslash/unusedClassInNamespace4.ts new file mode 100644 index 0000000000000..79701a5e0e20f --- /dev/null +++ b/tests/cases/fourslash/unusedClassInNamespace4.ts @@ -0,0 +1,19 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters:true + +//// [| namespace Validation { +//// class c1 { +//// +//// } +//// +//// export class c2 { +//// +//// } +//// } |] + +verify.codeFixAtPosition(`namespace Validation { + export class c2 { + } +}`); diff --git a/tests/cases/fourslash/unusedClassInNamespace5.ts b/tests/cases/fourslash/unusedClassInNamespace5.ts new file mode 100644 index 0000000000000..80d8fe857bd12 --- /dev/null +++ b/tests/cases/fourslash/unusedClassInNamespace5.ts @@ -0,0 +1,26 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters:true + +//// [| namespace Validation { +//// class c1 { +//// +//// } +//// +//// export class c2 { +//// +//// } +//// +//// class c3 extends c1 { +//// +//// } +////} |] + +verify.codeFixAtPosition(`namespace Validation { + class c1 { + } + + export class c2 { + } +}`); diff --git a/tests/cases/fourslash/unusedClassInNamespace6.ts b/tests/cases/fourslash/unusedClassInNamespace6.ts new file mode 100644 index 0000000000000..5db5b1aefa65d --- /dev/null +++ b/tests/cases/fourslash/unusedClassInNamespace6.ts @@ -0,0 +1,27 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters:true +//// [| namespace Validation { +//// class c1 { +//// +//// } +//// +//// export class c2 { +//// +//// } +//// +//// class c3 { +//// public x: c1; +//// } +////} |] + +verify.codeFixAtPosition(`namespace Validation { + class c1 { + + } + + export class c2 { + + } +}`); diff --git a/tests/cases/fourslash/unusedConstantInFunction1.ts b/tests/cases/fourslash/unusedConstantInFunction1.ts new file mode 100644 index 0000000000000..df37325780997 --- /dev/null +++ b/tests/cases/fourslash/unusedConstantInFunction1.ts @@ -0,0 +1,10 @@ +/// + +// @noUnusedLocals: true +//// [| function f1 () { +//// const x: string = "x"; +//// } |] + +verify.codeFixAtPosition(`function f1 () { +}`); + diff --git a/tests/cases/fourslash/unusedEnumInFunction1.ts b/tests/cases/fourslash/unusedEnumInFunction1.ts new file mode 100644 index 0000000000000..1d88f07ebf76b --- /dev/null +++ b/tests/cases/fourslash/unusedEnumInFunction1.ts @@ -0,0 +1,11 @@ +/// + +// @noUnusedLocals: true +//// [| function f1 () { +//// enum Directions { Up, Down} +//// } |] + +verify.codeFixAtPosition(`function f1 () { +} +`); + diff --git a/tests/cases/fourslash/unusedFunctionInNamespace1.ts b/tests/cases/fourslash/unusedFunctionInNamespace1.ts new file mode 100644 index 0000000000000..e0f6b2e18ac15 --- /dev/null +++ b/tests/cases/fourslash/unusedFunctionInNamespace1.ts @@ -0,0 +1,10 @@ +/// + +// @noUnusedLocals: true +//// [| namespace greeter { +//// function function1() { +//// }/*1*/ +//// } |] + +verify.codeFixAtPosition(`namespace greeter { +}`); diff --git a/tests/cases/fourslash/unusedFunctionInNamespace2.ts b/tests/cases/fourslash/unusedFunctionInNamespace2.ts new file mode 100644 index 0000000000000..c823777048e2e --- /dev/null +++ b/tests/cases/fourslash/unusedFunctionInNamespace2.ts @@ -0,0 +1,14 @@ +/// + +// @noUnusedLocals: true +//// [| namespace greeter { +//// export function function2() { +//// } +//// function function1() { +//// } +////} |] + +verify.codeFixAtPosition(`namespace greeter { + export function function2() { + } +}`); diff --git a/tests/cases/fourslash/unusedFunctionInNamespace3.ts b/tests/cases/fourslash/unusedFunctionInNamespace3.ts new file mode 100644 index 0000000000000..144e9f325b444 --- /dev/null +++ b/tests/cases/fourslash/unusedFunctionInNamespace3.ts @@ -0,0 +1,12 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters:true + +//// [| namespace Validation { +//// function function1() { +//// } +////} |] + +verify.codeFixAtPosition(`namespace Validation { +}`); diff --git a/tests/cases/fourslash/unusedFunctionInNamespace4.ts b/tests/cases/fourslash/unusedFunctionInNamespace4.ts new file mode 100644 index 0000000000000..5b5995da9c745 --- /dev/null +++ b/tests/cases/fourslash/unusedFunctionInNamespace4.ts @@ -0,0 +1,11 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters:true +//// [| namespace Validation { +//// var function1 = function() { +//// } +////} |] + +verify.codeFixAtPosition(`namespace Validation { +}`); diff --git a/tests/cases/fourslash/unusedFunctionInNamespace5.ts b/tests/cases/fourslash/unusedFunctionInNamespace5.ts new file mode 100644 index 0000000000000..fa1eed2364a51 --- /dev/null +++ b/tests/cases/fourslash/unusedFunctionInNamespace5.ts @@ -0,0 +1,28 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters:true +////namespace Validation { +//// var function1 = function() { +//// } +//// +//// export function function2() { +//// +//// } +//// +//// [| function function3() { +//// function1(); +//// } +//// +//// function function4() { +//// +//// } +//// +//// exp ort let a = function3; |] +////} + +verify.codeFixAtPosition(`function function3() { + function1(); + } + + export let a = function3;`, 6133); diff --git a/tests/cases/fourslash/unusedImports10FS.ts b/tests/cases/fourslash/unusedImports10FS.ts new file mode 100644 index 0000000000000..2eb923c9b8fbc --- /dev/null +++ b/tests/cases/fourslash/unusedImports10FS.ts @@ -0,0 +1,16 @@ +/// + +// @noUnusedLocals: true +//// module A { +//// export class Calculator { +//// public handelChar() { +//// } +//// } +//// } + +//// module B { +//// [|import a = A;|] +//// } + +verify.codeFixAtPosition(" import {} = A;"); + diff --git a/tests/cases/fourslash/unusedImports1FS.ts b/tests/cases/fourslash/unusedImports1FS.ts new file mode 100644 index 0000000000000..c3ae198d876dc --- /dev/null +++ b/tests/cases/fourslash/unusedImports1FS.ts @@ -0,0 +1,12 @@ +/// + +// @noUnusedLocals: true +// @Filename: file2.ts +//// [| import {/*0*/Calculator/*1*/} from "./file1" |] + +// @Filename: file1.ts +//// export class Calculator { +//// +//// } + +verify.codeFixAtPosition(`import {} from "./file1"`); diff --git a/tests/cases/fourslash/unusedImports2FS.ts b/tests/cases/fourslash/unusedImports2FS.ts new file mode 100644 index 0000000000000..a7144d1eb4976 --- /dev/null +++ b/tests/cases/fourslash/unusedImports2FS.ts @@ -0,0 +1,20 @@ +/// + +// @noUnusedLocals: true +// @Filename: file2.ts +//// [| import {Calculator} from "./file1" +//// import {test} from "./file1" |] + +//// var x = new Calculator(); +//// x.handleChar(); + +// @Filename: file1.ts +//// export class Calculator { +//// handleChar() {} +//// } +//// export function test() { +//// +//// } + +verify.codeFixAtPosition(`import {Calculator} from "./file1" +import {} from "./file1"`); diff --git a/tests/cases/fourslash/unusedImports3FS.ts b/tests/cases/fourslash/unusedImports3FS.ts new file mode 100644 index 0000000000000..f030232dc1e5b --- /dev/null +++ b/tests/cases/fourslash/unusedImports3FS.ts @@ -0,0 +1,24 @@ +/// + +// @noUnusedLocals: true +// @Filename: file2.ts +////[| import {/*0*/Calculator,/*1*/ test, test2} from "./file1" |] + +//// test(); +//// test2(); + +// @Filename: file1.ts +//// export class Calculator { +//// handleChar() {} +//// } + +//// export function test() { +//// +//// } + +//// export function test2() { +//// +//// } + +verify.codeFixAtPosition(`import {test, test2} from "./file1"`); + diff --git a/tests/cases/fourslash/unusedImports4FS.ts b/tests/cases/fourslash/unusedImports4FS.ts new file mode 100644 index 0000000000000..ab37928eb0164 --- /dev/null +++ b/tests/cases/fourslash/unusedImports4FS.ts @@ -0,0 +1,24 @@ +/// + +// @noUnusedLocals: true +// @Filename: file2.ts +//// [| import {Calculator/*0*/, test/*1*/, test2} from "./file1" |] +//// +//// var x = new Calculator(); +//// x.handleChar(); +//// test2(); + +// @Filename: file1.ts +//// export class Calculator { +//// handleChar() {} +//// } +//// +//// export function test() { +//// +//// } +//// +//// export function test2() { +//// +//// } + +verify.codeFixAtPosition(`import {Calculator, test2} from "./file1"`); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedImports5FS.ts b/tests/cases/fourslash/unusedImports5FS.ts new file mode 100644 index 0000000000000..1d68f6ae64383 --- /dev/null +++ b/tests/cases/fourslash/unusedImports5FS.ts @@ -0,0 +1,24 @@ +/// + +// @noUnusedLocals: true +// @Filename: file2.ts +//// [| import {Calculator, test, test2} from "./file1" |] +//// +//// var x = new Calculator(); +//// x.handleChar(); +//// test(); + +// @Filename: file1.ts +//// export class Calculator { +//// handleChar() {} +//// } +//// +//// export function test() { +//// +//// } +//// +//// export function test2() { +//// +//// } + +verify.codeFixAtPosition(`import {Calculator, test} from "./file1"`); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedImports6FS.ts b/tests/cases/fourslash/unusedImports6FS.ts new file mode 100644 index 0000000000000..c8e1af9231389 --- /dev/null +++ b/tests/cases/fourslash/unusedImports6FS.ts @@ -0,0 +1,20 @@ +/// + +// @noUnusedLocals: true +// @Filename: file2.ts +//// [| import d from "./file1" |] + +// @Filename: file1.ts +//// export class Calculator { +//// handleChar() { } +//// } + +//// export function test() { +//// +//// } + +//// export default function test2() { +//// +//// } + +verify.codeFixAtPosition(`import {} from "./file1"`); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedImports7FS.ts b/tests/cases/fourslash/unusedImports7FS.ts new file mode 100644 index 0000000000000..6dc0886e8ffbe --- /dev/null +++ b/tests/cases/fourslash/unusedImports7FS.ts @@ -0,0 +1,20 @@ +/// + +// @noUnusedLocals: true +// @Filename: file2.ts +//// [| import * as n from "./file1" |] + +// @Filename: file1.ts +//// export class Calculator { +//// handleChar() { } +//// } +//// +//// export function test() { +//// +//// } +//// +//// export default function test2() { +//// +//// } + +verify.codeFixAtPosition(`import {} from "./file1"`); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedImports8FS.ts b/tests/cases/fourslash/unusedImports8FS.ts new file mode 100644 index 0000000000000..02564e359895d --- /dev/null +++ b/tests/cases/fourslash/unusedImports8FS.ts @@ -0,0 +1,24 @@ +/// + +// @noUnusedLocals: true +// @Filename: file2.ts +//// [|import {Calculator as calc, test as t1, test2 as t2} from "./file1"|] +//// +//// var x = new calc(); +//// x.handleChar(); +//// t1(); + +// @Filename: file1.ts +//// export class Calculator { +//// handleChar() { } +//// } + +//// export function test() { +//// +//// } + +//// export function test2() { +//// +//// } + +verify.codeFixAtPosition(`import {Calculator as calc, test as t1} from "./file1"`); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedImports9FS.ts b/tests/cases/fourslash/unusedImports9FS.ts new file mode 100644 index 0000000000000..2ba30c95bb718 --- /dev/null +++ b/tests/cases/fourslash/unusedImports9FS.ts @@ -0,0 +1,20 @@ +/// + +// @noUnusedLocals: true +// @Filename: file2.ts +//// [|import c = require('./file1')|] + +// @Filename: file1.ts +//// export class Calculator { +//// handleChar() { } +//// } +//// +//// export function test() { +//// +//// } +//// +//// export function test2() { +//// +//// } + +verify.codeFixAtPosition("import {} = require('./file1')"); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedInterfaceInNamespace1.ts b/tests/cases/fourslash/unusedInterfaceInNamespace1.ts new file mode 100644 index 0000000000000..8d07a8c79121e --- /dev/null +++ b/tests/cases/fourslash/unusedInterfaceInNamespace1.ts @@ -0,0 +1,11 @@ +/// + +// @noUnusedLocals: true +//// [| namespace greeter { +//// interface interface1 { +//// } +////} |] + +verify.codeFixAtPosition(` +namespace greeter { +}`); diff --git a/tests/cases/fourslash/unusedInterfaceInNamespace2.ts b/tests/cases/fourslash/unusedInterfaceInNamespace2.ts new file mode 100644 index 0000000000000..baa46c65a0ce6 --- /dev/null +++ b/tests/cases/fourslash/unusedInterfaceInNamespace2.ts @@ -0,0 +1,12 @@ +/// + +// @noUnusedLocals: true +////namespace greeter { +//// [| export interface interface2 { +//// } +//// interface interface1 { +//// } |] +////} + +verify.codeFixAtPosition(`export interface interface2 { +}`); diff --git a/tests/cases/fourslash/unusedLocalsInFunction1.ts b/tests/cases/fourslash/unusedLocalsInFunction1.ts new file mode 100644 index 0000000000000..2edd7c176e7dd --- /dev/null +++ b/tests/cases/fourslash/unusedLocalsInFunction1.ts @@ -0,0 +1,10 @@ +/// + +// @noUnusedLocals: true +//// [| function greeter() { +//// var x = 0; +////} |] + +verify.codeFixAtPosition(` +function greeter() { +}`); diff --git a/tests/cases/fourslash/unusedLocalsInFunction2.ts b/tests/cases/fourslash/unusedLocalsInFunction2.ts new file mode 100644 index 0000000000000..b8f5a650aa7e8 --- /dev/null +++ b/tests/cases/fourslash/unusedLocalsInFunction2.ts @@ -0,0 +1,9 @@ +/// + +// @noUnusedLocals: true +////function greeter() { +//// [| var x, y = 0; |] +//// x++; +////} + +verify.codeFixAtPosition("var x;"); diff --git a/tests/cases/fourslash/unusedLocalsInFunction3.ts b/tests/cases/fourslash/unusedLocalsInFunction3.ts new file mode 100644 index 0000000000000..93303bec0e5cc --- /dev/null +++ b/tests/cases/fourslash/unusedLocalsInFunction3.ts @@ -0,0 +1,10 @@ +/// + +// @noUnusedLocals: true +////function greeter() { +//// [| var x, y = 0,z = 1; |] +//// x++; +//// z++; +////} + +verify.codeFixAtPosition("var x,z = 1;"); diff --git a/tests/cases/fourslash/unusedLocalsInFunction4.ts b/tests/cases/fourslash/unusedLocalsInFunction4.ts new file mode 100644 index 0000000000000..54d3223f23608 --- /dev/null +++ b/tests/cases/fourslash/unusedLocalsInFunction4.ts @@ -0,0 +1,10 @@ +/// + +// @noUnusedLocals: true +////function greeter() { +//// [| var x,y = 0,z = 1; |] +//// y++; +//// z++; +////} + +verify.codeFixAtPosition("var y = 0,z = 1;"); diff --git a/tests/cases/fourslash/unusedLocalsInMethodFS1.ts b/tests/cases/fourslash/unusedLocalsInMethodFS1.ts new file mode 100644 index 0000000000000..43b782ce2661a --- /dev/null +++ b/tests/cases/fourslash/unusedLocalsInMethodFS1.ts @@ -0,0 +1,12 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true +////class greeter { +//// public function1() { +//// [| var /*0*/x,/*1*/ y = 10; |] +//// y++; +//// } +////} + +verify.codeFixAtPosition("var y = 10;"); diff --git a/tests/cases/fourslash/unusedLocalsInMethodFS2.ts b/tests/cases/fourslash/unusedLocalsInMethodFS2.ts new file mode 100644 index 0000000000000..322cfad394007 --- /dev/null +++ b/tests/cases/fourslash/unusedLocalsInMethodFS2.ts @@ -0,0 +1,12 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true +////class greeter { +//// public function1() { +//// [| var x, y; |] +//// y = 1; +//// } +////} + +verify.codeFixAtPosition("var y;"); diff --git a/tests/cases/fourslash/unusedLocalsinConstructorFS1.ts b/tests/cases/fourslash/unusedLocalsinConstructorFS1.ts new file mode 100644 index 0000000000000..412b599b780a9 --- /dev/null +++ b/tests/cases/fourslash/unusedLocalsinConstructorFS1.ts @@ -0,0 +1,12 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters:true +////class greeter { +//// [| constructor() { +//// var unused = 20; +//// } |] +////} + +verify.codeFixAtPosition(`constructor() { +}`); diff --git a/tests/cases/fourslash/unusedLocalsinConstructorFS2.ts b/tests/cases/fourslash/unusedLocalsinConstructorFS2.ts new file mode 100644 index 0000000000000..eff9b7c8d54b5 --- /dev/null +++ b/tests/cases/fourslash/unusedLocalsinConstructorFS2.ts @@ -0,0 +1,18 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true +////class greeter { +//// [|constructor() { +//// var unused = 20; +//// var used = "dummy"; +//// used = used + "second part"; +//// }|] +////} + +verify.codeFixAtPosition(` + constructor() { + var used = "dummy"; + used = used + "second part"; + } +`); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedMethodInClass1.ts b/tests/cases/fourslash/unusedMethodInClass1.ts new file mode 100644 index 0000000000000..7795a4d15303e --- /dev/null +++ b/tests/cases/fourslash/unusedMethodInClass1.ts @@ -0,0 +1,11 @@ +/// + +// @noUnusedLocals: true +////[| class greeter { +//// private function1() { +//// } +////} |] + +verify.codeFixAtPosition(` +class greeter { +}`); diff --git a/tests/cases/fourslash/unusedMethodInClass2.ts b/tests/cases/fourslash/unusedMethodInClass2.ts new file mode 100644 index 0000000000000..24b6fe155efb5 --- /dev/null +++ b/tests/cases/fourslash/unusedMethodInClass2.ts @@ -0,0 +1,15 @@ +/// + +// @noUnusedLocals: true +//// [| class greeter { +//// public function2() { +//// } +//// private function1() { +//// } +////} |] + +verify.codeFixAtPosition(` +class greeter { + public function2() { + } +}`); diff --git a/tests/cases/fourslash/unusedMethodInClass3.ts b/tests/cases/fourslash/unusedMethodInClass3.ts new file mode 100644 index 0000000000000..eab535fb5af66 --- /dev/null +++ b/tests/cases/fourslash/unusedMethodInClass3.ts @@ -0,0 +1,11 @@ +/// + +// @noUnusedLocals: true +////[|class greeter { +//// private function1 = function() { +//// } +////} |] + +verify.codeFixAtPosition(` +class greeter { +}`); diff --git a/tests/cases/fourslash/unusedMethodInClass4.ts b/tests/cases/fourslash/unusedMethodInClass4.ts new file mode 100644 index 0000000000000..ee27ec331eb84 --- /dev/null +++ b/tests/cases/fourslash/unusedMethodInClass4.ts @@ -0,0 +1,12 @@ +/// + +// @noUnusedLocals: true +////class greeter { +//// [|public function2(){ +//// } +//// private function1 = function() { +//// } |] +////} + +verify.codeFixAtPosition(`public function2(){ +}`); diff --git a/tests/cases/fourslash/unusedNamespaceInNamespace.ts b/tests/cases/fourslash/unusedNamespaceInNamespace.ts new file mode 100644 index 0000000000000..41fe162ef1564 --- /dev/null +++ b/tests/cases/fourslash/unusedNamespaceInNamespace.ts @@ -0,0 +1,13 @@ +/// + +// @noUnusedLocals: true +//// [|namespace A { +//// namespace B { +//// } +//// }|] + +verify.codeFixAtPosition(` +namespace A { +} +`); + diff --git a/tests/cases/fourslash/unusedParameterInConstructor1.ts b/tests/cases/fourslash/unusedParameterInConstructor1.ts new file mode 100644 index 0000000000000..f53c6d3e8bdde --- /dev/null +++ b/tests/cases/fourslash/unusedParameterInConstructor1.ts @@ -0,0 +1,8 @@ +/// + +// @noUnusedLocals: true +//// class C1 { +//// [|constructor(private p1: string, public p2: boolean, public p3: any, p5)|] { p5; } +//// } + +verify.codeFixAtPosition("constructor(public p2: boolean, public p3: any, p5)"); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedParameterInFunction1.ts b/tests/cases/fourslash/unusedParameterInFunction1.ts new file mode 100644 index 0000000000000..2243af9f5f553 --- /dev/null +++ b/tests/cases/fourslash/unusedParameterInFunction1.ts @@ -0,0 +1,7 @@ +/// + +// @noUnusedParameters: true +////function [|greeter( x)|] { +////} + +verify.codeFixAtPosition("greeter()"); diff --git a/tests/cases/fourslash/unusedParameterInFunction2.ts b/tests/cases/fourslash/unusedParameterInFunction2.ts new file mode 100644 index 0000000000000..493eafc572223 --- /dev/null +++ b/tests/cases/fourslash/unusedParameterInFunction2.ts @@ -0,0 +1,8 @@ +/// + +// @noUnusedParameters: true +////function [|greeter(x,y)|] { +//// x++; +////} + +verify.codeFixAtPosition("greeter(x)"); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedParameterInFunction3.ts b/tests/cases/fourslash/unusedParameterInFunction3.ts new file mode 100644 index 0000000000000..6d79ba071b450 --- /dev/null +++ b/tests/cases/fourslash/unusedParameterInFunction3.ts @@ -0,0 +1,8 @@ +/// + +// @noUnusedParameters: true +////function [|greeter(x,y)|] { +//// y++; +////} + +verify.codeFixAtPosition("greeter(y)"); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedParameterInFunction4.ts b/tests/cases/fourslash/unusedParameterInFunction4.ts new file mode 100644 index 0000000000000..b536543fb6d59 --- /dev/null +++ b/tests/cases/fourslash/unusedParameterInFunction4.ts @@ -0,0 +1,9 @@ +/// + +// @noUnusedParameters: true +////[|function greeter(x,y,z) |] { +//// x++; +//// z++; +////} + +verify.codeFixAtPosition("function greeter(x,z)"); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedParameterInLambda1.ts b/tests/cases/fourslash/unusedParameterInLambda1.ts new file mode 100644 index 0000000000000..c462b7425694d --- /dev/null +++ b/tests/cases/fourslash/unusedParameterInLambda1.ts @@ -0,0 +1,9 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true +//// function f1() { +//// [|return (x:number) => {}|] +//// } + +verify.codeFixAtPosition("return () => {}"); diff --git a/tests/cases/fourslash/unusedTypeParametersInClass1.ts b/tests/cases/fourslash/unusedTypeParametersInClass1.ts new file mode 100644 index 0000000000000..ab654a5150e73 --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInClass1.ts @@ -0,0 +1,7 @@ +/// + +// @noUnusedLocals: true +////[|class greeter |] { +////} + +verify.codeFixAtPosition("class greeter"); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedTypeParametersInClass2.ts b/tests/cases/fourslash/unusedTypeParametersInClass2.ts new file mode 100644 index 0000000000000..8e860c10e049b --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInClass2.ts @@ -0,0 +1,8 @@ +/// + +// @noUnusedLocals: true +////[|class greeter |] { +//// public a: X; +////} + +verify.codeFixAtPosition("class greeter"); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedTypeParametersInClass3.ts b/tests/cases/fourslash/unusedTypeParametersInClass3.ts new file mode 100644 index 0000000000000..75ae98f53e0ed --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInClass3.ts @@ -0,0 +1,9 @@ +/// + +// @noUnusedLocals: true +////[|class greeter |] { +//// public a: X; +//// public b: Z; +////} + +verify.codeFixAtPosition("class greeter"); diff --git a/tests/cases/fourslash/unusedTypeParametersInFunction1.ts b/tests/cases/fourslash/unusedTypeParametersInFunction1.ts new file mode 100644 index 0000000000000..7177ed41c8445 --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInFunction1.ts @@ -0,0 +1,6 @@ +/// + +// @noUnusedLocals: true +//// [|function f1() {}|] + +verify.codeFixAtPosition("function f1() {}"); diff --git a/tests/cases/fourslash/unusedTypeParametersInFunction2.ts b/tests/cases/fourslash/unusedTypeParametersInFunction2.ts new file mode 100644 index 0000000000000..344ae303c75df --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInFunction2.ts @@ -0,0 +1,6 @@ +/// + +// @noUnusedLocals: true +//// [|function f1(a: X) {a}|] + +verify.codeFixAtPosition("function f1(a: X) {a}"); diff --git a/tests/cases/fourslash/unusedTypeParametersInFunction3.ts b/tests/cases/fourslash/unusedTypeParametersInFunction3.ts new file mode 100644 index 0000000000000..746b174db18d9 --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInFunction3.ts @@ -0,0 +1,6 @@ +/// + +// @noUnusedLocals: true +//// [|function f1(a: X) {a;var b:Z;b}|] + +verify.codeFixAtPosition("function f1(a: X) {a;var b:Z;b}"); diff --git a/tests/cases/fourslash/unusedTypeParametersInInterface1.ts b/tests/cases/fourslash/unusedTypeParametersInInterface1.ts new file mode 100644 index 0000000000000..70d8bc7800cd8 --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInInterface1.ts @@ -0,0 +1,7 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true +//// [|interface I {}|] + +verify.codeFixAtPosition("interface I {}"); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedTypeParametersInLambda1.ts b/tests/cases/fourslash/unusedTypeParametersInLambda1.ts new file mode 100644 index 0000000000000..73d7067236850 --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInLambda1.ts @@ -0,0 +1,9 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true +//// function f1() { +//// [|return (x:number) => {x}|] +//// } + +verify.codeFixAtPosition("return (x:number) => {x}"); diff --git a/tests/cases/fourslash/unusedTypeParametersInLambda2.ts b/tests/cases/fourslash/unusedTypeParametersInLambda2.ts new file mode 100644 index 0000000000000..77c802f5c44f3 --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInLambda2.ts @@ -0,0 +1,9 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true +//// var x : { +//// [|new (a: T): void;|] +//// } + +verify.codeFixAtPosition("new (a: T): void;"); diff --git a/tests/cases/fourslash/unusedTypeParametersInLambda3.ts b/tests/cases/fourslash/unusedTypeParametersInLambda3.ts new file mode 100644 index 0000000000000..0ecb0338be2ce --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInLambda3.ts @@ -0,0 +1,10 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true +//// class A { public x: Dummy } +//// var x : { +//// [|new (a: T): A;|] +//// } + +verify.codeFixAtPosition("new (a: T): A;"); diff --git a/tests/cases/fourslash/unusedTypeParametersInLambda4.ts b/tests/cases/fourslash/unusedTypeParametersInLambda4.ts new file mode 100644 index 0000000000000..5a226fc9005ef --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInLambda4.ts @@ -0,0 +1,9 @@ +/// + +// @noUnusedLocals: true +//// class A { +//// public x: T; +//// } +//// [|var y: new (a:T)=>void;|] + +verify.codeFixAtPosition("var y: new (a:T)=>void;"); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedTypeParametersInMethod1.ts b/tests/cases/fourslash/unusedTypeParametersInMethod1.ts new file mode 100644 index 0000000000000..7a9f04147d617 --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInMethod1.ts @@ -0,0 +1,8 @@ +/// + +// @noUnusedLocals: true +//// class C1 { +//// [|f1()|] {} +//// } + +verify.codeFixAtPosition("f1()"); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedTypeParametersInMethod2.ts b/tests/cases/fourslash/unusedTypeParametersInMethod2.ts new file mode 100644 index 0000000000000..3650cfbad98a0 --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInMethod2.ts @@ -0,0 +1,8 @@ +/// + +// @noUnusedLocals: true +//// class C1 { +//// [|f1(a: U)|] {a;} +//// } + +verify.codeFixAtPosition("f1(a: U)"); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedTypeParametersInMethods1.ts b/tests/cases/fourslash/unusedTypeParametersInMethods1.ts new file mode 100644 index 0000000000000..cb9b965ca4d45 --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInMethods1.ts @@ -0,0 +1,8 @@ +/// + +// @noUnusedLocals: true +//// class A { +//// [|public f1(a: X)|] { a; var b: Z; b } +//// } + +verify.codeFixAtPosition("public f1(a: X)"); diff --git a/tests/cases/fourslash/unusedVariableInBlocks.ts b/tests/cases/fourslash/unusedVariableInBlocks.ts new file mode 100644 index 0000000000000..e9dedaef31eb0 --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInBlocks.ts @@ -0,0 +1,15 @@ +/// + +// @noUnusedLocals: true +//// function f1 () { +//// [|let x = 10; +//// { +//// let x = 11; +//// } +//// x;|] +//// } + +verify.codeFixAtPosition(`let x = 10; + { + } + x;`); diff --git a/tests/cases/fourslash/unusedVariableInClass1.ts b/tests/cases/fourslash/unusedVariableInClass1.ts new file mode 100644 index 0000000000000..82bb99016efd5 --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInClass1.ts @@ -0,0 +1,8 @@ +/// + +// @noUnusedLocals: true +////class greeter { +//// [|private greeting: string;|] +////} + +verify.codeFixAtPosition(""); diff --git a/tests/cases/fourslash/unusedVariableInClass2.ts b/tests/cases/fourslash/unusedVariableInClass2.ts new file mode 100644 index 0000000000000..c971092584a53 --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInClass2.ts @@ -0,0 +1,9 @@ +/// + +// @noUnusedLocals: true +////class greeter { +//// [|public greeting1; +//// private greeting: string;|] +////} + +verify.codeFixAtPosition("public greeting1;"); diff --git a/tests/cases/fourslash/unusedVariableInClass3.ts b/tests/cases/fourslash/unusedVariableInClass3.ts new file mode 100644 index 0000000000000..8d2a62e7175b9 --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInClass3.ts @@ -0,0 +1,8 @@ +/// + +// @noUnusedLocals: true +////class greeter {[| +//// private X = function() {}; +////|]} + +verify.codeFixAtPosition(""); diff --git a/tests/cases/fourslash/unusedVariableInForLoop1FS.ts b/tests/cases/fourslash/unusedVariableInForLoop1FS.ts new file mode 100644 index 0000000000000..0ee02ab43632d --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInForLoop1FS.ts @@ -0,0 +1,11 @@ +/// + +// @noUnusedLocals: true +//// function f1 () { +//// [|for(var i = 0; ;) |]{ +//// +//// } +//// } + +verify.codeFixAtPosition("for(; ;)"); + diff --git a/tests/cases/fourslash/unusedVariableInForLoop2FS.ts b/tests/cases/fourslash/unusedVariableInForLoop2FS.ts new file mode 100644 index 0000000000000..1b1a0798c0445 --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInForLoop2FS.ts @@ -0,0 +1,10 @@ +/// + +// @noUnusedLocals: true +//// function f1 () { +//// [|for(var i = 0, j= 0; ;i++)|] { +//// +//// } +//// } + +verify.codeFixAtPosition("for(var i = 0; ;i++)"); diff --git a/tests/cases/fourslash/unusedVariableInForLoop3FS.ts b/tests/cases/fourslash/unusedVariableInForLoop3FS.ts new file mode 100644 index 0000000000000..4eed9599b1513 --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInForLoop3FS.ts @@ -0,0 +1,10 @@ +/// + +// @noUnusedLocals: true +//// function f1 () { +//// [|for(var i = 0, j= 0, k=0; ;i++, k++)|] { +//// +//// } +//// } + +verify.codeFixAtPosition("for(var i = 0, k=0; ;i++,k++)"); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedVariableInForLoop4FS.ts b/tests/cases/fourslash/unusedVariableInForLoop4FS.ts new file mode 100644 index 0000000000000..76e551612ba79 --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInForLoop4FS.ts @@ -0,0 +1,10 @@ +/// + +// @noUnusedLocals: true +//// function f1 () { +//// [|for(var i = 0, j= 0, k=0; ;j++, k++) |]{ +//// +//// } +//// } + +verify.codeFixAtPosition("for(var j = 0, k=0; ;j++,k++)"); diff --git a/tests/cases/fourslash/unusedVariableInForLoop5FS.ts b/tests/cases/fourslash/unusedVariableInForLoop5FS.ts new file mode 100644 index 0000000000000..60369da522d17 --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInForLoop5FS.ts @@ -0,0 +1,11 @@ +/// + +// @noUnusedLocals: true +//// function f1 () { +//// for ([|const elem in|] ["a", "b", "c"]) { +//// +//// } +//// } + +verify.codeFixAtPosition("const {} in "); + diff --git a/tests/cases/fourslash/unusedVariableInForLoop6FS.ts b/tests/cases/fourslash/unusedVariableInForLoop6FS.ts new file mode 100644 index 0000000000000..4187c3141b547 --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInForLoop6FS.ts @@ -0,0 +1,11 @@ +/// + +// @noUnusedLocals: true +//// function f1 () { +//// for ([|const elem of|] ["a", "b", "c"]) { +//// +//// } +//// } + +verify.codeFixAtPosition("const {} of "); + diff --git a/tests/cases/fourslash/unusedVariableInForLoop7FS.ts b/tests/cases/fourslash/unusedVariableInForLoop7FS.ts new file mode 100644 index 0000000000000..8fd0fee735e27 --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInForLoop7FS.ts @@ -0,0 +1,12 @@ +/// + +// @noUnusedLocals: true +//// function f1 () { +//// for (const elem of ["a", "b", "c"]) { +//// elem; +//// [|var x = 20;|] +//// } +////} +//// + +verify.codeFixAtPosition(""); diff --git a/tests/cases/fourslash/unusedVariableInModule1.ts b/tests/cases/fourslash/unusedVariableInModule1.ts new file mode 100644 index 0000000000000..011434ce098df --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInModule1.ts @@ -0,0 +1,9 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true +//// export {} +//// [|var x: string;|] +//// export var y: string; + +verify.codeFixAtPosition(""); diff --git a/tests/cases/fourslash/unusedVariableInModule2.ts b/tests/cases/fourslash/unusedVariableInModule2.ts new file mode 100644 index 0000000000000..09108ab1ee0f9 --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInModule2.ts @@ -0,0 +1,10 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true +//// export {} +//// [|var x: string, y: number;|] +//// y; +//// export var y: string; + +verify.codeFixAtPosition("var y: number;", 6133); diff --git a/tests/cases/fourslash/unusedVariableInModule3.ts b/tests/cases/fourslash/unusedVariableInModule3.ts new file mode 100644 index 0000000000000..bffffc768d355 --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInModule3.ts @@ -0,0 +1,9 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true +//// export {} +//// [|var x = function f1() {}|] +//// export var y: string; + +verify.codeFixAtPosition(""); diff --git a/tests/cases/fourslash/unusedVariableInModule4.ts b/tests/cases/fourslash/unusedVariableInModule4.ts new file mode 100644 index 0000000000000..6a1be9fe5b89a --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInModule4.ts @@ -0,0 +1,10 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true +//// export {} +//// [|var x = function f1(m: number) {}|] +//// x; +//// export var y: string; + +verify.codeFixAtPosition(`var x = function f1() {}`); diff --git a/tests/cases/fourslash/unusedVariableInNamespace1.ts b/tests/cases/fourslash/unusedVariableInNamespace1.ts new file mode 100644 index 0000000000000..caf778bc0da76 --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInNamespace1.ts @@ -0,0 +1,8 @@ +/// + +// @noUnusedLocals: true +////namespace greeter { +//// [|let a = "dummy entry";|] +////} + +verify.codeFixAtPosition(""); diff --git a/tests/cases/fourslash/unusedVariableInNamespace2.ts b/tests/cases/fourslash/unusedVariableInNamespace2.ts new file mode 100644 index 0000000000000..fbb9e2d6a0c2b --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInNamespace2.ts @@ -0,0 +1,12 @@ +/// + +// @noUnusedLocals: true +////namespace greeter { +//// [|let a = "dummy entry", b, c = 0;|] +//// export function function1() { +//// a = "dummy"; +//// c++; +//// } +////} + +verify.codeFixAtPosition(`let a = "dummy entry", c = 0;`); diff --git a/tests/cases/fourslash/unusedVariableInNamespace3.ts b/tests/cases/fourslash/unusedVariableInNamespace3.ts new file mode 100644 index 0000000000000..33e501d0c0def --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInNamespace3.ts @@ -0,0 +1,12 @@ +/// + +// @noUnusedLocals: true +////namespace greeter { +//// [|let a = "dummy entry", b, c = 0;|] +//// export function function1() { +//// a = "dummy"; +//// b = 0; +//// } +////} + +verify.codeFixAtPosition(`let a = "dummy entry", b;`);