jsii-pacmak 1.65.0 → 1.67.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/generate.sh +2 -1
- package/lib/targets/dotnet/dotnetgenerator.js +19 -110
- package/lib/targets/dotnet/dotnettyperesolver.js +5 -4
- package/lib/targets/dotnet/runtime-type-checking.d.ts +13 -0
- package/lib/targets/dotnet/runtime-type-checking.js +146 -0
- package/lib/targets/go/dependencies.d.ts +16 -0
- package/lib/targets/go/dependencies.js +59 -0
- package/lib/targets/go/emit-context.d.ts +2 -0
- package/lib/targets/go/package.d.ts +1 -0
- package/lib/targets/go/package.js +54 -33
- package/lib/targets/go/runtime/class-constructor.d.ts +2 -1
- package/lib/targets/go/runtime/class-constructor.js +4 -1
- package/lib/targets/go/runtime/method-call.d.ts +2 -2
- package/lib/targets/go/runtime/method-call.js +11 -5
- package/lib/targets/go/runtime/property-access.d.ts +3 -2
- package/lib/targets/go/runtime/property-access.js +7 -2
- package/lib/targets/go/runtime/runtime-type-checking.d.ts +29 -0
- package/lib/targets/go/runtime/runtime-type-checking.js +408 -0
- package/lib/targets/go/types/class.d.ts +10 -5
- package/lib/targets/go/types/class.js +60 -30
- package/lib/targets/go/types/enum.d.ts +2 -2
- package/lib/targets/go/types/enum.js +6 -2
- package/lib/targets/go/types/go-type-reference.d.ts +6 -1
- package/lib/targets/go/types/go-type-reference.js +37 -21
- package/lib/targets/go/types/go-type.d.ts +4 -1
- package/lib/targets/go/types/go-type.js +3 -0
- package/lib/targets/go/types/interface.d.ts +5 -3
- package/lib/targets/go/types/interface.js +40 -17
- package/lib/targets/go/types/struct.d.ts +7 -3
- package/lib/targets/go/types/struct.js +41 -2
- package/lib/targets/go/types/type-member.d.ts +8 -1
- package/lib/targets/go/types/type-member.js +63 -18
- package/lib/targets/go.d.ts +6 -2
- package/lib/targets/go.js +6 -4
- package/lib/targets/java.d.ts +19 -0
- package/lib/targets/java.js +223 -1
- package/lib/targets/python/type-name.js +3 -3
- package/lib/targets/python.js +5 -1
- package/lib/version.d.ts +2 -2
- package/lib/version.js +4 -3
- package/package.json +14 -14
package/generate.sh
CHANGED
|
@@ -15,7 +15,8 @@ cat > lib/version.ts <<HERE
|
|
|
15
15
|
// Generated at $(date -u +"%Y-%m-%dT%H:%M:%SZ") by generate.sh
|
|
16
16
|
|
|
17
17
|
/** The short version number for this JSII compiler (e.g: \`X.Y.Z\`) */
|
|
18
|
-
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-inferrable-types
|
|
19
|
+
export const VERSION: string = '${VERSION}';
|
|
19
20
|
|
|
20
21
|
/** The qualified version number for this JSII compiler (e.g: \`X.Y.Z (build #######)\`) */
|
|
21
22
|
export const VERSION_DESC = '${VERSION} (build ${commit:0:7}${suffix:-})';
|
|
@@ -3,10 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.DotNetGenerator = void 0;
|
|
4
4
|
const spec = require("@jsii/spec");
|
|
5
5
|
const clone = require("clone");
|
|
6
|
-
const crypto_1 = require("crypto");
|
|
7
6
|
const fs = require("fs-extra");
|
|
8
7
|
const http = require("http");
|
|
9
8
|
const https = require("https");
|
|
9
|
+
const reflect = require("jsii-reflect");
|
|
10
10
|
const path = require("path");
|
|
11
11
|
const generator_1 = require("../../generator");
|
|
12
12
|
const logging_1 = require("../../logging");
|
|
@@ -15,6 +15,7 @@ const dotnetruntimegenerator_1 = require("./dotnetruntimegenerator");
|
|
|
15
15
|
const dotnettyperesolver_1 = require("./dotnettyperesolver");
|
|
16
16
|
const filegenerator_1 = require("./filegenerator");
|
|
17
17
|
const nameutils_1 = require("./nameutils");
|
|
18
|
+
const runtime_type_checking_1 = require("./runtime-type-checking");
|
|
18
19
|
/**
|
|
19
20
|
* CODE GENERATOR V2
|
|
20
21
|
*/
|
|
@@ -272,7 +273,8 @@ class DotNetGenerator extends generator_1.Generator {
|
|
|
272
273
|
// the instance will be created in the kernel (where it'd fail on a sub-optimal error instead)...
|
|
273
274
|
this.code.line('[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]');
|
|
274
275
|
this.code.openBlock(`private static DeputyProps _MakeDeputyProps(${parametersDefinition})`);
|
|
275
|
-
this.emitUnionParameterValdation(
|
|
276
|
+
this.emitUnionParameterValdation(this.reflectAssembly.findType(cls.fqn)
|
|
277
|
+
.initializer?.parameters);
|
|
276
278
|
const args = parametersBase.length > 0
|
|
277
279
|
? `new object?[]{${parametersBase}}`
|
|
278
280
|
: `System.Array.Empty<object?>()`;
|
|
@@ -432,7 +434,7 @@ class DotNetGenerator extends generator_1.Generator {
|
|
|
432
434
|
}
|
|
433
435
|
else {
|
|
434
436
|
this.code.openBlock(`${access} ${staticKeyWord}${overrideKeyWord}${virtualKeyWord}${signature}`);
|
|
435
|
-
this.emitUnionParameterValdation(method.parameters);
|
|
437
|
+
this.emitUnionParameterValdation(this.reflectAssembly.findType(cls.fqn).allMethods.find((m) => m.name === method.name).parameters);
|
|
436
438
|
this.code.line(this.dotnetRuntimeGenerator.createInvokeMethodIdentifier(method, cls));
|
|
437
439
|
this.code.closeBlock();
|
|
438
440
|
}
|
|
@@ -443,113 +445,18 @@ class DotNetGenerator extends generator_1.Generator {
|
|
|
443
445
|
* @param parameters the list of parameters received by the function.
|
|
444
446
|
* @param noMangle use parameter names as-is (useful for setters, for example) instead of mangling them.
|
|
445
447
|
*/
|
|
446
|
-
emitUnionParameterValdation(parameters, { noMangle
|
|
448
|
+
emitUnionParameterValdation(parameters = [], opts = { noMangle: false }) {
|
|
447
449
|
if (!this.runtimeTypeChecking) {
|
|
448
450
|
// We were configured not to emit those, so bail out now.
|
|
449
451
|
return;
|
|
450
452
|
}
|
|
451
|
-
const
|
|
452
|
-
if (
|
|
453
|
+
const validator = runtime_type_checking_1.ParameterValidator.forParameters(parameters, this.nameutils, opts);
|
|
454
|
+
if (validator == null) {
|
|
453
455
|
return;
|
|
454
456
|
}
|
|
455
457
|
this.code.openBlock('if (Amazon.JSII.Runtime.Configuration.RuntimeTypeChecking)');
|
|
456
|
-
|
|
457
|
-
const name = noMangle
|
|
458
|
-
? param.name
|
|
459
|
-
: this.nameutils.convertParameterName(param.name);
|
|
460
|
-
if (param.optional) {
|
|
461
|
-
this.code.openBlock(`if (${name} != null)`);
|
|
462
|
-
}
|
|
463
|
-
validate.call(this, name, noMangle ? name : `argument {nameof(${name})}`, param.type, noMangle ? name : `{nameof(${name})}`);
|
|
464
|
-
if (param.optional) {
|
|
465
|
-
this.code.closeBlock();
|
|
466
|
-
}
|
|
467
|
-
}
|
|
458
|
+
validator.emit(this.code, this.typeresolver);
|
|
468
459
|
this.code.closeBlock();
|
|
469
|
-
function validate(value, descr, type, parameterName) {
|
|
470
|
-
if (spec.isUnionTypeReference(type)) {
|
|
471
|
-
validateTypeUnion.call(this, value, descr, type, parameterName);
|
|
472
|
-
}
|
|
473
|
-
else {
|
|
474
|
-
const collectionType = type;
|
|
475
|
-
if (collectionType.collection.kind === spec.CollectionKind.Array) {
|
|
476
|
-
validateArray.call(this, value, descr, collectionType.collection.elementtype, parameterName);
|
|
477
|
-
}
|
|
478
|
-
else if (collectionType.collection.kind === spec.CollectionKind.Map) {
|
|
479
|
-
validateMap.call(this, value, descr, collectionType.collection.elementtype, parameterName);
|
|
480
|
-
}
|
|
481
|
-
else {
|
|
482
|
-
throw new Error(`Unhandled collection kind: ${spec.describeTypeReference(type)}`);
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
function validateArray(value, descr, elementType, parameterName) {
|
|
487
|
-
const varName = `__idx_${(0, crypto_1.createHash)('sha256')
|
|
488
|
-
.update(descr)
|
|
489
|
-
.digest('hex')
|
|
490
|
-
.slice(0, 6)}`;
|
|
491
|
-
this.code.openBlock(`for (int ${varName} = 0 ; ${varName} < ${value}.Length ; ${varName}++)`);
|
|
492
|
-
validate.call(this, `${value}[${varName}]`, `${descr}[{${varName}}]`, elementType, parameterName);
|
|
493
|
-
this.code.closeBlock();
|
|
494
|
-
}
|
|
495
|
-
function validateMap(value, descr, elementType, parameterName) {
|
|
496
|
-
const varName = `__item_${(0, crypto_1.createHash)('sha256')
|
|
497
|
-
.update(descr)
|
|
498
|
-
.digest('hex')
|
|
499
|
-
.slice(0, 6)}`;
|
|
500
|
-
this.code.openBlock(`foreach (var ${varName} in ${value})`);
|
|
501
|
-
validate.call(this, `${varName}.Value`, `${descr}[\\"{${varName}.Key}\\"]`, elementType, parameterName);
|
|
502
|
-
this.code.closeBlock();
|
|
503
|
-
}
|
|
504
|
-
function validateTypeUnion(value, descr, type, parameterName) {
|
|
505
|
-
this.code.indent('if (');
|
|
506
|
-
let emitAnd = false;
|
|
507
|
-
const typeRefs = type.union.types;
|
|
508
|
-
for (const typeRef of typeRefs) {
|
|
509
|
-
const prefix = emitAnd ? '&& ' : '';
|
|
510
|
-
const dotNetType = this.typeresolver.toDotNetType(typeRef);
|
|
511
|
-
// In the case of double, we test for all standard numeric types of .NET (these implicitly convert).
|
|
512
|
-
const test = dotNetType === 'double'
|
|
513
|
-
? [
|
|
514
|
-
'byte',
|
|
515
|
-
'decimal',
|
|
516
|
-
'double',
|
|
517
|
-
'float',
|
|
518
|
-
'int',
|
|
519
|
-
'long',
|
|
520
|
-
'sbyte',
|
|
521
|
-
'short',
|
|
522
|
-
'uint',
|
|
523
|
-
'ulong',
|
|
524
|
-
'ushort',
|
|
525
|
-
]
|
|
526
|
-
.map((numeric) => `${value} is ${numeric}`)
|
|
527
|
-
.join(' || ')
|
|
528
|
-
: `${value} is ${dotNetType}`;
|
|
529
|
-
this.code.line(`${prefix}!(${test})`);
|
|
530
|
-
emitAnd = true;
|
|
531
|
-
}
|
|
532
|
-
if (typeRefs.some((ref) => spec.isNamedTypeReference(ref) &&
|
|
533
|
-
spec.isInterfaceType(this.findType(ref.fqn)))) {
|
|
534
|
-
// AnonymousObject will convert to any interface type, even if unsafely. It is the opaque
|
|
535
|
-
// type returned when a non-intrinsically typed value is passed through an any or union
|
|
536
|
-
// return point. We basically cannot type-check that at runtime in a complete way.
|
|
537
|
-
this.code.line(`&& !(${value} is Amazon.JSII.Runtime.Deputy.AnonymousObject)`);
|
|
538
|
-
}
|
|
539
|
-
this.code.unindent(')');
|
|
540
|
-
this.code.openBlock('');
|
|
541
|
-
const placeholders = typeRefs
|
|
542
|
-
.map((typeRef) => {
|
|
543
|
-
const typeName = this.typeresolver.toDotNetTypeName(typeRef);
|
|
544
|
-
if (typeName.startsWith('"') && typeName.endsWith('"')) {
|
|
545
|
-
return typeName.slice(1, -1);
|
|
546
|
-
}
|
|
547
|
-
return `{${typeName}}`;
|
|
548
|
-
})
|
|
549
|
-
.join(', ');
|
|
550
|
-
this.code.line(`throw new System.ArgumentException($"Expected ${descr} to be one of: ${placeholders}; received {${value}.GetType().FullName}", $"${parameterName}");`);
|
|
551
|
-
this.code.closeBlock();
|
|
552
|
-
}
|
|
553
460
|
}
|
|
554
461
|
/**
|
|
555
462
|
* Founds out if a member (property or method) is already defined in one of the base classes
|
|
@@ -870,15 +777,15 @@ class DotNetGenerator extends generator_1.Generator {
|
|
|
870
777
|
}
|
|
871
778
|
}
|
|
872
779
|
// Emit setters
|
|
780
|
+
const reflectCls = this.reflectAssembly.findType(cls.fqn);
|
|
781
|
+
const syntheticParam = new reflect.Parameter(reflectCls.system, reflectCls, new reflect.Method(reflectCls.system, reflectCls.assembly, reflectCls, reflectCls, { name: '<synthetic>' }), {
|
|
782
|
+
name: 'value',
|
|
783
|
+
type: prop.type,
|
|
784
|
+
optional: prop.optional,
|
|
785
|
+
});
|
|
873
786
|
if (backingFieldName) {
|
|
874
787
|
this.code.openBlock('set');
|
|
875
|
-
this.emitUnionParameterValdation([
|
|
876
|
-
{
|
|
877
|
-
name: 'value',
|
|
878
|
-
type: prop.type,
|
|
879
|
-
optional: prop.optional,
|
|
880
|
-
},
|
|
881
|
-
], { noMangle: true });
|
|
788
|
+
this.emitUnionParameterValdation([syntheticParam], { noMangle: true });
|
|
882
789
|
this.code.line(`${backingFieldName} = value;`);
|
|
883
790
|
this.code.closeBlock();
|
|
884
791
|
}
|
|
@@ -892,7 +799,9 @@ class DotNetGenerator extends generator_1.Generator {
|
|
|
892
799
|
: 'SetInstanceProperty(value);';
|
|
893
800
|
if (containsUnionType(prop.type)) {
|
|
894
801
|
this.code.openBlock('set');
|
|
895
|
-
this.emitUnionParameterValdation([
|
|
802
|
+
this.emitUnionParameterValdation([syntheticParam], {
|
|
803
|
+
noMangle: true,
|
|
804
|
+
});
|
|
896
805
|
this.code.line(setCode);
|
|
897
806
|
this.code.closeBlock();
|
|
898
807
|
}
|
|
@@ -203,13 +203,14 @@ class DotNetTypeResolver {
|
|
|
203
203
|
* Translates a collection in jsii to the name of a native .NET collection
|
|
204
204
|
*/
|
|
205
205
|
toDotNetCollectionName(ref) {
|
|
206
|
+
const [_, dollar, quote, content] = /^(?:(\$)?("))?([^"]+)"?$/.exec(this.toDotNetTypeName(ref.collection.elementtype));
|
|
207
|
+
const interpolates = dollar || !quote ? '$' : '';
|
|
208
|
+
const elementTypeName = quote ? content : `{${content}}`;
|
|
206
209
|
switch (ref.collection.kind) {
|
|
207
210
|
case spec.CollectionKind.Array:
|
|
208
|
-
|
|
209
|
-
return `$"{${elementDotNetTypeName}}[]"`;
|
|
211
|
+
return `${interpolates}"${elementTypeName}[]"`;
|
|
210
212
|
case spec.CollectionKind.Map:
|
|
211
|
-
|
|
212
|
-
return `typeof(System.Collections.Generic.IDictionary<string, ${elementDotNetType}>).FullName`;
|
|
213
|
+
return `${interpolates}"System.Collections.Generic.IDictionary<string, ${elementTypeName}>"`;
|
|
213
214
|
default:
|
|
214
215
|
throw new Error(`Unsupported collection kind: ${ref.collection.kind}`);
|
|
215
216
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { CodeMaker } from 'codemaker';
|
|
2
|
+
import { Parameter } from 'jsii-reflect';
|
|
3
|
+
import { DotNetTypeResolver } from './dotnettyperesolver';
|
|
4
|
+
import { DotNetNameUtils } from './nameutils';
|
|
5
|
+
export declare class ParameterValidator {
|
|
6
|
+
private readonly validations;
|
|
7
|
+
static forParameters(parameters: readonly Parameter[], nameUtils: DotNetNameUtils, { noMangle }: {
|
|
8
|
+
readonly noMangle: boolean;
|
|
9
|
+
}): ParameterValidator | undefined;
|
|
10
|
+
private constructor();
|
|
11
|
+
emit(code: CodeMaker, resolver: DotNetTypeResolver): void;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=runtime-type-checking.d.ts.map
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ParameterValidator = void 0;
|
|
4
|
+
const spec_1 = require("@jsii/spec");
|
|
5
|
+
const crypto_1 = require("crypto");
|
|
6
|
+
const jsii_reflect_1 = require("jsii-reflect");
|
|
7
|
+
class ParameterValidator {
|
|
8
|
+
constructor(validations) {
|
|
9
|
+
this.validations = validations;
|
|
10
|
+
}
|
|
11
|
+
static forParameters(parameters, nameUtils, { noMangle }) {
|
|
12
|
+
if (parameters.length === 0) {
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
const parameterValidations = new Map();
|
|
16
|
+
for (const param of parameters) {
|
|
17
|
+
const expr = noMangle
|
|
18
|
+
? param.name
|
|
19
|
+
: nameUtils.convertParameterName(param.name);
|
|
20
|
+
const argName = `nameof(${expr})`;
|
|
21
|
+
const validations = new Array();
|
|
22
|
+
const validation = Validation.forTypeReference(argName, expr, `${noMangle ? '' : 'argument '}{${argName}}`, param.variadic
|
|
23
|
+
? new jsii_reflect_1.TypeReference(param.system, {
|
|
24
|
+
collection: {
|
|
25
|
+
kind: spec_1.CollectionKind.Array,
|
|
26
|
+
elementtype: param.type.spec,
|
|
27
|
+
},
|
|
28
|
+
})
|
|
29
|
+
: param.type, param.optional);
|
|
30
|
+
if (validation) {
|
|
31
|
+
validations.push(validation);
|
|
32
|
+
}
|
|
33
|
+
if (validations.length !== 0) {
|
|
34
|
+
parameterValidations.set(param, validations);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (parameterValidations.size === 0) {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
return new ParameterValidator(parameterValidations);
|
|
41
|
+
}
|
|
42
|
+
emit(code, resolver) {
|
|
43
|
+
for (const [_parameter, validations] of this.validations) {
|
|
44
|
+
for (const validation of validations) {
|
|
45
|
+
validation.emit(code, resolver);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.ParameterValidator = ParameterValidator;
|
|
51
|
+
class Validation {
|
|
52
|
+
static forTypeReference(argument, expression, description, ref, allowNull) {
|
|
53
|
+
if (ref.unionOfTypes) {
|
|
54
|
+
return Validation.unionCheck(argument, expression, description, ref.unionOfTypes, allowNull);
|
|
55
|
+
}
|
|
56
|
+
else if (ref.arrayOfType) {
|
|
57
|
+
return Validation.collectionCheck(argument, expression, description, 'array', ref.arrayOfType);
|
|
58
|
+
}
|
|
59
|
+
else if (ref.mapOfType) {
|
|
60
|
+
return Validation.collectionCheck(argument, expression, description, 'map', ref.mapOfType);
|
|
61
|
+
}
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
static collectionCheck(argument, expression, description, type, elementType) {
|
|
65
|
+
const elementValidator = Validation.forTypeReference(argument, `${expression}[idx]`, `${description}[@{idx}]`, elementType, false);
|
|
66
|
+
if (elementValidator == null) {
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
class CollectionCheck extends Validation {
|
|
70
|
+
emit(code, resolver) {
|
|
71
|
+
// We need to come up with a unique-enough ID here... so we use a hash.
|
|
72
|
+
const prefix = type === 'array' ? '__idx' : '__item';
|
|
73
|
+
const varName = `${prefix}_${(0, crypto_1.createHash)('sha256')
|
|
74
|
+
.update(expression)
|
|
75
|
+
.digest('hex')
|
|
76
|
+
.slice(0, 6)}`;
|
|
77
|
+
if (type === 'array') {
|
|
78
|
+
code.openBlock(`for (var ${varName} = 0 ; ${varName} < ${expression}.Length ; ${varName}++)`);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
code.openBlock(`foreach (var ${varName} in ${expression})`);
|
|
82
|
+
}
|
|
83
|
+
Validation.forTypeReference(argument, type === 'array' ? `${expression}[${varName}]` : `${varName}.Value`, `${description}[${type === 'array' ? `{${varName}}` : `"{${varName}.Key}"`}]`, elementType, false).emit(code, resolver);
|
|
84
|
+
code.closeBlock();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return new CollectionCheck();
|
|
88
|
+
}
|
|
89
|
+
static unionCheck(argument, expression, description, types, allowNull) {
|
|
90
|
+
const hasInterface = types.some((t) => t.type?.isInterfaceType());
|
|
91
|
+
class UnionCheck extends Validation {
|
|
92
|
+
emit(code, resolver) {
|
|
93
|
+
const validTypes = new Array();
|
|
94
|
+
const castVarName = `cast_${(0, crypto_1.createHash)('sha256')
|
|
95
|
+
.update(expression)
|
|
96
|
+
.digest('hex')
|
|
97
|
+
.slice(0, 6)}`;
|
|
98
|
+
code.openBlock(`switch (${expression})`);
|
|
99
|
+
for (const type of types) {
|
|
100
|
+
validTypes.push(resolver.toDotNetTypeName(type.spec));
|
|
101
|
+
const typeNames = [resolver.toDotNetType(type.spec)];
|
|
102
|
+
if (typeNames[0] === 'double') {
|
|
103
|
+
// For doubles, we accept any numeric value, really...
|
|
104
|
+
typeNames.push('byte', 'decimal', 'float', 'int', 'long', 'sbyte', 'short', 'uint', 'ulong', 'ushort');
|
|
105
|
+
}
|
|
106
|
+
for (const typeName of typeNames) {
|
|
107
|
+
code.indent(`case ${typeName} ${castVarName}:`);
|
|
108
|
+
Validation.forTypeReference(argument, castVarName, description, type, allowNull)?.emit(code, resolver);
|
|
109
|
+
code.line('break;');
|
|
110
|
+
code.unindent(false);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (hasInterface) {
|
|
114
|
+
code.indent(`case Amazon.JSII.Runtime.Deputy.AnonymousObject ${castVarName}:`);
|
|
115
|
+
code.line('// Not enough information to type-check...');
|
|
116
|
+
code.line('break;');
|
|
117
|
+
code.unindent(false);
|
|
118
|
+
}
|
|
119
|
+
code.indent('case null:');
|
|
120
|
+
const acceptedTypes = validTypes
|
|
121
|
+
.map((t) => t.startsWith('"')
|
|
122
|
+
? t.slice(1, t.length - 1)
|
|
123
|
+
: t.startsWith('$"')
|
|
124
|
+
? t.slice(2, t.length - 1)
|
|
125
|
+
: `{${t}}`)
|
|
126
|
+
.join(', ');
|
|
127
|
+
if (allowNull) {
|
|
128
|
+
code.line('break;');
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
const message = JSON.stringify(`Expected ${description} to be one of: ${acceptedTypes}; received null`);
|
|
132
|
+
code.line(`throw new System.ArgumentException($${message}, ${argument});`);
|
|
133
|
+
}
|
|
134
|
+
code.unindent(false);
|
|
135
|
+
code.indent('default:');
|
|
136
|
+
const message = JSON.stringify(`Expected ${description} to be one of: ${acceptedTypes}; received {${expression}.GetType().FullName}`);
|
|
137
|
+
code.line(`throw new System.ArgumentException($${message}, ${argument});`);
|
|
138
|
+
code.unindent(false);
|
|
139
|
+
code.closeBlock();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return new UnionCheck();
|
|
143
|
+
}
|
|
144
|
+
constructor() { }
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=runtime-type-checking.js.map
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import { Package } from './package';
|
|
1
2
|
/**
|
|
2
3
|
* Information about a module's dependency on "special" packages (either part of
|
|
3
4
|
* the go standard library, or generated as part of the current module).
|
|
4
5
|
*/
|
|
5
6
|
export interface SpecialDependencies {
|
|
7
|
+
/** Whether the go standard library for string formatting is needed */
|
|
8
|
+
readonly fmt: boolean;
|
|
6
9
|
/** Whether the jsii runtime library for go is needed */
|
|
7
10
|
readonly runtime: boolean;
|
|
8
11
|
/** Whether the package's initialization hook is needed */
|
|
@@ -12,4 +15,17 @@ export interface SpecialDependencies {
|
|
|
12
15
|
/** Whether go's standard library "time" module is needed */
|
|
13
16
|
readonly time: boolean;
|
|
14
17
|
}
|
|
18
|
+
export declare function reduceSpecialDependencies(...specialDepsList: readonly SpecialDependencies[]): SpecialDependencies;
|
|
19
|
+
export interface ImportedModule {
|
|
20
|
+
readonly alias?: string;
|
|
21
|
+
readonly module: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function toImportedModules(specialDeps: SpecialDependencies, context: Package): readonly ImportedModule[];
|
|
24
|
+
/**
|
|
25
|
+
* The name of a sub-package that includes internal type aliases it has to be
|
|
26
|
+
* "internal" so it not published.
|
|
27
|
+
*/
|
|
28
|
+
export declare const INTERNAL_PACKAGE_NAME = "internal";
|
|
29
|
+
export declare const JSII_RT_MODULE: ImportedModule;
|
|
30
|
+
export declare const GO_REFLECT: ImportedModule;
|
|
15
31
|
//# sourceMappingURL=dependencies.d.ts.map
|
|
@@ -1,3 +1,62 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GO_REFLECT = exports.JSII_RT_MODULE = exports.INTERNAL_PACKAGE_NAME = exports.toImportedModules = exports.reduceSpecialDependencies = void 0;
|
|
4
|
+
const assert = require("assert");
|
|
5
|
+
const runtime_1 = require("./runtime");
|
|
6
|
+
function reduceSpecialDependencies(...specialDepsList) {
|
|
7
|
+
const [first, ...rest] = specialDepsList;
|
|
8
|
+
if (!first) {
|
|
9
|
+
assert(rest.length === 0);
|
|
10
|
+
return {
|
|
11
|
+
fmt: false,
|
|
12
|
+
init: false,
|
|
13
|
+
internal: false,
|
|
14
|
+
runtime: false,
|
|
15
|
+
time: false,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
return rest.reduce((acc, elt) => ({
|
|
19
|
+
fmt: acc.fmt || elt.fmt,
|
|
20
|
+
init: acc.init || elt.init,
|
|
21
|
+
internal: acc.internal || elt.internal,
|
|
22
|
+
runtime: acc.runtime || elt.runtime,
|
|
23
|
+
time: acc.time || elt.time,
|
|
24
|
+
}), first);
|
|
25
|
+
}
|
|
26
|
+
exports.reduceSpecialDependencies = reduceSpecialDependencies;
|
|
27
|
+
function toImportedModules(specialDeps, context) {
|
|
28
|
+
const result = new Array();
|
|
29
|
+
if (specialDeps.fmt) {
|
|
30
|
+
result.push({ module: 'fmt' });
|
|
31
|
+
}
|
|
32
|
+
if (specialDeps.time) {
|
|
33
|
+
result.push({ module: 'time' });
|
|
34
|
+
}
|
|
35
|
+
if (specialDeps.runtime) {
|
|
36
|
+
result.push(exports.JSII_RT_MODULE);
|
|
37
|
+
}
|
|
38
|
+
if (specialDeps.init) {
|
|
39
|
+
result.push({
|
|
40
|
+
alias: runtime_1.JSII_INIT_ALIAS,
|
|
41
|
+
module: `${context.root.goModuleName}/${runtime_1.JSII_INIT_PACKAGE}`,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
if (specialDeps.internal) {
|
|
45
|
+
result.push({
|
|
46
|
+
module: `${context.goModuleName}/${exports.INTERNAL_PACKAGE_NAME}`,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
exports.toImportedModules = toImportedModules;
|
|
52
|
+
/**
|
|
53
|
+
* The name of a sub-package that includes internal type aliases it has to be
|
|
54
|
+
* "internal" so it not published.
|
|
55
|
+
*/
|
|
56
|
+
exports.INTERNAL_PACKAGE_NAME = 'internal';
|
|
57
|
+
exports.JSII_RT_MODULE = {
|
|
58
|
+
alias: runtime_1.JSII_RT_ALIAS,
|
|
59
|
+
module: runtime_1.JSII_RT_PACKAGE_NAME,
|
|
60
|
+
};
|
|
61
|
+
exports.GO_REFLECT = { module: 'reflect' };
|
|
3
62
|
//# sourceMappingURL=dependencies.js.map
|
|
@@ -8,5 +8,7 @@ export interface EmitContext {
|
|
|
8
8
|
readonly code: CodeMaker;
|
|
9
9
|
/** A Documentation generator. Includes Rosetta stone to translate code examples. */
|
|
10
10
|
readonly documenter: Documentation;
|
|
11
|
+
/** Whether runtime type checking code should be emitted */
|
|
12
|
+
readonly runtimeTypeChecking: boolean;
|
|
11
13
|
}
|
|
12
14
|
//# sourceMappingURL=emit-context.d.ts.map
|
|
@@ -4,6 +4,7 @@ exports.InternalPackage = exports.RootPackage = exports.Package = exports.GO_VER
|
|
|
4
4
|
const path_1 = require("path");
|
|
5
5
|
const semver = require("semver");
|
|
6
6
|
const version_1 = require("../../version");
|
|
7
|
+
const dependencies_1 = require("./dependencies");
|
|
7
8
|
const readme_file_1 = require("./readme-file");
|
|
8
9
|
const runtime_1 = require("./runtime");
|
|
9
10
|
const types_1 = require("./types");
|
|
@@ -11,9 +12,6 @@ const util_1 = require("./util");
|
|
|
11
12
|
const version_file_1 = require("./version-file");
|
|
12
13
|
exports.GOMOD_FILENAME = 'go.mod';
|
|
13
14
|
exports.GO_VERSION = '1.16';
|
|
14
|
-
// the name of a sub-package that includes internal type aliases it has to be
|
|
15
|
-
// "internal" so it not published.
|
|
16
|
-
const INTERNAL_PACKAGE_NAME = 'internal';
|
|
17
15
|
/*
|
|
18
16
|
* Package represents a single `.go` source file within a package. This can be the root package file or a submodule
|
|
19
17
|
*/
|
|
@@ -121,7 +119,7 @@ class Package {
|
|
|
121
119
|
foriegnTypeName: original,
|
|
122
120
|
foriegnType: typeref,
|
|
123
121
|
fieldName: aliasName,
|
|
124
|
-
embed: `${INTERNAL_PACKAGE_NAME}.${aliasName}`,
|
|
122
|
+
embed: `${dependencies_1.INTERNAL_PACKAGE_NAME}.${aliasName}`,
|
|
125
123
|
};
|
|
126
124
|
this.embeddedTypes.set(type.fqn, embeddedType);
|
|
127
125
|
return embeddedType;
|
|
@@ -136,21 +134,22 @@ class Package {
|
|
|
136
134
|
* responsible for correctly initializing the module, including registering
|
|
137
135
|
* the declared types with the jsii runtime for go.
|
|
138
136
|
*/
|
|
139
|
-
emitGoInitFunction(
|
|
137
|
+
emitGoInitFunction(context) {
|
|
140
138
|
// We don't emit anything if there are not types in this (sub)module. This
|
|
141
139
|
// avoids registering an `init` function that does nothing, which is poor
|
|
142
140
|
// form. It also saves us from "imported but unused" errors that would arise
|
|
143
141
|
// as a consequence.
|
|
144
142
|
if (this.types.length > 0) {
|
|
143
|
+
const { code } = context;
|
|
145
144
|
const initFile = (0, path_1.join)(this.directory, `${this.packageName}.go`);
|
|
146
145
|
code.openFile(initFile);
|
|
147
146
|
code.line(`package ${this.packageName}`);
|
|
148
147
|
code.line();
|
|
149
|
-
importGoModules(code, [GO_REFLECT, JSII_RT_MODULE]);
|
|
148
|
+
importGoModules(code, [dependencies_1.GO_REFLECT, dependencies_1.JSII_RT_MODULE]);
|
|
150
149
|
code.line();
|
|
151
150
|
code.openBlock('func init()');
|
|
152
151
|
for (const type of this.types) {
|
|
153
|
-
type.emitRegistration(
|
|
152
|
+
type.emitRegistration(context);
|
|
154
153
|
}
|
|
155
154
|
code.closeBlock();
|
|
156
155
|
code.closeFile(initFile);
|
|
@@ -158,24 +157,7 @@ class Package {
|
|
|
158
157
|
}
|
|
159
158
|
emitImports(code, type) {
|
|
160
159
|
const toImport = new Array();
|
|
161
|
-
|
|
162
|
-
if (specialDeps.time) {
|
|
163
|
-
toImport.push({ module: 'time' });
|
|
164
|
-
}
|
|
165
|
-
if (specialDeps.runtime) {
|
|
166
|
-
toImport.push(JSII_RT_MODULE);
|
|
167
|
-
}
|
|
168
|
-
if (specialDeps.init) {
|
|
169
|
-
toImport.push({
|
|
170
|
-
alias: runtime_1.JSII_INIT_ALIAS,
|
|
171
|
-
module: `${this.root.goModuleName}/${runtime_1.JSII_INIT_PACKAGE}`,
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
if (specialDeps.internal) {
|
|
175
|
-
toImport.push({
|
|
176
|
-
module: `${this.goModuleName}/${INTERNAL_PACKAGE_NAME}`,
|
|
177
|
-
});
|
|
178
|
-
}
|
|
160
|
+
toImport.push(...(0, dependencies_1.toImportedModules)(type.specialDependencies, this));
|
|
179
161
|
for (const goModuleName of new Set(type.dependencies.map(({ goModuleName }) => goModuleName))) {
|
|
180
162
|
// If the module is the same as the current one being written, don't emit an import statement
|
|
181
163
|
if (goModuleName !== this.goModuleName) {
|
|
@@ -193,6 +175,50 @@ class Package {
|
|
|
193
175
|
this.emitImports(context.code, type);
|
|
194
176
|
type.emit(context);
|
|
195
177
|
context.code.closeFile(filePath);
|
|
178
|
+
this.emitValidators(context, type);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
emitValidators({ code, runtimeTypeChecking }, type) {
|
|
182
|
+
if (!runtimeTypeChecking) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
if (type.parameterValidators.length === 0 && type.structValidator == null) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
emit.call(this, (0, path_1.join)(this.directory, `${this.packageName}_${type.name}__runtime_type_checks.go`), false);
|
|
189
|
+
emit.call(this, (0, path_1.join)(this.directory, `${this.packageName}_${type.name}__no_runtime_type_checking.go`), true);
|
|
190
|
+
function emit(filePath, forNoOp) {
|
|
191
|
+
code.openFile(filePath);
|
|
192
|
+
// Conditional compilation tag...
|
|
193
|
+
code.line(`//go:build ${forNoOp ? '' : '!'}no_runtime_type_checking`);
|
|
194
|
+
// For go1.16 compatibility
|
|
195
|
+
code.line(`// +build ${forNoOp ? '' : '!'}no_runtime_type_checking`);
|
|
196
|
+
code.line();
|
|
197
|
+
this.emitHeader(code);
|
|
198
|
+
if (!forNoOp) {
|
|
199
|
+
const specialDependencies = (0, dependencies_1.reduceSpecialDependencies)(...type.parameterValidators.map((v) => v.specialDependencies), ...(type.structValidator
|
|
200
|
+
? [type.structValidator.specialDependencies]
|
|
201
|
+
: []));
|
|
202
|
+
importGoModules(code, [
|
|
203
|
+
...(0, dependencies_1.toImportedModules)(specialDependencies, this),
|
|
204
|
+
...Array.from(new Set([
|
|
205
|
+
...(type.structValidator?.dependencies ?? []),
|
|
206
|
+
...type.parameterValidators.flatMap((v) => v.dependencies),
|
|
207
|
+
].map((mod) => mod.goModuleName)))
|
|
208
|
+
.filter((mod) => mod !== this.goModuleName)
|
|
209
|
+
.map((mod) => ({ module: mod })),
|
|
210
|
+
]);
|
|
211
|
+
code.line();
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
code.line('// Building without runtime type checking enabled, so all the below just return nil');
|
|
215
|
+
code.line();
|
|
216
|
+
}
|
|
217
|
+
type.structValidator?.emitImplementation(code, this, forNoOp);
|
|
218
|
+
for (const validator of type.parameterValidators) {
|
|
219
|
+
validator.emitImplementation(code, this, forNoOp);
|
|
220
|
+
}
|
|
221
|
+
code.closeFile(filePath);
|
|
196
222
|
}
|
|
197
223
|
}
|
|
198
224
|
emitInternal(context) {
|
|
@@ -200,9 +226,9 @@ class Package {
|
|
|
200
226
|
return;
|
|
201
227
|
}
|
|
202
228
|
const code = context.code;
|
|
203
|
-
const fileName = (0, path_1.join)(this.directory, INTERNAL_PACKAGE_NAME, 'types.go');
|
|
229
|
+
const fileName = (0, path_1.join)(this.directory, dependencies_1.INTERNAL_PACKAGE_NAME, 'types.go');
|
|
204
230
|
code.openFile(fileName);
|
|
205
|
-
code.line(`package ${INTERNAL_PACKAGE_NAME}`);
|
|
231
|
+
code.line(`package ${dependencies_1.INTERNAL_PACKAGE_NAME}`);
|
|
206
232
|
const imports = new Set();
|
|
207
233
|
for (const alias of this.embeddedTypes.values()) {
|
|
208
234
|
if (!alias.foriegnType) {
|
|
@@ -321,7 +347,7 @@ class RootPackage extends Package {
|
|
|
321
347
|
code.line(`package ${runtime_1.JSII_INIT_PACKAGE}`);
|
|
322
348
|
code.line();
|
|
323
349
|
const toImport = [
|
|
324
|
-
JSII_RT_MODULE,
|
|
350
|
+
dependencies_1.JSII_RT_MODULE,
|
|
325
351
|
{ module: 'embed', alias: '_' },
|
|
326
352
|
];
|
|
327
353
|
if (dependencies.length > 0) {
|
|
@@ -391,11 +417,6 @@ function determineMajorVersionSuffix(version) {
|
|
|
391
417
|
}
|
|
392
418
|
return `/v${sv.major}`;
|
|
393
419
|
}
|
|
394
|
-
const JSII_RT_MODULE = {
|
|
395
|
-
alias: runtime_1.JSII_RT_ALIAS,
|
|
396
|
-
module: runtime_1.JSII_RT_PACKAGE_NAME,
|
|
397
|
-
};
|
|
398
|
-
const GO_REFLECT = { module: 'reflect' };
|
|
399
420
|
function importGoModules(code, modules) {
|
|
400
421
|
if (modules.length === 0) {
|
|
401
422
|
return;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { CodeMaker } from 'codemaker';
|
|
2
|
+
import { EmitContext } from '../emit-context';
|
|
2
3
|
import { GoClassConstructor } from '../types';
|
|
3
4
|
export declare class ClassConstructor {
|
|
4
5
|
readonly parent: GoClassConstructor;
|
|
5
6
|
constructor(parent: GoClassConstructor);
|
|
6
|
-
emit(code:
|
|
7
|
+
emit({ code, runtimeTypeChecking }: EmitContext): void;
|
|
7
8
|
emitOverride(code: CodeMaker, instanceVar: string): void;
|
|
8
9
|
}
|
|
9
10
|
//# sourceMappingURL=class-constructor.d.ts.map
|