implements PR-05.0.6
This commit is contained in:
parent
9aac65a2e9
commit
4e0f3a3532
@ -5,6 +5,8 @@ import p.studio.compiler.models.IRReservedMetadata;
|
|||||||
import p.studio.compiler.source.diagnostics.DiagnosticSink;
|
import p.studio.compiler.source.diagnostics.DiagnosticSink;
|
||||||
import p.studio.compiler.source.diagnostics.Diagnostics;
|
import p.studio.compiler.source.diagnostics.Diagnostics;
|
||||||
import p.studio.compiler.source.diagnostics.RelatedSpan;
|
import p.studio.compiler.source.diagnostics.RelatedSpan;
|
||||||
|
import p.studio.compiler.source.identifiers.HostBindingId;
|
||||||
|
import p.studio.compiler.source.tables.HostBindingTable;
|
||||||
import p.studio.utilities.structures.ReadOnlyList;
|
import p.studio.utilities.structures.ReadOnlyList;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -25,7 +27,8 @@ public final class PbsHostAdmissionValidator {
|
|||||||
final var knownCapabilities = normalizedSet(context.knownCapabilities());
|
final var knownCapabilities = normalizedSet(context.knownCapabilities());
|
||||||
final var declaredCapabilities = normalizedSet(context.declaredCapabilities());
|
final var declaredCapabilities = normalizedSet(context.declaredCapabilities());
|
||||||
final var requiredCapabilities = new LinkedHashSet<String>();
|
final var requiredCapabilities = new LinkedHashSet<String>();
|
||||||
final var firstCapabilityByHostBinding = new HashMap<String, FirstBindingCapability>();
|
final var hostBindingTable = new HostBindingTable();
|
||||||
|
final var firstCapabilityByHostBinding = new HashMap<HostBindingId, FirstBindingCapability>();
|
||||||
|
|
||||||
for (final var hostBinding : metadata.hostMethodBindings()) {
|
for (final var hostBinding : metadata.hostMethodBindings()) {
|
||||||
final var normalizedCapability = normalize(hostBinding.requiredCapability());
|
final var normalizedCapability = normalize(hostBinding.requiredCapability());
|
||||||
@ -68,12 +71,12 @@ public final class PbsHostAdmissionValidator {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
final var bindingKey = "%s|%s|%d".formatted(
|
final var hostBindingId = hostBindingTable.register(
|
||||||
hostBinding.abiModule(),
|
hostBinding.abiModule(),
|
||||||
hostBinding.abiMethod(),
|
hostBinding.abiMethod(),
|
||||||
hostBinding.abiVersion());
|
hostBinding.abiVersion());
|
||||||
final var firstBindingCapability = firstCapabilityByHostBinding.putIfAbsent(
|
final var firstBindingCapability = firstCapabilityByHostBinding.putIfAbsent(
|
||||||
bindingKey,
|
hostBindingId,
|
||||||
new FirstBindingCapability(normalizedCapability, hostBinding.span()));
|
new FirstBindingCapability(normalizedCapability, hostBinding.span()));
|
||||||
if (firstBindingCapability != null && !firstBindingCapability.capability().equals(normalizedCapability)) {
|
if (firstBindingCapability != null && !firstBindingCapability.capability().equals(normalizedCapability)) {
|
||||||
Diagnostics.error(
|
Diagnostics.error(
|
||||||
|
|||||||
@ -0,0 +1,7 @@
|
|||||||
|
package p.studio.compiler.source.identifiers;
|
||||||
|
|
||||||
|
public class HostBindingId extends SourceIdentifier {
|
||||||
|
public HostBindingId(final int id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
package p.studio.compiler.source.tables;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public record HostBindingRef(
|
||||||
|
String module,
|
||||||
|
String name,
|
||||||
|
long version) {
|
||||||
|
public HostBindingRef {
|
||||||
|
module = Objects.requireNonNull(module, "module");
|
||||||
|
name = Objects.requireNonNull(name, "name");
|
||||||
|
if (module.isBlank() || name.isBlank()) {
|
||||||
|
throw new IllegalArgumentException("module and name must not be blank");
|
||||||
|
}
|
||||||
|
if (version < 0) {
|
||||||
|
throw new IllegalArgumentException("version must be non-negative");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package p.studio.compiler.source.tables;
|
||||||
|
|
||||||
|
import p.studio.compiler.source.identifiers.HostBindingId;
|
||||||
|
|
||||||
|
public class HostBindingTable extends InternTable<HostBindingId, HostBindingRef> {
|
||||||
|
|
||||||
|
public HostBindingTable() {
|
||||||
|
super(HostBindingId::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HostBindingId register(
|
||||||
|
final String module,
|
||||||
|
final String name,
|
||||||
|
final long version) {
|
||||||
|
return register(new HostBindingRef(module, name, version));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
package p.studio.compiler.source.tables;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
|
class HostBindingTableTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldInternEqualHostBindingsToSameIdentifier() {
|
||||||
|
final var table = new HostBindingTable();
|
||||||
|
|
||||||
|
final var first = table.register("gfx", "draw_pixel", 1);
|
||||||
|
final var second = table.register("gfx", "draw_pixel", 1);
|
||||||
|
final var third = table.register("gfx", "draw_pixel", 2);
|
||||||
|
|
||||||
|
assertEquals(first, second);
|
||||||
|
assertNotEquals(first, third);
|
||||||
|
assertEquals(2, table.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldRejectInvalidHostBindingContract() {
|
||||||
|
assertThrows(IllegalArgumentException.class, () -> new HostBindingRef("", "draw_pixel", 1));
|
||||||
|
assertThrows(IllegalArgumentException.class, () -> new HostBindingRef("gfx", "", 1));
|
||||||
|
assertThrows(IllegalArgumentException.class, () -> new HostBindingRef("gfx", "draw_pixel", -1));
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user