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 017package org.jetbrains.k2js.translate.operation; 018 019import com.google.dart.compiler.backend.js.ast.JsBinaryOperation; 020import com.google.dart.compiler.backend.js.ast.JsBinaryOperator; 021import com.google.dart.compiler.backend.js.ast.JsExpression; 022import org.jetbrains.annotations.NotNull; 023import org.jetbrains.jet.lang.psi.JetBinaryExpression; 024import org.jetbrains.jet.lang.types.expressions.OperatorConventions; 025import org.jetbrains.jet.lexer.JetToken; 026import org.jetbrains.k2js.translate.context.TranslationContext; 027import org.jetbrains.k2js.translate.reference.ReferenceAccessTranslator; 028 029import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken; 030import static org.jetbrains.k2js.translate.utils.PsiUtils.isAssignment; 031 032public final class IntrinsicAssignmentTranslator extends AssignmentTranslator { 033 034 035 @NotNull 036 public static JsExpression doTranslate(@NotNull JetBinaryExpression expression, 037 @NotNull TranslationContext context) { 038 return (new IntrinsicAssignmentTranslator(expression, context)).translate(); 039 } 040 041 private IntrinsicAssignmentTranslator(@NotNull JetBinaryExpression expression, 042 @NotNull TranslationContext context) { 043 super(expression, context); 044 } 045 046 @NotNull 047 private JsExpression translate() { 048 if (isAssignment(getOperationToken(expression))) { 049 return translateAsPlainAssignment(); 050 } 051 return translateAsAssignmentOperation(); 052 } 053 054 @NotNull 055 private JsExpression translateAsAssignmentOperation() { 056 if (accessTranslator instanceof ReferenceAccessTranslator) { 057 return translateAsPlainAssignmentOperation(); 058 } 059 return translateAsAssignToCounterpart(); 060 } 061 062 @NotNull 063 private JsExpression translateAsAssignToCounterpart() { 064 JsBinaryOperator operator = getCounterpartOperator(); 065 JsBinaryOperation counterpartOperation = 066 new JsBinaryOperation(operator, accessTranslator.translateAsGet(), right); 067 return accessTranslator.translateAsSet(counterpartOperation); 068 } 069 070 @NotNull 071 private JsBinaryOperator getCounterpartOperator() { 072 JetToken assignmentOperationToken = getOperationToken(expression); 073 assert OperatorConventions.ASSIGNMENT_OPERATIONS.containsKey(assignmentOperationToken); 074 JetToken counterpartToken = OperatorConventions.ASSIGNMENT_OPERATION_COUNTERPARTS.get(assignmentOperationToken); 075 assert OperatorTable.hasCorrespondingBinaryOperator(counterpartToken) : 076 "Unsupported token encountered: " + counterpartToken.toString(); 077 return OperatorTable.getBinaryOperator(counterpartToken); 078 } 079 080 @NotNull 081 private JsExpression translateAsPlainAssignmentOperation() { 082 JsBinaryOperator operator = getAssignmentOperator(); 083 return new JsBinaryOperation(operator, accessTranslator.translateAsGet(), right); 084 } 085 086 @NotNull 087 private JsBinaryOperator getAssignmentOperator() { 088 JetToken token = getOperationToken(expression); 089 assert OperatorConventions.ASSIGNMENT_OPERATIONS.containsKey(token); 090 assert OperatorTable.hasCorrespondingBinaryOperator(token) : 091 "Unsupported token encountered: " + token.toString(); 092 return OperatorTable.getBinaryOperator(token); 093 } 094 095 @NotNull 096 private JsExpression translateAsPlainAssignment() { 097 return accessTranslator.translateAsSet(right); 098 } 099}