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

import com.google.gwt.dev.js.JsKeywords;
import com.google.gwt.dev.util.StringInterner;

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

/**
 * A scope is a factory for creating and allocating
 * {@link com.google.gwt.dev.js.ast.JsName}s. A JavaScript AST is built in terms
 * of abstract name objects without worrying about obfuscation,
 * keyword/identifier blacklisting, and so on.
 * 
 * <p>
 * 
 * Scopes are associated with {@link com.google.gwt.dev.js.ast.JsFunction}s, but
 * the two are not equivalent. Functions <i>have</i> scopes, but a scope does
 * not necessarily have an associated Function. Examples of this include the
 * {@link com.google.gwt.dev.js.ast.JsRootScope} and synthetic scopes that might
 * be created by a client.
 * 
 * <p>
 * 
 * Scopes can have parents to provide constraints when allocating actual
 * identifiers for names. Specifically, names in child scopes are chosen such
 * that they do not conflict with names in their parent scopes. The ultimate
 * parent is usually the global scope (see
 * {@link com.google.gwt.dev.js.ast.JsProgram#getGlobalScope()}), but parentless
 * scopes are useful for managing names that are always accessed with a
 * qualifier and could therefore never be confused with the global scope
 * hierarchy.
 */
public abstract class JsScope implements Serializable {

  /**
   * Prevents the client from programmatically creating an illegal ident.
   */
  private static String maybeMangleKeyword(String ident) {
    if (JsKeywords.isKeyword(ident)) {
      ident = ident + "_$";
    }
    return StringInterner.get().intern(ident);
  }

  private final String description;

  protected JsScope(String description) {
    this.description = StringInterner.get().intern(description);
  }

  /**
   * Gets a name object associated with the specified ident in this scope,
   * creating it if necessary.
   * 
   * @param ident An identifier that is unique within this scope.
   */
  public final JsName declareName(String ident) {
    ident = maybeMangleKeyword(ident);
    JsName name = findExistingNameNoRecurse(ident);
    if (name != null) {
      return name;
    }
    return doCreateName(ident, ident);
  }

  /**
   * Gets a name object associated with the specified ident in this scope,
   * creating it if necessary.
   * 
   * @param ident An identifier that is unique within this scope.
   * @param shortIdent A "pretty" name that does not have to be unique.
   * @throws IllegalArgumentException if ident already exists in this scope but
   *           the requested short name does not match the existing short name.
   */
  public final JsName declareName(String ident, String shortIdent) {
    ident = maybeMangleKeyword(ident);
    shortIdent = maybeMangleKeyword(shortIdent);
    JsName name = findExistingNameNoRecurse(ident);
    if (name != null) {
      if (!name.getShortIdent().equals(shortIdent)) {
        throw new IllegalArgumentException("Requested short name " + shortIdent
            + " conflicts with preexisting short name " + name.getShortIdent()
            + " for identifier " + ident);
      }
      return name;
    }
    return doCreateName(ident, shortIdent);
  }

  /**
   * Attempts to find the name object for the specified ident, searching in this
   * scope, and if not found, in the parent scopes.
   * 
   * @return <code>null</code> if the identifier has no associated name
   */
  public final JsName findExistingName(String ident) {
    ident = maybeMangleKeyword(ident);
    JsName name = findExistingNameNoRecurse(ident);
    if (name == null && getParent() != null) {
      return getParent().findExistingName(ident);
    }
    return name;
  }

  /**
   * Attempts to find an unobfuscatable name object for the specified ident,
   * searching in this scope, and if not found, in the parent scopes.
   * 
   * @return <code>null</code> if the identifier has no associated name
   */
  public final JsName findExistingUnobfuscatableName(String ident) {
    ident = maybeMangleKeyword(ident);
    JsName name = findExistingNameNoRecurse(ident);
    if (name != null && name.isObfuscatable()) {
      name = null;
    }
    if (name == null && getParent() != null) {
      return getParent().findExistingUnobfuscatableName(ident);
    }
    return name;
  }

  /**
   * Returns an iterator for all the names defined by this scope.
   */
  public abstract Iterator<JsName> getAllNames();

  /**
   * Returns a list of this scope's child scopes.
   */
  public abstract List<JsScope> getChildren();

  /**
   * Returns the parent scope of this scope, or <code>null</code> if this is the
   * root scope.
   */
  public abstract JsScope getParent();

  @Override
  public final String toString() {
    if (getParent() != null) {
      return description + "->" + getParent();
    } else {
      return description;
    }
  }

  protected abstract void addChild(JsScope child);

  /**
   * Creates a new name in this scope.
   */
  protected abstract JsName doCreateName(String ident, String shortIdent);

  /**
   * Attempts to find the name object for the specified ident, searching in this
   * scope only.
   * 
   * @return <code>null</code> if the identifier has no associated name
   */
  protected abstract JsName findExistingNameNoRecurse(String ident);
}
