diff --git a/.idea/modules.xml b/.idea/modules.xml
index 335a959bed2..8958a9581db 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -6,6 +6,7 @@
+
diff --git a/idea/idea.iml b/idea/idea.iml
index fcc6e7e360a..d01e54ca4d0 100644
--- a/idea/idea.iml
+++ b/idea/idea.iml
@@ -10,6 +10,7 @@
+
diff --git a/idea/src/org/jetbrains/jet/codegen/ClassCodegen.java b/idea/src/org/jetbrains/jet/codegen/ClassCodegen.java
index c62c45cd104..a7e4872dff8 100644
--- a/idea/src/org/jetbrains/jet/codegen/ClassCodegen.java
+++ b/idea/src/org/jetbrains/jet/codegen/ClassCodegen.java
@@ -5,10 +5,7 @@ import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
-import org.jetbrains.jet.lang.types.ClassDescriptor;
-import org.jetbrains.jet.lang.types.JetStandardLibrary;
-import org.jetbrains.jet.lang.types.JetType;
-import org.jetbrains.jet.lang.types.PropertyDescriptor;
+import org.jetbrains.jet.lang.types.*;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
@@ -27,11 +24,15 @@ public class ClassCodegen {
private final Project project;
private final BindingContext bindingContext;
private final Codegens factory;
+ private final JetTypeMapper typeMapper;
public ClassCodegen(Project project, Codegens factory, BindingContext bindingContext) {
this.project = project;
this.factory = factory;
this.bindingContext = bindingContext;
+
+ final JetStandardLibrary standardLibrary = JetStandardLibrary.getJetStandardLibrary(project);
+ typeMapper = new JetTypeMapper(standardLibrary, bindingContext);
}
public void generate(JetClass aClass) {
@@ -68,7 +69,7 @@ public class ClassCodegen {
ClassVisitor v = kind == OwnerKind.IMPLEMENTATION ? factory.forClassImplementation(descriptor) : factory.forClassDelegatingImplementation(descriptor);
v.visit(Opcodes.V1_6,
Opcodes.ACC_PUBLIC,
- JetTypeMapper.jvmNameForImplementation(descriptor),
+ JetTypeMapper.jvmName(descriptor, kind),
null,
superClass,
new String[] {JetTypeMapper.jvmNameForInterface(descriptor)}
@@ -158,31 +159,133 @@ public class ClassCodegen {
}
private void generatePrimaryConstructor(JetClass aClass, ClassVisitor v, OwnerKind kind) {
+ ConstructorDescriptor constructorDescriptor = bindingContext.getConstructorDescriptor(aClass);
+ if (constructorDescriptor == null) return;
+
+ ClassDescriptor classDescriptor = bindingContext.getClassDescriptor(aClass);
+
+ Method method = typeMapper.mapConstructorSignature(constructorDescriptor, kind);
int flags = Opcodes.ACC_PUBLIC; // TODO
- Method method = new Method("", Type.VOID_TYPE, new Type[0]);
final MethodVisitor mv = v.visitMethod(flags, "", method.getDescriptor(), null, null);
mv.visitCode();
+ Type[] argTypes = method.getArgumentTypes();
+ List paramDescrs = constructorDescriptor.getUnsubstitutedValueParameters();
+
FrameMap frameMap = new FrameMap();
frameMap.enterTemp(); // this
final InstructionAdapter iv = new InstructionAdapter(mv);
- String superClass = getSuperClass(aClass, kind);
- iv.load(0, Type.getType("L" + superClass + ";"));
- iv.invokespecial(superClass, "", method.getDescriptor());
+ ExpressionCodegen codegen = new ExpressionCodegen(mv, bindingContext, frameMap, typeMapper, Type.VOID_TYPE, classDescriptor, kind);
- final JetStandardLibrary standardLibrary = JetStandardLibrary.getJetStandardLibrary(project);
- final JetTypeMapper typeMapper = new JetTypeMapper(standardLibrary, bindingContext);
- ExpressionCodegen codegen = new ExpressionCodegen(mv, bindingContext, frameMap,
- typeMapper, Type.VOID_TYPE);
- generateInitializers(aClass, kind, codegen, iv, typeMapper);
+ String classname = JetTypeMapper.jvmName(classDescriptor, kind);
+ final Type classType = Type.getType("L" + classname + ";");
+
+ if (kind == OwnerKind.DELEGATING_IMPLEMENTATION) {
+ String interfaceDesc = JetTypeMapper.jetInterfaceType(classDescriptor).getDescriptor();
+ v.visitField(Opcodes.ACC_PRIVATE, "$this", interfaceDesc, /*TODO*/null, null);
+ iv.load(1, argTypes[0]);
+ iv.putfield(classname, "$this", interfaceDesc);
+ frameMap.enterTemp();
+ }
+
+ for (int i = 0; i < paramDescrs.size(); i++) {
+ ValueParameterDescriptor parameter = paramDescrs.get(i);
+ frameMap.enter(parameter, argTypes[i].getSize());
+ }
+
+ List specifiers = aClass.getDelegationSpecifiers();
+
+ if (specifiers.isEmpty() || !(specifiers.get(0) instanceof JetDelegatorToSuperCall)) {
+ String superClass = getSuperClass(aClass, kind);
+ iv.load(0, Type.getType("L" + superClass + ";"));
+ iv.invokespecial(superClass, "", /* TODO super constructor descriptor */"()V");
+ }
+
+ int n = 0;
+ for (JetDelegationSpecifier specifier : specifiers) {
+ boolean delegateOnStack = specifier instanceof JetDelegatorToSuperCall && n > 0 ||
+ specifier instanceof JetDelegatorByExpressionSpecifier ;
+
+ if (delegateOnStack) {
+ iv.load(0, classType);
+ }
+
+ if (specifier instanceof JetDelegatorToSuperCall) {
+ JetDelegatorToSuperCall superCall = (JetDelegatorToSuperCall) specifier;
+ ConstructorDescriptor constructorDescriptor1 = bindingContext.resolveSuperConstructor(superCall, this);
+
+ ClassDescriptor classDecl = constructorDescriptor1.getContainingDeclaration();
+ boolean isDelegating = kind == OwnerKind.DELEGATING_IMPLEMENTATION;
+ Type type = isDelegating ? JetTypeMapper.jetDelegatingImplementationType(classDecl) : JetTypeMapper.jetImplementationType(classDecl);
+
+ if (n > 0) {
+ if (kind == OwnerKind.DELEGATING_IMPLEMENTATION) {
+ codegen.thisToStack();
+ }
+ }
+
+ if (n == 0) {
+ iv.load(0, type);
+ }
+ else {
+ iv.anew(type);
+ iv.dup();
+ }
+
+ Method method1 = typeMapper.mapConstructorSignature(constructorDescriptor1, kind);
+ final Type[] argTypes1 = method1.getArgumentTypes();
+ List args = superCall.getValueArguments();
+ for (int i = 0, argsSize = args.size(); i < argsSize; i++) {
+ JetArgument arg = args.get(i);
+ codegen.gen(arg.getArgumentExpression(), argTypes1[i]);
+ }
+
+ iv.invokespecial(type.getClassName(), "", method1.getDescriptor());
+ }
+ else if (specifier instanceof JetDelegatorByExpressionSpecifier) {
+ codegen.genToJVMStack(((JetDelegatorByExpressionSpecifier) specifier).getDelegateExpression());
+ }
+
+ if (delegateOnStack) {
+ JetType superType = bindingContext.resolveTypeReference(specifier.getTypeReference());
+ ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
+ String delegateField = "$delegate_" + n;
+ Type fieldType = JetTypeMapper.jetInterfaceType(superClassDescriptor);
+ String fieldDesc = fieldType.getDescriptor();
+ v.visitField(Opcodes.ACC_PRIVATE, delegateField, fieldDesc, /*TODO*/null, null);
+ iv.putfield(classname, delegateField, fieldDesc);
+
+ JetClass superClass = (JetClass) bindingContext.getDeclarationPsiElement(superClassDescriptor);
+ generateDelegates(aClass, superClass, v,
+ new OwnerKind.DelegateKind(StackValue.field(fieldType, classname, delegateField, false),
+ JetTypeMapper.jvmNameForInterface(superClassDescriptor)));
+ }
+
+ n++;
+ }
+
+ generateInitializers(aClass, kind, codegen, iv);
+
+ int curParam = 0;
+ List constructorParameters = aClass.getPrimaryConstructorParameters();
+ for (JetParameter parameter : constructorParameters) {
+ if (parameter.getValOrVarNode() != null) {
+ VariableDescriptor descriptor = paramDescrs.get(curParam);
+ Type type = typeMapper.mapType(descriptor.getOutType());
+ iv.load(0, classType);
+ iv.load(frameMap.getIndex(descriptor), type);
+ iv.putfield(classname, descriptor.getName(), type.getDescriptor());
+ }
+ curParam++;
+ }
iv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
}
- private void generateInitializers(JetClass aClass, OwnerKind kind, ExpressionCodegen codegen, InstructionAdapter iv, JetTypeMapper typeMapper) {
+ private void generateInitializers(JetClass aClass, OwnerKind kind, ExpressionCodegen codegen, InstructionAdapter iv) {
for (JetDeclaration declaration : aClass.getDeclarations()) {
if (declaration instanceof JetProperty) {
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) bindingContext.getVariableDescriptor((JetProperty) declaration);
@@ -201,7 +304,7 @@ public class ClassCodegen {
private void generateClassBody(JetClass aClass, ClassVisitor v, OwnerKind kind) {
final JetStandardLibrary standardLibrary = JetStandardLibrary.getJetStandardLibrary(project);
- final FunctionCodegen functionCodegen = new FunctionCodegen(v, standardLibrary, bindingContext);
+ final FunctionCodegen functionCodegen = new FunctionCodegen(aClass, v, standardLibrary, bindingContext);
final PropertyCodegen propertyCodegen = new PropertyCodegen(v, standardLibrary, bindingContext, functionCodegen);
for (JetDeclaration declaration : aClass.getDeclarations()) {
@@ -212,5 +315,56 @@ public class ClassCodegen {
functionCodegen.gen((JetFunction) declaration, kind);
}
}
+
+ for (JetParameter p : aClass.getPrimaryConstructorParameters()) {
+ if (p.getValOrVarNode() != null) {
+ VariableDescriptor descriptor = bindingContext.getParameterDescriptor(p);
+ if (descriptor instanceof PropertyDescriptor) {
+ PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
+ propertyCodegen.generateDefaultGetter(propertyDescriptor, Opcodes.ACC_PUBLIC, kind);
+ if (propertyDescriptor.isVar()) {
+ propertyCodegen.generateDefaultSetter(propertyDescriptor, Opcodes.ACC_PUBLIC, kind);
+ }
+
+ if (!(kind instanceof OwnerKind.DelegateKind) && kind != OwnerKind.INTERFACE && bindingContext.hasBackingField(propertyDescriptor)) {
+ v.visitField(Opcodes.ACC_PRIVATE, p.getName(), typeMapper.mapType(propertyDescriptor.getOutType()).getDescriptor(), null, null);
+ }
+ }
+ }
+ }
+ }
+
+ private void generateDelegates(JetClass inClass, JetClass toClass, ClassVisitor v, OwnerKind kind) {
+ final JetStandardLibrary standardLibrary = JetStandardLibrary.getJetStandardLibrary(project);
+ final FunctionCodegen functionCodegen = new FunctionCodegen(toClass, v, standardLibrary, bindingContext);
+ final PropertyCodegen propertyCodegen = new PropertyCodegen(v, standardLibrary, bindingContext, functionCodegen);
+
+/* TODO
+ for (JetDeclaration declaration : toClass.getDeclarations()) {
+ if (declaration instanceof JetProperty) {
+ propertyCodegen.gen((JetProperty) declaration, kind);
+ }
+ else if (declaration instanceof JetFunction) {
+ functionCodegen.gen((JetFunction) declaration, kind);
+ }
+ }
+*/
+
+ for (JetParameter p : toClass.getPrimaryConstructorParameters()) {
+ if (p.getValOrVarNode() != null) {
+ VariableDescriptor descriptor = bindingContext.getParameterDescriptor(p);
+ if (descriptor instanceof PropertyDescriptor) {
+ PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
+ propertyCodegen.generateDefaultGetter(propertyDescriptor, Opcodes.ACC_PUBLIC, kind);
+ if (propertyDescriptor.isVar()) {
+ propertyCodegen.generateDefaultSetter(propertyDescriptor, Opcodes.ACC_PUBLIC, kind);
+ }
+
+ if (!(kind instanceof OwnerKind.DelegateKind) && kind != OwnerKind.INTERFACE && bindingContext.hasBackingField(propertyDescriptor)) {
+ v.visitField(Opcodes.ACC_PRIVATE, p.getName(), typeMapper.mapType(propertyDescriptor.getOutType()).getDescriptor(), null, null);
+ }
+ }
+ }
+ }
}
}
diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
index 93e0df63f92..ea00ced7f68 100644
--- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
+++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
@@ -1,7 +1,11 @@
package org.jetbrains.jet.codegen;
+import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
+import com.intellij.psi.search.ProjectScope;
import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.util.PsiTreeUtil;
+import jet.IntRange;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
@@ -15,6 +19,7 @@ import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
import org.objectweb.asm.commons.Method;
+import java.util.Iterator;
import java.util.List;
import java.util.Stack;
@@ -26,6 +31,18 @@ public class ExpressionCodegen extends JetVisitor {
private static final String CLASS_STRING = "java/lang/String";
private static final String CLASS_STRING_BUILDER = "java/lang/StringBuilder";
private static final String CLASS_COMPARABLE = "java/lang/Comparable";
+ private static final String CLASS_ITERABLE = "java/lang/Iterable";
+ private static final String CLASS_ITERATOR = "java/util/Iterator";
+
+ private static final String CLASS_INT_RANGE = "jet/IntRange";
+
+ private static final String ITERABLE_ITERATOR_DESCRIPTOR = "()Ljava/util/Iterator;";
+ private static final String ITERATOR_HASNEXT_DESCRIPTOR = "()Z";
+ private static final String ITERATOR_NEXT_DESCRIPTOR = "()Ljava/lang/Object;";
+ private static final String INT_RANGE_CONSTRUCTOR_DESCRIPTOR = "(II)V";
+
+ private static final Type ITERATOR_TYPE = Type.getType(Iterator.class);
+ private static final Type INT_RANGE_TYPE = Type.getType(IntRange.class);
private final Stack