Merge pull request #27019 from iliashkolyar/codefix_add_missing_new_operator
Codefix: add quick fix for missing 'new' operator
This commit is contained in:
commit
fe263708be
|
@ -4748,7 +4748,6 @@
|
||||||
"category": "Message",
|
"category": "Message",
|
||||||
"code": 95062
|
"code": 95062
|
||||||
},
|
},
|
||||||
|
|
||||||
"Add missing enum member '{0}'": {
|
"Add missing enum member '{0}'": {
|
||||||
"category": "Message",
|
"category": "Message",
|
||||||
"code": 95063
|
"code": 95063
|
||||||
|
@ -4780,5 +4779,13 @@
|
||||||
"Add 'unknown' to all conversions of non-overlapping types": {
|
"Add 'unknown' to all conversions of non-overlapping types": {
|
||||||
"category": "Message",
|
"category": "Message",
|
||||||
"code": 95070
|
"code": 95070
|
||||||
|
},
|
||||||
|
"Add missing 'new' operator to call": {
|
||||||
|
"category": "Message",
|
||||||
|
"code": 95071
|
||||||
|
},
|
||||||
|
"Add missing 'new' operator to all calls": {
|
||||||
|
"category": "Message",
|
||||||
|
"code": 95072
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
32
src/services/codefixes/fixAddMissingNewOperator.ts
Normal file
32
src/services/codefixes/fixAddMissingNewOperator.ts
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/* @internal */
|
||||||
|
namespace ts.codefix {
|
||||||
|
const fixId = "addMissingNewOperator";
|
||||||
|
const errorCodes = [Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new.code];
|
||||||
|
registerCodeFix({
|
||||||
|
errorCodes,
|
||||||
|
getCodeActions(context) {
|
||||||
|
const { sourceFile, span } = context;
|
||||||
|
const changes = textChanges.ChangeTracker.with(context, t => addMissingNewOperator(t, sourceFile, span));
|
||||||
|
return [createCodeFixAction(fixId, changes, Diagnostics.Add_missing_new_operator_to_call, fixId, Diagnostics.Add_missing_new_operator_to_all_calls)];
|
||||||
|
},
|
||||||
|
fixIds: [fixId],
|
||||||
|
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) =>
|
||||||
|
addMissingNewOperator(changes, context.sourceFile, diag)),
|
||||||
|
});
|
||||||
|
|
||||||
|
function addMissingNewOperator(changes: textChanges.ChangeTracker, sourceFile: SourceFile, span: TextSpan): void {
|
||||||
|
const call = cast(findAncestorMatchingSpan(sourceFile, span), isCallExpression);
|
||||||
|
const newExpression = createNew(call.expression, call.typeArguments, call.arguments);
|
||||||
|
|
||||||
|
changes.replaceNode(sourceFile, call, newExpression);
|
||||||
|
}
|
||||||
|
|
||||||
|
function findAncestorMatchingSpan(sourceFile: SourceFile, span: TextSpan): Node {
|
||||||
|
let token = getTokenAtPosition(sourceFile, span.start);
|
||||||
|
const end = textSpanEnd(span);
|
||||||
|
while (token.end < end) {
|
||||||
|
token = token.parent;
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
}
|
|
@ -55,6 +55,7 @@
|
||||||
"codefixes/importFixes.ts",
|
"codefixes/importFixes.ts",
|
||||||
"codefixes/fixSpelling.ts",
|
"codefixes/fixSpelling.ts",
|
||||||
"codefixes/fixAddMissingMember.ts",
|
"codefixes/fixAddMissingMember.ts",
|
||||||
|
"codefixes/fixAddMissingNewOperator.ts",
|
||||||
"codefixes/fixCannotFindModule.ts",
|
"codefixes/fixCannotFindModule.ts",
|
||||||
"codefixes/fixClassDoesntImplementInheritedAbstractMember.ts",
|
"codefixes/fixClassDoesntImplementInheritedAbstractMember.ts",
|
||||||
"codefixes/fixClassSuperMustPrecedeThisAccess.ts",
|
"codefixes/fixClassSuperMustPrecedeThisAccess.ts",
|
||||||
|
|
14
tests/cases/fourslash/codeFixAddMissingNew.ts
Normal file
14
tests/cases/fourslash/codeFixAddMissingNew.ts
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
/// <reference path='fourslash.ts' />
|
||||||
|
|
||||||
|
////class C {
|
||||||
|
////}
|
||||||
|
////var c = C();
|
||||||
|
|
||||||
|
verify.codeFix({
|
||||||
|
description: "Add missing 'new' operator to call",
|
||||||
|
index: 0,
|
||||||
|
newFileContent:
|
||||||
|
`class C {
|
||||||
|
}
|
||||||
|
var c = new C();`
|
||||||
|
});
|
14
tests/cases/fourslash/codeFixAddMissingNew2.ts
Normal file
14
tests/cases/fourslash/codeFixAddMissingNew2.ts
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
/// <reference path='fourslash.ts' />
|
||||||
|
|
||||||
|
////class C {
|
||||||
|
////}
|
||||||
|
////let x = (() => C)()();
|
||||||
|
|
||||||
|
verify.codeFix({
|
||||||
|
description: "Add missing 'new' operator to call",
|
||||||
|
index: 0,
|
||||||
|
newFileContent:
|
||||||
|
`class C {
|
||||||
|
}
|
||||||
|
let x = new ((() => C)())();`
|
||||||
|
});
|
16
tests/cases/fourslash/codeFixAddMissingNew3.ts
Normal file
16
tests/cases/fourslash/codeFixAddMissingNew3.ts
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
/// <reference path='fourslash.ts' />
|
||||||
|
|
||||||
|
////class C {
|
||||||
|
////}
|
||||||
|
////let x = [C];
|
||||||
|
////let a = x[0]();
|
||||||
|
|
||||||
|
verify.codeFix({
|
||||||
|
description: "Add missing 'new' operator to call",
|
||||||
|
index: 0,
|
||||||
|
newFileContent:
|
||||||
|
`class C {
|
||||||
|
}
|
||||||
|
let x = [C];
|
||||||
|
let a = new x[0]();`
|
||||||
|
});
|
18
tests/cases/fourslash/codeFixAddMissingNew4.ts
Normal file
18
tests/cases/fourslash/codeFixAddMissingNew4.ts
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
/// <reference path='fourslash.ts' />
|
||||||
|
|
||||||
|
////class C {
|
||||||
|
////}
|
||||||
|
////class D {
|
||||||
|
////}
|
||||||
|
////let x = (true ? C : D)();
|
||||||
|
|
||||||
|
verify.codeFix({
|
||||||
|
description: "Add missing 'new' operator to call",
|
||||||
|
index: 0,
|
||||||
|
newFileContent:
|
||||||
|
`class C {
|
||||||
|
}
|
||||||
|
class D {
|
||||||
|
}
|
||||||
|
let x = new (true ? C : D)();`
|
||||||
|
});
|
25
tests/cases/fourslash/codeFixAddMissingNew5.ts
Normal file
25
tests/cases/fourslash/codeFixAddMissingNew5.ts
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/// <reference path='fourslash.ts' />
|
||||||
|
|
||||||
|
////class C {
|
||||||
|
////}
|
||||||
|
////
|
||||||
|
////function foo() {
|
||||||
|
//// return C;
|
||||||
|
////}
|
||||||
|
////
|
||||||
|
////foo()!();
|
||||||
|
|
||||||
|
|
||||||
|
verify.codeFix({
|
||||||
|
description: "Add missing 'new' operator to call",
|
||||||
|
index: 0,
|
||||||
|
newFileContent:
|
||||||
|
`class C {
|
||||||
|
}
|
||||||
|
|
||||||
|
function foo() {
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
|
||||||
|
new (foo()!)();`
|
||||||
|
});
|
18
tests/cases/fourslash/codeFixAddMissingNew_all.ts
Normal file
18
tests/cases/fourslash/codeFixAddMissingNew_all.ts
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
/// <reference path='fourslash.ts' />
|
||||||
|
|
||||||
|
////class C {
|
||||||
|
//// constructor(num?: number) {}
|
||||||
|
////}
|
||||||
|
////var a = C();
|
||||||
|
////var b = C(3);
|
||||||
|
|
||||||
|
verify.codeFixAll({
|
||||||
|
fixId: "addMissingNewOperator",
|
||||||
|
fixAllDescription: "Add missing 'new' operator to all calls",
|
||||||
|
newFileContent:
|
||||||
|
`class C {
|
||||||
|
constructor(num?: number) {}
|
||||||
|
}
|
||||||
|
var a = new C();
|
||||||
|
var b = new C(3);`
|
||||||
|
});
|
22
tests/cases/fourslash/codeFixAddMissingNew_all_arguments.ts
Normal file
22
tests/cases/fourslash/codeFixAddMissingNew_all_arguments.ts
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
/// <reference path='fourslash.ts' />
|
||||||
|
|
||||||
|
////class C<T = number> {
|
||||||
|
//// x?: T;
|
||||||
|
//// constructor(x: T) { this.x = x; }
|
||||||
|
////}
|
||||||
|
////let a = C(1, 2, 3);
|
||||||
|
////let b = C<string>("hello");
|
||||||
|
////let c = C<boolean>();
|
||||||
|
|
||||||
|
verify.codeFixAll({
|
||||||
|
fixId: "addMissingNewOperator",
|
||||||
|
fixAllDescription: "Add missing 'new' operator to all calls",
|
||||||
|
newFileContent:
|
||||||
|
`class C<T = number> {
|
||||||
|
x?: T;
|
||||||
|
constructor(x: T) { this.x = x; }
|
||||||
|
}
|
||||||
|
let a = new C(1, 2, 3);
|
||||||
|
let b = new C<string>("hello");
|
||||||
|
let c = new C<boolean>();`
|
||||||
|
});
|
Loading…
Reference in a new issue