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