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(java): invalid code when multi-inheriting optional properties #2591

Merged
merged 4 commits into from
Feb 22, 2021

Conversation

RomainMuller
Copy link
Contributor

The generated code for interfaces includes default implementations for
optional properties (since adding a new optional property is a non
breaking change in TypeScript, this allows us to preserve this property
in Java, too).

However, if two distinct super-interfaces declare the same property, the
child inherits two unrelated default implementations for the same
method, which results in dispatch ambiguity that is illegal.

In order to remove the ambiguity, a new default implementation must be
provided on the child interface, so that the dispatch is unambiguous
again.

Fixes #22556


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

The generated code for interfaces includes default implementations for
optional properties (since adding a new optional property is a non
breaking change in TypeScript, this allows us to preserve this property
in Java, too).

However, if two distinct super-interfaces declare the same property, the
child inherits two unrelated default implementations for the same
method, which results in dispatch ambiguity that is illegal.

In order to remove the ambiguity, a new default implementation must be
provided on the child interface, so that the dispatch is unambiguous
again.

Fixes #22556
@RomainMuller RomainMuller added bug This issue is a bug. language/java Related to Java bindings effort/small Small work item – less than a day of effort module/pacmak Issues affecting the `jsii-pacmak` module contribution/core This is a PR that came from AWS. labels Feb 19, 2021
@RomainMuller RomainMuller requested a review from a team February 19, 2021 10:53
@RomainMuller RomainMuller self-assigned this Feb 19, 2021
Comment on lines 7000 to 7006
/**
*/
@software.amazon.jsii.Stability(software.amazon.jsii.Stability.Level.Deprecated)
@Deprecated
default @org.jetbrains.annotations.Nullable java.lang.String getHoistedTop() {
return null;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This right here is what used to not be emitted - leading to DiamondBottom inheriting the default implementation from both DiamondLeft and DiamondRight (both of which hoisted that from their internal parent InternalDiamondTop) -- causing illegal dispatch ambiguity.

New default declared here replaces the parent's, and solves the issue.

@nija-at nija-at added the pr/do-not-merge This PR should not be merged at this time. label Feb 19, 2021
Copy link
Contributor

@nija-at nija-at 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!

const type = this.findType(fqn) as spec.InterfaceType;
const result: Record<string, spec.Property> = {};
for (const prop of type.properties ?? []) {
// Adding artifical "overrides" here for code-gen quality's sake.
Copy link
Contributor

Choose a reason for hiding this comment

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

why artificial?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Technically, the property as we fetch it is not overridden... We actually generate an override, but per the jsii type model, it's only inherited.

packages/jsii-pacmak/lib/targets/java.ts Show resolved Hide resolved

const localProps = new Set(ifc.properties?.map((prop) => prop.name) ?? []);
for (const { spec, count } of Object.values(inheritedOptionalProps)) {
if (count < 2 || localProps.has(spec.name)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the latter half of this check doing?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Avoids re-declaring a property that was already overridden locally (that would be illegal).

Copy link
Contributor

@skinny85 skinny85 left a comment

Choose a reason for hiding this comment

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

LGTM!

I think Niranjan's comments make a lot of sense, no additional ones from me 🙂.

Co-authored-by: Niranjan Jayakar <nija@amazon.com>
@RomainMuller RomainMuller removed the pr/do-not-merge This PR should not be merged at this time. label Feb 22, 2021
@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • CodeBuild project: AutoBuildProject89A8053A-6Jw05QLuWWwe
  • Commit ID: 1f94889
  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@mergify
Copy link
Contributor

mergify bot commented Feb 22, 2021

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 Feb 22, 2021
@mergify mergify bot merged commit 2399608 into main Feb 22, 2021
@mergify mergify bot deleted the rmuller/java-diamond branch February 22, 2021 10:41
@mergify
Copy link
Contributor

mergify bot commented Feb 22, 2021

Merging (with squash)...

This was referenced Mar 17, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue is a bug. contribution/core This is a PR that came from AWS. effort/small Small work item – less than a day of effort language/java Related to Java bindings module/pacmak Issues affecting the `jsii-pacmak` module
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants