added Load into compiler pipeline
This commit is contained in:
parent
7b15aebef2
commit
f627914c9f
@ -8,7 +8,7 @@ javafx-controls = { group = "org.openjfx", name = "javafx-controls", version.ref
|
|||||||
javafx-fxml = { group = "org.openjfx", name = "javafx-fxml", version.ref = "javafx" }
|
javafx-fxml = { group = "org.openjfx", name = "javafx-fxml", version.ref = "javafx" }
|
||||||
richtextfx = { group = "org.fxmisc.richtext", name = "richtextfx", version.ref = "richtextfx" }
|
richtextfx = { group = "org.fxmisc.richtext", name = "richtextfx", version.ref = "richtextfx" }
|
||||||
jackson-databind = { group = "com.fasterxml.jackson.core", name = "jackson-databind", version.ref = "jackson" }
|
jackson-databind = { group = "com.fasterxml.jackson.core", name = "jackson-databind", version.ref = "jackson" }
|
||||||
apache-commons-lang3 = { group = "org.apache.commons", name = "commons-lang3", version = "3.13.0" }
|
apache-commons-lang3 = { group = "org.apache.commons", name = "commons-lang3", version = "3.18.0" }
|
||||||
apache-commons-io = { group = "commons-io", name = "commons-io", version = "2.13.0" }
|
apache-commons-io = { group = "commons-io", name = "commons-io", version = "2.13.0" }
|
||||||
apache-commons-collections = { group = "org.apache.commons", name = "commons-collections4", version = "4.4" }
|
apache-commons-collections = { group = "org.apache.commons", name = "commons-collections4", version = "4.4" }
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@ public class PBSDefinitions {
|
|||||||
public static final FrontendSpec PBS = FrontendSpec
|
public static final FrontendSpec PBS = FrontendSpec
|
||||||
.builder()
|
.builder()
|
||||||
.languageId("pbs")
|
.languageId("pbs")
|
||||||
.allowedExtensions(ReadOnlySet.from("pbs"))
|
.allowedExtensions(ReadOnlySet.from("pbs", "barrel"))
|
||||||
.sourceRoots(ReadOnlySet.from("src"))
|
.sourceRoots(ReadOnlySet.from("src"))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,18 +1,28 @@
|
|||||||
package p.studio.compiler.models;
|
package p.studio.compiler.models;
|
||||||
|
|
||||||
import p.studio.compiler.messages.BuilderPipelineConfig;
|
import p.studio.compiler.messages.BuilderPipelineConfig;
|
||||||
|
import p.studio.compiler.source.tables.FileTable;
|
||||||
|
import p.studio.compiler.utilities.SourceProviderFactory;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
public class BuilderPipelineContext {
|
public class BuilderPipelineContext {
|
||||||
public final BuilderPipelineConfig config;
|
public final BuilderPipelineConfig config;
|
||||||
|
public final SourceProviderFactory sourceProviderFactory;
|
||||||
|
|
||||||
|
public Path rootProjectPathCanon;
|
||||||
public ResolvedWorkspace resolvedWorkspace;
|
public ResolvedWorkspace resolvedWorkspace;
|
||||||
|
|
||||||
|
public final FileTable fileTable = new FileTable();
|
||||||
|
|
||||||
private BuilderPipelineContext(
|
private BuilderPipelineContext(
|
||||||
final BuilderPipelineConfig config) {
|
final BuilderPipelineConfig config,
|
||||||
|
final SourceProviderFactory factory) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
this.sourceProviderFactory = factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BuilderPipelineContext basedOn(BuilderPipelineConfig config) {
|
public static BuilderPipelineContext compilerContext(final BuilderPipelineConfig config) {
|
||||||
return new BuilderPipelineContext(config);
|
return new BuilderPipelineContext(config, SourceProviderFactory.filesystem());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import p.studio.compiler.exceptions.BuildException;
|
import p.studio.compiler.exceptions.BuildException;
|
||||||
import p.studio.compiler.messages.BuilderPipelineConfig;
|
import p.studio.compiler.messages.BuilderPipelineConfig;
|
||||||
import p.studio.compiler.models.BuilderPipelineContext;
|
import p.studio.compiler.models.BuilderPipelineContext;
|
||||||
|
import p.studio.compiler.workspaces.stages.LoadPipelineStage;
|
||||||
import p.studio.compiler.workspaces.stages.ResolvePipelineStage;
|
import p.studio.compiler.workspaces.stages.ResolvePipelineStage;
|
||||||
import p.studio.utilities.logs.LogAggregator;
|
import p.studio.utilities.logs.LogAggregator;
|
||||||
import p.studio.utilities.structures.ReadOnlyCollection;
|
import p.studio.utilities.structures.ReadOnlyCollection;
|
||||||
@ -16,7 +17,8 @@ public class BuilderPipelineService {
|
|||||||
|
|
||||||
static {
|
static {
|
||||||
final var stages = List.<PipelineStage>of(
|
final var stages = List.<PipelineStage>of(
|
||||||
new ResolvePipelineStage()
|
new ResolvePipelineStage(),
|
||||||
|
new LoadPipelineStage()
|
||||||
);
|
);
|
||||||
INSTANCE = new BuilderPipelineService(stages);
|
INSTANCE = new BuilderPipelineService(stages);
|
||||||
}
|
}
|
||||||
@ -30,7 +32,7 @@ public class BuilderPipelineService {
|
|||||||
public void run(
|
public void run(
|
||||||
final BuilderPipelineConfig config,
|
final BuilderPipelineConfig config,
|
||||||
final LogAggregator logs) {
|
final LogAggregator logs) {
|
||||||
final var ctx = BuilderPipelineContext.basedOn(config);
|
final var ctx = BuilderPipelineContext.compilerContext(config);
|
||||||
|
|
||||||
for (final var builderPipelineStage : stages) {
|
for (final var builderPipelineStage : stages) {
|
||||||
final var issues = builderPipelineStage.run(ctx, logs);
|
final var issues = builderPipelineStage.run(ctx, logs);
|
||||||
|
|||||||
@ -0,0 +1,145 @@
|
|||||||
|
package p.studio.compiler.workspaces.stages;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.io.FilenameUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import p.studio.compiler.messages.BuildingIssues;
|
||||||
|
import p.studio.compiler.models.BuilderPipelineContext;
|
||||||
|
import p.studio.compiler.models.SourceHandle;
|
||||||
|
import p.studio.compiler.workspaces.PipelineStage;
|
||||||
|
import p.studio.utilities.logs.LogAggregator;
|
||||||
|
import p.studio.utilities.structures.ReadOnlySet;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.FileVisitResult;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.SimpleFileVisitor;
|
||||||
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class LoadPipelineStage implements PipelineStage {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BuildingIssues run(final BuilderPipelineContext ctx, final LogAggregator logs) {
|
||||||
|
final var issues = BuildingIssues.empty();
|
||||||
|
|
||||||
|
// Iterates projects; "loads sources"; registers files
|
||||||
|
ctx.resolvedWorkspace.topologicalOrder().forEach(pId -> {
|
||||||
|
final var pd = ctx.resolvedWorkspace.graph().projectTable().get(pId);
|
||||||
|
logs.using(log).info("Project [ " + pd.getName() + " ] source loading...");
|
||||||
|
|
||||||
|
final var allowedExtensions = normalize(pd.getFrontendSpec().getAllowedExtensions());
|
||||||
|
for (final var sourceRootPath : pd.getSourceRoots()) {
|
||||||
|
logs.using(log).debug("Walking source root [ " + sourceRootPath + " ]");
|
||||||
|
|
||||||
|
try {
|
||||||
|
final List<Path> paths = new ArrayList<>();
|
||||||
|
Files.walkFileTree(sourceRootPath, new SourceCrawler(allowedExtensions, paths));
|
||||||
|
paths.sort(Path::compareTo);
|
||||||
|
for (var path : paths) {
|
||||||
|
logs.using(log).debug("file tabling [ " + path + " ]");
|
||||||
|
final var attributes = Files.readAttributes(path, BasicFileAttributes.class);
|
||||||
|
final var size = attributes.size();
|
||||||
|
final var lastModified = attributes.lastModifiedTime().toMillis();
|
||||||
|
final var rawFile = new SourceHandle(pId, path, size, lastModified, ctx.sourceProviderFactory);
|
||||||
|
// register in dense tables
|
||||||
|
var fileId = ctx.fileTable.register(rawFile);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
issues.add(builder -> builder
|
||||||
|
.error(true)
|
||||||
|
.message("Failed to load project [ " + pd.getName() + " ]")
|
||||||
|
.exception(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return BuildingIssues.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlySet<String> normalize(final ReadOnlySet<String> extensions) {
|
||||||
|
return ReadOnlySet
|
||||||
|
.wrap(extensions
|
||||||
|
.map(String::toLowerCase)
|
||||||
|
.map(s -> s.startsWith(".") ? s.substring(1) : s)
|
||||||
|
.collect(Collectors.toSet()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class SourceCrawler extends SimpleFileVisitor<Path> {
|
||||||
|
|
||||||
|
private static final Set<String> IGNORED_DIRS = Set.of(
|
||||||
|
".git",
|
||||||
|
".prometeu",
|
||||||
|
".workspace",
|
||||||
|
"target",
|
||||||
|
"build",
|
||||||
|
"out",
|
||||||
|
"node_modules"
|
||||||
|
);
|
||||||
|
|
||||||
|
private final ReadOnlySet<String> allowedExtensions;
|
||||||
|
private final List<Path> paths;
|
||||||
|
|
||||||
|
public SourceCrawler(
|
||||||
|
final ReadOnlySet<String> allowedExtensions,
|
||||||
|
final List<Path> paths) {
|
||||||
|
this.allowedExtensions = allowedExtensions;
|
||||||
|
this.paths = paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileVisitResult preVisitDirectory(final Path path, final BasicFileAttributes attrs) {
|
||||||
|
for (final var directory : path) {
|
||||||
|
if (!isAllowedPath(directory)) {
|
||||||
|
return FileVisitResult.SKIP_SUBTREE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileVisitResult visitFile(final Path path, final BasicFileAttributes attrs) {
|
||||||
|
if (!attrs.isRegularFile()) {
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasAllowedExt(path, allowedExtensions)) {
|
||||||
|
paths.add(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isAllowedPath(
|
||||||
|
final Path path) {
|
||||||
|
for (Path part : path) {
|
||||||
|
if (IGNORED_DIRS.contains(part.toString())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean hasAllowedExt(
|
||||||
|
final Path path,
|
||||||
|
final ReadOnlySet<String> allowedExtensions) {
|
||||||
|
|
||||||
|
final var fileName = path.getFileName();
|
||||||
|
if (Objects.isNull(fileName)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final var extension = FilenameUtils.getExtension(fileName.toString()).toLowerCase();
|
||||||
|
if (StringUtils.isBlank(extension)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return allowedExtensions.contains(extension);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -9,16 +9,14 @@ import p.studio.compiler.workspaces.PipelineStage;
|
|||||||
import p.studio.utilities.logs.LogAggregator;
|
import p.studio.utilities.logs.LogAggregator;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class ResolvePipelineStage implements PipelineStage {
|
public class ResolvePipelineStage implements PipelineStage {
|
||||||
@Override
|
@Override
|
||||||
public BuildingIssues run(final BuilderPipelineContext ctx, LogAggregator logs) {
|
public BuildingIssues run(final BuilderPipelineContext ctx, LogAggregator logs) {
|
||||||
final Path rootCanonPath;
|
|
||||||
try {
|
try {
|
||||||
rootCanonPath = Paths.get(ctx.config.rootProjectPath()).toRealPath();
|
ctx.rootProjectPathCanon = Paths.get(ctx.config.rootProjectPath()).toRealPath();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
return BuildingIssues.empty()
|
return BuildingIssues.empty()
|
||||||
.add(builder -> builder
|
.add(builder -> builder
|
||||||
@ -26,9 +24,8 @@ public class ResolvePipelineStage implements PipelineStage {
|
|||||||
.message("[BUILD]: root project directory no found: " + ctx.config.rootProjectPath())
|
.message("[BUILD]: root project directory no found: " + ctx.config.rootProjectPath())
|
||||||
.exception(e));
|
.exception(e));
|
||||||
}
|
}
|
||||||
final var dependencyConfig = new DependencyConfig(ctx.config.explain(), rootCanonPath);
|
final var dependencyConfig = new DependencyConfig(ctx.config.explain(), ctx.rootProjectPathCanon);
|
||||||
ctx.resolvedWorkspace = DependencyService.INSTANCE.run(dependencyConfig, logs);
|
ctx.resolvedWorkspace = DependencyService.INSTANCE.run(dependencyConfig, logs);
|
||||||
ctx.resolvedWorkspace.topologicalOrder().forEach(pd -> logs.using(log).info("Project [ " + pd.getName() + " ] read"));
|
|
||||||
return BuildingIssues.empty();
|
return BuildingIssues.empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,9 +9,9 @@ import java.nio.file.Path;
|
|||||||
@Builder
|
@Builder
|
||||||
@Getter
|
@Getter
|
||||||
public final class ProjectDescriptor {
|
public final class ProjectDescriptor {
|
||||||
private final Path rootPath;
|
private final Path rootPath; // canon root path
|
||||||
private final String name;
|
private final String name; // project name
|
||||||
private final String version;
|
private final String version; // project version
|
||||||
private final ReadOnlyList<Path> sourceRoots;
|
private final ReadOnlyList<Path> sourceRoots;
|
||||||
private final FrontendSpec frontendSpec;
|
private final FrontendSpec frontendSpec;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,49 @@
|
|||||||
|
package p.studio.compiler.models;
|
||||||
|
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
import p.studio.compiler.source.identifiers.ProjectId;
|
||||||
|
import p.studio.compiler.utilities.SourceProvider;
|
||||||
|
import p.studio.compiler.utilities.SourceProviderFactory;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||||
|
public class SourceHandle {
|
||||||
|
@Getter
|
||||||
|
private final ProjectId projectId;
|
||||||
|
@EqualsAndHashCode.Include
|
||||||
|
@Getter
|
||||||
|
private final Path path; // canon path to file
|
||||||
|
@Getter
|
||||||
|
private final String filename;
|
||||||
|
@Getter
|
||||||
|
private final long size;
|
||||||
|
@Getter
|
||||||
|
private final long lastModified;
|
||||||
|
private final SourceProvider provider;
|
||||||
|
|
||||||
|
public SourceHandle(
|
||||||
|
final ProjectId projectId,
|
||||||
|
final Path path,
|
||||||
|
final long size,
|
||||||
|
final long lastModified,
|
||||||
|
final SourceProviderFactory factory) {
|
||||||
|
this.projectId = projectId;
|
||||||
|
this.path = path;
|
||||||
|
this.filename = path.getFileName().toString();
|
||||||
|
this.size = size;
|
||||||
|
this.lastModified = lastModified;
|
||||||
|
this.provider = factory.create(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] readBytes() throws IOException {
|
||||||
|
return provider.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String readUtf8() throws IOException {
|
||||||
|
return new String(readBytes(), StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,15 +0,0 @@
|
|||||||
package p.studio.compiler.source;
|
|
||||||
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Getter;
|
|
||||||
import p.studio.compiler.source.identifiers.ProjectId;
|
|
||||||
|
|
||||||
@Builder
|
|
||||||
@Getter
|
|
||||||
public class SourceFile {
|
|
||||||
private final ProjectId projectId;
|
|
||||||
private final String module;
|
|
||||||
private final String name;
|
|
||||||
private final String extension;
|
|
||||||
private final byte[] content;
|
|
||||||
}
|
|
||||||
@ -1,13 +1,14 @@
|
|||||||
package p.studio.compiler.source.tables;
|
package p.studio.compiler.source.tables;
|
||||||
|
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import p.studio.compiler.source.SourceFile;
|
import p.studio.compiler.models.SourceHandle;
|
||||||
import p.studio.compiler.source.identifiers.FileId;
|
import p.studio.compiler.source.identifiers.FileId;
|
||||||
import p.studio.compiler.source.identifiers.ProjectId;
|
import p.studio.compiler.source.identifiers.ProjectId;
|
||||||
|
import p.studio.utilities.structures.ReadOnlyList;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class FileTable extends InternTable<FileId, SourceFile> {
|
public class FileTable extends InternTable<FileId, SourceHandle> {
|
||||||
|
|
||||||
private final Map<ProjectId, Set<FileId>> projectFiles = new HashMap<>();
|
private final Map<ProjectId, Set<FileId>> projectFiles = new HashMap<>();
|
||||||
|
|
||||||
@ -16,17 +17,17 @@ public class FileTable extends InternTable<FileId, SourceFile> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FileId register(final SourceFile value) {
|
public FileId register(final SourceHandle value) {
|
||||||
final var fileId = super.register(value);
|
final var fileId = super.register(value);
|
||||||
projectFiles.computeIfAbsent(value.getProjectId(), ignored -> new HashSet<>()).add(fileId);
|
projectFiles.computeIfAbsent(value.getProjectId(), ignored -> new HashSet<>()).add(fileId);
|
||||||
return fileId;
|
return fileId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SourceFile> getSourceFiles(final ProjectId projectId) {
|
public ReadOnlyList<FileId> getFiles(final ProjectId projectId) {
|
||||||
final var fileIds = projectFiles.get(projectId);
|
final var fileIds = projectFiles.get(projectId);
|
||||||
if (CollectionUtils.isEmpty(fileIds)) {
|
if (CollectionUtils.isEmpty(fileIds)) {
|
||||||
return List.of();
|
return ReadOnlyList.empty();
|
||||||
}
|
}
|
||||||
return fileIds.stream().map(this::get).toList();
|
return ReadOnlyList.wrap(fileIds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
package p.studio.compiler.utilities;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface SourceProvider {
|
||||||
|
byte[] read() throws IOException;
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
package p.studio.compiler.utilities;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface SourceProviderFactory {
|
||||||
|
SourceProvider create(Path path);
|
||||||
|
|
||||||
|
static SourceProviderFactory filesystem() {
|
||||||
|
return path -> new SourceProvider() {
|
||||||
|
|
||||||
|
private volatile byte[] cachedBytes = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] read() throws IOException {
|
||||||
|
if (Objects.isNull(cachedBytes)) {
|
||||||
|
cachedBytes = Files.readAllBytes(path);
|
||||||
|
}
|
||||||
|
return cachedBytes;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// more providers can be added here, e.g., in-memory, etc.
|
||||||
|
}
|
||||||
@ -8,15 +8,16 @@ public record ResolvedWorkspace(
|
|||||||
ProjectId projectId,
|
ProjectId projectId,
|
||||||
WorkspaceGraph graph,
|
WorkspaceGraph graph,
|
||||||
BuildStack stack) {
|
BuildStack stack) {
|
||||||
|
|
||||||
public ProjectDescriptor mainProject() {
|
public ProjectDescriptor mainProject() {
|
||||||
return graph.projectDescriptor(projectId);
|
return graph.projectDescriptor(projectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Stream<ProjectDescriptor> topologicalOrder() {
|
public Stream<ProjectId> topologicalOrder() {
|
||||||
return stack.topologicalOrder.stream().map(graph::projectDescriptor);
|
return stack.topologicalOrder.stream();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Stream<ProjectDescriptor> reverseTopologicalOrder() {
|
public Stream<ProjectId> reverseTopologicalOrder() {
|
||||||
return stack.reverseTopologicalOrder.stream().map(graph::projectDescriptor);
|
return stack.reverseTopologicalOrder.stream();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,5 +5,6 @@ plugins {
|
|||||||
dependencies {
|
dependencies {
|
||||||
api(libs.jackson.databind)
|
api(libs.jackson.databind)
|
||||||
api(libs.apache.commons.lang3)
|
api(libs.apache.commons.lang3)
|
||||||
|
api(libs.apache.commons.io)
|
||||||
api(libs.apache.commons.collections)
|
api(libs.apache.commons.collections)
|
||||||
}
|
}
|
||||||
@ -1,7 +1,5 @@
|
|||||||
package p.studio.utilities.structures;
|
package p.studio.utilities.structures;
|
||||||
|
|
||||||
import org.apache.commons.collections4.ListUtils;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@ -23,8 +21,8 @@ public class ReadOnlyList<T> extends ReadOnlyCollection<T> {
|
|||||||
return ReadOnlyList.wrap(new ArrayList<>(c.collection));
|
return ReadOnlyList.wrap(new ArrayList<>(c.collection));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> ReadOnlyCollection<T> wrap(final Set<T> set) {
|
public static <T> ReadOnlyList<T> wrap(final Set<T> set) {
|
||||||
return new ReadOnlyCollection<>(List.copyOf(set));
|
return new ReadOnlyList<>(List.copyOf(set));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SafeVarargs
|
@SafeVarargs
|
||||||
|
|||||||
0
test-projects/main/src/main.pbs
Normal file
0
test-projects/main/src/main.pbs
Normal file
0
test-projects/main/src/module-a/mod.barrel
Normal file
0
test-projects/main/src/module-a/mod.barrel
Normal file
0
test-projects/main/src/module-a/source-1.pbs
Normal file
0
test-projects/main/src/module-a/source-1.pbs
Normal file
0
test-projects/main/src/module-a/source-2.pbs
Normal file
0
test-projects/main/src/module-a/source-2.pbs
Normal file
0
test-projects/main/src/module-a/source-3.pbs
Normal file
0
test-projects/main/src/module-a/source-3.pbs
Normal file
0
test-projects/main/src/module-b/mod.barrel
Normal file
0
test-projects/main/src/module-b/mod.barrel
Normal file
0
test-projects/main/src/module-b/source-1.pbs
Normal file
0
test-projects/main/src/module-b/source-1.pbs
Normal file
0
test-projects/main/src/module-b/source-2.pbs
Normal file
0
test-projects/main/src/module-b/source-2.pbs
Normal file
0
test-projects/main/src/module-b/source-3.pbs
Normal file
0
test-projects/main/src/module-b/source-3.pbs
Normal file
0
test-projects/main/src/module-c/mod.barrel
Normal file
0
test-projects/main/src/module-c/mod.barrel
Normal file
0
test-projects/main/src/module-c/source-1.pbs
Normal file
0
test-projects/main/src/module-c/source-1.pbs
Normal file
0
test-projects/main/src/module-c/source-2.pbs
Normal file
0
test-projects/main/src/module-c/source-2.pbs
Normal file
0
test-projects/main/src/module-c/source-3.pbs
Normal file
0
test-projects/main/src/module-c/source-3.pbs
Normal file
Loading…
x
Reference in New Issue
Block a user