Replace some REFERENCE_TARGET calls with RESOLVED_CALL

Also don't do unnecessary and failing casts in CodegenAnnotatingVisitor for SAM
adapters

 #KT-3173 Fixed
 #KT-3999 Fixed
 #KT-4682 Fixed
This commit is contained in:
Alexander Udalov
2014-05-05 03:37:51 +04:00
parent 13f7ca51b0
commit 51b01b5d7d
7 changed files with 127 additions and 65 deletions
@@ -27,7 +27,6 @@ import com.intellij.util.Function;
import com.intellij.util.containers.Stack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.constants.IntegerValueConstant;
import org.jetbrains.jet.codegen.binding.CalculatedClosure;
import org.jetbrains.jet.codegen.binding.CodegenBinding;
import org.jetbrains.jet.codegen.binding.MutableClosure;
@@ -47,6 +46,7 @@ import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.calls.model.*;
import org.jetbrains.jet.lang.resolve.calls.util.CallMaker;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.constants.IntegerValueConstant;
import org.jetbrains.jet.lang.resolve.constants.IntegerValueTypeConstant;
import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
@@ -1341,12 +1341,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
JetDelegatorToSuperCall superCall = closure.getSuperCall();
if (superCall != null) {
ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET,
superCall
.getCalleeExpression()
.getConstructorReferenceExpression());
ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext
.get(BindingContext.REFERENCE_TARGET, superCall.getCalleeExpression().getConstructorReferenceExpression());
assert superConstructor != null;
//noinspection SuspiciousMethodCalls
CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor);
Type[] argumentTypes = superCallable.getAsmMethod().getArgumentTypes();
ResolvedCall<?> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, superCall.getCalleeExpression());
@@ -2640,21 +2637,19 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
else {
ResolvedCall<?> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, reference);
Call call = bindingContext.get(BindingContext.CALL, reference);
assert resolvedCall != null : "Binary expression call is unresolved: " + expression.getText();
FunctionDescriptor descriptor = (FunctionDescriptor) resolvedCall.getResultingDescriptor();
DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, reference);
assert op instanceof FunctionDescriptor : String.valueOf(op);
Callable callable = resolveToCallable((FunctionDescriptor) op, false);
Callable callable = resolveToCallable(descriptor, false);
if (callable instanceof IntrinsicMethod) {
//noinspection ConstantConditions
Type returnType = typeMapper.mapType(resolvedCall.getResultingDescriptor());
Type returnType = typeMapper.mapType(descriptor);
((IntrinsicMethod) callable).generate(this, v, returnType, expression,
Arrays.asList(expression.getLeft(), expression.getRight()), receiver);
return StackValue.onStack(returnType);
}
else {
return invokeFunction(call, receiver, resolvedCall);
}
Call call = bindingContext.get(BindingContext.CALL, reference);
return invokeFunction(call, receiver, resolvedCall);
}
}
@@ -2830,9 +2825,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
private StackValue generateComparison(JetBinaryExpression expression, StackValue receiver) {
DeclarationDescriptor target = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference());
assert target instanceof FunctionDescriptor : "compareTo target should be a function: " + target;
FunctionDescriptor descriptor = (FunctionDescriptor) target;
ResolvedCall<?> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference());
assert resolvedCall != null : "compareTo target should be resolved: " + expression.getText();
FunctionDescriptor descriptor = (FunctionDescriptor) resolvedCall.getResultingDescriptor();
JetExpression left = expression.getLeft();
JetExpression right = expression.getRight();
@@ -2847,7 +2842,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
gen(right, type);
}
else {
ResolvedCall<?> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference());
Call call = bindingContext.get(BindingContext.CALL, expression.getOperationReference());
StackValue result = invokeFunction(call, receiver, resolvedCall);
type = Type.INT_TYPE;
@@ -2867,52 +2861,46 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
private StackValue generateAugmentedAssignment(JetBinaryExpression expression) {
DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference());
assert op instanceof FunctionDescriptor : String.valueOf(op);
Callable callable = resolveToCallable((FunctionDescriptor) op, false);
ResolvedCall<?> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference());
assert resolvedCall != null : "Augmented assignment call is unresolved: " + expression.getText();
FunctionDescriptor descriptor = (FunctionDescriptor) resolvedCall.getResultingDescriptor();
Callable callable = resolveToCallable(descriptor, false);
JetExpression lhs = expression.getLeft();
// if (lhs instanceof JetArrayAccessExpression) {
// JetArrayAccessExpression arrayAccessExpression = (JetArrayAccessExpression) lhs;
// if (arrayAccessExpression.getIndexExpressions().size() != 1) {
// throw new UnsupportedOperationException("Augmented assignment with multi-index");
// }
// }
Type lhsType = expressionType(lhs);
boolean keepReturnValue;
//noinspection ConstantConditions
if (bindingContext.get(BindingContext.VARIABLE_REASSIGNMENT, expression)) {
if (callable instanceof IntrinsicMethod) {
StackValue value = gen(lhs); // receiver
value.dupReceiver(v); // receiver receiver
value.put(lhsType, v); // receiver lhs
IntrinsicMethod intrinsic = (IntrinsicMethod) callable;
JetExpression right = expression.getRight();
assert right != null;
Type returnType = typeMapper.mapType((FunctionDescriptor) op);
intrinsic.generate(this, v, returnType, expression, Collections.singletonList(right), StackValue.onStack(lhsType));
value.dupReceiver(v); // receiver receiver
value.put(lhsType, v); // receiver lhs
((IntrinsicMethod) callable).generate(this, v, typeMapper.mapType(descriptor), expression,
Collections.singletonList(expression.getRight()), StackValue.onStack(lhsType));
value.store(lhsType, v);
return StackValue.none();
}
else {
callAugAssignMethod(expression, (CallableMethod) callable, lhsType, true);
keepReturnValue = true;
}
}
else {
JetType type = ((FunctionDescriptor) op).getReturnType();
assert type != null;
boolean keepReturnValue = !type.equals(KotlinBuiltIns.getInstance().getUnitType());
callAugAssignMethod(expression, (CallableMethod) callable, lhsType, keepReturnValue);
keepReturnValue = !KotlinBuiltIns.getInstance().getUnitType().equals(descriptor.getReturnType());
}
callAugAssignMethod(expression, resolvedCall, (CallableMethod) callable, lhsType, keepReturnValue);
return StackValue.none();
}
private void callAugAssignMethod(JetBinaryExpression expression, CallableMethod callable, Type lhsType, boolean keepReturnValue) {
JetSimpleNameExpression reference = expression.getOperationReference();
ResolvedCall<?> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, reference);
Call call = bindingContext.get(BindingContext.CALL, reference);
assert resolvedCall != null : "Resolved call should be not null for operation reference in " + expression.getText();
private void callAugAssignMethod(
@NotNull JetBinaryExpression expression,
@NotNull ResolvedCall<?> resolvedCall,
@NotNull CallableMethod callable,
@NotNull Type lhsType,
boolean keepReturnValue
) {
Call call = bindingContext.get(BindingContext.CALL, expression.getOperationReference());
assert call != null : "Call should be not null for operation reference in " + expression.getText();
StackValue value = gen(expression.getLeft());
@@ -22,7 +22,6 @@ import com.intellij.psi.tree.TokenSet;
import com.intellij.util.containers.Stack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.jet.codegen.SamCodegenUtil;
import org.jetbrains.jet.codegen.state.GenerationState;
import org.jetbrains.jet.lang.descriptors.*;
@@ -43,6 +42,7 @@ import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.org.objectweb.asm.Type;
import java.util.*;
@@ -445,11 +445,10 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
public void visitBinaryExpression(@NotNull JetBinaryExpression expression) {
super.visitBinaryExpression(expression);
FunctionDescriptor operationDescriptor =
(FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference());
if (operationDescriptor == null) return;
DeclarationDescriptor operationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference());
if (!(operationDescriptor instanceof FunctionDescriptor)) return;
FunctionDescriptor original = SamCodegenUtil.getOriginalIfSamAdapter(operationDescriptor);
FunctionDescriptor original = SamCodegenUtil.getOriginalIfSamAdapter((FunctionDescriptor) operationDescriptor);
if (original == null) return;
JavaClassDescriptor samInterfaceOfParameter = getInterfaceIfSamType(original.getValueParameters().get(0).getType());
@@ -468,24 +467,18 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
public void visitArrayAccessExpression(@NotNull JetArrayAccessExpression expression) {
super.visitArrayAccessExpression(expression);
FunctionDescriptor operationDescriptor = (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, expression);
if (operationDescriptor == null) {
return;
}
DeclarationDescriptor operationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, expression);
if (!(operationDescriptor instanceof FunctionDescriptor)) return;
boolean isSetter = operationDescriptor.getName().asString().equals("set");
FunctionDescriptor original = SamCodegenUtil.getOriginalIfSamAdapter(operationDescriptor);
if (original == null) {
return;
}
FunctionDescriptor original = SamCodegenUtil.getOriginalIfSamAdapter((FunctionDescriptor) operationDescriptor);
if (original == null) return;
List<JetExpression> indexExpressions = expression.getIndexExpressions();
List<ValueParameterDescriptor> parameters = original.getValueParameters();
for (ValueParameterDescriptor valueParameter : parameters) {
JavaClassDescriptor samInterface = getInterfaceIfSamType(valueParameter.getType());
if (samInterface == null) {
continue;
}
if (samInterface == null) continue;
if (isSetter && valueParameter.getIndex() == parameters.size() - 1) {
PsiElement parent = expression.getParent();
@@ -0,0 +1,4 @@
fun box(): String {
val sum = {Int.(other: Int) -> this + other }
return if (1 sum 2 == 3) "OK" else "Fail"
}
@@ -0,0 +1,30 @@
class A() {
fun A.invoke(a: A) = "$this ${this@A} $a"
}
fun test1() {
val a = A()
val b = A()
val c = A()
a.b(c)
a b c
}
fun test2() {
val a: ExtensionFunction1<*, *, *>.(ExtensionFunction1<*, *, *>)->Unit = {}
val b: ExtensionFunction1<*, *, *>.(ExtensionFunction1<*, *, *>)->Unit = {"$this $it"}
val c: ExtensionFunction1<*, *, *>.(ExtensionFunction1<*, *, *>)->Unit = {}
a.b(c)
a b c
}
fun Int.foo(a: Int) = this * a
val boo = {Int.(a: Int): Int -> this + a}
fun box(): String {
test1()
test2()
1 foo 2
3 boo 4
return "OK"
}
@@ -0,0 +1,8 @@
fun foo(compareTo: Any.(p: Function0<Int>) -> Int, p: () -> Int) {
p < p
}
fun box(): String {
foo({ it() }, { 42 })
return "OK"
}
@@ -0,0 +1,10 @@
class A
fun foo(plusAssign: A.(A) -> Unit) {
A() += A()
}
fun box(): String {
foo { }
return "OK"
}
@@ -31,7 +31,7 @@ import org.jetbrains.jet.codegen.generated.AbstractBlackBoxCodegenTest;
/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("compiler/testData/codegen/box")
@InnerTestClasses({BlackBoxCodegenTestGenerated.Arrays.class, BlackBoxCodegenTestGenerated.BinaryOp.class, BlackBoxCodegenTestGenerated.Bridges.class, BlackBoxCodegenTestGenerated.BuiltinStubMethods.class, BlackBoxCodegenTestGenerated.CallableReference.class, BlackBoxCodegenTestGenerated.Casts.class, BlackBoxCodegenTestGenerated.Classes.class, BlackBoxCodegenTestGenerated.Closures.class, BlackBoxCodegenTestGenerated.Constants.class, BlackBoxCodegenTestGenerated.ControlStructures.class, BlackBoxCodegenTestGenerated.DefaultArguments.class, BlackBoxCodegenTestGenerated.DelegatedProperty.class, BlackBoxCodegenTestGenerated.Elvis.class, BlackBoxCodegenTestGenerated.Enum.class, BlackBoxCodegenTestGenerated.ExclExcl.class, BlackBoxCodegenTestGenerated.ExtensionFunctions.class, BlackBoxCodegenTestGenerated.ExtensionProperties.class, BlackBoxCodegenTestGenerated.FakeOverride.class, BlackBoxCodegenTestGenerated.FieldRename.class, BlackBoxCodegenTestGenerated.Finally.class, BlackBoxCodegenTestGenerated.Functions.class, BlackBoxCodegenTestGenerated.InnerNested.class, BlackBoxCodegenTestGenerated.Instructions.class, BlackBoxCodegenTestGenerated.Intrinsics.class, BlackBoxCodegenTestGenerated.Labels.class, BlackBoxCodegenTestGenerated.LocalClasses.class, BlackBoxCodegenTestGenerated.MultiDecl.class, BlackBoxCodegenTestGenerated.Objects.class, BlackBoxCodegenTestGenerated.OperatorConventions.class, BlackBoxCodegenTestGenerated.Package.class, BlackBoxCodegenTestGenerated.PrimitiveTypes.class, BlackBoxCodegenTestGenerated.Properties.class, BlackBoxCodegenTestGenerated.Reflection.class, BlackBoxCodegenTestGenerated.SafeCall.class, BlackBoxCodegenTestGenerated.SamConstructors.class, BlackBoxCodegenTestGenerated.Strings.class, BlackBoxCodegenTestGenerated.Super.class, BlackBoxCodegenTestGenerated.ToArray.class, BlackBoxCodegenTestGenerated.Traits.class, BlackBoxCodegenTestGenerated.TypeInfo.class, BlackBoxCodegenTestGenerated.TypeMapping.class, BlackBoxCodegenTestGenerated.UnaryOp.class, BlackBoxCodegenTestGenerated.Unit.class, BlackBoxCodegenTestGenerated.Vararg.class, BlackBoxCodegenTestGenerated.When.class})
@InnerTestClasses({BlackBoxCodegenTestGenerated.Arrays.class, BlackBoxCodegenTestGenerated.BinaryOp.class, BlackBoxCodegenTestGenerated.Bridges.class, BlackBoxCodegenTestGenerated.BuiltinStubMethods.class, BlackBoxCodegenTestGenerated.CallableReference.class, BlackBoxCodegenTestGenerated.Casts.class, BlackBoxCodegenTestGenerated.Classes.class, BlackBoxCodegenTestGenerated.Closures.class, BlackBoxCodegenTestGenerated.Constants.class, BlackBoxCodegenTestGenerated.ControlStructures.class, BlackBoxCodegenTestGenerated.DefaultArguments.class, BlackBoxCodegenTestGenerated.DelegatedProperty.class, BlackBoxCodegenTestGenerated.Elvis.class, BlackBoxCodegenTestGenerated.Enum.class, BlackBoxCodegenTestGenerated.ExclExcl.class, BlackBoxCodegenTestGenerated.ExtensionFunctions.class, BlackBoxCodegenTestGenerated.ExtensionProperties.class, BlackBoxCodegenTestGenerated.FakeOverride.class, BlackBoxCodegenTestGenerated.FieldRename.class, BlackBoxCodegenTestGenerated.Finally.class, BlackBoxCodegenTestGenerated.Functions.class, BlackBoxCodegenTestGenerated.InnerNested.class, BlackBoxCodegenTestGenerated.Instructions.class, BlackBoxCodegenTestGenerated.Intrinsics.class, BlackBoxCodegenTestGenerated.Labels.class, BlackBoxCodegenTestGenerated.LocalClasses.class, BlackBoxCodegenTestGenerated.MultiDecl.class, BlackBoxCodegenTestGenerated.Objects.class, BlackBoxCodegenTestGenerated.OperatorConventions.class, BlackBoxCodegenTestGenerated.Package.class, BlackBoxCodegenTestGenerated.PrimitiveTypes.class, BlackBoxCodegenTestGenerated.Properties.class, BlackBoxCodegenTestGenerated.Reflection.class, BlackBoxCodegenTestGenerated.Regressions.class, BlackBoxCodegenTestGenerated.SafeCall.class, BlackBoxCodegenTestGenerated.SamConstructors.class, BlackBoxCodegenTestGenerated.Strings.class, BlackBoxCodegenTestGenerated.Super.class, BlackBoxCodegenTestGenerated.ToArray.class, BlackBoxCodegenTestGenerated.Traits.class, BlackBoxCodegenTestGenerated.TypeInfo.class, BlackBoxCodegenTestGenerated.TypeMapping.class, BlackBoxCodegenTestGenerated.UnaryOp.class, BlackBoxCodegenTestGenerated.Unit.class, BlackBoxCodegenTestGenerated.Vararg.class, BlackBoxCodegenTestGenerated.When.class})
public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInBox() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/box"), Pattern.compile("^(.+)\\.kt$"), true);
@@ -4864,6 +4864,34 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
}
@TestMetadata("compiler/testData/codegen/box/regressions")
public static class Regressions extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInRegressions() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/box/regressions"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("kt3173.kt")
public void testKt3173() throws Exception {
doTest("compiler/testData/codegen/box/regressions/kt3173.kt");
}
@TestMetadata("kt3999.kt")
public void testKt3999() throws Exception {
doTest("compiler/testData/codegen/box/regressions/kt3999.kt");
}
@TestMetadata("kt4682.kt")
public void testKt4682() throws Exception {
doTest("compiler/testData/codegen/box/regressions/kt4682.kt");
}
@TestMetadata("unjustifiedReferenceTarget.kt")
public void testUnjustifiedReferenceTarget() throws Exception {
doTest("compiler/testData/codegen/box/regressions/unjustifiedReferenceTarget.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/safeCall")
public static class SafeCall extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInSafeCall() throws Exception {
@@ -5626,6 +5654,7 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
suite.addTestSuite(PrimitiveTypes.class);
suite.addTestSuite(Properties.class);
suite.addTestSuite(Reflection.class);
suite.addTestSuite(Regressions.class);
suite.addTestSuite(SafeCall.class);
suite.addTestSuite(SamConstructors.class);
suite.addTestSuite(Strings.class);