sdk executable service bodies
This commit is contained in:
parent
ffd5f6c801
commit
0d01c0a522
@ -22,11 +22,13 @@ final class PbsExecutableCallableRegistryFactory {
|
||||
final PbsAst.File ast,
|
||||
final ModuleId moduleId,
|
||||
final NameTable nameTable,
|
||||
final Map<String, String> builtinCanonicalBySourceType,
|
||||
final ReadOnlyList<PbsFrontendCompiler.ImportedCallableSurface> importedCallables) {
|
||||
final var callableIdTable = new CallableTable();
|
||||
final var callableIdsByNameAndArity = new HashMap<PbsCallableResolutionKey, List<CallableId>>();
|
||||
final var callableIdByDeclaration = new HashMap<PbsLowerableCallable, CallableId>();
|
||||
final var returnSlotsByCallableId = new HashMap<CallableId, Integer>();
|
||||
final var returnOwnerByCallableId = new HashMap<CallableId, String>();
|
||||
final var tupleProjectionByCallableId = new HashMap<CallableId, PbsTupleProjection>();
|
||||
final var typeSurfaceTable = new TypeSurfaceTable();
|
||||
final var callableShapeTable = new CallableShapeTable();
|
||||
@ -39,17 +41,21 @@ final class PbsExecutableCallableRegistryFactory {
|
||||
callableIdsByNameAndArity,
|
||||
callableIdByDeclaration,
|
||||
returnSlotsByCallableId,
|
||||
returnOwnerByCallableId,
|
||||
tupleProjectionByCallableId,
|
||||
typeSurfaceTable,
|
||||
callableShapeTable,
|
||||
localCallables);
|
||||
localCallables,
|
||||
builtinCanonicalBySourceType);
|
||||
registerImportedCallables(
|
||||
nameTable,
|
||||
callableIdTable,
|
||||
callableIdsByNameAndArity,
|
||||
returnSlotsByCallableId,
|
||||
tupleProjectionByCallableId,
|
||||
importedCallables);
|
||||
returnOwnerByCallableId,
|
||||
importedCallables,
|
||||
builtinCanonicalBySourceType);
|
||||
|
||||
final var callableSignatureByCallableId = new HashMap<CallableId, CallableSignatureRef>();
|
||||
final var callableSignatures = new ArrayList<CallableSignatureRef>(callableIdTable.size());
|
||||
@ -64,6 +70,7 @@ final class PbsExecutableCallableRegistryFactory {
|
||||
callableIdsByNameAndArity,
|
||||
callableSignatureByCallableId,
|
||||
returnSlotsByCallableId,
|
||||
returnOwnerByCallableId,
|
||||
tupleProjectionByCallableId,
|
||||
ReadOnlyList.wrap(callableSignatures));
|
||||
}
|
||||
@ -91,10 +98,12 @@ final class PbsExecutableCallableRegistryFactory {
|
||||
final Map<PbsCallableResolutionKey, List<CallableId>> callableIdsByNameAndArity,
|
||||
final Map<PbsLowerableCallable, CallableId> callableIdByDeclaration,
|
||||
final Map<CallableId, Integer> returnSlotsByCallableId,
|
||||
final Map<CallableId, String> returnOwnerByCallableId,
|
||||
final Map<CallableId, PbsTupleProjection> tupleProjectionByCallableId,
|
||||
final TypeSurfaceTable typeSurfaceTable,
|
||||
final CallableShapeTable callableShapeTable,
|
||||
final ReadOnlyList<PbsLowerableCallable> localCallables) {
|
||||
final ReadOnlyList<PbsLowerableCallable> localCallables,
|
||||
final Map<String, String> builtinCanonicalBySourceType) {
|
||||
for (final var declaredCallable : localCallables) {
|
||||
final var declaredFn = declaredCallable.functionDecl();
|
||||
final var callableShapeId = callableShapeSurfaceService.callableShapeId(
|
||||
@ -113,6 +122,13 @@ final class PbsExecutableCallableRegistryFactory {
|
||||
ignored -> new ArrayList<>())
|
||||
.add(callableId);
|
||||
returnSlotsByCallableId.put(callableId, returnSlotsFor(declaredFn));
|
||||
final var returnOwner = inferCallableReturnOwner(
|
||||
declaredFn.returnKind(),
|
||||
declaredFn.returnType(),
|
||||
builtinCanonicalBySourceType);
|
||||
if (!returnOwner.isBlank()) {
|
||||
returnOwnerByCallableId.put(callableId, returnOwner);
|
||||
}
|
||||
final var tupleProjection = tupleProjectionOf(declaredFn.returnKind(), declaredFn.returnType());
|
||||
if (tupleProjection != null) {
|
||||
tupleProjectionByCallableId.put(callableId, tupleProjection);
|
||||
@ -126,7 +142,9 @@ final class PbsExecutableCallableRegistryFactory {
|
||||
final Map<PbsCallableResolutionKey, List<CallableId>> callableIdsByNameAndArity,
|
||||
final Map<CallableId, Integer> returnSlotsByCallableId,
|
||||
final Map<CallableId, PbsTupleProjection> tupleProjectionByCallableId,
|
||||
final ReadOnlyList<PbsFrontendCompiler.ImportedCallableSurface> importedCallables) {
|
||||
final Map<CallableId, String> returnOwnerByCallableId,
|
||||
final ReadOnlyList<PbsFrontendCompiler.ImportedCallableSurface> importedCallables,
|
||||
final Map<String, String> builtinCanonicalBySourceType) {
|
||||
for (final var importedCallable : importedCallables) {
|
||||
final var callableId = callableIdTable.register(
|
||||
importedCallable.moduleId(),
|
||||
@ -141,6 +159,13 @@ final class PbsExecutableCallableRegistryFactory {
|
||||
ignored -> new ArrayList<>())
|
||||
.add(callableId);
|
||||
returnSlotsByCallableId.put(callableId, importedCallable.returnSlots());
|
||||
final var returnOwner = inferCallableReturnOwner(
|
||||
importedCallable.returnKind(),
|
||||
importedCallable.returnType(),
|
||||
builtinCanonicalBySourceType);
|
||||
if (!returnOwner.isBlank()) {
|
||||
returnOwnerByCallableId.put(callableId, returnOwner);
|
||||
}
|
||||
final var tupleProjection = tupleProjectionOf(importedCallable.returnKind(), importedCallable.returnType());
|
||||
if (tupleProjection != null) {
|
||||
tupleProjectionByCallableId.put(callableId, tupleProjection);
|
||||
@ -148,6 +173,20 @@ final class PbsExecutableCallableRegistryFactory {
|
||||
}
|
||||
}
|
||||
|
||||
private String inferCallableReturnOwner(
|
||||
final PbsAst.ReturnKind returnKind,
|
||||
final PbsAst.TypeRef returnType,
|
||||
final Map<String, String> builtinCanonicalBySourceType) {
|
||||
if (returnKind != PbsAst.ReturnKind.PLAIN || returnType == null || builtinCanonicalBySourceType == null) {
|
||||
return "";
|
||||
}
|
||||
final var unwrapped = unwrapGroup(returnType);
|
||||
if (unwrapped == null || unwrapped.kind() != PbsAst.TypeRefKind.SIMPLE) {
|
||||
return "";
|
||||
}
|
||||
return builtinCanonicalBySourceType.getOrDefault(unwrapped.name(), "");
|
||||
}
|
||||
|
||||
private int returnSlotsFor(final PbsAst.FunctionDecl functionDecl) {
|
||||
return PbsCallableSlotCounter.returnSlots(functionDecl.returnKind(), functionDecl.returnType());
|
||||
}
|
||||
|
||||
@ -337,18 +337,21 @@ final class PbsExecutableCallsiteEmitter {
|
||||
return "";
|
||||
}
|
||||
final var receiverOwner = resolveReceiverOwnerForCallee(callExpr.callee(), context);
|
||||
if (receiverOwner.isBlank()) {
|
||||
if (!receiverOwner.isBlank()) {
|
||||
final var key = new PbsIntrinsicOwnerMethodKey(receiverOwner, calleeIdentity.memberSourceMethodName());
|
||||
final var intrinsicCandidates = context.intrinsicByOwnerAndMethod().getOrDefault(key, List.of());
|
||||
if (intrinsicCandidates.size() == 1) {
|
||||
final var intrinsic = intrinsicCandidates.getFirst();
|
||||
return context.intrinsicReturnOwnerByCanonical().getOrDefault(
|
||||
new PbsIntrinsicCanonicalKey(intrinsic.canonicalName(), intrinsic.canonicalVersion()),
|
||||
"");
|
||||
}
|
||||
}
|
||||
final var callableCandidates = resolveCallableCandidates(callExpr, calleeIdentity, context);
|
||||
if (callableCandidates.size() != 1) {
|
||||
return "";
|
||||
}
|
||||
final var key = new PbsIntrinsicOwnerMethodKey(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 PbsIntrinsicCanonicalKey(intrinsic.canonicalName(), intrinsic.canonicalVersion()),
|
||||
"");
|
||||
return context.returnOwnerByCallableId().getOrDefault(callableCandidates.getFirst(), "");
|
||||
}
|
||||
|
||||
private PbsCalleeIdentity resolveCalleeIdentity(
|
||||
|
||||
@ -96,6 +96,10 @@ final class PbsExecutableLoweringContext {
|
||||
return callableRegistry.returnSlotsByCallableId();
|
||||
}
|
||||
|
||||
Map<p.studio.compiler.source.identifiers.CallableId, String> returnOwnerByCallableId() {
|
||||
return callableRegistry.returnOwnerByCallableId();
|
||||
}
|
||||
|
||||
Map<p.studio.compiler.source.identifiers.CallableId, PbsTupleProjection> tupleProjectionByCallableId() {
|
||||
return callableRegistry.tupleProjectionByCallableId();
|
||||
}
|
||||
|
||||
@ -58,6 +58,7 @@ public class PbsExecutableLoweringModels {
|
||||
Map<PbsCallableResolutionKey, List<CallableId>> callableIdsByNameAndArity,
|
||||
Map<CallableId, CallableSignatureRef> callableSignatureByCallableId,
|
||||
Map<CallableId, Integer> returnSlotsByCallableId,
|
||||
Map<CallableId, String> returnOwnerByCallableId,
|
||||
Map<CallableId, PbsTupleProjection> tupleProjectionByCallableId,
|
||||
ReadOnlyList<CallableSignatureRef> callableSignatures) {
|
||||
}
|
||||
|
||||
@ -45,6 +45,7 @@ public final class PbsExecutableLoweringService {
|
||||
ast,
|
||||
normalizedModuleId,
|
||||
nameTable,
|
||||
metadataIndex.builtinCanonicalBySourceType(),
|
||||
importedCallables);
|
||||
final var intrinsicIdTable = new IntrinsicTable();
|
||||
final var executableFunctions = new ArrayList<IRBackendExecutableFunction>(callableRegistry.localCallables().size());
|
||||
|
||||
@ -97,7 +97,7 @@ public final class PbsDeclarationSemanticsValidator {
|
||||
binder.registerType(serviceDecl.name(), serviceDecl.span(), "service");
|
||||
binder.registerValue(serviceDecl.name(), serviceDecl.span(), "service singleton");
|
||||
binder.registerVisibleTopLevelSurface(serviceDecl.name(), serviceDecl.span(), "service");
|
||||
validateServiceDeclaration(serviceDecl, binder, rules);
|
||||
validateServiceDeclaration(serviceDecl, binder, rules, interfaceModule, diagnostics);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -221,7 +221,9 @@ public final class PbsDeclarationSemanticsValidator {
|
||||
private void validateServiceDeclaration(
|
||||
final PbsAst.ServiceDecl serviceDecl,
|
||||
final PbsNamespaceBinder binder,
|
||||
final PbsDeclarationRuleValidator rules) {
|
||||
final PbsDeclarationRuleValidator rules,
|
||||
final boolean interfaceModule,
|
||||
final DiagnosticSink diagnostics) {
|
||||
final var methodScope = PbsCallableScope.serviceMethods(nameTable.register(serviceDecl.name()));
|
||||
for (final var method : serviceDecl.methods()) {
|
||||
validateCallable(
|
||||
@ -235,9 +237,144 @@ public final class PbsDeclarationSemanticsValidator {
|
||||
true,
|
||||
binder,
|
||||
rules);
|
||||
if (interfaceModule) {
|
||||
validateSdkExecutableServiceMethodBody(method, diagnostics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void validateSdkExecutableServiceMethodBody(
|
||||
final PbsAst.FunctionDecl method,
|
||||
final DiagnosticSink diagnostics) {
|
||||
validateSdkExecutableBlock(method.body(), diagnostics);
|
||||
}
|
||||
|
||||
private void validateSdkExecutableBlock(
|
||||
final PbsAst.Block block,
|
||||
final DiagnosticSink diagnostics) {
|
||||
if (block == null) {
|
||||
return;
|
||||
}
|
||||
for (final var statement : block.statements()) {
|
||||
validateSdkExecutableStatement(statement, diagnostics);
|
||||
}
|
||||
if (block.tailExpression() != null) {
|
||||
reportUnsupportedSdkExecutableConstruct(
|
||||
block.tailExpression().span(),
|
||||
"SDK executable service bodies do not support block tail expressions in the initial restricted subset",
|
||||
diagnostics);
|
||||
}
|
||||
}
|
||||
|
||||
private void validateSdkExecutableStatement(
|
||||
final PbsAst.Statement statement,
|
||||
final DiagnosticSink diagnostics) {
|
||||
switch (statement) {
|
||||
case PbsAst.LetStatement letStatement ->
|
||||
validateSdkExecutableExpression(letStatement.initializer(), diagnostics);
|
||||
case PbsAst.AssignStatement assignStatement ->
|
||||
validateSdkExecutableExpression(assignStatement.value(), diagnostics);
|
||||
case PbsAst.ReturnStatement returnStatement ->
|
||||
validateSdkExecutableExpression(returnStatement.value(), diagnostics);
|
||||
case PbsAst.ExpressionStatement expressionStatement ->
|
||||
validateSdkExecutableExpression(expressionStatement.expression(), diagnostics);
|
||||
case PbsAst.IfStatement ignored ->
|
||||
reportUnsupportedSdkExecutableConstruct(
|
||||
statement.span(),
|
||||
"SDK executable service bodies do not support if statements in the initial restricted subset",
|
||||
diagnostics);
|
||||
case PbsAst.ForStatement ignored ->
|
||||
reportUnsupportedSdkExecutableConstruct(
|
||||
statement.span(),
|
||||
"SDK executable service bodies do not support for statements in the initial restricted subset",
|
||||
diagnostics);
|
||||
case PbsAst.WhileStatement ignored ->
|
||||
reportUnsupportedSdkExecutableConstruct(
|
||||
statement.span(),
|
||||
"SDK executable service bodies do not support while statements in the initial restricted subset",
|
||||
diagnostics);
|
||||
case PbsAst.BreakStatement ignored ->
|
||||
reportUnsupportedSdkExecutableConstruct(
|
||||
statement.span(),
|
||||
"SDK executable service bodies do not support break statements in the initial restricted subset",
|
||||
diagnostics);
|
||||
case PbsAst.ContinueStatement ignored ->
|
||||
reportUnsupportedSdkExecutableConstruct(
|
||||
statement.span(),
|
||||
"SDK executable service bodies do not support continue statements in the initial restricted subset",
|
||||
diagnostics);
|
||||
}
|
||||
}
|
||||
|
||||
private void validateSdkExecutableExpression(
|
||||
final PbsAst.Expression expression,
|
||||
final DiagnosticSink diagnostics) {
|
||||
if (expression == null) {
|
||||
return;
|
||||
}
|
||||
switch (expression) {
|
||||
case PbsAst.IdentifierExpr ignored -> {
|
||||
}
|
||||
case PbsAst.IntLiteralExpr ignored -> {
|
||||
}
|
||||
case PbsAst.FloatLiteralExpr ignored -> {
|
||||
}
|
||||
case PbsAst.BoundedLiteralExpr ignored -> {
|
||||
}
|
||||
case PbsAst.StringLiteralExpr ignored -> {
|
||||
}
|
||||
case PbsAst.BoolLiteralExpr ignored -> {
|
||||
}
|
||||
case PbsAst.ThisExpr ignored -> {
|
||||
}
|
||||
case PbsAst.UnitExpr ignored -> {
|
||||
}
|
||||
case PbsAst.NoneExpr ignored -> {
|
||||
}
|
||||
case PbsAst.UnaryExpr unaryExpr ->
|
||||
validateSdkExecutableExpression(unaryExpr.expression(), diagnostics);
|
||||
case PbsAst.BinaryExpr binaryExpr -> {
|
||||
validateSdkExecutableExpression(binaryExpr.left(), diagnostics);
|
||||
validateSdkExecutableExpression(binaryExpr.right(), diagnostics);
|
||||
}
|
||||
case PbsAst.CallExpr callExpr -> {
|
||||
validateSdkExecutableExpression(callExpr.callee(), diagnostics);
|
||||
for (final var argument : callExpr.arguments()) {
|
||||
validateSdkExecutableExpression(argument, diagnostics);
|
||||
}
|
||||
}
|
||||
case PbsAst.MemberExpr memberExpr ->
|
||||
validateSdkExecutableExpression(memberExpr.receiver(), diagnostics);
|
||||
case PbsAst.GroupExpr groupExpr ->
|
||||
validateSdkExecutableExpression(groupExpr.expression(), diagnostics);
|
||||
case PbsAst.NewExpr newExpr -> {
|
||||
for (final var argument : newExpr.arguments()) {
|
||||
validateSdkExecutableExpression(argument, diagnostics);
|
||||
}
|
||||
}
|
||||
case PbsAst.TupleExpr tupleExpr -> {
|
||||
for (final var item : tupleExpr.items()) {
|
||||
validateSdkExecutableExpression(item.expression(), diagnostics);
|
||||
}
|
||||
}
|
||||
default -> reportUnsupportedSdkExecutableConstruct(
|
||||
expression.span(),
|
||||
"SDK executable service bodies use an unsupported expression form in the initial restricted subset",
|
||||
diagnostics);
|
||||
}
|
||||
}
|
||||
|
||||
private void reportUnsupportedSdkExecutableConstruct(
|
||||
final Span span,
|
||||
final String message,
|
||||
final DiagnosticSink diagnostics) {
|
||||
p.studio.compiler.source.diagnostics.Diagnostics.error(
|
||||
diagnostics,
|
||||
PbsSemanticsErrors.E_SEM_SDK_EXEC_SERVICE_UNSUPPORTED_CONSTRUCT.name(),
|
||||
message,
|
||||
span);
|
||||
}
|
||||
|
||||
private void validateContractDeclaration(
|
||||
final PbsAst.ContractDecl contractDecl,
|
||||
final PbsNamespaceBinder binder,
|
||||
|
||||
@ -68,6 +68,7 @@ public enum PbsSemanticsErrors {
|
||||
E_SEM_HANDLE_NON_RESULT,
|
||||
E_SEM_HANDLE_ERROR_MISMATCH,
|
||||
E_SEM_HANDLE_ARM_TERMINAL_INVALID,
|
||||
E_SEM_SDK_EXEC_SERVICE_UNSUPPORTED_CONSTRUCT,
|
||||
E_SEM_EXEC_LOWERING_UNRESOLVED_CALLEE,
|
||||
W_SEM_IGNORED_VALUE,
|
||||
}
|
||||
|
||||
@ -104,7 +104,9 @@ class PbsGateUSdkInterfaceConformanceTest {
|
||||
assertTrue(positive.irBackend().getReservedMetadata().builtinTypeSurfaces().stream()
|
||||
.anyMatch(t -> t.sourceTypeName().equals("Color")));
|
||||
assertTrue(positive.irBackend().getReservedMetadata().builtinTypeSurfaces().stream()
|
||||
.anyMatch(t -> t.sourceTypeName().equals("Input") && t.canonicalTypeName().equals("input")));
|
||||
.anyMatch(t -> t.sourceTypeName().equals("InputType") && t.canonicalTypeName().equals("input")));
|
||||
assertTrue(positive.irBackend().getReservedMetadata().builtinConstSurfaces().stream()
|
||||
.anyMatch(c -> c.sourceConstName().equals("LowInput") && c.canonicalTarget().equals("input")));
|
||||
assertTrue(positive.irBackend().getReservedMetadata().builtinTypeSurfaces().stream()
|
||||
.anyMatch(t -> t.sourceTypeName().equals("InputButton")
|
||||
&& t.intrinsics().stream().anyMatch(i -> i.canonicalName().equals("input.button.hold"))));
|
||||
@ -157,6 +159,47 @@ class PbsGateUSdkInterfaceConformanceTest {
|
||||
assertStableDiagnosticIdentity(notPublic, PbsLinkErrors.E_LINK_IMPORT_SYMBOL_NOT_PUBLIC.name(), DiagnosticPhase.LINKING);
|
||||
}
|
||||
|
||||
@Test
|
||||
void gateU_shouldRejectUnsupportedControlFlowInExecutableSdkServiceBodies() {
|
||||
final var diagnostics = DiagnosticSink.empty();
|
||||
new PbsFrontendCompiler().compileFile(
|
||||
new FileId(60),
|
||||
"""
|
||||
[BuiltinType(name = "input", version = 1)]
|
||||
declare builtin type InputType() {
|
||||
[IntrinsicCall(name = "touch", version = 1)]
|
||||
fn touch() -> InputTouch;
|
||||
}
|
||||
|
||||
[BuiltinType(name = "input.touch", version = 1)]
|
||||
declare builtin type InputTouch() {
|
||||
[IntrinsicCall(name = "x", version = 1)]
|
||||
fn x() -> int;
|
||||
}
|
||||
|
||||
[BuiltinConst(target = "input", name = "global", version = 1)]
|
||||
declare const LowInput: InputType;
|
||||
|
||||
declare service Input {
|
||||
fn touch() -> InputTouch {
|
||||
if (true) {
|
||||
return LowInput.touch();
|
||||
}
|
||||
return LowInput.touch();
|
||||
}
|
||||
}
|
||||
""",
|
||||
diagnostics,
|
||||
SourceKind.SDK_INTERFACE);
|
||||
|
||||
final var diagnostic = firstDiagnostic(diagnostics,
|
||||
d -> d.getCode().equals(PbsSemanticsErrors.E_SEM_SDK_EXEC_SERVICE_UNSUPPORTED_CONSTRUCT.name()));
|
||||
assertStableDiagnosticIdentity(
|
||||
diagnostic,
|
||||
PbsSemanticsErrors.E_SEM_SDK_EXEC_SERVICE_UNSUPPORTED_CONSTRUCT.name(),
|
||||
DiagnosticPhase.STATIC_SEMANTICS);
|
||||
}
|
||||
|
||||
@Test
|
||||
void gateU_shouldParseReservedDeclarationsInInterfaceModeOnly() {
|
||||
final var source = """
|
||||
|
||||
@ -1410,13 +1410,28 @@ class PBSFrontendPhaseServiceTest {
|
||||
+ " executableNames="
|
||||
+ executableNames);
|
||||
final var frameExecutable = frameExecutableOptional.orElseThrow();
|
||||
final var callableCalls = frameExecutable.instructions().stream()
|
||||
.filter(instruction ->
|
||||
instruction.kind() == p.studio.compiler.models.IRBackendExecutableFunction.InstructionKind.CALL_FUNC)
|
||||
.map(instruction -> instruction.calleeCallableName())
|
||||
.toList();
|
||||
final var intrinsicCalls = frameExecutable.instructions().stream()
|
||||
.filter(instruction ->
|
||||
instruction.kind() == p.studio.compiler.models.IRBackendExecutableFunction.InstructionKind.CALL_INTRINSIC)
|
||||
.toList();
|
||||
final var inputPadExecutable = irBackend.getExecutableFunctions().stream()
|
||||
.filter(function -> "Input.pad".equals(function.callableName()))
|
||||
.findFirst()
|
||||
.orElseThrow();
|
||||
final var inputPadIntrinsics = inputPadExecutable.instructions().stream()
|
||||
.filter(instruction ->
|
||||
instruction.kind() == p.studio.compiler.models.IRBackendExecutableFunction.InstructionKind.CALL_INTRINSIC
|
||||
&& instruction.intrinsicCall() != null)
|
||||
.map(instruction -> instruction.intrinsicCall().canonicalName())
|
||||
.toList();
|
||||
assertTrue(callableCalls.contains("Input.pad"));
|
||||
assertTrue(intrinsicCalls.stream().anyMatch(instruction -> Integer.valueOf(1).equals(instruction.expectedArgSlots())));
|
||||
assertTrue(intrinsicCalls.stream().anyMatch(instruction ->
|
||||
instruction.intrinsicCall() != null && "input.pad".equals(instruction.intrinsicCall().canonicalName())));
|
||||
assertTrue(inputPadIntrinsics.contains("input.pad"));
|
||||
assertTrue(intrinsicCalls.stream().anyMatch(instruction ->
|
||||
instruction.intrinsicCall() != null && "input.pad.a".equals(instruction.intrinsicCall().canonicalName())));
|
||||
assertTrue(intrinsicCalls.stream().anyMatch(instruction ->
|
||||
@ -1481,16 +1496,43 @@ class PBSFrontendPhaseServiceTest {
|
||||
.filter(function -> "frame".equals(function.callableName()))
|
||||
.findFirst()
|
||||
.orElseThrow();
|
||||
final var callableCalls = frameExecutable.instructions().stream()
|
||||
.filter(instruction ->
|
||||
instruction.kind() == p.studio.compiler.models.IRBackendExecutableFunction.InstructionKind.CALL_FUNC)
|
||||
.map(instruction -> instruction.calleeCallableName())
|
||||
.toList();
|
||||
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"));
|
||||
final var inputPadExecutable = irBackend.getExecutableFunctions().stream()
|
||||
.filter(function -> "Input.pad".equals(function.callableName()))
|
||||
.findFirst()
|
||||
.orElseThrow();
|
||||
final var inputTouchExecutable = irBackend.getExecutableFunctions().stream()
|
||||
.filter(function -> "Input.touch".equals(function.callableName()))
|
||||
.findFirst()
|
||||
.orElseThrow();
|
||||
final var inputPadIntrinsics = inputPadExecutable.instructions().stream()
|
||||
.filter(instruction ->
|
||||
instruction.kind() == p.studio.compiler.models.IRBackendExecutableFunction.InstructionKind.CALL_INTRINSIC
|
||||
&& instruction.intrinsicCall() != null)
|
||||
.map(instruction -> instruction.intrinsicCall().canonicalName())
|
||||
.toList();
|
||||
final var inputTouchIntrinsics = inputTouchExecutable.instructions().stream()
|
||||
.filter(instruction ->
|
||||
instruction.kind() == p.studio.compiler.models.IRBackendExecutableFunction.InstructionKind.CALL_INTRINSIC
|
||||
&& instruction.intrinsicCall() != null)
|
||||
.map(instruction -> instruction.intrinsicCall().canonicalName())
|
||||
.toList();
|
||||
assertTrue(callableCalls.contains("Input.pad"));
|
||||
assertTrue(callableCalls.contains("Input.touch"));
|
||||
assertTrue(inputPadIntrinsics.contains("input.pad"));
|
||||
assertTrue(intrinsicCalls.contains("input.pad.x"));
|
||||
assertTrue(intrinsicCalls.contains("input.button.pressed"));
|
||||
assertTrue(intrinsicCalls.contains("input.touch"));
|
||||
assertTrue(inputTouchIntrinsics.contains("input.touch"));
|
||||
assertTrue(intrinsicCalls.contains("input.touch.x"));
|
||||
}
|
||||
|
||||
@ -1547,13 +1589,29 @@ class PBSFrontendPhaseServiceTest {
|
||||
.filter(function -> "frame".equals(function.callableName()))
|
||||
.findFirst()
|
||||
.orElseThrow();
|
||||
final var callableCalls = frameExecutable.instructions().stream()
|
||||
.filter(instruction ->
|
||||
instruction.kind() == p.studio.compiler.models.IRBackendExecutableFunction.InstructionKind.CALL_FUNC)
|
||||
.map(instruction -> instruction.calleeCallableName())
|
||||
.toList();
|
||||
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.touch"));
|
||||
final var inputTouchExecutable = irBackend.getExecutableFunctions().stream()
|
||||
.filter(function -> "Input.touch".equals(function.callableName()))
|
||||
.findFirst()
|
||||
.orElseThrow();
|
||||
final var inputTouchIntrinsics = inputTouchExecutable.instructions().stream()
|
||||
.filter(instruction ->
|
||||
instruction.kind() == p.studio.compiler.models.IRBackendExecutableFunction.InstructionKind.CALL_INTRINSIC
|
||||
&& instruction.intrinsicCall() != null)
|
||||
.map(instruction -> instruction.intrinsicCall().canonicalName())
|
||||
.toList();
|
||||
assertTrue(callableCalls.contains("Input.touch"));
|
||||
assertTrue(inputTouchIntrinsics.contains("input.touch"));
|
||||
assertTrue(intrinsicCalls.contains("input.touch.x"));
|
||||
assertTrue(intrinsicCalls.contains("input.touch.y"));
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user