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