diff --git a/idea/src/org/jetbrains/jet/codegen/ClassCodegen.java b/idea/src/org/jetbrains/jet/codegen/ClassCodegen.java index 0cc66c26bab..fef9847f70f 100644 --- a/idea/src/org/jetbrains/jet/codegen/ClassCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ClassCodegen.java @@ -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 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(); } } diff --git a/idea/src/org/jetbrains/jet/codegen/Codegens.java b/idea/src/org/jetbrains/jet/codegen/Codegens.java index 142f679a54c..acb6b5545d7 100644 --- a/idea/src/org/jetbrains/jet/codegen/Codegens.java +++ b/idea/src/org/jetbrains/jet/codegen/Codegens.java @@ -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); } diff --git a/idea/src/org/jetbrains/jet/codegen/FrameMap.java b/idea/src/org/jetbrains/jet/codegen/FrameMap.java index 98b46f592ca..827ab5f1367 100644 --- a/idea/src/org/jetbrains/jet/codegen/FrameMap.java +++ b/idea/src/org/jetbrains/jet/codegen/FrameMap.java @@ -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 diff --git a/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java index 342963f9b4a..87b040a1020 100644 --- a/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -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 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 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) { diff --git a/idea/src/org/jetbrains/jet/codegen/OwnerKind.java b/idea/src/org/jetbrains/jet/codegen/OwnerKind.java new file mode 100644 index 00000000000..7e1b1545dfb --- /dev/null +++ b/idea/src/org/jetbrains/jet/codegen/OwnerKind.java @@ -0,0 +1,11 @@ +package org.jetbrains.jet.codegen; + +/** + * @author max + */ +public enum OwnerKind { + NAMESPACE, + INTERFACE, + IMPLEMENTATION, + DELEGATING_IMPLEMENTATION +} diff --git a/idea/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/idea/src/org/jetbrains/jet/codegen/PropertyCodegen.java index 6b51df0944a..2e357495772 100644 --- a/idea/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -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) { } } diff --git a/idea/src/org/jetbrains/jet/resolve/DescriptorUtil.java b/idea/src/org/jetbrains/jet/resolve/DescriptorUtil.java index acada12de63..ba189bf744b 100644 --- a/idea/src/org/jetbrains/jet/resolve/DescriptorUtil.java +++ b/idea/src/org/jetbrains/jet/resolve/DescriptorUtil.java @@ -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(); diff --git a/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java b/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java index 6644770dd6a..37939f133cf 100644 --- a/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java @@ -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); } } diff --git a/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java b/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java index 28b4d45610b..e58c918912b 100644 --- a/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java +++ b/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java @@ -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 result = new Ref(); + 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()) {