Compile and dispatch authoritative acceptance hooks with target-specific package roots
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -58,92 +58,93 @@ EDGE=57
|
||||
PROJECTION=58
|
||||
WITH=59
|
||||
USING=60
|
||||
VIA=61
|
||||
MATERIALIZE=62
|
||||
IF=63
|
||||
ABSENT=64
|
||||
ON=65
|
||||
POLICY=66
|
||||
DEFAULT=67
|
||||
SOURCE=68
|
||||
REPOSITORY=69
|
||||
COMMIT=70
|
||||
REVISION=71
|
||||
SEMANTIC_MAJOR=72
|
||||
ON_DELETE=73
|
||||
RETAIN_OTHER=74
|
||||
KEYED=75
|
||||
PUBLIC_TRAVERSAL=76
|
||||
ID=77
|
||||
DOC=78
|
||||
MODE=79
|
||||
EMITS=80
|
||||
RECEIVER=81
|
||||
REQUIRES=82
|
||||
ANY=83
|
||||
GET=84
|
||||
SET=85
|
||||
WATCH=86
|
||||
START=87
|
||||
STOP=88
|
||||
READ=89
|
||||
WRITE=90
|
||||
RESOLVE=91
|
||||
CONNECT=92
|
||||
DISCONNECT=93
|
||||
CALL=94
|
||||
WATCH_START=95
|
||||
WATCH_STOP=96
|
||||
SUBSCRIBE=97
|
||||
UNSUBSCRIBE=98
|
||||
REGISTER=99
|
||||
CRDT=100
|
||||
OPTIONAL_ONE=101
|
||||
EXACTLY_ONE=102
|
||||
MANY_UNIQUE=103
|
||||
MANY=104
|
||||
ORDERED=105
|
||||
UNIT=106
|
||||
WATCH_HANDLE=107
|
||||
MESSAGE=108
|
||||
ATOM_REF=109
|
||||
INTERFACE_REF=110
|
||||
OPTIONAL=111
|
||||
LIST=112
|
||||
RECORD=113
|
||||
BOOL=114
|
||||
BYTES=115
|
||||
DOUBLE=116
|
||||
INT32=117
|
||||
INT64=118
|
||||
STRING=119
|
||||
UINT32=120
|
||||
UINT64=121
|
||||
TRUE=122
|
||||
FALSE=123
|
||||
NULL=124
|
||||
ARROW=125
|
||||
COLON=126
|
||||
SEMI=127
|
||||
COMMA=128
|
||||
DOT=129
|
||||
LBRACE=130
|
||||
RBRACE=131
|
||||
LBRACK=132
|
||||
RBRACK=133
|
||||
LPAREN=134
|
||||
RPAREN=135
|
||||
LT=136
|
||||
GT=137
|
||||
AMP=138
|
||||
EQUAL=139
|
||||
INTEGER=140
|
||||
JSON_NUMBER=141
|
||||
IDENTIFIER=142
|
||||
STRING_LITERAL=143
|
||||
LINE_COMMENT=144
|
||||
BLOCK_COMMENT=145
|
||||
WS=146
|
||||
ACCEPT=61
|
||||
VIA=62
|
||||
MATERIALIZE=63
|
||||
IF=64
|
||||
ABSENT=65
|
||||
ON=66
|
||||
POLICY=67
|
||||
DEFAULT=68
|
||||
SOURCE=69
|
||||
REPOSITORY=70
|
||||
COMMIT=71
|
||||
REVISION=72
|
||||
SEMANTIC_MAJOR=73
|
||||
ON_DELETE=74
|
||||
RETAIN_OTHER=75
|
||||
KEYED=76
|
||||
PUBLIC_TRAVERSAL=77
|
||||
ID=78
|
||||
DOC=79
|
||||
MODE=80
|
||||
EMITS=81
|
||||
RECEIVER=82
|
||||
REQUIRES=83
|
||||
ANY=84
|
||||
GET=85
|
||||
SET=86
|
||||
WATCH=87
|
||||
START=88
|
||||
STOP=89
|
||||
READ=90
|
||||
WRITE=91
|
||||
RESOLVE=92
|
||||
CONNECT=93
|
||||
DISCONNECT=94
|
||||
CALL=95
|
||||
WATCH_START=96
|
||||
WATCH_STOP=97
|
||||
SUBSCRIBE=98
|
||||
UNSUBSCRIBE=99
|
||||
REGISTER=100
|
||||
CRDT=101
|
||||
OPTIONAL_ONE=102
|
||||
EXACTLY_ONE=103
|
||||
MANY_UNIQUE=104
|
||||
MANY=105
|
||||
ORDERED=106
|
||||
UNIT=107
|
||||
WATCH_HANDLE=108
|
||||
MESSAGE=109
|
||||
ATOM_REF=110
|
||||
INTERFACE_REF=111
|
||||
OPTIONAL=112
|
||||
LIST=113
|
||||
RECORD=114
|
||||
BOOL=115
|
||||
BYTES=116
|
||||
DOUBLE=117
|
||||
INT32=118
|
||||
INT64=119
|
||||
STRING=120
|
||||
UINT32=121
|
||||
UINT64=122
|
||||
TRUE=123
|
||||
FALSE=124
|
||||
NULL=125
|
||||
ARROW=126
|
||||
COLON=127
|
||||
SEMI=128
|
||||
COMMA=129
|
||||
DOT=130
|
||||
LBRACE=131
|
||||
RBRACE=132
|
||||
LBRACK=133
|
||||
RBRACK=134
|
||||
LPAREN=135
|
||||
RPAREN=136
|
||||
LT=137
|
||||
GT=138
|
||||
AMP=139
|
||||
EQUAL=140
|
||||
INTEGER=141
|
||||
JSON_NUMBER=142
|
||||
IDENTIFIER=143
|
||||
STRING_LITERAL=144
|
||||
LINE_COMMENT=145
|
||||
BLOCK_COMMENT=146
|
||||
WS=147
|
||||
'edit'=1
|
||||
'creation'=2
|
||||
'initialize'=3
|
||||
@@ -204,82 +205,83 @@ WS=146
|
||||
'projection'=58
|
||||
'with'=59
|
||||
'using'=60
|
||||
'via'=61
|
||||
'materialize'=62
|
||||
'if'=63
|
||||
'absent'=64
|
||||
'on'=65
|
||||
'policy'=66
|
||||
'default'=67
|
||||
'source'=68
|
||||
'repository'=69
|
||||
'commit'=70
|
||||
'revision'=71
|
||||
'semantic-major'=72
|
||||
'on-delete'=73
|
||||
'retain-other'=74
|
||||
'keyed'=75
|
||||
'public-traversal'=76
|
||||
'id'=77
|
||||
'doc'=78
|
||||
'mode'=79
|
||||
'emits'=80
|
||||
'receiver'=81
|
||||
'requires'=82
|
||||
'any'=83
|
||||
'get'=84
|
||||
'set'=85
|
||||
'watch'=86
|
||||
'start'=87
|
||||
'stop'=88
|
||||
'read'=89
|
||||
'write'=90
|
||||
'resolve'=91
|
||||
'connect'=92
|
||||
'disconnect'=93
|
||||
'call'=94
|
||||
'watch-start'=95
|
||||
'watch-stop'=96
|
||||
'subscribe'=97
|
||||
'unsubscribe'=98
|
||||
'register'=99
|
||||
'crdt'=100
|
||||
'optional-one'=101
|
||||
'exactly-one'=102
|
||||
'many-unique'=103
|
||||
'many'=104
|
||||
'ordered'=105
|
||||
'unit'=106
|
||||
'watch-handle'=107
|
||||
'message'=108
|
||||
'atom-ref'=109
|
||||
'interface-ref'=110
|
||||
'optional'=111
|
||||
'list'=112
|
||||
'record'=113
|
||||
'bool'=114
|
||||
'bytes'=115
|
||||
'double'=116
|
||||
'int32'=117
|
||||
'int64'=118
|
||||
'string'=119
|
||||
'uint32'=120
|
||||
'uint64'=121
|
||||
'true'=122
|
||||
'false'=123
|
||||
'null'=124
|
||||
'->'=125
|
||||
':'=126
|
||||
';'=127
|
||||
','=128
|
||||
'.'=129
|
||||
'{'=130
|
||||
'}'=131
|
||||
'['=132
|
||||
']'=133
|
||||
'('=134
|
||||
')'=135
|
||||
'<'=136
|
||||
'>'=137
|
||||
'&'=138
|
||||
'='=139
|
||||
'accept'=61
|
||||
'via'=62
|
||||
'materialize'=63
|
||||
'if'=64
|
||||
'absent'=65
|
||||
'on'=66
|
||||
'policy'=67
|
||||
'default'=68
|
||||
'source'=69
|
||||
'repository'=70
|
||||
'commit'=71
|
||||
'revision'=72
|
||||
'semantic-major'=73
|
||||
'on-delete'=74
|
||||
'retain-other'=75
|
||||
'keyed'=76
|
||||
'public-traversal'=77
|
||||
'id'=78
|
||||
'doc'=79
|
||||
'mode'=80
|
||||
'emits'=81
|
||||
'receiver'=82
|
||||
'requires'=83
|
||||
'any'=84
|
||||
'get'=85
|
||||
'set'=86
|
||||
'watch'=87
|
||||
'start'=88
|
||||
'stop'=89
|
||||
'read'=90
|
||||
'write'=91
|
||||
'resolve'=92
|
||||
'connect'=93
|
||||
'disconnect'=94
|
||||
'call'=95
|
||||
'watch-start'=96
|
||||
'watch-stop'=97
|
||||
'subscribe'=98
|
||||
'unsubscribe'=99
|
||||
'register'=100
|
||||
'crdt'=101
|
||||
'optional-one'=102
|
||||
'exactly-one'=103
|
||||
'many-unique'=104
|
||||
'many'=105
|
||||
'ordered'=106
|
||||
'unit'=107
|
||||
'watch-handle'=108
|
||||
'message'=109
|
||||
'atom-ref'=110
|
||||
'interface-ref'=111
|
||||
'optional'=112
|
||||
'list'=113
|
||||
'record'=114
|
||||
'bool'=115
|
||||
'bytes'=116
|
||||
'double'=117
|
||||
'int32'=118
|
||||
'int64'=119
|
||||
'string'=120
|
||||
'uint32'=121
|
||||
'uint64'=122
|
||||
'true'=123
|
||||
'false'=124
|
||||
'null'=125
|
||||
'->'=126
|
||||
':'=127
|
||||
';'=128
|
||||
','=129
|
||||
'.'=130
|
||||
'{'=131
|
||||
'}'=132
|
||||
'['=133
|
||||
']'=134
|
||||
'('=135
|
||||
')'=136
|
||||
'<'=137
|
||||
'>'=138
|
||||
'&'=139
|
||||
'='=140
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -58,92 +58,93 @@ EDGE=57
|
||||
PROJECTION=58
|
||||
WITH=59
|
||||
USING=60
|
||||
VIA=61
|
||||
MATERIALIZE=62
|
||||
IF=63
|
||||
ABSENT=64
|
||||
ON=65
|
||||
POLICY=66
|
||||
DEFAULT=67
|
||||
SOURCE=68
|
||||
REPOSITORY=69
|
||||
COMMIT=70
|
||||
REVISION=71
|
||||
SEMANTIC_MAJOR=72
|
||||
ON_DELETE=73
|
||||
RETAIN_OTHER=74
|
||||
KEYED=75
|
||||
PUBLIC_TRAVERSAL=76
|
||||
ID=77
|
||||
DOC=78
|
||||
MODE=79
|
||||
EMITS=80
|
||||
RECEIVER=81
|
||||
REQUIRES=82
|
||||
ANY=83
|
||||
GET=84
|
||||
SET=85
|
||||
WATCH=86
|
||||
START=87
|
||||
STOP=88
|
||||
READ=89
|
||||
WRITE=90
|
||||
RESOLVE=91
|
||||
CONNECT=92
|
||||
DISCONNECT=93
|
||||
CALL=94
|
||||
WATCH_START=95
|
||||
WATCH_STOP=96
|
||||
SUBSCRIBE=97
|
||||
UNSUBSCRIBE=98
|
||||
REGISTER=99
|
||||
CRDT=100
|
||||
OPTIONAL_ONE=101
|
||||
EXACTLY_ONE=102
|
||||
MANY_UNIQUE=103
|
||||
MANY=104
|
||||
ORDERED=105
|
||||
UNIT=106
|
||||
WATCH_HANDLE=107
|
||||
MESSAGE=108
|
||||
ATOM_REF=109
|
||||
INTERFACE_REF=110
|
||||
OPTIONAL=111
|
||||
LIST=112
|
||||
RECORD=113
|
||||
BOOL=114
|
||||
BYTES=115
|
||||
DOUBLE=116
|
||||
INT32=117
|
||||
INT64=118
|
||||
STRING=119
|
||||
UINT32=120
|
||||
UINT64=121
|
||||
TRUE=122
|
||||
FALSE=123
|
||||
NULL=124
|
||||
ARROW=125
|
||||
COLON=126
|
||||
SEMI=127
|
||||
COMMA=128
|
||||
DOT=129
|
||||
LBRACE=130
|
||||
RBRACE=131
|
||||
LBRACK=132
|
||||
RBRACK=133
|
||||
LPAREN=134
|
||||
RPAREN=135
|
||||
LT=136
|
||||
GT=137
|
||||
AMP=138
|
||||
EQUAL=139
|
||||
INTEGER=140
|
||||
JSON_NUMBER=141
|
||||
IDENTIFIER=142
|
||||
STRING_LITERAL=143
|
||||
LINE_COMMENT=144
|
||||
BLOCK_COMMENT=145
|
||||
WS=146
|
||||
ACCEPT=61
|
||||
VIA=62
|
||||
MATERIALIZE=63
|
||||
IF=64
|
||||
ABSENT=65
|
||||
ON=66
|
||||
POLICY=67
|
||||
DEFAULT=68
|
||||
SOURCE=69
|
||||
REPOSITORY=70
|
||||
COMMIT=71
|
||||
REVISION=72
|
||||
SEMANTIC_MAJOR=73
|
||||
ON_DELETE=74
|
||||
RETAIN_OTHER=75
|
||||
KEYED=76
|
||||
PUBLIC_TRAVERSAL=77
|
||||
ID=78
|
||||
DOC=79
|
||||
MODE=80
|
||||
EMITS=81
|
||||
RECEIVER=82
|
||||
REQUIRES=83
|
||||
ANY=84
|
||||
GET=85
|
||||
SET=86
|
||||
WATCH=87
|
||||
START=88
|
||||
STOP=89
|
||||
READ=90
|
||||
WRITE=91
|
||||
RESOLVE=92
|
||||
CONNECT=93
|
||||
DISCONNECT=94
|
||||
CALL=95
|
||||
WATCH_START=96
|
||||
WATCH_STOP=97
|
||||
SUBSCRIBE=98
|
||||
UNSUBSCRIBE=99
|
||||
REGISTER=100
|
||||
CRDT=101
|
||||
OPTIONAL_ONE=102
|
||||
EXACTLY_ONE=103
|
||||
MANY_UNIQUE=104
|
||||
MANY=105
|
||||
ORDERED=106
|
||||
UNIT=107
|
||||
WATCH_HANDLE=108
|
||||
MESSAGE=109
|
||||
ATOM_REF=110
|
||||
INTERFACE_REF=111
|
||||
OPTIONAL=112
|
||||
LIST=113
|
||||
RECORD=114
|
||||
BOOL=115
|
||||
BYTES=116
|
||||
DOUBLE=117
|
||||
INT32=118
|
||||
INT64=119
|
||||
STRING=120
|
||||
UINT32=121
|
||||
UINT64=122
|
||||
TRUE=123
|
||||
FALSE=124
|
||||
NULL=125
|
||||
ARROW=126
|
||||
COLON=127
|
||||
SEMI=128
|
||||
COMMA=129
|
||||
DOT=130
|
||||
LBRACE=131
|
||||
RBRACE=132
|
||||
LBRACK=133
|
||||
RBRACK=134
|
||||
LPAREN=135
|
||||
RPAREN=136
|
||||
LT=137
|
||||
GT=138
|
||||
AMP=139
|
||||
EQUAL=140
|
||||
INTEGER=141
|
||||
JSON_NUMBER=142
|
||||
IDENTIFIER=143
|
||||
STRING_LITERAL=144
|
||||
LINE_COMMENT=145
|
||||
BLOCK_COMMENT=146
|
||||
WS=147
|
||||
'edit'=1
|
||||
'creation'=2
|
||||
'initialize'=3
|
||||
@@ -204,82 +205,83 @@ WS=146
|
||||
'projection'=58
|
||||
'with'=59
|
||||
'using'=60
|
||||
'via'=61
|
||||
'materialize'=62
|
||||
'if'=63
|
||||
'absent'=64
|
||||
'on'=65
|
||||
'policy'=66
|
||||
'default'=67
|
||||
'source'=68
|
||||
'repository'=69
|
||||
'commit'=70
|
||||
'revision'=71
|
||||
'semantic-major'=72
|
||||
'on-delete'=73
|
||||
'retain-other'=74
|
||||
'keyed'=75
|
||||
'public-traversal'=76
|
||||
'id'=77
|
||||
'doc'=78
|
||||
'mode'=79
|
||||
'emits'=80
|
||||
'receiver'=81
|
||||
'requires'=82
|
||||
'any'=83
|
||||
'get'=84
|
||||
'set'=85
|
||||
'watch'=86
|
||||
'start'=87
|
||||
'stop'=88
|
||||
'read'=89
|
||||
'write'=90
|
||||
'resolve'=91
|
||||
'connect'=92
|
||||
'disconnect'=93
|
||||
'call'=94
|
||||
'watch-start'=95
|
||||
'watch-stop'=96
|
||||
'subscribe'=97
|
||||
'unsubscribe'=98
|
||||
'register'=99
|
||||
'crdt'=100
|
||||
'optional-one'=101
|
||||
'exactly-one'=102
|
||||
'many-unique'=103
|
||||
'many'=104
|
||||
'ordered'=105
|
||||
'unit'=106
|
||||
'watch-handle'=107
|
||||
'message'=108
|
||||
'atom-ref'=109
|
||||
'interface-ref'=110
|
||||
'optional'=111
|
||||
'list'=112
|
||||
'record'=113
|
||||
'bool'=114
|
||||
'bytes'=115
|
||||
'double'=116
|
||||
'int32'=117
|
||||
'int64'=118
|
||||
'string'=119
|
||||
'uint32'=120
|
||||
'uint64'=121
|
||||
'true'=122
|
||||
'false'=123
|
||||
'null'=124
|
||||
'->'=125
|
||||
':'=126
|
||||
';'=127
|
||||
','=128
|
||||
'.'=129
|
||||
'{'=130
|
||||
'}'=131
|
||||
'['=132
|
||||
']'=133
|
||||
'('=134
|
||||
')'=135
|
||||
'<'=136
|
||||
'>'=137
|
||||
'&'=138
|
||||
'='=139
|
||||
'accept'=61
|
||||
'via'=62
|
||||
'materialize'=63
|
||||
'if'=64
|
||||
'absent'=65
|
||||
'on'=66
|
||||
'policy'=67
|
||||
'default'=68
|
||||
'source'=69
|
||||
'repository'=70
|
||||
'commit'=71
|
||||
'revision'=72
|
||||
'semantic-major'=73
|
||||
'on-delete'=74
|
||||
'retain-other'=75
|
||||
'keyed'=76
|
||||
'public-traversal'=77
|
||||
'id'=78
|
||||
'doc'=79
|
||||
'mode'=80
|
||||
'emits'=81
|
||||
'receiver'=82
|
||||
'requires'=83
|
||||
'any'=84
|
||||
'get'=85
|
||||
'set'=86
|
||||
'watch'=87
|
||||
'start'=88
|
||||
'stop'=89
|
||||
'read'=90
|
||||
'write'=91
|
||||
'resolve'=92
|
||||
'connect'=93
|
||||
'disconnect'=94
|
||||
'call'=95
|
||||
'watch-start'=96
|
||||
'watch-stop'=97
|
||||
'subscribe'=98
|
||||
'unsubscribe'=99
|
||||
'register'=100
|
||||
'crdt'=101
|
||||
'optional-one'=102
|
||||
'exactly-one'=103
|
||||
'many-unique'=104
|
||||
'many'=105
|
||||
'ordered'=106
|
||||
'unit'=107
|
||||
'watch-handle'=108
|
||||
'message'=109
|
||||
'atom-ref'=110
|
||||
'interface-ref'=111
|
||||
'optional'=112
|
||||
'list'=113
|
||||
'record'=114
|
||||
'bool'=115
|
||||
'bytes'=116
|
||||
'double'=117
|
||||
'int32'=118
|
||||
'int64'=119
|
||||
'string'=120
|
||||
'uint32'=121
|
||||
'uint64'=122
|
||||
'true'=123
|
||||
'false'=124
|
||||
'null'=125
|
||||
'->'=126
|
||||
':'=127
|
||||
';'=128
|
||||
','=129
|
||||
'.'=130
|
||||
'{'=131
|
||||
'}'=132
|
||||
'['=133
|
||||
']'=134
|
||||
'('=135
|
||||
')'=136
|
||||
'<'=137
|
||||
'>'=138
|
||||
'&'=139
|
||||
'='=140
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -34,6 +34,7 @@ import { PackageQuerySpecializationContext } from "./QuixosCapabilityParser.js";
|
||||
import { QueryClauseContext } from "./QuixosCapabilityParser.js";
|
||||
import { PackageOperationExportContext } from "./QuixosCapabilityParser.js";
|
||||
import { PackageFunctionExportContext } from "./QuixosCapabilityParser.js";
|
||||
import { AcceptanceClauseContext } from "./QuixosCapabilityParser.js";
|
||||
import { ExecutionClauseContext } from "./QuixosCapabilityParser.js";
|
||||
import { SelectedOperationsContext } from "./QuixosCapabilityParser.js";
|
||||
import { PackageConstructorExportContext } from "./QuixosCapabilityParser.js";
|
||||
@@ -62,6 +63,7 @@ import { OperationBindingDeclContext } from "./QuixosCapabilityParser.js";
|
||||
import { MemberOperationRefContext } from "./QuixosCapabilityParser.js";
|
||||
import { OperationNameContext } from "./QuixosCapabilityParser.js";
|
||||
import { OperationProviderContext } from "./QuixosCapabilityParser.js";
|
||||
import { AcceptanceBindingContext } from "./QuixosCapabilityParser.js";
|
||||
import { StatePrimitiveContext } from "./QuixosCapabilityParser.js";
|
||||
import { EdgePrimitiveContext } from "./QuixosCapabilityParser.js";
|
||||
import { DependencyBindingBlockContext } from "./QuixosCapabilityParser.js";
|
||||
@@ -279,6 +281,12 @@ export class QuixosCapabilityVisitor<Result> extends AbstractParseTreeVisitor<Re
|
||||
* @return the visitor result
|
||||
*/
|
||||
visitPackageFunctionExport?: (ctx: PackageFunctionExportContext) => Result;
|
||||
/**
|
||||
* Visit a parse tree produced by `QuixosCapabilityParser.acceptanceClause`.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
visitAcceptanceClause?: (ctx: AcceptanceClauseContext) => Result;
|
||||
/**
|
||||
* Visit a parse tree produced by `QuixosCapabilityParser.executionClause`.
|
||||
* @param ctx the parse tree
|
||||
@@ -447,6 +455,12 @@ export class QuixosCapabilityVisitor<Result> extends AbstractParseTreeVisitor<Re
|
||||
* @return the visitor result
|
||||
*/
|
||||
visitOperationProvider?: (ctx: OperationProviderContext) => Result;
|
||||
/**
|
||||
* Visit a parse tree produced by `QuixosCapabilityParser.acceptanceBinding`.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
visitAcceptanceBinding?: (ctx: AcceptanceBindingContext) => Result;
|
||||
/**
|
||||
* Visit a parse tree produced by `QuixosCapabilityParser.statePrimitive`.
|
||||
* @param ctx the parse tree
|
||||
|
||||
@@ -1514,6 +1514,13 @@ const lowerPackage = (
|
||||
const operation = exportContext.packageOperationExport();
|
||||
const generic = operation ?? exportContext.packageFunctionExport();
|
||||
if (generic?.typeParameters()) {
|
||||
if (generic.acceptanceClause())
|
||||
loweringIssue(
|
||||
state,
|
||||
generic,
|
||||
"unsupported-generic-acceptance",
|
||||
"Acceptance hooks currently require a closed export",
|
||||
);
|
||||
genericExports.push(atGenericSource(generic, () => lowerGenericPackageExport(state, generic)));
|
||||
return [];
|
||||
}
|
||||
@@ -1535,6 +1542,22 @@ const lowerPackage = (
|
||||
state.types.self = previousSelf;
|
||||
}
|
||||
});
|
||||
// Resolve after all exports have been declared, so checks can follow bodies.
|
||||
for (const source of context.packageExport()) {
|
||||
const declaration = source.packageOperationExport() ?? source.packageFunctionExport();
|
||||
const clause = declaration?.acceptanceClause();
|
||||
if (!declaration || !clause || declaration.typeParameters()) continue;
|
||||
const entry = exports.find((entry) => entry.displayName === identifier(declaration.identifier()));
|
||||
const check = exports.find((entry) => entry.displayName === identifier(clause.identifier()));
|
||||
if (!check)
|
||||
loweringIssue(
|
||||
state,
|
||||
clause,
|
||||
"unknown-acceptance-export",
|
||||
"Acceptance hook must name a closed export in this package",
|
||||
);
|
||||
else if (entry) entry.acceptanceExportId = check.id;
|
||||
}
|
||||
for (const entry of context.packageExport()) {
|
||||
const specialized = entry.packageQuerySpecialization();
|
||||
if (!specialized) continue;
|
||||
@@ -2047,6 +2070,22 @@ const lowerConformance = (
|
||||
} else if (provider.typeArguments()) {
|
||||
throw new GenericTypeError("type-arity", exportName, "Non-generic export takes no type arguments");
|
||||
}
|
||||
const packageExport = packageSymbol?.definition?.exports.find((entry) => entry.id === exportSymbol?.exportId);
|
||||
const check = packageSymbol?.definition?.exports.find((entry) => entry.id === packageExport?.acceptanceExportId);
|
||||
const acceptanceBlock = provider.acceptanceBinding()?.dependencyBindingBlock();
|
||||
if (acceptanceBlock && !check)
|
||||
loweringIssue(
|
||||
state,
|
||||
acceptanceBlock,
|
||||
"unexpected-acceptance-binding",
|
||||
"Export does not declare an acceptance hook",
|
||||
);
|
||||
const acceptanceDependencies = check
|
||||
? lowerBoundDependencies(state, acceptanceBlock ?? undefined, {
|
||||
exportId: check.id,
|
||||
ports: new Map(check.dependencyPorts.map((port) => [port.displayName, port.id])),
|
||||
})
|
||||
: undefined;
|
||||
return packageSymbol && exportSymbol
|
||||
? [
|
||||
{
|
||||
@@ -2056,6 +2095,7 @@ const lowerConformance = (
|
||||
kind: "package" as const,
|
||||
packageRevisionId: packageSymbol.revisionId,
|
||||
exportId: exportSymbol.exportId,
|
||||
...(acceptanceDependencies ? { acceptanceDependencies } : {}),
|
||||
dependencies: lowerBoundDependencies(
|
||||
state,
|
||||
provider.dependencyBindingBlock() ?? undefined,
|
||||
|
||||
@@ -257,6 +257,8 @@ export interface DependencyPort {
|
||||
}
|
||||
|
||||
interface PackageExportBase {
|
||||
/** Required authoritative snapshot export in this package. */
|
||||
acceptanceExportId?: PackageExportId;
|
||||
execution?: ExecutionContract;
|
||||
id: PackageExportId;
|
||||
displayName: string;
|
||||
@@ -375,6 +377,7 @@ export type Binding =
|
||||
packageRevisionId: PackageRevisionId;
|
||||
exportId: PackageExportId;
|
||||
dependencies: BoundDependency[];
|
||||
acceptanceDependencies?: BoundDependency[];
|
||||
};
|
||||
|
||||
export interface OperationBinding {
|
||||
|
||||
@@ -961,6 +961,32 @@ const validatePackages = (
|
||||
const exportPath = `${path}.exports[${exportIndex}]`;
|
||||
validateValueType(issues, entry.inputType, `${exportPath}.inputType`, indexes);
|
||||
validateValueType(issues, entry.outputType, `${exportPath}.outputType`, indexes);
|
||||
if (entry.acceptanceExportId !== undefined) {
|
||||
const check = revision.exports.find((candidate) => candidate.id === entry.acceptanceExportId);
|
||||
if (
|
||||
entry.execution?.kind !== "transaction" ||
|
||||
!entry.execution.targets.includes("server") ||
|
||||
!check ||
|
||||
check.execution?.kind !== "snapshot" ||
|
||||
check.execution.targets.length !== 1 ||
|
||||
check.execution.targets[0] !== "server" ||
|
||||
check.acceptanceExportId !== undefined ||
|
||||
entry.kind !== check.kind ||
|
||||
entry.kind === "constructor" ||
|
||||
!valueTypesEqual(entry.inputType, check.inputType) ||
|
||||
!valueTypesEqual(check.outputType, valueType.unit) ||
|
||||
(entry.kind === "operation" &&
|
||||
(check.kind !== "operation" ||
|
||||
check.mode !== "call" ||
|
||||
!isDeepStrictEqual(entry.receiverRequirement, check.receiverRequirement)))
|
||||
)
|
||||
issue(
|
||||
issues,
|
||||
"invalid-operation",
|
||||
`${exportPath}.acceptanceExportId`,
|
||||
"Acceptance requires a server snapshot export with matching kind, receiver and input, unit output, and no further acceptance hook",
|
||||
);
|
||||
}
|
||||
if (entry.kind === "operation") {
|
||||
validateOperationEventShape(issues, entry, exportPath);
|
||||
if (entry.eventType) {
|
||||
@@ -1862,6 +1888,20 @@ const validateConformances = (
|
||||
requirementGraph,
|
||||
graphSourceKey: key,
|
||||
});
|
||||
const check = packageEntry.exports.get(packageExport.acceptanceExportId!);
|
||||
if (check) {
|
||||
validateBoundDependencies(issues, {
|
||||
dependencies: binding.acceptanceDependencies ?? [],
|
||||
dependencyPorts: check.dependencyPorts,
|
||||
atomId: conformance.atomId,
|
||||
conformance,
|
||||
path: `${bindingPath}.binding.acceptance`,
|
||||
indexes,
|
||||
requirementGraph,
|
||||
graphSourceKey: key,
|
||||
});
|
||||
} else if (binding.acceptanceDependencies !== undefined)
|
||||
issue(issues, "invalid-package-binding", bindingPath, "Acceptance ports require a declared acceptance export");
|
||||
}
|
||||
|
||||
for (const member of interfaceEntry.revision.members) {
|
||||
|
||||
@@ -3,6 +3,8 @@ import type {
|
||||
InitializationField,
|
||||
PersistentAttachment,
|
||||
DependencyBinding,
|
||||
BoundDependency,
|
||||
PackageExport,
|
||||
} from "../capability-model/types.js";
|
||||
import { type ExecutionPlan, ExecutionPlanError, hexDigest } from "./plan.js";
|
||||
import { portableValueSchema } from "../bindings/portable.js";
|
||||
@@ -107,57 +109,70 @@ export function compileKernelProgram(plan: ExecutionPlan): unknown {
|
||||
else {
|
||||
const pkg = workspace.packageImports.find((p) => p.revisionId === binding.packageRevisionId)!;
|
||||
const entry = pkg.exports.find((e) => e.id === binding.exportId)!;
|
||||
const ports = binding.dependencies.map((dependency) => {
|
||||
const requirement = entry.dependencyPorts.find((p) => p.id === dependency.portId)!.requirement;
|
||||
const bound = dependency.binding;
|
||||
const common = { id: dependency.portId, ...via(bound) };
|
||||
if (bound.kind === "state" && requirement.kind === "state")
|
||||
return {
|
||||
...common,
|
||||
kind: "state",
|
||||
owner: slotOwner(bound.slotId),
|
||||
slot: bound.slotId,
|
||||
primitives: requirement.primitives,
|
||||
};
|
||||
if (bound.kind === "edge" && requirement.kind === "edge")
|
||||
return {
|
||||
...common,
|
||||
kind: "edge",
|
||||
edge: bound.edgeTypeId,
|
||||
projection: bound.projectionId,
|
||||
primitives: requirement.primitives,
|
||||
};
|
||||
if (bound.kind === "interface" && requirement.kind === "interface") {
|
||||
const iface = workspace.interfaceImports.find((i) => i.revisionId === bound.interfaceRevisionId)!;
|
||||
return {
|
||||
...common,
|
||||
kind: "interface",
|
||||
interface: bound.interfaceRevisionId,
|
||||
operations: requirement.operations ?? iface.members.flatMap((m) => m.operations.map((o) => o.id)),
|
||||
};
|
||||
}
|
||||
if (bound.kind === "creation" && requirement.kind === "creation")
|
||||
return {
|
||||
...common,
|
||||
kind: "creation",
|
||||
atom: bound.atomId,
|
||||
schema: portableValueSchema(requirement.inputType),
|
||||
recipe: hexDigest({ plan: plan.digest, operation: operation.key, port: dependency.portId }),
|
||||
owners: bound.owners.map((seed) => {
|
||||
const owner = owners.find((o) => o.atom === bound.atomId && o.interface === seed.interfaceRevisionId);
|
||||
if (!owner)
|
||||
throw new ExecutionPlanError(
|
||||
"MISSING_STORAGE_OWNER",
|
||||
dependency.portId,
|
||||
"Creation has no initialization owner",
|
||||
);
|
||||
return { owner: owner.id, inputPath: seed.inputPath };
|
||||
}),
|
||||
};
|
||||
unsupported = `UNSUPPORTED_EXECUTION_PORT:${bound.kind}`;
|
||||
return { ...common, kind: "unavailable" };
|
||||
});
|
||||
target = { kind: "package", package: binding.packageRevisionId, export: binding.exportId, ports };
|
||||
const compilePorts = (entry: PackageExport, dependencies: BoundDependency[]) =>
|
||||
dependencies.map((dependency) => {
|
||||
const requirement = entry.dependencyPorts.find((p) => p.id === dependency.portId)!.requirement;
|
||||
const bound = dependency.binding;
|
||||
const common = { id: dependency.portId, ...via(bound) };
|
||||
if (bound.kind === "state" && requirement.kind === "state")
|
||||
return {
|
||||
...common,
|
||||
kind: "state",
|
||||
owner: slotOwner(bound.slotId),
|
||||
slot: bound.slotId,
|
||||
primitives: requirement.primitives,
|
||||
};
|
||||
if (bound.kind === "edge" && requirement.kind === "edge")
|
||||
return {
|
||||
...common,
|
||||
kind: "edge",
|
||||
edge: bound.edgeTypeId,
|
||||
projection: bound.projectionId,
|
||||
primitives: requirement.primitives,
|
||||
};
|
||||
if (bound.kind === "interface" && requirement.kind === "interface") {
|
||||
const iface = workspace.interfaceImports.find((i) => i.revisionId === bound.interfaceRevisionId)!;
|
||||
return {
|
||||
...common,
|
||||
kind: "interface",
|
||||
interface: bound.interfaceRevisionId,
|
||||
operations: requirement.operations ?? iface.members.flatMap((m) => m.operations.map((o) => o.id)),
|
||||
};
|
||||
}
|
||||
if (bound.kind === "creation" && requirement.kind === "creation")
|
||||
return {
|
||||
...common,
|
||||
kind: "creation",
|
||||
atom: bound.atomId,
|
||||
schema: portableValueSchema(requirement.inputType),
|
||||
recipe: hexDigest({ plan: plan.digest, operation: operation.key, port: dependency.portId }),
|
||||
owners: bound.owners.map((seed) => {
|
||||
const owner = owners.find((o) => o.atom === bound.atomId && o.interface === seed.interfaceRevisionId);
|
||||
if (!owner)
|
||||
throw new ExecutionPlanError(
|
||||
"MISSING_STORAGE_OWNER",
|
||||
dependency.portId,
|
||||
"Creation has no initialization owner",
|
||||
);
|
||||
return { owner: owner.id, inputPath: seed.inputPath };
|
||||
}),
|
||||
};
|
||||
unsupported = `UNSUPPORTED_EXECUTION_PORT:${bound.kind}`;
|
||||
return { ...common, kind: "unavailable" };
|
||||
});
|
||||
const ports = compilePorts(entry, binding.dependencies);
|
||||
const check = entry.acceptanceExportId
|
||||
? pkg.exports.find((candidate) => candidate.id === entry.acceptanceExportId)!
|
||||
: undefined;
|
||||
target = {
|
||||
kind: "package",
|
||||
package: binding.packageRevisionId,
|
||||
export: binding.exportId,
|
||||
ports,
|
||||
...(check
|
||||
? { acceptance: { export: check.id, ports: compilePorts(check, binding.acceptanceDependencies ?? []) } }
|
||||
: {}),
|
||||
};
|
||||
}
|
||||
const input = schema(operation.input),
|
||||
output = schema(operation.output);
|
||||
@@ -179,6 +194,7 @@ export function compileKernelProgram(plan: ExecutionPlan): unknown {
|
||||
revision: pkg.revisionId,
|
||||
exports: pkg.exports.map((entry) => ({
|
||||
id: entry.id,
|
||||
...(entry.acceptanceExportId ? { acceptance: entry.acceptanceExportId } : {}),
|
||||
effect: entry.execution?.kind ?? "remote",
|
||||
targets: entry.execution && entry.execution.kind !== "remote" ? entry.execution.targets : [],
|
||||
receiver:
|
||||
|
||||
Reference in New Issue
Block a user