You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(pacmak): generates too many methods for Java (#5007)
When pacmak is generating Java code, it is generating `Jsii$Default` interfaces and `Jsii$Proxy` classes; these have default implementations that call out to the jsii kernel for every property and method.
Because all `Jsii$Default` interfaces already have default implementations for every method to call out to jsii, any methods that are inherited from these default interfaces don't need to be inherited on `$Proxy` and `$Default` subtypes.
The logic for this was incorrect, and didn't cut out as many types as it could.
Example:
```ts
interface ISuper {
public readonly super: string;
}
interface ISub extends ISuper {
public readonly sub: string;
}
```
Leads to (roughly) the following Java code:
```java
interface ISuper {
String getSuper();
interface Jsii$Default extends ISuper {
String getSuper() {
return /* call jsii kernel here */
}
}
}
interface ISub extends ISuper {
String getSub();
interface Jsii$Default extends ISub, ISuper.Jsii$Default {
String getSuper() { // <--- ❌ doesn't need to be here!
return /* call jsii kernel here */
}
String getSub() {
return /* call jsii kernel here */
}
}
}
```
The logic that decided whether or not to render methods made two mistakes:
- `abstract`: abstract members need to be rendered, but only for classes. Interface members are always abstract, but also will have a default implementation on the `$Default` interface already.
- The check was using `member.parentType`, but should have been using `member.definingType` instead: `parentType` is *always* the current type we're rendering members for.
The upshot of not rendering unnecessary members is that if we happen to backwards incompatibly break some upstream interface (😇) the upstream implementation can just be inherited instead of re-rendered. This improves compatibility across versions, and makes it easier to roll out breaking changes like this.
Unfortunately there was also a bug in the original implementation which led it to generating too *few* members -- method overloads for optional arguments were not being generated into the `Jsii$Default` implementation. So we still need to generate methods for overloads in the subtypes. We can only drop the generation of these overloads when the lowest version of the jsii package that a library can be used in conjunction with definitely has them already, and I'm not sure we can know that in advance (only if users set up the version combination correctly, which we can't really control). Do the cleanup of that later.
There logic of rendering optional properties that are multiply inherited was also overzealous: it was not figuring out that a single implementation inherited via different parents didn't need to be duplicated; and in fact said it was doing only optional properties, but was actually doing all properties.
---
By submitting this pull request, I confirm that my contribution is made under the terms of the [Apache 2.0 license].
[Apache 2.0 license]: https://www.apache.org/licenses/LICENSE-2.0
0 commit comments