001    /*
002     * Copyright 2010-2013 JetBrains s.r.o.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.jetbrains.k2js.translate.operation;
018    
019    import com.google.dart.compiler.backend.js.ast.JsBinaryOperation;
020    import com.google.dart.compiler.backend.js.ast.JsBinaryOperator;
021    import com.google.dart.compiler.backend.js.ast.JsExpression;
022    import org.jetbrains.annotations.NotNull;
023    import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
024    import org.jetbrains.jet.lang.psi.JetBinaryExpression;
025    import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
026    import org.jetbrains.k2js.translate.context.TranslationContext;
027    import org.jetbrains.k2js.translate.general.AbstractTranslator;
028    
029    import static org.jetbrains.k2js.translate.utils.BindingUtils.getCallableDescriptorForOperationExpression;
030    import static org.jetbrains.k2js.translate.utils.ErrorReportingUtils.message;
031    import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.isCompareTo;
032    import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken;
033    
034    public final class CompareToTranslator extends AbstractTranslator {
035    
036        public static boolean isCompareToCall(
037                @NotNull JetBinaryExpression expression,
038                @NotNull TranslationContext context
039        ) {
040            if (!OperatorConventions.COMPARISON_OPERATIONS.contains(getOperationToken(expression))) return false;
041    
042            CallableDescriptor operationDescriptor =
043                    getCallableDescriptorForOperationExpression(context.bindingContext(), expression);
044    
045            if (operationDescriptor == null) return false;
046    
047            return isCompareTo(operationDescriptor);
048        }
049    
050        @NotNull
051        public static JsExpression translate(@NotNull JetBinaryExpression expression,
052                @NotNull TranslationContext context) {
053            return (new CompareToTranslator(expression, context)).translate();
054        }
055    
056        @NotNull
057        private final JetBinaryExpression expression;
058    
059        private CompareToTranslator(
060                @NotNull JetBinaryExpression expression,
061                @NotNull TranslationContext context
062        ) {
063            super(context);
064            this.expression = expression;
065            CallableDescriptor descriptor = getCallableDescriptorForOperationExpression(context.bindingContext(), expression);
066            assert descriptor != null : "CompareTo should always have a descriptor";
067            assert (OperatorConventions.COMPARISON_OPERATIONS.contains(getOperationToken(expression))) :
068                    message(expression, "CompareToTranslator supported only expressions with operation token from COMPARISON_OPERATIONS, " +
069                                        "expression: " + expression.getText());
070        }
071    
072        @NotNull
073        private JsExpression translate() {
074            JsBinaryOperator correspondingOperator = OperatorTable.getBinaryOperator(getOperationToken(expression));
075            JsExpression methodCall = BinaryOperationTranslator.translateAsOverloadedCall(expression, context());
076            return new JsBinaryOperation(correspondingOperator, methodCall, context().program().getNumberLiteral(0));
077        }
078    }