diff --git a/.idea/ant.xml b/.idea/ant.xml
index 544e1256edb..37ffae42808 100644
--- a/.idea/ant.xml
+++ b/.idea/ant.xml
@@ -26,6 +26,14 @@
+
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
index 2df90c07743..4959db82cd6 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -4,6 +4,7 @@
+
diff --git a/build.xml b/build.xml
new file mode 100644
index 00000000000..9f10c18ad52
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java
index 6ffc688431f..4ab6dfeb815 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java
@@ -40,10 +40,10 @@ public abstract class ClassBodyCodegen {
public void generate() {
generateDeclaration();
- generateSyntheticParts();
-
generateClassBody();
+ generateSyntheticParts();
+
generateStaticInitializer();
v.visitEnd();
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java
index 60dc3bc46f0..86ebc6554ad 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java
@@ -4,8 +4,6 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.commons.InstructionAdapter;
/**
* @author max
@@ -25,7 +23,7 @@ public class ClassCodegen {
generateImplementation(parentContext, aClass, OwnerKind.IMPLEMENTATION);
- final ClassContext contextForInners = parentContext.intoClass(descriptor, OwnerKind.IMPLEMENTATION);
+ final ClassContext contextForInners = parentContext.intoClass(null, descriptor, OwnerKind.IMPLEMENTATION);
for (JetDeclaration declaration : aClass.getDeclarations()) {
if (declaration instanceof JetClass && !(declaration instanceof JetEnumEntry)) {
generate(contextForInners, (JetClass) declaration);
@@ -36,11 +34,11 @@ public class ClassCodegen {
private void generateImplementation(ClassContext parentContext, JetClassOrObject aClass, OwnerKind kind) {
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass);
ClassVisitor v = state.forClassImplementation(descriptor);
- new ImplementationBodyCodegen(aClass, parentContext.intoClass(descriptor, kind), v, state).generate();
+ new ImplementationBodyCodegen(aClass, parentContext.intoClass(null, descriptor, kind), v, state).generate();
if(aClass instanceof JetClass && ((JetClass)aClass).isTrait()) {
v = state.forTraitImplementation(descriptor);
- new TraitImplBodyCodegen(aClass, parentContext.intoClass(descriptor, OwnerKind.TRAIT_IMPL), v, state).generate();
+ new TraitImplBodyCodegen(aClass, parentContext.intoClass(null, descriptor, OwnerKind.TRAIT_IMPL), v, state).generate();
}
}
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassContext.java
index e0fe6e08cb3..3e1200388ab 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassContext.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassContext.java
@@ -1,6 +1,3 @@
-/*
- * @author max
- */
package org.jetbrains.jet.codegen;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
@@ -14,18 +11,22 @@ import org.objectweb.asm.commons.InstructionAdapter;
import java.util.HashMap;
+/*
+ * @author max
+ * @author alex.tkachman
+ */
public class ClassContext {
public static final ClassContext STATIC = new ClassContext(null, OwnerKind.NAMESPACE, null, null, null);
private final DeclarationDescriptor contextType;
private final OwnerKind contextKind;
private final StackValue thisExpression;
private final ClassContext parentContext;
- private final ClosureCodegen closure;
+ public final FunctionOrClosureCodegen closure;
private boolean thisWasUsed = false;
HashMap typeInfoConstants;
- public ClassContext(DeclarationDescriptor contextType, OwnerKind contextKind, StackValue thisExpression, ClassContext parentContext, ClosureCodegen closureCodegen) {
+ public ClassContext(DeclarationDescriptor contextType, OwnerKind contextKind, StackValue thisExpression, ClassContext parentContext, FunctionOrClosureCodegen closureCodegen) {
this.contextType = contextType;
this.contextKind = contextKind;
this.thisExpression = thisExpression;
@@ -60,11 +61,11 @@ public class ClassContext {
return new ClassContext(descriptor, OwnerKind.NAMESPACE, null, this, null);
}
- public ClassContext intoClass(ClassDescriptor descriptor, OwnerKind kind) {
+ public ClassContext intoClass(FunctionOrClosureCodegen closure, ClassDescriptor descriptor, OwnerKind kind) {
final StackValue thisValue;
thisValue = StackValue.local(0, JetTypeMapper.TYPE_OBJECT);
- return new ClassContext(descriptor, kind, thisValue, this, null);
+ return new ClassContext(descriptor, kind, thisValue, this, closure);
}
public ClassContext intoFunction(FunctionDescriptor descriptor) {
@@ -140,13 +141,21 @@ public class ClassContext {
}
public StackValue lookupInContext(DeclarationDescriptor d, InstructionAdapter v) {
- final ClosureCodegen top = closure;
+ final FunctionOrClosureCodegen top = closure;
if (top != null) {
final StackValue answer = top.lookupInContext(d);
if (answer != null) return answer;
final StackValue thisContext = getThisExpression();
- thisContext.put(thisContext.type, v);
+ if(thisContext instanceof StackValue.Local) {
+ }
+ else if(thisContext instanceof StackValue.InstanceField) {
+ StackValue.InstanceField instanceField = (StackValue.InstanceField) thisContext;
+ v.getfield(instanceField.owner, instanceField.name, instanceField.type.getDescriptor());
+ }
+ else {
+ throw new UnsupportedOperationException();
+ }
}
return parentContext != null ? parentContext.lookupInContext(d, v) : null;
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java
index 2e04ada073d..8e507409cb9 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java
@@ -26,19 +26,10 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-public class ClosureCodegen {
- public final GenerationState state;
- private final ExpressionCodegen exprContext;
- private final ClassContext context;
- private ClassVisitor cv = null;
- public String name = null;
-
- private Map closure = new LinkedHashMap();
+public class ClosureCodegen extends FunctionOrClosureCodegen {
public ClosureCodegen(GenerationState state, ExpressionCodegen exprContext, ClassContext context) {
- this.state = state;
- this.exprContext = exprContext;
- this.context = context;
+ super(exprContext, context, state);
}
public static Method erasedInvokeSignature(FunctionDescriptor fd) {
@@ -57,31 +48,6 @@ public class ClosureCodegen {
return state.getTypeMapper().mapSignature("invoke", fd);
}
- public StackValue lookupInContext(DeclarationDescriptor d) {
- if (d instanceof VariableDescriptor) {
- VariableDescriptor vd = (VariableDescriptor) d;
-
- EnclosedValueDescriptor answer = closure.get(vd);
- if (answer != null) return answer.getInnerValue();
-
- final int idx = exprContext.lookupLocal(vd);
- if (idx < 0) return null;
-
- final Type type = state.getTypeMapper().mapType(vd.getOutType());
-
- StackValue outerValue = StackValue.local(idx, type);
- final String fieldName = "$" + (closure.size() + 1);
- StackValue innerValue = StackValue.field(type, name, fieldName, false);
- cv.visitField(Opcodes.ACC_PUBLIC, fieldName, type.getDescriptor(), null, null);
- answer = new EnclosedValueDescriptor(d, innerValue, outerValue);
- closure.put(d, answer);
-
- return innerValue;
- }
-
- return null;
- }
-
public GeneratedAnonymousClassDescriptor gen(JetFunctionLiteralExpression fun) {
final Pair nameAndVisitor = state.forAnonymousSubclass(fun);
@@ -120,7 +86,7 @@ public class ClosureCodegen {
final Method constructor = generateConstructor(funClass, captureThis, funDescriptor.getReturnType());
if (captureThis) {
- cv.visitField(Opcodes.ACC_PRIVATE, "this$0", enclosingType.getDescriptor(), null, null);
+ cv.visitField(0, "this$0", enclosingType.getDescriptor(), null, null);
}
cv.visitEnd();
@@ -192,7 +158,9 @@ public class ClosureCodegen {
}
for (DeclarationDescriptor descriptor : closure.keySet()) {
- argTypes[i++] = state.getTypeMapper().mapType(((VariableDescriptor) descriptor).getOutType());
+ final Type sharedVarType = exprContext.getSharedVarType(descriptor);
+ final Type type = sharedVarType != null ? sharedVarType : state.getTypeMapper().mapType(((VariableDescriptor) descriptor).getOutType());
+ argTypes[i++] = type;
}
final Method constructor = new Method("", Type.VOID_TYPE, argTypes);
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
index a7137d43e8a..782ec25c56a 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
@@ -551,7 +551,7 @@ public class ExpressionCodegen extends JetVisitor {
final Method cons = closure.getConstructor();
if (closure.isCaptureThis()) {
- thisToStack();
+ v.load(0, JetTypeMapper.TYPE_OBJECT);
}
for (int i = 0; i < closure.getArgs().size(); i++) {
@@ -566,16 +566,43 @@ public class ExpressionCodegen extends JetVisitor {
@Override
public StackValue visitObjectLiteralExpression(JetObjectLiteralExpression expression, StackValue receiver) {
- GeneratedAnonymousClassDescriptor descriptor = state.generateObjectLiteral(expression, this, context);
- Type type = Type.getObjectType(descriptor.getClassname());
+ FunctionOrClosureCodegen closureCodegen = new FunctionOrClosureCodegen(this, context, state);
+ GeneratedAnonymousClassDescriptor closure = state.generateObjectLiteral(expression, closureCodegen);
+ Type type = Type.getObjectType(closure.getClassname());
v.anew(type);
v.dup();
- v.load(0, JetTypeMapper.TYPE_OBJECT);
- String jvmDescriptor = descriptor.getConstructor().getDescriptor().replace("(","(" + typeMapper.jetImplementationType((ClassDescriptor) contextType()));
- v.invokespecial(descriptor.getClassname(), "", jvmDescriptor);
- return StackValue.onStack(type);
+ final List consArgTypes = new LinkedList(Arrays.asList(closure.getConstructor().getArgumentTypes()));
+
+ if (consArgTypes.size() > 0) {
+ v.load(0, JetTypeMapper.TYPE_OBJECT);
+ }
+
+ for (DeclarationDescriptor descriptor : closureCodegen.closure.keySet()) {
+ final Type sharedVarType = getSharedVarType(descriptor);
+ consArgTypes.add(sharedVarType != null ? sharedVarType : state.getTypeMapper().mapType(((VariableDescriptor) descriptor).getOutType()));
+ final EnclosedValueDescriptor valueDescriptor = closureCodegen.closure.get(descriptor);
+ valueDescriptor.getOuterValue().put(sharedVarType, v);
+ }
+
+ Method cons = new Method("", Type.VOID_TYPE, consArgTypes.toArray(new Type[consArgTypes.size()]));
+ v.invokespecial(closure.getClassname(), "", cons.getDescriptor());
+ return StackValue.onStack(Type.getObjectType(closure.getClassname()));
}
+ Type getSharedVarType(DeclarationDescriptor variableDescriptor) {
+ if(!(variableDescriptor instanceof VariableDescriptor))
+ return null;
+
+ Boolean aBoolean = bindingContext.get(BindingContext.MUST_BE_WRAPPED_IN_A_REF, (VariableDescriptor) variableDescriptor);
+ if (aBoolean != null && aBoolean) {
+ JetType outType = ((VariableDescriptor) variableDescriptor).getOutType();
+ return StackValue.sharedTypeForType(typeMapper.mapType(outType));
+ }
+ else {
+ return null;
+ }
+ }
+
private StackValue generateBlock(List statements) {
Label blockStart = new Label();
v.mark(blockStart);
@@ -584,7 +611,9 @@ public class ExpressionCodegen extends JetVisitor {
if (statement instanceof JetProperty) {
final VariableDescriptor variableDescriptor = bindingContext.get(BindingContext.VARIABLE, statement);
assert variableDescriptor != null;
- final Type type = typeMapper.mapType(variableDescriptor.getOutType());
+
+ final Type sharedVarType = getSharedVarType(variableDescriptor);
+ final Type type = sharedVarType != null ? sharedVarType : typeMapper.mapType(variableDescriptor.getOutType());
myMap.enter(variableDescriptor, type.getSize());
}
}
@@ -608,10 +637,17 @@ public class ExpressionCodegen extends JetVisitor {
JetProperty var = (JetProperty) statement;
VariableDescriptor variableDescriptor = bindingContext.get(BindingContext.VARIABLE, var);
assert variableDescriptor != null;
- Type outType = typeMapper.mapType(variableDescriptor.getOutType());
int index = myMap.leave(variableDescriptor);
- v.visitLocalVariable(var.getName(), outType.getDescriptor(), null, blockStart, blockEnd, index);
+
+ final Type sharedVarType = getSharedVarType(variableDescriptor);
+ final Type type = sharedVarType != null ? sharedVarType : typeMapper.mapType(variableDescriptor.getOutType());
+ if(sharedVarType != null) {
+ v.aconst(null);
+ v.store(index, JetTypeMapper.TYPE_OBJECT);
+ }
+
+ v.visitLocalVariable(var.getName(), type.getDescriptor(), null, blockStart, blockEnd, index);
}
}
@@ -699,8 +735,14 @@ public class ExpressionCodegen extends JetVisitor {
else {
int index = lookupLocal(descriptor);
if (index >= 0) {
+ Type sharedVarType = getSharedVarType(descriptor);
final JetType outType = ((VariableDescriptor) descriptor).getOutType();
- return StackValue.local(index, typeMapper.mapType(outType));
+ if(sharedVarType != null) {
+ return StackValue.shared(index, typeMapper.mapType(outType));
+ }
+ else {
+ return StackValue.local(index, typeMapper.mapType(outType));
+ }
}
else if (descriptor instanceof PropertyDescriptor) {
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
@@ -785,6 +827,12 @@ public class ExpressionCodegen extends JetVisitor {
if (value == null) {
throw new UnsupportedOperationException("don't know how to generate reference " + descriptor);
}
+
+ if(value instanceof StackValue.FieldForSharedVar) {
+ StackValue.FieldForSharedVar fieldForSharedVar = (StackValue.FieldForSharedVar) value;
+ Type sharedType = StackValue.sharedTypeForType(value.type);
+ v.visitFieldInsn(Opcodes.GETFIELD, fieldForSharedVar.owner, fieldForSharedVar.name, sharedType.getDescriptor());
+ }
return value;
}
}
@@ -1617,12 +1665,27 @@ public class ExpressionCodegen extends JetVisitor {
assert index >= 0;
+ final Type sharedVarType = getSharedVarType(variableDescriptor);
+ assert variableDescriptor != null;
+ Type varType = typeMapper.mapType(variableDescriptor.getOutType());
+ if(sharedVarType != null) {
+ v.anew(sharedVarType);
+ v.dup();
+ v.invokespecial(sharedVarType.getInternalName(), "", "()V");
+ v.store(index, JetTypeMapper.TYPE_OBJECT);
+ }
+
JetExpression initializer = property.getInitializer();
if (initializer != null) {
- assert variableDescriptor != null;
- Type type = typeMapper.mapType(variableDescriptor.getOutType());
- gen(initializer, type);
- v.store(index, type);
+ if(sharedVarType == null) {
+ gen(initializer, varType);
+ v.store(index, varType);
+ }
+ else {
+ v.load(index, JetTypeMapper.TYPE_OBJECT);
+ gen(initializer, varType);
+ v.putfield(sharedVarType.getInternalName(), "ref", sharedVarType == JetTypeMapper.TYPE_SHARED_VAR ? "Ljava/lang/Object;" : varType.getDescriptor());
+ }
}
return StackValue.none();
}
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FrameMap.java b/compiler/backend/src/org/jetbrains/jet/codegen/FrameMap.java
index bf6c4710c31..3bcaf17e855 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/FrameMap.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/FrameMap.java
@@ -3,6 +3,7 @@ package org.jetbrains.jet.codegen;
import gnu.trove.TObjectIntHashMap;
import gnu.trove.TObjectIntIterator;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
+import org.jetbrains.jet.lang.resolve.BindingContext;
import java.util.ArrayList;
import java.util.List;
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java
index d7b0b188569..1fcd98e320c 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java
@@ -98,6 +98,23 @@ public class FunctionCodegen {
iv.areturn(jvmSignature.getReturnType());
}
else {
+ for (int i = 0; i < paramDescrs.size(); i++) {
+ ValueParameterDescriptor parameter = paramDescrs.get(i);
+
+ Type sharedVarType = codegen.getSharedVarType(parameter);
+ Type localVarType = state.getTypeMapper().mapType(parameter.getOutType());
+ if(sharedVarType != null) {
+ int index = frameMap.getIndex(parameter);
+ mv.visitTypeInsn(Opcodes.NEW, sharedVarType.getInternalName());
+ mv.visitInsn(Opcodes.DUP);
+ mv.visitInsn(Opcodes.DUP);
+ mv.visitMethodInsn(Opcodes.INVOKESPECIAL, sharedVarType.getInternalName(), "", "()V");
+ mv.visitVarInsn(localVarType.getOpcode(Opcodes.ILOAD), index);
+ mv.visitFieldInsn(Opcodes.PUTFIELD, sharedVarType.getInternalName(), "ref", StackValue.refType(localVarType).getDescriptor());
+ mv.visitVarInsn(sharedVarType.getOpcode(Opcodes.ISTORE), index);
+ }
+ }
+
codegen.returnExpression(bodyExpressions);
}
mv.visitMaxs(0, 0);
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionOrClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionOrClosureCodegen.java
new file mode 100644
index 00000000000..a6a57ece6b5
--- /dev/null
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionOrClosureCodegen.java
@@ -0,0 +1,57 @@
+package org.jetbrains.jet.codegen;
+
+import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
+import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * @author alex.tkachman
+ */
+public class FunctionOrClosureCodegen {
+ public final GenerationState state;
+ protected final ExpressionCodegen exprContext;
+ protected final ClassContext context;
+ protected ClassVisitor cv = null;
+ public String name = null;
+ protected Map closure = new LinkedHashMap();
+
+ public FunctionOrClosureCodegen(ExpressionCodegen exprContext, ClassContext context, GenerationState state) {
+ this.exprContext = exprContext;
+ this.context = context;
+ this.state = state;
+ }
+
+ public StackValue lookupInContext(DeclarationDescriptor d) {
+ if (d instanceof VariableDescriptor) {
+ VariableDescriptor vd = (VariableDescriptor) d;
+
+ EnclosedValueDescriptor answer = closure.get(vd);
+ if (answer != null) return answer.getInnerValue();
+
+ final int idx = exprContext.lookupLocal(vd);
+ if (idx < 0) return null;
+
+ final Type sharedVarType = exprContext.getSharedVarType(vd);
+ Type localType = state.getTypeMapper().mapType(vd.getOutType());
+ final Type type = sharedVarType != null ? sharedVarType : localType;
+
+ StackValue outerValue = StackValue.local(idx, type);
+ final String fieldName = "$" + (closure.size() + 1); // + "$" + vd.getName();
+ StackValue innerValue = sharedVarType != null ? StackValue.fieldForSharedVar(localType, name, fieldName) : StackValue.field(type, name, fieldName, false);
+
+ cv.visitField(Opcodes.ACC_PUBLIC, fieldName, type.getDescriptor(), null, null);
+
+ answer = new EnclosedValueDescriptor(d, innerValue, outerValue);
+ closure.put(d, answer);
+
+ return innerValue;
+ }
+
+ return null;
+ }
+}
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java b/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java
index 39862f0051e..51713dc8fb4 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java
@@ -9,6 +9,7 @@ import com.intellij.util.containers.Stack;
import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethods;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
+import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.lang.resolve.BindingContext;
@@ -120,13 +121,19 @@ public class GenerationState {
}
}
- public GeneratedAnonymousClassDescriptor generateObjectLiteral(JetObjectLiteralExpression literal, ExpressionCodegen context, ClassContext classContext) {
- Pair nameAndVisitor = forAnonymousSubclass(literal.getObjectDeclaration());
+ public GeneratedAnonymousClassDescriptor generateObjectLiteral(JetObjectLiteralExpression literal, FunctionOrClosureCodegen closure) {
+ JetObjectDeclaration objectDeclaration = literal.getObjectDeclaration();
+ Pair nameAndVisitor = forAnonymousSubclass(objectDeclaration);
- final ClassContext objectContext = classContext.intoClass(getBindingContext().get(BindingContext.CLASS, literal.getObjectDeclaration()), OwnerKind.IMPLEMENTATION);
+ closure.cv = nameAndVisitor.getSecond();
+ closure.name = nameAndVisitor.getFirst();
+ final ClassContext objectContext = closure.context.intoClass(closure, getBindingContext().get(BindingContext.CLASS, objectDeclaration), OwnerKind.IMPLEMENTATION);
- new ImplementationBodyCodegen(literal.getObjectDeclaration(), objectContext, nameAndVisitor.getSecond(), this).generate();
- return new GeneratedAnonymousClassDescriptor(nameAndVisitor.first, new Method("", "()V"), false);
+ new ImplementationBodyCodegen(objectDeclaration, objectContext, nameAndVisitor.getSecond(), this).generate();
+
+ ConstructorDescriptor constructorDescriptor = closure.state.getBindingContext().get(BindingContext.CONSTRUCTOR, objectDeclaration);
+ CallableMethod callableMethod = closure.state.getTypeMapper().mapToCallableMethod(constructorDescriptor, OwnerKind.IMPLEMENTATION);
+ return new GeneratedAnonymousClassDescriptor(nameAndVisitor.first, callableMethod.getSignature(), false);
}
public static void prepareAnonymousClasses(JetElement aClass, final JetTypeMapper typeMapper) {
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java
index bdf2d80bc06..5dd9bf9f711 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java
@@ -225,6 +225,22 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
callableMethod = state.getTypeMapper().mapToCallableMethod(constructorDescriptor, kind);
method = callableMethod.getSignature();
}
+
+ int firstClosureIndex = -1;
+ if(context.closure != null) {
+ final List consArgTypes = new LinkedList(Arrays.asList(method.getArgumentTypes()));
+
+ firstClosureIndex = consArgTypes.size()+1;
+
+ Map closure = context.closure.closure;
+ for (DeclarationDescriptor descriptor : closure.keySet()) {
+ final Type sharedVarType = context.closure.exprContext.getSharedVarType(descriptor);
+ consArgTypes.add(sharedVarType != null ? sharedVarType : state.getTypeMapper().mapType(((VariableDescriptor) descriptor).getOutType()));
+ }
+
+ method = new Method("", Type.VOID_TYPE, consArgTypes.toArray(new Type[consArgTypes.size()]));
+ }
+
int flags = Opcodes.ACC_PUBLIC; // TODO
final MethodVisitor mv = v.visitMethod(flags, "", method.getDescriptor(), null, null);
mv.visitCode();
@@ -300,7 +316,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
iv.putfield(classname, delegateField, fieldDesc);
JetClass superClass = (JetClass) state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, superClassDescriptor);
- final ClassContext delegateContext = context.intoClass(superClassDescriptor,
+ final ClassContext delegateContext = context.intoClass(null, superClassDescriptor,
new OwnerKind.DelegateKind(StackValue.field(fieldType, classname, delegateField, false),
JetTypeMapper.jvmNameForInterface(superClassDescriptor)));
generateDelegates(superClass, delegateContext, overridden);
@@ -322,6 +338,17 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
generateTypeInfoInitializer(frameMap.getFirstTypeParameter(), frameMap.getTypeParameterCount(), iv);
}
+ if(context.closure != null) {
+ Map closure = context.closure.closure;
+ int k = 0;
+ for (DeclarationDescriptor varDescr : closure.keySet()) {
+ final Type sharedVarType = context.closure.exprContext.getSharedVarType(varDescr);
+ iv.load(0, JetTypeMapper.TYPE_OBJECT);
+ iv.load(firstClosureIndex + k, StackValue.refType(sharedVarType));
+ iv.putfield(state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION), "$" + (k+1), sharedVarType.getDescriptor());
+ }
+ }
+
generateInitializers(codegen, iv);
generateTraitMethods(codegen);
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java
index b8e221c52a9..9cf08cd2482 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java
@@ -59,6 +59,15 @@ public class JetTypeMapper {
public static final Type TYPE_FUNCTION1 = Type.getObjectType("jet/Function1");
public static final Type TYPE_ITERATOR = Type.getObjectType("jet/Iterator");
public static final Type TYPE_INT_RANGE = Type.getObjectType("jet/IntRange");
+ public static final Type TYPE_SHARED_VAR = Type.getObjectType("jet/refs/SharedVar$Object");
+ public static final Type TYPE_SHARED_INT = Type.getObjectType("jet/refs/SharedVar$Int");
+ public static final Type TYPE_SHARED_DOUBLE = Type.getObjectType("jet/refs/SharedVar$Double");
+ public static final Type TYPE_SHARED_FLOAT = Type.getObjectType("jet/refs/SharedVar$Float");
+ public static final Type TYPE_SHARED_BYTE = Type.getObjectType("jet/refs/SharedVar$Byte");
+ public static final Type TYPE_SHARED_SHORT = Type.getObjectType("jet/refs/SharedVar$Short");
+ public static final Type TYPE_SHARED_CHAR = Type.getObjectType("jet/refs/SharedVar$Char");
+ public static final Type TYPE_SHARED_LONG = Type.getObjectType("jet/refs/SharedVar$Long");
+ public static final Type TYPE_SHARED_BOOLEAN = Type.getObjectType("jet/refs/SharedVar$Boolean");
public JetTypeMapper(JetStandardLibrary standardLibrary, BindingContext bindingContext) {
this.standardLibrary = standardLibrary;
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java
index f60fc9804cc..52ff48a6183 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java
@@ -11,6 +11,7 @@ import org.objectweb.asm.commons.Method;
/**
* @author yole
+ * @author alex.tkachman
*/
public abstract class StackValue {
public final Type type;
@@ -59,6 +60,10 @@ public abstract class StackValue {
return new Local(index, type);
}
+ public static StackValue shared(int index, Type type) {
+ return new Shared(index, type);
+ }
+
public static StackValue onStack(Type type) {
return type == Type.VOID_TYPE ? none() : new OnStack(type);
}
@@ -225,7 +230,11 @@ public abstract class StackValue {
public static StackValue none() {
return None.INSTANCE;
}
-
+
+ public static StackValue fieldForSharedVar(Type type, String name, String fieldName) {
+ return new FieldForSharedVar(type, name, fieldName);
+ }
+
private static class None extends StackValue {
public static None INSTANCE = new None();
private None() {
@@ -496,9 +505,9 @@ public abstract class StackValue {
}
- private static class Field extends StackValue {
- private final String owner;
- private final String name;
+ static class Field extends StackValue {
+ final String owner;
+ final String name;
private final boolean isStatic;
public Field(Type type, String owner, String name, boolean isStatic) {
@@ -531,9 +540,9 @@ public abstract class StackValue {
}
}
- private static class InstanceField extends StackValue {
- private final String owner;
- private final String name;
+ static class InstanceField extends StackValue {
+ final String owner;
+ final String name;
public InstanceField(Type type, String owner, String name) {
super(type);
@@ -625,4 +634,106 @@ public abstract class StackValue {
generator.gen(expression, type);
}
}
+
+ public static class Shared extends StackValue {
+ private final int index;
+
+ public Shared(int index, Type type) {
+ super(type);
+ this.index = index;
+ }
+
+ @Override
+ public void put(Type type, InstructionAdapter v) {
+ v.load(index, JetTypeMapper.TYPE_OBJECT);
+ Type refType = refType(this.type);
+ Type sharedType = sharedTypeForType(this.type);
+ v.visitFieldInsn(Opcodes.GETFIELD, sharedType.getInternalName(), "ref", refType.getDescriptor());
+ StackValue.onStack(refType).coerce(this.type, v);
+ StackValue.onStack(this.type).coerce(type, v);
+ }
+
+ @Override
+ public void store(InstructionAdapter v) {
+ v.load(index, JetTypeMapper.TYPE_OBJECT);
+ v.swap();
+ Type refType = refType(this.type);
+ Type sharedType = sharedTypeForType(this.type);
+ v.visitFieldInsn(Opcodes.PUTFIELD, sharedType.getInternalName(), "ref", refType.getDescriptor());
+ }
+ }
+
+ public static Type sharedTypeForType(Type type) {
+ switch(type.getSort()) {
+ case Type.OBJECT:
+ case Type.ARRAY:
+ return JetTypeMapper.TYPE_SHARED_VAR;
+
+ case Type.BYTE:
+ return JetTypeMapper.TYPE_SHARED_BYTE;
+
+ case Type.SHORT:
+ return JetTypeMapper.TYPE_SHARED_SHORT;
+
+ case Type.CHAR:
+ return JetTypeMapper.TYPE_SHARED_CHAR;
+
+ case Type.INT:
+ return JetTypeMapper.TYPE_SHARED_INT;
+
+ case Type.BOOLEAN:
+ return JetTypeMapper.TYPE_SHARED_BOOLEAN;
+
+ case Type.FLOAT:
+ return JetTypeMapper.TYPE_SHARED_FLOAT;
+
+ case Type.DOUBLE:
+ return JetTypeMapper.TYPE_SHARED_DOUBLE;
+
+ default:
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ public static Type refType(Type type) {
+ if(type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY)
+ return JetTypeMapper.TYPE_OBJECT;
+
+ return type;
+ }
+
+ static class FieldForSharedVar extends StackValue {
+ final String owner;
+ final String name;
+
+ public FieldForSharedVar(Type type, String owner, String name) {
+ super(type);
+ this.owner = owner;
+ this.name = name;
+ }
+
+ @Override
+ public void dupReceiver(InstructionAdapter v, int below) {
+ if (below == 1) {
+ v.dupX1();
+ }
+ else {
+ v.dup();
+ }
+ }
+
+ @Override
+ public void put(Type type, InstructionAdapter v) {
+ Type sharedType = sharedTypeForType(this.type);
+ Type refType = refType(this.type);
+ v.visitFieldInsn(Opcodes.GETFIELD, sharedType.getInternalName(), "ref", refType.getDescriptor());
+ StackValue.onStack(refType).coerce(this.type, v);
+ StackValue.onStack(this.type).coerce(type, v);
+ }
+
+ @Override
+ public void store(InstructionAdapter v) {
+ v.visitFieldInsn(Opcodes.PUTFIELD, sharedTypeForType(type).getInternalName(), "ref", refType(type).getDescriptor());
+ }
+ }
}
diff --git a/compiler/cli/bin/kotlinc b/compiler/cli/bin/kotlinc
new file mode 100644
index 00000000000..6763c5e7605
--- /dev/null
+++ b/compiler/cli/bin/kotlinc
@@ -0,0 +1,96 @@
+#!/bin/bash --posix
+#
+##############################################################################
+# Copyright 2002-2011, LAMP/EPFL
+# Copyright 2011, JetBrains
+#
+# This is free software; see the distribution for copying conditions.
+# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+##############################################################################
+
+cygwin=false;
+case "`uname`" in
+ CYGWIN*) cygwin=true ;;
+esac
+
+# Finding the root folder for this Kotlin distribution
+SOURCE=$0;
+SCRIPT=`basename "$SOURCE"`;
+while [ -h "$SOURCE" ]; do
+ SCRIPT=`basename "$SOURCE"`;
+ LOOKUP=`ls -ld "$SOURCE"`;
+ TARGET=`expr "$LOOKUP" : '.*-> \(.*\)$'`;
+ if expr "${TARGET:-.}/" : '/.*/$' > /dev/null; then
+ SOURCE=${TARGET:-.};
+ else
+ SOURCE=`dirname "$SOURCE"`/${TARGET:-.};
+ fi;
+done;
+
+# see #2092
+KOTLIN_HOME=`dirname "$SOURCE"`
+KOTLIN_HOME=`cd "$KOTLIN_HOME"; pwd -P`
+KOTLIN_HOME=`cd "$KOTLIN_HOME"/..; pwd`
+
+# Remove spaces from KOTLIN_HOME on windows
+if $cygwin; then
+ KOTLIN_HOME=`cygpath --windows --short-name "$KOTLIN_HOME"`
+ KOTLIN_HOME=`cygpath --unix "$KOTLIN_HOME"`
+fi
+
+# Constructing the extension classpath
+TOOL_CLASSPATH=""
+if [ -z "$TOOL_CLASSPATH" ] ; then
+ for ext in "$KOTLIN_HOME"/lib/* ; do
+ if [ -z "$TOOL_CLASSPATH" ] ; then
+ TOOL_CLASSPATH="$ext"
+ else
+ TOOL_CLASSPATH="$TOOL_CLASSPATH:$ext"
+ fi
+ done
+fi
+
+[ -n "$JAVA_OPTS" ] || JAVA_OPTS="-Xmx256M -Xms32M"
+
+# break out -D and -J options and add them to JAVA_OPTS as well
+# so they reach the underlying JVM in time to do some good. The
+# -D options will be available as system properties.
+declare -a java_args
+declare -a kotlin_args
+
+while [ $# -gt 0 ]; do
+ case "$1" in
+ -D*)
+ # pass to kotlin as well: otherwise we lose it sometimes when we
+ # need it, e.g. communicating with a server compiler.
+ java_args=("${java_args[@]}" "$1")
+ kotlin_args=("${kotlin_args[@]}" "$1")
+ shift
+ ;;
+ -J*)
+ # as with -D, pass to scala even though it will almost
+ # never be used.
+ java_args=("${java_args[@]}" "${1:2}")
+ kotlin_args=("${kotlin_args[@]}" "$1")
+ shift
+ ;;
+ *)
+ kotlin_args=("${kotlin_args[@]}" "$1")
+ shift
+ ;;
+ esac
+done
+
+# reset "$@" to the remaining args
+set -- "${kotlin_args[@]}"
+
+if [ -z "$JAVACMD" -a -n "$JAVA_HOME" -a -x "$JAVA_HOME/bin/java" ]; then
+ JAVACMD="$JAVA_HOME/bin/java"
+fi
+
+"${JAVACMD:=java}" \
+ $JAVA_OPTS \
+ "${java_args[@]}" \
+ ${CPSELECT}${TOOL_CLASSPATH} \
+ org.jetbrains.jet.cli.KotlinCompiler "$@"
diff --git a/compiler/cli/bin/kotlinc.bat b/compiler/cli/bin/kotlinc.bat
new file mode 100644
index 00000000000..20d2e1795d8
--- /dev/null
+++ b/compiler/cli/bin/kotlinc.bat
@@ -0,0 +1,51 @@
+rem based on scalac.bat from the Scala distribution
+rem ##########################################################################
+rem # Copyright 2002-2011, LAMP/EPFL
+rem # Copyright 2011, JetBrains
+rem #
+rem # This is free software; see the distribution for copying conditions.
+rem # There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
+rem # PARTICULAR PURPOSE.
+rem ##########################################################################
+@echo off
+
+@setlocal
+call :set_home
+
+if not "%JAVA_HOME%"=="" (
+ if exist "%JAVA_HOME%\bin\java.exe" set "_JAVACMD=%JAVA_HOME%\bin\java.exe"
+)
+
+if "%_JAVACMD%"=="" set _JAVACMD=java
+
+rem We use the value of the JAVA_OPTS environment variable if defined
+set _JAVA_OPTS=-Xmx256M -Xms32M
+
+set _TOOL_CLASSPATH=
+if "%_TOOL_CLASSPATH%"=="" (
+ for %%f in ("%_KOTLIN_HOME%\lib\*") do call :add_cpath "%%f"
+ for /d %%f in ("%_KOTLIN_HOME%\lib\*") do call :add_cpath "%%f"
+)
+
+"%_JAVACMD%" %_JAVA_OPTS% cp "%_TOOL_CLASSPATH%" org.jetbrains.jet.cli.KotlinCompiler %*
+goto end
+
+rem ##########################################################################
+rem # subroutines
+
+:add_cpath
+ if "%_TOOL_CLASSPATH%"=="" (
+ set _TOOL_CLASSPATH=%~1
+ ) else (
+ set _TOOL_CLASSPATH=%_TOOL_CLASSPATH%;%~1
+ )
+goto :eof
+
+:set_home
+ set _BIN_DIR=
+ for %%i in (%~sf0) do set _BIN_DIR=%_BIN_DIR%%%~dpsi
+ set _KOTLIN_HOME=%_BIN_DIR%..
+goto :eof
+
+:end
+@endlocal
diff --git a/compiler/cli/cli.iml b/compiler/cli/cli.iml
new file mode 100644
index 00000000000..de82ce75e19
--- /dev/null
+++ b/compiler/cli/cli.iml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java
new file mode 100644
index 00000000000..576f436dd8d
--- /dev/null
+++ b/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java
@@ -0,0 +1,114 @@
+package org.jetbrains.jet.cli;
+
+import com.google.common.collect.Lists;
+import com.intellij.core.JavaCoreEnvironment;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
+import org.jetbrains.jet.codegen.ClassFileFactory;
+import org.jetbrains.jet.codegen.GenerationState;
+import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
+import org.jetbrains.jet.lang.diagnostics.Diagnostic;
+import org.jetbrains.jet.lang.parsing.JetParserDefinition;
+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.resolve.java.JavaDefaultImports;
+import org.jetbrains.jet.plugin.JetFileType;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * @author yole
+ */
+public class KotlinCompiler {
+ public static void main(String[] args) {
+ System.setProperty("java.awt.headless", "true");
+ if (args.length < 1) {
+ System.out.println("Usage: KotlinCompiler ");
+ return;
+ }
+ String javaHome = System.getenv("JAVA_HOME");
+ if (javaHome == null) {
+ System.out.println("JAVA_HOME environment variable needs to be defined");
+ return;
+ }
+ File rtJar = findRtJar(javaHome);
+ if (rtJar == null || !rtJar.exists()) {
+ System.out.print("No rt.jar found under JAVA_HOME");
+ return;
+ }
+
+ Disposable root = new Disposable() {
+ @Override
+ public void dispose() {
+ }
+ };
+ JavaCoreEnvironment environment = new JavaCoreEnvironment(root);
+ environment.addToClasspath(rtJar);
+
+ environment.registerFileType(JetFileType.INSTANCE, "kt");
+ environment.registerParserDefinition(new JetParserDefinition());
+ VirtualFile vFile = environment.getLocalFileSystem().findFileByPath(args [0]);
+
+ Project project = environment.getProject();
+ GenerationState generationState = new GenerationState(project, false);
+ List namespaces = Lists.newArrayList();
+ PsiFile psiFile = PsiManager.getInstance(project).findFile(vFile);
+ if (psiFile instanceof JetFile) {
+ namespaces.add(((JetFile) psiFile).getRootNamespace());
+ }
+
+ BindingContext bindingContext = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS).analyzeNamespaces(project, namespaces, JetControlFlowDataTraceFactory.EMPTY);
+
+ boolean errors = false;
+ for (Diagnostic diagnostic : bindingContext.getDiagnostics()) {
+ switch (diagnostic.getSeverity()) {
+ case ERROR:
+ errors = true;
+ report(diagnostic);
+ break;
+ case INFO:
+ report(diagnostic);
+ break;
+ case WARNING:
+ report(diagnostic);
+ break;
+ }
+ }
+
+ if (!errors) {
+ generationState.compileCorrectNamespaces(bindingContext, namespaces);
+
+ final ClassFileFactory factory = generationState.getFactory();
+ List files = factory.files();
+ for (String file : files) {
+ File target = new File(vFile.getParent().getPath(), file);
+ try {
+ FileUtil.writeToFile(target, factory.asBytes(file));
+ } catch (IOException e) {
+ System.out.println(e.getMessage());
+ }
+ }
+ }
+
+ }
+
+ private static void report(Diagnostic diagnostic) {
+ System.out.println(diagnostic.getMessage());
+ }
+
+ private static File findRtJar(String javaHome) {
+ File rtJar = new File(javaHome, "jre/lib/rt.jar");
+ if (rtJar.exists()) {
+ return rtJar;
+ }
+ return null;
+ }
+}
diff --git a/compiler/frontend/src/org/jetbrains/jet/plugin/JetFileType.java b/compiler/frontend/src/org/jetbrains/jet/plugin/JetFileType.java
index 1dcc9763674..4d9461ae798 100644
--- a/compiler/frontend/src/org/jetbrains/jet/plugin/JetFileType.java
+++ b/compiler/frontend/src/org/jetbrains/jet/plugin/JetFileType.java
@@ -5,13 +5,20 @@ package org.jetbrains.jet.plugin;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.util.IconLoader;
+import com.intellij.openapi.util.NotNullLazyValue;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
public class JetFileType extends LanguageFileType {
public static final JetFileType INSTANCE = new JetFileType();
- private final Icon myIcon = IconLoader.getIcon("/org/jetbrains/jet/plugin/icons/kotlin16x16.png");
+ private final NotNullLazyValue myIcon = new NotNullLazyValue() {
+ @NotNull
+ @Override
+ protected Icon compute() {
+ return IconLoader.getIcon("/org/jetbrains/jet/plugin/icons/kotlin16x16.png");
+ }
+ };
private JetFileType() {
super(JetLanguage.INSTANCE);
@@ -33,7 +40,7 @@ public class JetFileType extends LanguageFileType {
}
public Icon getIcon() {
- return myIcon;
+ return myIcon.getValue();
}
@Override
diff --git a/idea/testData/codegen/classes/enclosingLocalVariable.jet b/idea/testData/codegen/classes/enclosingLocalVariable.jet
index aaf5081cefb..d2dbe243469 100644
--- a/idea/testData/codegen/classes/enclosingLocalVariable.jet
+++ b/idea/testData/codegen/classes/enclosingLocalVariable.jet
@@ -1,6 +1,6 @@
fun box() : String {
val cl = 39
- return if (sum(200, { cl }) == 239) "OK" else "FAIL"
+ return if (sum(200, { val m = { val r = { cl }; r() }; m() }) == 239) "OK" else "FAIL"
}
fun sum(arg:Int, f : fun () : Int) : Int {
diff --git a/idea/testData/codegen/controlStructures/ifBlock.jet b/idea/testData/codegen/controlStructures/ifBlock.jet
new file mode 100644
index 00000000000..4905fb2efc6
--- /dev/null
+++ b/idea/testData/codegen/controlStructures/ifBlock.jet
@@ -0,0 +1,10 @@
+import java.util.*
+
+fun concat(l: List): String? {
+ val sb = StringBuilder()
+ for(s in l) {
+ val x = if(l.size() > 1) { "T" } else { "F" };
+ sb.append(x)
+ }
+ return sb.toString()
+}
diff --git a/idea/testData/codegen/objects/objectLiteral.jet b/idea/testData/codegen/objects/objectLiteral.jet
index 1ea5a0355bc..a457840fefc 100644
--- a/idea/testData/codegen/objects/objectLiteral.jet
+++ b/idea/testData/codegen/objects/objectLiteral.jet
@@ -1,10 +1,17 @@
-class C() {
- val child = object {
- fun toString(): String = "child"
+class C(x: Int, val y : Int) {
+ fun initChild(x: Int) : java.lang.Object {
+ return object : java.lang.Object() {
+ override fun toString(): String? {
+ x = x + y
+ return "child" + x
+ }
+ }
}
+
+ val child = initChild(x)
}
fun box(): String {
- val c = C()
- return if (c.child.toString() == "child") "OK" else "fail"
+ val c = C(10,3)
+ return if (c.child.toString() == "child13" && c.child.toString() == "child16" && c.child.toString() == "child19") "OK" else "fail"
}
diff --git a/idea/testData/codegen/regressions/kt344.jet b/idea/testData/codegen/regressions/kt344.jet
new file mode 100644
index 00000000000..3274de6aa23
--- /dev/null
+++ b/idea/testData/codegen/regressions/kt344.jet
@@ -0,0 +1,196 @@
+/*
+fun s0() : Boolean {
+ val y = "222"
+ val foo = {
+ val bar = { y }
+ bar ()
+ }
+ return foo() == "222"
+}
+
+fun s1() : Boolean {
+ var x = "222"
+ val foo = {
+ val bar = {
+ x = "aaa"
+ }
+ bar ()
+ }
+ foo()
+ return x == "aaa"
+}
+
+fun t1() : Boolean {
+ var x = "111"
+
+ val y = x + "22"
+ val foo = {
+ x = x + "45" + y
+ x = x.substring(3)
+ x += "aaa"
+ ()
+ }
+ foo()
+
+ x += "bbb"
+ System.out?.println(x)
+ return x == "4511122aaabbb"
+}
+
+fun t2() : Boolean {
+ var x = 111
+ val y = x + 22
+ val foo = {
+ x = x + 5 + y
+ x += 5
+ x++
+ ()
+ }
+ foo()
+ x -= 55
+ System.out?.println(x)
+ return x == 200
+}
+
+fun t3() : Boolean {
+ var x = true
+ val foo = {
+ x = false
+ ()
+ }
+ foo()
+ return !x
+}
+
+fun t4() : Boolean {
+ var x = 100.flt
+ val y = x + 22
+ val foo = {
+ x = x + 200.flt + y
+ x += 18
+ ()
+ }
+ foo()
+ System.out?.println(x)
+ return x == 440.flt
+}
+
+fun t5() : Boolean {
+ var x = 100.dbl
+ val y = x + 22
+ val foo = {
+ x = x + 200.dbl + y
+ x -= 22
+ ()
+ }
+ foo()
+ System.out?.println(x)
+ return x == 400.dbl
+}
+
+fun t6() : Boolean {
+ var x = 20.byt
+ val y = x + 22
+ val foo = {
+ x = (x + 20.byt + y).byt
+ x += 2
+ x--
+ ()
+ }
+ foo()
+ System.out?.println(x)
+ return x == 83.byt
+}
+
+fun t7() : Boolean {
+ var x : Char = 'a'
+ val foo = {
+ x = 'b'
+ ()
+ }
+ foo()
+ System.out?.println(x)
+ return x == 'b'
+}
+
+fun t8() : Boolean {
+ var x = 20.sht
+ val foo = {
+ val bar = {
+ x = 30.sht
+ ()
+ }
+ bar()
+ ()
+ }
+ foo()
+ return x == 30.sht
+}
+
+fun t9(x: Int) : Boolean {
+ while(x < 100) {
+ x++
+ }
+ return x == 100
+}
+
+fun t10() : Boolean {
+ var y = 1
+ val foo = {
+ val bar = {
+ y = y + 1
+ }
+ bar()
+ }
+ foo()
+ return y == 2
+}
+
+fun t11(x: Int) : Int {
+ val foo = {
+ x = x + 1
+ val bar = {
+ x = x + 1
+ x += 3
+ }
+ bar()
+ }
+ while(x < 100) {
+ foo()
+ }
+ return x
+}
+*/
+fun t12(x: Int) : Int {
+ var y = x
+ val runnable = object : Runnable {
+ override fun run () {
+ y = y + 1
+ }
+ }
+ while(y < 100) {
+ runnable.run()
+ }
+ return y
+}
+
+fun box(): String {
+/*
+ if (!s0()) return "fail"
+ if (!s1()) return "fail"
+ if (!t1()) return "fail"
+ if (!t2()) return "fail"
+ if (!t3()) return "fail"
+ if (!t4()) return "fail"
+ if (!t5()) return "fail"
+ if (!t6()) return "fail"
+ if (!t7()) return "fail"
+ if (!t8()) return "fail"
+ if (!t9(0)) return "fail"
+ if (!t10()) return "fail"
+ if (t11(1) != 104) return "fail"
+*/
+ if (t12(0) != 100) return "fail"
+
+ return "OK"
+}
\ No newline at end of file
diff --git a/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java b/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java
index 72a131c61c6..97e4098243d 100644
--- a/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java
+++ b/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java
@@ -190,4 +190,10 @@ public class ClassGenTest extends CodegenTestCase {
blackBoxFile("regressions/kt343.jet");
System.out.println(generateToText());
}
+
+ public void testKt344 () throws Exception {
+ loadFile("regressions/kt344.jet");
+ System.out.println(generateToText());
+ blackBox();
+ }
}
diff --git a/idea/tests/org/jetbrains/jet/codegen/ClosuresGenTest.java b/idea/tests/org/jetbrains/jet/codegen/ClosuresGenTest.java
index 7d5f4a68fc8..07b094c344d 100644
--- a/idea/tests/org/jetbrains/jet/codegen/ClosuresGenTest.java
+++ b/idea/tests/org/jetbrains/jet/codegen/ClosuresGenTest.java
@@ -27,6 +27,7 @@ public class ClosuresGenTest extends CodegenTestCase {
public void testEnclosingLocalVariable() throws Exception {
blackBoxFile("classes/enclosingLocalVariable.jet");
+ System.out.println(generateToText());
}
public void testDoubleEnclosedLocalVariable() throws Exception {
diff --git a/idea/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java b/idea/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java
index 581ef507d36..698c668b042 100644
--- a/idea/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java
+++ b/idea/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java
@@ -86,6 +86,16 @@ public class ControlStructuresTest extends CodegenTestCase {
assertEquals("IntelliJ IDEA", main.invoke(null, args));
}
+ public void testIfBlock() throws Exception {
+ loadFile();
+ System.out.println(generateToText());
+ final Method main = generateFunction();
+ List args = Arrays.asList("IntelliJ", " ", "IDEA");
+ assertEquals("TTT", main.invoke(null, args));
+ args = Arrays.asList("JetBrains");
+ assertEquals("F", main.invoke(null, args));
+ }
+
public void testForInArray() throws Exception {
loadFile();
System.out.println(generateToText());
diff --git a/idea/tests/org/jetbrains/jet/codegen/ObjectGenTest.java b/idea/tests/org/jetbrains/jet/codegen/ObjectGenTest.java
index 286900722d5..9980b8c9fae 100644
--- a/idea/tests/org/jetbrains/jet/codegen/ObjectGenTest.java
+++ b/idea/tests/org/jetbrains/jet/codegen/ObjectGenTest.java
@@ -10,6 +10,7 @@ public class ObjectGenTest extends CodegenTestCase {
public void testObjectLiteral() throws Exception {
blackBoxFile("objects/objectLiteral.jet");
+ System.out.println(generateToText());
}
public void testMethodOnObject() throws Exception {
diff --git a/idea/tests/org/jetbrains/jet/codegen/PropertyGenTest.java b/idea/tests/org/jetbrains/jet/codegen/PropertyGenTest.java
index cd81cc54e01..ed9beaf4e74 100644
--- a/idea/tests/org/jetbrains/jet/codegen/PropertyGenTest.java
+++ b/idea/tests/org/jetbrains/jet/codegen/PropertyGenTest.java
@@ -19,7 +19,7 @@ public class PropertyGenTest extends CodegenTestCase {
final Class aClass = loadImplementationClass(generateClassesInFile(), "PrivateVal");
final Field[] fields = aClass.getDeclaredFields();
assertEquals(2, fields.length); // $typeInfo, prop
- final Field field = fields[1];
+ final Field field = fields[0];
assertEquals("prop", field.getName());
}
diff --git a/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java b/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java
index ef032cd7b37..2f07aa92e9f 100644
--- a/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java
+++ b/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java
@@ -21,9 +21,7 @@ import org.jetbrains.jet.lang.resolve.calls.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
-import org.jetbrains.jet.lang.types.JetStandardLibrary;
-import org.jetbrains.jet.lang.types.JetType;
-import org.jetbrains.jet.lang.types.TypeProjection;
+import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.parsing.JetParsingTest;
import java.io.File;
@@ -111,7 +109,7 @@ public class JetResolveTest extends ExtensibleResolveTestCase {
@NotNull
private FunctionDescriptor standardFunction(ClassDescriptor classDescriptor, List typeArguments, String name, JetType... parameterType) {
List parameterTypeList = Arrays.asList(parameterType);
-// ExpressionTypingServices typeInferrerServices = JetSemanticServices.createSemanticServices(getProject()).getTypeInferrerServices(new BindingTraceContext());
+// JetTypeInferrer.Services typeInferrerServices = JetSemanticServices.createSemanticServices(getProject()).getTypeInferrerServices(new BindingTraceContext());
CallResolver callResolver = new CallResolver(JetSemanticServices.createSemanticServices(getProject()), DataFlowInfo.getEmpty());
OverloadResolutionResults functions = callResolver.resolveExactSignature(
diff --git a/stdlib/src/jet/refs/SharedVar.java b/stdlib/src/jet/refs/SharedVar.java
new file mode 100644
index 00000000000..0bd99c66965
--- /dev/null
+++ b/stdlib/src/jet/refs/SharedVar.java
@@ -0,0 +1,39 @@
+package jet.refs;
+
+public final class SharedVar {
+ public static final class Object {
+ public T ref;
+ }
+
+ public static final class Byte {
+ public byte ref;
+ }
+
+ public static final class Short {
+ public short ref;
+ }
+
+ public static final class Int {
+ public int ref;
+ }
+
+ public static final class Long {
+ public long ref;
+ }
+
+ public static final class Float {
+ public float ref;
+ }
+
+ public static final class Double {
+ public double ref;
+ }
+
+ public static final class Char {
+ public char ref;
+ }
+
+ public static final class Boolean {
+ public boolean ref;
+ }
+}