use of com.google.javascript.jscomp.colors.Color in project closure-compiler by google.
the class AmbiguateProperties method process.
@Override
public void process(Node externs, Node root) {
this.graphNodeFactory = ColorGraphNodeFactory.createFactory(this.colorRegistry);
// Find all property references and record the types on which they occur.
// Populate stringNodesToRename, propertyMap, quotedNames.
NodeTraversal.traverse(compiler, root, new ProcessPropertiesAndConstructors());
ColorGraphBuilder graphBuilder = new ColorGraphBuilder(graphNodeFactory, LowestCommonAncestorFinder::new, this.colorRegistry);
graphBuilder.addAll(graphNodeFactory.getAllKnownTypes());
DiGraph<ColorGraphNode, Object> colorGraph = graphBuilder.build();
for (ColorGraphNode node : graphNodeFactory.getAllKnownTypes()) {
// Init subtyping as reflexive.
node.getSubtypeIndices().set(node.getIndex());
}
FixedPointGraphTraversal.<ColorGraphNode, Object>newReverseTraversal((subtype, e, supertype) -> {
/**
* Cheap path for when we're sure there's going to be a change.
*
* <p>Since bits only ever turn on, using more bits means there are definitely more
* elements. This prevents of from needing to check cardinality or equality, which
* would otherwise dominate the cost of computing the fixed point.
*
* <p>We're guaranteed to converge because the sizes will be euqal after the OR
* operation.
*/
if (subtype.getSubtypeIndices().size() > supertype.getSubtypeIndices().size()) {
supertype.getSubtypeIndices().or(subtype.getSubtypeIndices());
return true;
}
int startSize = supertype.getSubtypeIndices().cardinality();
supertype.getSubtypeIndices().or(subtype.getSubtypeIndices());
return supertype.getSubtypeIndices().cardinality() > startSize;
}).computeFixedPoint(colorGraph);
// Fill in all transitive edges in subtyping graph per property
for (Property prop : propertyMap.values()) {
if (prop.relatedColorsSeeds == null) {
continue;
}
for (ColorGraphNode color : prop.relatedColorsSeeds.keySet()) {
prop.relatedColors.or(color.getSubtypeIndices());
}
prop.relatedColorsSeeds = null;
}
ImmutableSet.Builder<String> reservedNames = ImmutableSet.<String>builder().addAll(externedNames).addAll(quotedNames);
int numRenamedPropertyNames = 0;
int numSkippedPropertyNames = 0;
ArrayList<PropertyGraphNode> nodes = new ArrayList<>(propertyMap.size());
for (Property prop : propertyMap.values()) {
if (prop.skipAmbiguating) {
++numSkippedPropertyNames;
reservedNames.add(prop.oldName);
} else {
++numRenamedPropertyNames;
nodes.add(new PropertyGraphNode(prop));
}
}
PropertyGraph propertyGraph = new PropertyGraph(nodes);
GraphColoring<Property, Void> coloring = new GreedyGraphColoring<>(propertyGraph, FREQUENCY_COMPARATOR);
int numNewPropertyNames = coloring.color();
// Generate new names for the properties that will be renamed.
NameGenerator nameGen = new DefaultNameGenerator(reservedNames.build(), "", reservedFirstCharacters, reservedNonFirstCharacters);
String[] colorMap = new String[numNewPropertyNames];
for (int i = 0; i < numNewPropertyNames; ++i) {
colorMap[i] = nameGen.generateNextName();
}
// Translate the color of each Property instance to a name.
for (PropertyGraphNode node : propertyGraph.getNodes()) {
node.getValue().newName = colorMap[node.getAnnotation().hashCode()];
if (renamingMap != null) {
renamingMap.put(node.getValue().oldName, node.getValue().newName);
}
}
// Actually assign the new names to the relevant STRING nodes in the AST.
for (Node n : stringNodesToRename) {
String oldName = n.getString();
Property p = propertyMap.get(oldName);
if (p != null && p.newName != null) {
checkState(oldName.equals(p.oldName));
if (!p.newName.equals(oldName)) {
n.setString(p.newName);
compiler.reportChangeToEnclosingScope(n);
}
}
}
// We may have renamed getter / setter properties.
// TODO(b/161947315): this shouldn't be the responsibility of AmbiguateProperties
GatherGetterAndSetterProperties.update(compiler, externs, root);
if (logger.isLoggable(Level.FINE)) {
logger.fine("Collapsed " + numRenamedPropertyNames + " properties into " + numNewPropertyNames + " and skipped renaming " + numSkippedPropertyNames + " properties.");
}
}
use of com.google.javascript.jscomp.colors.Color in project closure-compiler by google.
the class ColorFindPropertyReferences method handleClass.
private void handleClass(Node classNode) {
Color classType = classNode.getColor();
this.traverseObjectlitLike(NodeUtil.getClassMembers(classNode), (m) -> {
if (m.isStaticMember()) {
return classType;
} else if (m.isMemberFieldDef()) {
ImmutableSet<Color> classInstanceType = classType.getInstanceColors();
return classInstanceType.isEmpty() ? StandardColors.UNKNOWN : Color.createUnion(classInstanceType);
} else {
checkState(m.isMemberFunctionDef() || m.isGetterDef() || m.isSetterDef(), m);
ImmutableSet<Color> classPrototypeType = classType.getPrototypes();
return classPrototypeType.isEmpty() ? StandardColors.UNKNOWN : Color.createUnion(classPrototypeType);
}
});
colorGraphNodeFactory.createNode(classType);
}
use of com.google.javascript.jscomp.colors.Color in project closure-compiler by google.
the class ColorFindPropertyReferences method handleObjectDefineProperties.
private void handleObjectDefineProperties(Node call) {
Node typeObj = call.getSecondChild();
Node objectLiteral = typeObj.getNext();
if (!objectLiteral.isObjectLit()) {
return;
}
Color type = typeObj.getColor();
this.traverseObjectlitLike(objectLiteral, (m) -> type);
}
use of com.google.javascript.jscomp.colors.Color in project closure-compiler by google.
the class ColorFindPropertyReferences method handlePropertyReflectorCall.
private void handlePropertyReflectorCall(Node call) {
Node name = call.getSecondChild();
if (name == null || !name.isStringLit()) {
return;
}
Node obj = name.getNext();
Color objColor = (obj == null) ? null : obj.getColor();
this.registerPropertyUse(name, objColor);
}
use of com.google.javascript.jscomp.colors.Color in project closure-compiler by google.
the class AstFactoryTest method createThisForEs6ClassMember_colors.
@Test
public void createThisForEs6ClassMember_colors() {
AstFactory astFactory = createTestAstFactoryWithColors();
Node root = parseAndAddColors(lines(//
"class C {", " method() {}", "}", ""));
Node classNode = // script
root.getFirstChild().getFirstChild();
Node memberDef = classNode.getLastChild().getFirstChild();
Color instanceType = Color.createUnion(classNode.getColor().getInstanceColors());
Node thisAlias = astFactory.createThisForEs6ClassMember(memberDef);
assertNode(thisAlias).hasType(Token.THIS);
assertNode(thisAlias).hasColorThat().isEqualTo(instanceType);
}
Aggregations