implements PR020
This commit is contained in:
parent
eb469fd68c
commit
d2287a0a58
@ -21,17 +21,26 @@ public final class PbsFrontendCompiler {
|
|||||||
final FileId fileId,
|
final FileId fileId,
|
||||||
final String source,
|
final String source,
|
||||||
final DiagnosticSink diagnostics) {
|
final DiagnosticSink diagnostics) {
|
||||||
|
final var admissionBaseline = diagnostics.errorCount();
|
||||||
final var tokens = PbsLexer.lex(source, fileId, diagnostics);
|
final var tokens = PbsLexer.lex(source, fileId, diagnostics);
|
||||||
final var ast = PbsParser.parse(tokens, fileId, diagnostics);
|
final var ast = PbsParser.parse(tokens, fileId, diagnostics);
|
||||||
return compileParsedFile(fileId, ast, diagnostics);
|
final var irBackendFile = compileParsedFile(fileId, ast, diagnostics);
|
||||||
|
if (diagnostics.errorCount() > admissionBaseline) {
|
||||||
|
return IRBackendFile.empty(fileId);
|
||||||
|
}
|
||||||
|
return irBackendFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IRBackendFile compileParsedFile(
|
public IRBackendFile compileParsedFile(
|
||||||
final FileId fileId,
|
final FileId fileId,
|
||||||
final PbsAst.File ast,
|
final PbsAst.File ast,
|
||||||
final DiagnosticSink diagnostics) {
|
final DiagnosticSink diagnostics) {
|
||||||
|
final var semanticsErrorBaseline = diagnostics.errorCount();
|
||||||
declarationSemanticsValidator.validate(ast, diagnostics);
|
declarationSemanticsValidator.validate(ast, diagnostics);
|
||||||
flowSemanticsValidator.validate(ast, diagnostics);
|
flowSemanticsValidator.validate(ast, diagnostics);
|
||||||
|
if (diagnostics.errorCount() > semanticsErrorBaseline) {
|
||||||
|
return IRBackendFile.empty(fileId);
|
||||||
|
}
|
||||||
return new IRBackendFile(fileId, lowerFunctions(fileId, ast));
|
return new IRBackendFile(fileId, lowerFunctions(fileId, ast));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,7 @@ import p.studio.compiler.pbs.parser.PbsBarrelParser;
|
|||||||
import p.studio.compiler.pbs.parser.PbsParser;
|
import p.studio.compiler.pbs.parser.PbsParser;
|
||||||
import p.studio.compiler.source.Span;
|
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.identifiers.FileId;
|
import p.studio.compiler.source.identifiers.FileId;
|
||||||
import p.studio.utilities.structures.ReadOnlyList;
|
import p.studio.utilities.structures.ReadOnlyList;
|
||||||
import p.studio.utilities.logs.LogAggregator;
|
import p.studio.utilities.logs.LogAggregator;
|
||||||
@ -22,8 +23,11 @@ import p.studio.utilities.logs.LogAggregator;
|
|||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class PBSFrontendPhaseService implements FrontendPhaseService {
|
public class PBSFrontendPhaseService implements FrontendPhaseService {
|
||||||
@ -39,6 +43,8 @@ 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 failedModuleKeys = new HashSet<String>();
|
||||||
|
|
||||||
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);
|
||||||
@ -49,24 +55,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 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);
|
||||||
|
final var parseErrorBaseline = diagnostics.errorCount();
|
||||||
final var ast = parseSourceFile(fId, utf8Content, diagnostics);
|
final var ast = parseSourceFile(fId, utf8Content, diagnostics);
|
||||||
moduleUnit.sources.add(new PbsModuleVisibilityValidator.SourceFile(fId, ast));
|
moduleUnit.sources.add(new PbsModuleVisibilityValidator.SourceFile(fId, ast));
|
||||||
parsedSourceFiles.add(new ParsedSourceFile(fId, ast));
|
parsedSourceFiles.add(new ParsedSourceFile(fId, ast, moduleKey));
|
||||||
|
if (diagnostics.errorCount() > parseErrorBaseline) {
|
||||||
|
failedModuleKeys.add(moduleKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case "barrel" -> {
|
case "barrel" -> {
|
||||||
|
moduleKeyByFile.put(fId, moduleKey);
|
||||||
if ("mod.barrel".equals(sourceHandle.getFilename())) {
|
if ("mod.barrel".equals(sourceHandle.getFilename())) {
|
||||||
|
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) {
|
||||||
|
failedModuleKeys.add(moduleKey);
|
||||||
|
}
|
||||||
} 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default -> {
|
default -> {
|
||||||
@ -89,8 +107,12 @@ public class PBSFrontendPhaseService implements FrontendPhaseService {
|
|||||||
ReadOnlyList.wrap(moduleUnit.barrels)));
|
ReadOnlyList.wrap(moduleUnit.barrels)));
|
||||||
}
|
}
|
||||||
moduleVisibilityValidator.validate(ReadOnlyList.wrap(modules), diagnostics);
|
moduleVisibilityValidator.validate(ReadOnlyList.wrap(modules), diagnostics);
|
||||||
|
markModulesWithLinkingErrors(diagnostics, moduleKeyByFile, failedModuleKeys);
|
||||||
|
|
||||||
for (final var parsedSource : parsedSourceFiles) {
|
for (final var parsedSource : parsedSourceFiles) {
|
||||||
|
if (failedModuleKeys.contains(parsedSource.moduleKey())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
final var irBackendFile = frontendCompiler.compileParsedFile(parsedSource.fileId(), parsedSource.ast(), diagnostics);
|
final var irBackendFile = frontendCompiler.compileParsedFile(parsedSource.fileId(), parsedSource.ast(), diagnostics);
|
||||||
irBackendAggregator.merge(irBackendFile);
|
irBackendAggregator.merge(irBackendFile);
|
||||||
}
|
}
|
||||||
@ -145,6 +167,28 @@ public class PBSFrontendPhaseService implements FrontendPhaseService {
|
|||||||
return sourceHandle.getRelativePath();
|
return sourceHandle.getRelativePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void markModulesWithLinkingErrors(
|
||||||
|
final DiagnosticSink diagnostics,
|
||||||
|
final Map<FileId, String> moduleKeyByFile,
|
||||||
|
final Set<String> failedModuleKeys) {
|
||||||
|
for (final var diagnostic : diagnostics) {
|
||||||
|
if (!diagnostic.getSeverity().isError()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (diagnostic.getPhase() != DiagnosticPhase.LINKING) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final var moduleKey = moduleKeyByFile.get(diagnostic.getSpan().getFileId());
|
||||||
|
if (moduleKey != null) {
|
||||||
|
failedModuleKeys.add(moduleKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String moduleKey(final PbsModuleVisibilityValidator.ModuleCoordinates coordinates) {
|
||||||
|
return coordinates.project() + ":" + String.join("/", coordinates.pathSegments().asList());
|
||||||
|
}
|
||||||
|
|
||||||
private static final class MutableModuleUnit {
|
private static final class MutableModuleUnit {
|
||||||
private final ArrayList<PbsModuleVisibilityValidator.SourceFile> sources = new ArrayList<>();
|
private final ArrayList<PbsModuleVisibilityValidator.SourceFile> sources = new ArrayList<>();
|
||||||
private final ArrayList<PbsModuleVisibilityValidator.BarrelFile> barrels = new ArrayList<>();
|
private final ArrayList<PbsModuleVisibilityValidator.BarrelFile> barrels = new ArrayList<>();
|
||||||
@ -152,6 +196,7 @@ public class PBSFrontendPhaseService implements FrontendPhaseService {
|
|||||||
|
|
||||||
private record ParsedSourceFile(
|
private record ParsedSourceFile(
|
||||||
FileId fileId,
|
FileId fileId,
|
||||||
PbsAst.File ast) {
|
PbsAst.File ast,
|
||||||
|
String moduleKey) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package p.studio.compiler.pbs;
|
package p.studio.compiler.pbs;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import p.studio.compiler.pbs.lexer.LexErrors;
|
||||||
import p.studio.compiler.pbs.semantics.PbsSemanticsErrors;
|
import p.studio.compiler.pbs.semantics.PbsSemanticsErrors;
|
||||||
import p.studio.compiler.source.diagnostics.DiagnosticSink;
|
import p.studio.compiler.source.diagnostics.DiagnosticSink;
|
||||||
import p.studio.compiler.source.identifiers.FileId;
|
import p.studio.compiler.source.identifiers.FileId;
|
||||||
@ -44,10 +45,11 @@ class PbsFrontendCompilerTest {
|
|||||||
|
|
||||||
final var diagnostics = DiagnosticSink.empty();
|
final var diagnostics = DiagnosticSink.empty();
|
||||||
final var compiler = new PbsFrontendCompiler();
|
final var compiler = new PbsFrontendCompiler();
|
||||||
compiler.compileFile(new FileId(0), source, diagnostics);
|
final var fileBackend = compiler.compileFile(new FileId(0), source, diagnostics);
|
||||||
|
|
||||||
assertTrue(diagnostics.stream().anyMatch(d ->
|
assertTrue(diagnostics.stream().anyMatch(d ->
|
||||||
d.getCode().equals(PbsSemanticsErrors.E_SEM_DUPLICATE_CALLABLE_SHAPE.name())));
|
d.getCode().equals(PbsSemanticsErrors.E_SEM_DUPLICATE_CALLABLE_SHAPE.name())));
|
||||||
|
assertEquals(0, fileBackend.functions().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -59,9 +61,42 @@ class PbsFrontendCompilerTest {
|
|||||||
|
|
||||||
final var diagnostics = DiagnosticSink.empty();
|
final var diagnostics = DiagnosticSink.empty();
|
||||||
final var compiler = new PbsFrontendCompiler();
|
final var compiler = new PbsFrontendCompiler();
|
||||||
compiler.compileFile(new FileId(0), source, diagnostics);
|
final var fileBackend = compiler.compileFile(new FileId(0), source, diagnostics);
|
||||||
|
|
||||||
assertTrue(diagnostics.stream().noneMatch(d ->
|
assertTrue(diagnostics.stream().noneMatch(d ->
|
||||||
d.getCode().equals(PbsSemanticsErrors.E_SEM_DUPLICATE_CALLABLE_SHAPE.name())));
|
d.getCode().equals(PbsSemanticsErrors.E_SEM_DUPLICATE_CALLABLE_SHAPE.name())));
|
||||||
|
assertEquals(2, fileBackend.functions().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldNotLowerWhenSyntaxErrorsExist() {
|
||||||
|
final var source = """
|
||||||
|
$
|
||||||
|
fn run() -> int { return 1; }
|
||||||
|
""";
|
||||||
|
|
||||||
|
final var diagnostics = DiagnosticSink.empty();
|
||||||
|
final var compiler = new PbsFrontendCompiler();
|
||||||
|
final var fileBackend = compiler.compileFile(new FileId(0), source, diagnostics);
|
||||||
|
|
||||||
|
assertTrue(diagnostics.stream().anyMatch(d ->
|
||||||
|
d.getCode().equals(LexErrors.E_LEX_INVALID_CHAR.name())));
|
||||||
|
assertEquals(0, fileBackend.functions().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldNotLowerWhenStaticSemanticsErrorsExist() {
|
||||||
|
final var source = """
|
||||||
|
fn run(x: int) -> int { return x; }
|
||||||
|
fn run(y: int) -> int { return y; }
|
||||||
|
""";
|
||||||
|
|
||||||
|
final var diagnostics = DiagnosticSink.empty();
|
||||||
|
final var compiler = new PbsFrontendCompiler();
|
||||||
|
final var fileBackend = compiler.compileFile(new FileId(0), source, diagnostics);
|
||||||
|
|
||||||
|
assertTrue(diagnostics.stream().anyMatch(d ->
|
||||||
|
d.getCode().equals(PbsSemanticsErrors.E_SEM_DUPLICATE_CALLABLE_SHAPE.name())));
|
||||||
|
assertEquals(0, fileBackend.functions().size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,7 @@ import java.nio.file.Path;
|
|||||||
import java.nio.file.attribute.BasicFileAttributes;
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
class PBSFrontendPhaseServiceTest {
|
class PBSFrontendPhaseServiceTest {
|
||||||
@ -61,13 +62,115 @@ class PBSFrontendPhaseServiceTest {
|
|||||||
new BuildStack(ReadOnlyList.wrap(List.of(projectId))));
|
new BuildStack(ReadOnlyList.wrap(List.of(projectId))));
|
||||||
final var diagnostics = DiagnosticSink.empty();
|
final var diagnostics = DiagnosticSink.empty();
|
||||||
|
|
||||||
new PBSFrontendPhaseService().compile(
|
final var irBackend = new PBSFrontendPhaseService().compile(
|
||||||
ctx,
|
ctx,
|
||||||
diagnostics,
|
diagnostics,
|
||||||
LogAggregator.empty(),
|
LogAggregator.empty(),
|
||||||
BuildingIssueSink.empty());
|
BuildingIssueSink.empty());
|
||||||
|
|
||||||
assertTrue(diagnostics.stream().anyMatch(d -> d.getCode().equals(PbsLinkErrors.E_LINK_INVALID_BARREL_FILENAME.name())));
|
assertTrue(diagnostics.stream().anyMatch(d -> d.getCode().equals(PbsLinkErrors.E_LINK_INVALID_BARREL_FILENAME.name())));
|
||||||
|
assertEquals(0, irBackend.getFunctions().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldLowerOnlyModulesThatPassAdmissionGates() throws IOException {
|
||||||
|
final var projectRoot = tempDir.resolve("project-mixed");
|
||||||
|
final var sourceRoot = projectRoot.resolve("src");
|
||||||
|
final var validModulePath = sourceRoot.resolve("valid");
|
||||||
|
final var invalidModulePath = sourceRoot.resolve("invalid");
|
||||||
|
Files.createDirectories(validModulePath);
|
||||||
|
Files.createDirectories(invalidModulePath);
|
||||||
|
|
||||||
|
final var validSource = validModulePath.resolve("source.pbs");
|
||||||
|
final var validBarrel = validModulePath.resolve("mod.barrel");
|
||||||
|
final var invalidSource = invalidModulePath.resolve("source.pbs");
|
||||||
|
Files.writeString(validSource, """
|
||||||
|
fn good(v: int) -> int {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
""");
|
||||||
|
Files.writeString(validBarrel, "pub fn good(v: int) -> int;");
|
||||||
|
Files.writeString(invalidSource, """
|
||||||
|
fn bad(v: int) -> int {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
""");
|
||||||
|
|
||||||
|
final var projectTable = new ProjectTable();
|
||||||
|
final var fileTable = new FileTable(1);
|
||||||
|
final var projectId = projectTable.register(ProjectDescriptor.builder()
|
||||||
|
.rootPath(projectRoot)
|
||||||
|
.name("core")
|
||||||
|
.version("1.0.0")
|
||||||
|
.sourceRoots(ReadOnlyList.wrap(List.of(sourceRoot)))
|
||||||
|
.build());
|
||||||
|
|
||||||
|
registerFile(projectId, projectRoot, validSource, fileTable);
|
||||||
|
registerFile(projectId, projectRoot, validBarrel, fileTable);
|
||||||
|
registerFile(projectId, projectRoot, invalidSource, fileTable);
|
||||||
|
|
||||||
|
final var ctx = new FrontendPhaseContext(
|
||||||
|
projectTable,
|
||||||
|
fileTable,
|
||||||
|
new BuildStack(ReadOnlyList.wrap(List.of(projectId))));
|
||||||
|
final var diagnostics = DiagnosticSink.empty();
|
||||||
|
|
||||||
|
final var irBackend = new PBSFrontendPhaseService().compile(
|
||||||
|
ctx,
|
||||||
|
diagnostics,
|
||||||
|
LogAggregator.empty(),
|
||||||
|
BuildingIssueSink.empty());
|
||||||
|
|
||||||
|
assertTrue(diagnostics.stream().anyMatch(d ->
|
||||||
|
d.getCode().equals(PbsLinkErrors.E_LINK_MISSING_BARREL.name())));
|
||||||
|
assertEquals(1, irBackend.getFunctions().size());
|
||||||
|
assertEquals("good", irBackend.getFunctions().getFirst().name());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldLowerAllSourcesWhenNoAdmissionErrorsExist() throws IOException {
|
||||||
|
final var projectRoot = tempDir.resolve("project-valid");
|
||||||
|
final var sourceRoot = projectRoot.resolve("src");
|
||||||
|
final var modulePath = sourceRoot.resolve("math");
|
||||||
|
Files.createDirectories(modulePath);
|
||||||
|
|
||||||
|
final var sourceFile = modulePath.resolve("source.pbs");
|
||||||
|
final var modBarrel = modulePath.resolve("mod.barrel");
|
||||||
|
Files.writeString(sourceFile, """
|
||||||
|
fn run() -> int { return 1; }
|
||||||
|
fn sum(a: int, b: int) -> int { return a + b; }
|
||||||
|
""");
|
||||||
|
Files.writeString(modBarrel, """
|
||||||
|
pub fn run() -> int;
|
||||||
|
pub fn sum(a: int, b: int) -> int;
|
||||||
|
""");
|
||||||
|
|
||||||
|
final var projectTable = new ProjectTable();
|
||||||
|
final var fileTable = new FileTable(1);
|
||||||
|
final var projectId = projectTable.register(ProjectDescriptor.builder()
|
||||||
|
.rootPath(projectRoot)
|
||||||
|
.name("core")
|
||||||
|
.version("1.0.0")
|
||||||
|
.sourceRoots(ReadOnlyList.wrap(List.of(sourceRoot)))
|
||||||
|
.build());
|
||||||
|
|
||||||
|
registerFile(projectId, projectRoot, sourceFile, fileTable);
|
||||||
|
registerFile(projectId, projectRoot, modBarrel, fileTable);
|
||||||
|
|
||||||
|
final var ctx = new FrontendPhaseContext(
|
||||||
|
projectTable,
|
||||||
|
fileTable,
|
||||||
|
new BuildStack(ReadOnlyList.wrap(List.of(projectId))));
|
||||||
|
final var diagnostics = DiagnosticSink.empty();
|
||||||
|
|
||||||
|
final var irBackend = new PBSFrontendPhaseService().compile(
|
||||||
|
ctx,
|
||||||
|
diagnostics,
|
||||||
|
LogAggregator.empty(),
|
||||||
|
BuildingIssueSink.empty());
|
||||||
|
|
||||||
|
assertTrue(diagnostics.isEmpty());
|
||||||
|
assertEquals(2, irBackend.getFunctions().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerFile(
|
private void registerFile(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user