Index: compiler/java/com/google/dart/compiler/backend/js/ast/JsScope.java |
diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsScope.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsScope.java |
deleted file mode 100644 |
index 0344842aa6140dcad04ae08a13b0fdaf445a1369..0000000000000000000000000000000000000000 |
--- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsScope.java |
+++ /dev/null |
@@ -1,301 +0,0 @@ |
-// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
-// for details. All rights reserved. Use of this source code is governed by a |
-// BSD-style license that can be found in the LICENSE file. |
- |
-package com.google.dart.compiler.backend.js.ast; |
- |
-import com.google.common.collect.Interner; |
-import com.google.common.collect.Interners; |
-import com.google.dart.compiler.util.Lists; |
-import com.google.dart.compiler.util.Maps; |
- |
-import java.io.Serializable; |
-import java.util.Collections; |
-import java.util.Iterator; |
-import java.util.List; |
-import java.util.Map; |
- |
-/** |
- * A scope is a factory for creating and allocating |
- * {@link com.google.dart.compiler.backend.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.dart.compiler.backend.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.dart.compiler.backend.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.dart.compiler.backend.js.ast.JsProgram#getRootScope()}), |
- * 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 class JsScope implements Serializable { |
- |
- private List<JsScope> children = Collections.emptyList(); |
- private final String description; |
- private Map<String, JsName> names = Collections.emptyMap(); |
- private JsScope parent; |
- protected int tempIndex = 0; |
- private final String scopeId; |
- private static Interner<String> interner = Interners.newWeakInterner(); |
- |
- /* |
- * Create a scope with parent. |
- */ |
- public JsScope(JsScope parent, String description) { |
- this(parent, description, null); |
- } |
- |
- /** |
- * Create a scope with parent. |
- */ |
- public JsScope(JsScope parent, String description, String scopeId) { |
- assert (parent != null); |
- this.scopeId = scopeId; |
- this.description = interner.intern(description); |
- this.parent = parent; |
- parent.children = Lists.add(parent.children, this); |
- } |
- |
- /** |
- * Rebase the function to a new scope. |
- * @param newParent The scope to add the function to. |
- */ |
- public void rebase(JsScope newParent) { |
- detachFromParent(); |
- parent = newParent; |
- parent.children = Lists.add(parent.children, this); |
- } |
- |
- /** |
- * Rebase the function's children to a new scope. |
- * @param newParent |
- */ |
- public void rebaseChildScopes(JsScope newParent) { |
- if (newParent == this) { |
- return; |
- } |
- parent.children = Lists.addAll(parent.children, children); |
- for (JsScope child : children) { |
- child.parent = newParent; |
- } |
- children = Collections.emptyList(); |
- } |
- |
- /** |
- * Subclasses can detach and become parentless. |
- */ |
- protected void detachFromParent() { |
- JsScope oldParent = parent; |
- |
- oldParent.children = Lists.remove( |
- parent.children, oldParent.children.indexOf(this)); |
- |
- parent = null; |
- } |
- |
- /** |
- * Subclasses can be parentless. |
- */ |
- protected JsScope(String description) { |
- this.description = description; |
- this.parent = null; |
- this.scopeId = null; |
- } |
- |
- /** |
- * Gets a name object associated with the specified ident in this scope, |
- * creating it if necessary.<br/> |
- * If the JsName does not exist yet, a new JsName is created. The ident, |
- * short name, and original name of the newly created JsName are equal to |
- * the given ident. |
- * |
- * @param ident An identifier that is unique within this scope. |
- */ |
- public JsName declareName(String ident) { |
- JsName name = findExistingNameNoRecurse(ident); |
- if (name != null) { |
- return name; |
- } |
- return doCreateName(ident, ident, ident); |
- } |
- |
- /** |
- * Creates a new variable with an unique ident in this scope. |
- * The generated JsName is guaranteed to have an identifier (but not short |
- * name) that does not clash with any existing variables in the scope. |
- * Future declarations of variables might however clash with the temporary |
- * (unless they use this function). |
- */ |
- public JsName declareFreshName(String shortName) { |
- String ident = shortName; |
- int counter = 0; |
- while (findExistingNameNoRecurse(ident) != null) { |
- ident = shortName + "_" + counter++; |
- } |
- return doCreateName(ident, shortName, shortName); |
- } |
- |
- String getNextTempName() { |
- // TODO(ngeoffray): Decide on a convention for temporary variables |
- // introduced by the compiler. |
- return "tmp$" + (scopeId != null ? scopeId + "$" : "") + tempIndex++; |
- } |
- |
- /** |
- * Creates a temporary variable with an unique name in this scope. |
- * The generated temporary is guaranteed to have an identifier (but not short |
- * name) that does not clash with any existing variables in the scope. |
- * Future declarations of variables might however clash with the temporary. |
- */ |
- public JsName declareTemporary() { |
- return declareFreshName(getNextTempName()); |
- } |
- |
- /** |
- * Gets a name object associated with the specified ident in this scope, |
- * creating it if necessary.<br/> |
- * If the JsName does not exist yet, a new JsName is created with the given |
- * ident, short name and original name. |
- * |
- * @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 JsName declareName(String ident, String shortIdent) { |
- return declareName(ident, shortIdent, ident); |
- } |
- |
- /** |
- * Gets a name object associated with the specified ident in this scope, |
- * creating it if necessary.<br/> |
- * If the JsName does not exist yet, a new JsName is created. The original |
- * name stored in the JsName is equal to the (unmangled) specified originalName. |
- * |
- * @param ident An identifier that is unique within this scope. |
- * @param shortIdent A "pretty" name that does not have to be unique. |
- * @param originalName The original name in the source. |
- * @throws IllegalArgumentException if ident already exists in this scope but |
- * the requested short name does not match the existing short name, |
- * or the original name does not match the existing original name. |
- */ |
- public JsName declareName(String ident, String shortIdent, String originalName) { |
- JsName name = findExistingNameNoRecurse(ident); |
- if (name != null) { |
- if (!name.getShortIdent().equals(shortIdent) |
- || !nullableEquals(name.getOriginalName(), originalName)) { |
- throw new IllegalArgumentException("Requested short name " + shortIdent |
- + " conflicts with preexisting short name " + name.getShortIdent() + " for identifier " |
- + ident); |
- } |
- return name; |
- } |
- return doCreateName(ident, shortIdent, originalName); |
- } |
- |
- boolean nullableEquals(String s1, String s2) { |
- return (s1 == null) ? (s2 == null) : s1.equals(s2); |
- } |
- |
- /** |
- * 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) { |
- JsName name = findExistingNameNoRecurse(ident); |
- if (name == null && parent != null) { |
- return parent.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) { |
- JsName name = findExistingNameNoRecurse(ident); |
- if (name != null && name.isObfuscatable()) { |
- name = null; |
- } |
- if (name == null && parent != null) { |
- return parent.findExistingUnobfuscatableName(ident); |
- } |
- return name; |
- } |
- |
- /** |
- * Returns an iterator for all the names defined by this scope. |
- */ |
- public Iterator<JsName> getAllNames() { |
- return names.values().iterator(); |
- } |
- |
- /** |
- * Returns a list of this scope's child scopes. |
- */ |
- public final List<JsScope> getChildren() { |
- return children; |
- } |
- |
- /** |
- * Returns the parent scope of this scope, or <code>null</code> if this is the |
- * root scope. |
- */ |
- public final JsScope getParent() { |
- return parent; |
- } |
- |
- /** |
- * Returns the associated program. |
- */ |
- public JsProgram getProgram() { |
- assert (parent != null) : "Subclasses must override getProgram() if they do not set a parent"; |
- return parent.getProgram(); |
- } |
- |
- @Override |
- public final String toString() { |
- if (parent != null) { |
- return description + "->" + parent; |
- } else { |
- return description; |
- } |
- } |
- |
- /** |
- * Creates a new name in this scope. |
- */ |
- protected JsName doCreateName(String ident, String shortIdent, String originalName) { |
- JsName name = new JsName(this, ident, shortIdent, originalName); |
- names = Maps.putOrdered(names, ident, name); |
- return name; |
- } |
- |
- /** |
- * 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 JsName findExistingNameNoRecurse(String ident) { |
- return names.get(ident); |
- } |
-} |