Skip to content

Conversation

Kingwl
Copy link
Contributor

@Kingwl Kingwl commented Jun 24, 2018

Fixes #25129

@@ -0,0 +1,79 @@
/* @internal */
namespace ts.codefix {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i would merge this with fixAddMissingMember.ts do not see why we need to separate code fixes here.

@Kingwl Kingwl force-pushed the fix-missing-enum-member branch from d5e7ae3 to d5268c8 Compare June 26, 2018 02:17
const classDeclarationSourceFile = classDeclaration.getSourceFile();
const inJs = isSourceFileJavaScript(classDeclarationSourceFile);
const call = tryCast(parent.parent, isCallExpression);
return { token, declaration: classDeclaration, makeStatic, classDeclarationSourceFile, inJs, call };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider adding a discriminant here, e.g. kind: "enum" vs kind: "class". this way you can skip the function isEnumInfo.

}
const enumDeclaration = find(symbol.declarations, isEnumDeclaration);
if (enumDeclaration) {
return { token, declaration: enumDeclaration, enumDeclarationSourceFile: enumDeclaration.getSourceFile() };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you need the sourceFile? you can get that from the declaration easily.

@@ -188,6 +211,16 @@ namespace ts.codefix {
return createCodeFixAction(fixName, changes, [makeStatic ? Diagnostics.Declare_static_method_0 : Diagnostics.Declare_method_0, token.text], fixId, Diagnostics.Add_all_missing_members);
}

function getActionForEnumMemberDeclaration(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider inlining this function in getCodeActions

return createEnumMember(token, enumMemberInitializer);
}

function addEnumMemberDeclaration(changes: textChanges.ChangeTracker, checker: TypeChecker, token: Identifier, enumDeclaration: EnumDeclaration, file: SourceFile) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider merging these two functions

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i mean addEnumMemberDeclaration and createEnumMemberFromEnumDeclaration

* value of initializer is a string literal that equal to name of enum member.
* literal enum or empty enum will not create initializer.
*/
const firstMember = firstOrUndefined(enumDeclaration.members);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be some, and not first. a literal enum can have both members, e.g.:

enum E { 
    a,
    b = 1,
    c = "ss"
}

@Kingwl
Copy link
Contributor Author

Kingwl commented Jun 27, 2018

enum E {
   a,
   b = 1,
   c = "123"
}
enum A {
   a = E.c    
}
enum B {
   b = A.a
}
B.c

could we have some way to handle this case?

@mhegazy
Copy link
Contributor

mhegazy commented Jun 28, 2018

I do not think we will be able to get them all.. so for that one, my gut reaction is to make it c, and let the user handle the error. another alternative is not to provide the quick fix.

if (!addToSeen(seenNames, token.text)) {
const checker = program.getTypeChecker();
const info = getInfo(diag.file, diag.start, checker);
if (!info || !addToSeen(seenNames, info.token.text)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So... this is not really caused by your change, but was already there, but i think this is wrong.. the key to addToSeen should not be the name of the property, but rather the the pair [container symbol, property Name]. e.g. today this fails:

class C {
    method() { 
        this.a = 0;
    }
}


class D {
    method() {
        this.a = 0;
    } 
}   

it gets a bit more involved if one of the two classes inherit from each other.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can handle that in a different change since it was not introduced by your change.

*/
const hasStringInitializer = some(enumDeclaration.members, member => {
const type = checker.getTypeAtLocation(member);
return !!(type && type.flags & (TypeFlags.StringLike | TypeFlags.Enum));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i would just check for stringLike here, and not enum. it can be both string or number, and since we are not handling numbers, i would leave that part off.

Copy link
Contributor

@mhegazy mhegazy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good with a couple of comments. @Andy-MS mind taking a look as well.

@mhegazy mhegazy merged commit c27dace into microsoft:master Jun 29, 2018
@Kingwl Kingwl deleted the fix-missing-enum-member branch June 29, 2018 20:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants