implements PR-05.0.2
This commit is contained in:
parent
3b5e8e0b24
commit
bafab68eac
@ -21,6 +21,9 @@ import p.studio.compiler.source.Span;
|
|||||||
import p.studio.compiler.source.diagnostics.DiagnosticSink;
|
import p.studio.compiler.source.diagnostics.DiagnosticSink;
|
||||||
import p.studio.compiler.source.diagnostics.DiagnosticPhase;
|
import p.studio.compiler.source.diagnostics.DiagnosticPhase;
|
||||||
import p.studio.compiler.source.identifiers.FileId;
|
import p.studio.compiler.source.identifiers.FileId;
|
||||||
|
import p.studio.compiler.source.identifiers.ModuleId;
|
||||||
|
import p.studio.compiler.source.tables.ModuleReference;
|
||||||
|
import p.studio.compiler.source.tables.ModuleTable;
|
||||||
import p.studio.utilities.structures.ReadOnlyList;
|
import p.studio.utilities.structures.ReadOnlyList;
|
||||||
import p.studio.utilities.logs.LogAggregator;
|
import p.studio.utilities.logs.LogAggregator;
|
||||||
|
|
||||||
@ -62,8 +65,9 @@ public class PBSFrontendPhaseService implements FrontendPhaseService {
|
|||||||
final var irBackendAggregator = IRBackend.aggregator();
|
final var irBackendAggregator = IRBackend.aggregator();
|
||||||
final var parsedSourceFiles = new ArrayList<ParsedSourceFile>();
|
final var parsedSourceFiles = new ArrayList<ParsedSourceFile>();
|
||||||
final Map<PbsModuleVisibilityValidator.ModuleCoordinates, MutableModuleUnit> modulesByCoordinates = new LinkedHashMap<>();
|
final Map<PbsModuleVisibilityValidator.ModuleCoordinates, MutableModuleUnit> modulesByCoordinates = new LinkedHashMap<>();
|
||||||
final var moduleKeyByFile = new HashMap<FileId, String>();
|
final var moduleTable = new ModuleTable();
|
||||||
final var failedModuleKeys = new HashSet<String>();
|
final var moduleIdByFile = new HashMap<FileId, ModuleId>();
|
||||||
|
final var failedModuleIds = new HashSet<ModuleId>();
|
||||||
|
|
||||||
for (final var pId : ctx.stack.reverseTopologicalOrder) {
|
for (final var pId : ctx.stack.reverseTopologicalOrder) {
|
||||||
final var projectDescriptor = ctx.projectTable.get(pId);
|
final var projectDescriptor = ctx.projectTable.get(pId);
|
||||||
@ -75,36 +79,36 @@ public class PBSFrontendPhaseService implements FrontendPhaseService {
|
|||||||
sourceHandle.readUtf8().ifPresentOrElse(
|
sourceHandle.readUtf8().ifPresentOrElse(
|
||||||
utf8Content -> {
|
utf8Content -> {
|
||||||
final var coordinates = resolveModuleCoordinates(projectDescriptor, sourceHandle);
|
final var coordinates = resolveModuleCoordinates(projectDescriptor, sourceHandle);
|
||||||
final var moduleKey = moduleKey(coordinates);
|
final var moduleId = moduleId(moduleTable, coordinates);
|
||||||
final var moduleUnit = modulesByCoordinates.computeIfAbsent(
|
final var moduleUnit = modulesByCoordinates.computeIfAbsent(
|
||||||
coordinates,
|
coordinates,
|
||||||
ignored -> new MutableModuleUnit());
|
ignored -> new MutableModuleUnit());
|
||||||
switch (sourceHandle.getExtension()) {
|
switch (sourceHandle.getExtension()) {
|
||||||
case "pbs" -> {
|
case "pbs" -> {
|
||||||
moduleKeyByFile.put(fId, moduleKey);
|
moduleIdByFile.put(fId, moduleId);
|
||||||
final var parseErrorBaseline = diagnostics.errorCount();
|
final var parseErrorBaseline = diagnostics.errorCount();
|
||||||
final var ast = parseSourceFile(fId, utf8Content, diagnostics, projectSourceKind);
|
final var ast = parseSourceFile(fId, utf8Content, diagnostics, projectSourceKind);
|
||||||
moduleUnit.sources.add(new PbsModuleVisibilityValidator.SourceFile(fId, ast));
|
moduleUnit.sources.add(new PbsModuleVisibilityValidator.SourceFile(fId, ast));
|
||||||
parsedSourceFiles.add(new ParsedSourceFile(fId, ast, moduleKey, projectSourceKind));
|
parsedSourceFiles.add(new ParsedSourceFile(fId, ast, moduleId, projectSourceKind));
|
||||||
if (diagnostics.errorCount() > parseErrorBaseline) {
|
if (diagnostics.errorCount() > parseErrorBaseline) {
|
||||||
failedModuleKeys.add(moduleKey);
|
failedModuleIds.add(moduleId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "barrel" -> {
|
case "barrel" -> {
|
||||||
moduleKeyByFile.put(fId, moduleKey);
|
moduleIdByFile.put(fId, moduleId);
|
||||||
if ("mod.barrel".equals(sourceHandle.getFilename())) {
|
if ("mod.barrel".equals(sourceHandle.getFilename())) {
|
||||||
final var parseErrorBaseline = diagnostics.errorCount();
|
final var parseErrorBaseline = diagnostics.errorCount();
|
||||||
final var barrelAst = parseBarrelFile(fId, utf8Content, diagnostics);
|
final var barrelAst = parseBarrelFile(fId, utf8Content, diagnostics);
|
||||||
moduleUnit.barrels.add(new PbsModuleVisibilityValidator.BarrelFile(fId, barrelAst));
|
moduleUnit.barrels.add(new PbsModuleVisibilityValidator.BarrelFile(fId, barrelAst));
|
||||||
if (diagnostics.errorCount() > parseErrorBaseline) {
|
if (diagnostics.errorCount() > parseErrorBaseline) {
|
||||||
failedModuleKeys.add(moduleKey);
|
failedModuleIds.add(moduleId);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
p.studio.compiler.source.diagnostics.Diagnostics.error(diagnostics,
|
p.studio.compiler.source.diagnostics.Diagnostics.error(diagnostics,
|
||||||
PbsLinkErrors.E_LINK_INVALID_BARREL_FILENAME.name(),
|
PbsLinkErrors.E_LINK_INVALID_BARREL_FILENAME.name(),
|
||||||
"Only 'mod.barrel' is allowed as barrel filename",
|
"Only 'mod.barrel' is allowed as barrel filename",
|
||||||
new Span(fId, 0, utf8Content.getBytes(StandardCharsets.UTF_8).length));
|
new Span(fId, 0, utf8Content.getBytes(StandardCharsets.UTF_8).length));
|
||||||
failedModuleKeys.add(moduleKey);
|
failedModuleIds.add(moduleId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default -> {
|
default -> {
|
||||||
@ -120,7 +124,8 @@ public class PBSFrontendPhaseService implements FrontendPhaseService {
|
|||||||
loadReservedStdlibModules(
|
loadReservedStdlibModules(
|
||||||
modulesByCoordinates,
|
modulesByCoordinates,
|
||||||
parsedSourceFiles,
|
parsedSourceFiles,
|
||||||
moduleKeyByFile,
|
moduleIdByFile,
|
||||||
|
moduleTable,
|
||||||
diagnostics,
|
diagnostics,
|
||||||
ctx.stdlibVersion());
|
ctx.stdlibVersion());
|
||||||
|
|
||||||
@ -134,13 +139,13 @@ public class PBSFrontendPhaseService implements FrontendPhaseService {
|
|||||||
ReadOnlyList.wrap(moduleUnit.barrels)));
|
ReadOnlyList.wrap(moduleUnit.barrels)));
|
||||||
}
|
}
|
||||||
moduleVisibilityValidator.validate(ReadOnlyList.wrap(modules), nameTable, diagnostics);
|
moduleVisibilityValidator.validate(ReadOnlyList.wrap(modules), nameTable, diagnostics);
|
||||||
markModulesWithLinkingErrors(diagnostics, moduleKeyByFile, failedModuleKeys);
|
markModulesWithLinkingErrors(diagnostics, moduleIdByFile, failedModuleIds);
|
||||||
final var moduleDependencyGraph = buildModuleDependencyGraph(parsedSourceFiles);
|
final var moduleDependencyGraph = buildModuleDependencyGraph(parsedSourceFiles, moduleTable);
|
||||||
|
|
||||||
final var compiledSourceFiles = new ArrayList<CompiledSourceFile>(parsedSourceFiles.size());
|
final var compiledSourceFiles = new ArrayList<CompiledSourceFile>(parsedSourceFiles.size());
|
||||||
for (final var parsedSource : parsedSourceFiles) {
|
for (final var parsedSource : parsedSourceFiles) {
|
||||||
final var blockedModuleKeys = blockedModulesByDependency(failedModuleKeys, moduleDependencyGraph);
|
final var blockedModuleIds = blockedModulesByDependency(failedModuleIds, moduleDependencyGraph);
|
||||||
if (blockedModuleKeys.contains(parsedSource.moduleKey())) {
|
if (blockedModuleIds.contains(parsedSource.moduleId())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final var compileErrorBaseline = diagnostics.errorCount();
|
final var compileErrorBaseline = diagnostics.errorCount();
|
||||||
@ -149,18 +154,18 @@ public class PBSFrontendPhaseService implements FrontendPhaseService {
|
|||||||
parsedSource.ast(),
|
parsedSource.ast(),
|
||||||
diagnostics,
|
diagnostics,
|
||||||
parsedSource.sourceKind(),
|
parsedSource.sourceKind(),
|
||||||
parsedSource.moduleKey(),
|
renderModuleKey(moduleTable, parsedSource.moduleId()),
|
||||||
ctx.hostAdmissionContext(),
|
ctx.hostAdmissionContext(),
|
||||||
nameTable);
|
nameTable);
|
||||||
if (diagnostics.errorCount() > compileErrorBaseline) {
|
if (diagnostics.errorCount() > compileErrorBaseline) {
|
||||||
failedModuleKeys.add(parsedSource.moduleKey());
|
failedModuleIds.add(parsedSource.moduleId());
|
||||||
}
|
}
|
||||||
compiledSourceFiles.add(new CompiledSourceFile(parsedSource.moduleKey(), irBackendFile));
|
compiledSourceFiles.add(new CompiledSourceFile(parsedSource.moduleId(), irBackendFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
final var blockedModuleKeys = blockedModulesByDependency(failedModuleKeys, moduleDependencyGraph);
|
final var blockedModuleIds = blockedModulesByDependency(failedModuleIds, moduleDependencyGraph);
|
||||||
for (final var compiledSource : compiledSourceFiles) {
|
for (final var compiledSource : compiledSourceFiles) {
|
||||||
if (blockedModuleKeys.contains(compiledSource.moduleKey())) {
|
if (blockedModuleIds.contains(compiledSource.moduleId())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
irBackendAggregator.merge(compiledSource.irBackendFile());
|
irBackendAggregator.merge(compiledSource.irBackendFile());
|
||||||
@ -174,18 +179,19 @@ public class PBSFrontendPhaseService implements FrontendPhaseService {
|
|||||||
private void loadReservedStdlibModules(
|
private void loadReservedStdlibModules(
|
||||||
final Map<PbsModuleVisibilityValidator.ModuleCoordinates, MutableModuleUnit> modulesByCoordinates,
|
final Map<PbsModuleVisibilityValidator.ModuleCoordinates, MutableModuleUnit> modulesByCoordinates,
|
||||||
final ArrayList<ParsedSourceFile> parsedSourceFiles,
|
final ArrayList<ParsedSourceFile> parsedSourceFiles,
|
||||||
final Map<FileId, String> moduleKeyByFile,
|
final Map<FileId, ModuleId> moduleIdByFile,
|
||||||
|
final ModuleTable moduleTable,
|
||||||
final DiagnosticSink diagnostics,
|
final DiagnosticSink diagnostics,
|
||||||
final int stdlibVersion) {
|
final int stdlibVersion) {
|
||||||
final var stdlibEnvironment = stdlibEnvironmentResolver.resolve(stdlibVersion);
|
final var stdlibEnvironment = stdlibEnvironmentResolver.resolve(stdlibVersion);
|
||||||
final var pending = new ArrayDeque<PbsModuleVisibilityValidator.ModuleCoordinates>();
|
final var pending = new ArrayDeque<PbsModuleVisibilityValidator.ModuleCoordinates>();
|
||||||
final var resolved = new HashSet<String>();
|
final var resolved = new HashSet<ModuleId>();
|
||||||
|
|
||||||
enqueueReservedImportsFromKnownModules(modulesByCoordinates, pending);
|
enqueueReservedImportsFromKnownModules(modulesByCoordinates, pending);
|
||||||
while (!pending.isEmpty()) {
|
while (!pending.isEmpty()) {
|
||||||
final var target = pending.removeFirst();
|
final var target = pending.removeFirst();
|
||||||
final var targetKey = moduleKey(target);
|
final var targetId = moduleId(moduleTable, target);
|
||||||
if (!resolved.add(targetKey)) {
|
if (!resolved.add(targetId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (modulesByCoordinates.containsKey(target)) {
|
if (modulesByCoordinates.containsKey(target)) {
|
||||||
@ -203,15 +209,15 @@ public class PBSFrontendPhaseService implements FrontendPhaseService {
|
|||||||
moduleData.barrels.addAll(loadedModule.barrelFiles().asList());
|
moduleData.barrels.addAll(loadedModule.barrelFiles().asList());
|
||||||
modulesByCoordinates.put(loadedModule.coordinates(), moduleData);
|
modulesByCoordinates.put(loadedModule.coordinates(), moduleData);
|
||||||
for (final var sourceFile : loadedModule.sourceFiles()) {
|
for (final var sourceFile : loadedModule.sourceFiles()) {
|
||||||
moduleKeyByFile.put(sourceFile.fileId(), targetKey);
|
moduleIdByFile.put(sourceFile.fileId(), targetId);
|
||||||
parsedSourceFiles.add(new ParsedSourceFile(
|
parsedSourceFiles.add(new ParsedSourceFile(
|
||||||
sourceFile.fileId(),
|
sourceFile.fileId(),
|
||||||
sourceFile.ast(),
|
sourceFile.ast(),
|
||||||
targetKey,
|
targetId,
|
||||||
SourceKind.SDK_INTERFACE));
|
SourceKind.SDK_INTERFACE));
|
||||||
}
|
}
|
||||||
for (final var barrelFile : loadedModule.barrelFiles()) {
|
for (final var barrelFile : loadedModule.barrelFiles()) {
|
||||||
moduleKeyByFile.put(barrelFile.fileId(), targetKey);
|
moduleIdByFile.put(barrelFile.fileId(), targetId);
|
||||||
}
|
}
|
||||||
enqueueReservedImportsFromSourceFiles(loadedModule.sourceFiles().asList(), pending);
|
enqueueReservedImportsFromSourceFiles(loadedModule.sourceFiles().asList(), pending);
|
||||||
}
|
}
|
||||||
@ -296,8 +302,8 @@ public class PBSFrontendPhaseService implements FrontendPhaseService {
|
|||||||
|
|
||||||
private void markModulesWithLinkingErrors(
|
private void markModulesWithLinkingErrors(
|
||||||
final DiagnosticSink diagnostics,
|
final DiagnosticSink diagnostics,
|
||||||
final Map<FileId, String> moduleKeyByFile,
|
final Map<FileId, ModuleId> moduleIdByFile,
|
||||||
final Set<String> failedModuleKeys) {
|
final Set<ModuleId> failedModuleIds) {
|
||||||
for (final var diagnostic : diagnostics) {
|
for (final var diagnostic : diagnostics) {
|
||||||
if (!diagnostic.getSeverity().isError()) {
|
if (!diagnostic.getSeverity().isError()) {
|
||||||
continue;
|
continue;
|
||||||
@ -305,32 +311,33 @@ public class PBSFrontendPhaseService implements FrontendPhaseService {
|
|||||||
if (diagnostic.getPhase() != DiagnosticPhase.LINKING) {
|
if (diagnostic.getPhase() != DiagnosticPhase.LINKING) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final var moduleKey = moduleKeyByFile.get(diagnostic.getSpan().getFileId());
|
final var moduleId = moduleIdByFile.get(diagnostic.getSpan().getFileId());
|
||||||
if (moduleKey != null) {
|
if (moduleId != null) {
|
||||||
failedModuleKeys.add(moduleKey);
|
failedModuleIds.add(moduleId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, Set<String>> buildModuleDependencyGraph(
|
private Map<ModuleId, Set<ModuleId>> buildModuleDependencyGraph(
|
||||||
final ArrayList<ParsedSourceFile> parsedSourceFiles) {
|
final ArrayList<ParsedSourceFile> parsedSourceFiles,
|
||||||
final Map<String, Set<String>> dependenciesByModule = new HashMap<>();
|
final ModuleTable moduleTable) {
|
||||||
|
final Map<ModuleId, Set<ModuleId>> dependenciesByModule = new HashMap<>();
|
||||||
for (final var parsedSource : parsedSourceFiles) {
|
for (final var parsedSource : parsedSourceFiles) {
|
||||||
final var moduleDependencies = dependenciesByModule.computeIfAbsent(
|
final var moduleDependencies = dependenciesByModule.computeIfAbsent(
|
||||||
parsedSource.moduleKey(),
|
parsedSource.moduleId(),
|
||||||
ignored -> new HashSet<>());
|
ignored -> new HashSet<>());
|
||||||
for (final var importDecl : parsedSource.ast().imports()) {
|
for (final var importDecl : parsedSource.ast().imports()) {
|
||||||
final var moduleRef = importDecl.moduleRef();
|
final var moduleRef = importDecl.moduleRef();
|
||||||
moduleDependencies.add(moduleKey(moduleRef.project(), moduleRef.pathSegments()));
|
moduleDependencies.add(moduleId(moduleTable, moduleRef.project(), moduleRef.pathSegments()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return dependenciesByModule;
|
return dependenciesByModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<String> blockedModulesByDependency(
|
private Set<ModuleId> blockedModulesByDependency(
|
||||||
final Set<String> failedModuleKeys,
|
final Set<ModuleId> failedModuleIds,
|
||||||
final Map<String, Set<String>> dependenciesByModule) {
|
final Map<ModuleId, Set<ModuleId>> dependenciesByModule) {
|
||||||
final Map<String, Set<String>> dependentsByModule = new HashMap<>();
|
final Map<ModuleId, Set<ModuleId>> dependentsByModule = new HashMap<>();
|
||||||
for (final var entry : dependenciesByModule.entrySet()) {
|
for (final var entry : dependenciesByModule.entrySet()) {
|
||||||
final var importer = entry.getKey();
|
final var importer = entry.getKey();
|
||||||
for (final var dependency : entry.getValue()) {
|
for (final var dependency : entry.getValue()) {
|
||||||
@ -338,8 +345,8 @@ public class PBSFrontendPhaseService implements FrontendPhaseService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final var blocked = new HashSet<String>(failedModuleKeys);
|
final var blocked = new HashSet<ModuleId>(failedModuleIds);
|
||||||
final var pending = new ArrayDeque<String>(failedModuleKeys);
|
final var pending = new ArrayDeque<ModuleId>(failedModuleIds);
|
||||||
while (!pending.isEmpty()) {
|
while (!pending.isEmpty()) {
|
||||||
final var failedOrBlocked = pending.removeFirst();
|
final var failedOrBlocked = pending.removeFirst();
|
||||||
final var dependents = dependentsByModule.getOrDefault(failedOrBlocked, Set.of());
|
final var dependents = dependentsByModule.getOrDefault(failedOrBlocked, Set.of());
|
||||||
@ -353,14 +360,24 @@ public class PBSFrontendPhaseService implements FrontendPhaseService {
|
|||||||
return blocked;
|
return blocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String moduleKey(final PbsModuleVisibilityValidator.ModuleCoordinates coordinates) {
|
private ModuleId moduleId(
|
||||||
return coordinates.project() + ":" + String.join("/", coordinates.pathSegments().asList());
|
final ModuleTable moduleTable,
|
||||||
|
final PbsModuleVisibilityValidator.ModuleCoordinates coordinates) {
|
||||||
|
return moduleId(moduleTable, coordinates.project(), coordinates.pathSegments());
|
||||||
}
|
}
|
||||||
|
|
||||||
private String moduleKey(
|
private ModuleId moduleId(
|
||||||
|
final ModuleTable moduleTable,
|
||||||
final String project,
|
final String project,
|
||||||
final ReadOnlyList<String> pathSegments) {
|
final ReadOnlyList<String> pathSegments) {
|
||||||
return project + ":" + String.join("/", pathSegments.asList());
|
return moduleTable.register(new ModuleReference(project, pathSegments));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String renderModuleKey(
|
||||||
|
final ModuleTable moduleTable,
|
||||||
|
final ModuleId moduleId) {
|
||||||
|
final var moduleReference = moduleTable.get(moduleId);
|
||||||
|
return moduleReference.project() + ":" + String.join("/", moduleReference.pathSegments().asList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class MutableModuleUnit {
|
private static final class MutableModuleUnit {
|
||||||
@ -371,12 +388,12 @@ public class PBSFrontendPhaseService implements FrontendPhaseService {
|
|||||||
private record ParsedSourceFile(
|
private record ParsedSourceFile(
|
||||||
FileId fileId,
|
FileId fileId,
|
||||||
PbsAst.File ast,
|
PbsAst.File ast,
|
||||||
String moduleKey,
|
ModuleId moduleId,
|
||||||
SourceKind sourceKind) {
|
SourceKind sourceKind) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private record CompiledSourceFile(
|
private record CompiledSourceFile(
|
||||||
String moduleKey,
|
ModuleId moduleId,
|
||||||
p.studio.compiler.models.IRBackendFile irBackendFile) {
|
p.studio.compiler.models.IRBackendFile irBackendFile) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,17 @@
|
|||||||
|
package p.studio.compiler.source.tables;
|
||||||
|
|
||||||
|
import p.studio.utilities.structures.ReadOnlyList;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public record ModuleReference(
|
||||||
|
String project,
|
||||||
|
ReadOnlyList<String> pathSegments) {
|
||||||
|
public ModuleReference {
|
||||||
|
project = Objects.requireNonNull(project, "project");
|
||||||
|
if (project.isBlank()) {
|
||||||
|
throw new IllegalArgumentException("project must not be blank");
|
||||||
|
}
|
||||||
|
pathSegments = pathSegments == null ? ReadOnlyList.empty() : pathSegments;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
package p.studio.compiler.source.tables;
|
||||||
|
|
||||||
|
import p.studio.compiler.source.identifiers.ModuleId;
|
||||||
|
|
||||||
|
public class ModuleTable extends InternTable<ModuleId, ModuleReference> {
|
||||||
|
|
||||||
|
public ModuleTable() {
|
||||||
|
super(ModuleId::new);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
package p.studio.compiler.source.tables;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import p.studio.utilities.structures.ReadOnlyList;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||||
|
|
||||||
|
class ModuleTableTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldInternSameReferenceWithStableId() {
|
||||||
|
final var table = new ModuleTable();
|
||||||
|
final var reference = new ModuleReference("core", ReadOnlyList.wrap(java.util.List.of("math", "vec")));
|
||||||
|
|
||||||
|
final var first = table.register(reference);
|
||||||
|
final var second = table.register(reference);
|
||||||
|
|
||||||
|
assertEquals(first, second);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldAllocateDifferentIdForDifferentReference() {
|
||||||
|
final var table = new ModuleTable();
|
||||||
|
|
||||||
|
final var first = table.register(new ModuleReference("core", ReadOnlyList.wrap(java.util.List.of("math"))));
|
||||||
|
final var second = table.register(new ModuleReference("core", ReadOnlyList.wrap(java.util.List.of("gfx"))));
|
||||||
|
|
||||||
|
assertNotEquals(first, second);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user