/*
 * Copyright 2011 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.Correlation.Literal;
import com.google.gwt.dev.jjs.CorrelationFactory;
import com.google.gwt.dev.jjs.CorrelationFactory.RealCorrelationFactory;
import com.google.gwt.dev.jjs.SourceInfo;
import com.google.gwt.dev.jjs.SourceInfoCorrelation;
import com.google.gwt.dev.jjs.SourceOrigin;
import com.google.gwt.dev.jjs.ast.Context;
import com.google.gwt.dev.jjs.ast.JClassLiteral;
import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.jjs.ast.JField;
import com.google.gwt.dev.jjs.ast.JFieldRef;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JNode;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JStringLiteral;
import com.google.gwt.dev.jjs.ast.JVisitor;
import com.google.gwt.dev.jjs.ast.js.JsniMethodBody;
import com.google.gwt.dev.js.ast.JsContext;
import com.google.gwt.dev.js.ast.JsNode;
import com.google.gwt.dev.js.ast.JsStringLiteral;
import com.google.gwt.dev.js.ast.JsSuperVisitor;
import com.google.gwt.dev.util.collect.Stack;

/**
 * Fix up SOYC parents and add correlations.
 */
public class SourceInfoCorrelator {

  private static class SourceInfoVisitor extends JVisitor {

    /**
     * Fix up SOYC for JSNI methods.
     */
    private class SourceInfoJsVisitor extends JsSuperVisitor {

      @Override
      public void endVisit(JsNode x, JsContext ctx) {
        SourceInfo popped = parents.pop();
        assert popped == x.getSourceInfo();
      }

      @Override
      public void endVisit(JsStringLiteral x, JsContext ctx) {
        x.getSourceInfo().addCorrelation(factory.by(Literal.STRING));
        super.endVisit(x, ctx);
      }

      @Override
      public boolean visit(JsNode x, JsContext ctx) {
        SourceInfo info = x.getSourceInfo();
        info = pushAndConvert(info);
        x.setSourceInfo(info);
        return true;
      }
    }

    private CorrelationFactory factory = RealCorrelationFactory.INSTANCE;
    private SourceInfoJsVisitor jsVisitor = new SourceInfoJsVisitor();
    private Stack<SourceInfoCorrelation> parents = new Stack<SourceInfoCorrelation>();

    @Override
    public void endVisit(JClassLiteral x, Context ctx) {
      x.getSourceInfo().addCorrelation(factory.by(Literal.CLASS));
      super.endVisit(x, ctx);
    }

    @Override
    public void endVisit(JDeclaredType x, Context ctx) {
      x.getSourceInfo().addCorrelation(factory.by(x));
      super.endVisit(x, ctx);
    }

    @Override
    public void endVisit(JField x, Context ctx) {
      x.getSourceInfo().addCorrelation(factory.by(x));
      super.endVisit(x, ctx);
    }

    @Override
    public void endVisit(JMethod x, Context ctx) {
      x.getSourceInfo().addCorrelation(factory.by(x));
      super.endVisit(x, ctx);
    }

    @Override
    public void endVisit(JNode x, Context ctx) {
      SourceInfo popped = parents.pop();
      assert popped == x.getSourceInfo();
    }

    @Override
    public void endVisit(JProgram x, Context ctx) {
      SourceInfo popped = parents.pop();
      assert popped == null;
    }

    @Override
    public void endVisit(JsniMethodBody x, Context ctx) {
      jsVisitor.accept(x.getFunc());
      super.endVisit(x, ctx);
    }

    @Override
    public void endVisit(JStringLiteral x, Context ctx) {
      x.getSourceInfo().addCorrelation(factory.by(Literal.STRING));
      super.endVisit(x, ctx);
    }

    @Override
    public void endVisit(JFieldRef x, Context ctx) {
      x.getSourceInfo().addCorrelation(factory.by(x.getField()));
      super.endVisit(x, ctx);
    }

    @Override
    public boolean visit(JNode x, Context ctx) {
      SourceInfo info = x.getSourceInfo();
      info = pushAndConvert(info);
      x.setSourceInfo(info);
      return true;
    }

    @Override
    public boolean visit(JProgram x, Context ctx) {
      // Types have no source parent.
      parents.push(null);
      return true;
    }

    protected SourceInfo pushAndConvert(SourceInfo info) {
      if (info instanceof SourceOrigin) {
        SourceOrigin origin = (SourceOrigin) info;
        SourceInfoCorrelation parent = parents.peek();
        if (parent != null) {
          info = new SourceInfoCorrelation(parent, origin);
        } else {
          info = new SourceInfoCorrelation(origin);
        }
      }
      parents.push((SourceInfoCorrelation) info);
      return info;
    }
  }

  public static void exec(JProgram program) {
    new SourceInfoVisitor().accept(program);
  }
}
