From 7f456ede1a1a7dd91399d82eb24b851b757a52b1 Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Mon, 6 Aug 2012 12:36:32 +0300 Subject: [PATCH] KT-2149 binary and text compilation in one pass --- .../jet/codegen/ClassBuilderFactories.java | 71 +++++++++++++++---- .../jetbrains/jet/codegen/ArrayGenTest.java | 2 +- .../jet/codegen/CodegenTestCase.java | 13 +++- .../jet/codegen/MultiFileGenTest.java | 2 +- .../jet/codegen/PrimitiveTypesTest.java | 2 +- 5 files changed, 72 insertions(+), 18 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilderFactories.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilderFactories.java index 679f1ecbcf4..9345f38177d 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilderFactories.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilderFactories.java @@ -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; + } + } } diff --git a/compiler/tests/org/jetbrains/jet/codegen/ArrayGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/ArrayGenTest.java index 7a45b9573fe..0cb7b27e63a 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ArrayGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ArrayGenTest.java @@ -78,7 +78,7 @@ public class ArrayGenTest extends CodegenTestCase { public void testIntGenerics () throws Exception { loadText("class L(var a : T) {} fun foo() = L(5).a"); - System.out.println(generateToText()); + //System.out.println(generateToText()); Method foo = generateFunction(); Object invoke = foo.invoke(null); System.out.println(invoke.getClass()); diff --git a/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java b/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java index bfe7cf776c1..c88277058d1 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java +++ b/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java @@ -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()); diff --git a/compiler/tests/org/jetbrains/jet/codegen/MultiFileGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/MultiFileGenTest.java index 23a9fd9c6c2..23400a5b171 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/MultiFileGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/MultiFileGenTest.java @@ -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() { diff --git a/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java b/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java index f20d4e1406f..c4f451e8a9c 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java @@ -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 () {