class AmbiguateProperties extends java.lang.Object implements CompilerPass
Properties are considered unrelated if they are never referenced from the
same type or from a subtype of each others' types, thus this pass is only
effective if type checking is enabled.
Example:
Foo.fooprop = 0;
Foo.fooprop2 = 0;
Bar.barprop = 0;
becomes:
Foo.a = 0;
Foo.b = 0;
Bar.a = 0;
Modifier and Type | Class and Description |
---|---|
private class |
AmbiguateProperties.JSTypeBitSet |
private class |
AmbiguateProperties.ProcessProperties
Finds all property references, recording the types on which they occur.
|
private class |
AmbiguateProperties.Property
Encapsulates the information needed for renaming a property.
|
(package private) class |
AmbiguateProperties.PropertyGraph |
(package private) class |
AmbiguateProperties.PropertyGraphNode |
(package private) class |
AmbiguateProperties.PropertySubGraph
A
SubGraph that represents properties. |
Modifier and Type | Field and Description |
---|---|
private AbstractCompiler |
compiler |
private java.util.Set<java.lang.String> |
externedNames
Property names that don't get renamed
|
private static java.util.Comparator<AmbiguateProperties.Property> |
FREQUENCY_COMPARATOR
Sorts Property objects by their count, breaking ties alphabetically to
ensure a deterministic total ordering.
|
private com.google.common.collect.BiMap<JSType,java.lang.Integer> |
intForType
A map from JSType to a unique representative Integer.
|
private java.util.Set<JSType> |
invalidatingTypes
A set of types that invalidate properties from ambiguation.
|
private static java.util.logging.Logger |
logger |
private java.util.Map<java.lang.String,AmbiguateProperties.Property> |
propertyMap
Map from property name to Property object
|
private java.util.Set<java.lang.String> |
quotedNames
Names to which properties shouldn't be renamed, to avoid name conflicts
|
private java.util.Map<JSType,AmbiguateProperties.JSTypeBitSet> |
relatedBitsets
A map from JSType to JSTypeBitSet representing the types related
to the type.
|
private java.util.Map<java.lang.String,java.lang.String> |
renamingMap
Map from original property name to new name.
|
private char[] |
reservedCharacters |
(package private) static java.lang.String |
SKIP_PREFIX
Prefix of properties to skip renaming.
|
private java.util.List<Node> |
stringNodesToRename |
Constructor and Description |
---|
AmbiguateProperties(AbstractCompiler compiler,
char[] reservedCharacters) |
Modifier and Type | Method and Description |
---|---|
private void |
addInvalidatingType(JSType type)
Invalidates the given type, so that no properties on it will be renamed.
|
private void |
addRelatedInstance(FunctionType constructor,
AmbiguateProperties.JSTypeBitSet related)
Adds the instance of the given constructor, its implicit prototype and all
its related types to the given bit set.
|
private void |
computeRelatedTypes(JSType type)
Adds subtypes - and implementors, in the case of interfaces - of the type
to its JSTypeBitSet of related types.
|
private int |
getIntForType(JSType type)
Returns an integer that uniquely identifies a JSType.
|
private JSType |
getJSType(Node n)
This method gets the JSType from the Node argument and verifies that it is
present.
|
private AmbiguateProperties.Property |
getProperty(java.lang.String name) |
private BitSet |
getRelatedTypesOnNonUnion(JSType type) |
(package private) java.util.Map<java.lang.String,java.lang.String> |
getRenamingMap() |
private boolean |
isInvalidatingType(JSType type)
Returns true if properties on this type should not be renamed.
|
(package private) static AmbiguateProperties |
makePassForTesting(AbstractCompiler compiler,
char[] reservedCharacters) |
void |
process(Node externs,
Node root)
Process the JS with root node root.
|
private static final java.util.logging.Logger logger
private final AbstractCompiler compiler
private final java.util.List<Node> stringNodesToRename
private final char[] reservedCharacters
private final java.util.Map<java.lang.String,AmbiguateProperties.Property> propertyMap
private final java.util.Set<java.lang.String> externedNames
private final java.util.Set<java.lang.String> quotedNames
private java.util.Map<java.lang.String,java.lang.String> renamingMap
private static final java.util.Comparator<AmbiguateProperties.Property> FREQUENCY_COMPARATOR
private com.google.common.collect.BiMap<JSType,java.lang.Integer> intForType
private java.util.Map<JSType,AmbiguateProperties.JSTypeBitSet> relatedBitsets
private final java.util.Set<JSType> invalidatingTypes
static final java.lang.String SKIP_PREFIX
AmbiguateProperties(AbstractCompiler compiler, char[] reservedCharacters)
static AmbiguateProperties makePassForTesting(AbstractCompiler compiler, char[] reservedCharacters)
private void addInvalidatingType(JSType type)
java.util.Map<java.lang.String,java.lang.String> getRenamingMap()
private int getIntForType(JSType type)
public void process(Node externs, Node root)
CompilerPass
process
in interface CompilerPass
externs
- Top of external JS treeroot
- Top of JS treeprivate void computeRelatedTypes(JSType type)
The 'is related to' relationship is best understood graphically. Draw an arrow from each instance type to the prototype of each of its subclass. Draw an arrow from each prototype to its instance type. Draw an arrow from each interface to its implementors. A type is related to another if there is a directed path in the graph from the type to other. Thus, the 'is related to' relationship is reflexive and transitive.
Example with Foo extends Bar which extends Baz and Bar implements I:
Foo -> Bar.prototype -> Bar -> Baz.prototype -> Baz ^ | I
Note that we don't need to correctly handle the relationships between functions, because the function type is invalidating (i.e. its properties won't be ambiguated).
private void addRelatedInstance(FunctionType constructor, AmbiguateProperties.JSTypeBitSet related)
private boolean isInvalidatingType(JSType type)
private AmbiguateProperties.Property getProperty(java.lang.String name)