jsii-pacmak 1.120.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.
- package/lib/targets/java.d.ts +32 -4
- package/lib/targets/java.js +143 -65
- package/lib/targets/python/type-name.d.ts +14 -13
- package/lib/targets/python/type-name.js +77 -50
- package/lib/targets/python.js +17 -41
- package/lib/version.d.ts +1 -1
- package/lib/version.js +3 -3
- package/package.json +10 -10
package/lib/targets/java.d.ts
CHANGED
|
@@ -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
|
|
111
|
-
*
|
|
112
|
-
*
|
|
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
|
|
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:
|
package/lib/targets/java.js
CHANGED
|
@@ -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.
|
|
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
|
|
640
|
-
*
|
|
641
|
-
*
|
|
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
|
-
|
|
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
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
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(
|
|
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.
|
|
1356
|
-
|
|
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(
|
|
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.
|
|
1394
|
-
|
|
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:
|
|
1375
|
+
overrides: true,
|
|
1400
1376
|
});
|
|
1401
1377
|
}
|
|
1402
1378
|
this.code.closeBlock();
|
|
@@ -1795,7 +1771,7 @@ class JavaGenerator extends generator_1.Generator {
|
|
|
1795
1771
|
}
|
|
1796
1772
|
this.code.line();
|
|
1797
1773
|
this.code.line('@Override');
|
|
1798
|
-
this.code.openBlock('public final boolean equals(final Object o)');
|
|
1774
|
+
this.code.openBlock('public final boolean equals(final java.lang.Object o)');
|
|
1799
1775
|
this.code.line('if (this == o) return true;');
|
|
1800
1776
|
// This was already checked by `super.equals(o)`, so we skip it here...
|
|
1801
1777
|
this.code.line('if (o == null || getClass() != o.getClass()) return false;');
|
|
@@ -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
|
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
import { Assembly, OptionalValue, TypeReference, Type } from '@jsii/spec';
|
|
2
2
|
import { CodeMaker } from 'codemaker';
|
|
3
|
+
/**
|
|
4
|
+
* The position of a type
|
|
5
|
+
*
|
|
6
|
+
* Types are rendered differently depending on what position they're in:
|
|
7
|
+
*
|
|
8
|
+
* - `type`: a type annotation; these are not evaluated during execution.
|
|
9
|
+
* - `value`: a value in a function body; these are evaluated when the function is called.
|
|
10
|
+
* - `decl`: a value in a class declaration; these are evaluated when a class is being
|
|
11
|
+
* instantiated, before it's done.
|
|
12
|
+
*/
|
|
13
|
+
export type TypePosition = 'type' | 'value' | 'decl';
|
|
3
14
|
/**
|
|
4
15
|
* Actually more of a TypeNameFactory than a TypeName
|
|
5
16
|
*/
|
|
6
17
|
export interface TypeName {
|
|
7
|
-
pythonType(context: NamingContext): string;
|
|
18
|
+
pythonType(pos: TypePosition, context: NamingContext): string;
|
|
8
19
|
requiredImports(context: NamingContext): PythonImports;
|
|
9
20
|
}
|
|
10
21
|
export interface PythonImports {
|
|
@@ -27,12 +38,6 @@ export interface NamingContext {
|
|
|
27
38
|
readonly submodule: string;
|
|
28
39
|
/** Holds the set of intersection types used in the current module */
|
|
29
40
|
readonly intersectionTypes: IntersectionTypesRegistry;
|
|
30
|
-
/**
|
|
31
|
-
* The declaration is made in the context of a type annotation (so it can be quoted)
|
|
32
|
-
*
|
|
33
|
-
* @default true
|
|
34
|
-
*/
|
|
35
|
-
readonly typeAnnotation?: boolean;
|
|
36
41
|
/**
|
|
37
42
|
* A an array representing the stack of declarations currently being
|
|
38
43
|
* initialized. All of these names can only be referred to using a forward
|
|
@@ -40,6 +45,8 @@ export interface NamingContext {
|
|
|
40
45
|
* they can be used safely from implementations so long as those are not *run*
|
|
41
46
|
* as part of the declaration).
|
|
42
47
|
*
|
|
48
|
+
* Closest to the current type is at the end.
|
|
49
|
+
*
|
|
43
50
|
* @default []
|
|
44
51
|
*/
|
|
45
52
|
readonly surroundingTypeFqns?: readonly string[];
|
|
@@ -49,12 +56,6 @@ export interface NamingContext {
|
|
|
49
56
|
* @internal
|
|
50
57
|
*/
|
|
51
58
|
readonly ignoreOptional?: boolean;
|
|
52
|
-
/**
|
|
53
|
-
* The set of jsii type FQNs that have already been emitted so far. This is
|
|
54
|
-
* used to determine whether a given type reference is a forward declaration
|
|
55
|
-
* or not when emitting type signatures.
|
|
56
|
-
*/
|
|
57
|
-
readonly emittedTypes: Set<string>;
|
|
58
59
|
/**
|
|
59
60
|
* Whether the type is emitted for a parameter or not. This may change the
|
|
60
61
|
* exact type signature being emitted (e.g: Arrays are typing.Sequence[T] for
|
|
@@ -87,8 +87,8 @@ class Dict {
|
|
|
87
87
|
_Dict_element.set(this, void 0);
|
|
88
88
|
__classPrivateFieldSet(this, _Dict_element, element, "f");
|
|
89
89
|
}
|
|
90
|
-
pythonType(context) {
|
|
91
|
-
return `typing.Mapping[builtins.str, ${__classPrivateFieldGet(this, _Dict_element, "f").pythonType(context)}]`;
|
|
90
|
+
pythonType(pos, context) {
|
|
91
|
+
return `typing.Mapping[builtins.str, ${__classPrivateFieldGet(this, _Dict_element, "f").pythonType(pos, context)}]`;
|
|
92
92
|
}
|
|
93
93
|
requiredImports(context) {
|
|
94
94
|
return __classPrivateFieldGet(this, _Dict_element, "f").requiredImports(context);
|
|
@@ -101,9 +101,9 @@ class List {
|
|
|
101
101
|
_List_element.set(this, void 0);
|
|
102
102
|
__classPrivateFieldSet(this, _List_element, element, "f");
|
|
103
103
|
}
|
|
104
|
-
pythonType(context) {
|
|
104
|
+
pythonType(pos, context) {
|
|
105
105
|
const type = context.parameterType ? 'Sequence' : 'List';
|
|
106
|
-
return `typing.${type}[${__classPrivateFieldGet(this, _List_element, "f").pythonType(context)}]`;
|
|
106
|
+
return `typing.${type}[${__classPrivateFieldGet(this, _List_element, "f").pythonType(pos, context)}]`;
|
|
107
107
|
}
|
|
108
108
|
requiredImports(context) {
|
|
109
109
|
return __classPrivateFieldGet(this, _List_element, "f").requiredImports(context);
|
|
@@ -116,8 +116,8 @@ class Optional {
|
|
|
116
116
|
_Optional_wrapped.set(this, void 0);
|
|
117
117
|
__classPrivateFieldSet(this, _Optional_wrapped, wrapped, "f");
|
|
118
118
|
}
|
|
119
|
-
pythonType(context) {
|
|
120
|
-
const optionalType = __classPrivateFieldGet(this, _Optional_wrapped, "f").pythonType({
|
|
119
|
+
pythonType(pos, context) {
|
|
120
|
+
const optionalType = __classPrivateFieldGet(this, _Optional_wrapped, "f").pythonType(pos, {
|
|
121
121
|
...context,
|
|
122
122
|
ignoreOptional: true,
|
|
123
123
|
});
|
|
@@ -176,9 +176,9 @@ class Union {
|
|
|
176
176
|
_Union_options.set(this, void 0);
|
|
177
177
|
__classPrivateFieldSet(this, _Union_options, options, "f");
|
|
178
178
|
}
|
|
179
|
-
pythonType(context) {
|
|
179
|
+
pythonType(pos, context) {
|
|
180
180
|
return `typing.Union[${__classPrivateFieldGet(this, _Union_options, "f")
|
|
181
|
-
.map((o) => o.pythonType(context))
|
|
181
|
+
.map((o) => o.pythonType(pos, context))
|
|
182
182
|
.join(', ')}]`;
|
|
183
183
|
}
|
|
184
184
|
requiredImports(context) {
|
|
@@ -192,9 +192,9 @@ class Intersection {
|
|
|
192
192
|
_Intersection_types.set(this, void 0);
|
|
193
193
|
__classPrivateFieldSet(this, _Intersection_types, types, "f");
|
|
194
194
|
}
|
|
195
|
-
pythonType(context) {
|
|
195
|
+
pythonType(pos, context) {
|
|
196
196
|
// We will be generating a special type to represent the intersection
|
|
197
|
-
const name = context.intersectionTypes.obtain(__classPrivateFieldGet(this, _Intersection_types, "f").map((t) => t.pythonType(context)).map(stripQuotes));
|
|
197
|
+
const name = context.intersectionTypes.obtain(__classPrivateFieldGet(this, _Intersection_types, "f").map((t) => t.pythonType(pos, context)).map(stripQuotes));
|
|
198
198
|
// This will never be in scope already, so always render between quotes
|
|
199
199
|
return `'${name}'`;
|
|
200
200
|
}
|
|
@@ -209,24 +209,32 @@ class UserType {
|
|
|
209
209
|
_UserType_fqn.set(this, void 0);
|
|
210
210
|
__classPrivateFieldSet(this, _UserType_fqn, fqn, "f");
|
|
211
211
|
}
|
|
212
|
-
pythonType(context) {
|
|
213
|
-
return this.resolve(context).pythonType;
|
|
212
|
+
pythonType(pos, context) {
|
|
213
|
+
return this.resolve(pos, context).pythonType;
|
|
214
214
|
}
|
|
215
215
|
requiredImports(context) {
|
|
216
|
-
const requiredImport = this.resolve(context).requiredImport;
|
|
216
|
+
const requiredImport = this.resolve('value', context).requiredImport;
|
|
217
217
|
if (requiredImport == null) {
|
|
218
218
|
return {};
|
|
219
219
|
}
|
|
220
220
|
return { [requiredImport.sourcePackage]: new Set([requiredImport.item]) };
|
|
221
221
|
}
|
|
222
|
-
resolve({ assembly,
|
|
222
|
+
resolve(pos, { assembly, submodule, surroundingTypeFqns, parameterType, typeResolver, }) {
|
|
223
223
|
const { assemblyName, packageName, pythonFqn } = toPythonFqn(__classPrivateFieldGet(this, _UserType_fqn, "f"), assembly);
|
|
224
|
-
// If this is a type annotation for a parameter, allow dicts to be passed
|
|
224
|
+
// If this is a type annotation for a parameter, allow dicts to be passed
|
|
225
|
+
// where structs are expected for backwards compatibility with the very
|
|
226
|
+
// first versions of jsii (dicts need to be in jsii-casing).
|
|
225
227
|
const type = typeResolver(__classPrivateFieldGet(this, _UserType_fqn, "f"));
|
|
226
228
|
const isStruct = (0, spec_1.isInterfaceType)(type) && !!type.datatype;
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
229
|
+
// Make a function that quotes the string based on whether we're using it as a type annotation or not.
|
|
230
|
+
// It's never wrong to quote type annotations, and it never fails and evaluates faster because it avoids
|
|
231
|
+
// object lookups at eval time.
|
|
232
|
+
const maybeQuote = (x) => (pos === 'type' ? `"${x}"` : x);
|
|
233
|
+
const wrapType = pos === 'type' && parameterType && isStruct
|
|
234
|
+
? (pyType) => `typing.Union[${maybeQuote(pyType)}, typing.Dict[builtins.str, typing.Any]]`
|
|
235
|
+
: maybeQuote;
|
|
236
|
+
/////////////////////////////////
|
|
237
|
+
// Type from other assembly
|
|
230
238
|
// Emit aliased imports for dependencies (this avoids name collisions)
|
|
231
239
|
if (assemblyName !== assembly.name) {
|
|
232
240
|
const aliasSuffix = (0, crypto_1.createHash)('sha256')
|
|
@@ -247,50 +255,69 @@ class UserType {
|
|
|
247
255
|
}
|
|
248
256
|
const submodulePythonName = toPythonFqn(submodule, assembly).pythonFqn;
|
|
249
257
|
const typeSubmodulePythonName = toPythonFqn(findParentSubmodule(type, assembly), assembly).pythonFqn;
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
258
|
+
//////////////////////////////////////////////
|
|
259
|
+
// Type from same assembly, other submodule
|
|
260
|
+
if (typeSubmodulePythonName !== submodulePythonName) {
|
|
261
|
+
const [toImport, ...nested] = pythonFqn
|
|
262
|
+
.substring(typeSubmodulePythonName.length + 1)
|
|
263
|
+
.split('.');
|
|
264
|
+
const aliasSuffix = (0, crypto_1.createHash)('sha256')
|
|
265
|
+
.update(typeSubmodulePythonName)
|
|
266
|
+
.update('.')
|
|
267
|
+
.update(toImport)
|
|
268
|
+
.digest('hex')
|
|
269
|
+
.substring(0, 8);
|
|
270
|
+
const alias = `_${toImport}_${aliasSuffix}`;
|
|
271
|
+
return {
|
|
272
|
+
pythonType: wrapType([alias, ...nested].join('.')),
|
|
273
|
+
requiredImport: {
|
|
274
|
+
sourcePackage: relativeImportPath(submodulePythonName, typeSubmodulePythonName),
|
|
275
|
+
item: `${toImport} as ${alias}`,
|
|
276
|
+
},
|
|
277
|
+
};
|
|
278
|
+
// Have the 'else' here to minimize the diff.
|
|
279
|
+
// eslint-disable-next-line no-else-return
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
//////////////////////////////////////////////
|
|
283
|
+
// Type from same submodule
|
|
284
|
+
//
|
|
285
|
+
// Considerations:
|
|
286
|
+
// - We could be in the same nested class or in a different nested class here.
|
|
287
|
+
// - We could also be trying to reference types that will be below
|
|
288
|
+
// ourselves in the source code order, which we will need to render as
|
|
289
|
+
// type reference strings.
|
|
255
290
|
const nestingParent = surroundingTypeFqns
|
|
256
291
|
?.map((fqn) => toPythonFqn(fqn, assembly).pythonFqn)
|
|
257
292
|
?.reverse()
|
|
258
293
|
?.find((parent) => pythonFqn.startsWith(`${parent}.`));
|
|
259
|
-
if (
|
|
260
|
-
|
|
261
|
-
//
|
|
294
|
+
if (nestingParent && pos === 'decl') {
|
|
295
|
+
// In normal function bodies etc. we must use the fully-qualified name,
|
|
296
|
+
// but while executing the class declarations we must use the shorter name
|
|
297
|
+
// of the local variable we're defining.
|
|
298
|
+
//
|
|
299
|
+
// An example is most clear:
|
|
300
|
+
//
|
|
301
|
+
// ```py
|
|
302
|
+
// class A:
|
|
303
|
+
// class B: pass
|
|
304
|
+
// class C(B): # <-- note
|
|
305
|
+
// def some_method(self, b: "A.B"): # <-- note
|
|
306
|
+
// return A.B() # <-- note
|
|
307
|
+
// ```
|
|
308
|
+
//
|
|
309
|
+
// The FQN is separated by `.` and we would
|
|
310
|
+
// also use `.` to access subtypes in Python and have the same names, so we
|
|
311
|
+
// can just use a substring.
|
|
262
312
|
return {
|
|
263
|
-
pythonType: wrapType(
|
|
313
|
+
pythonType: wrapType(pythonFqn.slice(nestingParent.length + 1)),
|
|
264
314
|
};
|
|
265
315
|
}
|
|
266
|
-
if (!typeAnnotation && nestingParent) {
|
|
267
|
-
// This is not for a type annotation, so we should be at a point in time
|
|
268
|
-
// where the surrounding symbol has been defined entirely, so we can
|
|
269
|
-
// refer to it "normally" now.
|
|
270
|
-
return { pythonType: pythonFqn.slice(packageName.length + 1) };
|
|
271
|
-
}
|
|
272
316
|
// We'll just make a module-qualified reference at this point.
|
|
273
317
|
return {
|
|
274
318
|
pythonType: wrapType(pythonFqn.substring(submodulePythonName.length + 1)),
|
|
275
319
|
};
|
|
276
320
|
}
|
|
277
|
-
const [toImport, ...nested] = pythonFqn
|
|
278
|
-
.substring(typeSubmodulePythonName.length + 1)
|
|
279
|
-
.split('.');
|
|
280
|
-
const aliasSuffix = (0, crypto_1.createHash)('sha256')
|
|
281
|
-
.update(typeSubmodulePythonName)
|
|
282
|
-
.update('.')
|
|
283
|
-
.update(toImport)
|
|
284
|
-
.digest('hex')
|
|
285
|
-
.substring(0, 8);
|
|
286
|
-
const alias = `_${toImport}_${aliasSuffix}`;
|
|
287
|
-
return {
|
|
288
|
-
pythonType: wrapType([alias, ...nested].join('.')),
|
|
289
|
-
requiredImport: {
|
|
290
|
-
sourcePackage: relativeImportPath(submodulePythonName, typeSubmodulePythonName),
|
|
291
|
-
item: `${toImport} as ${alias}`,
|
|
292
|
-
},
|
|
293
|
-
};
|
|
294
321
|
}
|
|
295
322
|
}
|
|
296
323
|
_UserType_fqn = new WeakMap();
|
package/lib/targets/python.js
CHANGED
|
@@ -341,9 +341,6 @@ class BasePythonClassType {
|
|
|
341
341
|
code.line('pass');
|
|
342
342
|
}
|
|
343
343
|
code.closeBlock();
|
|
344
|
-
if (this.fqn != null) {
|
|
345
|
-
context.emittedTypes.add(this.fqn);
|
|
346
|
-
}
|
|
347
344
|
}
|
|
348
345
|
/**
|
|
349
346
|
* Sort the this.bases array for proper Python MRO.
|
|
@@ -469,7 +466,9 @@ class BaseMethod {
|
|
|
469
466
|
}
|
|
470
467
|
emit(code, context, opts) {
|
|
471
468
|
const { renderAbstract = true, forceEmitBody = false } = opts ?? {};
|
|
472
|
-
const returnType = (0, type_name_1.toTypeName)(this.returns).pythonType(
|
|
469
|
+
const returnType = (0, type_name_1.toTypeName)(this.returns).pythonType('type', {
|
|
470
|
+
...context,
|
|
471
|
+
});
|
|
473
472
|
// We cannot (currently?) blindly use the names given to us by the JSII for
|
|
474
473
|
// initializers, because our keyword lifting will allow two names to clash.
|
|
475
474
|
// This can hopefully be removed once we get https://github.com/aws/jsii/issues/288
|
|
@@ -492,7 +491,7 @@ class BaseMethod {
|
|
|
492
491
|
// This can hopefully be removed once we get https://github.com/aws/jsii/issues/288
|
|
493
492
|
// resolved.
|
|
494
493
|
const paramName = toPythonParameterName(param.name, liftedPropNames);
|
|
495
|
-
const paramType = typeFac.pythonType({
|
|
494
|
+
const paramType = typeFac.pythonType('type', {
|
|
496
495
|
...context,
|
|
497
496
|
parameterType: true,
|
|
498
497
|
});
|
|
@@ -525,10 +524,9 @@ class BaseMethod {
|
|
|
525
524
|
// Iterate over all of our props, and reflect them into our params.
|
|
526
525
|
for (const prop of liftedProperties) {
|
|
527
526
|
const paramName = toPythonParameterName(prop.prop.name);
|
|
528
|
-
const paramType = (0, type_name_1.toTypeName)(prop.prop).pythonType({
|
|
527
|
+
const paramType = (0, type_name_1.toTypeName)(prop.prop).pythonType('type', {
|
|
529
528
|
...context,
|
|
530
529
|
parameterType: true,
|
|
531
|
-
typeAnnotation: true,
|
|
532
530
|
});
|
|
533
531
|
const paramDefault = prop.prop.optional ? ' = None' : '';
|
|
534
532
|
pythonParams.push(`${paramName}: ${paramType}${paramDefault}`);
|
|
@@ -549,7 +547,7 @@ class BaseMethod {
|
|
|
549
547
|
pythonParams.pop();
|
|
550
548
|
const lastParameter = this.parameters.slice(-1)[0];
|
|
551
549
|
const paramName = toPythonParameterName(lastParameter.name);
|
|
552
|
-
const paramType = (0, type_name_1.toTypeName)(lastParameter.type).pythonType(context);
|
|
550
|
+
const paramType = (0, type_name_1.toTypeName)(lastParameter.type).pythonType('type', context);
|
|
553
551
|
pythonParams.push(`*${paramName}: ${paramType}`);
|
|
554
552
|
}
|
|
555
553
|
const decorators = new Array();
|
|
@@ -595,10 +593,7 @@ class BaseMethod {
|
|
|
595
593
|
emitAutoProps(code, context, liftedPropNames) {
|
|
596
594
|
const lastParameter = this.parameters.slice(-1)[0];
|
|
597
595
|
const argName = toPythonParameterName(lastParameter.name, liftedPropNames);
|
|
598
|
-
const typeName = (0, type_name_1.toTypeName)(lastParameter.type).pythonType(
|
|
599
|
-
...context,
|
|
600
|
-
typeAnnotation: false,
|
|
601
|
-
});
|
|
596
|
+
const typeName = (0, type_name_1.toTypeName)(lastParameter.type).pythonType('value', context);
|
|
602
597
|
// We need to build up a list of properties, which are mandatory, these are the
|
|
603
598
|
// ones we will specify to start with in our dictionary literal.
|
|
604
599
|
const liftedProps = this.getLiftedProperties(context.resolver).map((p) => new StructField(this.generator, p.prop, p.definingType));
|
|
@@ -616,10 +611,7 @@ class BaseMethod {
|
|
|
616
611
|
throw new Error('Parent not known.');
|
|
617
612
|
}
|
|
618
613
|
if (this.isStatic) {
|
|
619
|
-
jsiiMethodParams.push((0, type_name_1.toTypeName)(this.parent).pythonType(
|
|
620
|
-
...context,
|
|
621
|
-
typeAnnotation: false,
|
|
622
|
-
}));
|
|
614
|
+
jsiiMethodParams.push((0, type_name_1.toTypeName)(this.parent).pythonType('value', context));
|
|
623
615
|
}
|
|
624
616
|
else {
|
|
625
617
|
// Using the dynamic class of `self`.
|
|
@@ -698,7 +690,7 @@ class BaseProperty {
|
|
|
698
690
|
}
|
|
699
691
|
emit(code, context, opts) {
|
|
700
692
|
const { renderAbstract = true, forceEmitBody = false } = opts ?? {};
|
|
701
|
-
const pythonType = (0, type_name_1.toTypeName)(this.type).pythonType(context);
|
|
693
|
+
const pythonType = (0, type_name_1.toTypeName)(this.type).pythonType('type', context);
|
|
702
694
|
code.line(`@${this.decorator}`);
|
|
703
695
|
code.line(`@jsii.member(jsii_name="${this.jsName}")`);
|
|
704
696
|
if (renderAbstract && this.abstract) {
|
|
@@ -758,10 +750,7 @@ class Interface extends BasePythonClassType {
|
|
|
758
750
|
// Then, we have to emit a Proxy class which implements our proxy interface.
|
|
759
751
|
const proxyBases = this.bases.map((b) =>
|
|
760
752
|
// "# type: ignore[misc]" because MyPy cannot check dynamic base classes (naturally)
|
|
761
|
-
`jsii.proxy_for(${(0, type_name_1.toTypeName)(b).pythonType(
|
|
762
|
-
...context,
|
|
763
|
-
typeAnnotation: false,
|
|
764
|
-
})}) # type: ignore[misc]`);
|
|
753
|
+
`jsii.proxy_for(${(0, type_name_1.toTypeName)(b).pythonType('value', context)}) # type: ignore[misc]`);
|
|
765
754
|
openSignature(code, 'class', this.proxyClassName, proxyBases);
|
|
766
755
|
this.generator.emitDocString(code, this.apiLocation, this.docs, {
|
|
767
756
|
documentableItem: `class-${this.pythonName}`,
|
|
@@ -783,12 +772,9 @@ class Interface extends BasePythonClassType {
|
|
|
783
772
|
code.line();
|
|
784
773
|
code.line('# Adding a "__jsii_proxy_class__(): typing.Type" function to the interface');
|
|
785
774
|
code.line(`typing.cast(typing.Any, ${this.pythonName}).__jsii_proxy_class__ = lambda : ${this.proxyClassName}`);
|
|
786
|
-
if (this.fqn != null) {
|
|
787
|
-
context.emittedTypes.add(this.fqn);
|
|
788
|
-
}
|
|
789
775
|
}
|
|
790
776
|
getClassParams(context) {
|
|
791
|
-
const params = this.bases.map((b) => (0, type_name_1.toTypeName)(b).pythonType(
|
|
777
|
+
const params = this.bases.map((b) => (0, type_name_1.toTypeName)(b).pythonType('decl', context));
|
|
792
778
|
params.push('typing_extensions.Protocol');
|
|
793
779
|
return params;
|
|
794
780
|
}
|
|
@@ -842,15 +828,12 @@ class Struct extends BasePythonClassType {
|
|
|
842
828
|
}
|
|
843
829
|
this.emitMagicMethods(code);
|
|
844
830
|
code.closeBlock();
|
|
845
|
-
if (this.fqn != null) {
|
|
846
|
-
context.emittedTypes.add(this.fqn);
|
|
847
|
-
}
|
|
848
831
|
}
|
|
849
832
|
requiredImports(context) {
|
|
850
833
|
return (0, type_name_1.mergePythonImports)(super.requiredImports(context), ...this.allMembers.map((mem) => mem.requiredImports(context)));
|
|
851
834
|
}
|
|
852
835
|
getClassParams(context) {
|
|
853
|
-
return this.bases.map((b) => (0, type_name_1.toTypeName)(b).pythonType(
|
|
836
|
+
return this.bases.map((b) => (0, type_name_1.toTypeName)(b).pythonType('decl', context));
|
|
854
837
|
}
|
|
855
838
|
/**
|
|
856
839
|
* Find all fields (inherited as well)
|
|
@@ -876,10 +859,7 @@ class Struct extends BasePythonClassType {
|
|
|
876
859
|
// Re-type struct arguments that were passed as "dict". Do this before validating argument types...
|
|
877
860
|
for (const member of members.filter((m) => m.isStruct(this.generator))) {
|
|
878
861
|
// Note that "None" is NOT an instance of dict (that's convenient!)
|
|
879
|
-
const typeName = (0, type_name_1.toTypeName)(member.type.type).pythonType(
|
|
880
|
-
...context,
|
|
881
|
-
typeAnnotation: false,
|
|
882
|
-
});
|
|
862
|
+
const typeName = (0, type_name_1.toTypeName)(member.type.type).pythonType('value', context);
|
|
883
863
|
code.openBlock(`if isinstance(${member.pythonName}, dict)`);
|
|
884
864
|
code.line(`${member.pythonName} = ${typeName}(**${member.pythonName})`);
|
|
885
865
|
code.closeBlock();
|
|
@@ -987,7 +967,7 @@ class StructField {
|
|
|
987
967
|
* Return the Python type annotation for this type
|
|
988
968
|
*/
|
|
989
969
|
typeAnnotation(context) {
|
|
990
|
-
return (0, type_name_1.toTypeName)(this.type).pythonType(context);
|
|
970
|
+
return (0, type_name_1.toTypeName)(this.type).pythonType('type', context);
|
|
991
971
|
}
|
|
992
972
|
emitDocString(code) {
|
|
993
973
|
this.generator.emitDocString(code, this.apiLocation, this.docs, {
|
|
@@ -1042,7 +1022,7 @@ class Class extends BasePythonClassType {
|
|
|
1042
1022
|
emit(code, context) {
|
|
1043
1023
|
// First we emit our implments decorator
|
|
1044
1024
|
if (this.interfaces.length > 0) {
|
|
1045
|
-
const interfaces = this.interfaces.map((b) => (0, type_name_1.toTypeName)(b).pythonType(
|
|
1025
|
+
const interfaces = this.interfaces.map((b) => (0, type_name_1.toTypeName)(b).pythonType('decl', context));
|
|
1046
1026
|
code.line(`@jsii.implements(${interfaces.join(', ')})`);
|
|
1047
1027
|
}
|
|
1048
1028
|
// Then we do our normal class logic for emitting our members.
|
|
@@ -1055,10 +1035,7 @@ class Class extends BasePythonClassType {
|
|
|
1055
1035
|
const proxyBases = [this.pythonName];
|
|
1056
1036
|
for (const base of this.abstractBases) {
|
|
1057
1037
|
// "# type: ignore[misc]" because MyPy cannot check dynamic base classes (naturally)
|
|
1058
|
-
proxyBases.push(`jsii.proxy_for(${(0, type_name_1.toTypeName)(base).pythonType(
|
|
1059
|
-
...context,
|
|
1060
|
-
typeAnnotation: false,
|
|
1061
|
-
})}) # type: ignore[misc]`);
|
|
1038
|
+
proxyBases.push(`jsii.proxy_for(${(0, type_name_1.toTypeName)(base).pythonType('value', context)}) # type: ignore[misc]`);
|
|
1062
1039
|
}
|
|
1063
1040
|
code.line();
|
|
1064
1041
|
code.line();
|
|
@@ -1090,7 +1067,7 @@ class Class extends BasePythonClassType {
|
|
|
1090
1067
|
}
|
|
1091
1068
|
}
|
|
1092
1069
|
getClassParams(context) {
|
|
1093
|
-
const params = this.bases.map((b) => (0, type_name_1.toTypeName)(b).pythonType(
|
|
1070
|
+
const params = this.bases.map((b) => (0, type_name_1.toTypeName)(b).pythonType('decl', context));
|
|
1094
1071
|
const metaclass = this.abstract ? 'JSIIAbstractClass' : 'JSIIMeta';
|
|
1095
1072
|
params.push(`metaclass=jsii.${metaclass}`);
|
|
1096
1073
|
params.push(`jsii_type="${this.fqn}"`);
|
|
@@ -1948,7 +1925,6 @@ class PythonGenerator extends generator_1.Generator {
|
|
|
1948
1925
|
const resolver = new TypeResolver(this.types, assm, (fqn) => this.findModule(fqn), (fqn) => this.findType(fqn));
|
|
1949
1926
|
this.package.write(this.code, {
|
|
1950
1927
|
assembly: assm,
|
|
1951
|
-
emittedTypes: new Set(),
|
|
1952
1928
|
resolver,
|
|
1953
1929
|
runtimeTypeChecking: this.runtimeTypeChecking,
|
|
1954
1930
|
submodule: assm.name,
|
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.
|
|
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-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
41
|
-
"@jsii/spec": "1.
|
|
40
|
+
"@jsii/check-node": "1.122.0",
|
|
41
|
+
"@jsii/spec": "1.122.0",
|
|
42
42
|
"clone": "^2.1.2",
|
|
43
|
-
"codemaker": "^1.
|
|
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.
|
|
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.
|
|
55
|
-
"@jsii/go-runtime": "^1.
|
|
56
|
-
"@jsii/java-runtime": "^1.
|
|
57
|
-
"@scope/jsii-calc-lib": "^1.
|
|
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.
|
|
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"
|