@rcrsr/rill 0.15.0 → 0.17.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/README.md +37 -21
- 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 +3 -4
- package/dist/ext/crypto/index.js +66 -64
- package/dist/ext/exec/index.d.ts +3 -4
- package/dist/ext/exec/index.js +17 -12
- package/dist/ext/exec/runner.d.ts +0 -1
- package/dist/ext/exec/runner.js +0 -1
- package/dist/ext/fetch/index.d.ts +3 -4
- package/dist/ext/fetch/index.js +23 -49
- package/dist/ext/fetch/request.d.ts +0 -1
- package/dist/ext/fetch/request.js +0 -1
- package/dist/ext/fs/index.d.ts +3 -4
- package/dist/ext/fs/index.js +268 -266
- package/dist/ext/fs/sandbox.d.ts +0 -1
- package/dist/ext/fs/sandbox.js +0 -1
- package/dist/ext/kv/index.d.ts +3 -4
- package/dist/ext/kv/index.js +216 -215
- package/dist/ext/kv/store.d.ts +0 -1
- package/dist/ext/kv/store.js +2 -2
- package/dist/ext-parse-bridge.d.ts +10 -0
- package/dist/ext-parse-bridge.js +10 -0
- package/dist/generated/introspection-data.d.ts +1 -2
- package/dist/generated/introspection-data.js +385 -297
- 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 +15 -5
- package/dist/index.js +14 -6
- 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 +76 -13
- package/dist/parser/parser-use.d.ts +0 -1
- package/dist/parser/parser-use.js +7 -2
- 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 +59 -20
- package/dist/runtime/core/callable.js +188 -39
- package/dist/runtime/core/context.d.ts +0 -12
- package/dist/runtime/core/context.js +77 -77
- 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 +2 -3
- package/dist/runtime/core/eval/index.js +11 -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 +92 -70
- 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 +196 -188
- package/dist/runtime/core/eval/mixins/core.d.ts +0 -1
- package/dist/runtime/core/eval/mixins/core.js +2 -3
- package/dist/runtime/core/eval/mixins/expressions.d.ts +0 -1
- package/dist/runtime/core/eval/mixins/expressions.js +35 -28
- 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 +6 -10
- package/dist/runtime/core/eval/mixins/types.d.ts +2 -1
- package/dist/runtime/core/eval/mixins/types.js +231 -261
- 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 +16 -15
- 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 +4 -5
- package/dist/runtime/core/field-descriptor.js +2 -2
- package/dist/runtime/core/introspection.d.ts +0 -1
- package/dist/runtime/core/introspection.js +6 -7
- package/dist/runtime/core/markers.d.ts +12 -0
- package/dist/runtime/core/markers.js +7 -0
- 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/type-registrations.d.ts +136 -0
- package/dist/runtime/core/type-registrations.js +749 -0
- package/dist/runtime/core/type-structures.d.ts +128 -0
- package/dist/runtime/core/type-structures.js +12 -0
- package/dist/runtime/core/types.d.ts +15 -4
- package/dist/runtime/core/types.js +0 -1
- package/dist/runtime/core/values.d.ts +88 -146
- package/dist/runtime/core/values.js +466 -470
- package/dist/runtime/ext/builtins.d.ts +0 -1
- package/dist/runtime/ext/builtins.js +125 -80
- package/dist/runtime/ext/extensions.d.ts +30 -125
- package/dist/runtime/ext/extensions.js +0 -94
- package/dist/runtime/ext/test-context.d.ts +28 -0
- package/dist/runtime/ext/test-context.js +154 -0
- package/dist/runtime/index.d.ts +22 -9
- package/dist/runtime/index.js +18 -5
- package/dist/signature-parser.d.ts +2 -3
- package/dist/signature-parser.js +19 -17
- 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
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* Public API for host applications.
|
|
6
6
|
*/
|
|
7
7
|
import { RuntimeError } from '../../types.js';
|
|
8
|
-
import { BUILTIN_FUNCTIONS
|
|
8
|
+
import { BUILTIN_FUNCTIONS } from '../ext/builtins.js';
|
|
9
|
+
import { BUILT_IN_TYPES } from './type-registrations.js';
|
|
9
10
|
import { bindDictCallables } from './types.js';
|
|
10
11
|
import { inferType } from './values.js';
|
|
11
12
|
import { callable, validateDefaultValueType, } from './callable.js';
|
|
@@ -14,72 +15,26 @@ import { callable, validateDefaultValueType, } from './callable.js';
|
|
|
14
15
|
// chain: pipe form sends 1 arg when signature declares 2 (pipeValue is the first).
|
|
15
16
|
const UNTYPED_BUILTINS = new Set(['log', 'chain']);
|
|
16
17
|
// Built-in methods that do their own internal arg validation with specific error
|
|
17
|
-
// messages expected by protected language tests. Generic
|
|
18
|
+
// messages expected by protected language tests. Generic marshalArgs
|
|
18
19
|
// must not fire before the method body's own check.
|
|
19
20
|
export const UNVALIDATED_METHOD_PARAMS = new Set(['has', 'has_any', 'has_all']);
|
|
20
|
-
// Built-in methods that perform their own receiver type checking with specific
|
|
21
|
-
// error messages. Generic RILL-R003 must not fire before the method body runs.
|
|
22
|
-
// Mirrors the old flat-structure convention of receiverTypes: [].
|
|
23
|
-
export const UNVALIDATED_METHOD_RECEIVERS = new Set([
|
|
24
|
-
'head',
|
|
25
|
-
'tail',
|
|
26
|
-
'first',
|
|
27
|
-
'at',
|
|
28
|
-
'eq',
|
|
29
|
-
'ne',
|
|
30
|
-
'keys',
|
|
31
|
-
'values',
|
|
32
|
-
'entries',
|
|
33
|
-
'has',
|
|
34
|
-
'has_any',
|
|
35
|
-
'has_all',
|
|
36
|
-
'dimensions',
|
|
37
|
-
'model',
|
|
38
|
-
'similarity',
|
|
39
|
-
'dot',
|
|
40
|
-
'distance',
|
|
41
|
-
'norm',
|
|
42
|
-
'normalize',
|
|
43
|
-
]);
|
|
44
21
|
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* for the same type trigger an Error (EC-6).
|
|
49
|
-
*
|
|
50
|
-
* Re-exported from the public barrel index for host integration use.
|
|
22
|
+
* Derive the set of method names that handle their own receiver type checking.
|
|
23
|
+
* Collects names from methods where skipReceiverValidation is true.
|
|
24
|
+
* Methods without the flag default to standard RILL-R003 receiver validation.
|
|
51
25
|
*/
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const existing = result.get(typeName) ?? {};
|
|
59
|
-
const dict = { ...existing };
|
|
60
|
-
for (const [name, fn] of Object.entries(methods)) {
|
|
61
|
-
if (seen.has(name)) {
|
|
62
|
-
throw new Error(`Duplicate method '${name}' on type '${typeName}'`);
|
|
26
|
+
function deriveUnvalidatedMethodReceivers(registrations) {
|
|
27
|
+
const bypass = new Set();
|
|
28
|
+
for (const reg of registrations) {
|
|
29
|
+
for (const [name, method] of Object.entries(reg.methods)) {
|
|
30
|
+
if (method.skipReceiverValidation) {
|
|
31
|
+
bypass.add(name);
|
|
63
32
|
}
|
|
64
|
-
seen.add(name);
|
|
65
|
-
const appCallable = {
|
|
66
|
-
__type: 'callable',
|
|
67
|
-
kind: 'application',
|
|
68
|
-
params: fn.params,
|
|
69
|
-
returnType: fn.returnType,
|
|
70
|
-
annotations: fn.annotations ?? {},
|
|
71
|
-
isProperty: false,
|
|
72
|
-
fn: fn.fn,
|
|
73
|
-
};
|
|
74
|
-
dict[name] = appCallable;
|
|
75
33
|
}
|
|
76
|
-
result.set(typeName, Object.freeze(dict));
|
|
77
34
|
}
|
|
78
|
-
return
|
|
35
|
+
return Object.freeze(bypass);
|
|
79
36
|
}
|
|
80
37
|
const BUILTIN_FN_CACHE = new Map();
|
|
81
|
-
const BUILTIN_METHOD_PARAMS_CACHE = new Map();
|
|
82
|
-
const BUILTIN_METHOD_RECEIVER_TYPES_CACHE = new Map();
|
|
83
38
|
function initBuiltinCaches() {
|
|
84
39
|
for (const [name, entry] of Object.entries(BUILTIN_FUNCTIONS)) {
|
|
85
40
|
if (UNTYPED_BUILTINS.has(name)) {
|
|
@@ -94,21 +49,6 @@ function initBuiltinCaches() {
|
|
|
94
49
|
};
|
|
95
50
|
BUILTIN_FN_CACHE.set(name, { appCallable: typedCallable });
|
|
96
51
|
}
|
|
97
|
-
for (const [typeName, methods] of Object.entries(BUILTIN_METHODS)) {
|
|
98
|
-
for (const [name, impl] of Object.entries(methods)) {
|
|
99
|
-
// Accumulate receiver types across all type groups for this method name.
|
|
100
|
-
// Skip methods that perform their own receiver type checking.
|
|
101
|
-
if (!UNVALIDATED_METHOD_RECEIVERS.has(name)) {
|
|
102
|
-
const existing = BUILTIN_METHOD_RECEIVER_TYPES_CACHE.get(name);
|
|
103
|
-
BUILTIN_METHOD_RECEIVER_TYPES_CACHE.set(name, existing !== undefined ? [...existing, typeName] : [typeName]);
|
|
104
|
-
}
|
|
105
|
-
if (!UNVALIDATED_METHOD_PARAMS.has(name)) {
|
|
106
|
-
if (impl.params.length > 0) {
|
|
107
|
-
BUILTIN_METHOD_PARAMS_CACHE.set(name, impl.params);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
52
|
}
|
|
113
53
|
// Initialise once at module load.
|
|
114
54
|
initBuiltinCaches();
|
|
@@ -194,15 +134,74 @@ export function createRuntimeContext(options = {}) {
|
|
|
194
134
|
const resolverConfigs = new Map(options.configurations?.resolvers
|
|
195
135
|
? Object.entries(options.configurations.resolvers)
|
|
196
136
|
: []);
|
|
197
|
-
//
|
|
198
|
-
|
|
199
|
-
const
|
|
137
|
+
// EC-1: Validate no duplicate type names in registrations.
|
|
138
|
+
const seenTypeNames = new Set();
|
|
139
|
+
for (const reg of BUILT_IN_TYPES) {
|
|
140
|
+
if (seenTypeNames.has(reg.name)) {
|
|
141
|
+
throw new Error(`Duplicate type registration '${reg.name}'`);
|
|
142
|
+
}
|
|
143
|
+
seenTypeNames.add(reg.name);
|
|
144
|
+
}
|
|
145
|
+
// EC-2: Validate every registration has protocol.format.
|
|
146
|
+
for (const reg of BUILT_IN_TYPES) {
|
|
147
|
+
if (!reg.protocol.format) {
|
|
148
|
+
throw new Error(`Type '${reg.name}' missing required format protocol`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
// Derive typeNames from registrations (replaces VALID_TYPE_NAMES in context).
|
|
152
|
+
const typeNames = Object.freeze(BUILT_IN_TYPES.map((r) => r.name));
|
|
153
|
+
// Derive leafTypes from registrations where isLeaf === true, plus 'any'
|
|
154
|
+
// which has no registration but rejects type arguments (AC-4).
|
|
155
|
+
const leafTypes = Object.freeze(new Set([
|
|
156
|
+
...BUILT_IN_TYPES.filter((r) => r.isLeaf).map((r) => r.name),
|
|
157
|
+
'any',
|
|
158
|
+
]));
|
|
159
|
+
// Derive method dicts from registration.methods (absorbs buildTypeMethodDicts
|
|
160
|
+
// logic). Validates EC-6: duplicate method on same type.
|
|
161
|
+
const methodRegistry = new Map();
|
|
162
|
+
const typeMethodDicts = new Map();
|
|
163
|
+
for (const reg of BUILT_IN_TYPES) {
|
|
164
|
+
const methods = reg.methods;
|
|
165
|
+
if (!methods || Object.keys(methods).length === 0)
|
|
166
|
+
continue;
|
|
167
|
+
const seen = methodRegistry.get(reg.name) ?? new Set();
|
|
168
|
+
methodRegistry.set(reg.name, seen);
|
|
169
|
+
const existing = typeMethodDicts.get(reg.name) ?? {};
|
|
170
|
+
const dict = { ...existing };
|
|
171
|
+
for (const [name, fn] of Object.entries(methods)) {
|
|
172
|
+
if (seen.has(name)) {
|
|
173
|
+
throw new Error(`Duplicate method '${name}' on type '${reg.name}'`);
|
|
174
|
+
}
|
|
175
|
+
seen.add(name);
|
|
176
|
+
const appCallable = {
|
|
177
|
+
__type: 'callable',
|
|
178
|
+
kind: 'application',
|
|
179
|
+
params: fn.params,
|
|
180
|
+
returnType: fn.returnType,
|
|
181
|
+
annotations: fn.annotations ?? {},
|
|
182
|
+
isProperty: false,
|
|
183
|
+
fn: fn.fn,
|
|
184
|
+
};
|
|
185
|
+
dict[name] = appCallable;
|
|
186
|
+
}
|
|
187
|
+
typeMethodDicts.set(reg.name, Object.freeze(dict));
|
|
188
|
+
}
|
|
189
|
+
// Derive bypass set from registrations: method names that handle their own
|
|
190
|
+
// receiver type checking. Generic RILL-R003 must not fire before the method body.
|
|
191
|
+
const unvalidatedMethodReceivers = deriveUnvalidatedMethodReceivers(BUILT_IN_TYPES);
|
|
192
|
+
// BC-5: Freeze all derived collections after creation.
|
|
193
|
+
Object.freeze(typeNames);
|
|
194
|
+
Object.freeze(typeMethodDicts);
|
|
195
|
+
// Suppress unused-variable warning for typeNames (consumed in later phases).
|
|
196
|
+
void typeNames;
|
|
200
197
|
return {
|
|
201
198
|
parent: undefined,
|
|
202
199
|
variables,
|
|
203
200
|
variableTypes,
|
|
204
201
|
functions,
|
|
205
202
|
typeMethodDicts,
|
|
203
|
+
leafTypes,
|
|
204
|
+
unvalidatedMethodReceivers,
|
|
206
205
|
callbacks: { ...defaultCallbacks, ...options.callbacks },
|
|
207
206
|
observability: options.observability ?? {},
|
|
208
207
|
pipeValue: null,
|
|
@@ -232,6 +231,8 @@ export function createChildContext(parent, overrides) {
|
|
|
232
231
|
variableTypes: new Map(),
|
|
233
232
|
functions: parent.functions,
|
|
234
233
|
typeMethodDicts: parent.typeMethodDicts,
|
|
234
|
+
leafTypes: parent.leafTypes,
|
|
235
|
+
unvalidatedMethodReceivers: parent.unvalidatedMethodReceivers,
|
|
235
236
|
callbacks: parent.callbacks,
|
|
236
237
|
observability: parent.observability,
|
|
237
238
|
pipeValue: parent.pipeValue,
|
|
@@ -319,4 +320,3 @@ export function popCallFrame(ctx) {
|
|
|
319
320
|
ctx.callStack.pop();
|
|
320
321
|
}
|
|
321
322
|
}
|
|
322
|
-
//# sourceMappingURL=context.js.map
|
|
@@ -544,7 +544,7 @@ function typeRefStaticEquals(a, b) {
|
|
|
544
544
|
return typeRefArgListEquals(a.args, b.args);
|
|
545
545
|
}
|
|
546
546
|
/**
|
|
547
|
-
* Compare two optional
|
|
547
|
+
* Compare two optional FieldArg arrays for structural equality.
|
|
548
548
|
*/
|
|
549
549
|
function typeRefArgListEquals(a, b) {
|
|
550
550
|
const aArgs = a ?? [];
|
|
@@ -556,7 +556,9 @@ function typeRefArgListEquals(a, b) {
|
|
|
556
556
|
const bArg = bArgs[i];
|
|
557
557
|
if (aArg.name !== bArg.name)
|
|
558
558
|
return false;
|
|
559
|
-
if (!typeRefEquals(aArg.
|
|
559
|
+
if (!typeRefEquals(aArg.value, bArg.value))
|
|
560
|
+
return false;
|
|
561
|
+
if (!literalNodeEquals(aArg.defaultValue, bArg.defaultValue))
|
|
560
562
|
return false;
|
|
561
563
|
}
|
|
562
564
|
return true;
|
|
@@ -578,4 +580,34 @@ function typeRefEquals(a, b) {
|
|
|
578
580
|
}
|
|
579
581
|
return false;
|
|
580
582
|
}
|
|
581
|
-
|
|
583
|
+
/**
|
|
584
|
+
* Compare two optional LiteralNode values for structural equality.
|
|
585
|
+
* Both-undefined returns true. One-undefined returns false.
|
|
586
|
+
* Complex nodes (ListLiteral, Dict, Closure) return false defensively.
|
|
587
|
+
*/
|
|
588
|
+
function literalNodeEquals(a, b) {
|
|
589
|
+
if (a === undefined && b === undefined)
|
|
590
|
+
return true;
|
|
591
|
+
if (a === undefined || b === undefined)
|
|
592
|
+
return false;
|
|
593
|
+
if (a.type !== b.type)
|
|
594
|
+
return false;
|
|
595
|
+
switch (a.type) {
|
|
596
|
+
case 'NumberLiteral':
|
|
597
|
+
return a.value === b.value;
|
|
598
|
+
case 'BoolLiteral':
|
|
599
|
+
return a.value === b.value;
|
|
600
|
+
case 'StringLiteral': {
|
|
601
|
+
const bStr = b;
|
|
602
|
+
if (a.parts.length !== 1 || bStr.parts.length !== 1)
|
|
603
|
+
return false;
|
|
604
|
+
return a.parts[0] === bStr.parts[0];
|
|
605
|
+
}
|
|
606
|
+
case 'ListLiteral':
|
|
607
|
+
case 'Dict':
|
|
608
|
+
case 'Closure':
|
|
609
|
+
return false;
|
|
610
|
+
default:
|
|
611
|
+
return false;
|
|
612
|
+
}
|
|
613
|
+
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import type { AnnotatedStatementNode, ASTNode, CaptureNode, ExpressionNode, RillTypeName, SourceLocation, StatementNode } from '../../../types.js';
|
|
10
10
|
import type { RillCallable } from '../callable.js';
|
|
11
11
|
import type { RuntimeContext } from '../types.js';
|
|
12
|
-
import type { RillValue,
|
|
12
|
+
import type { RillValue, TypeStructure } from '../values.js';
|
|
13
13
|
/**
|
|
14
14
|
* Capture information returned by handleCapture.
|
|
15
15
|
*/
|
|
@@ -39,7 +39,7 @@ export declare function handleCapture(capture: CaptureNode | null, value: RillVa
|
|
|
39
39
|
* Assert that a value is of the expected type.
|
|
40
40
|
* Returns the value unchanged if assertion passes, throws on mismatch.
|
|
41
41
|
*/
|
|
42
|
-
export declare function assertType(value: RillValue, expected: RillTypeName |
|
|
42
|
+
export declare function assertType(value: RillValue, expected: RillTypeName | TypeStructure, location?: SourceLocation): RillValue;
|
|
43
43
|
/**
|
|
44
44
|
* Evaluate an expression and return its value.
|
|
45
45
|
* Main entry point for expression evaluation.
|
|
@@ -69,4 +69,3 @@ export declare function getAnnotation(ctx: RuntimeContext, key: string): RillVal
|
|
|
69
69
|
* @param location - Optional call site location for error reporting
|
|
70
70
|
*/
|
|
71
71
|
export declare function invokeCallable(callable: RillCallable, args: RillValue[], ctx: RuntimeContext, location?: SourceLocation): Promise<RillValue>;
|
|
72
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -70,6 +70,17 @@ export function assertType(value, expected, location) {
|
|
|
70
70
|
resolverConfigs: new Map(),
|
|
71
71
|
resolvingSchemes: new Set(),
|
|
72
72
|
typeMethodDicts: new Map(),
|
|
73
|
+
leafTypes: new Set([
|
|
74
|
+
'string',
|
|
75
|
+
'number',
|
|
76
|
+
'bool',
|
|
77
|
+
'vector',
|
|
78
|
+
'type',
|
|
79
|
+
'any',
|
|
80
|
+
'closure',
|
|
81
|
+
'field_descriptor',
|
|
82
|
+
]),
|
|
83
|
+
unvalidatedMethodReceivers: new Set(),
|
|
73
84
|
};
|
|
74
85
|
const evaluator = getEvaluator(minimalContext);
|
|
75
86
|
return evaluator.assertType(value, expected, location);
|
|
@@ -117,4 +128,3 @@ export async function invokeCallable(callable, args, ctx, location) {
|
|
|
117
128
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
118
129
|
return evaluator.invokeCallable(callable, args, location);
|
|
119
130
|
}
|
|
120
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -149,4 +149,3 @@ function createAnnotationsMixin(Base) {
|
|
|
149
149
|
// TypeScript can't generate declarations for functions returning classes with protected members
|
|
150
150
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
151
151
|
export const AnnotationsMixin = createAnnotationsMixin;
|
|
152
|
-
//# sourceMappingURL=annotations.js.map
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
* @internal
|
|
43
43
|
*/
|
|
44
44
|
import { RillError, RuntimeError } from '../../../../types.js';
|
|
45
|
-
import { isCallable, isScriptCallable, isApplicationCallable, isDict,
|
|
46
|
-
import { getVariable, pushCallFrame, popCallFrame, UNVALIDATED_METHOD_PARAMS,
|
|
47
|
-
import { inferType, isTypeValue, isTuple, isOrdered,
|
|
45
|
+
import { isCallable, isScriptCallable, isApplicationCallable, isDict, marshalArgs, } from '../../callable.js';
|
|
46
|
+
import { getVariable, pushCallFrame, popCallFrame, UNVALIDATED_METHOD_PARAMS, } from '../../context.js';
|
|
47
|
+
import { inferType, isTypeValue, isTuple, isOrdered, paramToFieldDef, inferStructure, structureMatches, formatStructure, anyTypeValue, structureToTypeValue, } 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) {
|
|
@@ -207,8 +215,8 @@ function createClosuresMixin(Base) {
|
|
|
207
215
|
validateParamType(param, value, callLocation) {
|
|
208
216
|
if (param.type === undefined)
|
|
209
217
|
return;
|
|
210
|
-
if (!
|
|
211
|
-
const expectedType =
|
|
218
|
+
if (!structureMatches(value, param.type)) {
|
|
219
|
+
const expectedType = formatStructure(param.type);
|
|
212
220
|
const actualType = inferType(value);
|
|
213
221
|
throw new RuntimeError('RILL-R001', `Parameter type mismatch: ${param.name} expects ${expectedType}, got ${actualType}`, callLocation, { paramName: param.name, expectedType, actualType });
|
|
214
222
|
}
|
|
@@ -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' &&
|
|
@@ -541,13 +541,13 @@ function createClosuresMixin(Base) {
|
|
|
541
541
|
throw new RuntimeError('RILL-R003', `Method .${node.name} not available on callable (invoke with -> $() first)`, this.getNodeLocation(node), { methodName: node.name, receiverType: 'callable' });
|
|
542
542
|
}
|
|
543
543
|
// IR-3: .name on type values returns the typeName string (method path)
|
|
544
|
-
// IR-4: .signature on type values returns
|
|
544
|
+
// IR-4: .signature on type values returns formatStructure(structure)
|
|
545
545
|
if (isTypeValue(receiver)) {
|
|
546
546
|
if (node.name === 'name') {
|
|
547
547
|
return receiver.typeName;
|
|
548
548
|
}
|
|
549
549
|
if (node.name === 'signature') {
|
|
550
|
-
return
|
|
550
|
+
return formatStructure(receiver.structure);
|
|
551
551
|
}
|
|
552
552
|
}
|
|
553
553
|
const args = await this.evaluateArgs(node.args);
|
|
@@ -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) {
|
|
@@ -601,10 +617,10 @@ function createClosuresMixin(Base) {
|
|
|
601
617
|
throw new RuntimeError('RILL-R009', `Property '${node.name}' not found on type value (available: name, signature)`, this.getNodeLocation(node), { property: node.name, type: 'type value' });
|
|
602
618
|
}
|
|
603
619
|
// RILL-R003: method exists on other types but not this receiver's type.
|
|
604
|
-
// Methods in
|
|
620
|
+
// Methods in unvalidatedMethodReceivers handle their own receiver validation
|
|
605
621
|
// with specific error messages; skip generic RILL-R003 for them and let the
|
|
606
622
|
// method body run its own check (they exist in at least one type dict).
|
|
607
|
-
if (!
|
|
623
|
+
if (!this.ctx.unvalidatedMethodReceivers.has(node.name)) {
|
|
608
624
|
const supportedTypes = [];
|
|
609
625
|
for (const [dictType, dict] of this.ctx.typeMethodDicts) {
|
|
610
626
|
if (dict[node.name] !== undefined) {
|
|
@@ -616,14 +632,25 @@ function createClosuresMixin(Base) {
|
|
|
616
632
|
}
|
|
617
633
|
}
|
|
618
634
|
else {
|
|
619
|
-
//
|
|
635
|
+
// unvalidatedMethodReceivers: dispatch to the method in ANY type dict so the
|
|
620
636
|
// method body can run its own custom receiver validation and error message.
|
|
621
637
|
for (const [, dict] of this.ctx.typeMethodDicts) {
|
|
622
638
|
const fallbackMethod = dict[node.name];
|
|
623
639
|
if (fallbackMethod !== undefined &&
|
|
624
640
|
isApplicationCallable(fallbackMethod)) {
|
|
625
641
|
try {
|
|
626
|
-
|
|
642
|
+
// Unvalidated methods 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) {
|
|
@@ -679,7 +706,7 @@ function createClosuresMixin(Base) {
|
|
|
679
706
|
const typeValue = Object.freeze({
|
|
680
707
|
__rill_type: true,
|
|
681
708
|
typeName: inferType(value),
|
|
682
|
-
structure:
|
|
709
|
+
structure: inferStructure(value),
|
|
683
710
|
});
|
|
684
711
|
return typeValue;
|
|
685
712
|
}
|
|
@@ -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 structureToTypeValue({ kind: 'ordered', fields: [] });
|
|
705
732
|
}
|
|
706
|
-
const
|
|
707
|
-
return
|
|
733
|
+
const fields = value.params.map((param) => paramToFieldDef(param.name, param.type ?? { kind: 'any' }, param.defaultValue));
|
|
734
|
+
return structureToTypeValue({ kind: '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
|
/**
|
|
@@ -871,7 +894,7 @@ function createClosuresMixin(Base) {
|
|
|
871
894
|
const paramEntry = {};
|
|
872
895
|
// Add type field if param has type annotation
|
|
873
896
|
if (param.type !== undefined) {
|
|
874
|
-
paramEntry['type'] =
|
|
897
|
+
paramEntry['type'] = formatStructure(param.type);
|
|
875
898
|
}
|
|
876
899
|
// Add __annotations field if param has parameter-level annotations
|
|
877
900
|
if (Object.keys(param.annotations).length > 0) {
|
|
@@ -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
|