Plugable asm visitors strategy
This commit is contained in:
Generated
+3
-1
@@ -4,6 +4,8 @@
|
||||
<root url="jar://$PROJECT_DIR$/lib/asm-util-3.3.1.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
<SOURCES>
|
||||
<root url="file://$USER_HOME$/libs/asm-3.3.1/src" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
@@ -0,0 +1,57 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.util.TraceClassVisitor;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public interface ClassBuilderFactory {
|
||||
ClassBuilder newClassBuilder();
|
||||
String asText(ClassBuilder builder);
|
||||
byte[] asBytes(ClassBuilder builder);
|
||||
|
||||
ClassBuilderFactory TEXT = new ClassBuilderFactory() {
|
||||
@Override
|
||||
public ClassBuilder newClassBuilder() {
|
||||
return new ClassBuilder(new TraceClassVisitor(new PrintWriter(new StringWriter())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String asText(ClassBuilder builder) {
|
||||
TraceClassVisitor visitor = (TraceClassVisitor) builder.getVisitor();
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
visitor.print(new PrintWriter(writer));
|
||||
|
||||
return writer.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] asBytes(ClassBuilder builder) {
|
||||
throw new UnsupportedOperationException("TEXT generator asked for bytes");
|
||||
}
|
||||
};
|
||||
|
||||
ClassBuilderFactory BINARIES = new ClassBuilderFactory() {
|
||||
@Override
|
||||
public ClassBuilder newClassBuilder() {
|
||||
return new ClassBuilder(new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String asText(ClassBuilder builder) {
|
||||
throw new UnsupportedOperationException("BINARIES generator asked for text");
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] asBytes(ClassBuilder builder) {
|
||||
ClassWriter visitor = (ClassWriter) builder.getVisitor();
|
||||
return visitor.toByteArray();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,42 +1,26 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.jet.lang.psi.JetNamespace;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.util.TraceClassVisitor;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public class ClassFileFactory {
|
||||
private final Project project;
|
||||
private final boolean isText;
|
||||
private final ClassBuilderFactory builderFactory;
|
||||
private final Map<String, NamespaceCodegen> ns2codegen = new HashMap<String, NamespaceCodegen>();
|
||||
private final Map<String, ClassBuilder> generators = new LinkedHashMap<String, ClassBuilder>();
|
||||
private boolean isDone = false;
|
||||
public final GenerationState state;
|
||||
|
||||
public ClassFileFactory(Project project, boolean text, GenerationState state) {
|
||||
this.project = project;
|
||||
isText = text;
|
||||
public ClassFileFactory(ClassBuilderFactory builderFactory, GenerationState state) {
|
||||
this.builderFactory = builderFactory;
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
ClassBuilder newVisitor(String filePath) {
|
||||
ClassVisitor visitor;
|
||||
if (isText) {
|
||||
visitor = new TraceClassVisitor(new PrintWriter(new StringWriter()));
|
||||
}
|
||||
else {
|
||||
visitor = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||
}
|
||||
|
||||
final ClassBuilder answer = new ClassBuilder(visitor);
|
||||
final ClassBuilder answer = builderFactory.newClassBuilder();
|
||||
generators.put(filePath, answer);
|
||||
return answer;
|
||||
}
|
||||
@@ -68,25 +52,13 @@ public class ClassFileFactory {
|
||||
}
|
||||
|
||||
public String asText(String file) {
|
||||
assert isText : "Need to create with text=true";
|
||||
|
||||
done();
|
||||
|
||||
TraceClassVisitor visitor = (TraceClassVisitor) generators.get(file).getVisitor();
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
visitor.print(new PrintWriter(writer));
|
||||
|
||||
return writer.toString();
|
||||
return builderFactory.asText(generators.get(file));
|
||||
}
|
||||
|
||||
public byte[] asBytes(String file) {
|
||||
assert !isText : "This is debug stuff, only produces texts.";
|
||||
|
||||
done();
|
||||
|
||||
ClassWriter visitor = (ClassWriter) generators.get(file).getVisitor();
|
||||
return visitor.toByteArray();
|
||||
return builderFactory.asBytes(generators.get(file));
|
||||
}
|
||||
|
||||
public List<String> files() {
|
||||
|
||||
@@ -28,10 +28,10 @@ public class GenerationState {
|
||||
private final JetStandardLibrary standardLibrary;
|
||||
private final IntrinsicMethods intrinsics;
|
||||
|
||||
public GenerationState(Project project, boolean text) {
|
||||
public GenerationState(Project project, ClassBuilderFactory builderFactory) {
|
||||
this.project = project;
|
||||
this.standardLibrary = JetStandardLibrary.getJetStandardLibrary(project);
|
||||
this.factory = new ClassFileFactory(project, text, this);
|
||||
this.factory = new ClassFileFactory(builderFactory, this);
|
||||
this.intrinsics = new IntrinsicMethods(project, standardLibrary);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import org.jetbrains.jet.JetCoreEnvironment;
|
||||
import org.jetbrains.jet.codegen.ClassBuilderFactory;
|
||||
import org.jetbrains.jet.codegen.ClassFileFactory;
|
||||
import org.jetbrains.jet.codegen.GenerationState;
|
||||
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
|
||||
@@ -93,7 +94,7 @@ public class CompileSession {
|
||||
}
|
||||
|
||||
public ClassFileFactory generate() {
|
||||
GenerationState generationState = new GenerationState(myEnvironment.getProject(), false);
|
||||
GenerationState generationState = new GenerationState(myEnvironment.getProject(), ClassBuilderFactory.BINARIES);
|
||||
generationState.compileCorrectNamespaces(myBindingContext, mySourceFileNamespaces);
|
||||
return generationState.getFactory();
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ public abstract class CodegenTestCase extends JetLiteFixture {
|
||||
}
|
||||
|
||||
protected String generateToText() {
|
||||
GenerationState state = new GenerationState(getProject(), true);
|
||||
GenerationState state = new GenerationState(getProject(), ClassBuilderFactory.TEXT);
|
||||
AnalyzingUtils.checkForSyntacticErrors(myFile);
|
||||
state.compile(myFile);
|
||||
|
||||
@@ -152,7 +152,7 @@ public abstract class CodegenTestCase extends JetLiteFixture {
|
||||
|
||||
protected ClassFileFactory generateClassesInFile() {
|
||||
try {
|
||||
GenerationState state = new GenerationState(getProject(), false);
|
||||
GenerationState state = new GenerationState(getProject(), ClassBuilderFactory.BINARIES);
|
||||
AnalyzingUtils.checkForSyntacticErrors(myFile);
|
||||
state.compile(myFile);
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.util.Chunk;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.codegen.ClassBuilderFactory;
|
||||
import org.jetbrains.jet.codegen.ClassFileFactory;
|
||||
import org.jetbrains.jet.codegen.GenerationState;
|
||||
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
|
||||
@@ -69,7 +70,7 @@ public class JetCompiler implements TranslatingCompiler {
|
||||
public void run() {
|
||||
VirtualFile[] allFiles = compileContext.getCompileScope().getFiles(null, true);
|
||||
|
||||
GenerationState generationState = new GenerationState(compileContext.getProject(), false);
|
||||
GenerationState generationState = new GenerationState(compileContext.getProject(), ClassBuilderFactory.BINARIES);
|
||||
List<JetNamespace> namespaces = Lists.newArrayList();
|
||||
for (VirtualFile virtualFile : allFiles) {
|
||||
PsiFile psiFile = PsiManager.getInstance(compileContext.getProject()).findFile(virtualFile);
|
||||
|
||||
Reference in New Issue
Block a user