Merge pull request #14097 from aozgaa/MissingPropertyFix

Missing property fix
This commit is contained in:
Arthur Ozga
2017-02-16 14:04:51 -08:00
committed by GitHub
20 changed files with 288 additions and 18 deletions

View File

@@ -0,0 +1,67 @@
/* @internal */
namespace ts.codefix {
registerCodeFix({
errorCodes: [Diagnostics.Property_0_does_not_exist_on_type_1.code],
getCodeActions: getActionsForAddMissingMember
});
function getActionsForAddMissingMember(context: CodeFixContext): CodeAction[] | undefined {
const sourceFile = context.sourceFile;
const start = context.span.start;
// This is the identifier of the missing property. eg:
// this.missing = 1;
// ^^^^^^^
const token = getTokenAtPosition(sourceFile, start);
if (token.kind != SyntaxKind.Identifier) {
return undefined;
}
const classDeclaration = getContainingClass(token);
if (!classDeclaration) {
return undefined;
}
if (!(token.parent && token.parent.kind === SyntaxKind.PropertyAccessExpression)) {
return undefined;
}
if ((token.parent as PropertyAccessExpression).expression.kind !== SyntaxKind.ThisKeyword) {
return undefined;
}
let typeString = "any";
if (token.parent.parent.kind === SyntaxKind.BinaryExpression) {
const binaryExpression = token.parent.parent as BinaryExpression;
const checker = context.program.getTypeChecker();
const widenedType = checker.getWidenedType(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(binaryExpression.right)));
typeString = checker.typeToString(widenedType);
}
const startPos = classDeclaration.members.pos;
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};`
}]
}]
},
{
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};`
}]
}]
}];
}
}

View File

@@ -1,4 +1,5 @@
/// <reference path="fixClassIncorrectlyImplementsInterface.ts" />
/// <reference path="fixAddMissingMember.ts" />
/// <reference path="fixClassDoesntImplementInheritedAbstractMember.ts" />
/// <reference path="fixClassSuperMustPrecedeThisAccess.ts" />
/// <reference path="fixConstructorForDerivedNeedSuperCall.ts" />

View File

@@ -32,7 +32,7 @@ namespace ts.codefix {
const declaration = declarations[0] as Declaration;
const name = declaration.name ? declaration.name.getText() : undefined;
const visibility = getVisibilityPrefix(getModifierFlags(declaration));
const visibility = getVisibilityPrefixWithSpace(getModifierFlags(declaration));
switch (declaration.kind) {
case SyntaxKind.GetAccessor:
@@ -58,7 +58,7 @@ namespace ts.codefix {
if (declarations.length === 1) {
Debug.assert(signatures.length === 1);
const sigString = checker.signatureToString(signatures[0], enclosingDeclaration, TypeFormatFlags.SuppressAnyReturnType, SignatureKind.Call);
return `${visibility}${name}${sigString}${getMethodBodyStub(newlineChar)}`;
return getStubbedMethod(visibility, name, sigString, newlineChar);
}
let result = "";
@@ -78,7 +78,7 @@ namespace ts.codefix {
bodySig = createBodySignatureWithAnyTypes(signatures, enclosingDeclaration, checker);
}
const sigString = checker.signatureToString(bodySig, enclosingDeclaration, TypeFormatFlags.SuppressAnyReturnType, SignatureKind.Call);
result += `${visibility}${name}${sigString}${getMethodBodyStub(newlineChar)}`;
result += getStubbedMethod(visibility, name, sigString, newlineChar);
return result;
default:
@@ -138,11 +138,15 @@ namespace ts.codefix {
}
}
function getMethodBodyStub(newLineChar: string) {
return ` {${newLineChar}throw new Error('Method not implemented.');${newLineChar}}${newLineChar}`;
export function getStubbedMethod(visibility: string, name: string, sigString = "()", newlineChar: string): string {
return `${visibility}${name}${sigString}${getMethodBodyStub(newlineChar)}`;
}
function getVisibilityPrefix(flags: ModifierFlags): string {
function getMethodBodyStub(newlineChar: string) {
return ` {${newlineChar}throw new Error('Method not implemented.');${newlineChar}}${newlineChar}`;
}
function getVisibilityPrefixWithSpace(flags: ModifierFlags): string {
if (flags & ModifierFlags.Public) {
return "public ";
}

View File

@@ -78,6 +78,7 @@
"formatting/smartIndenter.ts",
"formatting/tokenRange.ts",
"codeFixProvider.ts",
"codefixes/fixAddMissingMember.ts",
"codefixes/fixExtendsInterfaceBecomesImplements.ts",
"codefixes/fixClassIncorrectlyImplementsInterface.ts",
"codefixes/fixClassDoesntImplementInheritedAbstractMember.ts",