Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Arthur Ozga committed Feb 16, 2017
1 parent 510b384 commit 533262c
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 4 deletions.
74 changes: 74 additions & 0 deletions src/services/codefixes/fixAddMissingMember.ts
@@ -0,0 +1,74 @@
/* @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 in the case of a class declaration
// or the class keyword token in the case of a class expression.
const token = getTokenAtPosition(sourceFile, start);
const checker = context.program.getTypeChecker();

if(!(token.parent && token.parent.kind === SyntaxKind.PropertyAccessExpression)) {
return undefined;
}

if((token.parent as PropertyAccessExpression).expression.kind !== SyntaxKind.ThisKeyword) {
return undefined;
}
1 + 1;

let typeString: string = 'any';
// if binary expression, try to infer type for LHS, else use any
if(token.parent.parent.kind === SyntaxKind.BinaryExpression)
{
const binaryExpression = token.parent.parent as BinaryExpression;
binaryExpression.operatorToken;

const type = checker.getTypeAtLocation(binaryExpression.right);
typeString = checker.typeToString(type);
}

const classDeclaration = getContainingClass(token);
const startPos = classDeclaration.members.pos;
return [{
description: getLocaleSpecificMessage(Diagnostics.Implement_inherited_abstract_class),
changes: [{
fileName: sourceFile.fileName,
textChanges: [{
span: { start: startPos, length: 0 },
newText: `${token.getFullText(sourceFile)}: ${typeString};`
}]
}]
}];
}




// x needs to be a `this` construct. ie
// this.<thing>.
// Want to infer type of x when possible. ie:
// * assignment,
// * function call argument: foo<T>(this.x) where foo(x: SomeType<T>)
// * expression with a type assertion: this.x as MyFavoriteType
// * access expression: this.x.push("asdf") ... probably an array?
// *
// What if there are multiple usages of this.x? Create intersection over all usages?

// needs to be in a class
// inferred type might be error. then add any.
// either make indexable of the inferred type
// add named member of the inferred type.
}

// // class C {
// // constructor() {
// // this.x = 1;
// // }
// // }
1 change: 1 addition & 0 deletions src/services/codefixes/fixes.ts
@@ -1,4 +1,5 @@
/// <reference path="fixClassIncorrectlyImplementsInterface.ts" />
/// <reference path="fixAddMissingMember.ts" />
/// <reference path="fixClassDoesntImplementInheritedAbstractMember.ts" />
/// <reference path="fixClassSuperMustPrecedeThisAccess.ts" />
/// <reference path="fixConstructorForDerivedNeedSuperCall.ts" />
Expand Down
12 changes: 8 additions & 4 deletions src/services/codefixes/helpers.ts
Expand Up @@ -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:
Expand Down Expand Up @@ -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, signature: string = '()', newlineChar: string): string {
return `${visibility}${name}${signature}${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 ";
}
Expand Down
17 changes: 17 additions & 0 deletions tests/cases/fourslash/codeFixUndeclaredPropertyNumericLiteral.ts
@@ -0,0 +1,17 @@
/// <reference path='fourslash.ts' />

//// [|class A {
//// constructor() {
//// this.x = 10;
//// }
//// }|]

verify.rangeAfterCodeFix(`
class A {
x: number;
constructor() {
this.x = 10;
}
}
`);

0 comments on commit 533262c

Please sign in to comment.