@rcrsr/rill 0.15.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 -13
- 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 +32 -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 -52
- 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 -28
- 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 -60
- 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 +153 -86
- 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 -242
- 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 -26
- package/dist/runtime/core/values.js +289 -77
- 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 -6
- 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,16 +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
|
|
731
|
+
return rillTypeToTypeValue({ type: 'ordered', fields: [] });
|
|
705
732
|
}
|
|
706
|
-
const
|
|
707
|
-
return
|
|
733
|
+
const fields = value.params.map((param) => paramToFieldDef(param.name, param.type ?? { type: 'any' }, param.defaultValue));
|
|
734
|
+
return rillTypeToTypeValue({ type: 'ordered', fields });
|
|
708
735
|
}
|
|
709
736
|
// IR-3: ^output reads callable.returnType directly for all kinds
|
|
710
737
|
if (key === 'output') {
|
|
@@ -723,7 +750,14 @@ function createClosuresMixin(Base) {
|
|
|
723
750
|
*
|
|
724
751
|
* Evaluates positional args LTR, evaluates the spread expression, dispatches
|
|
725
752
|
* by value type (Tuple, Ordered, or Dict), validates bindings, and returns
|
|
726
|
-
* 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
|
|
727
761
|
*
|
|
728
762
|
* EC-3: bare ... with null pipe value → RuntimeError
|
|
729
763
|
* EC-4: spread value is not tuple/dict/ordered → RuntimeError
|
|
@@ -835,17 +869,6 @@ function createClosuresMixin(Base) {
|
|
|
835
869
|
finally {
|
|
836
870
|
this.ctx.pipeValue = savedPipeValue;
|
|
837
871
|
}
|
|
838
|
-
// EC-8: check for missing required parameters
|
|
839
|
-
for (const param of params) {
|
|
840
|
-
if (!bound.has(param.name)) {
|
|
841
|
-
if (param.defaultValue !== null && param.defaultValue !== undefined) {
|
|
842
|
-
bound.set(param.name, param.defaultValue);
|
|
843
|
-
}
|
|
844
|
-
else {
|
|
845
|
-
throw new RuntimeError('RILL-R001', `Missing required parameter '${param.name}'`, callLocation);
|
|
846
|
-
}
|
|
847
|
-
}
|
|
848
|
-
}
|
|
849
872
|
return { params: bound };
|
|
850
873
|
}
|
|
851
874
|
/**
|
|
@@ -887,4 +910,3 @@ function createClosuresMixin(Base) {
|
|
|
887
910
|
// TypeScript can't generate declarations for functions returning classes with protected members
|
|
888
911
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
889
912
|
export const ClosuresMixin = createClosuresMixin;
|
|
890
|
-
//# 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,
|
|
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,16 +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
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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
|
+
}
|
|
64
79
|
return this.convertToTupleWithSig(input, typeRef, node);
|
|
65
80
|
}
|
|
66
|
-
// Non-dict/ordered constructors: convert first, then assert structural type
|
|
81
|
+
// Non-dict/ordered/tuple constructors: convert first, then assert structural type
|
|
67
82
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
68
83
|
const typeValue = await this.evaluateTypeConstructor(typeRef);
|
|
69
84
|
const result = this.applyConversion(input, typeRef.constructorName, node);
|
|
@@ -209,28 +224,45 @@ function createConversionMixin(Base) {
|
|
|
209
224
|
* - Extra keys not in signature: omitted from result
|
|
210
225
|
*/
|
|
211
226
|
async convertToOrderedWithSig(input, sigNode, node) {
|
|
212
|
-
|
|
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 {
|
|
213
235
|
throw new RuntimeError('RILL-R036', `cannot convert ${inferType(input)} to ordered`, this.getNodeLocation(node), { source: inferType(input), target: 'ordered' });
|
|
214
236
|
}
|
|
237
|
+
const sourceType = isOrdered(input) ? 'ordered' : 'dict';
|
|
215
238
|
// Evaluate the full type constructor to get resolved fields with defaults.
|
|
216
239
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
217
240
|
const typeValue = await this.evaluateTypeConstructor(sigNode);
|
|
218
241
|
const resolvedFields = typeValue.structure.type === 'ordered' && typeValue.structure.fields
|
|
219
242
|
? typeValue.structure.fields
|
|
220
243
|
: [];
|
|
221
|
-
const dictInput = input;
|
|
222
244
|
const entries = [];
|
|
223
245
|
for (const field of resolvedFields) {
|
|
224
|
-
const fieldName = field
|
|
225
|
-
const hasDefault = field.length === 3;
|
|
246
|
+
const fieldName = field.name;
|
|
226
247
|
if (fieldName in dictInput) {
|
|
227
|
-
|
|
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
|
+
]);
|
|
228
257
|
}
|
|
229
|
-
else if (
|
|
230
|
-
entries.push([
|
|
258
|
+
else if (hasCollectionFields(field.type)) {
|
|
259
|
+
entries.push([
|
|
260
|
+
fieldName,
|
|
261
|
+
this.hydrateNested(emptyForType(field.type), field.type, node),
|
|
262
|
+
]);
|
|
231
263
|
}
|
|
232
264
|
else {
|
|
233
|
-
throw new RuntimeError('RILL-R044', `cannot convert
|
|
265
|
+
throw new RuntimeError('RILL-R044', `cannot convert ${sourceType} to ordered: missing required field '${fieldName}'`, this.getNodeLocation(node), { source: sourceType, target: 'ordered' });
|
|
234
266
|
}
|
|
235
267
|
}
|
|
236
268
|
return createOrdered(entries);
|
|
@@ -246,19 +278,26 @@ function createConversionMixin(Base) {
|
|
|
246
278
|
* - Recurses into nested dict-typed fields for nested hydration
|
|
247
279
|
*/
|
|
248
280
|
async convertToDictWithSig(input, sigNode, node) {
|
|
249
|
-
|
|
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 {
|
|
250
289
|
throw new RuntimeError('RILL-R036', `cannot convert ${inferType(input)} to dict`, this.getNodeLocation(node), { source: inferType(input), target: 'dict' });
|
|
251
290
|
}
|
|
291
|
+
const sourceType = isOrdered(input) ? 'ordered' : 'dict';
|
|
252
292
|
// Evaluate the full type constructor to get resolved fields with defaults.
|
|
253
293
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
254
294
|
const typeValue = await this.evaluateTypeConstructor(sigNode);
|
|
255
295
|
const resolvedFields = typeValue.structure.type === 'dict' && typeValue.structure.fields
|
|
256
296
|
? typeValue.structure.fields
|
|
257
297
|
: {};
|
|
258
|
-
const dictInput = input;
|
|
259
298
|
const result = {};
|
|
260
299
|
for (const arg of sigNode.args) {
|
|
261
|
-
if (arg.
|
|
300
|
+
if (arg.name === undefined) {
|
|
262
301
|
continue;
|
|
263
302
|
}
|
|
264
303
|
const fieldName = arg.name;
|
|
@@ -267,21 +306,22 @@ function createConversionMixin(Base) {
|
|
|
267
306
|
// Field present in input: use it, recursing if the field type is a nested dict
|
|
268
307
|
let fieldValue = dictInput[fieldName];
|
|
269
308
|
if (resolvedField !== undefined) {
|
|
270
|
-
|
|
271
|
-
? resolvedField.type
|
|
272
|
-
: resolvedField;
|
|
273
|
-
fieldValue = this.hydrateNestedDict(fieldValue, innerType, node);
|
|
309
|
+
fieldValue = this.hydrateNested(fieldValue, resolvedField.type, node);
|
|
274
310
|
}
|
|
275
311
|
result[fieldName] = fieldValue;
|
|
276
312
|
}
|
|
277
313
|
else {
|
|
278
314
|
// Field missing from input: use default if available, else error
|
|
279
315
|
if (resolvedField !== undefined &&
|
|
280
|
-
|
|
281
|
-
result[fieldName] = deepCopyRillValue(resolvedField.defaultValue);
|
|
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);
|
|
282
322
|
}
|
|
283
323
|
else {
|
|
284
|
-
throw new RuntimeError('RILL-R044', `cannot convert
|
|
324
|
+
throw new RuntimeError('RILL-R044', `cannot convert ${sourceType} to dict: missing required field '${fieldName}'`, this.getNodeLocation(node), { source: sourceType, target: 'dict' });
|
|
285
325
|
}
|
|
286
326
|
}
|
|
287
327
|
}
|
|
@@ -314,14 +354,17 @@ function createConversionMixin(Base) {
|
|
|
314
354
|
const result = [];
|
|
315
355
|
for (let i = 0; i < resolvedElements.length; i++) {
|
|
316
356
|
const element = resolvedElements[i];
|
|
317
|
-
const hasDefault = element.length === 2;
|
|
318
357
|
if (i < inputEntries.length) {
|
|
319
|
-
// Element present in input:
|
|
320
|
-
result.push(inputEntries[i]);
|
|
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));
|
|
321
364
|
}
|
|
322
|
-
else if (
|
|
323
|
-
// Missing
|
|
324
|
-
result.push(
|
|
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));
|
|
325
368
|
}
|
|
326
369
|
else {
|
|
327
370
|
// Missing element without default
|
|
@@ -331,40 +374,94 @@ function createConversionMixin(Base) {
|
|
|
331
374
|
return createTuple(result);
|
|
332
375
|
}
|
|
333
376
|
/**
|
|
334
|
-
* Recursively hydrate a
|
|
335
|
-
* Only applies when the field type
|
|
336
|
-
* Returns the value unchanged if
|
|
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.
|
|
337
380
|
*/
|
|
338
|
-
|
|
339
|
-
if (fieldType.type
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
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;
|
|
344
403
|
}
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
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
|
+
]);
|
|
352
432
|
}
|
|
353
433
|
else {
|
|
354
|
-
|
|
434
|
+
throw new RuntimeError('RILL-R044', `cannot convert ${source} to ordered: missing required field '${name}'`, this.getNodeLocation(node), { source, target: 'ordered' });
|
|
355
435
|
}
|
|
356
|
-
result[fieldName] = fieldValue;
|
|
357
436
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
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));
|
|
361
457
|
}
|
|
362
458
|
else {
|
|
363
|
-
throw new RuntimeError('RILL-R044', `cannot convert
|
|
459
|
+
throw new RuntimeError('RILL-R044', `cannot convert tuple to tuple: missing required element at position ${i}`, this.getNodeLocation(node), { source: 'tuple', target: 'tuple' });
|
|
364
460
|
}
|
|
365
461
|
}
|
|
462
|
+
return createTuple(resultEntries);
|
|
366
463
|
}
|
|
367
|
-
return
|
|
464
|
+
return value;
|
|
368
465
|
}
|
|
369
466
|
/** Throw EC-10 incompatible conversion error. */
|
|
370
467
|
throwIncompatible(source, target, node) {
|
|
@@ -372,35 +469,6 @@ function createConversionMixin(Base) {
|
|
|
372
469
|
}
|
|
373
470
|
};
|
|
374
471
|
}
|
|
375
|
-
/**
|
|
376
|
-
* Deep copy a RillValue, producing a new independent value.
|
|
377
|
-
* Handles primitives, arrays, plain dicts, and null.
|
|
378
|
-
* Special markers (closures, tuples, ordered, vectors, type values) are returned
|
|
379
|
-
* as-is since they are immutable by contract.
|
|
380
|
-
*/
|
|
381
|
-
function deepCopyRillValue(value) {
|
|
382
|
-
if (value === null || typeof value !== 'object') {
|
|
383
|
-
return value;
|
|
384
|
-
}
|
|
385
|
-
if (Array.isArray(value)) {
|
|
386
|
-
return value.map(deepCopyRillValue);
|
|
387
|
-
}
|
|
388
|
-
// Plain dict: copy recursively. Special markers (RillTuple, RillOrdered, etc.)
|
|
389
|
-
// carry __rill_* own properties and are treated as immutable; return as-is.
|
|
390
|
-
if (!('__rill_tuple' in value) &&
|
|
391
|
-
!('__rill_ordered' in value) &&
|
|
392
|
-
!('__rill_vector' in value) &&
|
|
393
|
-
!('__rill_type' in value) &&
|
|
394
|
-
!('__type' in value) &&
|
|
395
|
-
!('__rill_field_descriptor' in value)) {
|
|
396
|
-
const copy = {};
|
|
397
|
-
for (const [k, v] of Object.entries(value)) {
|
|
398
|
-
copy[k] = deepCopyRillValue(v);
|
|
399
|
-
}
|
|
400
|
-
return copy;
|
|
401
|
-
}
|
|
402
|
-
return value;
|
|
403
|
-
}
|
|
404
472
|
/**
|
|
405
473
|
* Type guard: check if a TypeRef | TypeConstructorNode is a TypeConstructorNode.
|
|
406
474
|
*/
|
|
@@ -410,4 +478,3 @@ function isTypeConstructorNode(ref) {
|
|
|
410
478
|
// Export with type assertion to work around TS4094 limitation
|
|
411
479
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
412
480
|
export const ConversionMixin = createConversionMixin;
|
|
413
|
-
//# 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
|