/*
 * Copyright 2008 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.dev.jjs.impl;

import com.google.gwt.dev.jjs.ast.JBinaryOperation;
import com.google.gwt.dev.jjs.ast.JBinaryOperator;
import com.google.gwt.dev.jjs.ast.JCastOperation;
import com.google.gwt.dev.jjs.ast.JExpression;
import com.google.gwt.dev.jjs.ast.JPostfixOperation;
import com.google.gwt.dev.jjs.ast.JPrefixOperation;
import com.google.gwt.dev.jjs.ast.JPrimitiveType;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JType;

/**
 * Normalize compound assignments as needed after optimization. Integer division
 * and operations on longs need to be broken up.
 */
public class PostOptimizationCompoundAssignmentNormalizer extends CompoundAssignmentNormalizer {
  public static void exec(JProgram program) {
    new PostOptimizationCompoundAssignmentNormalizer().accept(program);
  }

  protected PostOptimizationCompoundAssignmentNormalizer() {
  }

  @Override
  protected JExpression modifyResultOperation(JBinaryOperation op) {
    JType lhsType = op.getLhs().getType();
    JType rhsType = op.getRhs().getType();
    if (lhsType != rhsType) {
      // first widen binary op to encompass both sides, then add narrow cast
      return new JCastOperation(op.getSourceInfo(), lhsType, new JBinaryOperation(op
          .getSourceInfo(), widenType(lhsType, rhsType), op.getOp(), op.getLhs(), op.getRhs()));
    }
    return op;
  }

  @Override
  protected boolean shouldBreakUp(JBinaryOperation x) {
    if (x.getType() == JPrimitiveType.LONG) {
      return true;
    }
    if (x.getOp() == JBinaryOperator.ASG_DIV && x.getType() != JPrimitiveType.FLOAT
        && x.getType() != JPrimitiveType.DOUBLE) {
      return true;
    }

    JType lhsType = x.getLhs().getType();
    JType rhsType = x.getRhs().getType();

    // don't bother with float op= double since we don't float == double in JS
    if (lhsType == JPrimitiveType.FLOAT && rhsType == JPrimitiveType.DOUBLE) {
      return false;
    }
    // break up so that result may be coerced to LHS type
    if (lhsType.isPrimitiveType() && rhsType.isPrimitiveType()
        && widenType(lhsType, rhsType) != lhsType) {
      return true;
    }
    return false;
  }

  @Override
  protected boolean shouldBreakUp(JPostfixOperation x) {
    if (x.getType() == JPrimitiveType.LONG) {
      return true;
    }
    return false;
  }

  @Override
  protected boolean shouldBreakUp(JPrefixOperation x) {
    if (x.getType() == JPrimitiveType.LONG) {
      return true;
    }
    return false;
  }

  /**
   * Implements 5.6 Numeric Promotions.
   *
   * <pre>
   * http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#26917
   * </pre>
   */
  private JType widenType(JType lhsType, JType rhsType) {
    if (lhsType == JPrimitiveType.DOUBLE || rhsType == JPrimitiveType.DOUBLE) {
      return JPrimitiveType.DOUBLE;
    } else if (lhsType == JPrimitiveType.FLOAT || rhsType == JPrimitiveType.FLOAT) {
      return JPrimitiveType.FLOAT;
    } else if (lhsType == JPrimitiveType.LONG || rhsType == JPrimitiveType.LONG) {
      return JPrimitiveType.LONG;
    } else {
      return JPrimitiveType.INT;
    }
  }
}
