Skip to content

Commit c702dca

Browse files
committedJan 24, 2024
8323815: Source launcher should find classes with $ in names
Reviewed-by: jlahoda, sundar
1 parent c432dc0 commit c702dca

File tree

2 files changed

+38
-8
lines changed

2 files changed

+38
-8
lines changed
 

‎src/jdk.compiler/share/classes/com/sun/tools/javac/launcher/MemoryContext.java

+15-4
Original file line numberDiff line numberDiff line change
@@ -170,11 +170,22 @@ public void started(TaskEvent event) {
170170
* if no source file was found for the given name
171171
*/
172172
byte[] compileJavaFileByName(String name) {
173+
// Initially, determine existing directory from class name.
174+
// [pack$age . ] na$me [ $ enclo$ed [$ dee$per] ]
175+
var lastDot = name.lastIndexOf(".");
176+
var packageName = lastDot == -1 ? "" : name.substring(0, lastDot);
177+
var packagePath = descriptor.sourceRootPath().resolve(packageName.replace('.', '/'));
178+
// Trivial case: no matching directory exists
179+
if (!Files.isDirectory(packagePath)) return null;
180+
173181
// Determine source file from class name.
174-
var firstDollarSign = name.indexOf('$'); // [package . ] name [ $ enclosed [$ deeper] ]
175-
var packageAndClassName = firstDollarSign == -1 ? name : name.substring(0, firstDollarSign);
176-
var path = packageAndClassName.replace('.', '/') + ".java";
177-
var file = descriptor.sourceRootPath().resolve(path);
182+
var candidate = name.substring(lastDot + 1, name.length()); // "na$me$enclo$ed$dee$per"
183+
// For each `$` in the name try to find the first matching compilation unit.
184+
while (candidate.contains("$")) {
185+
if (Files.exists(packagePath.resolve(candidate + ".java"))) break;
186+
candidate = candidate.substring(0, candidate.lastIndexOf("$"));
187+
}
188+
var file = packagePath.resolve(candidate + ".java");
178189

179190
// Trivial case: no matching source file exists
180191
if (!Files.exists(file)) return null;

‎test/langtools/tools/javac/launcher/MultiFileSourceLauncherTests.java

+23-4
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ void testLoadingOfEnclosedTypes(@TempDir Path base) throws Exception {
7575
public class Hello {
7676
public static void main(String... args) throws Exception {
7777
System.out.println(Class.forName("World$Core"));
78-
System.out.println(Class.forName("p.q.Unit$First$Second"));
78+
System.out.println(Class.forName("p.q.Unit$Fir$t"));
79+
System.out.println(Class.forName("p.q.Unit$123$Fir$t$$econd"));
80+
System.out.println(Class.forName("$.$.$"));
7981
}
8082
}
8183
""");
@@ -90,18 +92,35 @@ record Core() {}
9092
"""
9193
package p.q;
9294
record Unit() {
93-
record First() {
94-
record Second() {}
95+
record Fir$t() {
96+
record $econd() {}
9597
}
9698
}
9799
""");
100+
Files.writeString(pq.resolve("Unit$123.java"),
101+
"""
102+
package p.q;
103+
record Unit$123() {
104+
record Fir$t() {
105+
record $econd() {}
106+
}
107+
}
108+
""");
109+
var $$ = Files.createDirectories(base.resolve("$/$"));
110+
Files.writeString($$.resolve("$.java"),
111+
"""
112+
package $.$;
113+
record $($ $) {}
114+
""");
98115

99116
var run = Run.of(hello);
100117
assertAll("Run -> " + run,
101118
() -> assertLinesMatch(
102119
"""
103120
class World$Core
104-
class p.q.Unit$First$Second
121+
class p.q.Unit$Fir$t
122+
class p.q.Unit$123$Fir$t$$econd
123+
class $.$.$
105124
""".lines(),
106125
run.stdOut().lines()),
107126
() -> assertTrue(run.stdErr().isEmpty()),

0 commit comments

Comments
 (0)
Please sign in to comment.