-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Codefix: add quick fix for missing 'new' operator #27019
Changes from 1 commit
76c6ee6
8b14fb2
7c15378
304c6e9
35665d1
58b262e
6bd9b76
21feb20
047b76f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4608,7 +4608,6 @@ | |
"category": "Message", | ||
"code": 95062 | ||
}, | ||
|
||
"Add missing enum member '{0}'": { | ||
"category": "Message", | ||
"code": 95063 | ||
|
@@ -4619,10 +4618,18 @@ | |
}, | ||
"Convert to async function":{ | ||
"category": "Message", | ||
"code": 95065 | ||
"code": 95065 | ||
}, | ||
"Convert all to async functions": { | ||
"category": "Message", | ||
"code": 95066 | ||
"category": "Message", | ||
"code": 95066 | ||
}, | ||
"Add missing 'new' operator to caller": { | ||
"category": "Message", | ||
"code": 95067 | ||
}, | ||
"Add missing 'new' operator to all callers": { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "to all calls" |
||
"category": "Message", | ||
"code": 95068 | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/* @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 identifierWithoutNew = getIdentifier(sourceFile, span.start); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not guaranteed to be an identifier - you really have an arbitrary expression. For example: class C {}
let x = (() => C)()(); Can you add a respective test that ensures it gets corrected to let x = new ((() => C)())(); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This indeed doesn't work at the moment. When I tried working with its parent element, I received the following: |
||
const changes = textChanges.ChangeTracker.with(context, t => addMissingNewOperator(t, sourceFile, identifierWithoutNew)); | ||
return [createCodeFixAction(fixId, changes, Diagnostics.Add_missing_new_operator_to_caller, fixId, Diagnostics.Add_missing_new_operator_to_all_callers)]; | ||
}, | ||
fixIds: [fixId], | ||
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => | ||
addMissingNewOperator(changes, context.sourceFile, getIdentifier(diag.file, diag.start))), | ||
}); | ||
|
||
function getIdentifier(sourceFile: SourceFile, pos: number): Identifier { | ||
const token = getTokenAtPosition(sourceFile, pos); | ||
Debug.assert(token.kind === SyntaxKind.Identifier); | ||
Debug.assert(isCallExpression(token.parent)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
return <Identifier>token; | ||
} | ||
|
||
function addMissingNewOperator(changes: textChanges.ChangeTracker, sourceFile: SourceFile, identifierWithoutNew: Identifier): void { | ||
const newTypeNode = createNew(identifierWithoutNew, /*typeArguments*/ undefined, /*argumentsArray*/ undefined); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should carry along the original type arguments and arguments. Can you add a test for these?
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tests Added (without passing the arguments - see comment below). |
||
changes.replaceNode(sourceFile, identifierWithoutNew, newTypeNode); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am so surprised that this is working. You should be replacing the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it works because the identifier doesn't have the I guess it only works in the "simple" scenarios that I added, and indeed in the test without the identifier it doesn't. Thanks |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/// <reference path='fourslash.ts' /> | ||
|
||
////class C { | ||
////} | ||
////var c = C(); | ||
|
||
verify.codeFix({ | ||
description: "Add missing 'new' operator to caller", | ||
index: 0, | ||
newFileContent: `class C { | ||
} | ||
var c = new C();` | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 callers", | ||
newFileContent: | ||
`class C { | ||
constructor(num?: number) {} | ||
} | ||
var a = new C(); | ||
var b = new C(3);` | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
caller -> call