Custom equals operator (includes little patch to frontend)

#KT-2354 fixed
This commit is contained in:
Pavel V. Talanov
2012-07-05 15:32:57 +04:00
parent 88a38d9b5b
commit 6354d1bae0
5 changed files with 24 additions and 19 deletions
@@ -21,7 +21,6 @@ import com.google.common.collect.Multimap;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.JetNodeTypes;
@@ -958,6 +957,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
if (resolutionResults.isSuccess()) {
FunctionDescriptor equals = resolutionResults.getResultingCall().getResultingDescriptor();
context.trace.record(REFERENCE_TARGET, operationSign, equals);
context.trace.record(RESOLVED_CALL, operationSign, resolutionResults.getResultingCall());
if (ensureBooleanResult(operationSign, name, equals.getReturnType(), context)) {
ensureNonemptyIntersectionOfOperandTypes(expression, context);
}
@@ -22,7 +22,7 @@ public final class EqualsTest extends AbstractExpressionTest {
super("equals/");
}
public void TODO_testCustomEqualsMethod() throws Exception {
public void testCustomEqualsMethod() throws Exception {
fooBoxTest();
}
@@ -39,8 +39,8 @@ import static org.jetbrains.k2js.translate.operation.AssignmentTranslator.isAssi
import static org.jetbrains.k2js.translate.operation.CompareToTranslator.isCompareToCall;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getResolvedCall;
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.isEquals;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.not;
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.isEquals;
import static org.jetbrains.k2js.translate.utils.PsiUtils.*;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.*;
@@ -52,13 +52,13 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
@NotNull
public static JsExpression translate(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) {
@NotNull TranslationContext context) {
return (new BinaryOperationTranslator(expression, context).translate());
}
@NotNull
/*package*/ static JsExpression translateAsOverloadedCall(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) {
@NotNull TranslationContext context) {
return (new BinaryOperationTranslator(expression, context)).translateAsOverloadedBinaryOperation();
}
@@ -69,11 +69,11 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
private final FunctionDescriptor operationDescriptor;
private BinaryOperationTranslator(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) {
@NotNull TranslationContext context) {
super(context);
this.expression = expression;
this.operationDescriptor =
getFunctionDescriptorForOperationExpression(bindingContext(), expression);
getFunctionDescriptorForOperationExpression(bindingContext(), expression);
}
@NotNull
@@ -91,9 +91,9 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
return CompareToTranslator.translate(expression, context());
}
assert operationDescriptor != null :
"Overloadable operations must have not null descriptor";
if (isEquals(operationDescriptor)) {
return translateAsEqualsCall();
"Overloadable operations must have not null descriptor";
if (isEquals(operationDescriptor) && context().intrinsics().isIntrinsic(operationDescriptor)) {
return translateAsEqualsIntrinsic();
}
return translateAsOverloadedBinaryOperation();
}
@@ -116,7 +116,7 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
}
@NotNull
private JsExpression translateAsEqualsCall() {
private JsExpression translateAsEqualsIntrinsic() {
assert operationDescriptor != null : "Equals operation must resolve to descriptor.";
EqualsIntrinsic intrinsic = context().intrinsics().getEqualsIntrinsic(operationDescriptor);
intrinsic.setNegated(expression.getOperationToken().equals(JetTokens.EXCLEQ));
@@ -137,10 +137,8 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
@NotNull
private JsExpression translateAsOverloadedBinaryOperation() {
CallBuilder callBuilder = setReceiverAndArguments();
ResolvedCall<?> resolvedCall1 =
getResolvedCall(bindingContext(), expression.getOperationReference());
JsExpression result = callBuilder.resolvedCall(resolvedCall1)
.type(CallType.NORMAL).translate();
ResolvedCall<?> resolvedCall = getResolvedCall(bindingContext(), expression.getOperationReference());
JsExpression result = callBuilder.resolvedCall(resolvedCall).type(CallType.NORMAL).translate();
return mayBeWrapWithNegation(result);
}
@@ -161,7 +159,7 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
@NotNull
private JsExpression mayBeWrapWithNegation(@NotNull JsExpression result) {
if (isNotInOperation(expression)) {
if (isNegatedOperation(expression)) {
return not(result);
}
else {
@@ -93,6 +93,10 @@ public final class PsiUtils {
return (binaryExpression.getOperationToken() == JetTokens.NOT_IN);
}
public static boolean isNegatedOperation(@NotNull JetBinaryExpression binaryExpression) {
return (binaryExpression.getOperationToken() == JetTokens.EXCLEQ) || isNotInOperation(binaryExpression);
}
private static boolean isInOperation(@NotNull JetBinaryExpression binaryExpression) {
return (binaryExpression.getOperationToken() == JetTokens.IN_KEYWORD);
}
@@ -1,9 +1,12 @@
package foo
class Foo(val name: String) {
public fun equals(that: Foo): Boolean {
return this.name == that.name
}
public fun equals(that: Any?): Boolean {
if (that !is Foo) {
return false
}
return this.name == that.name
}
}
fun box() : Boolean {