implements PR023
This commit is contained in:
parent
213c6a2f76
commit
57f1a617ac
@ -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<StdlibModuleSource> resolveModule(
|
||||
final String project,
|
||||
final ReadOnlyList<String> pathSegments) {
|
||||
return Optional.empty();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public StdlibEnvironment resolve(final int stdlibVersion) {
|
||||
return EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<PbsModuleVisibilityValidator.SourceFile>(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<PbsModuleVisibilityValidator.BarrelFile>(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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,10 @@
|
||||
package p.studio.compiler.pbs.stdlib;
|
||||
|
||||
import p.studio.utilities.structures.ReadOnlyList;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface StdlibEnvironment {
|
||||
Optional<StdlibModuleSource> resolveModule(String project, ReadOnlyList<String> pathSegments);
|
||||
}
|
||||
|
||||
@ -0,0 +1,6 @@
|
||||
package p.studio.compiler.pbs.stdlib;
|
||||
|
||||
public interface StdlibEnvironmentResolver {
|
||||
StdlibEnvironment resolve(int stdlibVersion);
|
||||
}
|
||||
|
||||
@ -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<String> pathSegments,
|
||||
ReadOnlyList<SourceFile> 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<PbsModuleVisibilityValidator.ModuleUnit>(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<PbsModuleVisibilityValidator.ModuleCoordinates, MutableModuleUnit> modulesByCoordinates,
|
||||
final DiagnosticSink diagnostics,
|
||||
final int stdlibVersion) {
|
||||
final var stdlibEnvironment = stdlibEnvironmentResolver.resolve(stdlibVersion);
|
||||
final var pending = new ArrayDeque<PbsModuleVisibilityValidator.ModuleCoordinates>();
|
||||
final var resolved = new HashSet<String>();
|
||||
|
||||
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<PbsModuleVisibilityValidator.ModuleCoordinates, MutableModuleUnit> modulesByCoordinates,
|
||||
final ArrayDeque<PbsModuleVisibilityValidator.ModuleCoordinates> pending) {
|
||||
for (final var moduleUnit : modulesByCoordinates.values()) {
|
||||
enqueueReservedImportsFromSourceFiles(moduleUnit.sources, pending);
|
||||
}
|
||||
}
|
||||
|
||||
private void enqueueReservedImportsFromSourceFiles(
|
||||
final Iterable<PbsModuleVisibilityValidator.SourceFile> sourceFiles,
|
||||
final ArrayDeque<PbsModuleVisibilityValidator.ModuleCoordinates> 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,
|
||||
|
||||
@ -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<String, StdlibModuleSource>();
|
||||
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<StdlibModuleSource> resolveModule(
|
||||
final String project,
|
||||
final ReadOnlyList<String> pathSegments) {
|
||||
return Optional.ofNullable(byModuleKey.get(moduleKey(project, pathSegments)));
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
private String moduleKey(
|
||||
final String project,
|
||||
final ReadOnlyList<String> pathSegments) {
|
||||
return project + ":" + String.join("/", pathSegments.asList());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ class PrometeuManifestUtilsTest {
|
||||
Path tempDir;
|
||||
|
||||
@Test
|
||||
void buildManifestParsesStdlibMajor() throws IOException {
|
||||
void buildManifestParsesStdlib() throws IOException {
|
||||
final var manifestPath = writeManifest("""
|
||||
{
|
||||
"name": "main",
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user