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

import com.google.gwt.dev.jjs.SourceInfo;
import com.google.gwt.dev.jjs.SourceOrigin;

import java.io.Serializable;
import java.util.List;

/**
 * A Java constructor method.
 */
public class JConstructor extends JMethod {

  private static class ExternalSerializedForm implements Serializable {

    private final JClassType enclosingType;
    private final String signature;

    public ExternalSerializedForm(JConstructor ctor) {
      enclosingType = ctor.getEnclosingType();
      signature = ctor.getSignature();
    }

    private Object readResolve() {
      JConstructor result = new JConstructor(SourceOrigin.UNKNOWN, enclosingType);
      result.signature = signature;
      return result;
    }
  }

  /**
   * Caches whether or not this constructor does any work. Once true, we never
   * have to recheck, but we keep rechecking as long as it's false.
   */
  private boolean isEmpty = false;

  public JConstructor(SourceInfo info, JClassType enclosingType) {
    super(info, enclosingType.getShortName(), enclosingType, JPrimitiveType.VOID, false, false,
        true, false);
  }

  @Override
  public boolean canBePolymorphic() {
    return false;
  }

  @Override
  public JMethodBody getBody() {
    return (JMethodBody) super.getBody();
  }

  @Override
  public JClassType getEnclosingType() {
    return (JClassType) super.getEnclosingType();
  }

  public JNonNullType getNewType() {
    return getEnclosingType().getNonNull();
  }

  /**
   * Returns <code>true</code> if this constructor does no real work.
   * 
   * NOTE: this method does NOT account for any clinits that would be triggered
   * if this constructor is the target of a new instance operation from an
   * external class.
   * 
   * TODO(scottb): make this method less expensive by computing in an external
   * visitor.
   */
  public boolean isEmpty() {
    if (isEmpty) {
      return true;
    }
    JMethodBody body = getBody();
    List<JStatement> statements = body.getStatements();
    if (statements.isEmpty()) {
      return (isEmpty = true);
    }
    if (statements.size() > 1) {
      return false;
    }
    // Only one statement. Check to see if it's an empty super() or this() call.
    JStatement stmt = statements.get(0);
    if (stmt instanceof JExpressionStatement) {
      JExpressionStatement exprStmt = (JExpressionStatement) stmt;
      JExpression expr = exprStmt.getExpr();
      if (expr instanceof JMethodCall && !(expr instanceof JNewInstance)) {
        JMethodCall call = (JMethodCall) expr;
        JMethod target = call.getTarget();
        if (target instanceof JConstructor) {
          return isEmpty = ((JConstructor) target).isEmpty();
        }
      }
    }
    return false;
  }

  @Override
  public boolean needsVtable() {
    return false;
  }

  @Override
  public void traverse(JVisitor visitor, Context ctx) {
    String before = traceBefore(visitor);
    if (visitor.visit(this, ctx)) {
      visitChildren(visitor);
    }
    visitor.endVisit(this, ctx);
    traceAfter(visitor, before);
  }

  @Override
  protected Object writeReplace() {
    if (isExternal()) {
      return new ExternalSerializedForm(this);
    } else {
      return this;
    }
  }

}
