/*
 * Copyright 2007 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.CanBeSetFinal;
import com.google.gwt.dev.jjs.ast.Context;
import com.google.gwt.dev.jjs.ast.JBinaryOperation;
import com.google.gwt.dev.jjs.ast.JClassType;
import com.google.gwt.dev.jjs.ast.JConstructor;
import com.google.gwt.dev.jjs.ast.JDeclarationStatement;
import com.google.gwt.dev.jjs.ast.JExpression;
import com.google.gwt.dev.jjs.ast.JField;
import com.google.gwt.dev.jjs.ast.JLocal;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JMethodBody;
import com.google.gwt.dev.jjs.ast.JModVisitor;
import com.google.gwt.dev.jjs.ast.JParameter;
import com.google.gwt.dev.jjs.ast.JPostfixOperation;
import com.google.gwt.dev.jjs.ast.JPrefixOperation;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JVariable;
import com.google.gwt.dev.jjs.ast.JVariableRef;
import com.google.gwt.dev.jjs.ast.JVisitor;
import com.google.gwt.dev.jjs.ast.js.JsniFieldRef;
import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;

import java.util.HashSet;
import java.util.Set;

/**
 * Finds all items are effectively final. That is, methods that are never
 * overridden, classes that are never subclassed, and variables that are never
 * reassigned. Mark all such methods and classes as final, since it helps us
 * optimize.
 */
public class Finalizer {
  private static final String NAME = Finalizer.class.getSimpleName();

  /**
   * Any items that weren't marked during MarkVisitor can be set final.
   *
   *  Open question: What does it mean if an interface/abstract method becomes
   * final? Is this possible after Pruning? I guess it means that someone tried
   * to make a call to method that wasn't actually implemented anywhere in the
   * program. But if it wasn't implemented, then the enclosing class should have
   * come up as not instantiated and been culled. So I think it's not possible.
   */
  private class FinalizeVisitor extends JModVisitor {

    @Override
    public void endVisit(JClassType x, Context ctx) {
      if (!x.isFinal() && !isSubclassed.contains(x)) {
        setFinal(x);
      }
    }

    @Override
    public void endVisit(JConstructor x, Context ctx) {
      // Not applicable.
    }

    @Override
    public void endVisit(JField x, Context ctx) {
      if (!x.isVolatile()) {
        maybeFinalize(x);
      }
    }

    @Override
    public void endVisit(JLocal x, Context ctx) {
      maybeFinalize(x);
    }

    @Override
    public void endVisit(JMethod x, Context ctx) {
      if (!x.isFinal() && !isOverriden.contains(x)) {
        setFinal(x);
      }
    }

    @Override
    public void endVisit(JParameter x, Context ctx) {
      maybeFinalize(x);
    }

    @Override
    public boolean visit(JClassType x, Context ctx) {
      // Don't visit external types, because we can't change their final
      // specifiers.
      return !x.isExternal();
    }

    @Override
    public boolean visit(JMethodBody x, Context ctx) {
      for (JLocal local : x.getLocals()) {
        maybeFinalize(local);
      }
      return false;
    }

    private void maybeFinalize(JVariable x) {
      if (!x.isFinal() && !isReassigned.contains(x)) {
        setFinal(x);
      }
    }

    private void setFinal(CanBeSetFinal x) {
      x.setFinal();
      assert x.isFinal();
      madeChanges();
    }
  }
  /**
   * Find all items that ARE overriden/subclassed/reassigned.
   */
  private class MarkVisitor extends JVisitor {

    @Override
    public void endVisit(JBinaryOperation x, Context ctx) {
      if (x.getOp().isAssignment()) {
        recordAssignment(x.getLhs());
      }
    }

    @Override
    public void endVisit(JClassType x, Context ctx) {
      if (x.getSuperClass() != null) {
        isSubclassed.add(x.getSuperClass());
      }
    }

    @Override
    public void endVisit(JConstructor x, Context ctx) {
      // Never overridden.
    }

    @Override
    public void endVisit(JDeclarationStatement x, Context ctx) {
      // This is not a reassignment, the target may still be final.
    }

    @Override
    public void endVisit(JMethod x, Context ctx) {
      for (int i = 0; i < x.getOverrides().size(); ++i) {
        JMethod it = x.getOverrides().get(i);
        isOverriden.add(it);
      }
    }

    @Override
    public void endVisit(JPostfixOperation x, Context ctx) {
      if (x.getOp().isModifying()) {
        recordAssignment(x.getArg());
      }
    }

    @Override
    public void endVisit(JPrefixOperation x, Context ctx) {
      if (x.getOp().isModifying()) {
        recordAssignment(x.getArg());
      }
    }

    @Override
    public void endVisit(JsniFieldRef x, Context ctx) {
      if (x.isLvalue()) {
        recordAssignment(x);
      }
    }

    @Override
    public boolean visit(JClassType x, Context ctx) {
      // Don't visit external types, because we can't change their final
      // specifiers.
      return !x.isExternal();
    }

    private void recordAssignment(JExpression lhs) {
      if (lhs instanceof JVariableRef) {
        JVariableRef variableRef = (JVariableRef) lhs;
        isReassigned.add(variableRef.getTarget());
      }
    }
  }

  public static OptimizerStats exec(JProgram program) {
    Event optimizeEvent = SpeedTracerLogger.start(
        CompilerEventType.OPTIMIZE, "optimizer", NAME);
    OptimizerStats stats = new Finalizer().execImpl(program);
    optimizeEvent.end("didChange", "" + stats.didChange());
    return stats;
  }

  private final Set<JMethod> isOverriden = new HashSet<JMethod>();

  private final Set<JVariable> isReassigned = new HashSet<JVariable>();

  private final Set<JClassType> isSubclassed = new HashSet<JClassType>();

  private Finalizer() {
  }

  private OptimizerStats execImpl(JProgram program) {
    MarkVisitor marker = new MarkVisitor();
    marker.accept(program);
    
    FinalizeVisitor finalizer = new FinalizeVisitor();
    finalizer.accept(program);

    return new OptimizerStats(NAME).recordModified(
        finalizer.getNumMods());
  }
}
