-
Notifications
You must be signed in to change notification settings - Fork 13k
add quick fix for add missing enum member #25182
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
Conversation
@@ -0,0 +1,79 @@ | |||
/* @internal */ | |||
namespace ts.codefix { |
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.
i would merge this with fixAddMissingMember.ts
do not see why we need to separate code fixes here.
d5e7ae3
to
d5268c8
Compare
const classDeclarationSourceFile = classDeclaration.getSourceFile(); | ||
const inJs = isSourceFileJavaScript(classDeclarationSourceFile); | ||
const call = tryCast(parent.parent, isCallExpression); | ||
return { token, declaration: classDeclaration, makeStatic, classDeclarationSourceFile, inJs, call }; |
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.
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() }; |
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.
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( |
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.
consider inlining this function in getCodeActions
return createEnumMember(token, enumMemberInitializer); | ||
} | ||
|
||
function addEnumMemberDeclaration(changes: textChanges.ChangeTracker, checker: TypeChecker, token: Identifier, enumDeclaration: EnumDeclaration, file: SourceFile) { |
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.
consider merging these two functions
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.
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); |
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.
this should be some
, and not first
. a literal enum can have both members, e.g.:
enum E {
a,
b = 1,
c = "ss"
}
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? |
I do not think we will be able to get them all.. so for that one, my gut reaction is to make it |
if (!addToSeen(seenNames, token.text)) { | ||
const checker = program.getTypeChecker(); | ||
const info = getInfo(diag.file, diag.start, checker); | ||
if (!info || !addToSeen(seenNames, info.token.text)) { |
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.
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.
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.
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)); |
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.
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.
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.
Looks good with a couple of comments. @Andy-MS mind taking a look as well.
Fixes #25129