/*
 * 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 instanceof JPrimitiveType && rhsType instanceof JPrimitiveType
        && 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;
    }
  }
}
