-
Notifications
You must be signed in to change notification settings - Fork 244
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
fix(jsii): two enum members cannot have the same value #3207
Conversation
If two enum members have the same value, only the first one will be retained. This is a bit of an issue as we are renaming enum members: the named version will never appear in the assembly, and so not work over jsii. What's worse, if we *deprecate-and-strip* the original one, neither of the enum members will appear. Address this issue by working around TypeScript's natural tendencies to collapse enum values. There was a bug in single-valued enum symbolIds as well, which this PR also fixes. Fixes #2782.
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.
Nice!
Note that this as written is going to break the CDK build due to some existing enum names -- which were previously shadowed and ignored -- not adhering to jsii conventions. See #3208 |
I actually don't think this is the best way to go anymore. Quoth an internal exchange: What does it even mean for 2 enums to have the same value? It doesn't mean anything. Enum values are supposed to be distinct. What's going wrong here is that we are overloading the enum to be a mapping from 1 or more names we care about that we might want to change, to a single fixed value in CloudFormation that we cannot change. Well that shouldn't have been an num, that should have been a regular mapping. So instead of enum SubnetType {
PRIVATE = 'private',
PRIVATE_WITH_NAT = 'private'
} We should have had: enum SubnetType {
PRIVATE,
PRIVATE_WITH_NAT
}
const CfnSubnetType: Record<SubnetType, string> = {
[SubnetType.PRIVATE]: 'private',
[SubnetType.PRIVATE_WITH_NAT]: 'private',
} And we're conflating the two. (Disregarding the fact that in this particular case, the value of So I think the better solution is for jsii to recognize and reject this situation, and fix the occurrences in the CDK. Thoughts @nija-at, @otaviomacedo, @RomainMuller ? |
I agree with this argument. It's makes sense to me, in principle. How do you think we'll implement this without making it (a) a jsii breaking change, and (b) apply it on the cdk without it being a cdk breaking change? For the former, we could make this a diagnostic that is 'ignore' by default and enable it for all CDK packages. For the latter, I suspect there will be some (perhaps small) set of users using the enum outside of the construct, for whom this will be a breaking change. |
I was planning to... not.
I'm thinking we should discourage this going forward as well: assigning desirable string values to enums was the cause of this mess in the first place. How about we disallow assigning values to enums? (Error or warning) Then people also will not be tempted to use the enums out of context (not a lot of point in reusing But this is probably overly wishful thinking hey? |
Why shouldn't they? It's an enum like any other. We haven't forbidden its use nor is it an obscure use case to write a CDK construct that relies on an enum provided by the CDK.
Agreed with this statement, as long as there is an upgrade path. If the path for the CDK is unclear, then we have no guidance for the rest of the jsii ecosystem. Here are the options I see - (b) sounds like a reasonable approach with a decent upgrade path. |
What you are saying is we are locked in to existing enum values in the CDK libraries, right? |
Well it depends on what you do with it. If you pass the enum back to the CDK, you don't have a problem. If you compare to the symbolic value, you don't have a problem. You only have a problem if you wrote your code to do "I know what value this enum evaluates to, let me write that directly to a JSON file" |
Kind of, yes.
Good point. |
@yuth is working on this |
This is necessary as the previous benchark target had multiple occurrences of enums with several constants having the same value, which is now illegal in jsii code (#3207). The fix for this (aws/aws-cdk@7f4f150) was released in CDK 2.31.0.
If two enum members have the same value, only the first one will
be retained.
This is a bit of an issue as we are renaming enum members: the named
version will never appear in the assembly, and so not work over jsii.
What's worse, if we deprecate-and-strip the original one, neither
of the enum members will appear.
Address this issue by working around TypeScript's natural tendencies
to collapse enum values. There was a bug in single-valued enum symbolIds
as well, which this PR also fixes.
Fixes #2782.
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.