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; package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.ClassVisitor;
import org.jetbrains.asm4.ClassWriter; import org.jetbrains.asm4.ClassWriter;
import org.jetbrains.asm4.util.TraceClassVisitor; import org.jetbrains.asm4.util.TraceClassVisitor;
@@ -28,6 +29,34 @@ import java.io.StringWriter;
*/ */
public class ClassBuilderFactories { 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() { public static ClassBuilderFactory TEXT = new ClassBuilderFactory() {
@NotNull @NotNull
@Override @Override
@@ -56,6 +85,9 @@ public class ClassBuilderFactories {
} }
}; };
private ClassBuilderFactories() {
}
public static ClassBuilderFactory binaries(final boolean stubs) { public static ClassBuilderFactory binaries(final boolean stubs) {
return new ClassBuilderFactory() { return new ClassBuilderFactory() {
@NotNull @NotNull
@@ -66,18 +98,7 @@ public class ClassBuilderFactories {
@Override @Override
public ClassBuilder newClassBuilder() { public ClassBuilder newClassBuilder() {
return new ClassBuilder.Concrete(new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS){ return new ClassBuilder.Concrete(new BinaryClassWriter());
@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";
}
}
});
} }
@Override @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 { public void testIntGenerics () throws Exception {
loadText("class L<T>(var a : T) {} fun foo() = L<Int>(5).a"); loadText("class L<T>(var a : T) {} fun foo() = L<Int>(5).a");
System.out.println(generateToText()); //System.out.println(generateToText());
Method foo = generateFunction(); Method foo = generateFunction();
Object invoke = foo.invoke(null); Object invoke = foo.invoke(null);
System.out.println(invoke.getClass()); System.out.println(invoke.getClass());
@@ -59,6 +59,7 @@ public abstract class CodegenTestCase extends UsefulTestCase {
protected CodegenTestFiles myFiles; protected CodegenTestFiles myFiles;
protected Object scriptInstance; protected Object scriptInstance;
private GenerationState alreadyGenerated;
protected void createEnvironmentWithMockJdkAndIdeaAnnotations() { protected void createEnvironmentWithMockJdkAndIdeaAnnotations() {
if (myEnvironment != null) { if (myEnvironment != null) {
@@ -102,6 +103,7 @@ public abstract class CodegenTestCase extends UsefulTestCase {
myFiles = null; myFiles = null;
myEnvironment = null; myEnvironment = null;
scriptInstance = null; scriptInstance = null;
alreadyGenerated = null;
super.tearDown(); super.tearDown();
} }
@@ -255,10 +257,15 @@ public abstract class CodegenTestCase extends UsefulTestCase {
} }
protected String generateToText() { protected String generateToText() {
return generateCommon(ClassBuilderFactories.TEXT).createText(); if(alreadyGenerated == null)
alreadyGenerated = generateCommon(ClassBuilderFactories.TEST);
return alreadyGenerated.createText();
} }
private GenerationState generateCommon(ClassBuilderFactory classBuilderFactory) { private GenerationState generateCommon(ClassBuilderFactory classBuilderFactory) {
if(alreadyGenerated != null)
return alreadyGenerated;
final AnalyzeExhaust analyzeExhaust = AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegrationAndCheckForErrors( final AnalyzeExhaust analyzeExhaust = AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegrationAndCheckForErrors(
myEnvironment.getProject(), myEnvironment.getProject(),
myFiles.getPsiFiles(), myFiles.getPsiFiles(),
@@ -269,6 +276,7 @@ public abstract class CodegenTestCase extends UsefulTestCase {
AnalyzingUtils.throwExceptionOnErrors(analyzeExhaust.getBindingContext()); AnalyzingUtils.throwExceptionOnErrors(analyzeExhaust.getBindingContext());
GenerationState state = new GenerationState(myEnvironment.getProject(), classBuilderFactory, analyzeExhaust, myFiles.getPsiFiles()); GenerationState state = new GenerationState(myEnvironment.getProject(), classBuilderFactory, analyzeExhaust, myFiles.getPsiFiles());
state.compileCorrectFiles(CompilationErrorHandler.THROW_EXCEPTION); state.compileCorrectFiles(CompilationErrorHandler.THROW_EXCEPTION);
alreadyGenerated = state;
return state; return state;
} }
@@ -313,8 +321,7 @@ public abstract class CodegenTestCase extends UsefulTestCase {
private GenerationState generateClassesInFileGetState() { private GenerationState generateClassesInFileGetState() {
GenerationState generationState; GenerationState generationState;
try { try {
ClassBuilderFactory classBuilderFactory = ClassBuilderFactories.binaries(false); generationState = generateCommon(ClassBuilderFactories.TEST);
generationState = generateCommon(classBuilderFactory);
if (DxChecker.RUN_DX_CHECKER) { if (DxChecker.RUN_DX_CHECKER) {
DxChecker.check(generationState.getFactory()); DxChecker.check(generationState.getFactory());
@@ -27,7 +27,7 @@ public class MultiFileGenTest extends CodegenTestCase {
public void testSimple() { public void testSimple() {
blackBoxMultiFile("/multi/simple/box.kt", "/multi/simple/ok.kt"); blackBoxMultiFile("/multi/simple/box.kt", "/multi/simple/ok.kt");
System.out.println(generateToText()); //System.out.println(generateToText());
} }
public void testInternalVisibility() { public void testInternalVisibility() {
@@ -370,7 +370,7 @@ public class PrimitiveTypesTest extends CodegenTestCase {
public void testKt756 () { public void testKt756 () {
blackBoxFile("regressions/kt756.jet"); blackBoxFile("regressions/kt756.jet");
System.out.println(generateToText()); //System.out.println(generateToText());
} }
public void testKt757 () { public void testKt757 () {