From 57f1a617ac275cf06aad4c88dbb476bc65c2acaf Mon Sep 17 00:00:00 2001 From: bQUARKz Date: Fri, 6 Mar 2026 11:45:47 +0000 Subject: [PATCH] implements PR023 --- .../EmptyStdlibEnvironmentResolver.java | 22 +++ .../pbs/stdlib/InterfaceModuleLoader.java | 63 ++++++++ .../pbs/stdlib/StdlibEnvironment.java | 10 ++ .../pbs/stdlib/StdlibEnvironmentResolver.java | 6 + .../pbs/stdlib/StdlibModuleSource.java | 29 ++++ .../services/PBSFrontendPhaseService.java | 80 ++++++++++ .../services/PBSFrontendPhaseServiceTest.java | 140 ++++++++++++++++++ .../stages/FrontendPhasePipelineStage.java | 6 +- .../compiler/models/DependencyContext.java | 2 +- .../compiler/models/ResolvedWorkspace.java | 2 +- .../utilities/PrometeuManifestUtils.java | 22 +-- .../utilities/PrometeuManifestUtilsTest.java | 2 +- .../messages/FrontendPhaseContext.java | 14 ++ 13 files changed, 383 insertions(+), 15 deletions(-) create mode 100644 prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/stdlib/EmptyStdlibEnvironmentResolver.java create mode 100644 prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/stdlib/InterfaceModuleLoader.java create mode 100644 prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/stdlib/StdlibEnvironment.java create mode 100644 prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/stdlib/StdlibEnvironmentResolver.java create mode 100644 prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/stdlib/StdlibModuleSource.java diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/stdlib/EmptyStdlibEnvironmentResolver.java b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/stdlib/EmptyStdlibEnvironmentResolver.java new file mode 100644 index 00000000..9b1d97cb --- /dev/null +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/stdlib/EmptyStdlibEnvironmentResolver.java @@ -0,0 +1,22 @@ +package p.studio.compiler.pbs.stdlib; + +import p.studio.utilities.structures.ReadOnlyList; + +import java.util.Optional; + +public final class EmptyStdlibEnvironmentResolver implements StdlibEnvironmentResolver { + private static final StdlibEnvironment EMPTY = new StdlibEnvironment() { + @Override + public Optional resolveModule( + final String project, + final ReadOnlyList pathSegments) { + return Optional.empty(); + } + }; + + @Override + public StdlibEnvironment resolve(final int stdlibVersion) { + return EMPTY; + } +} + diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/stdlib/InterfaceModuleLoader.java b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/stdlib/InterfaceModuleLoader.java new file mode 100644 index 00000000..40fe6b0a --- /dev/null +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/stdlib/InterfaceModuleLoader.java @@ -0,0 +1,63 @@ +package p.studio.compiler.pbs.stdlib; + +import p.studio.compiler.pbs.ast.PbsAst; +import p.studio.compiler.pbs.lexer.PbsLexer; +import p.studio.compiler.pbs.linking.PbsModuleVisibilityValidator; +import p.studio.compiler.pbs.parser.PbsBarrelParser; +import p.studio.compiler.pbs.parser.PbsParser; +import p.studio.compiler.source.diagnostics.DiagnosticSink; +import p.studio.compiler.source.identifiers.FileId; +import p.studio.utilities.structures.ReadOnlyList; + +import java.util.ArrayList; +import java.util.concurrent.atomic.AtomicInteger; + +public final class InterfaceModuleLoader { + private final AtomicInteger nextSyntheticFileId; + + public InterfaceModuleLoader() { + this(1_000_000); + } + + public InterfaceModuleLoader(final int firstSyntheticFileId) { + this.nextSyntheticFileId = new AtomicInteger(firstSyntheticFileId); + } + + public PbsModuleVisibilityValidator.ModuleUnit load( + final StdlibModuleSource moduleSource, + final DiagnosticSink diagnostics) { + final var sources = new ArrayList(moduleSource.sourceFiles().size()); + for (final var sourceFile : moduleSource.sourceFiles()) { + final var fileId = new FileId(nextSyntheticFileId.getAndIncrement()); + final var sourceAst = parseSource(sourceFile.source(), fileId, diagnostics); + sources.add(new PbsModuleVisibilityValidator.SourceFile(fileId, sourceAst)); + } + + final var barrels = new ArrayList(1); + final var barrelFileId = new FileId(nextSyntheticFileId.getAndIncrement()); + final var barrelAst = parseBarrel(moduleSource.barrelSource(), barrelFileId, diagnostics); + barrels.add(new PbsModuleVisibilityValidator.BarrelFile(barrelFileId, barrelAst)); + + return new PbsModuleVisibilityValidator.ModuleUnit( + new PbsModuleVisibilityValidator.ModuleCoordinates(moduleSource.project(), moduleSource.pathSegments()), + ReadOnlyList.wrap(sources), + ReadOnlyList.wrap(barrels)); + } + + private PbsAst.File parseSource( + final String source, + final FileId fileId, + final DiagnosticSink diagnostics) { + final var tokens = PbsLexer.lex(source, fileId, diagnostics); + return PbsParser.parse(tokens, fileId, diagnostics); + } + + private PbsAst.BarrelFile parseBarrel( + final String source, + final FileId fileId, + final DiagnosticSink diagnostics) { + final var tokens = PbsLexer.lex(source, fileId, diagnostics); + return PbsBarrelParser.parse(tokens, fileId, diagnostics); + } +} + diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/stdlib/StdlibEnvironment.java b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/stdlib/StdlibEnvironment.java new file mode 100644 index 00000000..88c72513 --- /dev/null +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/stdlib/StdlibEnvironment.java @@ -0,0 +1,10 @@ +package p.studio.compiler.pbs.stdlib; + +import p.studio.utilities.structures.ReadOnlyList; + +import java.util.Optional; + +public interface StdlibEnvironment { + Optional resolveModule(String project, ReadOnlyList pathSegments); +} + diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/stdlib/StdlibEnvironmentResolver.java b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/stdlib/StdlibEnvironmentResolver.java new file mode 100644 index 00000000..ff040bf0 --- /dev/null +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/stdlib/StdlibEnvironmentResolver.java @@ -0,0 +1,6 @@ +package p.studio.compiler.pbs.stdlib; + +public interface StdlibEnvironmentResolver { + StdlibEnvironment resolve(int stdlibVersion); +} + diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/stdlib/StdlibModuleSource.java b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/stdlib/StdlibModuleSource.java new file mode 100644 index 00000000..50ac0d59 --- /dev/null +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/stdlib/StdlibModuleSource.java @@ -0,0 +1,29 @@ +package p.studio.compiler.pbs.stdlib; + +import p.studio.utilities.structures.ReadOnlyList; + +import java.util.Objects; + +public record StdlibModuleSource( + String project, + ReadOnlyList pathSegments, + ReadOnlyList sourceFiles, + String barrelSource) { + + public StdlibModuleSource { + project = Objects.requireNonNull(project, "project"); + pathSegments = pathSegments == null ? ReadOnlyList.empty() : pathSegments; + sourceFiles = sourceFiles == null ? ReadOnlyList.empty() : sourceFiles; + barrelSource = Objects.requireNonNull(barrelSource, "barrelSource"); + } + + public record SourceFile( + String logicalPath, + String source) { + public SourceFile { + logicalPath = Objects.requireNonNull(logicalPath, "logicalPath"); + source = Objects.requireNonNull(source, "source"); + } + } +} + diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/services/PBSFrontendPhaseService.java b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/services/PBSFrontendPhaseService.java index 92c1de3f..ea0d2e1f 100644 --- a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/services/PBSFrontendPhaseService.java +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/services/PBSFrontendPhaseService.java @@ -14,6 +14,9 @@ import p.studio.compiler.pbs.linking.PbsLinkErrors; import p.studio.compiler.pbs.linking.PbsModuleVisibilityValidator; import p.studio.compiler.pbs.parser.PbsBarrelParser; import p.studio.compiler.pbs.parser.PbsParser; +import p.studio.compiler.pbs.stdlib.EmptyStdlibEnvironmentResolver; +import p.studio.compiler.pbs.stdlib.InterfaceModuleLoader; +import p.studio.compiler.pbs.stdlib.StdlibEnvironmentResolver; import p.studio.compiler.source.Span; import p.studio.compiler.source.diagnostics.DiagnosticSink; import p.studio.compiler.source.diagnostics.DiagnosticPhase; @@ -23,6 +26,7 @@ import p.studio.utilities.logs.LogAggregator; import java.nio.charset.StandardCharsets; import java.nio.file.Path; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -34,6 +38,19 @@ import java.util.Set; public class PBSFrontendPhaseService implements FrontendPhaseService { private final PbsFrontendCompiler frontendCompiler = new PbsFrontendCompiler(); private final PbsModuleVisibilityValidator moduleVisibilityValidator = new PbsModuleVisibilityValidator(); + private final StdlibEnvironmentResolver stdlibEnvironmentResolver; + private final InterfaceModuleLoader interfaceModuleLoader; + + public PBSFrontendPhaseService() { + this(new EmptyStdlibEnvironmentResolver(), new InterfaceModuleLoader()); + } + + PBSFrontendPhaseService( + final StdlibEnvironmentResolver stdlibEnvironmentResolver, + final InterfaceModuleLoader interfaceModuleLoader) { + this.stdlibEnvironmentResolver = stdlibEnvironmentResolver; + this.interfaceModuleLoader = interfaceModuleLoader; + } @Override public IRBackend compile( @@ -99,6 +116,8 @@ public class PBSFrontendPhaseService implements FrontendPhaseService { } } + loadReservedStdlibModules(modulesByCoordinates, diagnostics, ctx.stdlibVersion()); + final var modules = new ArrayList(modulesByCoordinates.size()); for (final var entry : modulesByCoordinates.entrySet()) { final var coordinates = entry.getKey(); @@ -127,6 +146,67 @@ public class PBSFrontendPhaseService implements FrontendPhaseService { return irBackend; } + private void loadReservedStdlibModules( + final Map modulesByCoordinates, + final DiagnosticSink diagnostics, + final int stdlibVersion) { + final var stdlibEnvironment = stdlibEnvironmentResolver.resolve(stdlibVersion); + final var pending = new ArrayDeque(); + final var resolved = new HashSet(); + + enqueueReservedImportsFromKnownModules(modulesByCoordinates, pending); + while (!pending.isEmpty()) { + final var target = pending.removeFirst(); + final var targetKey = moduleKey(target); + if (!resolved.add(targetKey)) { + continue; + } + if (modulesByCoordinates.containsKey(target)) { + continue; + } + + final var moduleSource = stdlibEnvironment.resolveModule(target.project(), target.pathSegments()); + if (moduleSource.isEmpty()) { + continue; + } + + final var loadedModule = interfaceModuleLoader.load(moduleSource.get(), diagnostics); + final var moduleData = new MutableModuleUnit(); + moduleData.sources.addAll(loadedModule.sourceFiles().asList()); + moduleData.barrels.addAll(loadedModule.barrelFiles().asList()); + modulesByCoordinates.put(loadedModule.coordinates(), moduleData); + enqueueReservedImportsFromSourceFiles(loadedModule.sourceFiles().asList(), pending); + } + } + + private void enqueueReservedImportsFromKnownModules( + final Map modulesByCoordinates, + final ArrayDeque pending) { + for (final var moduleUnit : modulesByCoordinates.values()) { + enqueueReservedImportsFromSourceFiles(moduleUnit.sources, pending); + } + } + + private void enqueueReservedImportsFromSourceFiles( + final Iterable sourceFiles, + final ArrayDeque pending) { + for (final var source : sourceFiles) { + for (final var importDecl : source.ast().imports()) { + final var moduleRef = importDecl.moduleRef(); + if (!isReservedProjectSpace(moduleRef.project())) { + continue; + } + pending.addLast(new PbsModuleVisibilityValidator.ModuleCoordinates( + moduleRef.project(), + moduleRef.pathSegments())); + } + } + } + + private boolean isReservedProjectSpace(final String projectName) { + return "core".equals(projectName) || "sdk".equals(projectName); + } + private PbsAst.File parseSourceFile( final FileId fileId, final String source, diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/test/java/p/studio/compiler/services/PBSFrontendPhaseServiceTest.java b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/test/java/p/studio/compiler/services/PBSFrontendPhaseServiceTest.java index aceab3dd..ec8b2b23 100644 --- a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/test/java/p/studio/compiler/services/PBSFrontendPhaseServiceTest.java +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/test/java/p/studio/compiler/services/PBSFrontendPhaseServiceTest.java @@ -8,6 +8,10 @@ import p.studio.compiler.models.BuildStack; import p.studio.compiler.models.ProjectDescriptor; import p.studio.compiler.models.SourceHandle; import p.studio.compiler.models.SourceKind; +import p.studio.compiler.pbs.stdlib.InterfaceModuleLoader; +import p.studio.compiler.pbs.stdlib.StdlibEnvironment; +import p.studio.compiler.pbs.stdlib.StdlibEnvironmentResolver; +import p.studio.compiler.pbs.stdlib.StdlibModuleSource; import p.studio.compiler.pbs.linking.PbsLinkErrors; import p.studio.compiler.source.diagnostics.DiagnosticSink; import p.studio.compiler.source.identifiers.ProjectId; @@ -21,7 +25,10 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.attribute.BasicFileAttributes; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Optional; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -216,6 +223,111 @@ class PBSFrontendPhaseServiceTest { assertEquals(0, irBackend.getFunctions().size()); } + @Test + void shouldResolveReservedImportsThroughStdlibResolverForSelectedMajor() throws IOException { + final var projectRoot = tempDir.resolve("project-stdlib"); + final var sourceRoot = projectRoot.resolve("src"); + final var modulePath = sourceRoot.resolve("app"); + Files.createDirectories(modulePath); + + final var sourceFile = modulePath.resolve("source.pbs"); + final var modBarrel = modulePath.resolve("mod.barrel"); + Files.writeString(sourceFile, """ + import { draw } from @sdk:gfx; + fn use() -> int { return 1; } + """); + Files.writeString(modBarrel, "pub fn use() -> int;"); + + final var projectTable = new ProjectTable(); + final var fileTable = new FileTable(1); + final var projectId = projectTable.register(ProjectDescriptor.builder() + .rootPath(projectRoot) + .name("app") + .version("1.0.0") + .sourceRoots(ReadOnlyList.wrap(List.of(sourceRoot))) + .build()); + + registerFile(projectId, projectRoot, sourceFile, fileTable); + registerFile(projectId, projectRoot, modBarrel, fileTable); + + final var stdlibModule = new StdlibModuleSource( + "sdk", + ReadOnlyList.wrap(List.of("gfx")), + ReadOnlyList.wrap(List.of(new StdlibModuleSource.SourceFile("gfx.pbs", "fn draw() -> int { return 1; }"))), + "pub fn draw() -> int;"); + final var frontendService = new PBSFrontendPhaseService( + resolverForMajor(7, stdlibModule), + new InterfaceModuleLoader(2_000_000)); + + final var ctx = new FrontendPhaseContext( + projectTable, + fileTable, + new BuildStack(ReadOnlyList.wrap(List.of(projectId))), + 7); + final var diagnostics = DiagnosticSink.empty(); + + final var irBackend = frontendService.compile( + ctx, + diagnostics, + LogAggregator.empty(), + BuildingIssueSink.empty()); + + assertTrue(diagnostics.stream().noneMatch(d -> + d.getCode().equals(PbsLinkErrors.E_LINK_IMPORT_MODULE_NOT_FOUND.name()))); + assertTrue(diagnostics.stream().noneMatch(d -> + d.getCode().equals(PbsLinkErrors.E_LINK_IMPORT_SYMBOL_UNRESOLVED.name()))); + assertEquals(1, irBackend.getFunctions().size()); + assertEquals("use", irBackend.getFunctions().getFirst().name()); + } + + @Test + void shouldReportReservedImportModuleNotFoundWhenStdlibResolverMissesModule() throws IOException { + final var projectRoot = tempDir.resolve("project-stdlib-missing"); + final var sourceRoot = projectRoot.resolve("src"); + final var modulePath = sourceRoot.resolve("app"); + Files.createDirectories(modulePath); + + final var sourceFile = modulePath.resolve("source.pbs"); + final var modBarrel = modulePath.resolve("mod.barrel"); + Files.writeString(sourceFile, """ + import { draw } from @sdk:gfx; + fn use() -> int { return 1; } + """); + Files.writeString(modBarrel, "pub fn use() -> int;"); + + final var projectTable = new ProjectTable(); + final var fileTable = new FileTable(1); + final var projectId = projectTable.register(ProjectDescriptor.builder() + .rootPath(projectRoot) + .name("app") + .version("1.0.0") + .sourceRoots(ReadOnlyList.wrap(List.of(sourceRoot))) + .build()); + + registerFile(projectId, projectRoot, sourceFile, fileTable); + registerFile(projectId, projectRoot, modBarrel, fileTable); + + final var frontendService = new PBSFrontendPhaseService( + resolverForMajor(7), + new InterfaceModuleLoader(2_100_000)); + final var ctx = new FrontendPhaseContext( + projectTable, + fileTable, + new BuildStack(ReadOnlyList.wrap(List.of(projectId))), + 7); + final var diagnostics = DiagnosticSink.empty(); + + final var irBackend = frontendService.compile( + ctx, + diagnostics, + LogAggregator.empty(), + BuildingIssueSink.empty()); + + assertTrue(diagnostics.stream().anyMatch(d -> + d.getCode().equals(PbsLinkErrors.E_LINK_IMPORT_MODULE_NOT_FOUND.name()))); + assertEquals(0, irBackend.getFunctions().size()); + } + private void registerFile( final ProjectId projectId, final Path projectRoot, @@ -231,4 +343,32 @@ class PBSFrontendPhaseServiceTest { SourceProviderFactory.filesystem())); } + private StdlibEnvironmentResolver resolverForMajor( + final int acceptedStdlib, + final StdlibModuleSource... modules) { + final var byModuleKey = new HashMap(); + for (final var module : modules) { + byModuleKey.put(moduleKey(module.project(), module.pathSegments()), module); + } + return stdlib -> { + if (stdlib != acceptedStdlib) { + return (project, pathSegments) -> Optional.empty(); + } + return new StdlibEnvironment() { + @Override + public Optional resolveModule( + final String project, + final ReadOnlyList pathSegments) { + return Optional.ofNullable(byModuleKey.get(moduleKey(project, pathSegments))); + } + }; + }; + } + + private String moduleKey( + final String project, + final ReadOnlyList pathSegments) { + return project + ":" + String.join("/", pathSegments.asList()); + } + } diff --git a/prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/workspaces/stages/FrontendPhasePipelineStage.java b/prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/workspaces/stages/FrontendPhasePipelineStage.java index 53676a59..2814053a 100644 --- a/prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/workspaces/stages/FrontendPhasePipelineStage.java +++ b/prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/workspaces/stages/FrontendPhasePipelineStage.java @@ -23,7 +23,11 @@ public class FrontendPhasePipelineStage implements PipelineStage { } final var projectTable = ctx.resolvedWorkspace.graph().projectTable(); final var fileTable = ctx.fileTable; - final var frontendPhaseContext = new FrontendPhaseContext(projectTable, fileTable, ctx.resolvedWorkspace.stack()); + final var frontendPhaseContext = new FrontendPhaseContext( + projectTable, + fileTable, + ctx.resolvedWorkspace.stack(), + ctx.resolvedWorkspace.stdlib()); final var diagnostics = DiagnosticSink.empty(); final var issues = BuildingIssueSink.empty(); ctx.irBackend = service.get().compile(frontendPhaseContext, diagnostics, logs, issues); diff --git a/prometeu-compiler/prometeu-deps/src/main/java/p/studio/compiler/models/DependencyContext.java b/prometeu-compiler/prometeu-deps/src/main/java/p/studio/compiler/models/DependencyContext.java index e7e8b8c9..b9133192 100644 --- a/prometeu-compiler/prometeu-deps/src/main/java/p/studio/compiler/models/DependencyContext.java +++ b/prometeu-compiler/prometeu-deps/src/main/java/p/studio/compiler/models/DependencyContext.java @@ -47,7 +47,7 @@ public final class DependencyContext { throw new BuildException("dependenciesByProjectId: internal error: rootProjectId ProjectId not set"); } if (rootStdlib == null) { - throw new BuildException("dependenciesByProjectId: internal error: rootStdlibMajor not set"); + throw new BuildException("dependenciesByProjectId: internal error: rootStdlib not set"); } final var dependenciesByProject = buildDependenciesByProject(); final var workspaceGraph = new WorkspaceGraph(projectTable, dependenciesByProject); diff --git a/prometeu-compiler/prometeu-deps/src/main/java/p/studio/compiler/models/ResolvedWorkspace.java b/prometeu-compiler/prometeu-deps/src/main/java/p/studio/compiler/models/ResolvedWorkspace.java index cebc926a..5842057b 100644 --- a/prometeu-compiler/prometeu-deps/src/main/java/p/studio/compiler/models/ResolvedWorkspace.java +++ b/prometeu-compiler/prometeu-deps/src/main/java/p/studio/compiler/models/ResolvedWorkspace.java @@ -5,7 +5,7 @@ import p.studio.compiler.source.identifiers.ProjectId; public record ResolvedWorkspace( ProjectId mainProjectId, FrontendSpec frontendSpec, - int stdlibMajor, + int stdlib, WorkspaceGraph graph, BuildStack stack) { public ProjectDescriptor mainProject() { diff --git a/prometeu-compiler/prometeu-deps/src/main/java/p/studio/compiler/utilities/PrometeuManifestUtils.java b/prometeu-compiler/prometeu-deps/src/main/java/p/studio/compiler/utilities/PrometeuManifestUtils.java index 7373804d..6bb00a29 100644 --- a/prometeu-compiler/prometeu-deps/src/main/java/p/studio/compiler/utilities/PrometeuManifestUtils.java +++ b/prometeu-compiler/prometeu-deps/src/main/java/p/studio/compiler/utilities/PrometeuManifestUtils.java @@ -45,7 +45,7 @@ public final class PrometeuManifestUtils { .error(true) .message("[DEPS]: manifest missing 'version': " + manifestPathCanon)); } - final var stdlibMajorMaybe = parseStdlibMajor(dto.stdlib(), manifestPathCanon, issuesLocal); + final var stdlibMaybe = parseStdlib(dto.stdlib(), manifestPathCanon, issuesLocal); final var language = StringUtils.isBlank(dto.language()) ? FrontendRegistryService.getDefaultFrontendSpec().getLanguageId() : dto.language(); @@ -54,34 +54,34 @@ public final class PrometeuManifestUtils { issues.merge(issuesLocal); return Optional.empty(); } - return Optional.of(new PrometeuManifest(dto.name(), dto.version(), language, stdlibMajorMaybe.getAsInt(), ReadOnlyList.wrap(dependencies))); + return Optional.of(new PrometeuManifest(dto.name(), dto.version(), language, stdlibMaybe.getAsInt(), ReadOnlyList.wrap(dependencies))); } - private static OptionalInt parseStdlibMajor( - final String stdlib, + private static OptionalInt parseStdlib( + final String stdlibStr, final Path manifestPathCanon, final BuildingIssueSink issues) { - if (StringUtils.isBlank(stdlib)) { + if (StringUtils.isBlank(stdlibStr)) { issues.report(builder -> builder .error(true) .message("[DEPS]: manifest missing 'stdlib': " + manifestPathCanon)); return OptionalInt.empty(); } - final int stdlibMajor; + final int stdlib; try { - stdlibMajor = Integer.parseInt(stdlib); + stdlib = Integer.parseInt(stdlibStr); } catch (NumberFormatException e) { issues.report(builder -> builder .error(true) - .message("[DEPS]: invalid 'stdlib' major version \"" + stdlib + "\": " + manifestPathCanon)); + .message("[DEPS]: invalid 'stdlib' major version \"" + stdlibStr + "\": " + manifestPathCanon)); return OptionalInt.empty(); } - if (stdlibMajor <= 0 || !stdlib.equals(Integer.toString(stdlibMajor))) { + if (stdlib <= 0 || !stdlibStr.equals(Integer.toString(stdlib))) { issues.report(builder -> builder .error(true) - .message("[DEPS]: invalid 'stdlib' major version \"" + stdlib + "\": " + manifestPathCanon)); + .message("[DEPS]: invalid 'stdlib' major version \"" + stdlibStr + "\": " + manifestPathCanon)); return OptionalInt.empty(); } - return OptionalInt.of(stdlibMajor); + return OptionalInt.of(stdlib); } } diff --git a/prometeu-compiler/prometeu-deps/src/test/java/p/studio/compiler/utilities/PrometeuManifestUtilsTest.java b/prometeu-compiler/prometeu-deps/src/test/java/p/studio/compiler/utilities/PrometeuManifestUtilsTest.java index df0ef5e8..4c1a2a3d 100644 --- a/prometeu-compiler/prometeu-deps/src/test/java/p/studio/compiler/utilities/PrometeuManifestUtilsTest.java +++ b/prometeu-compiler/prometeu-deps/src/test/java/p/studio/compiler/utilities/PrometeuManifestUtilsTest.java @@ -16,7 +16,7 @@ class PrometeuManifestUtilsTest { Path tempDir; @Test - void buildManifestParsesStdlibMajor() throws IOException { + void buildManifestParsesStdlib() throws IOException { final var manifestPath = writeManifest(""" { "name": "main", diff --git a/prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/messages/FrontendPhaseContext.java b/prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/messages/FrontendPhaseContext.java index e69617b1..7c4e9c62 100644 --- a/prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/messages/FrontendPhaseContext.java +++ b/prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/messages/FrontendPhaseContext.java @@ -10,17 +10,31 @@ public class FrontendPhaseContext { public final ProjectTableReader projectTable; public final FileTableReader fileTable; public final BuildStack stack; + private final int stdlibVersion; public FrontendPhaseContext( final ProjectTableReader projectTable, final FileTableReader fileTable, final BuildStack stack) { + this(projectTable, fileTable, stack, 1); + } + + public FrontendPhaseContext( + final ProjectTableReader projectTable, + final FileTableReader fileTable, + final BuildStack stack, + final int stdlibVersion) { this.projectTable = projectTable; this.fileTable = fileTable; this.stack = stack; + this.stdlibVersion = stdlibVersion; } public SourceKind sourceKind(final ProjectId projectId) { return projectTable.sourceKind(projectId); } + + public int stdlibVersion() { + return stdlibVersion; + } }