/*
 * Copyright 2009 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.js;

import com.google.gwt.dev.jjs.impl.JavaToJavaScriptMap;
import com.google.gwt.dev.js.ast.JsBlock;
import com.google.gwt.dev.js.ast.JsContext;
import com.google.gwt.dev.js.ast.JsExprStmt;
import com.google.gwt.dev.js.ast.JsFunction;
import com.google.gwt.dev.js.ast.JsModVisitor;
import com.google.gwt.dev.js.ast.JsProgram;
import com.google.gwt.dev.js.ast.JsProgramFragment;
import com.google.gwt.dev.js.ast.JsStatement;
import com.google.gwt.thirdparty.guava.common.collect.Queues;

import java.util.Deque;
import java.util.HashSet;
import java.util.ListIterator;
import java.util.Set;

/**
 * Force all functions to be evaluated at the top of the lexical scope in which
 * they reside. This makes {@link StaticEvalVisitor} simpler in that we no
 * longer have to worry about function declarations within expressions. After
 * this runs, only statements can contain declarations. Moved functions will end
 * up just before the statement in which they presently reside.
 */
public class EvalFunctionsAtTopScope extends JsModVisitor {

  public static void exec(JsProgram jsProgram, JavaToJavaScriptMap map) {
    EvalFunctionsAtTopScope fev = new EvalFunctionsAtTopScope(map);
    fev.accept(jsProgram);
  }

  private JsStatement currentStatement;

  private final Set<JsFunction> dontMove = new HashSet<JsFunction>();

  private final Deque<ListIterator<JsStatement>> itrStack = Queues.newArrayDeque();

  private JavaToJavaScriptMap java2jsMap;

  private final Deque<JsBlock> scopeStack = Queues.newArrayDeque();

  public EvalFunctionsAtTopScope(JavaToJavaScriptMap java2jsMap) {
    this.java2jsMap = java2jsMap;
  }

  @Override
  public void endVisit(JsExprStmt x, JsContext ctx) {
    currentStatement = null;
  }

  @Override
  public void endVisit(JsFunction x, JsContext ctx) {
    scopeStack.pop();
  }

  @Override
  public void endVisit(JsProgram x, JsContext ctx) {
    scopeStack.pop();
  }

  @Override
  public void endVisit(JsProgramFragment x, JsContext ctx) {
    scopeStack.pop();
  }

  @Override
  public boolean visit(JsBlock x, JsContext ctx) {
    if (x == scopeStack.peek()) {
      ListIterator<JsStatement> itr = x.getStatements().listIterator();
      itrStack.push(itr);
      while (itr.hasNext()) {
        JsStatement stmt = itr.next();
        JsFunction func = JsUtils.isFunctionDeclaration(stmt);
        // Already at the top level.
        if (func != null) {
          dontMove.add(func);
        }
        accept(stmt);
        if (func != null) {
          dontMove.remove(func);
        }
      }
      itrStack.pop();
      // Already visited.
      return false;
    } else {
      // Just do normal visitation.
      return true;
    }
  }

  @Override
  public boolean visit(JsExprStmt x, JsContext ctx) {
    currentStatement = x;
    return true;
  }

  @Override
  public boolean visit(JsFunction x, JsContext ctx) {
    /*
     * We do this during visit() to preserve first-to-last evaluation order. We
     * check if this function is a vtable declaration and don't move functions
     * used in other expressions or are in vtable assignments.
     */
    if (x.getName() != null && x.getName().getNamespace() == null && !dontMove.contains(x)
        && !isMethodDefinition(currentStatement)) {
      /*
       * Reinsert this function into the statement immediately before the
       * current statement. The current statement will have already been
       * returned from the current iterator's next(), so we have to backshuffle
       * one step to get in front of it.
       */
      ListIterator<JsStatement> itr = itrStack.peek();
      itr.previous();
      itr.add(x.makeStmt());
      itr.next();
      ctx.replaceMe(x.getName().makeRef(x.getSourceInfo().makeChild()));
    }

    // Dive into the function itself.
    scopeStack.push(x.getBody());
    return true;
  }

  @Override
  public boolean visit(JsProgram x, JsContext ctx) {
    scopeStack.push(x.getGlobalBlock());
    return true;
  }

  @Override
  public boolean visit(JsProgramFragment x, JsContext ctx) {
    scopeStack.push(x.getGlobalBlock());
    return true;
  }

  private boolean isMethodDefinition(JsStatement currentStatement) {
    return java2jsMap.methodForStatement(currentStatement) != null;
  }
}
