KT-2149 binary and text compilation in one pass

This commit is contained in:
Alex Tkachman
2012-08-06 12:36:32 +03:00
parent a32cb40fc6
commit 7f456ede1a
5 changed files with 72 additions and 18 deletions
@@ -17,6 +17,7 @@
package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.ClassVisitor;
import org.jetbrains.asm4.ClassWriter;
import org.jetbrains.asm4.util.TraceClassVisitor;
@@ -28,6 +29,34 @@ import java.io.StringWriter;
*/
public class ClassBuilderFactories {
public static ClassBuilderFactory TEST = new ClassBuilderFactory() {
@NotNull
@Override
public ClassBuilderMode getClassBuilderMode() {
return ClassBuilderMode.FULL;
}
@Override
public ClassBuilder newClassBuilder() {
return new TraceBuilder(new BinaryClassWriter());
}
@Override
public String asText(ClassBuilder builder) {
TraceClassVisitor visitor = (TraceClassVisitor) builder.getVisitor();
StringWriter writer = new StringWriter();
visitor.p.print(new PrintWriter(writer));
return writer.toString();
}
@Override
public byte[] asBytes(ClassBuilder builder) {
return ((TraceBuilder) builder).binary.toByteArray();
}
};
public static ClassBuilderFactory TEXT = new ClassBuilderFactory() {
@NotNull
@Override
@@ -56,6 +85,9 @@ public class ClassBuilderFactories {
}
};
private ClassBuilderFactories() {
}
public static ClassBuilderFactory binaries(final boolean stubs) {
return new ClassBuilderFactory() {
@NotNull
@@ -66,18 +98,7 @@ public class ClassBuilderFactories {
@Override
public ClassBuilder newClassBuilder() {
return new ClassBuilder.Concrete(new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS){
@Override
protected String getCommonSuperClass(String type1, String type2) {
try {
return super.getCommonSuperClass(type1, type2);
}
catch (Throwable t) {
// @todo we might need at some point do more sofisticated handling
return "java/lang/Object";
}
}
});
return new ClassBuilder.Concrete(new BinaryClassWriter());
}
@Override
@@ -92,4 +113,30 @@ public class ClassBuilderFactories {
}
};
}
private static class BinaryClassWriter extends ClassWriter {
public BinaryClassWriter() {
super(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
}
@Override
protected String getCommonSuperClass(String type1, String type2) {
try {
return super.getCommonSuperClass(type1, type2);
}
catch (Throwable t) {
// @todo we might need at some point do more sofisticated handling
return "java/lang/Object";
}
}
}
private static class TraceBuilder extends ClassBuilder.Concrete {
public final BinaryClassWriter binary;
public TraceBuilder(BinaryClassWriter binary) {
super(new TraceClassVisitor(binary, new PrintWriter(new StringWriter())));
this.binary = binary;
}
}
}
@@ -78,7 +78,7 @@ public class ArrayGenTest extends CodegenTestCase {
public void testIntGenerics () throws Exception {
loadText("class L<T>(var a : T) {} fun foo() = L<Int>(5).a");
System.out.println(generateToText());
//System.out.println(generateToText());
Method foo = generateFunction();
Object invoke = foo.invoke(null);
System.out.println(invoke.getClass());
@@ -59,6 +59,7 @@ public abstract class CodegenTestCase extends UsefulTestCase {
protected CodegenTestFiles myFiles;
protected Object scriptInstance;
private GenerationState alreadyGenerated;
protected void createEnvironmentWithMockJdkAndIdeaAnnotations() {
if (myEnvironment != null) {
@@ -102,6 +103,7 @@ public abstract class CodegenTestCase extends UsefulTestCase {
myFiles = null;
myEnvironment = null;
scriptInstance = null;
alreadyGenerated = null;
super.tearDown();
}
@@ -255,10 +257,15 @@ public abstract class CodegenTestCase extends UsefulTestCase {
}
protected String generateToText() {
return generateCommon(ClassBuilderFactories.TEXT).createText();
if(alreadyGenerated == null)
alreadyGenerated = generateCommon(ClassBuilderFactories.TEST);
return alreadyGenerated.createText();
}
private GenerationState generateCommon(ClassBuilderFactory classBuilderFactory) {
if(alreadyGenerated != null)
return alreadyGenerated;
final AnalyzeExhaust analyzeExhaust = AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegrationAndCheckForErrors(
myEnvironment.getProject(),
myFiles.getPsiFiles(),
@@ -269,6 +276,7 @@ public abstract class CodegenTestCase extends UsefulTestCase {
AnalyzingUtils.throwExceptionOnErrors(analyzeExhaust.getBindingContext());
GenerationState state = new GenerationState(myEnvironment.getProject(), classBuilderFactory, analyzeExhaust, myFiles.getPsiFiles());
state.compileCorrectFiles(CompilationErrorHandler.THROW_EXCEPTION);
alreadyGenerated = state;
return state;
}
@@ -313,8 +321,7 @@ public abstract class CodegenTestCase extends UsefulTestCase {
private GenerationState generateClassesInFileGetState() {
GenerationState generationState;
try {
ClassBuilderFactory classBuilderFactory = ClassBuilderFactories.binaries(false);
generationState = generateCommon(classBuilderFactory);
generationState = generateCommon(ClassBuilderFactories.TEST);
if (DxChecker.RUN_DX_CHECKER) {
DxChecker.check(generationState.getFactory());
@@ -27,7 +27,7 @@ public class MultiFileGenTest extends CodegenTestCase {
public void testSimple() {
blackBoxMultiFile("/multi/simple/box.kt", "/multi/simple/ok.kt");
System.out.println(generateToText());
//System.out.println(generateToText());
}
public void testInternalVisibility() {
@@ -370,7 +370,7 @@ public class PrimitiveTypesTest extends CodegenTestCase {
public void testKt756 () {
blackBoxFile("regressions/kt756.jet");
System.out.println(generateToText());
//System.out.println(generateToText());
}
public void testKt757 () {