JS backend: fixed infix calls.

#KT-3998   fixed
#EA-56241 fixed
This commit is contained in:
Zalim Bashorov
2014-05-08 17:49:37 +04:00
parent 898275e658
commit a578fc6762
7 changed files with 39 additions and 34 deletions
@@ -20,14 +20,14 @@ import com.google.dart.compiler.backend.js.ast.JsBinaryOperation;
import com.google.dart.compiler.backend.js.ast.JsBinaryOperator; import com.google.dart.compiler.backend.js.ast.JsBinaryOperator;
import com.google.dart.compiler.backend.js.ast.JsExpression; import com.google.dart.compiler.backend.js.ast.JsExpression;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.psi.JetBinaryExpression; import org.jetbrains.jet.lang.psi.JetBinaryExpression;
import org.jetbrains.jet.lang.types.expressions.OperatorConventions; import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.operation.OperatorTable; import org.jetbrains.k2js.translate.operation.OperatorTable;
import org.jetbrains.k2js.translate.utils.JsDescriptorUtils; import org.jetbrains.k2js.translate.utils.JsDescriptorUtils;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression; import static org.jetbrains.k2js.translate.utils.BindingUtils.getCallableDescriptorForOperationExpression;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken; import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken;
public final class CompareToInstrinsic implements BinaryOperationIntrinsic { public final class CompareToInstrinsic implements BinaryOperationIntrinsic {
@@ -36,9 +36,10 @@ public final class CompareToInstrinsic implements BinaryOperationIntrinsic {
if (!OperatorConventions.COMPARISON_OPERATIONS.contains(getOperationToken(expression))) { if (!OperatorConventions.COMPARISON_OPERATIONS.contains(getOperationToken(expression))) {
return false; return false;
} }
FunctionDescriptor functionDescriptor = getFunctionDescriptorForOperationExpression(context.bindingContext(), expression);
assert functionDescriptor != null; CallableDescriptor descriptor = getCallableDescriptorForOperationExpression(context.bindingContext(), expression);
return JsDescriptorUtils.isBuiltin(functionDescriptor); assert descriptor != null;
return JsDescriptorUtils.isBuiltin(descriptor);
} }
@NotNull @NotNull
@@ -21,6 +21,7 @@ import com.google.dart.compiler.backend.js.ast.JsBinaryOperator;
import com.google.dart.compiler.backend.js.ast.JsExpression; import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsLiteral; import com.google.dart.compiler.backend.js.ast.JsLiteral;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.psi.JetBinaryExpression; import org.jetbrains.jet.lang.psi.JetBinaryExpression;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
@@ -36,7 +37,7 @@ import org.jetbrains.k2js.translate.utils.TranslationUtils;
import java.util.Arrays; import java.util.Arrays;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression; import static org.jetbrains.k2js.translate.utils.BindingUtils.getCallableDescriptorForOperationExpression;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken; import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken;
public final class EqualsIntrinsic implements BinaryOperationIntrinsic { public final class EqualsIntrinsic implements BinaryOperationIntrinsic {
@@ -46,9 +47,10 @@ public final class EqualsIntrinsic implements BinaryOperationIntrinsic {
if (!OperatorConventions.EQUALS_OPERATIONS.contains(getOperationToken(expression))) { if (!OperatorConventions.EQUALS_OPERATIONS.contains(getOperationToken(expression))) {
return false; return false;
} }
FunctionDescriptor functionDescriptor = getFunctionDescriptorForOperationExpression(context.bindingContext(), expression); CallableDescriptor functionDescriptor = getCallableDescriptorForOperationExpression(context.bindingContext(), expression);
assert functionDescriptor != null; if (!(functionDescriptor instanceof FunctionDescriptor)) return false;
return JsDescriptorUtils.isBuiltin(functionDescriptor) || TopLevelFIF.EQUALS_IN_ANY.apply(functionDescriptor);
return JsDescriptorUtils.isBuiltin(functionDescriptor) || TopLevelFIF.EQUALS_IN_ANY.apply((FunctionDescriptor) functionDescriptor);
} }
@Override @Override
@@ -19,6 +19,7 @@ package org.jetbrains.k2js.translate.operation;
import com.google.dart.compiler.backend.js.ast.*; import com.google.dart.compiler.backend.js.ast.*;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.psi.JetBinaryExpression; import org.jetbrains.jet.lang.psi.JetBinaryExpression;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
@@ -38,7 +39,7 @@ import org.jetbrains.k2js.translate.utils.mutator.LastExpressionMutator;
import static org.jetbrains.k2js.translate.operation.AssignmentTranslator.isAssignmentOperator; import static org.jetbrains.k2js.translate.operation.AssignmentTranslator.isAssignmentOperator;
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.getCallableDescriptorForOperationExpression;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionResolvedCall; import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionResolvedCall;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.convertToStatement; import static org.jetbrains.k2js.translate.utils.JsAstUtils.convertToStatement;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.not; import static org.jetbrains.k2js.translate.utils.JsAstUtils.not;
@@ -67,14 +68,13 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
private final JetBinaryExpression expression; private final JetBinaryExpression expression;
@Nullable @Nullable
private final FunctionDescriptor operationDescriptor; private final CallableDescriptor 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 = getCallableDescriptorForOperationExpression(bindingContext(), expression);
getFunctionDescriptorForOperationExpression(bindingContext(), expression);
} }
@NotNull @NotNull
@@ -20,13 +20,13 @@ import com.google.dart.compiler.backend.js.ast.JsBinaryOperation;
import com.google.dart.compiler.backend.js.ast.JsBinaryOperator; import com.google.dart.compiler.backend.js.ast.JsBinaryOperator;
import com.google.dart.compiler.backend.js.ast.JsExpression; import com.google.dart.compiler.backend.js.ast.JsExpression;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.psi.JetBinaryExpression; import org.jetbrains.jet.lang.psi.JetBinaryExpression;
import org.jetbrains.jet.lang.types.expressions.OperatorConventions; import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator; import org.jetbrains.k2js.translate.general.AbstractTranslator;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression; import static org.jetbrains.k2js.translate.utils.BindingUtils.getCallableDescriptorForOperationExpression;
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.isCompareTo; import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.isCompareTo;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken; import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken;
@@ -34,12 +34,12 @@ public final class CompareToTranslator extends AbstractTranslator {
public static boolean isCompareToCall(@NotNull JetBinaryExpression expression, public static boolean isCompareToCall(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) { @NotNull TranslationContext context) {
FunctionDescriptor operationDescriptor = CallableDescriptor operationDescriptor =
getFunctionDescriptorForOperationExpression(context.bindingContext(), expression); getCallableDescriptorForOperationExpression(context.bindingContext(), expression);
if (operationDescriptor == null) return false; if (operationDescriptor == null) return false;
return (isCompareTo(operationDescriptor)); return isCompareTo(operationDescriptor);
} }
@NotNull @NotNull
@@ -55,9 +55,8 @@ public final class CompareToTranslator extends AbstractTranslator {
@NotNull TranslationContext context) { @NotNull TranslationContext context) {
super(context); super(context);
this.expression = expression; this.expression = expression;
FunctionDescriptor functionDescriptor = CallableDescriptor descriptor = getCallableDescriptorForOperationExpression(context.bindingContext(), expression);
getFunctionDescriptorForOperationExpression(context.bindingContext(), expression); assert descriptor != null : "CompareTo should always have a descriptor";
assert functionDescriptor != null : "CompareTo should always have a descriptor";
assert (OperatorConventions.COMPARISON_OPERATIONS.contains(getOperationToken(expression))); assert (OperatorConventions.COMPARISON_OPERATIONS.contains(getOperationToken(expression)));
} }
@@ -174,16 +174,19 @@ public final class BindingUtils {
} }
@Nullable @Nullable
public static FunctionDescriptor getFunctionDescriptorForOperationExpression(@NotNull BindingContext context, public static CallableDescriptor getCallableDescriptorForOperationExpression(
@NotNull JetOperationExpression expression) { @NotNull BindingContext context,
DeclarationDescriptor descriptorForReferenceExpression = getNullableDescriptorForReferenceExpression @NotNull JetOperationExpression expression
(context, expression.getOperationReference()); ) {
JetSimpleNameExpression operationReference = expression.getOperationReference();
DeclarationDescriptor descriptorForReferenceExpression =
getNullableDescriptorForReferenceExpression(context, operationReference);
if (descriptorForReferenceExpression == null) return null; if (descriptorForReferenceExpression == null) return null;
assert descriptorForReferenceExpression instanceof FunctionDescriptor assert descriptorForReferenceExpression instanceof CallableDescriptor :
: message(expression.getOperationReference(), "Operation should resolve to function descriptor"); message(operationReference, "Operation should resolve to callable descriptor");
return (FunctionDescriptor) descriptorForReferenceExpression; return (CallableDescriptor) descriptorForReferenceExpression;
} }
@NotNull @NotNull
@@ -56,8 +56,8 @@ public final class JsDescriptorUtils {
return (valueParametersCount(functionDescriptor) > 0); return (valueParametersCount(functionDescriptor) > 0);
} }
public static boolean isCompareTo(@NotNull FunctionDescriptor functionDescriptor) { public static boolean isCompareTo(@NotNull CallableDescriptor descriptor) {
return (functionDescriptor.getName().equals(OperatorConventions.COMPARE_TO)); return descriptor.getName().equals(OperatorConventions.COMPARE_TO);
} }
@Nullable @Nullable
@@ -38,7 +38,7 @@ import java.util.*;
import static com.google.dart.compiler.backend.js.ast.JsBinaryOperator.*; import static com.google.dart.compiler.backend.js.ast.JsBinaryOperator.*;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getFqName; import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getFqName;
import static org.jetbrains.k2js.translate.context.Namer.getKotlinBackingFieldName; import static org.jetbrains.k2js.translate.context.Namer.getKotlinBackingFieldName;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression; import static org.jetbrains.k2js.translate.utils.BindingUtils.getCallableDescriptorForOperationExpression;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.assignment; import static org.jetbrains.k2js.translate.utils.JsAstUtils.assignment;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.createDataDescriptor; import static org.jetbrains.k2js.translate.utils.JsAstUtils.createDataDescriptor;
@@ -352,10 +352,10 @@ public final class TranslationUtils {
public static boolean hasCorrespondingFunctionIntrinsic(@NotNull TranslationContext context, public static boolean hasCorrespondingFunctionIntrinsic(@NotNull TranslationContext context,
@NotNull JetOperationExpression expression) { @NotNull JetOperationExpression expression) {
FunctionDescriptor operationDescriptor = getFunctionDescriptorForOperationExpression(context.bindingContext(), expression); CallableDescriptor operationDescriptor = getCallableDescriptorForOperationExpression(context.bindingContext(), expression);
if (operationDescriptor == null) return true; if (operationDescriptor == null || !(operationDescriptor instanceof FunctionDescriptor)) return true;
if (context.intrinsics().getFunctionIntrinsics().getIntrinsic(operationDescriptor).exists()) return true; if (context.intrinsics().getFunctionIntrinsics().getIntrinsic((FunctionDescriptor) operationDescriptor).exists()) return true;
return false; return false;
} }