diff --git a/idea/src/org/jetbrains/jet/codegen/Codegens.java b/idea/src/org/jetbrains/jet/codegen/Codegens.java index 2f6419d1516..142f679a54c 100644 --- a/idea/src/org/jetbrains/jet/codegen/Codegens.java +++ b/idea/src/org/jetbrains/jet/codegen/Codegens.java @@ -1,7 +1,12 @@ package org.jetbrains.jet.codegen; import com.intellij.openapi.project.Project; +import org.jetbrains.jet.lang.ErrorHandler; +import org.jetbrains.jet.lang.psi.JetClass; +import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetNamespace; +import org.jetbrains.jet.lang.resolve.AnalyzingUtils; +import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.types.ClassDescriptor; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; @@ -46,6 +51,13 @@ public class Codegens { return newVisitor(CodeGenUtil.getInternalInterfaceName(aClass)); } + public ClassCodegen forClassImplementation(JetClass aClass) { + String fqName = aClass.getName(); // TODO + final BindingContext bindingContext = AnalyzingUtils.analyzeFile((JetFile) aClass.getContainingFile(), + ErrorHandler.THROW_EXCEPTION); + return new ClassCodegen(project, this, bindingContext); + } + public ClassVisitor forClassImplementation(ClassDescriptor aClass) { return newVisitor(CodeGenUtil.getInternalImplementationName(aClass)); } diff --git a/idea/testData/codegen/simpleClass.jet b/idea/testData/codegen/simpleClass.jet new file mode 100644 index 00000000000..116684dac3b --- /dev/null +++ b/idea/testData/codegen/simpleClass.jet @@ -0,0 +1,5 @@ +class SimpleClass { + fun foo() { + return 0; + } +} diff --git a/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java b/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java new file mode 100644 index 00000000000..6644770dd6a --- /dev/null +++ b/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java @@ -0,0 +1,15 @@ +package org.jetbrains.jet.codegen; + +import java.lang.reflect.Method; + +/** + * @author yole + */ +public class ClassGenTest extends CodegenTestCase { + public void testPSVMClass() throws Exception { + loadFile("simpleClass.jet"); + final Class aClass = generateClass(); + final Method[] methods = aClass.getMethods(); + assertEquals(1, methods.length); + } +} diff --git a/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java b/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java index c15f1eef312..28b4d45610b 100644 --- a/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java +++ b/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java @@ -1,12 +1,12 @@ package org.jetbrains.jet.codegen; +import com.intellij.openapi.util.Ref; import com.intellij.testFramework.LightProjectDescriptor; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.JetLightProjectDescriptor; import org.jetbrains.jet.lang.JetFileType; -import org.jetbrains.jet.lang.psi.JetFile; -import org.jetbrains.jet.lang.psi.JetNamespace; +import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.parsing.JetParsingTest; import java.lang.reflect.Method; @@ -37,7 +37,7 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase { return state.asText(files.get(0)); } - private Class generateToClass() { + private Class generateNamespaceClass() { Codegens state = new Codegens(getProject(), false); JetFile jetFile = (JetFile) myFixture.getFile(); final JetNamespace namespace = jetFile.getRootNamespace(); @@ -45,20 +45,47 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase { NamespaceCodegen codegen = state.forNamespace(namespace); codegen.generate(namespace); + return getJVMClass(state, NamespaceCodegen.getJVMClassName(namespace.getFQName()).replace("/", ".")); + } + + protected Class generateClass() { + final Codegens state = new Codegens(getProject(), false); + JetFile jetFile = (JetFile) myFixture.getFile(); + final Ref result = new Ref(); + jetFile.acceptChildren(new JetVisitor() { + @Override + public void visitJetElement(JetElement elem) { + elem.acceptChildren(this); + } + + @Override + public void visitClass(JetClass klass) { + final ClassCodegen codegen = state.forClassImplementation(klass); + codegen.generate(klass); + result.set(getJVMClass(state, klass.getName())); + } + }); + if (result.isNull()) { + throw new IllegalArgumentException("found no classes in the file to generate"); + } + return result.get(); + } + + private static Class getJVMClass(Codegens state, final String fqName) { List files = state.files(); assertEquals("This test only supposed to generate single class file", 1, files.size()); final byte[] data = state.asBytes(files.get(0)); MyClassLoader classLoader = new MyClassLoader(NamespaceGenTest.class.getClassLoader()); - return classLoader.doDefineClass(NamespaceCodegen.getJVMClassName(namespace.getFQName()).replace("/", "."), data); + return classLoader.doDefineClass(fqName, data); } protected Method generateFunction() { - Class aClass = generateToClass(); + Class aClass = generateNamespaceClass(); return aClass.getMethods()[0]; } protected Method generateFunction(String name) { - Class aClass = generateToClass(); + Class aClass = generateNamespaceClass(); for (Method method : aClass.getMethods()) { if (method.getName().equals(name)) { return method;