implements PR-08.1
This commit is contained in:
parent
e11cfee9a4
commit
40188b67ab
@ -186,6 +186,7 @@ public final class PbsFrontendCompiler {
|
|||||||
final var executableLowering = lowerExecutableFunctions(
|
final var executableLowering = lowerExecutableFunctions(
|
||||||
fileId,
|
fileId,
|
||||||
ast,
|
ast,
|
||||||
|
effectiveSupplementalTopDecls,
|
||||||
moduleKey,
|
moduleKey,
|
||||||
effectiveReservedMetadata,
|
effectiveReservedMetadata,
|
||||||
effectiveNameTable,
|
effectiveNameTable,
|
||||||
@ -219,6 +220,7 @@ public final class PbsFrontendCompiler {
|
|||||||
private ExecutableLoweringResult lowerExecutableFunctions(
|
private ExecutableLoweringResult lowerExecutableFunctions(
|
||||||
final FileId fileId,
|
final FileId fileId,
|
||||||
final PbsAst.File ast,
|
final PbsAst.File ast,
|
||||||
|
final ReadOnlyList<PbsAst.TopDecl> supplementalTopDecls,
|
||||||
final String moduleKey,
|
final String moduleKey,
|
||||||
final IRReservedMetadata reservedMetadata,
|
final IRReservedMetadata reservedMetadata,
|
||||||
final NameTable nameTable,
|
final NameTable nameTable,
|
||||||
@ -231,12 +233,77 @@ public final class PbsFrontendCompiler {
|
|||||||
.computeIfAbsent(nameTable.register(hostBinding.sourceMethodName()), ignored -> new ArrayList<>())
|
.computeIfAbsent(nameTable.register(hostBinding.sourceMethodName()), ignored -> new ArrayList<>())
|
||||||
.add(hostBinding);
|
.add(hostBinding);
|
||||||
}
|
}
|
||||||
final var intrinsicByMethodName = new HashMap<NameId, List<IRReservedMetadata.IntrinsicSurface>>();
|
final var builtinCanonicalBySourceType = new HashMap<String, String>();
|
||||||
for (final var builtinType : reservedMetadata.builtinTypeSurfaces()) {
|
for (final var builtinType : reservedMetadata.builtinTypeSurfaces()) {
|
||||||
|
builtinCanonicalBySourceType.putIfAbsent(builtinType.sourceTypeName(), builtinType.canonicalTypeName());
|
||||||
|
}
|
||||||
|
final var builtinConstOwnerByNameId = new HashMap<NameId, String>();
|
||||||
|
for (final var builtinConst : reservedMetadata.builtinConstSurfaces()) {
|
||||||
|
if (builtinConst.sourceConstName().isBlank() || builtinConst.canonicalTarget().isBlank()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
builtinConstOwnerByNameId.put(nameTable.register(builtinConst.sourceConstName()), builtinConst.canonicalTarget());
|
||||||
|
}
|
||||||
|
|
||||||
|
final var builtinSignatureByOwnerAndMethod = new HashMap<IntrinsicOwnerMethodKey, PbsAst.FunctionSignature>();
|
||||||
|
final var topDeclsForIntrinsicInference = new ArrayList<PbsAst.TopDecl>(ast.topDecls().size() + supplementalTopDecls.size());
|
||||||
|
topDeclsForIntrinsicInference.addAll(ast.topDecls().asList());
|
||||||
|
topDeclsForIntrinsicInference.addAll(supplementalTopDecls.asList());
|
||||||
|
for (final var topDecl : topDeclsForIntrinsicInference) {
|
||||||
|
if (!(topDecl instanceof PbsAst.BuiltinTypeDecl builtinTypeDecl)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final var ownerCanonical = builtinCanonicalBySourceType.getOrDefault(builtinTypeDecl.name(), "");
|
||||||
|
if (ownerCanonical.isBlank()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (final var signature : builtinTypeDecl.signatures()) {
|
||||||
|
builtinSignatureByOwnerAndMethod.putIfAbsent(
|
||||||
|
new IntrinsicOwnerMethodKey(ownerCanonical, signature.name()),
|
||||||
|
signature);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final var intrinsicByOwnerAndMethod = new HashMap<IntrinsicOwnerMethodKey, List<IRReservedMetadata.IntrinsicSurface>>();
|
||||||
|
final var intrinsicReturnOwnerByCanonical = new HashMap<IntrinsicCanonicalKey, String>();
|
||||||
|
for (final var builtinType : reservedMetadata.builtinTypeSurfaces()) {
|
||||||
|
final var ownerCanonical = builtinType.canonicalTypeName();
|
||||||
for (final var intrinsicSurface : builtinType.intrinsics()) {
|
for (final var intrinsicSurface : builtinType.intrinsics()) {
|
||||||
intrinsicByMethodName
|
intrinsicByOwnerAndMethod
|
||||||
.computeIfAbsent(nameTable.register(intrinsicSurface.sourceMethodName()), ignored -> new ArrayList<>())
|
.computeIfAbsent(
|
||||||
|
new IntrinsicOwnerMethodKey(ownerCanonical, intrinsicSurface.sourceMethodName()),
|
||||||
|
ignored -> new ArrayList<>())
|
||||||
.add(intrinsicSurface);
|
.add(intrinsicSurface);
|
||||||
|
|
||||||
|
final var signature = builtinSignatureByOwnerAndMethod.get(
|
||||||
|
new IntrinsicOwnerMethodKey(ownerCanonical, intrinsicSurface.sourceMethodName()));
|
||||||
|
if (signature == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final var returnOwner = inferIntrinsicReturnOwner(
|
||||||
|
signature,
|
||||||
|
ownerCanonical,
|
||||||
|
builtinCanonicalBySourceType);
|
||||||
|
if (returnOwner.isBlank()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final var key = new IntrinsicCanonicalKey(
|
||||||
|
intrinsicSurface.canonicalName(),
|
||||||
|
intrinsicSurface.canonicalVersion());
|
||||||
|
final var previous = intrinsicReturnOwnerByCanonical.putIfAbsent(key, returnOwner);
|
||||||
|
if (previous != null && !previous.equals(returnOwner)) {
|
||||||
|
diagnostics.error(
|
||||||
|
DiagnosticPhase.STATIC_SEMANTICS,
|
||||||
|
PbsSemanticsErrors.E_SEM_EXEC_LOWERING_UNRESOLVED_CALLEE.name(),
|
||||||
|
PbsSemanticsErrors.E_SEM_EXEC_LOWERING_UNRESOLVED_CALLEE.name(),
|
||||||
|
Map.of(),
|
||||||
|
"inconsistent intrinsic return owner metadata for %s@%d: %s vs %s".formatted(
|
||||||
|
intrinsicSurface.canonicalName(),
|
||||||
|
intrinsicSurface.canonicalVersion(),
|
||||||
|
previous,
|
||||||
|
returnOwner),
|
||||||
|
intrinsicSurface.span());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final var callableIdTable = new CallableTable();
|
final var callableIdTable = new CallableTable();
|
||||||
@ -296,7 +363,9 @@ public final class PbsFrontendCompiler {
|
|||||||
diagnostics,
|
diagnostics,
|
||||||
nameTable,
|
nameTable,
|
||||||
hostByMethodName,
|
hostByMethodName,
|
||||||
intrinsicByMethodName,
|
intrinsicByOwnerAndMethod,
|
||||||
|
intrinsicReturnOwnerByCanonical,
|
||||||
|
builtinConstOwnerByNameId,
|
||||||
callableIdsByNameAndArity,
|
callableIdsByNameAndArity,
|
||||||
returnSlotsByCallableId,
|
returnSlotsByCallableId,
|
||||||
intrinsicIdTable,
|
intrinsicIdTable,
|
||||||
@ -458,6 +527,25 @@ public final class PbsFrontendCompiler {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String inferIntrinsicReturnOwner(
|
||||||
|
final PbsAst.FunctionSignature signature,
|
||||||
|
final String intrinsicOwnerCanonical,
|
||||||
|
final Map<String, String> builtinCanonicalBySourceType) {
|
||||||
|
if (signature.returnKind() == PbsAst.ReturnKind.INFERRED_UNIT
|
||||||
|
|| signature.returnKind() == PbsAst.ReturnKind.EXPLICIT_UNIT) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
final var returnType = unwrapGroup(signature.returnType());
|
||||||
|
if (returnType == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return switch (returnType.kind()) {
|
||||||
|
case SELF -> intrinsicOwnerCanonical == null ? "" : intrinsicOwnerCanonical;
|
||||||
|
case SIMPLE -> builtinCanonicalBySourceType.getOrDefault(returnType.name(), "");
|
||||||
|
default -> "";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private String typeSurfaceKey(final PbsAst.TypeRef typeRef) {
|
private String typeSurfaceKey(final PbsAst.TypeRef typeRef) {
|
||||||
final var unwrapped = unwrapGroup(typeRef);
|
final var unwrapped = unwrapGroup(typeRef);
|
||||||
if (unwrapped == null) {
|
if (unwrapped == null) {
|
||||||
@ -758,7 +846,7 @@ public final class PbsFrontendCompiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final var hostCandidates = context.hostByMethodName().getOrDefault(calleeIdentity.memberNameId(), List.of());
|
final var hostCandidates = context.hostByMethodName().getOrDefault(calleeIdentity.memberNameId(), List.of());
|
||||||
final var intrinsicCandidates = context.intrinsicByMethodName().getOrDefault(calleeIdentity.memberNameId(), List.of());
|
final var intrinsicCandidates = resolveIntrinsicCandidates(callExpr, calleeIdentity, context);
|
||||||
|
|
||||||
var categoryCount = 0;
|
var categoryCount = 0;
|
||||||
if (callableCandidates != null && !callableCandidates.isEmpty()) {
|
if (callableCandidates != null && !callableCandidates.isEmpty()) {
|
||||||
@ -843,6 +931,66 @@ public final class PbsFrontendCompiler {
|
|||||||
callExpr.span()));
|
callExpr.span()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<IRReservedMetadata.IntrinsicSurface> resolveIntrinsicCandidates(
|
||||||
|
final PbsAst.CallExpr callExpr,
|
||||||
|
final CalleeIdentity calleeIdentity,
|
||||||
|
final ExecutableLoweringContext context) {
|
||||||
|
final var receiverOwner = resolveReceiverOwnerForCallee(callExpr.callee(), context);
|
||||||
|
if (receiverOwner.isBlank()) {
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
final var key = new IntrinsicOwnerMethodKey(receiverOwner, calleeIdentity.memberSourceMethodName());
|
||||||
|
return context.intrinsicByOwnerAndMethod().getOrDefault(key, List.of());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String resolveReceiverOwnerForCallee(
|
||||||
|
final PbsAst.Expression callee,
|
||||||
|
final ExecutableLoweringContext context) {
|
||||||
|
return switch (callee) {
|
||||||
|
case PbsAst.MemberExpr memberExpr -> resolveExpressionOwner(memberExpr.receiver(), context);
|
||||||
|
case PbsAst.GroupExpr groupExpr -> resolveReceiverOwnerForCallee(groupExpr.expression(), context);
|
||||||
|
default -> "";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private String resolveExpressionOwner(
|
||||||
|
final PbsAst.Expression expression,
|
||||||
|
final ExecutableLoweringContext context) {
|
||||||
|
if (expression == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return switch (expression) {
|
||||||
|
case PbsAst.IdentifierExpr identifierExpr ->
|
||||||
|
context.builtinConstOwnerByNameId().getOrDefault(context.nameTable().register(identifierExpr.name()), "");
|
||||||
|
case PbsAst.CallExpr callExpr -> resolveCallReturnOwner(callExpr, context);
|
||||||
|
case PbsAst.MemberExpr memberExpr -> resolveExpressionOwner(memberExpr.receiver(), context);
|
||||||
|
case PbsAst.GroupExpr groupExpr -> resolveExpressionOwner(groupExpr.expression(), context);
|
||||||
|
default -> "";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private String resolveCallReturnOwner(
|
||||||
|
final PbsAst.CallExpr callExpr,
|
||||||
|
final ExecutableLoweringContext context) {
|
||||||
|
final var calleeIdentity = resolveCalleeIdentity(callExpr.callee(), context.nameTable());
|
||||||
|
if (calleeIdentity == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
final var receiverOwner = resolveReceiverOwnerForCallee(callExpr.callee(), context);
|
||||||
|
if (receiverOwner.isBlank()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
final var key = new IntrinsicOwnerMethodKey(receiverOwner, calleeIdentity.memberSourceMethodName());
|
||||||
|
final var intrinsicCandidates = context.intrinsicByOwnerAndMethod().getOrDefault(key, List.of());
|
||||||
|
if (intrinsicCandidates.size() != 1) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
final var intrinsic = intrinsicCandidates.getFirst();
|
||||||
|
return context.intrinsicReturnOwnerByCanonical().getOrDefault(
|
||||||
|
new IntrinsicCanonicalKey(intrinsic.canonicalName(), intrinsic.canonicalVersion()),
|
||||||
|
"");
|
||||||
|
}
|
||||||
|
|
||||||
private CalleeIdentity resolveCalleeIdentity(
|
private CalleeIdentity resolveCalleeIdentity(
|
||||||
final PbsAst.Expression callee,
|
final PbsAst.Expression callee,
|
||||||
final NameTable nameTable) {
|
final NameTable nameTable) {
|
||||||
@ -853,6 +1001,7 @@ public final class PbsFrontendCompiler {
|
|||||||
identifierExpr.name(),
|
identifierExpr.name(),
|
||||||
null,
|
null,
|
||||||
"",
|
"",
|
||||||
|
identifierExpr.name(),
|
||||||
nameTable.register(identifierExpr.name()));
|
nameTable.register(identifierExpr.name()));
|
||||||
case PbsAst.MemberExpr memberExpr -> {
|
case PbsAst.MemberExpr memberExpr -> {
|
||||||
final var memberName = memberExpr.memberName();
|
final var memberName = memberExpr.memberName();
|
||||||
@ -874,6 +1023,7 @@ public final class PbsFrontendCompiler {
|
|||||||
qualified,
|
qualified,
|
||||||
secondaryNameId,
|
secondaryNameId,
|
||||||
secondaryDisplayName,
|
secondaryDisplayName,
|
||||||
|
memberName,
|
||||||
nameTable.register(memberName));
|
nameTable.register(memberName));
|
||||||
}
|
}
|
||||||
case PbsAst.BindExpr bindExpr ->
|
case PbsAst.BindExpr bindExpr ->
|
||||||
@ -882,6 +1032,7 @@ public final class PbsFrontendCompiler {
|
|||||||
bindExpr.functionName(),
|
bindExpr.functionName(),
|
||||||
null,
|
null,
|
||||||
"",
|
"",
|
||||||
|
bindExpr.functionName(),
|
||||||
nameTable.register(bindExpr.functionName()));
|
nameTable.register(bindExpr.functionName()));
|
||||||
case PbsAst.GroupExpr groupExpr -> resolveCalleeIdentity(groupExpr.expression(), nameTable);
|
case PbsAst.GroupExpr groupExpr -> resolveCalleeIdentity(groupExpr.expression(), nameTable);
|
||||||
default -> null;
|
default -> null;
|
||||||
@ -1145,7 +1296,9 @@ public final class PbsFrontendCompiler {
|
|||||||
private final DiagnosticSink diagnostics;
|
private final DiagnosticSink diagnostics;
|
||||||
private final NameTable nameTable;
|
private final NameTable nameTable;
|
||||||
private final Map<NameId, List<IRReservedMetadata.HostMethodBinding>> hostByMethodName;
|
private final Map<NameId, List<IRReservedMetadata.HostMethodBinding>> hostByMethodName;
|
||||||
private final Map<NameId, List<IRReservedMetadata.IntrinsicSurface>> intrinsicByMethodName;
|
private final Map<IntrinsicOwnerMethodKey, List<IRReservedMetadata.IntrinsicSurface>> intrinsicByOwnerAndMethod;
|
||||||
|
private final Map<IntrinsicCanonicalKey, String> intrinsicReturnOwnerByCanonical;
|
||||||
|
private final Map<NameId, String> builtinConstOwnerByNameId;
|
||||||
private final Map<CallableResolutionKey, List<CallableId>> callableIdsByNameAndArity;
|
private final Map<CallableResolutionKey, List<CallableId>> callableIdsByNameAndArity;
|
||||||
private final Map<CallableId, Integer> returnSlotsByCallableId;
|
private final Map<CallableId, Integer> returnSlotsByCallableId;
|
||||||
private final IntrinsicTable intrinsicIdTable;
|
private final IntrinsicTable intrinsicIdTable;
|
||||||
@ -1159,7 +1312,9 @@ public final class PbsFrontendCompiler {
|
|||||||
final DiagnosticSink diagnostics,
|
final DiagnosticSink diagnostics,
|
||||||
final NameTable nameTable,
|
final NameTable nameTable,
|
||||||
final Map<NameId, List<IRReservedMetadata.HostMethodBinding>> hostByMethodName,
|
final Map<NameId, List<IRReservedMetadata.HostMethodBinding>> hostByMethodName,
|
||||||
final Map<NameId, List<IRReservedMetadata.IntrinsicSurface>> intrinsicByMethodName,
|
final Map<IntrinsicOwnerMethodKey, List<IRReservedMetadata.IntrinsicSurface>> intrinsicByOwnerAndMethod,
|
||||||
|
final Map<IntrinsicCanonicalKey, String> intrinsicReturnOwnerByCanonical,
|
||||||
|
final Map<NameId, String> builtinConstOwnerByNameId,
|
||||||
final Map<CallableResolutionKey, List<CallableId>> callableIdsByNameAndArity,
|
final Map<CallableResolutionKey, List<CallableId>> callableIdsByNameAndArity,
|
||||||
final Map<CallableId, Integer> returnSlotsByCallableId,
|
final Map<CallableId, Integer> returnSlotsByCallableId,
|
||||||
final IntrinsicTable intrinsicIdTable,
|
final IntrinsicTable intrinsicIdTable,
|
||||||
@ -1168,7 +1323,9 @@ public final class PbsFrontendCompiler {
|
|||||||
this.diagnostics = diagnostics;
|
this.diagnostics = diagnostics;
|
||||||
this.nameTable = nameTable;
|
this.nameTable = nameTable;
|
||||||
this.hostByMethodName = hostByMethodName;
|
this.hostByMethodName = hostByMethodName;
|
||||||
this.intrinsicByMethodName = intrinsicByMethodName;
|
this.intrinsicByOwnerAndMethod = intrinsicByOwnerAndMethod;
|
||||||
|
this.intrinsicReturnOwnerByCanonical = intrinsicReturnOwnerByCanonical;
|
||||||
|
this.builtinConstOwnerByNameId = builtinConstOwnerByNameId;
|
||||||
this.callableIdsByNameAndArity = callableIdsByNameAndArity;
|
this.callableIdsByNameAndArity = callableIdsByNameAndArity;
|
||||||
this.returnSlotsByCallableId = returnSlotsByCallableId;
|
this.returnSlotsByCallableId = returnSlotsByCallableId;
|
||||||
this.intrinsicIdTable = intrinsicIdTable;
|
this.intrinsicIdTable = intrinsicIdTable;
|
||||||
@ -1191,8 +1348,16 @@ public final class PbsFrontendCompiler {
|
|||||||
return hostByMethodName;
|
return hostByMethodName;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<NameId, List<IRReservedMetadata.IntrinsicSurface>> intrinsicByMethodName() {
|
private Map<IntrinsicOwnerMethodKey, List<IRReservedMetadata.IntrinsicSurface>> intrinsicByOwnerAndMethod() {
|
||||||
return intrinsicByMethodName;
|
return intrinsicByOwnerAndMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<IntrinsicCanonicalKey, String> intrinsicReturnOwnerByCanonical() {
|
||||||
|
return intrinsicReturnOwnerByCanonical;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<NameId, String> builtinConstOwnerByNameId() {
|
||||||
|
return builtinConstOwnerByNameId;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<CallableResolutionKey, List<CallableId>> callableIdsByNameAndArity() {
|
private Map<CallableResolutionKey, List<CallableId>> callableIdsByNameAndArity() {
|
||||||
@ -1255,11 +1420,22 @@ public final class PbsFrontendCompiler {
|
|||||||
int arity) {
|
int arity) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private record IntrinsicOwnerMethodKey(
|
||||||
|
String ownerCanonicalName,
|
||||||
|
String sourceMethodName) {
|
||||||
|
}
|
||||||
|
|
||||||
|
private record IntrinsicCanonicalKey(
|
||||||
|
String canonicalName,
|
||||||
|
long canonicalVersion) {
|
||||||
|
}
|
||||||
|
|
||||||
private record CalleeIdentity(
|
private record CalleeIdentity(
|
||||||
NameId primaryCallableNameId,
|
NameId primaryCallableNameId,
|
||||||
String primaryCallableDisplayName,
|
String primaryCallableDisplayName,
|
||||||
NameId secondaryCallableNameId,
|
NameId secondaryCallableNameId,
|
||||||
String secondaryCallableDisplayName,
|
String secondaryCallableDisplayName,
|
||||||
|
String memberSourceMethodName,
|
||||||
NameId memberNameId) {
|
NameId memberNameId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -867,6 +867,70 @@ class PBSFrontendPhaseServiceTest {
|
|||||||
+ executableNames);
|
+ executableNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldResolveIntrinsicChainsWithMethodNameCollisionsByOwnerIdentity() throws IOException {
|
||||||
|
final var projectRoot = tempDir.resolve("project-intrinsic-owner-collision");
|
||||||
|
final var sourceRoot = projectRoot.resolve("src");
|
||||||
|
Files.createDirectories(sourceRoot);
|
||||||
|
|
||||||
|
final var sourceFile = sourceRoot.resolve("main.pbs");
|
||||||
|
final var modBarrel = sourceRoot.resolve("mod.barrel");
|
||||||
|
Files.writeString(sourceFile, """
|
||||||
|
import { Input } from @sdk:input;
|
||||||
|
|
||||||
|
fn frame() -> void
|
||||||
|
{
|
||||||
|
Input.pad().x().pressed();
|
||||||
|
Input.touch().x();
|
||||||
|
}
|
||||||
|
""");
|
||||||
|
Files.writeString(modBarrel, "pub fn frame() -> void;");
|
||||||
|
|
||||||
|
final var projectTable = new ProjectTable();
|
||||||
|
final var fileTable = new FileTable(1);
|
||||||
|
final var projectId = projectTable.register(ProjectDescriptor.builder()
|
||||||
|
.rootPath(projectRoot)
|
||||||
|
.name("main")
|
||||||
|
.version("1.0.0")
|
||||||
|
.sourceRoots(ReadOnlyList.wrap(List.of(sourceRoot)))
|
||||||
|
.build());
|
||||||
|
|
||||||
|
registerFile(projectId, projectRoot, sourceFile, fileTable);
|
||||||
|
registerFile(projectId, projectRoot, modBarrel, fileTable);
|
||||||
|
|
||||||
|
final var ctx = new FrontendPhaseContext(
|
||||||
|
projectTable,
|
||||||
|
fileTable,
|
||||||
|
new BuildStack(ReadOnlyList.wrap(List.of(projectId))),
|
||||||
|
1);
|
||||||
|
final var diagnostics = DiagnosticSink.empty();
|
||||||
|
|
||||||
|
final var irBackend = new PBSFrontendPhaseService().compile(
|
||||||
|
ctx,
|
||||||
|
diagnostics,
|
||||||
|
LogAggregator.empty(),
|
||||||
|
BuildingIssueSink.empty());
|
||||||
|
|
||||||
|
assertTrue(diagnostics.stream().noneMatch(d ->
|
||||||
|
d.getCode().equals(PbsSemanticsErrors.E_SEM_EXEC_LOWERING_UNRESOLVED_CALLEE.name())),
|
||||||
|
diagnostics.stream().map(d -> d.getCode() + ":" + d.getMessage()).toList().toString());
|
||||||
|
final var frameExecutable = irBackend.getExecutableFunctions().stream()
|
||||||
|
.filter(function -> "frame".equals(function.callableName()))
|
||||||
|
.findFirst()
|
||||||
|
.orElseThrow();
|
||||||
|
final var intrinsicCalls = frameExecutable.instructions().stream()
|
||||||
|
.filter(instruction ->
|
||||||
|
instruction.kind() == p.studio.compiler.models.IRBackendExecutableFunction.InstructionKind.CALL_INTRINSIC
|
||||||
|
&& instruction.intrinsicCall() != null)
|
||||||
|
.map(instruction -> instruction.intrinsicCall().canonicalName())
|
||||||
|
.toList();
|
||||||
|
assertTrue(intrinsicCalls.contains("input.pad"));
|
||||||
|
assertTrue(intrinsicCalls.contains("input.pad.x"));
|
||||||
|
assertTrue(intrinsicCalls.contains("input.button.pressed"));
|
||||||
|
assertTrue(intrinsicCalls.contains("input.touch"));
|
||||||
|
assertTrue(intrinsicCalls.contains("input.touch.x"));
|
||||||
|
}
|
||||||
|
|
||||||
private void registerFile(
|
private void registerFile(
|
||||||
final ProjectId projectId,
|
final ProjectId projectId,
|
||||||
final Path projectRoot,
|
final Path projectRoot,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user