Merge pull request #14568 from Microsoft/checkJSFiles_QuickFixes
Allow skipping diagnostics in .js file using comments and quick fixes to add them
This commit is contained in:
commit
1fbbeadaf7
|
@ -945,7 +945,7 @@ task("generate-code-coverage", ["tests", builtLocalDirectory], function () {
|
|||
// Browser tests
|
||||
var nodeServerOutFile = "tests/webTestServer.js";
|
||||
var nodeServerInFile = "tests/webTestServer.ts";
|
||||
compileFile(nodeServerOutFile, [nodeServerInFile], [builtLocalDirectory, tscFile], [], /*useBuiltCompiler:*/ true, { noOutFile: true });
|
||||
compileFile(nodeServerOutFile, [nodeServerInFile], [builtLocalDirectory, tscFile], [], /*useBuiltCompiler:*/ true, { noOutFile: true, lib: "es6" });
|
||||
|
||||
desc("Runs browserify on run.js to produce a file suitable for running tests in the browser");
|
||||
task("browserify", ["tests", builtLocalDirectory, nodeServerOutFile], function() {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
{
|
||||
"Unterminated string literal.": {
|
||||
"category": "Error",
|
||||
"code": 1002
|
||||
|
@ -3355,6 +3355,24 @@
|
|||
"category": "Message",
|
||||
"code": 90017
|
||||
},
|
||||
"Disable checking for this file.": {
|
||||
"category": "Message",
|
||||
"code": 90018
|
||||
},
|
||||
"Suppress this error message.": {
|
||||
"category": "Message",
|
||||
"code": 90019
|
||||
},
|
||||
"Initialize property '{0}' in the constructor.": {
|
||||
"category": "Message",
|
||||
"code": 90020
|
||||
},
|
||||
"Initialize static property '{0}'.": {
|
||||
"category": "Message",
|
||||
"code": 90021
|
||||
},
|
||||
|
||||
|
||||
"Octal literal types must use ES2015 syntax. Use the syntax '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 8017
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
namespace ts {
|
||||
const emptyArray: any[] = [];
|
||||
const suppressDiagnosticCommentRegEx = /(^\s*$)|(^\s*\/\/\/?\s*(@ts-suppress)?)/;
|
||||
|
||||
export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName = "tsconfig.json"): string {
|
||||
while (true) {
|
||||
|
@ -923,10 +924,36 @@ namespace ts {
|
|||
const fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName);
|
||||
const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName);
|
||||
|
||||
return bindDiagnostics.concat(checkDiagnostics, fileProcessingDiagnosticsInFile, programDiagnosticsInFile);
|
||||
const diagnostics = bindDiagnostics.concat(checkDiagnostics, fileProcessingDiagnosticsInFile, programDiagnosticsInFile);
|
||||
return isSourceFileJavaScript(sourceFile)
|
||||
? filter(diagnostics, shouldReportDiagnostic)
|
||||
: diagnostics;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip errors if previous line start with '// @ts-suppress' comment, not counting non-empty non-comment lines
|
||||
*/
|
||||
function shouldReportDiagnostic(diagnostic: Diagnostic) {
|
||||
const { file, start } = diagnostic;
|
||||
const lineStarts = getLineStarts(file);
|
||||
let { line } = computeLineAndCharacterOfPosition(lineStarts, start);
|
||||
while (line > 0) {
|
||||
const previousLineText = file.text.slice(lineStarts[line - 1], lineStarts[line]);
|
||||
const result = suppressDiagnosticCommentRegEx.exec(previousLineText);
|
||||
if (!result) {
|
||||
// non-empty line
|
||||
return true;
|
||||
}
|
||||
if (result[3]) {
|
||||
// @ts-suppress
|
||||
return false;
|
||||
}
|
||||
line--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function getJavaScriptSyntacticDiagnosticsForFile(sourceFile: SourceFile): Diagnostic[] {
|
||||
return runWithCancellationToken(() => {
|
||||
const diagnostics: Diagnostic[] = [];
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -2550,6 +2550,11 @@ namespace FourSlash {
|
|||
}
|
||||
}
|
||||
|
||||
public printAvailableCodeFixes() {
|
||||
const codeFixes = this.getCodeFixActions(this.activeFile.fileName);
|
||||
Harness.IO.log(stringify(codeFixes));
|
||||
}
|
||||
|
||||
// Get the text of the entire line the caret is currently at
|
||||
private getCurrentLineContent() {
|
||||
const text = this.getFileContent(this.activeFile.fileName);
|
||||
|
@ -3738,6 +3743,10 @@ namespace FourSlashInterface {
|
|||
this.state.printCompletionListMembers();
|
||||
}
|
||||
|
||||
public printAvailableCodeFixes() {
|
||||
this.state.printAvailableCodeFixes();
|
||||
}
|
||||
|
||||
public printBreakpointLocation(pos: number) {
|
||||
this.state.printBreakpointLocation(pos);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
{
|
||||
"extends": "../tsconfig-base",
|
||||
"compilerOptions": {
|
||||
"removeComments": false,
|
||||
|
@ -81,6 +81,7 @@
|
|||
"../services/codefixes/helpers.ts",
|
||||
"../services/codefixes/importFixes.ts",
|
||||
"../services/codefixes/unusedIdentifierFixes.ts",
|
||||
"../services/codefixes/disableJsDiagnostics.ts",
|
||||
|
||||
"harness.ts",
|
||||
"sourceMapRecorder.ts",
|
||||
|
|
74
src/services/codefixes/disableJsDiagnostics.ts
Normal file
74
src/services/codefixes/disableJsDiagnostics.ts
Normal file
|
@ -0,0 +1,74 @@
|
|||
/* @internal */
|
||||
namespace ts.codefix {
|
||||
registerCodeFix({
|
||||
errorCodes: getApplicableDiagnosticCodes(),
|
||||
getCodeActions: getDisableJsDiagnosticsCodeActions
|
||||
});
|
||||
|
||||
function getApplicableDiagnosticCodes(): number[] {
|
||||
const allDiagnostcs = <MapLike<DiagnosticMessage>>Diagnostics;
|
||||
return Object.keys(allDiagnostcs)
|
||||
.filter(d => allDiagnostcs[d] && allDiagnostcs[d].category === DiagnosticCategory.Error)
|
||||
.map(d => allDiagnostcs[d].code);
|
||||
}
|
||||
|
||||
function shouldCheckJsFile(sourceFile: SourceFile, compilerOptions: CompilerOptions) {
|
||||
return sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : compilerOptions.checkJs;
|
||||
}
|
||||
|
||||
function getSuppressCommentLocationForLocation(sourceFile: SourceFile, position: number, newLineCharacter: string) {
|
||||
let { line } = getLineAndCharacterOfPosition(sourceFile, position);
|
||||
const lineStartPosition = getStartPositionOfLine(line, sourceFile);
|
||||
const startPosition = getFirstNonSpaceCharacterPosition(sourceFile.text, lineStartPosition);
|
||||
|
||||
// First try to see if we can put the '// @ts-suppress' on the previous line.
|
||||
// We need to make sure that we are not in the middle of a string literal or a comment.
|
||||
// We also want to check if the previous line holds a comment for a node on the next line
|
||||
// if so, we do not want to separate the node from its comment if we can.
|
||||
if (!isInComment(sourceFile, startPosition) && !isInString(sourceFile, startPosition) && !isInTemplateString(sourceFile, startPosition)) {
|
||||
const token = getTouchingToken(sourceFile, startPosition);
|
||||
const tokenLeadingCommnets = getLeadingCommentRangesOfNode(token, sourceFile);
|
||||
if (!tokenLeadingCommnets || !tokenLeadingCommnets.length || tokenLeadingCommnets[0].pos >= startPosition) {
|
||||
return {
|
||||
span: { start: startPosition, length: 0 },
|
||||
newText: `// @ts-suppress${newLineCharacter}`
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// If all fails, add an extra new line immediatlly before the error span.
|
||||
return {
|
||||
span: { start: position, length: 0 },
|
||||
newText: `${position === startPosition ? "" : newLineCharacter}// @ts-suppress${newLineCharacter}`
|
||||
};
|
||||
}
|
||||
|
||||
function getDisableJsDiagnosticsCodeActions(context: CodeFixContext): CodeAction[] | undefined {
|
||||
const { sourceFile, program, newLineCharacter, span } = context;
|
||||
|
||||
if (!isInJavaScriptFile(sourceFile) || !shouldCheckJsFile(sourceFile, program.getCompilerOptions())) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return [{
|
||||
description: getLocaleSpecificMessage(Diagnostics.Suppress_this_error_message),
|
||||
changes: [{
|
||||
fileName: sourceFile.fileName,
|
||||
textChanges: [getSuppressCommentLocationForLocation(sourceFile, span.start, newLineCharacter)]
|
||||
}]
|
||||
},
|
||||
{
|
||||
description: getLocaleSpecificMessage(Diagnostics.Disable_checking_for_this_file),
|
||||
changes: [{
|
||||
fileName: sourceFile.fileName,
|
||||
textChanges: [{
|
||||
span: {
|
||||
start: sourceFile.checkJsDirective ? sourceFile.checkJsDirective.pos : 0,
|
||||
length: sourceFile.checkJsDirective ? sourceFile.checkJsDirective.end - sourceFile.checkJsDirective.pos : 0
|
||||
},
|
||||
newText: `// @ts-nocheck${newLineCharacter}`
|
||||
}]
|
||||
}]
|
||||
}];
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/* @internal */
|
||||
/* @internal */
|
||||
namespace ts.codefix {
|
||||
registerCodeFix({
|
||||
errorCodes: [Diagnostics.Property_0_does_not_exist_on_type_1.code],
|
||||
|
@ -13,55 +13,106 @@ namespace ts.codefix {
|
|||
// this.missing = 1;
|
||||
// ^^^^^^^
|
||||
const token = getTokenAtPosition(sourceFile, start);
|
||||
|
||||
if (token.kind != SyntaxKind.Identifier) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const classDeclaration = getContainingClass(token);
|
||||
if (!classDeclaration) {
|
||||
if (!isPropertyAccessExpression(token.parent) || token.parent.expression.kind !== SyntaxKind.ThisKeyword) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (!(token.parent && token.parent.kind === SyntaxKind.PropertyAccessExpression)) {
|
||||
const classMemberDeclaration = getThisContainer(token, /*includeArrowFunctions*/ false);
|
||||
if (!isClassElement(classMemberDeclaration)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if ((token.parent as PropertyAccessExpression).expression.kind !== SyntaxKind.ThisKeyword) {
|
||||
const classDeclaration = <ClassLikeDeclaration>classMemberDeclaration.parent;
|
||||
if (!classDeclaration || !isClassLike(classDeclaration)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let typeString = "any";
|
||||
const isStatic = hasModifier(getThisContainer(token, /*includeArrowFunctions*/ false), ModifierFlags.Static);
|
||||
|
||||
if (token.parent.parent.kind === SyntaxKind.BinaryExpression) {
|
||||
const binaryExpression = token.parent.parent as BinaryExpression;
|
||||
return isInJavaScriptFile(sourceFile) ? getActionsForAddMissingMemberInJavaScriptFile() : getActionsForAddMissingMemberInTypeScriptFile();
|
||||
|
||||
const checker = context.program.getTypeChecker();
|
||||
const widenedType = checker.getWidenedType(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(binaryExpression.right)));
|
||||
typeString = checker.typeToString(widenedType);
|
||||
}
|
||||
function getActionsForAddMissingMemberInTypeScriptFile(): CodeAction[] | undefined {
|
||||
let typeString = "any";
|
||||
|
||||
const startPos = classDeclaration.members.pos;
|
||||
if (token.parent.parent.kind === SyntaxKind.BinaryExpression) {
|
||||
const binaryExpression = token.parent.parent as BinaryExpression;
|
||||
|
||||
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};`
|
||||
const checker = context.program.getTypeChecker();
|
||||
const widenedType = checker.getWidenedType(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(binaryExpression.right)));
|
||||
typeString = checker.typeToString(widenedType);
|
||||
}
|
||||
|
||||
const startPos = classDeclaration.members.pos;
|
||||
|
||||
const actions = [{
|
||||
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_declaration_for_missing_property_0), [token.getText()]),
|
||||
changes: [{
|
||||
fileName: sourceFile.fileName,
|
||||
textChanges: [{
|
||||
span: { start: startPos, length: 0 },
|
||||
newText: `${isStatic ? "static " : ""}${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};`
|
||||
}]
|
||||
}]
|
||||
}];
|
||||
}];
|
||||
|
||||
if (!isStatic) {
|
||||
actions.push({
|
||||
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_index_signature_for_missing_property_0), [token.getText()]),
|
||||
changes: [{
|
||||
fileName: sourceFile.fileName,
|
||||
textChanges: [{
|
||||
span: { start: startPos, length: 0 },
|
||||
newText: `[x: string]: ${typeString};`
|
||||
}]
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
function getActionsForAddMissingMemberInJavaScriptFile(): CodeAction[] | undefined {
|
||||
const memberName = token.getText();
|
||||
|
||||
if (isStatic) {
|
||||
if (classDeclaration.kind === SyntaxKind.ClassExpression) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const className = classDeclaration.name.getText();
|
||||
|
||||
return [{
|
||||
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Initialize_static_property_0), [memberName]),
|
||||
changes: [{
|
||||
fileName: sourceFile.fileName,
|
||||
textChanges: [{
|
||||
span: { start: classDeclaration.getEnd(), length: 0 },
|
||||
newText: `${context.newLineCharacter}${className}.${memberName} = undefined;${context.newLineCharacter}`
|
||||
}]
|
||||
}]
|
||||
}];
|
||||
}
|
||||
else {
|
||||
const classConstructor = getFirstConstructorWithBody(classDeclaration);
|
||||
if (!classConstructor) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return [{
|
||||
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Initialize_property_0_in_the_constructor), [memberName]),
|
||||
changes: [{
|
||||
fileName: sourceFile.fileName,
|
||||
textChanges: [{
|
||||
span: { start: classConstructor.body.getEnd() - 1, length: 0 },
|
||||
newText: `this.${memberName} = undefined;${context.newLineCharacter}`
|
||||
}]
|
||||
}]
|
||||
}];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,4 +7,5 @@
|
|||
/// <reference path="fixForgottenThisPropertyAccess.ts" />
|
||||
/// <reference path='unusedIdentifierFixes.ts' />
|
||||
/// <reference path='importFixes.ts' />
|
||||
/// <reference path='disableJsDiagnostics.ts' />
|
||||
/// <reference path='helpers.ts' />
|
||||
|
|
|
@ -105,9 +105,10 @@ namespace ts.codefix {
|
|||
else {
|
||||
// import |d,| * as ns from './file'
|
||||
const start = importClause.name.getStart();
|
||||
let end = findFirstNonSpaceCharPosStarting(importClause.name.end);
|
||||
const text = sourceFile.text;
|
||||
let end = getFirstNonSpaceCharacterPosition(text, importClause.name.end);
|
||||
if (sourceFile.text.charCodeAt(end) === CharacterCodes.comma) {
|
||||
end = findFirstNonSpaceCharPosStarting(end + 1);
|
||||
end = getFirstNonSpaceCharacterPosition(text, end + 1);
|
||||
}
|
||||
|
||||
return createCodeFix("", start, end - start);
|
||||
|
@ -166,13 +167,6 @@ namespace ts.codefix {
|
|||
return createCodeFix("", start, end - start);
|
||||
}
|
||||
|
||||
function findFirstNonSpaceCharPosStarting(start: number) {
|
||||
while (isWhiteSpace(sourceFile.text.charCodeAt(start))) {
|
||||
start += 1;
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
function createCodeFix(newText: string, start: number, length: number): CodeAction[] {
|
||||
return [{
|
||||
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Remove_declaration_for_Colon_0), { 0: token.getText() }),
|
||||
|
|
|
@ -90,6 +90,7 @@
|
|||
"codefixes/fixes.ts",
|
||||
"codefixes/helpers.ts",
|
||||
"codefixes/importFixes.ts",
|
||||
"codefixes/unusedIdentifierFixes.ts"
|
||||
"codefixes/unusedIdentifierFixes.ts",
|
||||
"codefixes/disableJsDiagnostics.ts"
|
||||
]
|
||||
}
|
|
@ -1388,4 +1388,11 @@ namespace ts {
|
|||
// First token is the open curly, this is where we want to put the 'super' call.
|
||||
return constructor.body.getFirstToken(sourceFile).getEnd();
|
||||
}
|
||||
|
||||
export function getFirstNonSpaceCharacterPosition(text: string, position: number) {
|
||||
while (isWhiteSpace(text.charCodeAt(position))) {
|
||||
position += 1;
|
||||
}
|
||||
return position;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
=== tests/cases/compiler/a.js ===
|
||||
|
||||
var x = 0;
|
||||
>x : Symbol(x, Decl(a.js, 1, 3))
|
||||
|
||||
|
||||
/// @ts-suppress
|
||||
x();
|
||||
>x : Symbol(x, Decl(a.js, 1, 3))
|
||||
|
||||
/// @ts-suppress
|
||||
x();
|
||||
>x : Symbol(x, Decl(a.js, 1, 3))
|
||||
|
||||
/// @ts-suppress
|
||||
x(
|
||||
>x : Symbol(x, Decl(a.js, 1, 3))
|
||||
|
||||
2,
|
||||
3);
|
||||
|
||||
|
||||
|
||||
// @ts-suppress
|
||||
// come comment
|
||||
// some other comment
|
||||
|
||||
// @anohter
|
||||
|
||||
x();
|
||||
>x : Symbol(x, Decl(a.js, 1, 3))
|
||||
|
||||
|
||||
|
||||
// @ts-suppress: no call signature
|
||||
x();
|
||||
>x : Symbol(x, Decl(a.js, 1, 3))
|
||||
|
47
tests/baselines/reference/checkJsFiles_skipDiagnostics.types
Normal file
47
tests/baselines/reference/checkJsFiles_skipDiagnostics.types
Normal file
|
@ -0,0 +1,47 @@
|
|||
=== tests/cases/compiler/a.js ===
|
||||
|
||||
var x = 0;
|
||||
>x : number
|
||||
>0 : 0
|
||||
|
||||
|
||||
/// @ts-suppress
|
||||
x();
|
||||
>x() : any
|
||||
>x : number
|
||||
|
||||
/// @ts-suppress
|
||||
x();
|
||||
>x() : any
|
||||
>x : number
|
||||
|
||||
/// @ts-suppress
|
||||
x(
|
||||
>x( 2, 3) : any
|
||||
>x : number
|
||||
|
||||
2,
|
||||
>2 : 2
|
||||
|
||||
3);
|
||||
>3 : 3
|
||||
|
||||
|
||||
|
||||
// @ts-suppress
|
||||
// come comment
|
||||
// some other comment
|
||||
|
||||
// @anohter
|
||||
|
||||
x();
|
||||
>x() : any
|
||||
>x : number
|
||||
|
||||
|
||||
|
||||
// @ts-suppress: no call signature
|
||||
x();
|
||||
>x() : any
|
||||
>x : number
|
||||
|
33
tests/cases/compiler/checkJsFiles_skipDiagnostics.ts
Normal file
33
tests/cases/compiler/checkJsFiles_skipDiagnostics.ts
Normal file
|
@ -0,0 +1,33 @@
|
|||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @noEmit: true
|
||||
|
||||
// @fileName: a.js
|
||||
var x = 0;
|
||||
|
||||
|
||||
/// @ts-suppress
|
||||
x();
|
||||
|
||||
/// @ts-suppress
|
||||
x();
|
||||
|
||||
/// @ts-suppress
|
||||
x(
|
||||
2,
|
||||
3);
|
||||
|
||||
|
||||
|
||||
// @ts-suppress
|
||||
// come comment
|
||||
// some other comment
|
||||
|
||||
// @anohter
|
||||
|
||||
x();
|
||||
|
||||
|
||||
|
||||
// @ts-suppress: no call signature
|
||||
x();
|
14
tests/cases/fourslash/codeFixAddMissingMember.ts
Normal file
14
tests/cases/fourslash/codeFixAddMissingMember.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////[|class C {
|
||||
//// method() {
|
||||
//// this.foo = 10;
|
||||
//// }
|
||||
////}|]
|
||||
|
||||
verify.rangeAfterCodeFix(`class C {
|
||||
foo: number;
|
||||
method() {
|
||||
this.foo = 10;
|
||||
}
|
||||
}`, /*includeWhiteSpace*/false, /*errorCode*/ undefined, /*index*/ 0);
|
14
tests/cases/fourslash/codeFixAddMissingMember2.ts
Normal file
14
tests/cases/fourslash/codeFixAddMissingMember2.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////[|class C {
|
||||
//// method() {
|
||||
//// this.foo = 10;
|
||||
//// }
|
||||
////}|]
|
||||
|
||||
verify.rangeAfterCodeFix(`class C {
|
||||
[x:string]: number;
|
||||
method() {
|
||||
this.foo = 10;
|
||||
}
|
||||
}`, /*includeWhiteSpace*/false, /*errorCode*/ undefined, /*index*/ 1);
|
14
tests/cases/fourslash/codeFixAddMissingMember3.ts
Normal file
14
tests/cases/fourslash/codeFixAddMissingMember3.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////[|class C {
|
||||
//// static method() {
|
||||
//// this.foo = 10;
|
||||
//// }
|
||||
////}|]
|
||||
|
||||
verify.rangeAfterCodeFix(`class C {
|
||||
static foo: number;
|
||||
static method() {
|
||||
this.foo = 10;
|
||||
}
|
||||
}`);
|
22
tests/cases/fourslash/codeFixAddMissingMember4.ts
Normal file
22
tests/cases/fourslash/codeFixAddMissingMember4.ts
Normal file
|
@ -0,0 +1,22 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @checkJs: true
|
||||
// @allowJs: true
|
||||
|
||||
// @Filename: a.js
|
||||
////[|class C {
|
||||
//// constructor() {
|
||||
//// }
|
||||
//// method() {
|
||||
//// this.foo === 10;
|
||||
//// }
|
||||
////}|]
|
||||
|
||||
verify.rangeAfterCodeFix(`class C {
|
||||
constructor() {
|
||||
this.foo = undefined;
|
||||
}
|
||||
method() {
|
||||
this.foo === 10;
|
||||
}
|
||||
}`, /*includeWhiteSpace*/false, /*errorCode*/ undefined, /*index*/ 0);
|
19
tests/cases/fourslash/codeFixAddMissingMember5.ts
Normal file
19
tests/cases/fourslash/codeFixAddMissingMember5.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @checkJs: true
|
||||
// @allowJs: true
|
||||
|
||||
// @Filename: a.js
|
||||
////[|class C {
|
||||
//// static method() {
|
||||
//// ()=>{ this.foo === 10 };
|
||||
//// }
|
||||
////}
|
||||
////|]
|
||||
|
||||
verify.rangeAfterCodeFix(`class C {
|
||||
static method() {
|
||||
()=>{ this.foo === 10 };
|
||||
}
|
||||
}
|
||||
C.foo = undefined;`, /*includeWhiteSpace*/false, /*errorCode*/ undefined, /*index*/ 0);
|
18
tests/cases/fourslash/codeFixAddMissingMember6.ts
Normal file
18
tests/cases/fourslash/codeFixAddMissingMember6.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @checkJs: true
|
||||
// @allowJs: true
|
||||
|
||||
// @Filename: a.js
|
||||
////[|class C {
|
||||
//// constructor() {
|
||||
//// }
|
||||
//// prop = ()=>{ this.foo === 10 };
|
||||
////}|]
|
||||
|
||||
verify.rangeAfterCodeFix(`class C {
|
||||
constructor() {
|
||||
this.foo = undefined;
|
||||
}
|
||||
prop = ()=>{ this.foo === 10 };
|
||||
}`, /*includeWhiteSpace*/false, /*errorCode*/ undefined, /*index*/ 0);
|
15
tests/cases/fourslash/codeFixAddMissingMember7.ts
Normal file
15
tests/cases/fourslash/codeFixAddMissingMember7.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @checkJs: true
|
||||
// @allowJs: true
|
||||
|
||||
// @Filename: a.js
|
||||
////[|class C {
|
||||
//// static p = ()=>{ this.foo === 10 };
|
||||
////}
|
||||
////|]
|
||||
|
||||
verify.rangeAfterCodeFix(`class C {
|
||||
static p = ()=>{ this.foo === 10 };
|
||||
}
|
||||
C.foo = undefined;`, /*includeWhiteSpace*/false, /*errorCode*/ undefined, /*index*/ 2);
|
11
tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile.ts
Normal file
11
tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @allowjs: true
|
||||
// @noEmit: true
|
||||
|
||||
// @Filename: a.js
|
||||
////[|// @ts-check|]
|
||||
////var x = "";
|
||||
////x = 1;
|
||||
|
||||
verify.rangeAfterCodeFix("// @ts-nocheck", /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 1);
|
15
tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile2.ts
Normal file
15
tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile2.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @allowjs: true
|
||||
// @noEmit: true
|
||||
// @checkJs: true
|
||||
|
||||
// @Filename: a.js
|
||||
////[|var x = "";
|
||||
////x = 1;|]
|
||||
|
||||
// Disable checking for the whole file
|
||||
verify.rangeAfterCodeFix(`// @ts-nocheck
|
||||
var x = "";
|
||||
x = 1;`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 1);
|
||||
|
14
tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile3.ts
Normal file
14
tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile3.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @allowjs: true
|
||||
// @noEmit: true
|
||||
// @checkJs: true
|
||||
|
||||
// @Filename: a.js
|
||||
////[|var x = "";
|
||||
////x = 1;|]
|
||||
|
||||
// Disable checking for next line
|
||||
verify.rangeAfterCodeFix(`var x = "";
|
||||
// @ts-suppress
|
||||
x = 1;`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0);
|
18
tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile4.ts
Normal file
18
tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile4.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @allowjs: true
|
||||
// @noEmit: true
|
||||
// @checkJs: true
|
||||
|
||||
// @Filename: a.js
|
||||
////var x = "";
|
||||
////
|
||||
////[|"test \
|
||||
////"; x = 1;|]
|
||||
|
||||
// Disable checking for next line
|
||||
verify.rangeAfterCodeFix(`"test \\
|
||||
";
|
||||
// @ts-suppress
|
||||
x = 1;`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0);
|
||||
|
17
tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile5.ts
Normal file
17
tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile5.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @allowjs: true
|
||||
// @noEmit: true
|
||||
// @checkJs: true
|
||||
|
||||
// @Filename: a.js
|
||||
////var x = "";
|
||||
////
|
||||
////[|/** comment */
|
||||
////x = 1;|]
|
||||
|
||||
// Disable checking for next line
|
||||
verify.rangeAfterCodeFix(`/** comment */
|
||||
// @ts-suppress
|
||||
x = 1;`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0);
|
||||
|
17
tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile6.ts
Normal file
17
tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile6.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @allowjs: true
|
||||
// @noEmit: true
|
||||
// @checkJs: true
|
||||
|
||||
// @Filename: a.js
|
||||
////var x = 0;
|
||||
////
|
||||
////function f(_a) {
|
||||
//// [|f(x());|]
|
||||
////}
|
||||
|
||||
// Disable checking for next line
|
||||
verify.rangeAfterCodeFix(`// @ts-suppress
|
||||
f(x());`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0);
|
||||
|
17
tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile7.ts
Normal file
17
tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile7.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @allowjs: true
|
||||
// @noEmit: true
|
||||
// @checkJs: true
|
||||
|
||||
// @Filename: a.js
|
||||
////var x = 0;
|
||||
////
|
||||
////function f(_a) {
|
||||
//// [|x();|]
|
||||
////}
|
||||
|
||||
// Disable checking for next line
|
||||
verify.rangeAfterCodeFix(`// @ts-suppress
|
||||
x();`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0);
|
||||
|
19
tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile8.ts
Normal file
19
tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile8.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @allowjs: true
|
||||
// @noEmit: true
|
||||
// @checkJs: true
|
||||
|
||||
// @Filename: a.js
|
||||
////var x = 0;
|
||||
////
|
||||
////function f(_a) {
|
||||
//// /** comment for f */
|
||||
//// [|f(x());|]
|
||||
////}
|
||||
|
||||
// Disable checking for next line
|
||||
verify.rangeAfterCodeFix(`f(
|
||||
// @ts-suppress
|
||||
x());`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0);
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
verify.rangeAfterCodeFix(`
|
||||
class A {
|
||||
[name: string]: number;
|
||||
[x: string]: number;
|
||||
|
||||
constructor() {
|
||||
this.x = 10;
|
||||
|
|
|
@ -296,6 +296,7 @@ declare namespace FourSlashInterface {
|
|||
printCurrentQuickInfo(): void;
|
||||
printCurrentSignatureHelp(): void;
|
||||
printCompletionListMembers(): void;
|
||||
printAvailableCodeFixes(): void;
|
||||
printBreakpointLocation(pos: number): void;
|
||||
printBreakpointAtCurrentLocation(): void;
|
||||
printNameOrDottedNameSpans(pos: number): void;
|
||||
|
|
Loading…
Reference in a new issue