Basic groundwork for suggestioning removing non-null assertions.

This commit is contained in:
Daniel Rosenwasser
2018-04-24 12:14:59 -07:00
parent 5d67f8ef68
commit 5d648efbb6
6 changed files with 53 additions and 2 deletions

View File

@@ -16551,13 +16551,18 @@ namespace ts {
undefinedDiagnostic?: DiagnosticMessage,
nullOrUndefinedDiagnostic?: DiagnosticMessage,
) {
return checkNonNullType(
checkExpression(node),
const originalType = checkExpression(node);
const nonNullType = checkNonNullType(
originalType,
node,
nullDiagnostic,
undefinedDiagnostic,
nullOrUndefinedDiagnostic
);
if (strictNullChecks && originalType === nonNullType) {
error(node, Diagnostics.This_non_null_assertion_operator_is_unnecessary_for_type_1, typeToString(originalType));
}
return nonNullType
}
function checkNonNullType(

View File

@@ -3894,6 +3894,10 @@
"category": "Suggestion",
"code": 80004
},
"This non-null assertion operator is unnecessary for type '{1}'": {
"category": "Suggestion",
"code": 80005
},
"Add missing 'super()' call": {
"category": "Message",
@@ -4170,5 +4174,13 @@
"Generate 'get' and 'set' accessors": {
"category": "Message",
"code": 95046
},
"Remove unnecessary non-null assertion operator": {
"category": "Message",
"code": 95047
},
"Remove all unnecessary non-null assertion operators": {
"category": "Message",
"code": 95048
}
}

View File

@@ -113,6 +113,7 @@
"../services/codefixes/fixInvalidImportSyntax.ts",
"../services/codefixes/fixStrictClassInitialization.ts",
"../services/codefixes/useDefaultImport.ts",
"../services/codefixes/removeUnnecessaryNonNullAssertion.ts",
"../services/refactors/extractSymbol.ts",
"../services/refactors/generateGetAccessorAndSetAccessor.ts",
"../services/sourcemaps.ts",

View File

@@ -109,6 +109,7 @@
"../services/codefixes/fixInvalidImportSyntax.ts",
"../services/codefixes/fixStrictClassInitialization.ts",
"../services/codefixes/useDefaultImport.ts",
"../services/codefixes/removeUnnecessaryNonNullAssertion.ts",
"../services/refactors/extractSymbol.ts",
"../services/refactors/generateGetAccessorAndSetAccessor.ts",
"../services/sourcemaps.ts",

View File

@@ -0,0 +1,31 @@
/* @internal */
namespace ts.codefix {
const fixId = "removeUnnecessaryNonNullAssertion";
const errorCodes = [Diagnostics.This_non_null_assertion_operator_is_unnecessary_for_type_1.code];
registerCodeFix({
errorCodes,
getCodeActions(context) {
const qualifiedName = getNonNullAssertion(context.sourceFile, context.span.start);
const changes = textChanges.ChangeTracker.with(context, t => doChange(t, context.sourceFile, qualifiedName));
return [createCodeFixAction(fixId, changes, Diagnostics.Remove_unnecessary_non_null_assertion_operator, fixId, Diagnostics.Remove_all_unnecessary_non_null_assertion_operators)];
},
fixIds: [fixId],
getAllCodeActions: (context) => codeFixAll(context, errorCodes, (changes, diag) => {
const q = getNonNullAssertion(diag.file, diag.start);
if (q) {
doChange(changes, diag.file, q);
}
}),
});
function getNonNullAssertion(sourceFile: SourceFile, pos: number): NonNullExpression {
const qualifiedName = findAncestor(getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ true), isNonNullExpression)!;
Debug.assert(!!qualifiedName, "Expected position to be owned by a non-null expression.");
return qualifiedName;
}
function doChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, nonNullExpression: NonNullExpression): void {
const expr = nonNullExpression.expression;
changeTracker.replaceNode(sourceFile, nonNullExpression, expr);
}
}

View File

@@ -106,6 +106,7 @@
"codefixes/fixInvalidImportSyntax.ts",
"codefixes/fixStrictClassInitialization.ts",
"codefixes/useDefaultImport.ts",
"codefixes/removeUnnecessaryNonNullAssertion.ts",
"refactors/extractSymbol.ts",
"refactors/generateGetAccessorAndSetAccessor.ts",
"sourcemaps.ts",