/*
 * 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.Context;
import com.google.gwt.dev.jjs.ast.JCastOperation;
import com.google.gwt.dev.jjs.ast.JClassType;
import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.jjs.ast.JInterfaceType;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JReferenceType;
import com.google.gwt.dev.jjs.ast.JType;
import com.google.gwt.dev.jjs.ast.JVisitor;

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

/**
 * Record all Cast operations on JSOs as instantiations. This must run before
 * {@link com.google.gwt.dev.jjs.impl.ImplementCastsAndTypeChecks}.
 */
public class ComputeInstantiatedJsoInterfaces {
  class InstantiatedJsoInterfacesCollector extends JVisitor {
    @Override
    public void endVisit(JCastOperation x, Context ctx) {
      JType toType = x.getCastType();

      if (toType instanceof JReferenceType && !toType.isNullType()) {
        toType = toType.getUnderlyingType();
        if (program.typeOracle.willCrossCastLikeJso(toType) ||
            program.typeOracle.isOrExtendsJsType(toType, true) ||
            program.typeOracle.isJsFunction(toType)) {
          instantiateJsoInterface((JReferenceType) toType);
        }
      }
    }
  }

  private void instantiateJsoInterface(JReferenceType toType) {
    if (instantiatedJsoTypes.add(toType)) {
      if (program.typeOracle.getSingleJsoImpl(toType) != null) {
        // rescuing an Interface via Cast, we record the JSO implementing it
        instantiateJsoInterface(program.typeOracle.getSingleJsoImpl(toType));
      }
      // if it's a class, and the superType is JSO, rescue it too
      if (toType instanceof JClassType) {
        JClassType superType = ((JClassType) toType).getSuperClass();
        if (superType != null && superType.isJsoType()) {
          instantiateJsoInterface(superType);
        }
      }
      // if we extend another JsType, or Interface with JSO implementation, rescue it
      for (JInterfaceType intf : ((JDeclaredType) toType).getImplements()) {
        if (intf.isJsType() || program.typeOracle.getSingleJsoImpl(intf) != null) {
          instantiateJsoInterface(intf);
        }
      }
    }
  }

  private final JProgram program;
  private final Set<JReferenceType> instantiatedJsoTypes = new HashSet<JReferenceType>();

  public static void exec(JProgram program) {
    new ComputeInstantiatedJsoInterfaces(program).execImpl();
  }

  private ComputeInstantiatedJsoInterfaces(JProgram program) {
    this.program = program;
  }

  private void execImpl() {
    InstantiatedJsoInterfacesCollector replacer = new InstantiatedJsoInterfacesCollector();
    replacer.accept(program);
    program.typeOracle.setInstantiatedJsoTypesViaCast(instantiatedJsoTypes);
  }
}
