Skip to content

Commit 65db113

Browse files
committed
Rejig RAM directory naming, add ability to dump tree view of workspaces
1 parent b114517 commit 65db113

File tree

4 files changed

+107
-16
lines changed

4 files changed

+107
-16
lines changed

java-compiler-testing/src/main/java/io/github/ascopes/jct/workspaces/Workspace.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import io.github.ascopes.jct.filemanagers.JctFileManager;
1919
import io.github.ascopes.jct.filemanagers.ModuleLocation;
20+
import java.io.IOException;
2021
import java.io.UncheckedIOException;
2122
import java.nio.file.Path;
2223
import java.util.List;
@@ -109,6 +110,17 @@ public interface Workspace extends AutoCloseable {
109110
@Override
110111
void close();
111112

113+
/**
114+
* Dump a visual representation of this workspace to the given appendable.
115+
*
116+
* <p>This provides a utility method for debugging.
117+
*
118+
* @param appendable the appendable to write to.
119+
* @throws UncheckedIOException if an IO error occurs when writing to the appendable.
120+
* @since 5.0.0
121+
*/
122+
void dump(Appendable appendable);
123+
112124
/**
113125
* Determine if the workspace is closed or not.
114126
*

java-compiler-testing/src/main/java/io/github/ascopes/jct/workspaces/impl/RamDirectoryImpl.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,10 @@ public static RamDirectoryImpl newRamDirectory(String name) {
8585
assertValidRootName(name);
8686

8787
// MemoryFileSystem needs unique FS names to work correctly, so use a UUID to enforce this.
88-
89-
var uniqueName = name + "-" + UUID.randomUUID();
90-
var fileSystem = MemoryFileSystemProvider.getInstance().createFileSystem(uniqueName);
91-
var path = fileSystem.getRootDirectories().iterator().next().resolve(uniqueName);
88+
var fileSystem = MemoryFileSystemProvider.getInstance()
89+
.createFileSystem(UUID.randomUUID().toString());
90+
var path = fileSystem.getRootDirectories().iterator().next()
91+
.resolve(name);
9292

9393
// Ensure the base directory exists.
9494
uncheckedIo(() -> Files.createDirectories(path));

java-compiler-testing/src/main/java/io/github/ascopes/jct/workspaces/impl/WorkspaceImpl.java

Lines changed: 87 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,18 @@
2020

2121
import io.github.ascopes.jct.ex.JctIllegalInputException;
2222
import io.github.ascopes.jct.filemanagers.ModuleLocation;
23+
import io.github.ascopes.jct.utils.IoExceptionUtils;
24+
import io.github.ascopes.jct.utils.ToStringBuilder;
2325
import io.github.ascopes.jct.workspaces.ManagedDirectory;
2426
import io.github.ascopes.jct.workspaces.PathRoot;
2527
import io.github.ascopes.jct.workspaces.PathStrategy;
2628
import io.github.ascopes.jct.workspaces.Workspace;
29+
import java.io.IOException;
30+
import java.nio.file.FileVisitResult;
2731
import java.nio.file.Files;
2832
import java.nio.file.Path;
33+
import java.nio.file.SimpleFileVisitor;
34+
import java.nio.file.attribute.BasicFileAttributes;
2935
import java.util.ArrayList;
3036
import java.util.HashMap;
3137
import java.util.List;
@@ -47,18 +53,20 @@
4753
public final class WorkspaceImpl implements Workspace {
4854

4955
private volatile boolean closed;
56+
private final String id;
5057
private final PathStrategy pathStrategy;
51-
private final Map<Location, List<PathRoot>> paths;
58+
private final Map<Location, List<PathRoot>> locations;
5259

5360
/**
5461
* Initialise this workspace.
5562
*
5663
* @param pathStrategy the path strategy to use for creating source and target paths.
5764
*/
5865
public WorkspaceImpl(PathStrategy pathStrategy) {
66+
id = UUID.randomUUID().toString();
5967
closed = false;
6068
this.pathStrategy = requireNonNull(pathStrategy, "pathStrategy");
61-
paths = new HashMap<>();
69+
locations = new HashMap<>();
6270
}
6371

6472
@Override
@@ -67,7 +75,7 @@ public void close() {
6775
// Close everything in a best-effort fashion.
6876
var exceptions = new ArrayList<Throwable>();
6977

70-
for (var list : paths.values()) {
78+
for (var list : locations.values()) {
7179
for (var path : list) {
7280
if (path instanceof AbstractManagedDirectory dir) {
7381
try {
@@ -90,6 +98,64 @@ public void close() {
9098
}
9199
}
92100

101+
@Override
102+
public void dump(Appendable appendable) {
103+
IoExceptionUtils.uncheckedIo(() -> {
104+
appendable.append(toString()).append("\n");
105+
for (var location : locations.keySet().stream().sorted().toList()) {
106+
appendable.append(" Location ").append(location.toString()).append(": \n");
107+
108+
for (var pathRoot : locations.get(location)) {
109+
appendable.append(" - ").append(pathRoot.getUri().toString()).append(" contents:\n");
110+
111+
var baseIndent = 8;
112+
var basePath = pathRoot.getPath();
113+
114+
Files.walkFileTree(basePath, new SimpleFileVisitor<>() {
115+
private int indent = 0;
116+
117+
@Override
118+
public FileVisitResult preVisitDirectory(
119+
Path dir,
120+
BasicFileAttributes attrs
121+
) throws IOException {
122+
if (!dir.equals(basePath)) {
123+
appendIndent();
124+
appendable.append(dir.getFileName().toString()).append("/\n");
125+
indent += 2;
126+
}
127+
128+
return FileVisitResult.CONTINUE;
129+
}
130+
131+
@Override
132+
public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
133+
indent -= 2;
134+
return FileVisitResult.CONTINUE;
135+
}
136+
137+
@Override
138+
public FileVisitResult visitFile(
139+
Path file,
140+
BasicFileAttributes attrs
141+
) throws IOException {
142+
appendIndent();
143+
appendable.append(file.getFileName().toString()).append("\n");
144+
return FileVisitResult.CONTINUE;
145+
}
146+
147+
private void appendIndent() throws IOException {
148+
appendable.append(" ".repeat(baseIndent))
149+
.append("·".repeat(indent));
150+
}
151+
});
152+
}
153+
154+
appendable.append("\n");
155+
}
156+
});
157+
}
158+
93159
@Override
94160
public boolean isClosed() {
95161
return closed;
@@ -109,7 +175,7 @@ public void addPackage(Location location, Path path) {
109175
}
110176

111177
var dir = new WrappingDirectoryImpl(path);
112-
paths.computeIfAbsent(location, unused -> new ArrayList<>()).add(dir);
178+
locations.computeIfAbsent(location, unused -> new ArrayList<>()).add(dir);
113179
}
114180

115181
@Override
@@ -139,13 +205,12 @@ public ManagedDirectory createPackage(Location location) {
139205
throw new JctIllegalInputException("Location must not be module-oriented");
140206
}
141207

142-
// Needs to be unique, and JIMFS cannot hold a file system name containing stuff like
143-
// underscores.
208+
// Needs to be unique.
144209
var fsName = location.getName().replaceAll("[^A-Za-z0-9]", "")
145210
+ UUID.randomUUID();
146211

147212
var dir = pathStrategy.newInstance(fsName);
148-
paths.computeIfAbsent(location, unused -> new ArrayList<>()).add(dir);
213+
locations.computeIfAbsent(location, unused -> new ArrayList<>()).add(dir);
149214
return dir;
150215
}
151216

@@ -170,9 +235,9 @@ public ManagedDirectory createModule(Location location, String moduleName) {
170235
@Override
171236
public Map<Location, List<? extends PathRoot>> getAllPaths() {
172237
// Create an immutable copy.
173-
var pathsCopy = new HashMap<Location, List<PathRoot>>();
174-
paths.forEach((location, list) -> pathsCopy.put(location, List.copyOf(list)));
175-
return unmodifiableMap(pathsCopy);
238+
var locationsCopy = new HashMap<Location, List<PathRoot>>();
239+
locations.forEach((location, list) -> locationsCopy.put(location, List.copyOf(list)));
240+
return unmodifiableMap(locationsCopy);
176241
}
177242

178243
@Override
@@ -205,7 +270,7 @@ public Map<String, List<? extends PathRoot>> getModules(Location location) {
205270

206271
var results = new HashMap<String, List<PathRoot>>();
207272

208-
paths.forEach((pathLocation, pathRoots) -> {
273+
locations.forEach((pathLocation, pathRoots) -> {
209274
if (pathLocation instanceof ModuleLocation modulePathLocation) {
210275
if (modulePathLocation.getParent().equals(location)) {
211276
results.computeIfAbsent(modulePathLocation.getModuleName(), name -> new ArrayList<>())
@@ -233,9 +298,19 @@ public List<? extends PathRoot> getPackages(Location location) {
233298
);
234299
}
235300

236-
var roots = paths.get(location);
301+
var roots = locations.get(location);
237302
return roots == null
238303
? List.of()
239304
: List.copyOf(roots);
240305
}
306+
307+
@Override
308+
public String toString() {
309+
return new ToStringBuilder(this)
310+
.attribute("id", id)
311+
.attribute("pathStrategy", pathStrategy)
312+
.attribute("closed", closed)
313+
.attribute("numberOfLocations", locations.size())
314+
.toString();
315+
}
241316
}

java-compiler-testing/src/test/java/io/github/ascopes/jct/integration/compilation/BasicModuleCompilationIntegrationTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ void helloWorldRamDisk(JctCompiler compiler) {
4848
assertThatCompilation(compilation)
4949
.isSuccessfulWithoutWarnings();
5050

51+
workspace.dump(System.out);
52+
5153
assertThatCompilation(compilation)
5254
.classOutputPackages()
5355
.fileExists("com", "example", "HelloWorld.class")
@@ -72,6 +74,8 @@ void helloWorldUsingTempDirectory(JctCompiler compiler) {
7274
// When
7375
var compilation = compiler.compile(workspace);
7476

77+
workspace.dump(System.out);
78+
7579
// Then
7680
assertThatCompilation(compilation)
7781
.isSuccessfulWithoutWarnings();

0 commit comments

Comments
 (0)