Search in sources :

Example 1 with Ref

use of com.google.javascript.jscomp.GlobalNamespace.Ref in project closure-compiler by google.

the class PolymerBehaviorExtractor method extractBehaviors.

/**
 * Extracts all Behaviors from an array literal, recursively. Entries in the array can be
 * object literals or array literals (of other behaviors). Behavior names must be
 * global, fully qualified names.
 * @see https://github.com/Polymer/polymer/blob/0.8-preview/PRIMER.md#behaviors
 * @return A list of all {@code BehaviorDefinitions} in the array.
 */
ImmutableList<BehaviorDefinition> extractBehaviors(Node behaviorArray) {
    if (behaviorArray == null) {
        return ImmutableList.of();
    }
    if (!behaviorArray.isArrayLit()) {
        compiler.report(JSError.make(behaviorArray, PolymerPassErrors.POLYMER_INVALID_BEHAVIOR_ARRAY));
        return ImmutableList.of();
    }
    ImmutableList.Builder<BehaviorDefinition> behaviors = ImmutableList.builder();
    for (Node behaviorName : behaviorArray.children()) {
        if (behaviorName.isObjectLit()) {
            PolymerPassStaticUtils.switchDollarSignPropsToBrackets(behaviorName, compiler);
            PolymerPassStaticUtils.quoteListenerAndHostAttributeKeys(behaviorName, compiler);
            if (NodeUtil.getFirstPropMatchingKey(behaviorName, "is") != null) {
                compiler.report(JSError.make(behaviorName, PolymerPassErrors.POLYMER_INVALID_BEHAVIOR));
            }
            behaviors.add(new BehaviorDefinition(PolymerPassStaticUtils.extractProperties(behaviorName, PolymerClassDefinition.DefinitionType.ObjectLiteral, compiler), getBehaviorFunctionsToCopy(behaviorName), getNonPropertyMembersToCopy(behaviorName), !NodeUtil.isInFunction(behaviorName), (FeatureSet) NodeUtil.getEnclosingScript(behaviorName).getProp(Node.FEATURE_SET)));
            continue;
        }
        Name behaviorGlobalName = globalNames.getSlot(behaviorName.getQualifiedName());
        boolean isGlobalDeclaration = true;
        if (behaviorGlobalName == null) {
            compiler.report(JSError.make(behaviorName, PolymerPassErrors.POLYMER_UNQUALIFIED_BEHAVIOR));
            continue;
        }
        Ref behaviorDeclaration = behaviorGlobalName.getDeclaration();
        // Use any set as a backup declaration, even if it's local.
        if (behaviorDeclaration == null) {
            List<Ref> behaviorRefs = behaviorGlobalName.getRefs();
            for (Ref ref : behaviorRefs) {
                if (ref.isSet()) {
                    isGlobalDeclaration = false;
                    behaviorDeclaration = ref;
                    break;
                }
            }
        }
        if (behaviorDeclaration == null) {
            compiler.report(JSError.make(behaviorName, PolymerPassErrors.POLYMER_UNQUALIFIED_BEHAVIOR));
            continue;
        }
        Node behaviorDeclarationNode = behaviorDeclaration.getNode();
        JSDocInfo behaviorInfo = NodeUtil.getBestJSDocInfo(behaviorDeclarationNode);
        if (behaviorInfo == null || !behaviorInfo.isPolymerBehavior()) {
            compiler.report(JSError.make(behaviorDeclarationNode, PolymerPassErrors.POLYMER_UNANNOTATED_BEHAVIOR));
        }
        Node behaviorValue = NodeUtil.getRValueOfLValue(behaviorDeclarationNode);
        if (behaviorValue == null) {
            compiler.report(JSError.make(behaviorName, PolymerPassErrors.POLYMER_UNQUALIFIED_BEHAVIOR));
        } else if (behaviorValue.isArrayLit()) {
            // Individual behaviors can also be arrays of behaviors. Parse them recursively.
            behaviors.addAll(extractBehaviors(behaviorValue));
        } else if (behaviorValue.isObjectLit()) {
            PolymerPassStaticUtils.switchDollarSignPropsToBrackets(behaviorValue, compiler);
            PolymerPassStaticUtils.quoteListenerAndHostAttributeKeys(behaviorValue, compiler);
            if (NodeUtil.getFirstPropMatchingKey(behaviorValue, "is") != null) {
                compiler.report(JSError.make(behaviorValue, PolymerPassErrors.POLYMER_INVALID_BEHAVIOR));
            }
            behaviors.add(new BehaviorDefinition(PolymerPassStaticUtils.extractProperties(behaviorValue, PolymerClassDefinition.DefinitionType.ObjectLiteral, compiler), getBehaviorFunctionsToCopy(behaviorValue), getNonPropertyMembersToCopy(behaviorValue), isGlobalDeclaration, (FeatureSet) NodeUtil.getEnclosingScript(behaviorValue).getProp(Node.FEATURE_SET)));
        } else {
            compiler.report(JSError.make(behaviorName, PolymerPassErrors.POLYMER_UNQUALIFIED_BEHAVIOR));
        }
    }
    return behaviors.build();
}
Also used : Ref(com.google.javascript.jscomp.GlobalNamespace.Ref) ImmutableList(com.google.common.collect.ImmutableList) Node(com.google.javascript.rhino.Node) FeatureSet(com.google.javascript.jscomp.parsing.parser.FeatureSet) JSDocInfo(com.google.javascript.rhino.JSDocInfo) Name(com.google.javascript.jscomp.GlobalNamespace.Name)

Example 2 with Ref

use of com.google.javascript.jscomp.GlobalNamespace.Ref in project closure-compiler by google.

the class GlobalNamespaceTest method testRemoveDeclaration1.

public void testRemoveDeclaration1() {
    Name n = new Name("a", null, false);
    Ref set1 = createNodelessRef(Ref.Type.SET_FROM_GLOBAL);
    Ref set2 = createNodelessRef(Ref.Type.SET_FROM_GLOBAL);
    n.addRef(set1);
    n.addRef(set2);
    assertEquals(set1, n.getDeclaration());
    assertEquals(2, n.globalSets);
    assertThat(n.getRefs()).hasSize(2);
    n.removeRef(set1);
    assertEquals(set2, n.getDeclaration());
    assertEquals(1, n.globalSets);
    assertThat(n.getRefs()).hasSize(1);
}
Also used : Ref(com.google.javascript.jscomp.GlobalNamespace.Ref) Name(com.google.javascript.jscomp.GlobalNamespace.Name)

Example 3 with Ref

use of com.google.javascript.jscomp.GlobalNamespace.Ref in project closure-compiler by google.

the class GlobalNamespaceTest method testRemoveDeclaration2.

public void testRemoveDeclaration2() {
    Name n = new Name("a", null, false);
    Ref set1 = createNodelessRef(Ref.Type.SET_FROM_GLOBAL);
    Ref set2 = createNodelessRef(Ref.Type.SET_FROM_LOCAL);
    n.addRef(set1);
    n.addRef(set2);
    assertEquals(set1, n.getDeclaration());
    assertEquals(1, n.globalSets);
    assertEquals(1, n.localSets);
    assertThat(n.getRefs()).hasSize(2);
    n.removeRef(set1);
    assertNull(n.getDeclaration());
    assertEquals(0, n.globalSets);
}
Also used : Ref(com.google.javascript.jscomp.GlobalNamespace.Ref) Name(com.google.javascript.jscomp.GlobalNamespace.Name)

Example 4 with Ref

use of com.google.javascript.jscomp.GlobalNamespace.Ref in project closure-compiler by google.

the class ProcessDefines method collectDefines.

/**
 * Finds all defines, and creates a {@link DefineInfo} data structure for
 * each one.
 * @return A map of {@link DefineInfo} structures, keyed by name.
 */
Map<String, DefineInfo> collectDefines(Node externs, Node root) {
    if (namespace == null) {
        namespace = new GlobalNamespace(compiler, externs, root);
    }
    // Find all the global names with a @define annotation
    List<Name> allDefines = new ArrayList<>();
    for (Name name : namespace.getNameIndex().values()) {
        Ref decl = name.getDeclaration();
        if (name.docInfo != null && name.docInfo.isDefine()) {
            // so we look for the JSDoc instead of the inferred type.
            if (isValidDefineType(name.docInfo.getType())) {
                allDefines.add(name);
            } else {
                JSError error = JSError.make(decl.node, INVALID_DEFINE_TYPE_ERROR);
                compiler.report(error);
            }
        } else {
            for (Ref ref : name.getRefs()) {
                if (ref == decl) {
                    // Declarations were handled above.
                    continue;
                }
                Node n = ref.node;
                Node parent = ref.node.getParent();
                JSDocInfo info = n.getJSDocInfo();
                if (info == null && parent.isVar() && parent.hasOneChild()) {
                    info = parent.getJSDocInfo();
                }
                if (info != null && info.isDefine()) {
                    allDefines.add(name);
                    break;
                }
            }
        }
    }
    CollectDefines pass = new CollectDefines(compiler, allDefines);
    NodeTraversal.traverseRootsEs6(compiler, pass, externs, root);
    return pass.getAllDefines();
}
Also used : Ref(com.google.javascript.jscomp.GlobalNamespace.Ref) Node(com.google.javascript.rhino.Node) ArrayList(java.util.ArrayList) JSDocInfo(com.google.javascript.rhino.JSDocInfo) Name(com.google.javascript.jscomp.GlobalNamespace.Name)

Example 5 with Ref

use of com.google.javascript.jscomp.GlobalNamespace.Ref in project closure-compiler by google.

the class CheckGlobalNames method validateName.

private void validateName(Name name, boolean isDefined) {
    // If the name is not defined, emit warnings for each reference. While
    // we're looking through each reference, check all the module dependencies.
    Ref declaration = name.getDeclaration();
    Name parent = name.parent;
    JSModuleGraph moduleGraph = compiler.getModuleGraph();
    for (Ref ref : name.getRefs()) {
        // Don't worry about global exprs.
        boolean isGlobalExpr = ref.getNode().getParent().isExprResult();
        if (!isDefined && !isTypedef(ref)) {
            if (!isGlobalExpr) {
                reportRefToUndefinedName(name, ref);
            }
        } else if (declaration != null && ref.getModule() != declaration.getModule() && !moduleGraph.dependsOn(ref.getModule(), declaration.getModule())) {
            reportBadModuleReference(name, ref);
        } else {
            // Check for late references.
            if (ref.scope.getClosestHoistScope().isGlobal()) {
                // Prototype references are special, because in our reference graph,
                // A.prototype counts as a reference to A.
                boolean isPrototypeGet = (ref.type == Ref.Type.PROTOTYPE_GET);
                Name owner = isPrototypeGet ? name : parent;
                boolean singleGlobalParentDecl = owner != null && owner.getDeclaration() != null && owner.localSets == 0;
                if (singleGlobalParentDecl && owner.getDeclaration().preOrderIndex > ref.preOrderIndex) {
                    String refName = isPrototypeGet ? name.getFullName() + ".prototype" : name.getFullName();
                    compiler.report(JSError.make(ref.node, NAME_DEFINED_LATE_WARNING, refName, owner.getFullName(), owner.getDeclaration().getSourceFile().getName(), String.valueOf(owner.getDeclaration().node.getLineno())));
                }
            }
        }
    }
}
Also used : Ref(com.google.javascript.jscomp.GlobalNamespace.Ref) Name(com.google.javascript.jscomp.GlobalNamespace.Name)

Aggregations

Ref (com.google.javascript.jscomp.GlobalNamespace.Ref)34 Name (com.google.javascript.jscomp.GlobalNamespace.Name)25 Node (com.google.javascript.rhino.Node)24 Test (org.junit.Test)13 NodeSubject.assertNode (com.google.javascript.rhino.testing.NodeSubject.assertNode)9 JSDocInfo (com.google.javascript.rhino.JSDocInfo)7 AstChange (com.google.javascript.jscomp.GlobalNamespace.AstChange)4 ArrayList (java.util.ArrayList)3 LinkedHashSet (java.util.LinkedHashSet)3 JSTypeExpression (com.google.javascript.rhino.JSTypeExpression)2 JSType (com.google.javascript.rhino.jstype.JSType)2 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 Module (com.google.javascript.jscomp.modules.Module)1 FeatureSet (com.google.javascript.jscomp.parsing.parser.FeatureSet)1 QualifiedName (com.google.javascript.rhino.QualifiedName)1 Nullable (javax.annotation.Nullable)1