@rcrsr/rill 0.14.0 → 0.16.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/dist/ast-nodes.d.ts +2 -11
- package/dist/ast-nodes.js +0 -1
- package/dist/ast-unions.d.ts +0 -1
- package/dist/ast-unions.js +0 -1
- package/dist/constants.d.ts +0 -1
- package/dist/constants.js +0 -1
- package/dist/error-classes.d.ts +0 -1
- package/dist/error-classes.js +0 -1
- package/dist/error-formatter.d.ts +0 -1
- package/dist/error-formatter.js +0 -1
- package/dist/error-registry.d.ts +0 -1
- package/dist/error-registry.js +50 -1
- package/dist/ext/crypto/index.d.ts +0 -1
- package/dist/ext/crypto/index.js +5 -6
- package/dist/ext/exec/index.d.ts +0 -1
- package/dist/ext/exec/index.js +3 -4
- package/dist/ext/exec/runner.d.ts +0 -1
- package/dist/ext/exec/runner.js +0 -1
- package/dist/ext/fetch/index.d.ts +0 -1
- package/dist/ext/fetch/index.js +8 -39
- package/dist/ext/fetch/request.d.ts +0 -1
- package/dist/ext/fetch/request.js +0 -1
- package/dist/ext/fs/index.d.ts +0 -1
- package/dist/ext/fs/index.js +26 -27
- package/dist/ext/fs/sandbox.d.ts +0 -1
- package/dist/ext/fs/sandbox.js +0 -1
- package/dist/ext/kv/index.d.ts +0 -1
- package/dist/ext/kv/index.js +19 -20
- package/dist/ext/kv/store.d.ts +0 -1
- package/dist/ext/kv/store.js +0 -1
- package/dist/generated/introspection-data.d.ts +0 -1
- package/dist/generated/introspection-data.js +0 -1
- package/dist/generated/version-data.d.ts +1 -2
- package/dist/generated/version-data.js +2 -3
- package/dist/highlight-map.d.ts +0 -1
- package/dist/highlight-map.js +0 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -2
- package/dist/lexer/errors.d.ts +0 -1
- package/dist/lexer/errors.js +0 -1
- package/dist/lexer/helpers.d.ts +0 -1
- package/dist/lexer/helpers.js +0 -1
- package/dist/lexer/index.d.ts +0 -1
- package/dist/lexer/index.js +0 -1
- package/dist/lexer/operators.d.ts +0 -1
- package/dist/lexer/operators.js +0 -1
- package/dist/lexer/readers.d.ts +0 -1
- package/dist/lexer/readers.js +0 -1
- package/dist/lexer/state.d.ts +0 -1
- package/dist/lexer/state.js +0 -1
- package/dist/lexer/tokenizer.d.ts +0 -1
- package/dist/lexer/tokenizer.js +0 -1
- package/dist/parser/helpers.d.ts +0 -1
- package/dist/parser/helpers.js +0 -1
- package/dist/parser/index.d.ts +0 -1
- package/dist/parser/index.js +0 -1
- package/dist/parser/parser-collect.d.ts +0 -1
- package/dist/parser/parser-collect.js +0 -1
- package/dist/parser/parser-control.d.ts +0 -1
- package/dist/parser/parser-control.js +0 -1
- package/dist/parser/parser-expr.d.ts +0 -1
- package/dist/parser/parser-expr.js +0 -1
- package/dist/parser/parser-extract.d.ts +0 -1
- package/dist/parser/parser-extract.js +0 -1
- package/dist/parser/parser-functions.d.ts +0 -1
- package/dist/parser/parser-functions.js +0 -1
- package/dist/parser/parser-literals.d.ts +0 -1
- package/dist/parser/parser-literals.js +4 -2
- package/dist/parser/parser-script.d.ts +0 -1
- package/dist/parser/parser-script.js +0 -1
- package/dist/parser/parser-shape.d.ts +2 -3
- package/dist/parser/parser-shape.js +8 -40
- package/dist/parser/parser-types.d.ts +28 -2
- package/dist/parser/parser-types.js +64 -13
- package/dist/parser/parser-use.d.ts +0 -1
- package/dist/parser/parser-use.js +0 -1
- package/dist/parser/parser-variables.d.ts +0 -1
- package/dist/parser/parser-variables.js +0 -1
- package/dist/parser/parser.d.ts +0 -1
- package/dist/parser/parser.js +0 -1
- package/dist/parser/state.d.ts +0 -1
- package/dist/parser/state.js +0 -1
- package/dist/runtime/core/callable.d.ts +40 -13
- package/dist/runtime/core/callable.js +137 -31
- package/dist/runtime/core/context.d.ts +0 -1
- package/dist/runtime/core/context.js +1 -2
- package/dist/runtime/core/equals.d.ts +0 -1
- package/dist/runtime/core/equals.js +35 -3
- package/dist/runtime/core/eval/base.d.ts +0 -1
- package/dist/runtime/core/eval/base.js +0 -1
- package/dist/runtime/core/eval/evaluator.d.ts +0 -1
- package/dist/runtime/core/eval/evaluator.js +0 -1
- package/dist/runtime/core/eval/index.d.ts +0 -1
- package/dist/runtime/core/eval/index.js +0 -1
- package/dist/runtime/core/eval/mixins/annotations.d.ts +0 -1
- package/dist/runtime/core/eval/mixins/annotations.js +0 -1
- package/dist/runtime/core/eval/mixins/closures.d.ts +0 -1
- package/dist/runtime/core/eval/mixins/closures.js +82 -69
- package/dist/runtime/core/eval/mixins/collections.d.ts +0 -1
- package/dist/runtime/core/eval/mixins/collections.js +9 -4
- package/dist/runtime/core/eval/mixins/control-flow.d.ts +0 -1
- package/dist/runtime/core/eval/mixins/control-flow.js +0 -1
- package/dist/runtime/core/eval/mixins/conversion.d.ts +0 -1
- package/dist/runtime/core/eval/mixins/conversion.js +263 -16
- package/dist/runtime/core/eval/mixins/core.d.ts +0 -1
- package/dist/runtime/core/eval/mixins/core.js +0 -1
- package/dist/runtime/core/eval/mixins/expressions.d.ts +0 -1
- package/dist/runtime/core/eval/mixins/expressions.js +0 -1
- package/dist/runtime/core/eval/mixins/extraction.d.ts +0 -1
- package/dist/runtime/core/eval/mixins/extraction.js +8 -9
- package/dist/runtime/core/eval/mixins/list-dispatch.d.ts +0 -1
- package/dist/runtime/core/eval/mixins/list-dispatch.js +0 -1
- package/dist/runtime/core/eval/mixins/literals.d.ts +0 -1
- package/dist/runtime/core/eval/mixins/literals.js +3 -7
- package/dist/runtime/core/eval/mixins/types.d.ts +2 -1
- package/dist/runtime/core/eval/mixins/types.js +222 -200
- package/dist/runtime/core/eval/mixins/use.d.ts +0 -1
- package/dist/runtime/core/eval/mixins/use.js +0 -1
- package/dist/runtime/core/eval/mixins/variables.d.ts +0 -1
- package/dist/runtime/core/eval/mixins/variables.js +6 -7
- package/dist/runtime/core/eval/types.d.ts +0 -1
- package/dist/runtime/core/eval/types.js +0 -1
- package/dist/runtime/core/execute.d.ts +0 -1
- package/dist/runtime/core/execute.js +0 -1
- package/dist/runtime/core/field-descriptor.d.ts +2 -3
- package/dist/runtime/core/field-descriptor.js +0 -1
- package/dist/runtime/core/introspection.d.ts +0 -1
- package/dist/runtime/core/introspection.js +0 -1
- package/dist/runtime/core/resolvers.d.ts +0 -1
- package/dist/runtime/core/resolvers.js +0 -1
- package/dist/runtime/core/signals.d.ts +0 -1
- package/dist/runtime/core/signals.js +0 -1
- package/dist/runtime/core/types.d.ts +0 -1
- package/dist/runtime/core/types.js +0 -1
- package/dist/runtime/core/values.d.ts +59 -8
- package/dist/runtime/core/values.js +338 -36
- package/dist/runtime/ext/builtins.d.ts +0 -1
- package/dist/runtime/ext/builtins.js +43 -17
- package/dist/runtime/ext/extensions.d.ts +0 -1
- package/dist/runtime/ext/extensions.js +0 -1
- package/dist/runtime/index.d.ts +2 -3
- package/dist/runtime/index.js +1 -2
- package/dist/signature-parser.d.ts +0 -1
- package/dist/signature-parser.js +8 -4
- package/dist/source-location.d.ts +0 -1
- package/dist/source-location.js +0 -1
- package/dist/token-types.d.ts +0 -1
- package/dist/token-types.js +0 -1
- package/dist/types.d.ts +0 -1
- package/dist/types.js +0 -1
- package/dist/value-types.d.ts +15 -12
- package/dist/value-types.js +0 -1
- package/package.json +2 -1
- package/dist/ast-nodes.d.ts.map +0 -1
- package/dist/ast-nodes.js.map +0 -1
- package/dist/ast-unions.d.ts.map +0 -1
- package/dist/ast-unions.js.map +0 -1
- package/dist/constants.d.ts.map +0 -1
- package/dist/constants.js.map +0 -1
- package/dist/error-classes.d.ts.map +0 -1
- package/dist/error-classes.js.map +0 -1
- package/dist/error-formatter.d.ts.map +0 -1
- package/dist/error-formatter.js.map +0 -1
- package/dist/error-registry.d.ts.map +0 -1
- package/dist/error-registry.js.map +0 -1
- package/dist/ext/crypto/index.d.ts.map +0 -1
- package/dist/ext/crypto/index.js.map +0 -1
- package/dist/ext/exec/index.d.ts.map +0 -1
- package/dist/ext/exec/index.js.map +0 -1
- package/dist/ext/exec/runner.d.ts.map +0 -1
- package/dist/ext/exec/runner.js.map +0 -1
- package/dist/ext/fetch/index.d.ts.map +0 -1
- package/dist/ext/fetch/index.js.map +0 -1
- package/dist/ext/fetch/request.d.ts.map +0 -1
- package/dist/ext/fetch/request.js.map +0 -1
- package/dist/ext/fs/index.d.ts.map +0 -1
- package/dist/ext/fs/index.js.map +0 -1
- package/dist/ext/fs/sandbox.d.ts.map +0 -1
- package/dist/ext/fs/sandbox.js.map +0 -1
- package/dist/ext/kv/index.d.ts.map +0 -1
- package/dist/ext/kv/index.js.map +0 -1
- package/dist/ext/kv/store.d.ts.map +0 -1
- package/dist/ext/kv/store.js.map +0 -1
- package/dist/generated/introspection-data.d.ts.map +0 -1
- package/dist/generated/introspection-data.js.map +0 -1
- package/dist/generated/version-data.d.ts.map +0 -1
- package/dist/generated/version-data.js.map +0 -1
- package/dist/highlight-map.d.ts.map +0 -1
- package/dist/highlight-map.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lexer/errors.d.ts.map +0 -1
- package/dist/lexer/errors.js.map +0 -1
- package/dist/lexer/helpers.d.ts.map +0 -1
- package/dist/lexer/helpers.js.map +0 -1
- package/dist/lexer/index.d.ts.map +0 -1
- package/dist/lexer/index.js.map +0 -1
- package/dist/lexer/operators.d.ts.map +0 -1
- package/dist/lexer/operators.js.map +0 -1
- package/dist/lexer/readers.d.ts.map +0 -1
- package/dist/lexer/readers.js.map +0 -1
- package/dist/lexer/state.d.ts.map +0 -1
- package/dist/lexer/state.js.map +0 -1
- package/dist/lexer/tokenizer.d.ts.map +0 -1
- package/dist/lexer/tokenizer.js.map +0 -1
- package/dist/parser/helpers.d.ts.map +0 -1
- package/dist/parser/helpers.js.map +0 -1
- package/dist/parser/index.d.ts.map +0 -1
- package/dist/parser/index.js.map +0 -1
- package/dist/parser/parser-collect.d.ts.map +0 -1
- package/dist/parser/parser-collect.js.map +0 -1
- package/dist/parser/parser-control.d.ts.map +0 -1
- package/dist/parser/parser-control.js.map +0 -1
- package/dist/parser/parser-expr.d.ts.map +0 -1
- package/dist/parser/parser-expr.js.map +0 -1
- package/dist/parser/parser-extract.d.ts.map +0 -1
- package/dist/parser/parser-extract.js.map +0 -1
- package/dist/parser/parser-functions.d.ts.map +0 -1
- package/dist/parser/parser-functions.js.map +0 -1
- package/dist/parser/parser-literals.d.ts.map +0 -1
- package/dist/parser/parser-literals.js.map +0 -1
- package/dist/parser/parser-script.d.ts.map +0 -1
- package/dist/parser/parser-script.js.map +0 -1
- package/dist/parser/parser-shape.d.ts.map +0 -1
- package/dist/parser/parser-shape.js.map +0 -1
- package/dist/parser/parser-types.d.ts.map +0 -1
- package/dist/parser/parser-types.js.map +0 -1
- package/dist/parser/parser-use.d.ts.map +0 -1
- package/dist/parser/parser-use.js.map +0 -1
- package/dist/parser/parser-variables.d.ts.map +0 -1
- package/dist/parser/parser-variables.js.map +0 -1
- package/dist/parser/parser.d.ts.map +0 -1
- package/dist/parser/parser.js.map +0 -1
- package/dist/parser/state.d.ts.map +0 -1
- package/dist/parser/state.js.map +0 -1
- package/dist/runtime/core/callable.d.ts.map +0 -1
- package/dist/runtime/core/callable.js.map +0 -1
- package/dist/runtime/core/context.d.ts.map +0 -1
- package/dist/runtime/core/context.js.map +0 -1
- package/dist/runtime/core/equals.d.ts.map +0 -1
- package/dist/runtime/core/equals.js.map +0 -1
- package/dist/runtime/core/eval/base.d.ts.map +0 -1
- package/dist/runtime/core/eval/base.js.map +0 -1
- package/dist/runtime/core/eval/evaluator.d.ts.map +0 -1
- package/dist/runtime/core/eval/evaluator.js.map +0 -1
- package/dist/runtime/core/eval/index.d.ts.map +0 -1
- package/dist/runtime/core/eval/index.js.map +0 -1
- package/dist/runtime/core/eval/mixins/annotations.d.ts.map +0 -1
- package/dist/runtime/core/eval/mixins/annotations.js.map +0 -1
- package/dist/runtime/core/eval/mixins/closures.d.ts.map +0 -1
- package/dist/runtime/core/eval/mixins/closures.js.map +0 -1
- package/dist/runtime/core/eval/mixins/collections.d.ts.map +0 -1
- package/dist/runtime/core/eval/mixins/collections.js.map +0 -1
- package/dist/runtime/core/eval/mixins/control-flow.d.ts.map +0 -1
- package/dist/runtime/core/eval/mixins/control-flow.js.map +0 -1
- package/dist/runtime/core/eval/mixins/conversion.d.ts.map +0 -1
- package/dist/runtime/core/eval/mixins/conversion.js.map +0 -1
- package/dist/runtime/core/eval/mixins/core.d.ts.map +0 -1
- package/dist/runtime/core/eval/mixins/core.js.map +0 -1
- package/dist/runtime/core/eval/mixins/expressions.d.ts.map +0 -1
- package/dist/runtime/core/eval/mixins/expressions.js.map +0 -1
- package/dist/runtime/core/eval/mixins/extraction.d.ts.map +0 -1
- package/dist/runtime/core/eval/mixins/extraction.js.map +0 -1
- package/dist/runtime/core/eval/mixins/list-dispatch.d.ts.map +0 -1
- package/dist/runtime/core/eval/mixins/list-dispatch.js.map +0 -1
- package/dist/runtime/core/eval/mixins/literals.d.ts.map +0 -1
- package/dist/runtime/core/eval/mixins/literals.js.map +0 -1
- package/dist/runtime/core/eval/mixins/types.d.ts.map +0 -1
- package/dist/runtime/core/eval/mixins/types.js.map +0 -1
- package/dist/runtime/core/eval/mixins/use.d.ts.map +0 -1
- package/dist/runtime/core/eval/mixins/use.js.map +0 -1
- package/dist/runtime/core/eval/mixins/variables.d.ts.map +0 -1
- package/dist/runtime/core/eval/mixins/variables.js.map +0 -1
- package/dist/runtime/core/eval/types.d.ts.map +0 -1
- package/dist/runtime/core/eval/types.js.map +0 -1
- package/dist/runtime/core/execute.d.ts.map +0 -1
- package/dist/runtime/core/execute.js.map +0 -1
- package/dist/runtime/core/field-descriptor.d.ts.map +0 -1
- package/dist/runtime/core/field-descriptor.js.map +0 -1
- package/dist/runtime/core/introspection.d.ts.map +0 -1
- package/dist/runtime/core/introspection.js.map +0 -1
- package/dist/runtime/core/resolvers.d.ts.map +0 -1
- package/dist/runtime/core/resolvers.js.map +0 -1
- package/dist/runtime/core/signals.d.ts.map +0 -1
- package/dist/runtime/core/signals.js.map +0 -1
- package/dist/runtime/core/types.d.ts.map +0 -1
- package/dist/runtime/core/types.js.map +0 -1
- package/dist/runtime/core/values.d.ts.map +0 -1
- package/dist/runtime/core/values.js.map +0 -1
- package/dist/runtime/ext/builtins.d.ts.map +0 -1
- package/dist/runtime/ext/builtins.js.map +0 -1
- package/dist/runtime/ext/extensions.d.ts.map +0 -1
- package/dist/runtime/ext/extensions.js.map +0 -1
- package/dist/runtime/index.d.ts.map +0 -1
- package/dist/runtime/index.js.map +0 -1
- package/dist/signature-parser.d.ts.map +0 -1
- package/dist/signature-parser.js.map +0 -1
- package/dist/source-location.d.ts.map +0 -1
- package/dist/source-location.js.map +0 -1
- package/dist/token-types.d.ts.map +0 -1
- package/dist/token-types.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/value-types.d.ts.map +0 -1
- package/dist/value-types.js.map +0 -1
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
* @internal
|
|
43
43
|
*/
|
|
44
44
|
import { RillError, RuntimeError } from '../../../../types.js';
|
|
45
|
-
import { isCallable, isScriptCallable, isApplicationCallable, isDict,
|
|
45
|
+
import { isCallable, isScriptCallable, isApplicationCallable, isDict, marshalArgs, } from '../../callable.js';
|
|
46
46
|
import { getVariable, pushCallFrame, popCallFrame, UNVALIDATED_METHOD_PARAMS, UNVALIDATED_METHOD_RECEIVERS, } from '../../context.js';
|
|
47
|
-
import { inferType, isTypeValue, isTuple, isOrdered,
|
|
47
|
+
import { inferType, isTypeValue, isTuple, isOrdered, paramToFieldDef, inferStructuralType, structuralTypeMatches, formatStructuralType, anyTypeValue, rillTypeToTypeValue, } from '../../values.js';
|
|
48
48
|
/**
|
|
49
49
|
* ClosuresMixin implementation.
|
|
50
50
|
*
|
|
@@ -153,14 +153,22 @@ function createClosuresMixin(Base) {
|
|
|
153
153
|
async invokeFnCallable(callable, args, callLocation, functionName = 'callable') {
|
|
154
154
|
// Apply boundDict BEFORE validation (property-style callables need dict as first arg)
|
|
155
155
|
const effectiveArgs = callable.boundDict && args.length === 0 ? [callable.boundDict] : args;
|
|
156
|
-
//
|
|
156
|
+
// Marshal arguments for typed ApplicationCallable (IC-1).
|
|
157
157
|
// Skip when params is undefined (untyped callable() factory).
|
|
158
|
-
//
|
|
158
|
+
// Untyped callables still receive RillValue[] cast as Record to preserve
|
|
159
|
+
// existing runtime behavior without changing the fn contract.
|
|
160
|
+
let fnArgs;
|
|
159
161
|
if (isApplicationCallable(callable) && callable.params !== undefined) {
|
|
160
|
-
|
|
162
|
+
fnArgs = marshalArgs(effectiveArgs, callable.params, {
|
|
163
|
+
functionName,
|
|
164
|
+
location: callLocation,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
fnArgs = effectiveArgs;
|
|
161
169
|
}
|
|
162
170
|
try {
|
|
163
|
-
const result = callable.fn(
|
|
171
|
+
const result = callable.fn(fnArgs, this.ctx, callLocation);
|
|
164
172
|
return result instanceof Promise ? await result : result;
|
|
165
173
|
}
|
|
166
174
|
catch (error) {
|
|
@@ -219,28 +227,20 @@ function createClosuresMixin(Base) {
|
|
|
219
227
|
*/
|
|
220
228
|
async invokeScriptCallable(callable, args, callLocation) {
|
|
221
229
|
const callableCtx = this.createCallableContext(callable);
|
|
222
|
-
//
|
|
223
|
-
|
|
224
|
-
|
|
230
|
+
// Marshal positional args to named record (IC-1).
|
|
231
|
+
// Script callables always have params defined.
|
|
232
|
+
const record = marshalArgs(args, callable.params, {
|
|
233
|
+
functionName: '<anonymous>',
|
|
234
|
+
location: callLocation,
|
|
235
|
+
});
|
|
236
|
+
// Bind each named value into the callable context.
|
|
237
|
+
for (const [name, value] of Object.entries(record)) {
|
|
238
|
+
callableCtx.variables.set(name, value);
|
|
225
239
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
value = args[i];
|
|
231
|
-
}
|
|
232
|
-
else if (param.defaultValue !== undefined) {
|
|
233
|
-
value = param.defaultValue;
|
|
234
|
-
}
|
|
235
|
-
else {
|
|
236
|
-
throw new RuntimeError('RILL-R001', `Missing argument for parameter '${param.name}' at position ${i}`, callLocation, { paramName: param.name, position: i });
|
|
237
|
-
}
|
|
238
|
-
this.validateParamType(param, value, callLocation);
|
|
239
|
-
callableCtx.variables.set(param.name, value);
|
|
240
|
-
// Block-closures have param named '$': sync with pipeValue for bare $ references
|
|
241
|
-
if (param.name === '$') {
|
|
242
|
-
callableCtx.pipeValue = value;
|
|
243
|
-
}
|
|
240
|
+
// IR-4: Block closure pipe sync — first param named '$' means block closure.
|
|
241
|
+
// Sync pipeValue so bare '$' references resolve correctly inside the body.
|
|
242
|
+
if (callable.params[0]?.name === '$') {
|
|
243
|
+
callableCtx.pipeValue = record['$'];
|
|
244
244
|
}
|
|
245
245
|
// EC-1: Reject empty block bodies before execution (AC-17)
|
|
246
246
|
if (callable.body.type === 'Block' &&
|
|
@@ -557,23 +557,39 @@ function createClosuresMixin(Base) {
|
|
|
557
557
|
const typeDict = this.ctx.typeMethodDicts.get(typeName);
|
|
558
558
|
const typeMethod = typeDict?.[node.name];
|
|
559
559
|
if (typeMethod !== undefined && isApplicationCallable(typeMethod)) {
|
|
560
|
-
//
|
|
561
|
-
//
|
|
562
|
-
//
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
560
|
+
// IC-1: marshalArgs handles type method dispatch.
|
|
561
|
+
// effectiveArgs prepends receiver as first element; after task 2.3 typeMethod.params
|
|
562
|
+
// will include the receiver param so the counts align.
|
|
563
|
+
// UNVALIDATED_METHOD_PARAMS methods handle their own validation internally;
|
|
564
|
+
// skip marshalArgs for them and pass the positional array via cast.
|
|
565
|
+
const callLocation = this.getNodeLocation(node);
|
|
566
|
+
const effectiveArgs = [receiver, ...args];
|
|
567
|
+
let methodArgs;
|
|
568
|
+
if (typeMethod.params === undefined) {
|
|
569
|
+
// Untyped method: pass positional array via cast.
|
|
570
|
+
methodArgs = effectiveArgs;
|
|
571
|
+
}
|
|
572
|
+
else if (UNVALIDATED_METHOD_PARAMS.has(node.name)) {
|
|
573
|
+
// UNVALIDATED_METHOD_PARAMS: method handles its own arity and type
|
|
574
|
+
// validation with custom error messages. Pass the actual user args
|
|
575
|
+
// via __positionalArgs so buildMethodEntry reconstructs positionalArgs
|
|
576
|
+
// with the correct length, letting method body arity checks fire.
|
|
577
|
+
methodArgs = {
|
|
578
|
+
receiver,
|
|
579
|
+
__positionalArgs: args,
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
else {
|
|
583
|
+
methodArgs = marshalArgs(effectiveArgs, typeMethod.params, {
|
|
584
|
+
functionName: node.name,
|
|
585
|
+
location: callLocation,
|
|
586
|
+
});
|
|
587
|
+
}
|
|
571
588
|
try {
|
|
572
|
-
const result = typeMethod.fn(
|
|
589
|
+
const result = typeMethod.fn(methodArgs, this.ctx, callLocation);
|
|
573
590
|
return result instanceof Promise ? await result : result;
|
|
574
591
|
}
|
|
575
592
|
catch (error) {
|
|
576
|
-
const callLocation = this.getNodeLocation(node);
|
|
577
593
|
if (error instanceof RuntimeError &&
|
|
578
594
|
!error.location &&
|
|
579
595
|
callLocation) {
|
|
@@ -623,7 +639,18 @@ function createClosuresMixin(Base) {
|
|
|
623
639
|
if (fallbackMethod !== undefined &&
|
|
624
640
|
isApplicationCallable(fallbackMethod)) {
|
|
625
641
|
try {
|
|
626
|
-
|
|
642
|
+
// UNVALIDATED_METHOD_RECEIVERS handle their own receiver validation.
|
|
643
|
+
// Build named record with receiver so buildMethodEntry extracts it correctly;
|
|
644
|
+
// the method body performs its own receiver type check with a custom error.
|
|
645
|
+
const fbMethodArgs = { receiver };
|
|
646
|
+
if (fallbackMethod.params) {
|
|
647
|
+
for (let i = 1; i < fallbackMethod.params.length; i++) {
|
|
648
|
+
const p = fallbackMethod.params[i];
|
|
649
|
+
if (p)
|
|
650
|
+
fbMethodArgs[p.name] = args[i - 1] ?? null;
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
const result = fallbackMethod.fn(fbMethodArgs, this.ctx, this.getNodeLocation(node));
|
|
627
654
|
return result instanceof Promise ? await result : result;
|
|
628
655
|
}
|
|
629
656
|
catch (error) {
|
|
@@ -695,25 +722,16 @@ function createClosuresMixin(Base) {
|
|
|
695
722
|
if (key === 'description') {
|
|
696
723
|
return value.annotations['description'] ?? {};
|
|
697
724
|
}
|
|
698
|
-
// IR-3: ^input computes from callable.params
|
|
699
|
-
//
|
|
700
|
-
//
|
|
725
|
+
// IR-3: ^input computes from callable.params for all kinds.
|
|
726
|
+
// Each param's RillType is converted to a RillTypeValue so it is recognized
|
|
727
|
+
// as a type token (not a plain dict) in rill's type system.
|
|
701
728
|
if (key === 'input') {
|
|
702
729
|
// Untyped host callables have params set to undefined at runtime (see callable() factory)
|
|
703
730
|
if (value.params === undefined) {
|
|
704
|
-
return
|
|
705
|
-
}
|
|
706
|
-
const shape = paramsToStructuralType(value.params);
|
|
707
|
-
if (shape.type === 'closure') {
|
|
708
|
-
return {
|
|
709
|
-
type: shape.type,
|
|
710
|
-
params: createOrdered(shape.params),
|
|
711
|
-
// Use callable.returnType.structure so :type-target return annotation is reflected
|
|
712
|
-
// Fall back to { type: 'any' } for callables without returnType (legacy construction)
|
|
713
|
-
ret: value.returnType?.structure ?? { type: 'any' },
|
|
714
|
-
};
|
|
731
|
+
return rillTypeToTypeValue({ type: 'ordered', fields: [] });
|
|
715
732
|
}
|
|
716
|
-
|
|
733
|
+
const fields = value.params.map((param) => paramToFieldDef(param.name, param.type ?? { type: 'any' }, param.defaultValue));
|
|
734
|
+
return rillTypeToTypeValue({ type: 'ordered', fields });
|
|
717
735
|
}
|
|
718
736
|
// IR-3: ^output reads callable.returnType directly for all kinds
|
|
719
737
|
if (key === 'output') {
|
|
@@ -732,7 +750,14 @@ function createClosuresMixin(Base) {
|
|
|
732
750
|
*
|
|
733
751
|
* Evaluates positional args LTR, evaluates the spread expression, dispatches
|
|
734
752
|
* by value type (Tuple, Ordered, or Dict), validates bindings, and returns
|
|
735
|
-
* a
|
|
753
|
+
* a BoundArgs map of param name → value.
|
|
754
|
+
*
|
|
755
|
+
* Output is compatible with marshalArgs stages 2-3 (IR-1):
|
|
756
|
+
* - All params present in returned map (defaults applied, missing required throws)
|
|
757
|
+
* - Stage 1 (excess args) is NOT checked here; bindArgsToParams validates arity
|
|
758
|
+
* differently per spread source type (tuple length, dict key match, etc.)
|
|
759
|
+
* - Phase 2 callers convert BoundArgs.params to positional RillValue[] then
|
|
760
|
+
* feed into marshalArgs stages 2-3 for type-checking
|
|
736
761
|
*
|
|
737
762
|
* EC-3: bare ... with null pipe value → RuntimeError
|
|
738
763
|
* EC-4: spread value is not tuple/dict/ordered → RuntimeError
|
|
@@ -844,17 +869,6 @@ function createClosuresMixin(Base) {
|
|
|
844
869
|
finally {
|
|
845
870
|
this.ctx.pipeValue = savedPipeValue;
|
|
846
871
|
}
|
|
847
|
-
// EC-8: check for missing required parameters
|
|
848
|
-
for (const param of params) {
|
|
849
|
-
if (!bound.has(param.name)) {
|
|
850
|
-
if (param.defaultValue !== null && param.defaultValue !== undefined) {
|
|
851
|
-
bound.set(param.name, param.defaultValue);
|
|
852
|
-
}
|
|
853
|
-
else {
|
|
854
|
-
throw new RuntimeError('RILL-R001', `Missing required parameter '${param.name}'`, callLocation);
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
}
|
|
858
872
|
return { params: bound };
|
|
859
873
|
}
|
|
860
874
|
/**
|
|
@@ -896,4 +910,3 @@ function createClosuresMixin(Base) {
|
|
|
896
910
|
// TypeScript can't generate declarations for functions returning classes with protected members
|
|
897
911
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
898
912
|
export const ClosuresMixin = createClosuresMixin;
|
|
899
|
-
//# sourceMappingURL=closures.js.map
|
|
@@ -24,7 +24,7 @@ import { RuntimeError } from '../../../../types.js';
|
|
|
24
24
|
import { inferType, isRillIterator, isVector } from '../../values.js';
|
|
25
25
|
import { createChildContext, getVariable } from '../../context.js';
|
|
26
26
|
import { BreakSignal } from '../../signals.js';
|
|
27
|
-
import { isCallable, isDict } from '../../callable.js';
|
|
27
|
+
import { isCallable, isDict, marshalArgs } from '../../callable.js';
|
|
28
28
|
import { getEvaluator } from '../evaluator.js';
|
|
29
29
|
/**
|
|
30
30
|
* Default maximum iteration count for iterators.
|
|
@@ -223,9 +223,15 @@ function createCollectionsMixin(Base) {
|
|
|
223
223
|
if (accumulator !== null) {
|
|
224
224
|
args.push(accumulator);
|
|
225
225
|
}
|
|
226
|
-
// Handle both CallableFn and ApplicationCallable (task 1.5 will refactor validation)
|
|
227
226
|
const fnToCall = typeof fn === 'function' ? fn : fn.fn;
|
|
228
|
-
|
|
227
|
+
// Marshal args to named record if fn has params; cast otherwise (IC-1).
|
|
228
|
+
const callArgs = typeof fn !== 'function' && fn.params !== undefined
|
|
229
|
+
? marshalArgs(args, fn.params, {
|
|
230
|
+
functionName: body.name,
|
|
231
|
+
location: body.span.start,
|
|
232
|
+
})
|
|
233
|
+
: args;
|
|
234
|
+
return fnToCall(callArgs, this.ctx, body.span.start);
|
|
229
235
|
}
|
|
230
236
|
default: {
|
|
231
237
|
// TypeScript exhaustiveness check - should never reach here
|
|
@@ -509,4 +515,3 @@ function createCollectionsMixin(Base) {
|
|
|
509
515
|
// TypeScript can't generate declarations for functions returning classes with protected members
|
|
510
516
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
511
517
|
export const CollectionsMixin = createCollectionsMixin;
|
|
512
|
-
//# sourceMappingURL=collections.js.map
|
|
@@ -453,4 +453,3 @@ function createControlFlowMixin(Base) {
|
|
|
453
453
|
// TypeScript can't generate declarations for functions returning classes with protected members
|
|
454
454
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
455
455
|
export const ControlFlowMixin = createControlFlowMixin;
|
|
456
|
-
//# sourceMappingURL=control-flow.js.map
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
* @internal
|
|
28
28
|
*/
|
|
29
29
|
import { RuntimeError } from '../../../../types.js';
|
|
30
|
-
import { inferType, isTuple, isOrdered, isTypeValue, createOrdered, createTuple, formatValue, } from '../../values.js';
|
|
30
|
+
import { inferType, isTuple, isOrdered, isTypeValue, createOrdered, createTuple, formatValue, deepCopyRillValue, hasCollectionFields, emptyForType, } from '../../values.js';
|
|
31
31
|
import { isDict } from '../../callable.js';
|
|
32
32
|
import { getVariable } from '../../context.js';
|
|
33
33
|
/**
|
|
@@ -54,10 +54,31 @@ function createConversionMixin(Base) {
|
|
|
54
54
|
const typeRef = node.typeRef;
|
|
55
55
|
// Structural type constructor: :>ordered(name: type, ...) or :>list(T), :>dict(...), :>tuple(...)
|
|
56
56
|
if (isTypeConstructorNode(typeRef)) {
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
// For dict/ordered/tuple, evaluate the type constructor to determine
|
|
58
|
+
// uniform (valueType) vs structural (fields/elements) dispatch.
|
|
59
|
+
if (typeRef.constructorName === 'ordered' ||
|
|
60
|
+
typeRef.constructorName === 'dict' ||
|
|
61
|
+
typeRef.constructorName === 'tuple') {
|
|
62
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
63
|
+
const typeValue = await this.evaluateTypeConstructor(typeRef);
|
|
64
|
+
const structure = typeValue.structure;
|
|
65
|
+
// Uniform types (valueType present): use general convert-then-assert path
|
|
66
|
+
if ('valueType' in structure && structure.valueType) {
|
|
67
|
+
const result = this.applyConversion(input, typeRef.constructorName, node);
|
|
68
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
69
|
+
this.assertType(result, structure, node.span.start);
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
// Structural types (fields/elements present): use structural-specific handlers
|
|
73
|
+
if (typeRef.constructorName === 'ordered') {
|
|
74
|
+
return this.convertToOrderedWithSig(input, typeRef, node);
|
|
75
|
+
}
|
|
76
|
+
if (typeRef.constructorName === 'dict') {
|
|
77
|
+
return this.convertToDictWithSig(input, typeRef, node);
|
|
78
|
+
}
|
|
79
|
+
return this.convertToTupleWithSig(input, typeRef, node);
|
|
59
80
|
}
|
|
60
|
-
// Non-ordered constructors: convert first, then assert structural type
|
|
81
|
+
// Non-dict/ordered/tuple constructors: convert first, then assert structural type
|
|
61
82
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
62
83
|
const typeValue = await this.evaluateTypeConstructor(typeRef);
|
|
63
84
|
const result = this.applyConversion(input, typeRef.constructorName, node);
|
|
@@ -194,26 +215,253 @@ function createConversionMixin(Base) {
|
|
|
194
215
|
return formatValue(input);
|
|
195
216
|
}
|
|
196
217
|
/**
|
|
197
|
-
* Convert dict -> :>ordered(field: type, ...) using structural signature.
|
|
198
|
-
*
|
|
218
|
+
* Convert dict -> :>ordered(field: type = default, ...) using structural signature.
|
|
219
|
+
*
|
|
220
|
+
* - Input must be a dict (else RILL-R036)
|
|
221
|
+
* - Iterates signature fields in declaration order
|
|
222
|
+
* - Missing field with default: inserts deep copy of default value
|
|
223
|
+
* - Missing field without default: emits RILL-R044
|
|
224
|
+
* - Extra keys not in signature: omitted from result
|
|
199
225
|
*/
|
|
200
|
-
convertToOrderedWithSig(input, sigNode, node) {
|
|
201
|
-
|
|
226
|
+
async convertToOrderedWithSig(input, sigNode, node) {
|
|
227
|
+
let dictInput;
|
|
228
|
+
if (isOrdered(input)) {
|
|
229
|
+
dictInput = Object.fromEntries(input.entries);
|
|
230
|
+
}
|
|
231
|
+
else if (isDict(input)) {
|
|
232
|
+
dictInput = input;
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
202
235
|
throw new RuntimeError('RILL-R036', `cannot convert ${inferType(input)} to ordered`, this.getNodeLocation(node), { source: inferType(input), target: 'ordered' });
|
|
203
236
|
}
|
|
204
|
-
const
|
|
237
|
+
const sourceType = isOrdered(input) ? 'ordered' : 'dict';
|
|
238
|
+
// Evaluate the full type constructor to get resolved fields with defaults.
|
|
239
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
240
|
+
const typeValue = await this.evaluateTypeConstructor(sigNode);
|
|
241
|
+
const resolvedFields = typeValue.structure.type === 'ordered' && typeValue.structure.fields
|
|
242
|
+
? typeValue.structure.fields
|
|
243
|
+
: [];
|
|
205
244
|
const entries = [];
|
|
245
|
+
for (const field of resolvedFields) {
|
|
246
|
+
const fieldName = field.name;
|
|
247
|
+
if (fieldName in dictInput) {
|
|
248
|
+
let fieldValue = dictInput[fieldName];
|
|
249
|
+
fieldValue = this.hydrateNested(fieldValue, field.type, node);
|
|
250
|
+
entries.push([fieldName, fieldValue]);
|
|
251
|
+
}
|
|
252
|
+
else if (field.defaultValue !== undefined) {
|
|
253
|
+
entries.push([
|
|
254
|
+
fieldName,
|
|
255
|
+
this.hydrateNested(deepCopyRillValue(field.defaultValue), field.type, node),
|
|
256
|
+
]);
|
|
257
|
+
}
|
|
258
|
+
else if (hasCollectionFields(field.type)) {
|
|
259
|
+
entries.push([
|
|
260
|
+
fieldName,
|
|
261
|
+
this.hydrateNested(emptyForType(field.type), field.type, node),
|
|
262
|
+
]);
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
throw new RuntimeError('RILL-R044', `cannot convert ${sourceType} to ordered: missing required field '${fieldName}'`, this.getNodeLocation(node), { source: sourceType, target: 'ordered' });
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return createOrdered(entries);
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Convert dict -> :>dict(field: type = default, ...) using structural signature [IR-4].
|
|
272
|
+
*
|
|
273
|
+
* - Input must be a dict (else RILL-R036)
|
|
274
|
+
* - Iterates signature fields in declaration order
|
|
275
|
+
* - Missing field with default: inserts deep copy of default value
|
|
276
|
+
* - Missing field without default: emits RILL-R044
|
|
277
|
+
* - Extra keys not in signature: omitted from result
|
|
278
|
+
* - Recurses into nested dict-typed fields for nested hydration
|
|
279
|
+
*/
|
|
280
|
+
async convertToDictWithSig(input, sigNode, node) {
|
|
281
|
+
let dictInput;
|
|
282
|
+
if (isOrdered(input)) {
|
|
283
|
+
dictInput = Object.fromEntries(input.entries);
|
|
284
|
+
}
|
|
285
|
+
else if (isDict(input)) {
|
|
286
|
+
dictInput = input;
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
throw new RuntimeError('RILL-R036', `cannot convert ${inferType(input)} to dict`, this.getNodeLocation(node), { source: inferType(input), target: 'dict' });
|
|
290
|
+
}
|
|
291
|
+
const sourceType = isOrdered(input) ? 'ordered' : 'dict';
|
|
292
|
+
// Evaluate the full type constructor to get resolved fields with defaults.
|
|
293
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
294
|
+
const typeValue = await this.evaluateTypeConstructor(sigNode);
|
|
295
|
+
const resolvedFields = typeValue.structure.type === 'dict' && typeValue.structure.fields
|
|
296
|
+
? typeValue.structure.fields
|
|
297
|
+
: {};
|
|
298
|
+
const result = {};
|
|
206
299
|
for (const arg of sigNode.args) {
|
|
207
|
-
if (arg.
|
|
208
|
-
|
|
300
|
+
if (arg.name === undefined) {
|
|
301
|
+
continue;
|
|
209
302
|
}
|
|
210
303
|
const fieldName = arg.name;
|
|
211
|
-
|
|
212
|
-
|
|
304
|
+
const resolvedField = resolvedFields[fieldName];
|
|
305
|
+
if (fieldName in dictInput) {
|
|
306
|
+
// Field present in input: use it, recursing if the field type is a nested dict
|
|
307
|
+
let fieldValue = dictInput[fieldName];
|
|
308
|
+
if (resolvedField !== undefined) {
|
|
309
|
+
fieldValue = this.hydrateNested(fieldValue, resolvedField.type, node);
|
|
310
|
+
}
|
|
311
|
+
result[fieldName] = fieldValue;
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
// Field missing from input: use default if available, else error
|
|
315
|
+
if (resolvedField !== undefined &&
|
|
316
|
+
resolvedField.defaultValue !== undefined) {
|
|
317
|
+
result[fieldName] = this.hydrateNested(deepCopyRillValue(resolvedField.defaultValue), resolvedField.type, node);
|
|
318
|
+
}
|
|
319
|
+
else if (resolvedField !== undefined &&
|
|
320
|
+
hasCollectionFields(resolvedField.type)) {
|
|
321
|
+
result[fieldName] = this.hydrateNested(emptyForType(resolvedField.type), resolvedField.type, node);
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
throw new RuntimeError('RILL-R044', `cannot convert ${sourceType} to dict: missing required field '${fieldName}'`, this.getNodeLocation(node), { source: sourceType, target: 'dict' });
|
|
325
|
+
}
|
|
213
326
|
}
|
|
214
|
-
entries.push([fieldName, dictInput[fieldName]]);
|
|
215
327
|
}
|
|
216
|
-
return
|
|
328
|
+
return result;
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Convert tuple/list -> :>tuple(type, ...) using structural signature [IR-5].
|
|
332
|
+
*
|
|
333
|
+
* - Input must be a tuple or list (else RILL-R036)
|
|
334
|
+
* - Iterates signature elements in declaration order
|
|
335
|
+
* - Missing trailing element with default: inserts deep copy of default value
|
|
336
|
+
* - Missing element without default: emits RILL-R044 with position
|
|
337
|
+
* - Extra elements beyond signature length: omitted from result
|
|
338
|
+
*/
|
|
339
|
+
async convertToTupleWithSig(input, sigNode, node) {
|
|
340
|
+
const isTupleInput = isTuple(input);
|
|
341
|
+
const isListInput = Array.isArray(input) && !isTupleInput && !isOrdered(input);
|
|
342
|
+
if (!isTupleInput && !isListInput) {
|
|
343
|
+
throw new RuntimeError('RILL-R036', `cannot convert ${inferType(input)} to tuple`, this.getNodeLocation(node), { source: inferType(input), target: 'tuple' });
|
|
344
|
+
}
|
|
345
|
+
// Evaluate the full type constructor to get resolved elements with defaults.
|
|
346
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
347
|
+
const typeValue = await this.evaluateTypeConstructor(sigNode);
|
|
348
|
+
const resolvedElements = typeValue.structure.type === 'tuple' && typeValue.structure.elements
|
|
349
|
+
? typeValue.structure.elements
|
|
350
|
+
: [];
|
|
351
|
+
const inputEntries = isTupleInput
|
|
352
|
+
? input.entries
|
|
353
|
+
: input;
|
|
354
|
+
const result = [];
|
|
355
|
+
for (let i = 0; i < resolvedElements.length; i++) {
|
|
356
|
+
const element = resolvedElements[i];
|
|
357
|
+
if (i < inputEntries.length) {
|
|
358
|
+
// Element present in input: recurse into nested types
|
|
359
|
+
result.push(this.hydrateNested(inputEntries[i], element.type, node));
|
|
360
|
+
}
|
|
361
|
+
else if (element.defaultValue !== undefined) {
|
|
362
|
+
// Missing trailing element with default: deep copy and hydrate
|
|
363
|
+
result.push(this.hydrateNested(deepCopyRillValue(element.defaultValue), element.type, node));
|
|
364
|
+
}
|
|
365
|
+
else if (hasCollectionFields(element.type)) {
|
|
366
|
+
// Missing element with collection type: seed empty and hydrate
|
|
367
|
+
result.push(this.hydrateNested(emptyForType(element.type), element.type, node));
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
370
|
+
// Missing element without default
|
|
371
|
+
throw new RuntimeError('RILL-R044', `cannot convert ${inferType(input)} to tuple: missing required element at position ${i}`, this.getNodeLocation(node), { source: inferType(input), target: 'tuple' });
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
return createTuple(result);
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Recursively hydrate a value against a nested dict, ordered, or tuple RillType.
|
|
378
|
+
* Only applies when the field type has explicit fields/elements.
|
|
379
|
+
* Returns the value unchanged if the type has no fields or the value type does not match.
|
|
380
|
+
*/
|
|
381
|
+
hydrateNested(value, fieldType, node) {
|
|
382
|
+
if (fieldType.type === 'dict' && fieldType.fields && isDict(value)) {
|
|
383
|
+
const dictValue = value;
|
|
384
|
+
const result = {};
|
|
385
|
+
for (const [fieldName, resolvedField] of Object.entries(fieldType.fields)) {
|
|
386
|
+
if (fieldName in dictValue) {
|
|
387
|
+
const fieldValue = this.hydrateNested(dictValue[fieldName], resolvedField.type, node);
|
|
388
|
+
result[fieldName] = fieldValue;
|
|
389
|
+
}
|
|
390
|
+
else {
|
|
391
|
+
if (resolvedField.defaultValue !== undefined) {
|
|
392
|
+
result[fieldName] = this.hydrateNested(deepCopyRillValue(resolvedField.defaultValue), resolvedField.type, node);
|
|
393
|
+
}
|
|
394
|
+
else if (hasCollectionFields(resolvedField.type)) {
|
|
395
|
+
result[fieldName] = this.hydrateNested(emptyForType(resolvedField.type), resolvedField.type, node);
|
|
396
|
+
}
|
|
397
|
+
else {
|
|
398
|
+
throw new RuntimeError('RILL-R044', `cannot convert dict to dict: missing required field '${fieldName}'`, this.getNodeLocation(node), { source: 'dict', target: 'dict' });
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
return result;
|
|
403
|
+
}
|
|
404
|
+
else if (fieldType.type === 'ordered' && fieldType.fields) {
|
|
405
|
+
// Only hydrate if the runtime value is an ordered or dict; return unchanged otherwise.
|
|
406
|
+
if (!isOrdered(value) && !isDict(value)) {
|
|
407
|
+
return value;
|
|
408
|
+
}
|
|
409
|
+
const source = isOrdered(value) ? 'ordered' : 'dict';
|
|
410
|
+
// Build a key->value lookup from either an ordered value or a dict value.
|
|
411
|
+
const lookup = new Map(isOrdered(value)
|
|
412
|
+
? value.entries.map(([k, v]) => [k, v])
|
|
413
|
+
: Object.entries(value));
|
|
414
|
+
const resultEntries = [];
|
|
415
|
+
for (const field of fieldType.fields) {
|
|
416
|
+
const name = field.name;
|
|
417
|
+
if (lookup.has(name)) {
|
|
418
|
+
const fieldValue = this.hydrateNested(lookup.get(name), field.type, node);
|
|
419
|
+
resultEntries.push([name, fieldValue]);
|
|
420
|
+
}
|
|
421
|
+
else if (field.defaultValue !== undefined) {
|
|
422
|
+
resultEntries.push([
|
|
423
|
+
name,
|
|
424
|
+
this.hydrateNested(deepCopyRillValue(field.defaultValue), field.type, node),
|
|
425
|
+
]);
|
|
426
|
+
}
|
|
427
|
+
else if (hasCollectionFields(field.type)) {
|
|
428
|
+
resultEntries.push([
|
|
429
|
+
name,
|
|
430
|
+
this.hydrateNested(emptyForType(field.type), field.type, node),
|
|
431
|
+
]);
|
|
432
|
+
}
|
|
433
|
+
else {
|
|
434
|
+
throw new RuntimeError('RILL-R044', `cannot convert ${source} to ordered: missing required field '${name}'`, this.getNodeLocation(node), { source, target: 'ordered' });
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
return createOrdered(resultEntries);
|
|
438
|
+
}
|
|
439
|
+
else if (fieldType.type === 'tuple' && fieldType.elements) {
|
|
440
|
+
// Only hydrate if the runtime value is a tuple; return unchanged otherwise.
|
|
441
|
+
if (!isTuple(value)) {
|
|
442
|
+
return value;
|
|
443
|
+
}
|
|
444
|
+
const inputEntries = value.entries;
|
|
445
|
+
const resultEntries = [];
|
|
446
|
+
for (let i = 0; i < fieldType.elements.length; i++) {
|
|
447
|
+
const element = fieldType.elements[i];
|
|
448
|
+
if (i < inputEntries.length) {
|
|
449
|
+
const elementValue = this.hydrateNested(inputEntries[i], element.type, node);
|
|
450
|
+
resultEntries.push(elementValue);
|
|
451
|
+
}
|
|
452
|
+
else if (element.defaultValue !== undefined) {
|
|
453
|
+
resultEntries.push(this.hydrateNested(deepCopyRillValue(element.defaultValue), element.type, node));
|
|
454
|
+
}
|
|
455
|
+
else if (hasCollectionFields(element.type)) {
|
|
456
|
+
resultEntries.push(this.hydrateNested(emptyForType(element.type), element.type, node));
|
|
457
|
+
}
|
|
458
|
+
else {
|
|
459
|
+
throw new RuntimeError('RILL-R044', `cannot convert tuple to tuple: missing required element at position ${i}`, this.getNodeLocation(node), { source: 'tuple', target: 'tuple' });
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
return createTuple(resultEntries);
|
|
463
|
+
}
|
|
464
|
+
return value;
|
|
217
465
|
}
|
|
218
466
|
/** Throw EC-10 incompatible conversion error. */
|
|
219
467
|
throwIncompatible(source, target, node) {
|
|
@@ -230,4 +478,3 @@ function isTypeConstructorNode(ref) {
|
|
|
230
478
|
// Export with type assertion to work around TS4094 limitation
|
|
231
479
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
232
480
|
export const ConversionMixin = createConversionMixin;
|
|
233
|
-
//# sourceMappingURL=conversion.js.map
|
|
@@ -753,4 +753,3 @@ function createCoreMixin(Base) {
|
|
|
753
753
|
// TypeScript can't generate declarations for functions returning classes with protected members
|
|
754
754
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
755
755
|
export const CoreMixin = createCoreMixin;
|
|
756
|
-
//# sourceMappingURL=core.js.map
|
|
@@ -252,4 +252,3 @@ function createExpressionsMixin(Base) {
|
|
|
252
252
|
// TypeScript can't generate declarations for functions returning classes with protected members
|
|
253
253
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
254
254
|
export const ExpressionsMixin = createExpressionsMixin;
|
|
255
|
-
//# sourceMappingURL=expressions.js.map
|