diff --git a/.idea/modules.xml b/.idea/modules.xml
index 4959db82cd6..463eb8bb67f 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -5,6 +5,7 @@
+
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java b/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java
index 01b0d082f3b..9b5888566d1 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java
@@ -2,6 +2,8 @@ package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
+import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
+import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
import org.objectweb.asm.commons.Method;
@@ -17,9 +19,9 @@ public class CallableMethod implements Callable {
private final int invokeOpcode;
private final List valueParameterTypes;
private boolean acceptsTypeArguments = false;
- private boolean needsReceiverOnStack = false;
private boolean ownerFromCall = false;
- private ClassDescriptor receiverClass = null;
+ private DeclarationDescriptor thisClass = null;
+ private DeclarationDescriptor receiverClass = null;
private Type generateCalleeType = null;
public CallableMethod(String owner, Method signature, int invokeOpcode, List valueParameterTypes) {
@@ -57,13 +59,12 @@ public class CallableMethod implements Callable {
this.acceptsTypeArguments = acceptsTypeArguments;
}
- public void setNeedsReceiver(@Nullable ClassDescriptor receiverClass) {
- needsReceiverOnStack = true;
+ public void setNeedsReceiver(@Nullable DeclarationDescriptor receiverClass) {
this.receiverClass = receiverClass;
}
- public boolean needsReceiverOnStack() {
- return needsReceiverOnStack;
+ public void setNeedsThis(@Nullable DeclarationDescriptor receiverClass) {
+ this.thisClass = receiverClass;
}
public boolean isOwnerFromCall() {
@@ -74,10 +75,6 @@ public class CallableMethod implements Callable {
this.ownerFromCall = ownerFromCall;
}
- public ClassDescriptor getReceiverClass() {
- return receiverClass;
- }
-
void invoke(InstructionAdapter v) {
v.visitMethodInsn(getInvokeOpcode(), getOwner(), getSignature().getName(), getSignature().getDescriptor());
}
@@ -89,4 +86,25 @@ public class CallableMethod implements Callable {
public Type getGenerateCalleeType() {
return generateCalleeType;
}
+
+ public void invokeWithDefault(InstructionAdapter v, int mask) {
+ v.iconst(mask);
+ String desc = getSignature().getDescriptor().replace(")", "I)");
+ if(getInvokeOpcode() != Opcodes.INVOKESTATIC)
+ desc = desc.replace("(", "(L" + getOwner() + ";");
+ v.visitMethodInsn(Opcodes.INVOKESTATIC, getInvokeOpcode() == Opcodes.INVOKEINTERFACE ? getOwner() + "$$TImpl" : getOwner(), getSignature().getName() + "$default", desc);
+ }
+
+ public boolean isNeedsThis() {
+ return thisClass != null;
+ }
+
+ public boolean isNeedsReceiver() {
+ return receiverClass != null;
+ }
+
+ public DeclarationDescriptor getThisClass() {
+ return thisClass;
+ }
+
}
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java
index 8e507409cb9..b062a56f417 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java
@@ -4,19 +4,13 @@
package org.jetbrains.jet.codegen;
import com.intellij.openapi.util.Pair;
-import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
-import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
-import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
-import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
+import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.JetFunctionLiteral;
import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
+import org.objectweb.asm.*;
import org.objectweb.asm.commons.InstructionAdapter;
import org.objectweb.asm.commons.Method;
import org.objectweb.asm.signature.SignatureWriter;
@@ -26,6 +20,8 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import static org.objectweb.asm.Opcodes.*;
+
public class ClosureCodegen extends FunctionOrClosureCodegen {
public ClosureCodegen(GenerationState state, ExpressionCodegen exprContext, ClassContext context) {
@@ -68,8 +64,8 @@ public class ClosureCodegen extends FunctionOrClosureCodegen {
appendType(signatureWriter, funDescriptor.getReturnType(), '=');
signatureWriter.visitEnd();
- cv.visit(Opcodes.V1_6,
- Opcodes.ACC_PUBLIC,
+ cv.visit(V1_6,
+ ACC_PUBLIC,
name,
null,
funClass,
@@ -79,7 +75,7 @@ public class ClosureCodegen extends FunctionOrClosureCodegen {
generateBridge(name, funDescriptor, cv);
- boolean captureThis = generateBody(funDescriptor, cv, fun.getFunctionLiteral());
+ captureThis = generateBody(funDescriptor, cv, fun.getFunctionLiteral());
final Type enclosingType = context.enclosingClassType(state.getTypeMapper());
if (enclosingType == null) captureThis = false;
@@ -89,6 +85,10 @@ public class ClosureCodegen extends FunctionOrClosureCodegen {
cv.visitField(0, "this$0", enclosingType.getDescriptor(), null, null);
}
+ if(isConst()) {
+ generateConstInstance();
+ }
+
cv.visitEnd();
final GeneratedAnonymousClassDescriptor answer = new GeneratedAnonymousClassDescriptor(name, constructor, captureThis);
@@ -99,6 +99,48 @@ public class ClosureCodegen extends FunctionOrClosureCodegen {
return answer;
}
+ private void generateConstInstance() {
+ cv.visitField(ACC_PRIVATE| ACC_STATIC, "$instance", "Ljava/lang/ref/SoftReference;", null, null);
+
+ MethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, "$getInstance", "()L" + name + ";", null, new String[0]);
+ mv.visitCode();
+ mv.visitFieldInsn(GETSTATIC, name, "$instance", "Ljava/lang/ref/SoftReference;");
+ mv.visitInsn(DUP);
+ Label makeNew = new Label();
+ mv.visitJumpInsn(IFNULL, makeNew);
+
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/ref/SoftReference", "get", "()Ljava/lang/Object;");
+ mv.visitInsn(DUP);
+
+ Label ret = new Label();
+ mv.visitJumpInsn(IFNULL, makeNew);
+ mv.visitTypeInsn(CHECKCAST, name);
+ mv.visitJumpInsn(GOTO, ret);
+
+ mv.visitLabel(makeNew);
+ mv.visitInsn(POP);
+
+ mv.visitTypeInsn(NEW, "java/lang/ref/SoftReference");
+ mv.visitInsn(DUP);
+
+ mv.visitTypeInsn(NEW, name);
+ mv.visitInsn(DUP);
+ mv.visitVarInsn(ASTORE, 0);
+
+ mv.visitInsn(DUP);
+ mv.visitMethodInsn(INVOKESPECIAL, name, "", "()V");
+
+ mv.visitMethodInsn(INVOKESPECIAL, "java/lang/ref/SoftReference", "", "(Ljava/lang/Object;)V");
+ mv.visitFieldInsn(PUTSTATIC, name, "$instance", "Ljava/lang/ref/SoftReference;");
+
+ mv.visitVarInsn(ALOAD, 0);
+
+ mv.visitLabel(ret);
+ mv.visitInsn(ARETURN);
+ mv.visitMaxs(0,0);
+ mv.visitEnd();
+ }
+
private boolean generateBody(FunctionDescriptor funDescriptor, ClassVisitor cv, JetFunctionLiteral body) {
final ClassContext closureContext = context.intoClosure(name, this);
FunctionCodegen fc = new FunctionCodegen(closureContext, cv, state);
@@ -110,7 +152,7 @@ public class ClosureCodegen extends FunctionOrClosureCodegen {
final Method bridge = erasedInvokeSignature(funDescriptor);
final Method delegate = invokeSignature(funDescriptor);
- final MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC, "invoke", bridge.getDescriptor(), state.getTypeMapper().genericSignature(funDescriptor), new String[0]);
+ final MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "invoke", bridge.getDescriptor(), state.getTypeMapper().genericSignature(funDescriptor), new String[0]);
mv.visitCode();
InstructionAdapter iv = new InstructionAdapter(mv);
@@ -164,7 +206,7 @@ public class ClosureCodegen extends FunctionOrClosureCodegen {
}
final Method constructor = new Method("", Type.VOID_TYPE, argTypes);
- final MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC, "", constructor.getDescriptor(), null, new String[0]);
+ final MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "", constructor.getDescriptor(), null, new String[0]);
mv.visitCode();
InstructionAdapter iv = new InstructionAdapter(mv);
ExpressionCodegen expressionCodegen = new ExpressionCodegen(mv, null, Type.VOID_TYPE, context, state);
@@ -190,7 +232,7 @@ public class ClosureCodegen extends FunctionOrClosureCodegen {
StackValue.field(type, name, fieldName, false).store(iv);
}
- iv.visitInsn(Opcodes.RETURN);
+ iv.visitInsn(RETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
@@ -215,15 +257,4 @@ public class ClosureCodegen extends FunctionOrClosureCodegen {
signatureWriter.visitClassType(rawRetType.getInternalName());
signatureWriter.visitEnd();
}
-
- public static CallableMethod asCallableMethod(FunctionDescriptor fd) {
- Method descriptor = erasedInvokeSignature(fd);
- String owner = getInternalClassName(fd);
- final CallableMethod result = new CallableMethod(owner, descriptor, Opcodes.INVOKEVIRTUAL, Arrays.asList(descriptor.getArgumentTypes()));
- if (fd.getReceiverParameter().exists()) {
- result.setNeedsReceiver(null);
- }
- result.requestGenerateCallee(Type.getObjectType(getInternalClassName(fd)));
- return result;
- }
}
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
index 782ec25c56a..0b577fedb1c 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
@@ -13,6 +13,7 @@ import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
+import org.jetbrains.jet.lang.resolve.calls.*;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.java.JavaClassDescriptor;
import org.jetbrains.jet.lang.types.*;
@@ -26,6 +27,8 @@ import org.objectweb.asm.commons.Method;
import java.util.*;
+import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
+
/**
* @author max
* @author yole
@@ -76,6 +79,17 @@ public class ExpressionCodegen extends JetVisitor {
this.intrinsics = state.getIntrinsics();
}
+ private CallableMethod asCallableMethod(FunctionDescriptor fd) {
+ Method descriptor = ClosureCodegen.erasedInvokeSignature(fd);
+ String owner = ClosureCodegen.getInternalClassName(fd);
+ final CallableMethod result = new CallableMethod(owner, descriptor, INVOKEVIRTUAL, Arrays.asList(descriptor.getArgumentTypes()));
+ if (fd.getReceiverParameter().exists()) {
+ result.setNeedsReceiver(fd.getReceiverParameter().getType().getConstructor().getDeclarationDescriptor());
+ }
+ result.requestGenerateCallee(Type.getObjectType(ClosureCodegen.getInternalClassName(fd)));
+ return result;
+ }
+
public GenerationState getState() {
return state;
}
@@ -428,9 +442,9 @@ public class ExpressionCodegen extends JetVisitor {
gen(expression.getLoopRange(), loopRangeType);
v.dup();
- v.invokevirtual("jet/IntRange", "getStartValue", "()I");
+ v.invokevirtual("jet/IntRange", "getStart", "()I");
v.store(lookupLocal(parameterDescriptor), Type.INT_TYPE);
- v.invokevirtual("jet/IntRange", "getEndValue", "()I");
+ v.invokevirtual("jet/IntRange", "getEnd", "()I");
v.store(myEndVar, Type.INT_TYPE);
}
}
@@ -543,23 +557,29 @@ public class ExpressionCodegen extends JetVisitor {
return generateBlock(expression.getFunctionLiteral().getBodyExpression().getStatements());
}
else {
- final GeneratedAnonymousClassDescriptor closure = new ClosureCodegen(state, this, context).gen(expression);
+ ClosureCodegen closureCodegen = new ClosureCodegen(state, this, context);
+ final GeneratedAnonymousClassDescriptor closure = closureCodegen.gen(expression);
- v.anew(Type.getObjectType(closure.getClassname()));
- v.dup();
-
- final Method cons = closure.getConstructor();
-
- if (closure.isCaptureThis()) {
- v.load(0, JetTypeMapper.TYPE_OBJECT);
+ if(closureCodegen.isConst()) {
+ v.invokestatic(closure.getClassname(), "$getInstance", "()L" + closure.getClassname() + ";");
}
+ else {
+ v.anew(Type.getObjectType(closure.getClassname()));
+ v.dup();
- for (int i = 0; i < closure.getArgs().size(); i++) {
- StackValue arg = closure.getArgs().get(i);
- arg.put(cons.getArgumentTypes()[i], v);
+ final Method cons = closure.getConstructor();
+
+ if (closure.isCaptureThis()) {
+ v.load(0, JetTypeMapper.TYPE_OBJECT);
+ }
+
+ for (int i = 0; i < closure.getArgs().size(); i++) {
+ StackValue arg = closure.getArgs().get(i);
+ arg.put(cons.getArgumentTypes()[i], v);
+ }
+
+ v.invokespecial(closure.getClassname(), "", cons.getDescriptor());
}
-
- v.invokespecial(closure.getClassname(), "", cons.getDescriptor());
return StackValue.onStack(Type.getObjectType(closure.getClassname()));
}
}
@@ -976,7 +996,7 @@ public class ExpressionCodegen extends JetVisitor {
callableMethod = typeMapper.mapToCallableMethod((PsiNamedElement) declarationPsiElement, null);
}
else if (fd instanceof VariableAsFunctionDescriptor) {
- callableMethod = ClosureCodegen.asCallableMethod((FunctionDescriptor) fd);
+ callableMethod = asCallableMethod((FunctionDescriptor) fd);
}
else if (fd instanceof FunctionDescriptor) {
callableMethod = typeMapper.mapToCallableMethod((FunctionDescriptor) fd, null);
@@ -1011,18 +1031,35 @@ public class ExpressionCodegen extends JetVisitor {
if (callableMethod.isOwnerFromCall()) {
setOwnerFromCall(callableMethod, expression);
}
- if (callableMethod.needsReceiverOnStack()) {
- if (receiver == StackValue.none()) {
- ClassDescriptor receiverClass = callableMethod.getReceiverClass();
- receiver = receiverClass == null ? thisExpression() : generateThisOrOuter(receiverClass);
+
+ if (callableMethod.isNeedsThis()) {
+ if(callableMethod.isNeedsReceiver()) {
+ generateThisOrOuter((ClassDescriptor) callableMethod.getThisClass()).put(JetTypeMapper.TYPE_OBJECT, v);
+ receiver.put(JetTypeMapper.TYPE_OBJECT, v);
+ }
+ else {
+ if (receiver == StackValue.none()) {
+ generateThisOrOuter((ClassDescriptor) callableMethod.getThisClass()).put(JetTypeMapper.TYPE_OBJECT, v);;
+ }
+ else {
+ receiver.put(JetTypeMapper.TYPE_OBJECT, v);
+ }
}
- receiver.put(JetTypeMapper.TYPE_OBJECT, v);
}
- pushMethodArguments(expression, callableMethod.getValueParameterTypes());
+ else {
+ if (callableMethod.isNeedsReceiver()) {
+ receiver.put(JetTypeMapper.TYPE_OBJECT, v);
+ }
+ }
+
+ int mask = pushMethodArguments(expression, callableMethod.getValueParameterTypes());
if (callableMethod.acceptsTypeArguments()) {
pushTypeArguments(expression);
}
- callableMethod.invoke(v);
+ if(mask == 0)
+ callableMethod.invoke(v);
+ else
+ callableMethod.invokeWithDefault(v, mask);
}
private void setOwnerFromCall(CallableMethod callableMethod, JetCallElement expression) {
@@ -1118,11 +1155,52 @@ public class ExpressionCodegen extends JetVisitor {
return false;
}
- private void pushMethodArguments(JetCallElement expression, List valueParameterTypes) {
+ private int pushMethodArguments(JetCallElement expression, List valueParameterTypes) {
+ ResolvedCall extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression());
List extends ValueArgument> args = expression.getValueArguments();
- for (int i = 0, argsSize = args.size(); i < argsSize; i++) {
- ValueArgument arg = args.get(i);
- gen(arg.getArgumentExpression(), valueParameterTypes.get(i));
+ if(resolvedCall != null) {
+ Map valueArguments = resolvedCall.getValueArguments();
+ CallableDescriptor fd = resolvedCall.getResultingDescriptor();
+
+ int index = 0;
+ int mask = 0;
+ for (ValueParameterDescriptor valueParameterDescriptor : fd.getValueParameters()) {
+ ResolvedValueArgument resolvedValueArgument = valueArguments.get(valueParameterDescriptor);
+ if(resolvedValueArgument instanceof ExpressionValueArgument) {
+ ExpressionValueArgument valueArgument = (ExpressionValueArgument) resolvedValueArgument;
+ gen(valueArgument.getExpression(), valueParameterTypes.get(index));
+ }
+ else if(resolvedValueArgument instanceof DefaultValueArgument) {
+ Type type = valueParameterTypes.get(index);
+ if(type.getSort() == Type.OBJECT||type.getSort() == Type.ARRAY)
+ v.aconst(null);
+ else if(type.getSort() == Type.FLOAT) {
+ v.aconst(0f);
+ }
+ else if(type.getSort() == Type.DOUBLE) {
+ v.aconst(0d);
+ }
+ else {
+ v.iconst(0);
+ }
+ mask |= (1 << index);
+ }
+ else if(resolvedValueArgument instanceof VarargValueArgument) {
+ throw new UnsupportedOperationException("Varargs are not supported yet");
+ }
+ else {
+ throw new UnsupportedOperationException();
+ }
+ index++;
+ }
+ return mask;
+ }
+ else {
+ for (int i = 0, argsSize = args.size(); i < argsSize; i++) {
+ ValueArgument arg = args.get(i);
+ gen(arg.getArgumentExpression(), valueParameterTypes.get(i));
+ }
+ return 0;
}
}
@@ -1739,8 +1817,19 @@ public class ExpressionCodegen extends JetVisitor {
}
private void pushTypeArguments(JetCallElement expression) {
- for (JetTypeProjection jetTypeArgument : expression.getTypeArguments()) {
- pushTypeArgument(jetTypeArgument);
+ ResolvedCall extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression());
+ if(resolvedCall != null) {
+ Map typeArguments = resolvedCall.getTypeArguments();
+ CallableDescriptor resultingDescriptor = resolvedCall.getCandidateDescriptor();
+ for (TypeParameterDescriptor typeParameterDescriptor : resultingDescriptor.getTypeParameters()) {
+ JetType jetType = typeArguments.get(typeParameterDescriptor);
+ generateTypeInfo(jetType);
+ }
+ }
+ else {
+ for (JetTypeProjection jetTypeArgument : expression.getTypeArguments()) {
+ pushTypeArgument(jetTypeArgument);
+ }
}
}
@@ -1754,7 +1843,7 @@ public class ExpressionCodegen extends JetVisitor {
Type type = JetTypeMapper.psiClassType(javaClass);
v.anew(type);
v.dup();
- final CallableMethod callableMethod = JetTypeMapper.mapToCallableMethod(constructor);
+ final CallableMethod callableMethod = typeMapper.mapToCallableMethod(constructor);
invokeMethodWithArguments(callableMethod, expression);
return type;
}
@@ -1850,7 +1939,7 @@ public class ExpressionCodegen extends JetVisitor {
assert declaration != null : "No declaration found for " + expression.getText();
final CallableMethod accessor;
if (declaration instanceof PsiMethod) {
- accessor = JetTypeMapper.mapToCallableMethod((PsiMethod) declaration);
+ accessor = typeMapper.mapToCallableMethod((PsiMethod) declaration);
}
else if (declaration instanceof JetNamedFunction) {
accessor = typeMapper.mapToCallableMethod((JetNamedFunction) declaration, null);
@@ -1922,7 +2011,7 @@ public class ExpressionCodegen extends JetVisitor {
@Override
public StackValue visitThisExpression(JetThisExpression expression, StackValue receiver) {
- final DeclarationDescriptor descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getThisReference());
+ final DeclarationDescriptor descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getInstanceReference());
if (descriptor instanceof ClassDescriptor) {
return generateThisOrOuter((ClassDescriptor) descriptor);
}
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java
index 1fcd98e320c..a7724378b36 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java
@@ -1,26 +1,22 @@
package org.jetbrains.jet.codegen;
-import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
-import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
-import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
-import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
-import org.jetbrains.jet.lang.psi.JetDeclarationWithBody;
-import org.jetbrains.jet.lang.psi.JetExpression;
-import org.jetbrains.jet.lang.psi.JetNamedFunction;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.jet.lang.descriptors.*;
+import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
+import org.objectweb.asm.*;
import org.objectweb.asm.commons.InstructionAdapter;
import org.objectweb.asm.commons.Method;
import java.util.List;
import java.util.Set;
+import static org.objectweb.asm.Opcodes.*;
+
/**
* @author max
* @author yole
+ * @author alex.tkachman
*/
public class FunctionCodegen {
private final ClassContext owner;
@@ -54,74 +50,89 @@ public class FunctionCodegen {
List paramDescrs = functionDescriptor.getValueParameters();
List typeParameters = functionDescriptor.getTypeParameters();
- int flags = Opcodes.ACC_PUBLIC; // TODO.
+ int flags = ACC_PUBLIC; // TODO.
OwnerKind kind = context.getContextKind();
- if(kind == OwnerKind.TRAIT_IMPL && bodyExpressions == null)
- return;
+ if (kind != OwnerKind.TRAIT_IMPL || bodyExpressions != null) {
- boolean isStatic = kind == OwnerKind.NAMESPACE || kind == OwnerKind.TRAIT_IMPL;
- if (isStatic) flags |= Opcodes.ACC_STATIC;
+ boolean isStatic = kind == OwnerKind.NAMESPACE || kind == OwnerKind.TRAIT_IMPL;
+ if (isStatic) flags |= ACC_STATIC;
- boolean isAbstract = !isStatic && (bodyExpressions == null || CodegenUtil.isInterface(functionDescriptor.getContainingDeclaration()));
- if (isAbstract) flags |= Opcodes.ACC_ABSTRACT;
+ boolean isAbstract = !isStatic && (bodyExpressions == null || CodegenUtil.isInterface(functionDescriptor.getContainingDeclaration()));
+ if (isAbstract) flags |= ACC_ABSTRACT;
- final MethodVisitor mv = v.visitMethod(flags, jvmSignature.getName(), jvmSignature.getDescriptor(), null, null);
- if (!isAbstract) {
- mv.visitCode();
- FrameMap frameMap = context.prepareFrame();
-
- ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getReturnType(), context, state);
-
- Type[] argTypes = jvmSignature.getArgumentTypes();
- for (int i = 0; i < paramDescrs.size(); i++) {
- ValueParameterDescriptor parameter = paramDescrs.get(i);
- frameMap.enter(parameter, argTypes[i].getSize());
- }
-
- for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
- int slot = frameMap.enterTemp();
- codegen.addTypeParameter(typeParameterDescriptor, StackValue.local(slot, JetTypeMapper.TYPE_TYPEINFO));
- }
-
- if (kind instanceof OwnerKind.DelegateKind) {
- OwnerKind.DelegateKind dk = (OwnerKind.DelegateKind) kind;
- InstructionAdapter iv = new InstructionAdapter(mv);
- iv.load(0, JetTypeMapper.TYPE_OBJECT);
- dk.getDelegate().put(JetTypeMapper.TYPE_OBJECT, iv);
- for (int i = 0; i < argTypes.length; i++) {
- Type argType = argTypes[i];
- iv.load(i + 1, argType);
+ final MethodVisitor mv = v.visitMethod(flags, jvmSignature.getName(), jvmSignature.getDescriptor(), null, null);
+ if(kind != OwnerKind.TRAIT_IMPL) {
+ int start = functionDescriptor.getReceiverParameter().exists() ? 1 : 0;
+ for(int i = 0; i != paramDescrs.size(); ++i) {
+ AnnotationVisitor annotationVisitor = mv.visitParameterAnnotation(i + start, "jet/typeinfo/JetParameterName", true);
+ annotationVisitor.visit("value", paramDescrs.get(i).getName());
+ annotationVisitor.visitEnd();
}
- iv.invokeinterface(dk.getOwnerClass(), jvmSignature.getName(), jvmSignature.getDescriptor());
- iv.areturn(jvmSignature.getReturnType());
}
- else {
+ if (!isAbstract) {
+ mv.visitCode();
+ FrameMap frameMap = context.prepareFrame();
+
+ ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getReturnType(), context, state);
+
+ Type[] argTypes = jvmSignature.getArgumentTypes();
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);
- }
+ frameMap.enter(parameter, argTypes[i].getSize());
}
- codegen.returnExpression(bodyExpressions);
- }
- mv.visitMaxs(0, 0);
- mv.visitEnd();
+ for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
+ int slot = frameMap.enterTemp();
+ codegen.addTypeParameter(typeParameterDescriptor, StackValue.local(slot, JetTypeMapper.TYPE_TYPEINFO));
+ }
- generateBridgeIfNeeded(owner, state, v, jvmSignature, functionDescriptor, kind);
+ if (kind instanceof OwnerKind.DelegateKind) {
+ OwnerKind.DelegateKind dk = (OwnerKind.DelegateKind) kind;
+ InstructionAdapter iv = new InstructionAdapter(mv);
+ iv.load(0, JetTypeMapper.TYPE_OBJECT);
+ dk.getDelegate().put(JetTypeMapper.TYPE_OBJECT, iv);
+ for (int i = 0; i < argTypes.length; i++) {
+ Type argType = argTypes[i];
+ iv.load(i + 1, argType);
+ }
+ iv.invokeinterface(dk.getOwnerClass(), jvmSignature.getName(), jvmSignature.getDescriptor());
+ 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(NEW, sharedVarType.getInternalName());
+ mv.visitInsn(DUP);
+ mv.visitInsn(DUP);
+ mv.visitMethodInsn(INVOKESPECIAL, sharedVarType.getInternalName(), "", "()V");
+ mv.visitVarInsn(localVarType.getOpcode(ILOAD), index);
+ mv.visitFieldInsn(PUTFIELD, sharedVarType.getInternalName(), "ref", StackValue.refType(localVarType).getDescriptor());
+ mv.visitVarInsn(sharedVarType.getOpcode(ISTORE), index);
+ }
+ }
+
+ codegen.returnExpression(bodyExpressions);
+ }
+ try {
+ mv.visitMaxs(0, 0);
+ }
+ catch (Throwable t) {
+ System.out.println(t);
+ }
+ mv.visitEnd();
+
+ generateBridgeIfNeeded(owner, state, v, jvmSignature, functionDescriptor, kind);
+ }
}
+
+ generateDefaultIfNeeded(context, state, v, jvmSignature, functionDescriptor, kind);
}
static void generateBridgeIfNeeded(ClassContext owner, GenerationState state, ClassVisitor v, Method jvmSignature, FunctionDescriptor functionDescriptor, OwnerKind kind) {
@@ -135,12 +146,153 @@ public class FunctionCodegen {
}
}
+ static void generateDefaultIfNeeded(ClassContext owner, GenerationState state, ClassVisitor v, Method jvmSignature, FunctionDescriptor functionDescriptor, OwnerKind kind) {
+ DeclarationDescriptor contextClass = owner.getContextClass();
+
+ if(kind != OwnerKind.TRAIT_IMPL) {
+ // we don't generate defaults for traits but do for traitImpl
+ if(contextClass instanceof ClassDescriptor) {
+ PsiElement psiElement = state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, contextClass);
+ if(psiElement instanceof JetClass) {
+ JetClass element = (JetClass) psiElement;
+ if(element.isTrait())
+ return;
+ }
+ }
+ }
+
+ boolean needed = false;
+ for (ValueParameterDescriptor parameterDescriptor : functionDescriptor.getValueParameters()) {
+ if(parameterDescriptor.hasDefaultValue()) {
+ needed = true;
+ break;
+ }
+ }
+
+ if(needed) {
+ boolean hasReceiver = functionDescriptor.getReceiverParameter().exists();
+ boolean isStatic = kind == OwnerKind.NAMESPACE;
+
+ if(kind == OwnerKind.TRAIT_IMPL) {
+ String correctedDescr = "(" + jvmSignature.getDescriptor().substring(jvmSignature.getDescriptor().indexOf(";") + 1);
+ jvmSignature = new Method(jvmSignature.getName(), correctedDescr);
+ }
+
+ int flags = ACC_PUBLIC; // TODO.
+
+ String ownerInternalName = contextClass instanceof NamespaceDescriptor ?
+ JetTypeMapper.jvmName((NamespaceDescriptor) contextClass) :
+ state.getTypeMapper().jvmName((ClassDescriptor) contextClass, OwnerKind.IMPLEMENTATION);
+
+ String descriptor = jvmSignature.getDescriptor().replace(")","I)");
+ if(!isStatic)
+ descriptor = descriptor.replace("(","(L" + ownerInternalName + ";");
+ final MethodVisitor mv = v.visitMethod(flags| ACC_STATIC, jvmSignature.getName() + "$default", descriptor, null, null);
+ InstructionAdapter iv = new InstructionAdapter(mv);
+ mv.visitCode();
+
+ FrameMap frameMap = owner.prepareFrame();
+
+ ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getReturnType(), owner, state);
+
+ int var = 0;
+ if(!isStatic) {
+ frameMap.enterTemp();
+ var++;
+ }
+
+ if(hasReceiver) {
+ frameMap.enterTemp();
+ var++;
+ }
+
+ Type[] argTypes = jvmSignature.getArgumentTypes();
+ List paramDescrs = functionDescriptor.getValueParameters();
+ for (int i = 0; i < paramDescrs.size(); i++) {
+ ValueParameterDescriptor parameter = paramDescrs.get(i);
+ int size = argTypes[i + (hasReceiver ? 1 : 0)].getSize();
+ var += size;
+ frameMap.enter(parameter, size);
+ }
+
+ List typeParameters = functionDescriptor.getTypeParameters();
+ for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
+ int slot = frameMap.enterTemp();
+ codegen.addTypeParameter(typeParameterDescriptor, StackValue.local(slot, JetTypeMapper.TYPE_TYPEINFO));
+ var++;
+ }
+
+ frameMap.enterTemp();
+
+ int maskIndex = var;
+
+ var = 0;
+ if(!isStatic) {
+ mv.visitVarInsn(ALOAD, var++);
+ }
+
+ if(hasReceiver) {
+ mv.visitVarInsn(ALOAD, var++);
+ }
+
+ Type[] argumentTypes = jvmSignature.getArgumentTypes();
+ for (int index = 0; index < paramDescrs.size(); index++) {
+ ValueParameterDescriptor parameterDescriptor = paramDescrs.get(index);
+
+ Type t = argumentTypes[(hasReceiver ? 1 : 0) + index];
+ Label endArg = null;
+ if (parameterDescriptor.hasDefaultValue()) {
+ iv.load(maskIndex, Type.INT_TYPE);
+ iv.iconst(1 << index);
+ iv.and(Type.INT_TYPE);
+ Label loadArg = new Label();
+ iv.ifeq(loadArg);
+
+ JetParameter jetParameter = (JetParameter) state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, parameterDescriptor);
+ codegen.gen(jetParameter.getDefaultValue(), t);
+
+ endArg = new Label();
+ iv.goTo(endArg);
+
+ iv.mark(loadArg);
+ }
+
+ iv.load(var, t);
+ var += t.getSize();
+
+ if (parameterDescriptor.hasDefaultValue()) {
+ iv.mark(endArg);
+ }
+ }
+
+ for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
+ iv.load(var++, JetTypeMapper.TYPE_OBJECT);
+ }
+
+ if(!isStatic) {
+ if(kind == OwnerKind.TRAIT_IMPL) {
+ iv.invokeinterface(ownerInternalName, jvmSignature.getName(), jvmSignature.getDescriptor());
+ }
+ else
+ iv.invokevirtual(ownerInternalName, jvmSignature.getName(), jvmSignature.getDescriptor());
+ }
+ else {
+ iv.invokestatic(ownerInternalName, jvmSignature.getName(), jvmSignature.getDescriptor());
+ }
+
+ iv.areturn(jvmSignature.getReturnType());
+
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+ }
+ }
+
private static void checkOverride(ClassContext owner, GenerationState state, ClassVisitor v, Method jvmSignature, FunctionDescriptor functionDescriptor, FunctionDescriptor overriddenFunction) {
Type type1 = state.getTypeMapper().mapType(overriddenFunction.getOriginal().getReturnType());
Type type2 = state.getTypeMapper().mapType(functionDescriptor.getReturnType());
if(!type1.equals(type2)) {
Method overriden = state.getTypeMapper().mapSignature(overriddenFunction.getName(), overriddenFunction.getOriginal());
- int flags = Opcodes.ACC_PUBLIC; // TODO.
+ int flags = ACC_PUBLIC; // TODO.
final MethodVisitor mv = v.visitMethod(flags, jvmSignature.getName(), overriden.getDescriptor(), null, null);
mv.visitCode();
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionOrClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionOrClosureCodegen.java
index a6a57ece6b5..a9834ed153d 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionOrClosureCodegen.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionOrClosureCodegen.java
@@ -13,6 +13,8 @@ import java.util.Map;
* @author alex.tkachman
*/
public class FunctionOrClosureCodegen {
+ protected boolean captureThis;
+
public final GenerationState state;
protected final ExpressionCodegen exprContext;
protected final ClassContext context;
@@ -54,4 +56,12 @@ public class FunctionOrClosureCodegen {
return null;
}
+
+ public boolean isCaptureThis() {
+ return captureThis;
+ }
+
+ public boolean isConst () {
+ return !captureThis && closure.isEmpty();
+ }
}
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java
index 9cf08cd2482..926b496e243 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java
@@ -162,40 +162,6 @@ public class JetTypeMapper {
return new Method(method.isConstructor() ? "" : method.getName(), Type.getMethodDescriptor(returnType, parameterTypes));
}
- static CallableMethod mapToCallableMethod(PsiMethod method) {
- final PsiClass containingClass = method.getContainingClass();
- String owner = jvmName(containingClass);
- Method signature = getMethodDescriptor(method);
- List valueParameterTypes = new ArrayList();
- Collections.addAll(valueParameterTypes, signature.getArgumentTypes());
- int opcode;
- boolean needsReceiver = false;
- boolean ownerFromCall = false;
- if (method.isConstructor()) {
- opcode = Opcodes.INVOKESPECIAL;
- }
- else if (method.hasModifierProperty(PsiModifier.STATIC)) {
- opcode = Opcodes.INVOKESTATIC;
- }
- else {
- needsReceiver = true;
- assert containingClass != null;
- if (containingClass.isInterface()) {
- opcode = Opcodes.INVOKEINTERFACE;
- }
- else {
- opcode = Opcodes.INVOKEVIRTUAL;
- }
- ownerFromCall = true;
- }
- final CallableMethod result = new CallableMethod(owner, signature, opcode, valueParameterTypes);
- if (needsReceiver) {
- result.setNeedsReceiver(null);
- }
- result.setOwnerFromCall(ownerFromCall);
- return result;
- }
-
public static Type getBoxedType(final Type type) {
switch (type.getSort()) {
case Type.BYTE:
@@ -518,18 +484,49 @@ public class JetTypeMapper {
return mapToCallableMethod(functionDescriptor, kind);
}
+ CallableMethod mapToCallableMethod(PsiMethod method) {
+ final PsiClass containingClass = method.getContainingClass();
+ String owner = jvmName(containingClass);
+ Method signature = getMethodDescriptor(method);
+ List valueParameterTypes = new ArrayList();
+ Collections.addAll(valueParameterTypes, signature.getArgumentTypes());
+ int opcode;
+ boolean ownerFromCall = false;
+ DeclarationDescriptor thisClass = null;
+ if (method.isConstructor()) {
+ opcode = Opcodes.INVOKESPECIAL;
+ }
+ else if (method.hasModifierProperty(PsiModifier.STATIC)) {
+ opcode = Opcodes.INVOKESTATIC;
+ }
+ else {
+ assert containingClass != null;
+ if (containingClass.isInterface()) {
+ opcode = Opcodes.INVOKEINTERFACE;
+ }
+ else {
+ opcode = Opcodes.INVOKEVIRTUAL;
+ }
+ ownerFromCall = true;
+ thisClass = JetStandardClasses.getAny(); // todo - this is hack, correct descriptor needed
+ }
+ final CallableMethod result = new CallableMethod(owner, signature, opcode, valueParameterTypes);
+ result.setNeedsThis(thisClass);
+ result.setOwnerFromCall(ownerFromCall);
+ return result;
+ }
+
public CallableMethod mapToCallableMethod(FunctionDescriptor functionDescriptor, OwnerKind kind) {
final DeclarationDescriptor functionParent = functionDescriptor.getContainingDeclaration();
final List valueParameterTypes = new ArrayList();
Method descriptor = mapSignature(functionDescriptor.getOriginal(), valueParameterTypes, kind);
String owner;
int invokeOpcode;
- boolean needsReceiver;
- ClassDescriptor receiverClass = null;
+ ClassDescriptor thisClass;
if (functionParent instanceof NamespaceDescriptor) {
owner = NamespaceCodegen.getJVMClassName(DescriptorRenderer.getFQName(functionParent));
invokeOpcode = Opcodes.INVOKESTATIC;
- needsReceiver = functionDescriptor.getReceiverParameter().exists();
+ thisClass = null;
}
else if (functionParent instanceof ClassDescriptor) {
ClassDescriptor containingClass = (ClassDescriptor) functionParent;
@@ -537,8 +534,7 @@ public class JetTypeMapper {
invokeOpcode = CodegenUtil.isInterface(containingClass)
? Opcodes.INVOKEINTERFACE
: Opcodes.INVOKEVIRTUAL;
- needsReceiver = true;
- receiverClass = containingClass;
+ thisClass = containingClass;
}
else {
throw new UnsupportedOperationException("unknown function parent");
@@ -546,9 +542,11 @@ public class JetTypeMapper {
final CallableMethod result = new CallableMethod(owner, descriptor, invokeOpcode, valueParameterTypes);
result.setAcceptsTypeArguments(true);
- if (needsReceiver) {
- result.setNeedsReceiver(receiverClass);
+ result.setNeedsThis(thisClass);
+ if(functionDescriptor.getReceiverParameter().exists()) {
+ result.setNeedsReceiver(functionDescriptor.getReceiverParameter().getType().getConstructor().getDeclarationDescriptor());
}
+
return result;
}
diff --git a/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java
index e41fcdddb7c..9d943679e2b 100644
--- a/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java
+++ b/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java
@@ -22,6 +22,8 @@ import org.jetbrains.jet.plugin.JetFileType;
import java.io.File;
import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
import java.util.List;
/**
@@ -34,16 +36,6 @@ public class KotlinCompiler {
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
@@ -51,9 +43,45 @@ public class KotlinCompiler {
}
};
JavaCoreEnvironment environment = new JavaCoreEnvironment(root);
+
+ String javaHome = System.getenv("JAVA_HOME");
+ File rtJar = null;
+ if (javaHome == null) {
+ ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
+ if(systemClassLoader instanceof URLClassLoader) {
+ URLClassLoader loader = (URLClassLoader) systemClassLoader;
+ for(URL url: loader.getURLs()) {
+ if("file".equals(url.getProtocol())) {
+ if(url.getFile().endsWith("/lib/rt.jar")) {
+ rtJar = new File(url.getFile());
+ break;
+ }
+ if(url.getFile().endsWith("/Classes/classes.jar")) {
+ rtJar = new File(url.getFile()).getAbsoluteFile();
+ break;
+ }
+ }
+ }
+ }
+
+ if(rtJar == null) {
+ System.out.println("JAVA_HOME environment variable needs to be defined");
+ return;
+ }
+ }
+ else {
+ rtJar = findRtJar(javaHome);
+ }
+
+ if (rtJar == null || !rtJar.exists()) {
+ System.out.print("No rt.jar found under JAVA_HOME=" + javaHome);
+ return;
+ }
+
environment.addToClasspath(rtJar);
environment.registerFileType(JetFileType.INSTANCE, "kt");
+ environment.registerFileType(JetFileType.INSTANCE, "jet");
environment.registerParserDefinition(new JetParserDefinition());
VirtualFile vFile = environment.getLocalFileSystem().findFileByPath(args [0]);
if (vFile == null) {
diff --git a/idea/src/org/jetbrains/jet/plugin/AnalyzerFacade.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AnalyzerFacade.java
similarity index 89%
rename from idea/src/org/jetbrains/jet/plugin/AnalyzerFacade.java
rename to compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AnalyzerFacade.java
index ec376a187b8..e0772dbcd28 100644
--- a/idea/src/org/jetbrains/jet/plugin/AnalyzerFacade.java
+++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AnalyzerFacade.java
@@ -1,4 +1,4 @@
-package org.jetbrains.jet.plugin;
+package org.jetbrains.jet.lang.resolve.java;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
@@ -6,7 +6,6 @@ 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;
/**
* @author abreslav
diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java
index ab02a9d9d42..c46e086ab25 100644
--- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java
+++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java
@@ -51,11 +51,6 @@ public class JavaClassMembersScope implements JetScope {
return null;
}
- @Override
- public DeclarationDescriptor getDeclarationDescriptorForUnqualifiedThis() {
- throw new UnsupportedOperationException();
- }
-
@Override
public ClassifierDescriptor getClassifier(@NotNull String name) {
ClassifierDescriptor classifierDescriptor = classifiers.get(name);
diff --git a/compiler/frontend/src/org/jetbrains/jet/JetNodeTypes.java b/compiler/frontend/src/org/jetbrains/jet/JetNodeTypes.java
index 9656239e4a2..e26d14c12dc 100644
--- a/compiler/frontend/src/org/jetbrains/jet/JetNodeTypes.java
+++ b/compiler/frontend/src/org/jetbrains/jet/JetNodeTypes.java
@@ -109,6 +109,7 @@ public interface JetNodeTypes {
JetNodeType LABEL_QUALIFIER = new JetNodeType("LABEL_QUALIFIER", JetContainerNode.class);
JetNodeType THIS_EXPRESSION = new JetNodeType("THIS_EXPRESSION", JetThisExpression.class);
+ JetNodeType SUPER_EXPRESSION = new JetNodeType("SUPER_EXPRESSION", JetSuperExpression.class);
JetNodeType BINARY_EXPRESSION = new JetNodeType("BINARY_EXPRESSION", JetBinaryExpression.class);
JetNodeType BINARY_WITH_TYPE = new JetNodeType("BINARY_WITH_TYPE", JetBinaryExpressionWithTypeRHS.class);
JetNodeType BINARY_WITH_PATTERN = new JetNodeType("BINARY_WITH_PATTERN", JetIsExpression.class); // TODO:
diff --git a/idea/src/org/jetbrains/jet/checkers/CheckerTestUtil.java b/compiler/frontend/src/org/jetbrains/jet/checkers/CheckerTestUtil.java
similarity index 100%
rename from idea/src/org/jetbrains/jet/checkers/CheckerTestUtil.java
rename to compiler/frontend/src/org/jetbrains/jet/checkers/CheckerTestUtil.java
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java
index 1b7057a76d4..cf468bee683 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java
@@ -14,7 +14,7 @@ import java.util.Set;
/**
* @author abreslav
*/
-public interface ClassDescriptor extends ClassifierDescriptor {
+public interface ClassDescriptor extends ClassifierDescriptor, MemberDescriptor {
@NotNull
JetScope getMemberScope(List typeArguments);
@@ -53,9 +53,11 @@ public interface ClassDescriptor extends ClassifierDescriptor {
@NotNull
ClassKind getKind();
+ @Override
@NotNull
Modality getModality();
-
+
+ @Override
@NotNull
Visibility getVisibility();
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/DeclarationDescriptorWithVisibility.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/DeclarationDescriptorWithVisibility.java
new file mode 100644
index 00000000000..eab9e41ff5d
--- /dev/null
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/DeclarationDescriptorWithVisibility.java
@@ -0,0 +1,11 @@
+package org.jetbrains.jet.lang.descriptors;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author abreslav
+ */
+public interface DeclarationDescriptorWithVisibility extends DeclarationDescriptor {
+ @NotNull
+ Visibility getVisibility();
+}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MemberDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MemberDescriptor.java
index 5327b981133..29940086e89 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MemberDescriptor.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MemberDescriptor.java
@@ -5,10 +5,11 @@ import org.jetbrains.annotations.NotNull;
/**
* @author abreslav
*/
-public interface MemberDescriptor {
+public interface MemberDescriptor extends DeclarationDescriptor, DeclarationDescriptorWithVisibility {
@NotNull
Modality getModality();
-
+
+ @Override
@NotNull
Visibility getVisibility();
}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/Visibility.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/Visibility.java
index e2c5364dfe3..4b6e70e2e77 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/Visibility.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/Visibility.java
@@ -1,5 +1,7 @@
package org.jetbrains.jet.lang.descriptors;
+import java.util.EnumSet;
+
/**
* @author svtk
*/
@@ -11,6 +13,8 @@ public enum Visibility {
INTERNAL_PROTECTED(false),
LOCAL(false);
+ public static final EnumSet INTERNAL_VISIBILITIES = EnumSet.of(PRIVATE, INTERNAL, INTERNAL_PROTECTED, LOCAL);
+
private final boolean isAPI;
private Visibility(boolean visibleOutside) {
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/AmbiguousDescriptorDiagnosticFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/AmbiguousDescriptorDiagnosticFactory.java
index b9d4050f915..23126722df9 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/AmbiguousDescriptorDiagnosticFactory.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/AmbiguousDescriptorDiagnosticFactory.java
@@ -2,7 +2,7 @@ package org.jetbrains.jet.lang.diagnostics;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
-import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
+import org.jetbrains.jet.lang.resolve.calls.ResolvedCallImpl;
import org.jetbrains.jet.resolve.DescriptorRenderer;
import java.util.Collection;
@@ -10,7 +10,7 @@ import java.util.Collection;
/**
* @author abreslav
*/
-public class AmbiguousDescriptorDiagnosticFactory extends ParameterizedDiagnosticFactory1>> {
+public class AmbiguousDescriptorDiagnosticFactory extends ParameterizedDiagnosticFactory1>> {
public static AmbiguousDescriptorDiagnosticFactory create(String messageTemplate) {
return new AmbiguousDescriptorDiagnosticFactory(messageTemplate);
}
@@ -20,9 +20,9 @@ public class AmbiguousDescriptorDiagnosticFactory extends ParameterizedDiagnosti
}
@Override
- protected String makeMessageFor(@NotNull Collection extends ResolvedCall extends DeclarationDescriptor>> argument) {
+ protected String makeMessageFor(@NotNull Collection extends ResolvedCallImpl extends DeclarationDescriptor>> argument) {
StringBuilder stringBuilder = new StringBuilder("\n");
- for (ResolvedCall extends DeclarationDescriptor> call : argument) {
+ for (ResolvedCallImpl extends DeclarationDescriptor> call : argument) {
stringBuilder.append(DescriptorRenderer.TEXT.render(call.getResultingDescriptor())).append("\n");
}
return stringBuilder.toString();
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java
index 4d01f8cbeea..4f4cfb16e36 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java
@@ -162,12 +162,16 @@ public interface Errors {
SimpleDiagnosticFactory EQUALS_MISSING = SimpleDiagnosticFactory.create(ERROR, "No method 'equals(Any?) : Boolean' available");
SimpleDiagnosticFactory ASSIGNMENT_IN_EXPRESSION_CONTEXT = SimpleDiagnosticFactory.create(ERROR, "Assignments are not expressions, and only expressions are allowed in this context");
- SimpleDiagnosticFactory NAMESPACE_IS_NOT_AN_EXPRESSION = SimpleDiagnosticFactory.create(ERROR, "'namespace' is not an expression");
+ SimpleDiagnosticFactory NAMESPACE_IS_NOT_AN_EXPRESSION = SimpleDiagnosticFactory.create(ERROR, "'namespace' is not an expression, it can only be used on the left-hand side of a dot ('.')");
+ ParameterizedDiagnosticFactory1 SUPER_IS_NOT_AN_EXPRESSION = ParameterizedDiagnosticFactory1.create(ERROR, "{0} is not an expression, it can only be used on the left-hand side of a dot ('.')");
SimpleDiagnosticFactory DECLARATION_IN_ILLEGAL_CONTEXT = SimpleDiagnosticFactory.create(ERROR, "Declarations are not allowed in this position");
SimpleDiagnosticFactory REF_SETTER_PARAMETER = SimpleDiagnosticFactory.create(ERROR, "Setter parameters can not be 'ref'");
SimpleDiagnosticFactory SETTER_PARAMETER_WITH_DEFAULT_VALUE = SimpleDiagnosticFactory.create(ERROR, "Setter parameters can not have default values");
SimpleDiagnosticFactory NO_THIS = SimpleDiagnosticFactory.create(ERROR, "'this' is not defined in this context");
+ SimpleDiagnosticFactory SUPER_NOT_AVAILABLE = SimpleDiagnosticFactory.create(ERROR, "No supertypes are accessible in this context");
+ SimpleDiagnosticFactory AMBIGUOUS_SUPER = SimpleDiagnosticFactory.create(ERROR, "Many supertypes available, please specify the one you mean in angle brackets, e.g. 'super'");
SimpleDiagnosticFactory NOT_A_SUPERTYPE = SimpleDiagnosticFactory.create(ERROR, "Not a supertype");
+ SimpleDiagnosticFactory TYPE_ARGUMENTS_REDUNDANT_IN_SUPER_QUALIFIER = SimpleDiagnosticFactory.create(WARNING, "Type arguments do not need to be specified in a 'super' qualifier");
SimpleDiagnosticFactory NO_WHEN_ENTRIES = SimpleDiagnosticFactory.create(ERROR, "Entries are required for when-expression"); // TODO : Scope, and maybe this should not be an error
SimplePsiElementOnlyDiagnosticFactory USELESS_CAST_STATIC_ASSERT_IS_FINE = SimplePsiElementOnlyDiagnosticFactory.create(WARNING, "No cast needed, use ':' instead");
SimplePsiElementOnlyDiagnosticFactory USELESS_CAST = SimplePsiElementOnlyDiagnosticFactory.create(WARNING, "No cast needed");
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java
index 2da63a0e2d6..d5b8b5a8760 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java
@@ -49,6 +49,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
LPAR, // tuple
THIS_KEYWORD, // this
+ SUPER_KEYWORD, // super
IF_KEYWORD, // if
WHEN_KEYWORD, // when
@@ -464,7 +465,8 @@ public class JetExpressionParsing extends AbstractJetParsing {
/*
* atomicExpression
* : tupleLiteral // or parenthesized element
- * : "this" getEntryPoint? ("<" type ">")?
+ * : "this" label?
+ * : "super" ("<" type ">")? label?
* : objectLiteral
* : jump
* : if
@@ -490,6 +492,9 @@ public class JetExpressionParsing extends AbstractJetParsing {
else if (at(THIS_KEYWORD)) {
parseThisExpression();
}
+ else if (at(SUPER_KEYWORD)) {
+ parseSuperExpression();
+ }
else if (at(OBJECT_KEYWORD)) {
parseObjectLiteral();
}
@@ -1593,7 +1598,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
}
/*
- * "this" getEntryPoint? ("<" type ">")?
+ * "this" label?
*/
private void parseThisExpression() {
assert _at(THIS_KEYWORD);
@@ -1605,8 +1610,22 @@ public class JetExpressionParsing extends AbstractJetParsing {
parseLabel();
+ mark.done(THIS_EXPRESSION);
+ }
+
+ /*
+ * "this" ("<" type ">")? label?
+ */
+ private void parseSuperExpression() {
+ assert _at(SUPER_KEYWORD);
+ PsiBuilder.Marker mark = mark();
+
+ PsiBuilder.Marker superReference = mark();
+ advance(); // SUPER_KEYWORD
+ superReference.done(REFERENCE_EXPRESSION);
+
if (at(LT)) {
- // This may be "this < foo" or "this", thus the backtracking
+ // This may be "super < foo" or "super", thus the backtracking
PsiBuilder.Marker supertype = mark();
myBuilder.disableNewlines();
@@ -1623,7 +1642,9 @@ public class JetExpressionParsing extends AbstractJetParsing {
}
myBuilder.restoreNewlinesState();
}
- mark.done(THIS_EXPRESSION);
+ parseLabel();
+
+ mark.done(SUPER_EXPRESSION);
}
/*
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetLabelQualifiedInstanceExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetLabelQualifiedInstanceExpression.java
new file mode 100644
index 00000000000..297830432d7
--- /dev/null
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetLabelQualifiedInstanceExpression.java
@@ -0,0 +1,20 @@
+package org.jetbrains.jet.lang.psi;
+
+import com.intellij.lang.ASTNode;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jet.JetNodeTypes;
+
+/**
+ * @author abreslav
+ */
+public abstract class JetLabelQualifiedInstanceExpression extends JetLabelQualifiedExpression {
+
+ public JetLabelQualifiedInstanceExpression(@NotNull ASTNode node) {
+ super(node);
+ }
+
+ @NotNull
+ public JetReferenceExpression getInstanceReference() {
+ return (JetReferenceExpression) findChildByType(JetNodeTypes.REFERENCE_EXPRESSION);
+ }
+}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSimpleNameExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSimpleNameExpression.java
index c40c07518a3..4ef04645259 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSimpleNameExpression.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSimpleNameExpression.java
@@ -10,13 +10,14 @@ import com.intellij.psi.tree.TokenSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.parsing.JetExpressionParsing;
-import org.jetbrains.jet.lexer.JetTokens;
+
+import static org.jetbrains.jet.lexer.JetTokens.*;
/**
* @author max
*/
public class JetSimpleNameExpression extends JetReferenceExpression {
- public static final TokenSet REFERENCE_TOKENS = TokenSet.orSet(JetTokens.LABELS, TokenSet.create(JetTokens.IDENTIFIER, JetTokens.FIELD_IDENTIFIER, JetTokens.THIS_KEYWORD));
+ public static final TokenSet REFERENCE_TOKENS = TokenSet.orSet(LABELS, TokenSet.create(IDENTIFIER, FIELD_IDENTIFIER, THIS_KEYWORD, SUPER_KEYWORD));
public JetSimpleNameExpression(@NotNull ASTNode node) {
super(node);
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSuperExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSuperExpression.java
new file mode 100644
index 00000000000..1eaa7bcf08d
--- /dev/null
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSuperExpression.java
@@ -0,0 +1,39 @@
+package org.jetbrains.jet.lang.psi;
+
+import com.intellij.lang.ASTNode;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jet.JetNodeTypes;
+
+/**
+ * @author max
+ */
+public class JetSuperExpression extends JetLabelQualifiedInstanceExpression {
+
+ public JetSuperExpression(@NotNull ASTNode node) {
+ super(node);
+ }
+
+ @Override
+ public void accept(@NotNull JetVisitorVoid visitor) {
+ visitor.visitSuperExpression(this);
+ }
+
+ @Override
+ public R accept(@NotNull JetVisitor visitor, D data) {
+ return visitor.visitSuperExpression(this, data);
+ }
+
+ /**
+ * class A : B, C {
+ * override fun foo() {
+ * super.foo()
+ * super.foo()
+ * }
+ * }
+ */
+ @Nullable
+ public JetTypeReference getSuperTypeQualifier() {
+ return (JetTypeReference) findChildByType(JetNodeTypes.TYPE_REFERENCE);
+ }
+}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetThisExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetThisExpression.java
index eb176aa19bd..ac42c897c7b 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetThisExpression.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetThisExpression.java
@@ -2,13 +2,11 @@ package org.jetbrains.jet.lang.psi;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.jet.JetNodeTypes;
/**
* @author max
*/
-public class JetThisExpression extends JetLabelQualifiedExpression {
+public class JetThisExpression extends JetLabelQualifiedInstanceExpression {
public JetThisExpression(@NotNull ASTNode node) {
super(node);
@@ -23,23 +21,4 @@ public class JetThisExpression extends JetLabelQualifiedExpression {
public R accept(@NotNull JetVisitor visitor, D data) {
return visitor.visitThisExpression(this, data);
}
-
- /**
- * class A : B, C {
- * override fun foo() {
- * this.foo()
- * this.foo()
- * }
- * }
- */
- @Nullable
- public JetTypeReference getSuperTypeQualifier() {
- return (JetTypeReference) findChildByType(JetNodeTypes.TYPE_REFERENCE);
- }
-
- @NotNull
- public JetReferenceExpression getThisReference() {
- return (JetReferenceExpression) findChildByType(JetNodeTypes.REFERENCE_EXPRESSION);
- }
-
}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTreeVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTreeVisitor.java
index d343f8bccf8..d48dc9a4d31 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTreeVisitor.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTreeVisitor.java
@@ -511,7 +511,15 @@ public class JetTreeVisitor extends JetVisitor {
@Override
public Void visitThisExpression(JetThisExpression expression, D data) {
- JetReferenceExpression thisReference = expression.getThisReference();
+ JetReferenceExpression thisReference = expression.getInstanceReference();
+ thisReference.accept(this, data);
+ visitLabelQualifiedExpression(expression, data);
+ return null;
+ }
+
+ @Override
+ public Void visitSuperExpression(JetSuperExpression expression, D data) {
+ JetReferenceExpression thisReference = expression.getInstanceReference();
thisReference.accept(this, data);
JetTypeReference superTypeQualifier = expression.getSuperTypeQualifier();
if (superTypeQualifier != null) {
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetVisitor.java
index 9c5787cda2c..4817657f54c 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetVisitor.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetVisitor.java
@@ -280,6 +280,10 @@ public class JetVisitor extends PsiElementVisitor {
return visitLabelQualifiedExpression(expression, data);
}
+ public R visitSuperExpression(JetSuperExpression expression, D data) {
+ return visitLabelQualifiedExpression(expression, data);
+ }
+
public R visitParenthesizedExpression(JetParenthesizedExpression expression, D data) {
return visitExpression(expression, data);
}
@@ -419,4 +423,5 @@ public class JetVisitor extends PsiElementVisitor {
public R visitEscapeStringTemplateEntry(JetEscapeStringTemplateEntry entry, D data) {
return visitStringTemplateEntry(entry, data);
}
+
}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetVisitorVoid.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetVisitorVoid.java
index 8fc840217da..e62e607a705 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetVisitorVoid.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetVisitorVoid.java
@@ -278,6 +278,10 @@ public class JetVisitorVoid extends PsiElementVisitor {
visitLabelQualifiedExpression(expression);
}
+ public void visitSuperExpression(JetSuperExpression expression) {
+ visitLabelQualifiedExpression(expression);
+ }
+
public void visitParenthesizedExpression(JetParenthesizedExpression expression) {
visitExpression(expression);
}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AbstractScopeAdapter.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AbstractScopeAdapter.java
index 2d5218a40a3..fec39dc6493 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AbstractScopeAdapter.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AbstractScopeAdapter.java
@@ -65,11 +65,6 @@ public abstract class AbstractScopeAdapter implements JetScope {
return getWorkerScope().getPropertyByFieldReference(fieldName);
}
- @Override
- public DeclarationDescriptor getDeclarationDescriptorForUnqualifiedThis() {
- return getWorkerScope().getDeclarationDescriptorForUnqualifiedThis();
- }
-
@NotNull
@Override
public Collection getAllDescriptors() {
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java
index c7ebed1f1e9..f05397f66a5 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java
@@ -10,7 +10,7 @@ import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetModifierList;
import org.jetbrains.jet.lang.resolve.calls.CallMaker;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
-import org.jetbrains.jet.lang.resolve.calls.DataFlowInfo;
+import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
@@ -36,7 +36,7 @@ public class AnnotationResolver {
this.trace = trace;
// this.typeInferrer = new JetTypeInferrer(JetFlowInformationProvider.THROW_EXCEPTION, semanticServices);
// this.services = typeInferrer.getServices(this.trace);
- this.callResolver = new CallResolver(semanticServices, DataFlowInfo.getEmpty());
+ this.callResolver = new CallResolver(semanticServices, DataFlowInfo.EMPTY);
}
@NotNull
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java
index e5d49d0c837..8d012378264 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java
@@ -7,6 +7,7 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
+import org.jetbrains.jet.lang.resolve.calls.ResolvedCallImpl;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.DeferredType;
@@ -29,7 +30,7 @@ public interface BindingContext {
WritableSlice REFERENCE_TARGET = new BasicWritableSlice("REFERENCE_TARGET", RewritePolicy.DO_NOTHING);
WritableSlice> RESOLVED_CALL = new BasicWritableSlice>("RESOLVED_CALL", RewritePolicy.DO_NOTHING);
- WritableSlice>> AMBIGUOUS_REFERENCE_TARGET = new BasicWritableSlice>>("AMBIGUOUS_REFERENCE_TARGET", RewritePolicy.DO_NOTHING);
+ WritableSlice>> AMBIGUOUS_REFERENCE_TARGET = new BasicWritableSlice>>("AMBIGUOUS_REFERENCE_TARGET", RewritePolicy.DO_NOTHING);
WritableSlice LOOP_RANGE_ITERATOR = Slices.createSimpleSlice("LOOP_RANGE_ITERATOR");
WritableSlice LOOP_RANGE_HAS_NEXT = Slices.createSimpleSlice("LOOP_RANGE_HAS_NEXT");
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java
index 1eba532f34c..7bc2afd02c8 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java
@@ -10,7 +10,7 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.calls.CallMaker;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
-import org.jetbrains.jet.lang.resolve.calls.DataFlowInfo;
+import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
@@ -176,7 +176,7 @@ public class BodyResolver {
JetTypeReference typeReference = call.getTypeReference();
if (typeReference != null) {
if (descriptor.getUnsubstitutedPrimaryConstructor() != null) {
- JetType supertype = new CallResolver(context.getSemanticServices(), DataFlowInfo.getEmpty()).resolveCall(
+ JetType supertype = new CallResolver(context.getSemanticServices(), DataFlowInfo.EMPTY).resolveCall(
context.getTrace(), scopeForConstructor,
CallMaker.makeCall(ReceiverDescriptor.NO_RECEIVER, null, call), NO_EXPECTED_TYPE);
if (supertype != null) {
@@ -322,7 +322,7 @@ public class BodyResolver {
private void resolveSecondaryConstructorBody(JetConstructor declaration, final ConstructorDescriptor descriptor, final JetScope declaringScope) {
final JetScope functionInnerScope = getInnerScopeForConstructor(descriptor, declaringScope, false);
- final CallResolver callResolver = new CallResolver(context.getSemanticServices(), DataFlowInfo.getEmpty()); // TODO: dataFlowInfo
+ final CallResolver callResolver = new CallResolver(context.getSemanticServices(), DataFlowInfo.EMPTY); // TODO: dataFlowInfo
JetClass containingClass = PsiTreeUtil.getParentOfType(declaration, JetClass.class);
assert containingClass != null : "This must be guaranteed by the parser";
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java
index c01f2934b82..76c23ca970d 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java
@@ -20,6 +20,7 @@ import java.util.List;
import static org.jetbrains.jet.lang.diagnostics.Errors.UNRESOLVED_REFERENCE;
import static org.jetbrains.jet.lang.diagnostics.Errors.WRONG_NUMBER_OF_TYPE_ARGUMENTS;
+import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
/**
* @author abreslav
@@ -240,6 +241,9 @@ public class TypeResolver {
if (classifierDescriptor == null) {
trace.report(UNRESOLVED_REFERENCE.on(userType.getReferenceExpression()));
}
+ else {
+ trace.record(REFERENCE_TARGET, userType.getReferenceExpression(), classifierDescriptor);
+ }
return classifierDescriptor;
}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/AutoCastUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/AutoCastUtils.java
deleted file mode 100644
index 63d47a2746f..00000000000
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/AutoCastUtils.java
+++ /dev/null
@@ -1,135 +0,0 @@
-package org.jetbrains.jet.lang.resolve.calls;
-
-import com.google.common.collect.Lists;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.jet.lang.descriptors.*;
-import org.jetbrains.jet.lang.psi.JetExpression;
-import org.jetbrains.jet.lang.psi.JetPsiUtil;
-import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
-import org.jetbrains.jet.lang.psi.JetThisExpression;
-import org.jetbrains.jet.lang.resolve.BindingContext;
-import org.jetbrains.jet.lang.resolve.BindingTrace;
-import org.jetbrains.jet.lang.resolve.scopes.receivers.*;
-import org.jetbrains.jet.lang.types.JetType;
-import org.jetbrains.jet.lang.types.JetTypeChecker;
-
-import java.util.Collections;
-import java.util.List;
-
-import static org.jetbrains.jet.lang.diagnostics.Errors.AUTOCAST_IMPOSSIBLE;
-import static org.jetbrains.jet.lang.resolve.BindingContext.AUTOCAST;
-import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
-
-/**
- * @author abreslav
- */
-public class AutoCastUtils {
-
- private AutoCastUtils() {}
-
- public static List getAutoCastVariants(@NotNull final BindingContext bindingContext, @NotNull final DataFlowInfo dataFlowInfo, @NotNull ReceiverDescriptor receiverToCast) {
- return receiverToCast.accept(new ReceiverDescriptorVisitor, Object>() {
- @Override
- public List visitNoReceiver(ReceiverDescriptor noReceiver, Object data) {
- return Collections.emptyList();
- }
-
- @Override
- public List visitTransientReceiver(TransientReceiver receiver, Object data) {
- return Collections.emptyList();
- }
-
- @Override
- public List visitExtensionReceiver(ExtensionReceiver receiver, Object data) {
- return castThis(dataFlowInfo, receiver);
- }
-
- @Override
- public List visitClassReceiver(ClassReceiver receiver, Object data) {
- return castThis(dataFlowInfo, receiver);
- }
-
- @Override
- public List visitExpressionReceiver(ExpressionReceiver receiver, Object data) {
- JetExpression expression = receiver.getExpression();
- VariableDescriptor variableDescriptor = getVariableDescriptorFromSimpleName(bindingContext, expression);
- if (variableDescriptor != null) {
- List result = Lists.newArrayList();
- for (JetType possibleType : dataFlowInfo.getPossibleTypesForVariable(variableDescriptor)) {
- result.add(new AutoCastReceiver(receiver, possibleType, isAutoCastable(variableDescriptor)));
- }
- return result;
- }
- else if (expression instanceof JetThisExpression) {
- return castThis(dataFlowInfo, receiver);
- }
- return Collections.emptyList();
- }
- }, null);
- }
-
- private static List castThis(@NotNull DataFlowInfo dataFlowInfo, @NotNull ReceiverDescriptor receiver) {
- assert receiver.exists();
- List result = Lists.newArrayList();
- for (JetType possibleType : dataFlowInfo.getPossibleTypesForReceiver(receiver)) {
- result.add(new AutoCastReceiver(receiver, possibleType, true));
- }
- return result;
- }
-
- @Nullable
- public static JetType castExpression(@NotNull JetExpression expression, @NotNull JetType expectedType, @NotNull DataFlowInfo dataFlowInfo, @NotNull BindingTrace trace) {
- JetTypeChecker typeChecker = JetTypeChecker.INSTANCE;
- VariableDescriptor variableDescriptor = getVariableDescriptorFromSimpleName(trace.getBindingContext(), expression);
- if (variableDescriptor != null) {
- List possibleTypes = Lists.newArrayList(dataFlowInfo.getPossibleTypesForVariable(variableDescriptor));
- Collections.reverse(possibleTypes);
- for (JetType possibleType : possibleTypes) {
- if (typeChecker.isSubtypeOf(possibleType, expectedType)) {
- if (isAutoCastable(variableDescriptor)) {
- trace.record(AUTOCAST, expression, possibleType);
- }
- else {
- trace.report(AUTOCAST_IMPOSSIBLE.on(expression, possibleType, expression.getText()));
- }
- return possibleType;
- }
- }
- }
- return null;
- }
-
- @Nullable
- public static VariableDescriptor getVariableDescriptorFromSimpleName(@NotNull BindingContext bindingContext, @NotNull JetExpression expression) {
- JetExpression receiver = JetPsiUtil.deparenthesize(expression);
- VariableDescriptor variableDescriptor = null;
- if (receiver instanceof JetSimpleNameExpression) {
- JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) receiver;
- DeclarationDescriptor declarationDescriptor = bindingContext.get(REFERENCE_TARGET, nameExpression);
- if (declarationDescriptor instanceof VariableDescriptor) {
- variableDescriptor = (VariableDescriptor) declarationDescriptor;
- }
- }
- return variableDescriptor;
- }
-
- public static boolean isAutoCastable(@NotNull VariableDescriptor variableDescriptor) {
- if (variableDescriptor.isVar()) return false;
- if (variableDescriptor instanceof PropertyDescriptor) {
- PropertyDescriptor propertyDescriptor = (PropertyDescriptor) variableDescriptor;
- DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
- if (containingDeclaration instanceof ClassDescriptor) {
- ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
- if (classDescriptor.getModality().isOverridable() && propertyDescriptor.getModality().isOverridable()) return false;
- }
- else {
- assert !propertyDescriptor.getModality().isOverridable() : "Property outside a class must not be overridable";
- }
- PropertyGetterDescriptor getter = propertyDescriptor.getGetter();
- if (getter == null || !getter.isDefault()) return false;
- }
- return true;
- }
-
-}
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java
index 4395382f451..3840d59e444 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java
@@ -11,6 +11,8 @@ import org.jetbrains.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.*;
+import org.jetbrains.jet.lang.resolve.calls.autocasts.AutoCastServiceImpl;
+import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
@@ -25,8 +27,8 @@ import java.util.*;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
import static org.jetbrains.jet.lang.resolve.calls.ResolutionStatus.*;
-import static org.jetbrains.jet.lang.resolve.calls.ResolvedCall.MAP_TO_CANDIDATE;
-import static org.jetbrains.jet.lang.resolve.calls.ResolvedCall.MAP_TO_RESULT;
+import static org.jetbrains.jet.lang.resolve.calls.ResolvedCallImpl.MAP_TO_CANDIDATE;
+import static org.jetbrains.jet.lang.resolve.calls.ResolvedCallImpl.MAP_TO_RESULT;
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER;
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
@@ -149,7 +151,7 @@ public class CallResolver {
trace.report(NO_CONSTRUCTOR.on(reportAbsenceOn));
return checkArgumentTypesAndFail(trace, scope, call);
}
- prioritizedTasks.add(new ResolutionTask(TaskPrioritizer.convertWithImpliedThis(scope, Collections.singletonList(NO_RECEIVER), constructors), call, DataFlowInfo.getEmpty()));
+ prioritizedTasks.add(new ResolutionTask(TaskPrioritizer.convertWithImpliedThis(scope, Collections.singletonList(NO_RECEIVER), constructors), call, DataFlowInfo.EMPTY));
}
else {
// trace.getErrorHandler().genericError(calleeExpression.getNode(), "Not a class");
@@ -169,7 +171,7 @@ public class CallResolver {
trace.report(NO_CONSTRUCTOR.on(reportAbsenceOn));
return checkArgumentTypesAndFail(trace, scope, call);
}
- prioritizedTasks = Collections.singletonList(new ResolutionTask(ResolvedCall.convertCollection(constructors), call, DataFlowInfo.getEmpty()));
+ prioritizedTasks = Collections.singletonList(new ResolutionTask(ResolvedCallImpl.convertCollection(constructors), call, DataFlowInfo.EMPTY));
}
else {
throw new UnsupportedOperationException("Type argument inference not implemented for " + call);
@@ -192,12 +194,12 @@ public class CallResolver {
@NotNull JetType expectedType,
@NotNull final List> prioritizedTasks, // high to low priority
@NotNull final JetReferenceExpression reference) {
- ResolvedCall resolvedCall = doResolveCall(trace, scope, call, expectedType, prioritizedTasks, reference);
+ ResolvedCallImpl resolvedCall = doResolveCall(trace, scope, call, expectedType, prioritizedTasks, reference);
return resolvedCall == null ? null : resolvedCall.getResultingDescriptor();
}
@Nullable
- private ResolvedCall doResolveCall(
+ private ResolvedCallImpl doResolveCall(
@NotNull BindingTrace trace,
@NotNull JetScope scope,
@NotNull final Call call,
@@ -208,7 +210,7 @@ public class CallResolver {
OverloadResolutionResults resultsForFirstNonemptyCandidateSet = null;
TracingStrategy tracing = new TracingStrategy() {
@Override
- public void bindReference(@NotNull BindingTrace trace, @NotNull ResolvedCall resolvedCall) {
+ public void bindReference(@NotNull BindingTrace trace, @NotNull ResolvedCallImpl resolvedCall) {
D descriptor = resolvedCall.getCandidateDescriptor();
// if (descriptor instanceof VariableAsFunctionDescriptor) {
// VariableAsFunctionDescriptor variableAsFunctionDescriptor = (VariableAsFunctionDescriptor) descriptor;
@@ -221,7 +223,7 @@ public class CallResolver {
}
@Override
- public void recordAmbiguity(BindingTrace trace, Collection> candidates) {
+ public void recordAmbiguity(BindingTrace trace, Collection> candidates) {
trace.record(AMBIGUOUS_REFERENCE_TARGET, reference, candidates);
}
@@ -270,12 +272,12 @@ public class CallResolver {
}
@Override
- public void ambiguity(@NotNull BindingTrace trace, @NotNull Set> descriptors) {
+ public void ambiguity(@NotNull BindingTrace trace, @NotNull Set> descriptors) {
trace.report(OVERLOAD_RESOLUTION_AMBIGUITY.on(call.getCallNode(), descriptors));
}
@Override
- public void noneApplicable(@NotNull BindingTrace trace, @NotNull Set> descriptors) {
+ public void noneApplicable(@NotNull BindingTrace trace, @NotNull Set> descriptors) {
trace.report(NONE_APPLICABLE.on(reference, descriptors));
}
@@ -301,7 +303,10 @@ public class CallResolver {
JetBinaryExpression binaryExpression = (JetBinaryExpression) callElement;
JetSimpleNameExpression operationReference = binaryExpression.getOperationReference();
String operationString = operationReference.getReferencedNameElementType() == JetTokens.IDENTIFIER ? operationReference.getText() : OperatorConventions.getNameForOperationSymbol(operationReference.getReferencedNameElementType());
- trace.report(UNSAFE_INFIX_CALL.on(reference, binaryExpression.getLeft().getText(), operationString, binaryExpression.getRight().getText()));
+ JetExpression right = binaryExpression.getRight();
+ if (right != null) {
+ trace.report(UNSAFE_INFIX_CALL.on(reference, binaryExpression.getLeft().getText(), operationString, right.getText()));
+ }
}
else {
trace.report(UNSAFE_CALL.on(reference, type));
@@ -347,7 +352,7 @@ public class CallResolver {
@NotNull
private OverloadResolutionResults performResolution(@NotNull BindingTrace trace, @NotNull JetScope scope, @NotNull JetType expectedType, @NotNull ResolutionTask task, @NotNull TracingStrategy tracing) {
- for (ResolvedCall candidateCall : task.getCandidates()) {
+ for (ResolvedCallImpl candidateCall : task.getCandidates()) {
D candidate = candidateCall.getCandidateDescriptor();
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(trace);
candidateCall.setTrace(temporaryTrace);
@@ -415,6 +420,9 @@ public class CallResolver {
assert substitute != null;
replaceValueParametersWithSubstitutedOnes(candidateCall, substitute);
candidateCall.setResultingDescriptor(substitute);
+ for (TypeParameterDescriptor typeParameterDescriptor : candidateCall.getCandidateDescriptor().getTypeParameters()) {
+ candidateCall.recordTypeArgument(typeParameterDescriptor, solution.getValue(typeParameterDescriptor));
+ }
candidateCall.setStatus(SUCCESS);
}
else {
@@ -454,6 +462,12 @@ public class CallResolver {
candidateCall.setResultingDescriptor(substitutedDescriptor);
replaceValueParametersWithSubstitutedOnes(candidateCall, substitutedDescriptor);
+
+ List typeParameters = candidateCall.getCandidateDescriptor().getTypeParameters();
+ for (int i = 0; i < typeParameters.size(); i++) {
+ TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i);
+ candidateCall.recordTypeArgument(typeParameterDescriptor, typeArguments.get(i));
+ }
candidateCall.setStatus(checkAllValueArguments(scope, tracing, task, candidateCall));
}
else {
@@ -469,9 +483,9 @@ public class CallResolver {
recordAutoCastIfNecessary(candidateCall.getThisObject(), candidateCall.getTrace());
}
- Set> successfulCandidates = Sets.newLinkedHashSet();
- Set> failedCandidates = Sets.newLinkedHashSet();
- for (ResolvedCall candidateCall : task.getCandidates()) {
+ Set> successfulCandidates = Sets.newLinkedHashSet();
+ Set> failedCandidates = Sets.newLinkedHashSet();
+ for (ResolvedCallImpl candidateCall : task.getCandidates()) {
ResolutionStatus status = candidateCall.getStatus();
if (status.isSuccess()) {
successfulCandidates.add(candidateCall);
@@ -541,7 +555,7 @@ public class CallResolver {
// };
// }
- private void replaceValueParametersWithSubstitutedOnes(ResolvedCall candidateCall, @NotNull D substitutedDescriptor) {
+ private void replaceValueParametersWithSubstitutedOnes(ResolvedCallImpl candidateCall, @NotNull D substitutedDescriptor) {
Map parameterMap = Maps.newHashMap();
for (ValueParameterDescriptor valueParameterDescriptor : substitutedDescriptor.getValueParameters()) {
parameterMap.put(valueParameterDescriptor.getOriginal(), valueParameterDescriptor);
@@ -557,14 +571,14 @@ public class CallResolver {
}
}
- private ResolutionStatus checkAllValueArguments(JetScope scope, TracingStrategy tracing, ResolutionTask task, ResolvedCall candidateCall) {
+ private ResolutionStatus checkAllValueArguments(JetScope scope, TracingStrategy tracing, ResolutionTask task, ResolvedCallImpl candidateCall) {
ResolutionStatus result = checkValueArgumentTypes(scope, candidateCall);
result = result.combine(checkReceiver(tracing, candidateCall, candidateCall.getResultingDescriptor().getReceiverParameter(), candidateCall.getReceiverArgument(), task));
result = result.combine(checkReceiver(tracing, candidateCall, candidateCall.getResultingDescriptor().getExpectedThisObject(), candidateCall.getThisObject(), task));
return result;
}
- private ResolutionStatus checkReceiver(TracingStrategy tracing, ResolvedCall candidateCall, ReceiverDescriptor receiverParameter, ReceiverDescriptor receiverArgument, ResolutionTask task) {
+ private ResolutionStatus checkReceiver(TracingStrategy tracing, ResolvedCallImpl candidateCall, ReceiverDescriptor receiverParameter, ReceiverDescriptor receiverArgument, ResolutionTask task) {
ResolutionStatus result = SUCCESS;
if (receiverParameter.exists() && receiverArgument.exists()) {
ASTNode callOperationNode = task.getCall().getCallOperationNode();
@@ -592,7 +606,7 @@ public class CallResolver {
return result;
}
- private ResolutionStatus checkValueArgumentTypes(JetScope scope, ResolvedCall candidateCall) {
+ private ResolutionStatus checkValueArgumentTypes(JetScope scope, ResolvedCallImpl candidateCall) {
ResolutionStatus result = SUCCESS;
for (Map.Entry entry : candidateCall.getValueArguments().entrySet()) {
ValueParameterDescriptor parameterDescriptor = entry.getKey();
@@ -618,7 +632,7 @@ public class CallResolver {
// }
// }
// if (autoCastType != null) {
-// if (AutoCastUtils.isAutoCastable(variableDescriptor)) {
+// if (AutoCastUtils.isStableVariable(variableDescriptor)) {
// temporaryTrace.record(AUTOCAST, argumentExpression, autoCastType);
// }
// else {
@@ -639,16 +653,16 @@ public class CallResolver {
private OverloadResolutionResults computeResultAndReportErrors(
BindingTrace trace,
TracingStrategy tracing,
- Set> successfulCandidates,
- Set> failedCandidates) {
+ Set> successfulCandidates,
+ Set> failedCandidates) {
// TODO : maybe it's better to filter overrides out first, and only then look for the maximally specific
if (successfulCandidates.size() > 0) {
return chooseAndReportMaximallySpecific(trace, tracing, successfulCandidates);
}
else if (!failedCandidates.isEmpty()) {
if (failedCandidates.size() != 1) {
- Set> weakErrors = Sets.newLinkedHashSet();
- for (ResolvedCall candidate : failedCandidates) {
+ Set> weakErrors = Sets.newLinkedHashSet();
+ for (ResolvedCallImpl candidate : failedCandidates) {
if (candidate.getStatus().isWeakError()) {
weakErrors.add(candidate);
}
@@ -662,7 +676,7 @@ public class CallResolver {
return OverloadResolutionResults.manyFailedCandidates(results.getResults());
}
- Set> noOverrides = OverridingUtil.filterOverrides(failedCandidates, MAP_TO_CANDIDATE);
+ Set> noOverrides = OverridingUtil.filterOverrides(failedCandidates, MAP_TO_CANDIDATE);
if (noOverrides.size() != 1) {
// tracing.reportOverallResolutionError(trace, "None of the following functions can be called with the arguments supplied: "
// + makeErrorMessageForMultipleDescriptors(noOverrides));
@@ -672,7 +686,7 @@ public class CallResolver {
}
failedCandidates = noOverrides;
}
- ResolvedCall failed = failedCandidates.iterator().next();
+ ResolvedCallImpl failed = failedCandidates.iterator().next();
failed.getTrace().commit();
return OverloadResolutionResults.singleFailedCandidate(failed);
}
@@ -682,12 +696,12 @@ public class CallResolver {
}
}
- private OverloadResolutionResults chooseAndReportMaximallySpecific(BindingTrace trace, TracingStrategy tracing, Set> candidates) {
+ private OverloadResolutionResults chooseAndReportMaximallySpecific(BindingTrace trace, TracingStrategy tracing, Set> candidates) {
if (candidates.size() != 1) {
- Set> cleanCandidates = Sets.newLinkedHashSet(candidates);
+ Set> cleanCandidates = Sets.newLinkedHashSet(candidates);
boolean allClean = true;
- for (Iterator> iterator = cleanCandidates.iterator(); iterator.hasNext(); ) {
- ResolvedCall candidate = iterator.next();
+ for (Iterator> iterator = cleanCandidates.iterator(); iterator.hasNext(); ) {
+ ResolvedCallImpl candidate = iterator.next();
if (candidate.isDirty()) {
iterator.remove();
allClean = false;
@@ -697,17 +711,17 @@ public class CallResolver {
if (cleanCandidates.isEmpty()) {
cleanCandidates = candidates;
}
- ResolvedCall maximallySpecific = overloadingConflictResolver.findMaximallySpecific(cleanCandidates, false);
+ ResolvedCallImpl maximallySpecific = overloadingConflictResolver.findMaximallySpecific(cleanCandidates, false);
if (maximallySpecific != null) {
return OverloadResolutionResults.success(maximallySpecific);
}
- ResolvedCall maximallySpecificGenericsDiscriminated = overloadingConflictResolver.findMaximallySpecific(cleanCandidates, true);
+ ResolvedCallImpl maximallySpecificGenericsDiscriminated = overloadingConflictResolver.findMaximallySpecific(cleanCandidates, true);
if (maximallySpecificGenericsDiscriminated != null) {
return OverloadResolutionResults.success(maximallySpecificGenericsDiscriminated);
}
- Set> noOverrides = OverridingUtil.filterOverrides(candidates, MAP_TO_RESULT);
+ Set> noOverrides = OverridingUtil.filterOverrides(candidates, MAP_TO_RESULT);
if (allClean) {
// tracing.reportOverallResolutionError(trace, "Overload resolution ambiguity: "
// + makeErrorMessageForMultipleDescriptors(noOverrides));
@@ -719,7 +733,7 @@ public class CallResolver {
return OverloadResolutionResults.ambiguity(noOverrides);
}
else {
- ResolvedCall result = candidates.iterator().next();
+ ResolvedCallImpl result = candidates.iterator().next();
TemporaryBindingTrace temporaryTrace = result.getTrace();
temporaryTrace.commit();
@@ -748,24 +762,24 @@ public class CallResolver {
@NotNull
public OverloadResolutionResults resolveExactSignature(@NotNull JetScope scope, @NotNull ReceiverDescriptor receiver, @NotNull String name, @NotNull List parameterTypes) {
- List> result = findCandidatesByExactSignature(scope, receiver, name, parameterTypes);
+ List> result = findCandidatesByExactSignature(scope, receiver, name, parameterTypes);
BindingTraceContext trace = new BindingTraceContext();
TemporaryBindingTrace temporaryBindingTrace = TemporaryBindingTrace.create(trace);
- Set> candidates = Sets.newLinkedHashSet();
- for (ResolvedCall call : result) {
+ Set> candidates = Sets.newLinkedHashSet();
+ for (ResolvedCallImpl call : result) {
call.setTrace(temporaryBindingTrace);
candidates.add(call);
}
- return computeResultAndReportErrors(trace, TracingStrategy.EMPTY, candidates, Collections.>emptySet());
+ return computeResultAndReportErrors(trace, TracingStrategy.EMPTY, candidates, Collections.>emptySet());
}
- private List> findCandidatesByExactSignature(JetScope scope, ReceiverDescriptor receiver, String name, List parameterTypes) {
- List> result = Lists.newArrayList();
+ private List> findCandidatesByExactSignature(JetScope scope, ReceiverDescriptor receiver, String name, List parameterTypes) {
+ List> result = Lists.newArrayList();
if (receiver.exists()) {
- Collection> extensionFunctionDescriptors = ResolvedCall.convertCollection(scope.getFunctions(name));
- List> nonlocal = Lists.newArrayList();
- List> local = Lists.newArrayList();
+ Collection> extensionFunctionDescriptors = ResolvedCallImpl.convertCollection(scope.getFunctions(name));
+ List> nonlocal = Lists.newArrayList();
+ List> local = Lists.newArrayList();
TaskPrioritizer.splitLexicallyLocalDescriptors(extensionFunctionDescriptors, scope.getContainingDeclaration(), local, nonlocal);
@@ -773,7 +787,7 @@ public class CallResolver {
return result;
}
- Collection> functionDescriptors = ResolvedCall.convertCollection(receiver.getType().getMemberScope().getFunctions(name));
+ Collection> functionDescriptors = ResolvedCallImpl.convertCollection(receiver.getType().getMemberScope().getFunctions(name));
if (lookupExactSignature(functionDescriptors, parameterTypes, result)) {
return result;
@@ -782,14 +796,14 @@ public class CallResolver {
return result;
}
else {
- lookupExactSignature(ResolvedCall.convertCollection(scope.getFunctions(name)), parameterTypes, result);
+ lookupExactSignature(ResolvedCallImpl.convertCollection(scope.getFunctions(name)), parameterTypes, result);
return result;
}
}
- private boolean lookupExactSignature(Collection> candidates, List parameterTypes, List> result) {
+ private boolean lookupExactSignature(Collection> candidates, List parameterTypes, List> result) {
boolean found = false;
- for (ResolvedCall resolvedCall : candidates) {
+ for (ResolvedCallImpl resolvedCall : candidates) {
FunctionDescriptor functionDescriptor = resolvedCall.getResultingDescriptor();
if (functionDescriptor.getReceiverParameter().exists()) continue;
if (!functionDescriptor.getTypeParameters().isEmpty()) continue;
@@ -800,9 +814,9 @@ public class CallResolver {
return found;
}
- private boolean findExtensionFunctions(Collection> candidates, ReceiverDescriptor receiver, List parameterTypes, List> result) {
+ private boolean findExtensionFunctions(Collection> candidates, ReceiverDescriptor receiver, List parameterTypes, List> result) {
boolean found = false;
- for (ResolvedCall resolvedCall : candidates) {
+ for (ResolvedCallImpl resolvedCall : candidates) {
FunctionDescriptor functionDescriptor = resolvedCall.getResultingDescriptor();
ReceiverDescriptor functionReceiver = functionDescriptor.getReceiverParameter();
if (!functionReceiver.exists()) continue;
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/DataFlowInfo.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/DataFlowInfo.java
deleted file mode 100644
index 0b91738ee7f..00000000000
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/DataFlowInfo.java
+++ /dev/null
@@ -1,224 +0,0 @@
-package org.jetbrains.jet.lang.resolve.calls;
-
-import com.google.common.collect.*;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
-import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
-import org.jetbrains.jet.lang.types.JetType;
-import org.jetbrains.jet.lang.types.TypeUtils;
-import org.jetbrains.jet.util.CommonSuppliers;
-
-import java.util.*;
-
-/**
- * @author abreslav
- */
-public class DataFlowInfo {
-
- public static abstract class CompositionOperator {
-
- public abstract DataFlowInfo compose(DataFlowInfo a, DataFlowInfo b);
- }
- public static final CompositionOperator AND = new CompositionOperator() {
- @Override
- public DataFlowInfo compose(DataFlowInfo a, DataFlowInfo b) {
- return a.and(b);
- }
- };
-
- public static final CompositionOperator OR = new CompositionOperator() {
- @Override
- public DataFlowInfo compose(DataFlowInfo a, DataFlowInfo b) {
- return a.or(b);
- }
- };
-
- private static DataFlowInfo EMPTY = new DataFlowInfo(ImmutableMap.