Compile and dispatch authoritative acceptance hooks with target-specific package roots
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user