/*
 * Copyright 2010 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.JMethod;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.js.JsniMethodBody;

public class PrunerTest extends OptimizerTestBase {
  @Override
  protected void setUp() throws Exception {
    super.setUp();
    runDeadCodeElimination = true;
  }

  public void testSmoke() throws Exception {
    addSnippetClassDecl("static int foo(int i) { return i; }");

    addSnippetClassDecl("static void unusedMethod() { }");
    addSnippetClassDecl("static void usedMethod() { }");
    addSnippetClassDecl("static class UnusedClass { }");
    addSnippetClassDecl("static class UninstantiatedClass { int field; void method() {} }");
    addSnippetClassDecl("static UninstantiatedClass uninstantiatedField;");
    addSnippetClassDecl("static int unusedField;");
    addSnippetClassDecl("static int unreadField;");
    addSnippetClassDecl("static int unassignedField;");
    addSnippetClassDecl("static UninstantiatedClass returnUninstantiatedClass() { return null; }");
    addSnippetClassDecl(
        "interface UsedInterface {",
        "  int unusedConstant = 2;",
        "  int usedConstant = 3;",
        "  void method2();",
        "}");
    addSnippetClassDecl("static class UsedClass implements UsedInterface {",
        "  int field2;",
        "  public void method2() { field2 = usedConstant; }",
        "  UsedClass(UninstantiatedClass c) { }",
        "  UsedClass(UninstantiatedClass c1, UninstantiatedClass c2) { }",
        "}");
    addSnippetClassDecl(
        "static native void usedNativeMethod(UninstantiatedClass c, UsedClass c2)",
        "/*-{",
        "  c.@test.EntryPoint.UninstantiatedClass::field = 2;",
        "  c.@test.EntryPoint.UninstantiatedClass::method();",
        "  c2.@test.EntryPoint.UsedClass::field2++;",
        "  c2.@test.EntryPoint.UsedClass::method2();",
        "}-*/;");
    addSnippetClassDecl(
        "static native void unusedNativeMethod()",
        "/*-{",
        "}-*/;");
    addSnippetClassDecl("static void methodWithUninstantiatedParam(UninstantiatedClass c) { }");
    addSnippetClassDecl("interface UnusedInterface { void foo(); }");

    Result result;
    (result = optimize("void", 
        "usedMethod();",
        "unreadField = 1;",  // should be pruned because it's not read.
        "foo(unassignedField);",
        "returnUninstantiatedClass();",
        "usedNativeMethod(null, null);",
        "foo(uninstantiatedField.field);",
        "uninstantiatedField.method();",
        "methodWithUninstantiatedParam(null);",
        "new UsedClass(null);",
        "new UsedClass(returnUninstantiatedClass(), returnUninstantiatedClass());",
        "UninstantiatedClass localUninstantiated = null;"
        )).intoString(
            "EntryPoint.usedMethod();",
            "EntryPoint.foo(EntryPoint.unassignedField);",
            "EntryPoint.returnUninstantiatedClass();",
            "EntryPoint.usedNativeMethod(null, null);",
            "EntryPoint.foo(null.nullField);",
            "null.nullMethod();",
            "EntryPoint.methodWithUninstantiatedParam();",
            "new EntryPoint$UsedClass();",
            "new EntryPoint$UsedClass((EntryPoint.returnUninstantiatedClass(), EntryPoint.returnUninstantiatedClass()));"
            );
    
    assertNotNull(result.findMethod("usedMethod"));
    // We do not assign to the field, but we use its default value.
    // Shouldn't be pruned.
    assertNotNull(result.findField("unassignedField"));
    assertNotNull(result.findMethod("usedNativeMethod"));
    assertNotNull(result.findMethod("returnUninstantiatedClass"));
    assertNotNull(result.findMethod("methodWithUninstantiatedParam"));
    assertNotNull(result.findClass("EntryPoint$UsedClass"));
    assertNotNull(result.findClass("EntryPoint$UsedInterface"));

    assertNull(result.findMethod("unusedMethod"));
    assertNull(result.findField("unusedField"));
    assertNull(result.findField("unreadField"));
    assertNull(result.findClass("EntryPoint$UnusedClass"));
    assertNull(result.findMethod("unusedNativeMethod"));
    assertNull(result.findField("uninstantiatedField"));
    assertNull(result.findClass("EntryPoint$UnusedInterface"));

    // Class is never instantiated. Should be pruned.
    assertNull(result.findClass("UninstantiatedClass"));

    assertEquals(
        "public static <null> returnUninstantiatedClass(){\n" + 
        "  return null;\n" +
        "}", 
        result.findMethod("returnUninstantiatedClass").toSource());
    
    assertEquals(
        "public static void methodWithUninstantiatedParam(){\n" + 
        "}", 
        result.findMethod("methodWithUninstantiatedParam").toSource());

    assertEquals(
        "[final <null> nullField, int field2]", 
        ((JsniMethodBody) result.findMethod("usedNativeMethod").getBody()).
        getJsniFieldRefs().toString());
    assertEquals(
        "[public final <null> nullMethod(), public void method2()]", 
        ((JsniMethodBody) result.findMethod("usedNativeMethod").getBody()).
        getJsniMethodRefs().toString());

    assertEquals(
        "interface EntryPoint$UsedInterface {\n" +
        "  private static final void $clinit(){\n" +
        "    Object.$clinit();\n" +
        "  }\n" +
        "\n" +
        "}", 
        result.findClass("EntryPoint$UsedInterface").toSource());
  }
  
  @Override
  protected boolean optimizeMethod(JProgram program, JMethod method) {
    program.addEntryMethod(findMainMethod(program));
    return Pruner.exec(program, true).didChange();
  }
}
