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
|
@@ -8,9 +8,12 @@ class ClassConstructor {
|
|
|
8
8
|
constructor(parent) {
|
|
9
9
|
this.parent = parent;
|
|
10
10
|
}
|
|
11
|
-
emit(code) {
|
|
11
|
+
emit({ code, runtimeTypeChecking }) {
|
|
12
12
|
(0, util_1.emitInitialization)(code);
|
|
13
13
|
code.line();
|
|
14
|
+
if (runtimeTypeChecking) {
|
|
15
|
+
this.parent.validator?.emitCall(code);
|
|
16
|
+
}
|
|
14
17
|
const resultVar = (0, util_1.slugify)(this.parent.parent.proxyName[0], this.parent.parameters.map((p) => p.name));
|
|
15
18
|
const args = (0, emit_arguments_1.emitArguments)(code, this.parent.parameters, resultVar);
|
|
16
19
|
code.line(`${resultVar} := ${this.parent.parent.proxyName}{}`);
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EmitContext } from '../emit-context';
|
|
2
2
|
import { GoMethod } from '../types';
|
|
3
3
|
import { FunctionCall } from './function-call';
|
|
4
4
|
export declare class MethodCall extends FunctionCall {
|
|
5
5
|
readonly parent: GoMethod;
|
|
6
6
|
private _returnVarName;
|
|
7
7
|
constructor(parent: GoMethod);
|
|
8
|
-
emit(
|
|
8
|
+
emit(context: EmitContext): void;
|
|
9
9
|
private emitDynamic;
|
|
10
10
|
private emitStatic;
|
|
11
11
|
private get returnVarName();
|
|
@@ -12,15 +12,18 @@ class MethodCall extends function_call_1.FunctionCall {
|
|
|
12
12
|
this.parent = parent;
|
|
13
13
|
this._returnVarName = '';
|
|
14
14
|
}
|
|
15
|
-
emit(
|
|
15
|
+
emit(context) {
|
|
16
16
|
if (this.inStatic) {
|
|
17
|
-
this.emitStatic(
|
|
17
|
+
this.emitStatic(context);
|
|
18
18
|
}
|
|
19
19
|
else {
|
|
20
|
-
this.emitDynamic(
|
|
20
|
+
this.emitDynamic(context);
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
-
emitDynamic(code) {
|
|
23
|
+
emitDynamic({ code, runtimeTypeChecking }) {
|
|
24
|
+
if (runtimeTypeChecking) {
|
|
25
|
+
this.parent.validator?.emitCall(code);
|
|
26
|
+
}
|
|
24
27
|
const args = (0, emit_arguments_1.emitArguments)(code, this.parent.parameters, this.returnVarName);
|
|
25
28
|
if (this.returnsVal) {
|
|
26
29
|
code.line(`var ${this.returnVarName} ${this.returnType}`);
|
|
@@ -42,9 +45,12 @@ class MethodCall extends function_call_1.FunctionCall {
|
|
|
42
45
|
code.line(`return ${this.returnVarName}`);
|
|
43
46
|
}
|
|
44
47
|
}
|
|
45
|
-
emitStatic(code) {
|
|
48
|
+
emitStatic({ code, runtimeTypeChecking }) {
|
|
46
49
|
(0, util_1.emitInitialization)(code);
|
|
47
50
|
code.line();
|
|
51
|
+
if (runtimeTypeChecking) {
|
|
52
|
+
this.parent.validator?.emitCall(code);
|
|
53
|
+
}
|
|
48
54
|
const args = (0, emit_arguments_1.emitArguments)(code, this.parent.parameters, this.returnVarName);
|
|
49
55
|
if (this.returnsVal) {
|
|
50
56
|
code.line(`var ${this.returnVarName} ${this.returnType}`);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CodeMaker } from 'codemaker';
|
|
2
|
+
import { EmitContext } from '../emit-context';
|
|
2
3
|
import { GoProperty } from '../types';
|
|
3
4
|
import { FunctionCall } from './function-call';
|
|
4
5
|
export declare class GetProperty extends FunctionCall {
|
|
@@ -9,7 +10,7 @@ export declare class GetProperty extends FunctionCall {
|
|
|
9
10
|
export declare class SetProperty {
|
|
10
11
|
readonly parent: GoProperty;
|
|
11
12
|
constructor(parent: GoProperty);
|
|
12
|
-
emit(code:
|
|
13
|
+
emit({ code, runtimeTypeChecking }: EmitContext): void;
|
|
13
14
|
}
|
|
14
15
|
export declare class StaticGetProperty extends FunctionCall {
|
|
15
16
|
readonly parent: GoProperty;
|
|
@@ -19,6 +20,6 @@ export declare class StaticGetProperty extends FunctionCall {
|
|
|
19
20
|
export declare class StaticSetProperty {
|
|
20
21
|
readonly parent: GoProperty;
|
|
21
22
|
constructor(parent: GoProperty);
|
|
22
|
-
emit(code:
|
|
23
|
+
emit({ code, runtimeTypeChecking }: EmitContext): void;
|
|
23
24
|
}
|
|
24
25
|
//# sourceMappingURL=property-access.d.ts.map
|
|
@@ -25,7 +25,9 @@ class SetProperty {
|
|
|
25
25
|
constructor(parent) {
|
|
26
26
|
this.parent = parent;
|
|
27
27
|
}
|
|
28
|
-
emit(code) {
|
|
28
|
+
emit({ code, runtimeTypeChecking }) {
|
|
29
|
+
if (runtimeTypeChecking)
|
|
30
|
+
this.parent.validator?.emitCall(code);
|
|
29
31
|
code.open(`${constants_1.JSII_SET_FUNC}(`);
|
|
30
32
|
code.line(`${this.parent.instanceArg},`);
|
|
31
33
|
code.line(`"${this.parent.property.name}",`);
|
|
@@ -56,8 +58,11 @@ class StaticSetProperty {
|
|
|
56
58
|
constructor(parent) {
|
|
57
59
|
this.parent = parent;
|
|
58
60
|
}
|
|
59
|
-
emit(code) {
|
|
61
|
+
emit({ code, runtimeTypeChecking }) {
|
|
60
62
|
(0, util_1.emitInitialization)(code);
|
|
63
|
+
if (runtimeTypeChecking) {
|
|
64
|
+
this.parent.validator?.emitCall(code);
|
|
65
|
+
}
|
|
61
66
|
code.open(`${constants_1.JSII_SSET_FUNC}(`);
|
|
62
67
|
code.line(`"${this.parent.parent.fqn}",`);
|
|
63
68
|
code.line(`"${this.parent.property.name}",`);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { CodeMaker } from 'codemaker';
|
|
2
|
+
import { SpecialDependencies } from '../dependencies';
|
|
3
|
+
import { Package } from '../package';
|
|
4
|
+
import { GoClassConstructor, GoMethod, GoProperty, Struct } from '../types';
|
|
5
|
+
export declare class ParameterValidator {
|
|
6
|
+
static forConstructor(ctor: GoClassConstructor): ParameterValidator | undefined;
|
|
7
|
+
static forMethod(method: GoMethod): ParameterValidator | undefined;
|
|
8
|
+
static forProperty(property: GoProperty): ParameterValidator | undefined;
|
|
9
|
+
private static fromParts;
|
|
10
|
+
private readonly receiver?;
|
|
11
|
+
private readonly name;
|
|
12
|
+
private readonly parameters;
|
|
13
|
+
private readonly validations;
|
|
14
|
+
private constructor();
|
|
15
|
+
get dependencies(): readonly Package[];
|
|
16
|
+
get specialDependencies(): SpecialDependencies;
|
|
17
|
+
emitCall(code: CodeMaker): void;
|
|
18
|
+
emitImplementation(code: CodeMaker, scope: Package, noOp?: boolean): void;
|
|
19
|
+
}
|
|
20
|
+
export declare class StructValidator {
|
|
21
|
+
private readonly receiver;
|
|
22
|
+
private readonly validations;
|
|
23
|
+
static for(struct: Struct): StructValidator | undefined;
|
|
24
|
+
private constructor();
|
|
25
|
+
get dependencies(): Package[];
|
|
26
|
+
get specialDependencies(): SpecialDependencies;
|
|
27
|
+
emitImplementation(code: CodeMaker, scope: Package, noOp?: boolean): void;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=runtime-type-checking.d.ts.map
|
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StructValidator = exports.ParameterValidator = void 0;
|
|
4
|
+
const crypto_1 = require("crypto");
|
|
5
|
+
const jsii_reflect_1 = require("jsii-reflect");
|
|
6
|
+
const dependencies_1 = require("../dependencies");
|
|
7
|
+
const types_1 = require("../types");
|
|
8
|
+
const constants_1 = require("./constants");
|
|
9
|
+
class ParameterValidator {
|
|
10
|
+
constructor(baseName, validations, receiver) {
|
|
11
|
+
this.receiver = receiver;
|
|
12
|
+
this.name = `validate${baseName}Parameters`;
|
|
13
|
+
this.validations = validations;
|
|
14
|
+
this.parameters = Array.from(validations.keys());
|
|
15
|
+
}
|
|
16
|
+
static forConstructor(ctor) {
|
|
17
|
+
return ParameterValidator.fromParts(`New${ctor.parent.name}`, ctor.parameters);
|
|
18
|
+
}
|
|
19
|
+
static forMethod(method) {
|
|
20
|
+
return ParameterValidator.fromParts(method.name, method.parameters, method.static
|
|
21
|
+
? undefined
|
|
22
|
+
: {
|
|
23
|
+
name: method.instanceArg,
|
|
24
|
+
type: `*${method.parent.proxyName}`,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
static forProperty(property) {
|
|
28
|
+
if (property.immutable) {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
return ParameterValidator.fromParts(property.setterName, [
|
|
32
|
+
syntheticParameter(property.parent, 'val', property.reference.reference.spec, property.property.optional),
|
|
33
|
+
], property.static
|
|
34
|
+
? undefined
|
|
35
|
+
: {
|
|
36
|
+
name: property.instanceArg,
|
|
37
|
+
type: `*${property.parent.proxyName}`,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
static fromParts(name, parameters, receiver) {
|
|
41
|
+
if (parameters.length === 0) {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
const parameterValidations = new Map();
|
|
45
|
+
for (const param of parameters) {
|
|
46
|
+
const expr = param.name;
|
|
47
|
+
const descr = `parameter ${param.name}`;
|
|
48
|
+
const validations = new Array();
|
|
49
|
+
if (!param.isOptional && !param.isVariadic) {
|
|
50
|
+
validations.push(Validation.nullCheck(expr, descr, param.reference));
|
|
51
|
+
}
|
|
52
|
+
const validation = Validation.forTypeMap(expr, descr, param.isVariadic
|
|
53
|
+
? { type: 'array', value: param.reference }
|
|
54
|
+
: param.reference.typeMap);
|
|
55
|
+
if (validation) {
|
|
56
|
+
validations.push(validation);
|
|
57
|
+
}
|
|
58
|
+
if (validations.length !== 0) {
|
|
59
|
+
parameterValidations.set(param, validations);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (parameterValidations.size === 0) {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
return new ParameterValidator(name, parameterValidations, receiver);
|
|
66
|
+
}
|
|
67
|
+
get dependencies() {
|
|
68
|
+
return [
|
|
69
|
+
...this.parameters.flatMap((p) => p.reference.withTransparentUnions.dependencies),
|
|
70
|
+
...Array.from(this.validations.values()).flatMap((vs) => vs.flatMap((v) => v.dependencies)),
|
|
71
|
+
];
|
|
72
|
+
}
|
|
73
|
+
get specialDependencies() {
|
|
74
|
+
return (0, dependencies_1.reduceSpecialDependencies)(...this.parameters.map((p) => p.reference.specialDependencies), ...Array.from(this.validations.values()).flatMap((vs) => vs.flatMap((v) => v.specialDependencies)));
|
|
75
|
+
}
|
|
76
|
+
emitCall(code) {
|
|
77
|
+
const recv = this.receiver?.name ? `${this.receiver.name}.` : '';
|
|
78
|
+
const params = this.parameters
|
|
79
|
+
.map((p) => (p.isVariadic ? `&${p.name}` : p.name))
|
|
80
|
+
.join(', ');
|
|
81
|
+
code.openBlock(`if err := ${recv}${this.name}(${params}); err != nil`);
|
|
82
|
+
code.line(`panic(err)`);
|
|
83
|
+
code.closeBlock();
|
|
84
|
+
}
|
|
85
|
+
emitImplementation(code, scope, noOp = false) {
|
|
86
|
+
code.openBlock(`func ${this.receiver ? `(${this.receiver.name} ${this.receiver.type}) ` : ''}${this.name}(${this.parameters
|
|
87
|
+
.map((p) => p.isVariadic
|
|
88
|
+
? `${p.name} *[]${p.reference.scopedReference(scope)}`
|
|
89
|
+
: p.toString())
|
|
90
|
+
.join(', ')}) error`);
|
|
91
|
+
if (noOp) {
|
|
92
|
+
code.line('return nil');
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
for (const [_parameter, validations] of this.validations) {
|
|
96
|
+
for (const validation of validations) {
|
|
97
|
+
validation.emit(code, scope);
|
|
98
|
+
}
|
|
99
|
+
code.line();
|
|
100
|
+
}
|
|
101
|
+
code.line('return nil');
|
|
102
|
+
}
|
|
103
|
+
code.closeBlock();
|
|
104
|
+
code.line();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
exports.ParameterValidator = ParameterValidator;
|
|
108
|
+
class StructValidator {
|
|
109
|
+
constructor(receiver, validations) {
|
|
110
|
+
this.receiver = receiver;
|
|
111
|
+
this.validations = validations;
|
|
112
|
+
}
|
|
113
|
+
static for(struct) {
|
|
114
|
+
const receiver = {
|
|
115
|
+
name: struct.name.slice(0, 1).toLowerCase(),
|
|
116
|
+
type: `*${struct.name}`,
|
|
117
|
+
};
|
|
118
|
+
const fieldValidations = new Map();
|
|
119
|
+
for (const prop of struct.properties) {
|
|
120
|
+
const expr = `${receiver.name}.${prop.name}`;
|
|
121
|
+
const descr = `@{desc()}.${prop.name}`;
|
|
122
|
+
const validations = new Array();
|
|
123
|
+
if (!prop.property.optional) {
|
|
124
|
+
validations.push(Validation.nullCheck(expr, descr, prop.reference));
|
|
125
|
+
}
|
|
126
|
+
const validation = Validation.forTypeMap(expr, descr, prop.reference.typeMap);
|
|
127
|
+
if (validation) {
|
|
128
|
+
validations.push(validation);
|
|
129
|
+
}
|
|
130
|
+
if (validations.length > 0) {
|
|
131
|
+
fieldValidations.set(prop, validations);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (fieldValidations.size === 0) {
|
|
135
|
+
return undefined;
|
|
136
|
+
}
|
|
137
|
+
return new StructValidator(receiver, fieldValidations);
|
|
138
|
+
}
|
|
139
|
+
get dependencies() {
|
|
140
|
+
return Array.from(this.validations.values()).flatMap((vs) => vs.flatMap((v) => v.dependencies));
|
|
141
|
+
}
|
|
142
|
+
get specialDependencies() {
|
|
143
|
+
return (0, dependencies_1.reduceSpecialDependencies)({
|
|
144
|
+
fmt: true,
|
|
145
|
+
init: false,
|
|
146
|
+
internal: false,
|
|
147
|
+
runtime: false,
|
|
148
|
+
time: false,
|
|
149
|
+
}, ...Array.from(this.validations.values()).flatMap((vs) => vs.flatMap((v) => v.specialDependencies)));
|
|
150
|
+
}
|
|
151
|
+
emitImplementation(code, scope, noOp = false) {
|
|
152
|
+
code.openBlock(`func (${this.receiver.name} ${this.receiver.type}) validate(desc func() string) error`);
|
|
153
|
+
if (noOp) {
|
|
154
|
+
code.line('return nil');
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
for (const [_prop, validations] of this.validations) {
|
|
158
|
+
for (const validation of validations) {
|
|
159
|
+
validation.emit(code, scope);
|
|
160
|
+
}
|
|
161
|
+
code.line();
|
|
162
|
+
}
|
|
163
|
+
code.line('return nil');
|
|
164
|
+
}
|
|
165
|
+
code.closeBlock();
|
|
166
|
+
code.line();
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
exports.StructValidator = StructValidator;
|
|
170
|
+
class Validation {
|
|
171
|
+
static forTypeMap(expression, description, typeMap) {
|
|
172
|
+
switch (typeMap.type) {
|
|
173
|
+
case 'union':
|
|
174
|
+
return Validation.unionCheck(expression, description, typeMap.value);
|
|
175
|
+
case 'interface':
|
|
176
|
+
return Validation.interfaceCheck(expression, description, typeMap.value);
|
|
177
|
+
case 'array':
|
|
178
|
+
case 'map':
|
|
179
|
+
return Validation.collectionCheck(expression, description, typeMap.value);
|
|
180
|
+
case 'primitive':
|
|
181
|
+
case 'void':
|
|
182
|
+
return undefined;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
static collectionCheck(expression, description, elementType) {
|
|
186
|
+
// We need to come up with a unique-enough ID here... so we use a hash.
|
|
187
|
+
const idx = `idx_${(0, crypto_1.createHash)('sha256')
|
|
188
|
+
.update(expression)
|
|
189
|
+
.digest('hex')
|
|
190
|
+
.slice(0, 6)}`;
|
|
191
|
+
// This is actually unused
|
|
192
|
+
const elementValidator = Validation.forTypeMap('v', `${description}[@{${idx}:#v}]`, elementType.typeMap);
|
|
193
|
+
if (elementValidator == null) {
|
|
194
|
+
return undefined;
|
|
195
|
+
}
|
|
196
|
+
class CollectionCheck extends Validation {
|
|
197
|
+
get specialDependencies() {
|
|
198
|
+
return elementValidator.specialDependencies;
|
|
199
|
+
}
|
|
200
|
+
get dependencies() {
|
|
201
|
+
return elementValidator.dependencies;
|
|
202
|
+
}
|
|
203
|
+
emit(code, scope) {
|
|
204
|
+
// We need to de-reference the pointer here (range does not operate on pointers)
|
|
205
|
+
code.openBlock(`for ${idx}, v := range *${expression}`);
|
|
206
|
+
elementValidator.emit(code, scope);
|
|
207
|
+
code.closeBlock();
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return new CollectionCheck();
|
|
211
|
+
}
|
|
212
|
+
static interfaceCheck(expression, description, iface) {
|
|
213
|
+
if (!iface.datatype) {
|
|
214
|
+
return undefined;
|
|
215
|
+
}
|
|
216
|
+
class InterfaceCheck extends Validation {
|
|
217
|
+
get dependencies() {
|
|
218
|
+
return [];
|
|
219
|
+
}
|
|
220
|
+
get specialDependencies() {
|
|
221
|
+
return {
|
|
222
|
+
fmt: INTERPOLATION.test(description),
|
|
223
|
+
init: false,
|
|
224
|
+
internal: false,
|
|
225
|
+
runtime: !!iface.datatype,
|
|
226
|
+
time: false,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
emit(code, _scope) {
|
|
230
|
+
code.openBlock(`if err := ${constants_1.JSII_RT_ALIAS}.ValidateStruct(${expression}, func() string { return ${interpolated(description)} }); err != nil`);
|
|
231
|
+
code.line(`return err`);
|
|
232
|
+
code.closeBlock();
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
return new InterfaceCheck();
|
|
236
|
+
}
|
|
237
|
+
static nullCheck(expression, description, typeRef) {
|
|
238
|
+
class NullCheck extends Validation {
|
|
239
|
+
get dependencies() {
|
|
240
|
+
return [];
|
|
241
|
+
}
|
|
242
|
+
get specialDependencies() {
|
|
243
|
+
return {
|
|
244
|
+
fmt: true,
|
|
245
|
+
init: false,
|
|
246
|
+
internal: false,
|
|
247
|
+
runtime: false,
|
|
248
|
+
time: false,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
emit(code) {
|
|
252
|
+
const nullValue = typeRef.type?.type?.isEnumType()
|
|
253
|
+
? `""` // Enums are represented as string-valued constants
|
|
254
|
+
: 'nil';
|
|
255
|
+
code.openBlock(`if ${expression} == ${nullValue}`);
|
|
256
|
+
code.line(returnErrorf(`${description} is required, but nil was provided`));
|
|
257
|
+
code.closeBlock();
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return new NullCheck();
|
|
261
|
+
}
|
|
262
|
+
static unionCheck(expression, description, types) {
|
|
263
|
+
const hasInterface = types.some((t) => t.typeMap.type === 'interface');
|
|
264
|
+
class UnionCheck extends Validation {
|
|
265
|
+
get dependencies() {
|
|
266
|
+
return types.flatMap((t) => t.dependencies);
|
|
267
|
+
}
|
|
268
|
+
get specialDependencies() {
|
|
269
|
+
return (0, dependencies_1.reduceSpecialDependencies)({
|
|
270
|
+
fmt: true,
|
|
271
|
+
init: false,
|
|
272
|
+
internal: false,
|
|
273
|
+
runtime: hasInterface,
|
|
274
|
+
time: false,
|
|
275
|
+
}, ...types.flatMap((t) => {
|
|
276
|
+
const validator = Validation.forTypeMap(expression, description, t.typeMap);
|
|
277
|
+
if (validator == null)
|
|
278
|
+
return [];
|
|
279
|
+
return [validator.specialDependencies];
|
|
280
|
+
}));
|
|
281
|
+
}
|
|
282
|
+
emit(code, scope) {
|
|
283
|
+
const validTypes = new Array();
|
|
284
|
+
code.line(`switch ${expression}.(type) {`);
|
|
285
|
+
for (const type of types) {
|
|
286
|
+
const typeName = type.scopedReference(scope);
|
|
287
|
+
validTypes.push(typeName);
|
|
288
|
+
// Maps a type to the conversion instructions to the ${typeName} type
|
|
289
|
+
const acceptableTypes = new Map();
|
|
290
|
+
acceptableTypes.set(typeName, undefined);
|
|
291
|
+
switch (typeName) {
|
|
292
|
+
case '*float64':
|
|
293
|
+
// For numbers, we accept everything that implictly converts to float64 (pointer & not)
|
|
294
|
+
acceptableTypes.set('float64', (code, inVar, outVar) => code.line(`${outVar} := &${inVar}`));
|
|
295
|
+
const ALTERNATE_TYPES = [
|
|
296
|
+
'int',
|
|
297
|
+
'uint',
|
|
298
|
+
'int8',
|
|
299
|
+
'int16',
|
|
300
|
+
'int32',
|
|
301
|
+
'int64',
|
|
302
|
+
'uint8',
|
|
303
|
+
'uint16',
|
|
304
|
+
'uint32',
|
|
305
|
+
'uint64',
|
|
306
|
+
];
|
|
307
|
+
for (const otherType of ALTERNATE_TYPES) {
|
|
308
|
+
const varName = (0, crypto_1.createHash)('sha256')
|
|
309
|
+
.update(expression)
|
|
310
|
+
.digest('hex')
|
|
311
|
+
.slice(6);
|
|
312
|
+
acceptableTypes.set(`*${otherType}`, (code) => {
|
|
313
|
+
code.openBlock(`${varName} := func (v *${otherType}) *float64`);
|
|
314
|
+
code.openBlock('if v == nil {');
|
|
315
|
+
code.line('return nil');
|
|
316
|
+
code.closeBlock();
|
|
317
|
+
code.line(`val := float64(*v)`);
|
|
318
|
+
code.line(`return &val`);
|
|
319
|
+
code.closeBlock('()');
|
|
320
|
+
});
|
|
321
|
+
acceptableTypes.set(otherType, (code) => {
|
|
322
|
+
code.openBlock(`${varName} := func (v ${otherType}) *float64`);
|
|
323
|
+
code.line(`val := float64(v)`);
|
|
324
|
+
code.line(`return &val`);
|
|
325
|
+
code.closeBlock('()');
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
break;
|
|
329
|
+
default:
|
|
330
|
+
// Accept pointer and non-pointer versions of everything
|
|
331
|
+
if (typeName.startsWith('*')) {
|
|
332
|
+
const nonPointerType = typeName.slice(1);
|
|
333
|
+
acceptableTypes.set(nonPointerType, (code, inVar, outVar) => code.line(`${outVar} := &${inVar}`));
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
for (const [acceptableType, conversion] of acceptableTypes) {
|
|
337
|
+
code.indent(`case ${acceptableType}:`);
|
|
338
|
+
const outVar = /^[a-z0-9_]+$/.test(expression) ? expression : `v`;
|
|
339
|
+
const validation = Validation.forTypeMap(outVar, description, type.typeMap);
|
|
340
|
+
if (validation) {
|
|
341
|
+
const inVar = conversion ? `${outVar}_` : outVar;
|
|
342
|
+
code.line(`${inVar} := ${expression}.(${acceptableType})`);
|
|
343
|
+
if (conversion) {
|
|
344
|
+
conversion(code, inVar, outVar);
|
|
345
|
+
}
|
|
346
|
+
validation.emit(code, scope);
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
code.line('// ok');
|
|
350
|
+
}
|
|
351
|
+
code.unindent(false);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
code.indent('default:');
|
|
355
|
+
if (hasInterface)
|
|
356
|
+
code.openBlock(`if !${constants_1.JSII_RT_ALIAS}.IsAnonymousProxy(${expression})`);
|
|
357
|
+
code.line(returnErrorf(`${description} must be one of the allowed types: ${validTypes.join(', ')}; received @{${expression}:#v} (a @{${expression}:T})`));
|
|
358
|
+
if (hasInterface)
|
|
359
|
+
code.closeBlock();
|
|
360
|
+
code.unindent('}');
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
return new UnionCheck();
|
|
364
|
+
}
|
|
365
|
+
constructor() { }
|
|
366
|
+
}
|
|
367
|
+
const INTERPOLATION = /@\{([^}:]+)(?::([^}]+))?\}/;
|
|
368
|
+
function interpolated(message) {
|
|
369
|
+
// Need to escape literal percent signes, as a precaution.
|
|
370
|
+
let escaped = message.replace(/%/gm, '%%');
|
|
371
|
+
const args = new Array();
|
|
372
|
+
let match;
|
|
373
|
+
while ((match = INTERPOLATION.exec(escaped))) {
|
|
374
|
+
const before = escaped.slice(0, match.index);
|
|
375
|
+
const expr = match[1];
|
|
376
|
+
const mod = match[2];
|
|
377
|
+
const after = escaped.slice(match.index + match[1].length + 3 + (mod ? mod.length + 1 : 0));
|
|
378
|
+
escaped = `${before}%${mod || 'v'}${after}`;
|
|
379
|
+
args.push(expr);
|
|
380
|
+
}
|
|
381
|
+
if (args.length === 0) {
|
|
382
|
+
return JSON.stringify(message);
|
|
383
|
+
}
|
|
384
|
+
return `fmt.Sprintf(${JSON.stringify(escaped)}, ${args.join(', ')})`;
|
|
385
|
+
}
|
|
386
|
+
function returnErrorf(message) {
|
|
387
|
+
const args = new Array();
|
|
388
|
+
// Need to escape literal percent signes, as a precaution.
|
|
389
|
+
message = message.replace(/%/gm, '%%');
|
|
390
|
+
let match;
|
|
391
|
+
while ((match = INTERPOLATION.exec(message))) {
|
|
392
|
+
const before = message.slice(0, match.index);
|
|
393
|
+
const expr = match[1];
|
|
394
|
+
const mod = match[2];
|
|
395
|
+
const after = message.slice(match.index + match[1].length + 3 + (mod ? mod.length + 1 : 0));
|
|
396
|
+
message = `${before}%${mod || 'v'}${after}`;
|
|
397
|
+
args.push(expr);
|
|
398
|
+
}
|
|
399
|
+
return `return fmt.Errorf(${[JSON.stringify(message), ...args].join(', ')})`;
|
|
400
|
+
}
|
|
401
|
+
function syntheticParameter(parent, name, type, optional) {
|
|
402
|
+
return new types_1.GoParameter(parent, new jsii_reflect_1.Parameter(parent.type.system, parent.type, new jsii_reflect_1.Method(parent.type.system, parent.type.assembly, parent.type, parent.type, { name: '__synthetic__' }), {
|
|
403
|
+
name,
|
|
404
|
+
optional,
|
|
405
|
+
type,
|
|
406
|
+
}));
|
|
407
|
+
}
|
|
408
|
+
//# sourceMappingURL=runtime-type-checking.js.map
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { CodeMaker } from 'codemaker';
|
|
2
1
|
import { Method, ClassType, Initializer } from 'jsii-reflect';
|
|
3
2
|
import { SpecialDependencies } from '../dependencies';
|
|
4
3
|
import { EmitContext } from '../emit-context';
|
|
5
4
|
import { Package } from '../package';
|
|
6
5
|
import { MethodCall } from '../runtime';
|
|
6
|
+
import { ParameterValidator } from '../runtime/runtime-type-checking';
|
|
7
7
|
import { GoType } from './go-type';
|
|
8
8
|
import { GoInterface } from './interface';
|
|
9
9
|
import { GoMethod, GoProperty, GoTypeMember } from './type-member';
|
|
10
10
|
export declare class GoClass extends GoType<ClassType> {
|
|
11
|
+
#private;
|
|
11
12
|
readonly methods: ClassMethod[];
|
|
12
13
|
readonly staticMethods: StaticMethod[];
|
|
13
14
|
readonly properties: GoProperty[];
|
|
@@ -16,26 +17,28 @@ export declare class GoClass extends GoType<ClassType> {
|
|
|
16
17
|
private _implements?;
|
|
17
18
|
private readonly initializer?;
|
|
18
19
|
constructor(pkg: Package, type: ClassType);
|
|
20
|
+
get parameterValidators(): readonly ParameterValidator[];
|
|
19
21
|
get extends(): GoClass | undefined;
|
|
20
22
|
get implements(): readonly GoInterface[];
|
|
21
23
|
get baseTypes(): ReadonlyArray<GoClass | GoInterface>;
|
|
22
24
|
emit(context: EmitContext): void;
|
|
23
|
-
emitRegistration(code:
|
|
25
|
+
emitRegistration({ code }: EmitContext): void;
|
|
24
26
|
get members(): GoTypeMember[];
|
|
25
27
|
get specialDependencies(): SpecialDependencies;
|
|
26
28
|
protected emitInterface(context: EmitContext): void;
|
|
27
29
|
private emitGetters;
|
|
28
30
|
private emitStruct;
|
|
29
|
-
private emitStaticProperty;
|
|
30
31
|
private emitSetters;
|
|
31
32
|
get dependencies(): Package[];
|
|
32
33
|
get interfaces(): string[];
|
|
33
34
|
}
|
|
34
35
|
export declare class GoClassConstructor extends GoMethod {
|
|
36
|
+
#private;
|
|
35
37
|
readonly parent: GoClass;
|
|
36
38
|
private readonly type;
|
|
37
39
|
private readonly constructorRuntimeCall;
|
|
38
40
|
constructor(parent: GoClass, type: Initializer);
|
|
41
|
+
get validator(): ParameterValidator | undefined;
|
|
39
42
|
get specialDependencies(): SpecialDependencies;
|
|
40
43
|
emit(context: EmitContext): void;
|
|
41
44
|
private emitNew;
|
|
@@ -46,15 +49,17 @@ export declare class ClassMethod extends GoMethod {
|
|
|
46
49
|
readonly method: Method;
|
|
47
50
|
readonly runtimeCall: MethodCall;
|
|
48
51
|
constructor(parent: GoClass, method: Method);
|
|
49
|
-
emit(
|
|
52
|
+
emit(context: EmitContext): void;
|
|
50
53
|
emitDecl({ code, documenter }: EmitContext): void;
|
|
51
54
|
get instanceArg(): string;
|
|
55
|
+
get static(): boolean;
|
|
52
56
|
get specialDependencies(): SpecialDependencies;
|
|
53
57
|
}
|
|
54
58
|
export declare class StaticMethod extends ClassMethod {
|
|
55
59
|
readonly parent: GoClass;
|
|
56
60
|
readonly method: Method;
|
|
61
|
+
readonly name: string;
|
|
57
62
|
constructor(parent: GoClass, method: Method);
|
|
58
|
-
emit(
|
|
63
|
+
emit(context: EmitContext): void;
|
|
59
64
|
}
|
|
60
65
|
//# sourceMappingURL=class.d.ts.map
|