First green test for class codegen
This commit is contained in:
@@ -23,12 +23,11 @@ public class ClassCodegen {
|
||||
this.project = project;
|
||||
this.factory = factory;
|
||||
this.bindingContext = bindingContext;
|
||||
|
||||
}
|
||||
|
||||
public void generate(JetClass aClass) {
|
||||
ClassDescriptor descriptor = bindingContext.getClassDescriptor(aClass);
|
||||
String fqName = CodeGenUtil.getInternalInterfaceName(descriptor);
|
||||
String fqName = CodeGenUtil.getInternalImplementationName(descriptor);
|
||||
|
||||
List<JetDelegationSpecifier> delegationSpecifiers = aClass.getDelegationSpecifiers();
|
||||
for (JetDelegationSpecifier specifier : delegationSpecifiers) {
|
||||
@@ -36,8 +35,6 @@ public class ClassCodegen {
|
||||
String superClassFQN = CodeGenUtil.getInternalInterfaceName((ClassDescriptor) superType.getConstructor().getDeclarationDescriptor());
|
||||
}
|
||||
|
||||
//descriptor.
|
||||
|
||||
ClassVisitor v = factory.forClassImplementation(descriptor);
|
||||
v.visit(Opcodes.V1_6,
|
||||
Opcodes.ACC_PUBLIC,
|
||||
@@ -59,5 +56,7 @@ public class ClassCodegen {
|
||||
functionCodegen.genInInterface((JetFunction) declaration);
|
||||
}
|
||||
}
|
||||
|
||||
v.visitEnd();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
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;
|
||||
@@ -51,10 +48,7 @@ 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);
|
||||
public ClassCodegen forClass(BindingContext bindingContext) {
|
||||
return new ClassCodegen(project, this, bindingContext);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.jetbrains.jet.codegen;
|
||||
|
||||
import gnu.trove.TObjectIntHashMap;
|
||||
import org.jetbrains.jet.lang.types.DeclarationDescriptor;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
|
||||
@@ -28,11 +28,11 @@ public class FunctionCodegen {
|
||||
}
|
||||
|
||||
public void genInNamespace(JetFunction f) {
|
||||
gen(f);
|
||||
gen(f, OwnerKind.NAMESPACE);
|
||||
}
|
||||
|
||||
public void genInInterface(JetFunction f) {
|
||||
|
||||
gen(f, OwnerKind.INTERFACE);
|
||||
}
|
||||
|
||||
public void genInImplementation(JetFunction f) {
|
||||
@@ -43,27 +43,40 @@ public class FunctionCodegen {
|
||||
|
||||
}
|
||||
|
||||
private void gen(JetFunction f) {
|
||||
Method method = typeMapper.mapSignature(f);
|
||||
final MethodVisitor mv = v.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
|
||||
method.getName(), method.getDescriptor(), null, null);
|
||||
mv.visitCode();
|
||||
private void gen(JetFunction f, OwnerKind kind) {
|
||||
int flags = Opcodes.ACC_PUBLIC; // TODO.
|
||||
|
||||
boolean isStatic = kind == OwnerKind.NAMESPACE;
|
||||
if (isStatic) flags |= Opcodes.ACC_STATIC;
|
||||
|
||||
final JetExpression bodyExpression = f.getBodyExpression();
|
||||
FrameMap frameMap = new FrameMap();
|
||||
boolean isAbstract = kind == OwnerKind.INTERFACE || bodyExpression == null;
|
||||
if (isAbstract) flags |= Opcodes.ACC_ABSTRACT;
|
||||
|
||||
List<ValueParameterDescriptor> parameDescrs = bindingContext.getFunctionDescriptor(f).getUnsubstitutedValueParameters();
|
||||
Method method = typeMapper.mapSignature(f);
|
||||
final MethodVisitor mv = v.visitMethod(flags, method.getName(), method.getDescriptor(), null, null);
|
||||
if (kind != OwnerKind.INTERFACE) {
|
||||
mv.visitCode();
|
||||
FrameMap frameMap = new FrameMap();
|
||||
|
||||
Type[] argTypes = method.getArgumentTypes();
|
||||
for (int i = 0; i < parameDescrs.size(); i++) {
|
||||
ValueParameterDescriptor parameter = parameDescrs.get(i);
|
||||
frameMap.enter(parameter, argTypes[i].getSize());
|
||||
if (kind != OwnerKind.NAMESPACE) {
|
||||
frameMap.enterTemp(); // 0 slot for this
|
||||
}
|
||||
|
||||
List<ValueParameterDescriptor> parameDescrs = bindingContext.getFunctionDescriptor(f).getUnsubstitutedValueParameters();
|
||||
|
||||
Type[] argTypes = method.getArgumentTypes();
|
||||
for (int i = 0; i < parameDescrs.size(); i++) {
|
||||
ValueParameterDescriptor parameter = parameDescrs.get(i);
|
||||
frameMap.enter(parameter, argTypes[i].getSize());
|
||||
}
|
||||
|
||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, bindingContext, frameMap, typeMapper, method.getReturnType());
|
||||
bodyExpression.accept(codegen);
|
||||
generateReturn(mv, bodyExpression, codegen);
|
||||
mv.visitMaxs(0, 0);
|
||||
mv.visitEnd();
|
||||
}
|
||||
|
||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, bindingContext, frameMap, typeMapper, method.getReturnType());
|
||||
bodyExpression.accept(codegen);
|
||||
generateReturn(mv, bodyExpression, codegen);
|
||||
mv.visitMaxs(0, 0);
|
||||
mv.visitEnd();
|
||||
}
|
||||
|
||||
private void generateReturn(MethodVisitor mv, JetExpression bodyExpression, ExpressionCodegen codegen) {
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public enum OwnerKind {
|
||||
NAMESPACE,
|
||||
INTERFACE,
|
||||
IMPLEMENTATION,
|
||||
DELEGATING_IMPLEMENTATION
|
||||
}
|
||||
@@ -14,18 +14,22 @@ public class PropertyCodegen {
|
||||
}
|
||||
|
||||
public void genInNamespace(JetProperty p) {
|
||||
|
||||
gen(p, OwnerKind.NAMESPACE);
|
||||
}
|
||||
|
||||
public void genInInterface(JetProperty p) {
|
||||
|
||||
gen(p, OwnerKind.INTERFACE);
|
||||
}
|
||||
|
||||
public void genInImplementation(JetProperty p) {
|
||||
|
||||
gen(p, OwnerKind.IMPLEMENTATION);
|
||||
}
|
||||
|
||||
public void genInDelegatingImplementation(JetProperty p) {
|
||||
gen(p, OwnerKind.DELEGATING_IMPLEMENTATION);
|
||||
}
|
||||
|
||||
public void gen(JetProperty p, OwnerKind kind) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,7 +129,8 @@ public class DescriptorUtil {
|
||||
public static String getFQName(DeclarationDescriptor descriptor) {
|
||||
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
||||
if (container != null && !(container instanceof ModuleDescriptor)) {
|
||||
return getFQName(container) + "." + descriptor.getName();
|
||||
String baseName = getFQName(container);
|
||||
if (!baseName.isEmpty()) return baseName + "." + descriptor.getName();
|
||||
}
|
||||
|
||||
return descriptor.getName();
|
||||
|
||||
@@ -9,7 +9,7 @@ public class ClassGenTest extends CodegenTestCase {
|
||||
public void testPSVMClass() throws Exception {
|
||||
loadFile("simpleClass.jet");
|
||||
final Class aClass = generateClass();
|
||||
final Method[] methods = aClass.getMethods();
|
||||
final Method[] methods = aClass.getDeclaredMethods();
|
||||
assertEquals(1, methods.length);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,10 @@ 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.ErrorHandler;
|
||||
import org.jetbrains.jet.lang.JetFileType;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
|
||||
import org.jetbrains.jet.parsing.JetParsingTest;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
@@ -52,6 +54,7 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase {
|
||||
final Codegens state = new Codegens(getProject(), false);
|
||||
JetFile jetFile = (JetFile) myFixture.getFile();
|
||||
final Ref<Class> result = new Ref<Class>();
|
||||
final ClassCodegen codegen = state.forClass(AnalyzingUtils.analyzeFile(jetFile, ErrorHandler.THROW_EXCEPTION));
|
||||
jetFile.acceptChildren(new JetVisitor() {
|
||||
@Override
|
||||
public void visitJetElement(JetElement elem) {
|
||||
@@ -60,9 +63,8 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase {
|
||||
|
||||
@Override
|
||||
public void visitClass(JetClass klass) {
|
||||
final ClassCodegen codegen = state.forClassImplementation(klass);
|
||||
codegen.generate(klass);
|
||||
result.set(getJVMClass(state, klass.getName()));
|
||||
result.set(getJVMClass(state, klass.getName() + "$$Impl"));
|
||||
}
|
||||
});
|
||||
if (result.isNull()) {
|
||||
|
||||
Reference in New Issue
Block a user