/*
 * Copyright 2010 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.Context;
import com.google.gwt.dev.jjs.ast.JArrayType;
import com.google.gwt.dev.jjs.ast.JBinaryOperation;
import com.google.gwt.dev.jjs.ast.JCastOperation;
import com.google.gwt.dev.jjs.ast.JConditional;
import com.google.gwt.dev.jjs.ast.JConstructor;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JNewArray;
import com.google.gwt.dev.jjs.ast.JPermutationDependentValue;
import com.google.gwt.dev.jjs.ast.JType;
import com.google.gwt.dev.jjs.ast.JVariable;

/**
 * A visitor that changes all JType references in the AST. Subclasses override
 * {@link #remap(JType)} to replace all occurrences of one or more types with
 * different types.
 */
public abstract class TypeRemapper extends JChangeTrackingVisitor {
  public TypeRemapper(OptimizerContext optimizerCtx) {
    super(optimizerCtx);
  }

  @Override
  public void endVisit(JBinaryOperation x, Context ctx) {
    x.setType(remap(x.getType()));
  }

  @Override
  public void endVisit(JCastOperation x, Context ctx) {
    /*
     * JCastOperation doesn't have a settable castType method, so need to create
     * a new one and do a replacement. Use remap() instead of modRemap() since
     * the ctx.replaceMe() will record a change.
     */
    JType remapCastType = remap(x.getCastType());
    if (remapCastType != x.getCastType()) {
      JCastOperation newX = new JCastOperation(x.getSourceInfo(), remapCastType, x.getExpr());
      ctx.replaceMe(newX);
    }
  }

  @Override
  public void endVisit(JConditional x, Context ctx) {
    x.setType(modRemap(x.getType()));
  }

  @Override
  public void exit(JConstructor x, Context ctx) {
    x.setType(modRemap(x.getType()));
  }

  @Override
  public void exit(JMethod x, Context ctx) {
    x.setType(modRemap(x.getType()));
  }

  @Override
  public void endVisit(JNewArray x, Context ctx) {
    x.setType((JArrayType) modRemap(x.getArrayType()));
  }

  @Override
  public void endVisit(JPermutationDependentValue x, Context ctx) {
    throw new IllegalStateException("AST should not contain permutation dependent values at " +
        "this point but contains " + x);
  }

  @Override
  public void exit(JVariable x, Context ctx) {
    x.setType(modRemap(x.getType()));
  }

  /**
   * Override to return a possibly-different type.
   *
   * @param type the original type
   * @return a replacement type, which may be the original type
   */
  protected abstract JType remap(JType type);

  private JType modRemap(JType type) {
    JType result = remap(type);
    if (result != type) {
      madeChanges();
    }
    return result;
  }
}
