Skip to content
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): fail compilation when two or more enum members have same val #3412

Merged
merged 4 commits into from
Jun 29, 2022

Conversation

yuth
Copy link
Contributor

@yuth yuth commented Mar 7, 2022

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.

Addressing the issue by failing the compilation by adding validation for enum values

Related change in CDK aws/aws-cdk#19320
Fixes #2782.


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

…alue

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.

Addressing the issue by failing the compilation by adding validation for
enum values

Fixes aws#2782.
@mergify mergify bot added the contribution/core This is a PR that came from AWS. label Mar 7, 2022
@skinny85
Copy link
Contributor

skinny85 commented Mar 7, 2022

I don't think this change will work for CDK, where we use multi-value enums often (like here).

@RomainMuller
Copy link
Contributor

I don't think this change will work for CDK, where we use multi-value enums often (like here).

I think the "right" way to fix this would actually be to have CDK use different values for each enum constant, and have code that gracefully normalizes downstream. That's however a little to easy to make mistakes with, and I wonder if we could come up with an eslint rule that makes this a little safer?

@skinny85
Copy link
Contributor

skinny85 commented Mar 8, 2022

I don't think this change will work for CDK, where we use multi-value enums often (like here).

I think the "right" way to fix this would actually be to have CDK use different values for each enum constant, and have code that gracefully normalizes downstream. That's however a little to easy to make mistakes with, and I wonder if we could come up with an eslint rule that makes this a little safer?

We can't do that, unfortunately, as that could be considered a breaking change.

@yuth
Copy link
Contributor Author

yuth commented Mar 9, 2022

I don't think this change will work for CDK, where we use multi-value enums often (like here).

I think the "right" way to fix this would actually be to have CDK use different values for each enum constant, and have code that gracefully normalizes downstream. That's however a little to easy to make mistakes with, and I wonder if we could come up with an eslint rule that makes this a little safer?

We can't do that, unfortunately, as that could be considered a breaking change.

My plan is to use the same value, but where it is duplicated, use a different value. So if a customer is using the string literal, it would still work as expected. And where we are using the enum transform them into the value needed by Cfn* construct

export enum SubnetType {
  ISOLATED = 'Deprecated_Isolated',
  PRIVATE_ISOLATED = 'Isolated',
  PRIVATE = 'Deprecated_Private',
  PRIVATE_WITH_NAT = 'Private',
  PUBLIC = 'Public'
}

and then update the instantiation code

// snip
    switch (subnetConfig.subnetType) {
        case SubnetType.PUBLIC:
          const publicSubnet = new PublicSubnet(this, name, subnetProps);
          this.publicSubnets.push(publicSubnet);
          subnet = publicSubnet;
          break;
        case SubnetType.PRIVATE_WITH_NAT:
        case SubnetType.PRIVATE:
          const privateSubnet = new PrivateSubnet(this, name, subnetProps);
          this.privateSubnets.push(privateSubnet);
          subnet = privateSubnet;
          break;
        case SubnetType.PRIVATE_ISOLATED:
        case SubnetType.ISOLATED:
          const isolatedSubnet = new PrivateSubnet(this, name, subnetProps);
          this.isolatedSubnets.push(isolatedSubnet);
          subnet = isolatedSubnet;
          break;
        default:
          throw new Error(`Unrecognized subnet type: ${subnetConfig.subnetType}`);
      }

@skinny85
Copy link
Contributor

skinny85 commented Mar 9, 2022

That's not a bad plan. Making sure @rix0rrr sees this (I remember him discussing this at lengths with Niranjan, although I can't find which issue that discussion was in).

yuth added a commit to yuth/aws-cdk that referenced this pull request Mar 10, 2022
CDK has some enums which use the same value for different enum members. This is done to support friendly names for EC2 instance and Subnet type. Having same value for differnt members causes the typescript compiler to ignore the members with same value and causes JSII not to generate the enum members in other languages. To fix this [JSII will throw an error](aws/jsii#3412) when enum members have the same value. Updating CDK code to ensure the build pass when this change lands in JSII

re #aws/jsii#3412
@yuth yuth marked this pull request as ready for review March 11, 2022 15:34
@mergify
Copy link
Contributor

mergify bot commented Jun 29, 2022

Thank you for contributing! ❤️ I will now look into making sure the PR is up-to-date, then proceed to try and merge it!

@mergify mergify bot added the pr/ready-to-merge This PR is ready to be merged. label Jun 29, 2022
@mergify
Copy link
Contributor

mergify bot commented Jun 29, 2022

Merging (with squash)...

@mergify mergify bot merged commit f64dace into aws:main Jun 29, 2022
@mergify mergify bot removed the pr/ready-to-merge This PR is ready to be merged. label Jun 29, 2022
mergify bot pushed a commit to aws/aws-cdk that referenced this pull request Jun 30, 2022
CDK has some enums which use the same value for different enum members. This is done to support friendly names for EC2 instance and Subnet type. Having same value for differnt members causes the typescript compiler to ignore the members with same value and causes JSII not to generate the enum members in other languages. To fix this [JSII will throw an error](aws/jsii#3412) when enum members have the same value. Updating CDK code to ensure the build pass when this change lands in JSII

re #aws/jsii#3412


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
mergify bot pushed a commit to aws/aws-cdk that referenced this pull request Jun 30, 2022
CDK has some enums which use the same value for different enum members. This is done to support friendly names for EC2 instance and Subnet type. Having same value for differnt members causes the typescript compiler to ignore the members with same value and causes JSII not to generate the enum members in other languages. To fix this [JSII will throw an error](aws/jsii#3412) when enum members have the same value. Updating CDK code to ensure the build pass when this change lands in JSII

re #aws/jsii#3412

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*

(cherry picked from commit b0346a4)

# Conflicts:
#	packages/@aws-cdk/aws-ec2/lib/vpc.ts
#	packages/@aws-cdk/aws-ec2/lib/windows-versions.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
contribution/core This is a PR that came from AWS.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Enums with duplicate values dropped
4 participants