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.JsExpression;
020    import org.jetbrains.annotations.NotNull;
021    import org.jetbrains.jet.lang.psi.JetBinaryExpression;
022    import org.jetbrains.jet.lang.psi.JetExpression;
023    import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
024    import org.jetbrains.jet.lexer.JetToken;
025    import org.jetbrains.k2js.translate.context.TranslationContext;
026    import org.jetbrains.k2js.translate.general.AbstractTranslator;
027    import org.jetbrains.k2js.translate.reference.AccessTranslationUtils;
028    import org.jetbrains.k2js.translate.reference.AccessTranslator;
029    
030    import static org.jetbrains.k2js.translate.utils.BindingUtils.isVariableReassignment;
031    import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken;
032    import static org.jetbrains.k2js.translate.utils.PsiUtils.isAssignment;
033    import static org.jetbrains.k2js.translate.utils.TranslationUtils.hasCorrespondingFunctionIntrinsic;
034    import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateRightExpression;
035    
036    public abstract class AssignmentTranslator extends AbstractTranslator {
037    
038        public static boolean isAssignmentOperator(JetBinaryExpression expression) {
039            JetToken operationToken = getOperationToken(expression);
040            return (OperatorConventions.ASSIGNMENT_OPERATIONS.keySet().contains(operationToken)
041                    || isAssignment(operationToken));
042        }
043    
044        @NotNull
045        public static JsExpression translate(@NotNull JetBinaryExpression expression,
046                                             @NotNull TranslationContext context) {
047            if (hasCorrespondingFunctionIntrinsic(context, expression)) {
048                return IntrinsicAssignmentTranslator.doTranslate(expression, context);
049            }
050            return OverloadedAssignmentTranslator.doTranslate(expression, context);
051        }
052    
053        @NotNull
054        protected final JetBinaryExpression expression;
055        protected final AccessTranslator accessTranslator;
056        protected final boolean isVariableReassignment;
057        @NotNull
058        protected final JsExpression right;
059    
060        protected AssignmentTranslator(@NotNull JetBinaryExpression expression,
061                                       @NotNull TranslationContext context) {
062            super(context);
063            this.expression = expression;
064            this.isVariableReassignment = isVariableReassignment(context.bindingContext(), expression);
065            JetExpression left = expression.getLeft();
066            assert left != null : "No left-hand side: " + expression.getText();
067            this.accessTranslator = AccessTranslationUtils.getAccessTranslator(left, context());
068            this.right = translateRightExpression(context(), expression);
069        }
070    }