class CollapseProperties extends java.lang.Object implements CompilerPass
RenameVars
pass to shorten namespaced names.
For example, goog.events.handleEvent() -> goog$events$handleEvent() -> Za().
If a global object's name is assigned to more than once, or if a property is added to the global object in a complex expression, then none of its properties will be collapsed (for safety/correctness).
If, after a global object is declared, it is never referenced except when its properties are read or set, then the object will be removed after its properties have been collapsed.
Uninitialized variable stubs are created at a global object's declaration site for any of its properties that are added late in a local scope.
Static properties of constructors are always collapsed, unsafely!
For other objects: if, after an object is declared, it is referenced directly
in a way that might create an alias for it, then none of its properties will
be collapsed.
This behavior is a safeguard to prevent the values associated with the
flattened names from getting out of sync with the object's actual property
values. For example, in the following case, an alias a$b, if created, could
easily keep the value 0 even after a.b became 5:
a = {b: 0}; c = a; c.b = 5;
.
This pass doesn't flatten property accesses of the form: a[b].
For lots of examples, see the unit test.
Modifier and Type | Field and Description |
---|---|
private AbstractCompiler |
compiler |
private java.util.List<GlobalNamespace.Name> |
globalNames
Global namespace tree
|
private java.util.Map<java.lang.String,GlobalNamespace.Name> |
nameMap
Maps names (e.g.
|
(package private) static DiagnosticType |
NAMESPACE_REDEFINED_WARNING |
(package private) static DiagnosticType |
UNSAFE_CTOR_ALIASING |
(package private) static DiagnosticType |
UNSAFE_NAMESPACE_WARNING |
(package private) static DiagnosticType |
UNSAFE_THIS |
Constructor and Description |
---|
CollapseProperties(AbstractCompiler compiler) |
Modifier and Type | Method and Description |
---|---|
private int |
addStubsForUndeclaredProperties(GlobalNamespace.Name n,
java.lang.String alias,
Node parent,
Node addAfter)
Adds global variable "stubs" for any properties of a global name that are
only set in a local scope or read but never set.
|
private java.lang.String |
appendPropForAlias(java.lang.String root,
java.lang.String prop) |
private void |
checkForHosedThisReferences(Node function,
JSDocInfo docInfo,
GlobalNamespace.Name name)
Warns about any references to "this" in the given FUNCTION.
|
private void |
checkNamespaces()
Runs through all namespaces (prefixes of classes and enums), and checks if
any of them have been used in an unsafe way.
|
private void |
collapseDeclarationOfNameAndDescendants(GlobalNamespace.Name n,
java.lang.String alias)
Collapses definitions of the collapsible properties of a global name.
|
private int |
declareVarsForObjLitValues(GlobalNamespace.Name objlitName,
java.lang.String alias,
Node objlit,
Node varNode,
Node nameToAddAfter,
Node varParent)
Declares global variables to serve as aliases for the values in an object
literal, optionally removing all of the object literal's keys and values.
|
private void |
flattenNameRef(java.lang.String alias,
Node n,
Node parent,
java.lang.String originalName)
Replaces a GETPROP a.b.c with a NAME a$b$c.
|
private void |
flattenNameRefAtDepth(java.lang.String alias,
Node n,
int depth,
java.lang.String originalName)
Flattens a particular prefix of a single name reference.
|
private void |
flattenPrefixes(java.lang.String alias,
GlobalNamespace.Name n,
int depth)
Flattens all occurrences of a name as a prefix of subnames beginning
with a particular subname.
|
private void |
flattenReferencesTo(GlobalNamespace.Name n,
java.lang.String alias)
Flattens all references to a collapsible property of a global name except
its initial definition.
|
private void |
flattenReferencesToCollapsibleDescendantNames(GlobalNamespace.Name n,
java.lang.String alias)
Flattens all references to collapsible properties of a global name except
their initial definitions.
|
private void |
flattenSimpleStubDeclaration(GlobalNamespace.Name name,
java.lang.String alias)
Flattens a stub declaration.
|
(package private) JSModule |
getRefModule(ReferenceCollectingCallback.Reference ref) |
private static Node |
getValueParent(GlobalNamespace.Ref ref)
Gets the parent node of the value for any assignment to a Name.
|
private void |
inlineAliases(GlobalNamespace namespace)
For each qualified name N in the global scope, we check if:
(a) No ancestor of N is ever aliased or assigned an unknown value type.
|
private boolean |
inlineAliasIfPossible(GlobalNamespace.Name name,
GlobalNamespace.Ref alias,
GlobalNamespace namespace) |
private boolean |
inlineGlobalAliasIfPossible(GlobalNamespace.Name name,
GlobalNamespace.Ref alias,
GlobalNamespace namespace)
Attempt to inline an global alias of a global name.
|
private boolean |
isSafeNamespaceReinit(GlobalNamespace.Ref ref) |
void |
process(Node externs,
Node root)
Process the JS with root node root.
|
private static void |
rewriteAliasProps(GlobalNamespace.Name name,
Node value,
int depth,
java.util.Set<GlobalNamespace.AstChange> newNodes) |
private void |
updateFunctionDeclarationAtFunctionNode(GlobalNamespace.Name n,
boolean canCollapseChildNames)
Updates the first initialization (a.k.a "declaration") of a global name
that occurs at a FUNCTION node.
|
private void |
updateObjLitOrFunctionDeclaration(GlobalNamespace.Name n,
java.lang.String alias,
boolean canCollapseChildNames)
Updates the first initialization (a.k.a "declaration") of a global name.
|
private void |
updateObjLitOrFunctionDeclarationAtAssignNode(GlobalNamespace.Name n,
java.lang.String alias,
boolean canCollapseChildNames)
Updates the first initialization (a.k.a "declaration") of a global name
that occurs at an ASSIGN node.
|
private void |
updateObjLitOrFunctionDeclarationAtVarNode(GlobalNamespace.Name n,
boolean canCollapseChildNames)
Updates the first initialization (a.k.a "declaration") of a global name
that occurs at a VAR node.
|
private void |
updateSimpleDeclaration(java.lang.String alias,
GlobalNamespace.Name refName,
GlobalNamespace.Ref ref)
Updates the initial assignment to a collapsible property at global scope
by changing it to a variable declaration (e.g.
|
private void |
warnAboutNamespaceAliasing(GlobalNamespace.Name nameObj,
GlobalNamespace.Ref ref)
Reports a warning because a namespace was aliased.
|
private void |
warnAboutNamespaceRedefinition(GlobalNamespace.Name nameObj,
GlobalNamespace.Ref ref)
Reports a warning because a namespace was redefined.
|
static final DiagnosticType UNSAFE_NAMESPACE_WARNING
static final DiagnosticType NAMESPACE_REDEFINED_WARNING
static final DiagnosticType UNSAFE_THIS
static final DiagnosticType UNSAFE_CTOR_ALIASING
private AbstractCompiler compiler
private java.util.List<GlobalNamespace.Name> globalNames
private java.util.Map<java.lang.String,GlobalNamespace.Name> nameMap
CollapseProperties(AbstractCompiler compiler)
public void process(Node externs, Node root)
CompilerPass
process
in interface CompilerPass
externs
- Top of external JS treeroot
- Top of JS treeprivate void inlineAliases(GlobalNamespace namespace)
InlineVariables
private boolean inlineGlobalAliasIfPossible(GlobalNamespace.Name name, GlobalNamespace.Ref alias, GlobalNamespace namespace)
alias
- The alias to inlineprivate static void rewriteAliasProps(GlobalNamespace.Name name, Node value, int depth, java.util.Set<GlobalNamespace.AstChange> newNodes)
name
- The Name whose properties references should be updated.value
- The value to use when rewriting.depth
- The chain depth.newNodes
- Expression nodes that have been updated.private boolean inlineAliasIfPossible(GlobalNamespace.Name name, GlobalNamespace.Ref alias, GlobalNamespace namespace)
JSModule getRefModule(ReferenceCollectingCallback.Reference ref)
private void checkNamespaces()
private boolean isSafeNamespaceReinit(GlobalNamespace.Ref ref)
private static Node getValueParent(GlobalNamespace.Ref ref)
var x = 3;
the parent would be the NAME node.private void warnAboutNamespaceAliasing(GlobalNamespace.Name nameObj, GlobalNamespace.Ref ref)
nameObj
- A namespace that is being aliasedref
- The reference that forced the aliasprivate void warnAboutNamespaceRedefinition(GlobalNamespace.Name nameObj, GlobalNamespace.Ref ref)
nameObj
- A namespace that is being redefinedref
- The reference that set the namespaceprivate void flattenReferencesToCollapsibleDescendantNames(GlobalNamespace.Name n, java.lang.String alias)
n
- An object representing a global namealias
- The flattened name for n
private void flattenSimpleStubDeclaration(GlobalNamespace.Name name, java.lang.String alias)
private void flattenReferencesTo(GlobalNamespace.Name n, java.lang.String alias)
n
- A global property name (e.g. "a.b" or "a.b.c.d")alias
- The flattened name (e.g. "a$b" or "a$b$c$d")private void flattenPrefixes(java.lang.String alias, GlobalNamespace.Name n, int depth)
n
- A global property name (e.g. "a.b.c.d")alias
- A flattened prefix name (e.g. "a$b")depth
- The difference in depth between the property name and
the prefix name (e.g. 2)private void flattenNameRefAtDepth(java.lang.String alias, Node n, int depth, java.lang.String originalName)
alias
- A flattened prefix name (e.g. "a$b")n
- The node corresponding to a subproperty name (e.g. "a.b.c.d")depth
- The difference in depth between the property name and
the prefix name (e.g. 2)originalName
- String version of the property name.private void flattenNameRef(java.lang.String alias, Node n, Node parent, java.lang.String originalName)
alias
- A flattened prefix name (e.g. "a$b")n
- The GETPROP node corresponding to the original name (e.g. "a.b")parent
- n
's parentoriginalName
- String version of the property name.private void collapseDeclarationOfNameAndDescendants(GlobalNamespace.Name n, java.lang.String alias)
n
- A node representing a global namealias
- The flattened name for n
private void updateSimpleDeclaration(java.lang.String alias, GlobalNamespace.Name refName, GlobalNamespace.Ref ref)
alias
- The flattened property name (e.g. "a$b")refName
- The name for the reference being updated.ref
- An object containing information about the assignment getting
updatedprivate void updateObjLitOrFunctionDeclaration(GlobalNamespace.Name n, java.lang.String alias, boolean canCollapseChildNames)
n
- An object representing a global name (e.g. "a", "a.b.c")alias
- The flattened name for n
(e.g. "a", "a$b$c")canCollapseChildNames
- Whether it's possible to collapse children of
this name. (This is mostly passed for convenience; it's equivalent to
n.canCollapseChildNames()).private void updateObjLitOrFunctionDeclarationAtAssignNode(GlobalNamespace.Name n, java.lang.String alias, boolean canCollapseChildNames)
updateObjLitOrFunctionDeclaration(com.google.javascript.jscomp.GlobalNamespace.Name, java.lang.String, boolean)
.n
- An object representing a global name (e.g. "a", "a.b.c")alias
- The flattened name for n
(e.g. "a", "a$b$c")private void checkForHosedThisReferences(Node function, JSDocInfo docInfo, GlobalNamespace.Name name)
private void updateObjLitOrFunctionDeclarationAtVarNode(GlobalNamespace.Name n, boolean canCollapseChildNames)
updateObjLitOrFunctionDeclaration(com.google.javascript.jscomp.GlobalNamespace.Name, java.lang.String, boolean)
.n
- An object representing a global name (e.g. "a")private void updateFunctionDeclarationAtFunctionNode(GlobalNamespace.Name n, boolean canCollapseChildNames)
updateObjLitOrFunctionDeclaration(com.google.javascript.jscomp.GlobalNamespace.Name, java.lang.String, boolean)
.n
- An object representing a global name (e.g. "a")private int declareVarsForObjLitValues(GlobalNamespace.Name objlitName, java.lang.String alias, Node objlit, Node varNode, Node nameToAddAfter, Node varParent)
alias
- The object literal's flattened name (e.g. "a$b$c")objlit
- The OBJLIT nodevarNode
- The VAR node to which new global variables should be added
as childrennameToAddAfter
- The child of varNode
after which new
variables should be added (may be null)varParent
- varNode
's parentprivate int addStubsForUndeclaredProperties(GlobalNamespace.Name n, java.lang.String alias, Node parent, Node addAfter)
n
- An object representing a global name (e.g. "a", "a.b.c")alias
- The flattened name of the object whose properties we are
adding stubs for (e.g. "a$b$c")parent
- The node to which new global variables should be added
as childrenaddAfter
- The child of after which new
variables should be addedprivate java.lang.String appendPropForAlias(java.lang.String root, java.lang.String prop)