Skip to content

Commit

Permalink
jOOQ#100: Prototype for compiling multiple classes in one go.
Browse files Browse the repository at this point in the history
  • Loading branch information
davsclaus committed Mar 27, 2022
1 parent 716162d commit 540c9ad
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,11 @@
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Deque;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Stream;

import static java.lang.StackWalker.Option.RETAIN_CLASS_REFERENCE;

Expand All @@ -50,8 +48,15 @@
*
* @author Lukas Eder
*/
public class CompileUnit {

public class MultiCompile {

/**
* Compiles multiple files as one unit
*
* @param unit the files to compile in the same unit
* @param compileOptions compile options
* @return the compilation result
*/
public static CompilationUnit.Result compileUnit(CompilationUnit unit, CompileOptions compileOptions) {
CompilationUnit.Result result = CompilationUnit.result();

Expand Down Expand Up @@ -130,24 +135,15 @@ public static CompilationUnit.Result compileUnit(CompilationUnit unit, CompileOp
// This method is called by client code from two levels up the current stack frame
// We need a private-access lookup from the class in that stack frame in order to get
// private-access to any local interfaces at that location.
// Class<?> caller = StackWalker
// .getInstance(RETAIN_CLASS_REFERENCE)
// .walk(s -> s
// .skip(2)
// .findFirst()
// .get()
// .getDeclaringClass());

int index = 2;
for (CharSequenceJavaFileObject f : files) {
String className = f.getClassName();

Class<?> caller = getClassFromIndex(index);
index++;
Class<?> caller = getClassFromIndex(index++);

// If the compiled class is in the same package as the caller class, then
// we can use the private-access Lookup of the caller class
if (className.startsWith(caller.getPackageName() + ".") &&
if (caller != null && className.startsWith(caller.getPackageName() + ".") &&

// [#74] This heuristic is necessary to prevent classes in subpackages of the caller to be loaded
// this way, as subpackages cannot access private content in super packages.
Expand Down Expand Up @@ -185,13 +181,13 @@ public static CompilationUnit.Result compileUnit(CompilationUnit unit, CompileOp
}

private static Class<?> getClassFromIndex(int index) {
return StackWalker
StackWalker.StackFrame sf = StackWalker
.getInstance(RETAIN_CLASS_REFERENCE)
.walk(s -> s
.skip(index)
.findFirst()
.get()
.getDeclaringClass());
.orElse(null));
return sf != null ? sf.getDeclaringClass() : null;
}

/* [java-9] */
Expand Down
3 changes: 1 addition & 2 deletions jOOR/src/main/java/org/joor/Reflect.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

Expand All @@ -52,7 +51,7 @@
public class Reflect {

public static CompilationUnit.Result compileUnit(CompilationUnit unit) throws ReflectException {
return CompileUnit.compileUnit(unit, new CompileOptions());
return MultiCompile.compileUnit(unit, new CompileOptions());
}

// ---------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

import static org.junit.Assert.assertEquals;

public class CompileUnitTest {
public class MultiCompileTest {

@Test
public void testSingleUnit() throws Exception {
Expand Down Expand Up @@ -72,4 +72,38 @@ public void testDualUnit() throws Exception {
assertEquals("Hi World!", out3);
}

@Test
public void testClassLoadingOrder() throws Exception {
CompilationUnit unit = CompilationUnit.input()
.addClass("pm.A", "package pm; public class A extends B {}")
.addClass("pm.B", "package pm; public class B {}"
);

CompilationUnit.Result result = Reflect.compileUnit(unit);
assertEquals(2, result.size());

Class<?> a = Reflect.onClass(result.getClass("pm.A")).type();
Class<?> b = Reflect.onClass(result.getClass("pm.B")).type();
assertEquals("pm.A", a.getName());
assertEquals("pm.B", a.getSuperclass().getName());
assertEquals("pm.B", b.getName());
}

@Test
public void testClassLoadingOrderReverse() throws Exception {
CompilationUnit unit = CompilationUnit.input()
.addClass("pm.C", "package pm; public class C {}")
.addClass("pm.D", "package pm; public class D extends C {}"
);

CompilationUnit.Result result = Reflect.compileUnit(unit);
assertEquals(2, result.size());

Class<?> c = Reflect.onClass(result.getClass("pm.C")).type();
Class<?> d = Reflect.onClass(result.getClass("pm.D")).type();
assertEquals("pm.C", c.getName());
assertEquals("pm.D", d.getName());
assertEquals("pm.C", d.getSuperclass().getName());
}

}

0 comments on commit 540c9ad

Please sign in to comment.