jsii-pacmak 1.121.0 → 1.122.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -107,16 +107,16 @@ declare class JavaGenerator extends Generator {
107
107
  protected onInterfaceMethodOverload(ifc: spec.InterfaceType, overload: spec.Method, _originalMethod: spec.Method): void;
108
108
  protected onInterfaceProperty(ifc: spec.InterfaceType, prop: spec.Property): void;
109
109
  /**
110
- * Emits a local default implementation for optional properties inherited from
111
- * multiple distinct parent types. This remvoes the default method dispatch
112
- * ambiguity that would otherwise exist.
110
+ * Emits a local default implementation for properties inherited from multiple
111
+ * distinct parent types. This removes the default method dispatch ambiguity
112
+ * that would otherwise exist.
113
113
  *
114
114
  * @param ifc the interface to be processed.
115
115
 
116
116
  *
117
117
  * @see https://github.com/aws/jsii/issues/2256
118
118
  */
119
- private emitMultiplyInheritedOptionalProperties;
119
+ private emitMultiplyInheritedProperties;
120
120
  private emitAssemblyPackageInfo;
121
121
  private emitSubmodulePackageInfo;
122
122
  private emitMavenPom;
@@ -215,6 +215,34 @@ declare class JavaGenerator extends Generator {
215
215
  private renderAccessLevel;
216
216
  private makeModuleClass;
217
217
  private emitModuleFile;
218
+ /**
219
+ * Given a method, return the methods that we should generate implementations for on the $Default interface
220
+ *
221
+ * This can be 0..N:
222
+ *
223
+ * - 0: if the method can be inherited from a parent $Default implementation
224
+ * - 1: if the method cannot be inherited from a parent $Default implementation
225
+ * - N: ah-ha, wait! There can be overloads! And because of a historical bug,
226
+ * we didn't use to generate overloads onto $Default interfaces. So it's possible
227
+ * that we don't generate the "main" implementation, but we do generate its overloads.
228
+ *
229
+ * Technically speaking we only have to account for the bug if the type is from a different
230
+ * assembly (because we know all types from the current assembly will be generated ✨ bugless ✨,
231
+ * but just to keep it simple we'll always do the same thing).
232
+ *
233
+ * We can only get rid of this bug once the oldest dependency package a Java
234
+ * package can be used with definitely has overloaded $Default impls. So that will be a while.
235
+ */
236
+ private makeDefaultImpls;
237
+ /**
238
+ * Given a method, return the methods that we should generate implementations for on the $Proxy class
239
+ *
240
+ * See `makeDefaultImpls` for the main rationale behind this. The $Proxy class inherits from $Default
241
+ * so technically this could have usually been empty, but we need to account for the possibility that
242
+ * we implement a $Default interface from another assembly that has been generated with a buggy version
243
+ * of pacmak.
244
+ */
245
+ private makeProxyImpls;
218
246
  private emitJsiiInitializers;
219
247
  /**
220
248
  * Computes the java FQN for a JSII FQN:
@@ -7,6 +7,7 @@ const clone = require("clone");
7
7
  const case_utils_1 = require("codemaker/lib/case-utils");
8
8
  const crypto_1 = require("crypto");
9
9
  const fs = require("fs-extra");
10
+ const reflect = require("jsii-reflect");
10
11
  const jsii_rosetta_1 = require("jsii-rosetta");
11
12
  const path = require("path");
12
13
  const xmlbuilder = require("xmlbuilder");
@@ -29,6 +30,14 @@ const BUILDER_CLASS_NAME = 'Builder';
29
30
  const ANN_NOT_NULL = '@org.jetbrains.annotations.NotNull';
30
31
  const ANN_NULLABLE = '@org.jetbrains.annotations.Nullable';
31
32
  const ANN_INTERNAL = '@software.amazon.jsii.Internal';
33
+ /**
34
+ * Because of a historical bug, $Default interfaces we inherit from might not
35
+ * have all method overloads generated correctly.
36
+ *
37
+ * So when inheriting these, we might need to generate the overloads in
38
+ * subinterfaces/subclasses.
39
+ */
40
+ const GENERATE_POTENTIALLY_MISING_DEFAULT_OVERLOADS = true;
32
41
  /**
33
42
  * Build Java packages all together, by generating an aggregate POM
34
43
  *
@@ -58,6 +67,7 @@ class JavaBuilder {
58
67
  try {
59
68
  const tempSourceDir = await this.generateAggregateSourceDir(this.modules, this.options);
60
69
  scratchDirs.push(tempSourceDir);
70
+ await resolveMavenVersions(tempSourceDir.directory);
61
71
  // Need any old module object to make a target to be able to invoke build, though none of its settings
62
72
  // will be used.
63
73
  const target = this.makeTarget(this.modules[0], this.options);
@@ -542,7 +552,7 @@ class JavaGenerator extends generator_1.Generator {
542
552
  this.code.openBlock(`public${inner} interface ${ifc.name} extends ${bases}`);
543
553
  }
544
554
  onEndInterface(ifc) {
545
- this.emitMultiplyInheritedOptionalProperties(ifc);
555
+ this.emitMultiplyInheritedProperties(ifc);
546
556
  if (ifc.datatype) {
547
557
  this.emitDataType(ifc);
548
558
  }
@@ -636,53 +646,37 @@ class JavaGenerator extends generator_1.Generator {
636
646
  }
637
647
  }
638
648
  /**
639
- * Emits a local default implementation for optional properties inherited from
640
- * multiple distinct parent types. This remvoes the default method dispatch
641
- * ambiguity that would otherwise exist.
649
+ * Emits a local default implementation for properties inherited from multiple
650
+ * distinct parent types. This removes the default method dispatch ambiguity
651
+ * that would otherwise exist.
642
652
  *
643
653
  * @param ifc the interface to be processed.
644
654
 
645
655
  *
646
656
  * @see https://github.com/aws/jsii/issues/2256
647
657
  */
648
- emitMultiplyInheritedOptionalProperties(ifc) {
658
+ emitMultiplyInheritedProperties(ifc) {
649
659
  if (ifc.interfaces == null || ifc.interfaces.length <= 1) {
650
660
  // Nothing to do if we don't have parent interfaces, or if we have exactly one
651
661
  return;
652
662
  }
653
- const inheritedOptionalProps = ifc.interfaces
654
- .map(allOptionalProps.bind(this))
655
- // Calculate how many direct parents brought a given optional property
656
- .reduce((histogram, entry) => {
657
- for (const [name, spec] of Object.entries(entry)) {
658
- histogram[name] = histogram[name] ?? { spec, count: 0 };
659
- histogram[name].count += 1;
660
- }
661
- return histogram;
662
- }, {});
663
- const localProps = new Set(ifc.properties?.map((prop) => prop.name) ?? []);
664
- for (const { spec, count } of Object.values(inheritedOptionalProps)) {
665
- if (count < 2 || localProps.has(spec.name)) {
666
- continue;
667
- }
668
- this.onInterfaceProperty(ifc, spec);
669
- }
670
- function allOptionalProps(fqn) {
671
- const type = this.findType(fqn);
672
- const result = {};
673
- for (const prop of type.properties ?? []) {
674
- // Adding artifical "overrides" here for code-gen quality's sake.
675
- result[prop.name] = { ...prop, overrides: type.fqn };
676
- }
677
- // Include optional properties of all super interfaces in the result
678
- for (const base of type.interfaces ?? []) {
679
- for (const [name, prop] of Object.entries(allOptionalProps.call(this, base))) {
680
- if (!(name in result)) {
681
- result[name] = prop;
682
- }
663
+ const memberSources = {};
664
+ for (const parent of ifc.interfaces) {
665
+ const type = this.reflectAssembly.system.findInterface(parent);
666
+ for (const prop of type.allProperties) {
667
+ if (!(prop.name in memberSources)) {
668
+ memberSources[prop.name] = {};
683
669
  }
670
+ memberSources[prop.name][prop.definingType.fqn] = prop.spec;
671
+ }
672
+ }
673
+ for (const defininingTypes of Object.values(memberSources)) {
674
+ // Ignore our own type
675
+ delete defininingTypes[ifc.fqn];
676
+ const keys = Object.keys(defininingTypes);
677
+ if (keys.length > 1) {
678
+ this.onInterfaceProperty(ifc, defininingTypes[keys[0]]);
684
679
  }
685
- return result;
686
680
  }
687
681
  }
688
682
  emitAssemblyPackageInfo(mod) {
@@ -1320,9 +1314,11 @@ class JavaGenerator extends generator_1.Generator {
1320
1314
  this.code.line('/**');
1321
1315
  this.code.line(' * A proxy class which represents a concrete javascript instance of this type.');
1322
1316
  this.code.line(' */');
1317
+ // Get the list of $Default interfaces
1323
1318
  const baseInterfaces = this.defaultInterfacesFor(type, {
1324
1319
  includeThisType: true,
1325
1320
  });
1321
+ // Add ourselves if we don't have a $Default interface
1326
1322
  if (type.isInterfaceType() && !hasDefaultInterfaces(type.assembly)) {
1327
1323
  // Extend this interface directly since this module does not have the Jsii$Default
1328
1324
  baseInterfaces.push(this.toNativeFqn(type.fqn));
@@ -1339,10 +1335,7 @@ class JavaGenerator extends generator_1.Generator {
1339
1335
  this.code.line('super(objRef);');
1340
1336
  this.code.closeBlock();
1341
1337
  // emit all properties
1342
- for (const reflectProp of type.allProperties.filter((prop) => prop.abstract &&
1343
- (prop.parentType.fqn === type.fqn ||
1344
- prop.parentType.isClassType() ||
1345
- !hasDefaultInterfaces(prop.assembly)))) {
1338
+ for (const reflectProp of type.allProperties.filter(needsProxyImpl)) {
1346
1339
  const prop = clone(reflectProp.spec);
1347
1340
  prop.abstract = false;
1348
1341
  // Emitting "final" since this is a proxy and nothing will/should override this
@@ -1352,21 +1345,11 @@ class JavaGenerator extends generator_1.Generator {
1352
1345
  });
1353
1346
  }
1354
1347
  // emit all the methods
1355
- for (const reflectMethod of type.allMethods.filter((method) => method.abstract &&
1356
- (method.parentType.fqn === type.fqn ||
1357
- method.parentType.isClassType() ||
1358
- !hasDefaultInterfaces(method.assembly)))) {
1359
- const method = clone(reflectMethod.spec);
1360
- method.abstract = false;
1348
+ for (const reflectMethod of type.allMethods.flatMap(this.makeProxyImpls.bind(this))) {
1349
+ const method = clone(reflectMethod);
1361
1350
  // Emitting "final" since this is a proxy and nothing will/should override this
1351
+ method.abstract = false;
1362
1352
  this.emitMethod(type.spec, method, { final: true, overrides: true });
1363
- for (const overloadedMethod of this.createOverloadsForOptionals(method)) {
1364
- overloadedMethod.abstract = false;
1365
- this.emitMethod(type.spec, overloadedMethod, {
1366
- final: true,
1367
- overrides: true,
1368
- });
1369
- }
1370
1353
  }
1371
1354
  this.code.closeBlock();
1372
1355
  }
@@ -1380,23 +1363,16 @@ class JavaGenerator extends generator_1.Generator {
1380
1363
  this.code.openBlock(`interface ${INTERFACE_DEFAULT_CLASS_NAME} extends ${baseInterfaces
1381
1364
  .sort()
1382
1365
  .join(', ')}`);
1383
- for (const property of type.allProperties.filter((prop) => prop.abstract &&
1384
- // Only checking the getter - java.lang.Object has no setters.
1385
- !isJavaLangObjectMethodName(`get${(0, naming_util_1.jsiiToPascalCase)(prop.name)}`) &&
1386
- (prop.parentType.fqn === type.fqn ||
1387
- !hasDefaultInterfaces(prop.assembly)))) {
1366
+ for (const property of type.allProperties.filter(needsDefaultImpl)) {
1388
1367
  this.emitProperty(type.spec, property.spec, property.definingType.spec, {
1389
1368
  defaultImpl: true,
1390
1369
  overrides: type.isInterfaceType(),
1391
1370
  });
1392
1371
  }
1393
- for (const method of type.allMethods.filter((method) => method.abstract &&
1394
- !isJavaLangObjectMethodName(method.name) &&
1395
- (method.parentType.fqn === type.fqn ||
1396
- !hasDefaultInterfaces(method.assembly)))) {
1397
- this.emitMethod(type.spec, method.spec, {
1372
+ for (const method of type.allMethods.flatMap(this.makeDefaultImpls.bind(this))) {
1373
+ this.emitMethod(type.spec, method, {
1398
1374
  defaultImpl: true,
1399
- overrides: type.isInterfaceType(),
1375
+ overrides: true,
1400
1376
  });
1401
1377
  }
1402
1378
  this.code.closeBlock();
@@ -2313,6 +2289,54 @@ class JavaGenerator extends generator_1.Generator {
2313
2289
  this.code.closeFile(moduleFile);
2314
2290
  return moduleClass;
2315
2291
  }
2292
+ /**
2293
+ * Given a method, return the methods that we should generate implementations for on the $Default interface
2294
+ *
2295
+ * This can be 0..N:
2296
+ *
2297
+ * - 0: if the method can be inherited from a parent $Default implementation
2298
+ * - 1: if the method cannot be inherited from a parent $Default implementation
2299
+ * - N: ah-ha, wait! There can be overloads! And because of a historical bug,
2300
+ * we didn't use to generate overloads onto $Default interfaces. So it's possible
2301
+ * that we don't generate the "main" implementation, but we do generate its overloads.
2302
+ *
2303
+ * Technically speaking we only have to account for the bug if the type is from a different
2304
+ * assembly (because we know all types from the current assembly will be generated ✨ bugless ✨,
2305
+ * but just to keep it simple we'll always do the same thing).
2306
+ *
2307
+ * We can only get rid of this bug once the oldest dependency package a Java
2308
+ * package can be used with definitely has overloaded $Default impls. So that will be a while.
2309
+ */
2310
+ makeDefaultImpls(m) {
2311
+ const ret = [];
2312
+ if (needsDefaultImpl(m)) {
2313
+ ret.push(m.spec);
2314
+ }
2315
+ // Account for a past bug
2316
+ if (needsDefaultImpl(m) || GENERATE_POTENTIALLY_MISING_DEFAULT_OVERLOADS) {
2317
+ ret.push(...this.createOverloadsForOptionals(m.spec));
2318
+ }
2319
+ return ret;
2320
+ }
2321
+ /**
2322
+ * Given a method, return the methods that we should generate implementations for on the $Proxy class
2323
+ *
2324
+ * See `makeDefaultImpls` for the main rationale behind this. The $Proxy class inherits from $Default
2325
+ * so technically this could have usually been empty, but we need to account for the possibility that
2326
+ * we implement a $Default interface from another assembly that has been generated with a buggy version
2327
+ * of pacmak.
2328
+ */
2329
+ makeProxyImpls(m) {
2330
+ const ret = [];
2331
+ if (needsProxyImpl(m)) {
2332
+ ret.push(m.spec);
2333
+ }
2334
+ // Account for a past bug
2335
+ if (needsProxyImpl(m) || GENERATE_POTENTIALLY_MISING_DEFAULT_OVERLOADS) {
2336
+ ret.push(...this.createOverloadsForOptionals(m.spec));
2337
+ }
2338
+ return ret;
2339
+ }
2316
2340
  emitJsiiInitializers(cls) {
2317
2341
  this.code.line();
2318
2342
  this.code.openBlock(`protected ${cls.name}(final software.amazon.jsii.JsiiObjectRef objRef)`);
@@ -2816,4 +2840,58 @@ function removeIntersections(x) {
2816
2840
  }
2817
2841
  return x;
2818
2842
  }
2843
+ /**
2844
+ * Run the maven 'versions:resolve-ranges' plugin
2845
+ *
2846
+ * Initially, we generate version ranges into the pom file based on the NPM
2847
+ * version ranges.
2848
+ *
2849
+ * At build time, given a dependency version range, Maven will download metadata
2850
+ * for all possible versions before every (uncached) build. This takes a long
2851
+ * time, before finally resolving to the latest version anyway.
2852
+ *
2853
+ * Instead, we use the Maven 'versions' plugin to resolve our wide ranges to
2854
+ * point versions. We want the "latest matching" version anyway, and if we don't
2855
+ * the resolution now (which downloads the .poms of all possible versions) it
2856
+ * will happen during every single build.
2857
+ */
2858
+ async function resolveMavenVersions(directory) {
2859
+ const versionsPluginVersion = '2.20.1';
2860
+ await (0, util_1.subprocess)('mvn', [
2861
+ `org.codehaus.mojo:versions-maven-plugin:${versionsPluginVersion}:resolve-ranges`,
2862
+ ], {
2863
+ cwd: directory,
2864
+ retry: { maxAttempts: 1 },
2865
+ });
2866
+ }
2867
+ /**
2868
+ * Whether the given property or method needs to be implemented on a $Proxy class
2869
+ *
2870
+ * Proxies extend the class they're for (if for a class), and the $Default interfaces
2871
+ * of all the base interfaces, so implementations need to be present for everything
2872
+ * that is not abstract and can be inherited from a $Default interface.
2873
+ */
2874
+ function needsProxyImpl(x) {
2875
+ // Interface members are always marked 'abstract', but we only need to
2876
+ // implement them if they come from a class (because interface members
2877
+ // will have a $Default impl that calls out to jsii already).
2878
+ const isAbstractClassMember = x.definingType.isClassType() && x.abstract;
2879
+ return (isAbstractClassMember || !hasDefaultInterfaces(x.definingType.assembly));
2880
+ }
2881
+ /**
2882
+ * Whether the given property or method needs to be implemented on a $Default interface
2883
+ *
2884
+ * $Default interfaces extend the interface they're for, and the $Default interfaces
2885
+ * of all the base interfaces, so implementations need to be present for everything
2886
+ * that is defined on the current interface or cannot be inherited from a $Default interface.
2887
+ */
2888
+ function needsDefaultImpl(x) {
2889
+ const isBuiltinMethod = x instanceof reflect.Property
2890
+ ? // Only checking the getter - java.lang.Object has no setters.
2891
+ isJavaLangObjectMethodName(`get${(0, naming_util_1.jsiiToPascalCase)(x.name)}`)
2892
+ : isJavaLangObjectMethodName(x.name);
2893
+ return ((!hasDefaultInterfaces(x.definingType.assembly) ||
2894
+ x.definingType.fqn === x.parentType.fqn) &&
2895
+ !isBuiltinMethod);
2896
+ }
2819
2897
  //# sourceMappingURL=java.js.map
package/lib/version.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /** The short version number for this jsii-pacmak release (e.g: `X.Y.Z`) */
2
2
  export declare const VERSION: string;
3
3
  /** The qualified version number for this jsii-pacmak release (e.g: `X.Y.Z (build #######)`) */
4
- export declare const VERSION_DESC = "1.121.0 (build d7af9b9)";
4
+ export declare const VERSION_DESC = "1.122.0 (build d5d44e9)";
5
5
  //# sourceMappingURL=version.d.ts.map
package/lib/version.js CHANGED
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
- // Generated at 2025-12-09T17:15:28Z by generate.sh
2
+ // Generated at 2025-12-22T15:21:44Z by generate.sh
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.VERSION_DESC = exports.VERSION = void 0;
5
5
  /** The short version number for this jsii-pacmak release (e.g: `X.Y.Z`) */
6
6
  // eslint-disable-next-line @typescript-eslint/no-inferrable-types
7
- exports.VERSION = '1.121.0';
7
+ exports.VERSION = '1.122.0';
8
8
  /** The qualified version number for this jsii-pacmak release (e.g: `X.Y.Z (build #######)`) */
9
- exports.VERSION_DESC = '1.121.0 (build d7af9b9)';
9
+ exports.VERSION_DESC = '1.122.0 (build d5d44e9)';
10
10
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jsii-pacmak",
3
- "version": "1.121.0",
3
+ "version": "1.122.0",
4
4
  "description": "A code generation framework for jsii backend languages",
5
5
  "license": "Apache-2.0",
6
6
  "author": {
@@ -37,24 +37,24 @@
37
37
  "package": "package-js"
38
38
  },
39
39
  "dependencies": {
40
- "@jsii/check-node": "1.121.0",
41
- "@jsii/spec": "1.121.0",
40
+ "@jsii/check-node": "1.122.0",
41
+ "@jsii/spec": "1.122.0",
42
42
  "clone": "^2.1.2",
43
- "codemaker": "^1.121.0",
43
+ "codemaker": "^1.122.0",
44
44
  "commonmark": "^0.31.2",
45
45
  "escape-string-regexp": "^4.0.0",
46
46
  "fs-extra": "^10.1.0",
47
- "jsii-reflect": "^1.121.0",
47
+ "jsii-reflect": "^1.122.0",
48
48
  "semver": "^7.7.2",
49
49
  "spdx-license-list": "^6.10.0",
50
50
  "xmlbuilder": "^15.1.1",
51
51
  "yargs": "^17.7.2"
52
52
  },
53
53
  "devDependencies": {
54
- "@jsii/dotnet-runtime": "^1.121.0",
55
- "@jsii/go-runtime": "^1.121.0",
56
- "@jsii/java-runtime": "^1.121.0",
57
- "@scope/jsii-calc-lib": "^1.121.0",
54
+ "@jsii/dotnet-runtime": "^1.122.0",
55
+ "@jsii/go-runtime": "^1.122.0",
56
+ "@jsii/java-runtime": "^1.122.0",
57
+ "@scope/jsii-calc-lib": "^1.122.0",
58
58
  "@types/clone": "^2.1.4",
59
59
  "@types/commonmark": "^0.27.10",
60
60
  "@types/diff": "^5.2.3",
@@ -63,7 +63,7 @@
63
63
  "@types/yargs": "^17.0.33",
64
64
  "diff": "^5.2.0",
65
65
  "jsii": "^5.9.10",
66
- "jsii-build-tools": "^1.121.0",
66
+ "jsii-build-tools": "^1.122.0",
67
67
  "jsii-calc": "^3.20.120",
68
68
  "jsii-rosetta": "~5.9.10",
69
69
  "pyright": "^1.1.403"