Supported SAM adapters as get/set operators.

This commit is contained in:
Evgeny Gerashchenko
2013-06-26 00:17:14 +04:00
parent 779ea1d7b8
commit b1fb0aafea
9 changed files with 126 additions and 3 deletions
@@ -2849,7 +2849,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
private StackValue generateAssignmentExpression(JetBinaryExpression expression) {
StackValue stackValue = gen(expression.getLeft());
gen(expression.getRight(), stackValue.type);
JetExpression right = expression.getRight();
assert right != null : expression.getText();
samAwareGen(right, stackValue.type);
stackValue.store(stackValue.type, v);
return StackValue.none();
}
@@ -3374,7 +3376,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
Method asmMethod = resolveToCallableMethod(operationDescriptor, false, context).getSignature().getAsmMethod();
Type[] argumentTypes = asmMethod.getArgumentTypes();
for (JetExpression jetExpression : expression.getIndexExpressions()) {
gen(jetExpression, argumentTypes[index]);
samAwareGen(jetExpression, argumentTypes[index]);
index++;
}
@@ -16,6 +16,7 @@
package org.jetbrains.jet.codegen.binding;
import com.intellij.psi.PsiElement;
import com.intellij.util.containers.Stack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -39,6 +40,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.jet.lexer.JetTokens;
import java.util.Collections;
import java.util.HashMap;
@@ -381,6 +383,43 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
}
}
@Override
public void visitArrayAccessExpression(JetArrayAccessExpression expression) {
super.visitArrayAccessExpression(expression);
FunctionDescriptor operationDescriptor = (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, expression);
if (operationDescriptor == null) {
return;
}
boolean isSetter = operationDescriptor.getName().asString().equals("set");
FunctionDescriptor original = SamCodegenUtil.getOriginalIfSamAdapter(bindingContext, operationDescriptor);
if (original == null) {
return;
}
List<JetExpression> indexExpressions = expression.getIndexExpressions();
List<ValueParameterDescriptor> parameters = original.getValueParameters();
for (ValueParameterDescriptor valueParameter : parameters) {
ClassDescriptorFromJvmBytecode samInterface = getInterfaceIfSamType(valueParameter.getType());
if (samInterface == null) {
continue;
}
if (isSetter && valueParameter.getIndex() == parameters.size() - 1) {
PsiElement parent = expression.getParent();
if (parent instanceof JetBinaryExpression && ((JetBinaryExpression) parent).getOperationToken() == JetTokens.EQ) {
JetExpression right = ((JetBinaryExpression) parent).getRight();
bindingTrace.record(CodegenBinding.SAM_VALUE, right, samInterface);
}
}
else {
JetExpression indexExpression = indexExpressions.get(valueParameter.getIndex());
bindingTrace.record(CodegenBinding.SAM_VALUE, indexExpression, samInterface);
}
}
}
@Nullable
private static ClassDescriptorFromJvmBytecode getInterfaceIfSamType(@NotNull JetType originalType) {
if (!SingleAbstractMethodUtils.isSamType(originalType)) {