/*
 * 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.shell.rewrite;

import com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.InstanceMethodOracle;

import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.Remapper;

import java.util.Set;

/**
 * Rewrites references to modified JSO subtypes.
 *
 * <ol>
 * <li>Changes the owner type for instructions that reference items in a JSO
 * class to the implementation class.</li>
 * <li>Rewrites instance calls to JSO classes into static calls.</li>
 * <li>Updates the descriptor for such call sites to includes a synthetic
 * <code>this</code> parameter. This modified method has same stack behavior
 * as the original instance method.</li>
 * </ol>
 */
class RewriteRefsToJsoClasses extends ClassVisitor {

  /**
   * A method body rewriter to actually rewrite call sites.
   */
  private class MyMethodAdapter extends MethodVisitor {

    private Remapper remapper = new Remapper() {
      @Override
      public String map(String typeName) {
        if (jsoDescriptors.contains(typeName)) {
          return HostedModeClassRewriter.JAVASCRIPTOBJECT_IMPL_DESC;
        }
        return typeName;
      }
    };

    public MyMethodAdapter(MethodVisitor mv) {
      super(Opcodes.ASM7, mv);
    }

    @Override
    public void visitFieldInsn(int opcode, String owner, String name,
        String desc) {
      if (jsoDescriptors.contains(owner)) {
        // Change the owner to the rewritten class.
        owner += "$";
      }
      super.visitFieldInsn(opcode, owner, name, desc);
    }

    @Override
    public void visitLdcInsn(Object cst) {
      cst = remapper.mapValue(cst);
      super.visitLdcInsn(cst);
    }

    @Override
    public void visitMethodInsn(int opcode, String owner, String name,
        String desc, boolean dintf) {
      if (jsoDescriptors.contains(owner)) {
        // Find the class that actually declared the method.
        if (opcode == Opcodes.INVOKEVIRTUAL) {
          owner = mapper.findOriginalDeclaringClass(owner, name + desc);
        }
        if (!owner.equals("java/lang/Object")) {
          if (opcode == Opcodes.INVOKEVIRTUAL
              || opcode == Opcodes.INVOKESPECIAL) {
            // Instance/super call to JSO; rewrite as static.
            opcode = Opcodes.INVOKESTATIC;
            desc = HostedModeClassRewriter.addSyntheticThisParam(owner, desc);
            name += "$";
          }
          // Change the owner to implementation class.
          owner += "$";
        }
      }
      super.visitMethodInsn(opcode, owner, name, desc, dintf);
    }

    @Override
    public void visitMultiANewArrayInsn(String desc, int dims) {
      desc = remapper.mapType(desc);
      super.visitMultiANewArrayInsn(desc, dims);
    }

    @Override
    public void visitTypeInsn(int opcode, String type) {
      if (opcode == Opcodes.ANEWARRAY) {
        type = remapper.mapType(type);
      }
      super.visitTypeInsn(opcode, type);
    }
  }

  /**
   * An unmodifiable set of descriptors containing <code>JavaScriptObject</code>
   * and all subclasses.
   */
  protected final Set<String> jsoDescriptors;

  /**
   * Maps methods to the class in which they are declared.
   */
  private InstanceMethodOracle mapper;

  /**
   * Construct a new rewriter instance.
   *
   * @param cv the visitor to chain to
   * @param jsoDescriptors an unmodifiable set of descriptors containing
   *          <code>JavaScriptObject</code> and all subclasses
   * @param mapper maps methods to the class in which they are declared
   */
  public RewriteRefsToJsoClasses(ClassVisitor cv, Set<String> jsoDescriptors,
      InstanceMethodOracle mapper) {
    super(Opcodes.ASM7, cv);
    this.jsoDescriptors = jsoDescriptors;
    this.mapper = mapper;
  }

  @Override
  public MethodVisitor visitMethod(int access, String name, String desc,
      String signature, String[] exceptions) {
    // Wrap the returned method visitor in my own.
    MethodVisitor mv = super.visitMethod(access, name, desc, signature,
        exceptions);
    return new MyMethodAdapter(mv);
  }

}
