8323815: Source launcher should find classes with $ in names
Reviewed-by: jlahoda, sundar
This commit is contained in:
parent
c432dc008b
commit
c702dcabf8
src/jdk.compiler/share/classes/com/sun/tools/javac/launcher
test/langtools/tools/javac/launcher
@ -170,11 +170,22 @@ final class MemoryContext {
|
||||
* if no source file was found for the given name
|
||||
*/
|
||||
byte[] compileJavaFileByName(String name) {
|
||||
// Initially, determine existing directory from class name.
|
||||
// [pack$age . ] na$me [ $ enclo$ed [$ dee$per] ]
|
||||
var lastDot = name.lastIndexOf(".");
|
||||
var packageName = lastDot == -1 ? "" : name.substring(0, lastDot);
|
||||
var packagePath = descriptor.sourceRootPath().resolve(packageName.replace('.', '/'));
|
||||
// Trivial case: no matching directory exists
|
||||
if (!Files.isDirectory(packagePath)) return null;
|
||||
|
||||
// Determine source file from class name.
|
||||
var firstDollarSign = name.indexOf('$'); // [package . ] name [ $ enclosed [$ deeper] ]
|
||||
var packageAndClassName = firstDollarSign == -1 ? name : name.substring(0, firstDollarSign);
|
||||
var path = packageAndClassName.replace('.', '/') + ".java";
|
||||
var file = descriptor.sourceRootPath().resolve(path);
|
||||
var candidate = name.substring(lastDot + 1, name.length()); // "na$me$enclo$ed$dee$per"
|
||||
// For each `$` in the name try to find the first matching compilation unit.
|
||||
while (candidate.contains("$")) {
|
||||
if (Files.exists(packagePath.resolve(candidate + ".java"))) break;
|
||||
candidate = candidate.substring(0, candidate.lastIndexOf("$"));
|
||||
}
|
||||
var file = packagePath.resolve(candidate + ".java");
|
||||
|
||||
// Trivial case: no matching source file exists
|
||||
if (!Files.exists(file)) return null;
|
||||
|
@ -75,7 +75,9 @@ class MultiFileSourceLauncherTests {
|
||||
public class Hello {
|
||||
public static void main(String... args) throws Exception {
|
||||
System.out.println(Class.forName("World$Core"));
|
||||
System.out.println(Class.forName("p.q.Unit$First$Second"));
|
||||
System.out.println(Class.forName("p.q.Unit$Fir$t"));
|
||||
System.out.println(Class.forName("p.q.Unit$123$Fir$t$$econd"));
|
||||
System.out.println(Class.forName("$.$.$"));
|
||||
}
|
||||
}
|
||||
""");
|
||||
@ -90,18 +92,35 @@ class MultiFileSourceLauncherTests {
|
||||
"""
|
||||
package p.q;
|
||||
record Unit() {
|
||||
record First() {
|
||||
record Second() {}
|
||||
record Fir$t() {
|
||||
record $econd() {}
|
||||
}
|
||||
}
|
||||
""");
|
||||
Files.writeString(pq.resolve("Unit$123.java"),
|
||||
"""
|
||||
package p.q;
|
||||
record Unit$123() {
|
||||
record Fir$t() {
|
||||
record $econd() {}
|
||||
}
|
||||
}
|
||||
""");
|
||||
var $$ = Files.createDirectories(base.resolve("$/$"));
|
||||
Files.writeString($$.resolve("$.java"),
|
||||
"""
|
||||
package $.$;
|
||||
record $($ $) {}
|
||||
""");
|
||||
|
||||
var run = Run.of(hello);
|
||||
assertAll("Run -> " + run,
|
||||
() -> assertLinesMatch(
|
||||
"""
|
||||
class World$Core
|
||||
class p.q.Unit$First$Second
|
||||
class p.q.Unit$Fir$t
|
||||
class p.q.Unit$123$Fir$t$$econd
|
||||
class $.$.$
|
||||
""".lines(),
|
||||
run.stdOut().lines()),
|
||||
() -> assertTrue(run.stdErr().isEmpty()),
|
||||
|
Loading…
x
Reference in New Issue
Block a user