jsii-pacmak 1.118.0 → 1.119.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.
@@ -31,6 +31,7 @@ const type_name_1 = require("./python/type-name");
31
31
  const util_2 = require("./python/util");
32
32
  const version_utils_1 = require("./version-utils");
33
33
  const rosetta_assembly_1 = require("../rosetta-assembly");
34
+ const toposort_1 = require("../toposort");
34
35
  const index_1 = require("./index");
35
36
  // eslint-disable-next-line @typescript-eslint/no-var-requires,@typescript-eslint/no-require-imports
36
37
  const spdxLicenseList = require('spdx-license-list');
@@ -318,8 +319,9 @@ class BasePythonClassType {
318
319
  }
319
320
  emit(code, context) {
320
321
  context = nestedContext(context, this.fqn);
321
- const classParams = this.getClassParams(context);
322
- openSignature(code, 'class', this.pythonName, classParams);
322
+ this.sortBasesForMro();
323
+ const baseClasses = this.getClassParams(context);
324
+ openSignature(code, 'class', this.pythonName, baseClasses);
323
325
  this.generator.emitDocString(code, this.apiLocation, this.docs, {
324
326
  documentableItem: `class-${this.pythonName}`,
325
327
  trailingNewLine: true,
@@ -343,6 +345,80 @@ class BasePythonClassType {
343
345
  context.emittedTypes.add(this.fqn);
344
346
  }
345
347
  }
348
+ /**
349
+ * Sort the this.bases array for proper Python MRO.
350
+ *
351
+ * If we don't do this, there is a chance that a superclass and subclass (or interface)
352
+ * have the parents in different order, which leads to an MRO violation.
353
+ *
354
+ * See: <https://docs.python.org/3/howto/mro.html>
355
+ *
356
+ * The bottom line is: child classes higher up in the hierarchy first.
357
+ * As an example, in the hierarchy:
358
+ *
359
+ * ```
360
+ * ┌─────┐
361
+ * │ A │
362
+ * └─────┘
363
+ * ▲
364
+ * ├─────┐
365
+ * │ ┌─────┐
366
+ * │ │ C │
367
+ * │ └─────┘
368
+ * │ ▲
369
+ * ├─────┘
370
+ * ┌─────┐
371
+ * │ B │
372
+ * └─────┘
373
+ * ```
374
+ *
375
+ * The order should be `class B(C, A)`, and not the other way around.
376
+ *
377
+ * This is yet another instance of topological sort.
378
+ */
379
+ sortBasesForMro() {
380
+ if (this.bases.length <= 1) {
381
+ return;
382
+ }
383
+ // Record original order
384
+ const originalOrder = new Map();
385
+ for (let i = 0; i < this.bases.length; i++) {
386
+ originalOrder.set(this.bases[i], i);
387
+ }
388
+ // Classify into sortable and non-sortable types
389
+ const sortableBases = [];
390
+ const nonSortableBases = [];
391
+ for (const baseRef of this.bases) {
392
+ if (spec.isNamedTypeReference(baseRef)) {
393
+ sortableBases.push(baseRef);
394
+ }
395
+ else {
396
+ nonSortableBases.push(baseRef);
397
+ }
398
+ }
399
+ // Toposort, in reverse (highest in the tree last)
400
+ const typeSystem = this.generator.reflectAssembly.system;
401
+ const sorted = (0, toposort_1.topologicalSort)(sortableBases, (t) => t.fqn, (d) => typeBaseFqns(typeSystem.findFqn(d.fqn)));
402
+ sorted.reverse();
403
+ // Inside a trance, we keep original sort order in the source declarations.
404
+ for (const tranche of sorted) {
405
+ tranche.sort((a, b) => originalOrder.get(a) - originalOrder.get(b));
406
+ }
407
+ // Replace original bases
408
+ this.bases.splice(0, this.bases.length, ...sorted.flatMap((xs) => xs), ...nonSortableBases);
409
+ function typeBaseFqns(x) {
410
+ if (x.isClassType()) {
411
+ return [
412
+ ...(x.base ? [x.base?.fqn] : []),
413
+ ...x.getInterfaces().map((i) => i.fqn),
414
+ ];
415
+ }
416
+ if (x.isInterfaceType()) {
417
+ return x.getInterfaces().map((i) => i.fqn);
418
+ }
419
+ return [];
420
+ }
421
+ }
346
422
  boundResolver(resolver) {
347
423
  if (this.fqn == null) {
348
424
  return resolver;
@@ -672,6 +748,7 @@ class BaseProperty {
672
748
  }
673
749
  class Interface extends BasePythonClassType {
674
750
  emit(code, context) {
751
+ this.sortBasesForMro();
675
752
  context = nestedContext(context, this.fqn);
676
753
  emitList(code, '@jsii.interface(', [`jsii_type="${this.fqn}"`], ')');
677
754
  // First we do our normal class logic for emitting our members.
@@ -749,6 +826,7 @@ class Struct extends BasePythonClassType {
749
826
  this.directMembers.push(member);
750
827
  }
751
828
  emit(code, context) {
829
+ this.sortBasesForMro();
752
830
  context = nestedContext(context, this.fqn);
753
831
  const baseInterfaces = this.getClassParams(context);
754
832
  code.indent('@jsii.data_type(');
package/lib/toposort.d.ts CHANGED
@@ -34,5 +34,5 @@ export declare function topologicalSort<T>(xs: Iterable<T>, keyFn: KeyFunc<T>, d
34
34
  * We do declare the type `Toposorted<A>` here so that if we ever change
35
35
  * the type, we can find all usage sites quickly.
36
36
  */
37
- export type Toposorted<A> = readonly A[][];
37
+ export type Toposorted<A> = A[][];
38
38
  //# sourceMappingURL=toposort.d.ts.map
package/lib/util.d.ts CHANGED
@@ -132,4 +132,5 @@ export declare function filterAsync<A>(xs: A[], pred: (x: A) => Promise<boolean>
132
132
  export declare function wait(ms: number): Promise<void>;
133
133
  export declare function flatten<A>(xs: readonly A[][]): A[];
134
134
  export declare function zip<A, B>(xs: A[], ys: B[]): Array<[A, B]>;
135
+ export declare function setAdd<T>(setA: Set<T>, setB: Iterable<T>): void;
135
136
  //# sourceMappingURL=util.d.ts.map
package/lib/util.js CHANGED
@@ -14,6 +14,7 @@ exports.filterAsync = filterAsync;
14
14
  exports.wait = wait;
15
15
  exports.flatten = flatten;
16
16
  exports.zip = zip;
17
+ exports.setAdd = setAdd;
17
18
  const child_process_1 = require("child_process");
18
19
  const fs = require("fs-extra");
19
20
  const os = require("os");
@@ -341,4 +342,9 @@ function zip(xs, ys) {
341
342
  }
342
343
  return ret;
343
344
  }
345
+ function setAdd(setA, setB) {
346
+ for (const b of setB) {
347
+ setA.add(b);
348
+ }
349
+ }
344
350
  //# sourceMappingURL=util.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.118.0 (build 02eec31)";
4
+ export declare const VERSION_DESC = "1.119.0 (build 1634eac)";
5
5
  //# sourceMappingURL=version.d.ts.map
package/lib/version.js CHANGED
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
- // Generated at 2025-10-29T09:48:29Z by generate.sh
2
+ // Generated at 2025-11-10T14:25:15Z 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.118.0';
7
+ exports.VERSION = '1.119.0';
8
8
  /** The qualified version number for this jsii-pacmak release (e.g: `X.Y.Z (build #######)`) */
9
- exports.VERSION_DESC = '1.118.0 (build 02eec31)';
9
+ exports.VERSION_DESC = '1.119.0 (build 1634eac)';
10
10
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jsii-pacmak",
3
- "version": "1.118.0",
3
+ "version": "1.119.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.118.0",
41
- "@jsii/spec": "1.118.0",
40
+ "@jsii/check-node": "1.119.0",
41
+ "@jsii/spec": "1.119.0",
42
42
  "clone": "^2.1.2",
43
- "codemaker": "^1.118.0",
43
+ "codemaker": "^1.119.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.118.0",
47
+ "jsii-reflect": "^1.119.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.118.0",
55
- "@jsii/go-runtime": "^1.118.0",
56
- "@jsii/java-runtime": "^1.118.0",
57
- "@scope/jsii-calc-lib": "^1.118.0",
54
+ "@jsii/dotnet-runtime": "^1.119.0",
55
+ "@jsii/go-runtime": "^1.119.0",
56
+ "@jsii/java-runtime": "^1.119.0",
57
+ "@scope/jsii-calc-lib": "^1.119.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.118.0",
66
+ "jsii-build-tools": "^1.119.0",
67
67
  "jsii-calc": "^3.20.120",
68
68
  "jsii-rosetta": "~5.9.10",
69
69
  "pyright": "^1.1.403"