Search in sources :

Example 1 with Color

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.");
    }
}
Also used : DefaultNameGenerator(com.google.javascript.jscomp.DefaultNameGenerator) GatherGetterAndSetterProperties(com.google.javascript.jscomp.GatherGetterAndSetterProperties) SubGraph(com.google.javascript.jscomp.graph.SubGraph) GraphNode(com.google.javascript.jscomp.graph.GraphNode) HashMap(java.util.HashMap) NameGenerator(com.google.javascript.jscomp.NameGenerator) ArrayList(java.util.ArrayList) Level(java.util.logging.Level) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) Map(java.util.Map) StandardColors(com.google.javascript.jscomp.colors.StandardColors) CompilerPass(com.google.javascript.jscomp.CompilerPass) AdjacencyGraph(com.google.javascript.jscomp.graph.AdjacencyGraph) DiGraph(com.google.javascript.jscomp.graph.DiGraph) FixedPointGraphTraversal(com.google.javascript.jscomp.graph.FixedPointGraphTraversal) Node(com.google.javascript.rhino.Node) GreedyGraphColoring(com.google.javascript.jscomp.graph.GraphColoring.GreedyGraphColoring) LowestCommonAncestorFinder(com.google.javascript.jscomp.graph.LowestCommonAncestorFinder) ImmutableSet(com.google.common.collect.ImmutableSet) IdentityHashMap(java.util.IdentityHashMap) NodeTraversal(com.google.javascript.jscomp.NodeTraversal) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) Set(java.util.Set) ColorRegistry(com.google.javascript.jscomp.colors.ColorRegistry) Logger(java.util.logging.Logger) Preconditions.checkState(com.google.common.base.Preconditions.checkState) AbstractPostOrderCallback(com.google.javascript.jscomp.NodeTraversal.AbstractPostOrderCallback) NodeUtil(com.google.javascript.jscomp.NodeUtil) List(java.util.List) Color(com.google.javascript.jscomp.colors.Color) Annotation(com.google.javascript.jscomp.graph.Annotation) AbstractCompiler(com.google.javascript.jscomp.AbstractCompiler) GraphColoring(com.google.javascript.jscomp.graph.GraphColoring) BitSet(java.util.BitSet) Comparator(java.util.Comparator) LowestCommonAncestorFinder(com.google.javascript.jscomp.graph.LowestCommonAncestorFinder) GraphNode(com.google.javascript.jscomp.graph.GraphNode) Node(com.google.javascript.rhino.Node) ArrayList(java.util.ArrayList) DefaultNameGenerator(com.google.javascript.jscomp.DefaultNameGenerator) DefaultNameGenerator(com.google.javascript.jscomp.DefaultNameGenerator) NameGenerator(com.google.javascript.jscomp.NameGenerator) ImmutableSet(com.google.common.collect.ImmutableSet) GreedyGraphColoring(com.google.javascript.jscomp.graph.GraphColoring.GreedyGraphColoring)

Example 2 with Color

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);
}
Also used : ImmutableSet(com.google.common.collect.ImmutableSet) Color(com.google.javascript.jscomp.colors.Color)

Example 3 with Color

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);
}
Also used : Node(com.google.javascript.rhino.Node) Color(com.google.javascript.jscomp.colors.Color)

Example 4 with Color

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);
}
Also used : Node(com.google.javascript.rhino.Node) Color(com.google.javascript.jscomp.colors.Color)

Example 5 with Color

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);
}
Also used : Node(com.google.javascript.rhino.Node) NodeSubject.assertNode(com.google.javascript.rhino.testing.NodeSubject.assertNode) Color(com.google.javascript.jscomp.colors.Color) Test(org.junit.Test)

Aggregations

Color (com.google.javascript.jscomp.colors.Color)57 Node (com.google.javascript.rhino.Node)37 Test (org.junit.Test)37 NodeSubject.assertNode (com.google.javascript.rhino.testing.NodeSubject.assertNode)29 JSType (com.google.javascript.rhino.jstype.JSType)6 TestExternsBuilder (com.google.javascript.jscomp.testing.TestExternsBuilder)5 ImmutableSet (com.google.common.collect.ImmutableSet)2 CodeSubTree (com.google.javascript.jscomp.testing.CodeSubTree)2 ArrayList (java.util.ArrayList)2 LinkedHashMap (java.util.LinkedHashMap)2 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)1 Preconditions.checkNotNull (com.google.common.base.Preconditions.checkNotNull)1 Preconditions.checkState (com.google.common.base.Preconditions.checkState)1 AbstractCompiler (com.google.javascript.jscomp.AbstractCompiler)1 CompilerPass (com.google.javascript.jscomp.CompilerPass)1 DefaultNameGenerator (com.google.javascript.jscomp.DefaultNameGenerator)1 GatherGetterAndSetterProperties (com.google.javascript.jscomp.GatherGetterAndSetterProperties)1 NameGenerator (com.google.javascript.jscomp.NameGenerator)1 NodeTraversal (com.google.javascript.jscomp.NodeTraversal)1 AbstractPostOrderCallback (com.google.javascript.jscomp.NodeTraversal.AbstractPostOrderCallback)1