Search in sources :

Example 16 with FlowScope

use of com.google.javascript.jscomp.type.FlowScope in project closure-compiler by google.

the class LinkedFlowScopeTest method testLongChain.

/**
 * Create a long chain of flow scopes.
 */
@Test
public void testLongChain() {
    FlowScope chainA = localEntry;
    FlowScope chainB = localEntry;
    for (int i = 0; i < LONG_CHAIN_LENGTH; i++) {
        localScope.declare("local" + i, null, null, null, true);
        chainA = chainA.inferSlotType("local" + i, i % 2 == 0 ? getNativeNumberType() : getNativeBooleanType());
        chainB = chainB.inferSlotType("local" + i, i % 3 == 0 ? getNativeStringType() : getNativeBooleanType());
    }
    FlowScope joined = join(chainA, chainB);
    for (int i = 0; i < LONG_CHAIN_LENGTH; i++) {
        assertTypeEquals(i % 2 == 0 ? getNativeNumberType() : getNativeBooleanType(), chainA.getSlot("local" + i).getType());
        assertTypeEquals(i % 3 == 0 ? getNativeStringType() : getNativeBooleanType(), chainB.getSlot("local" + i).getType());
        JSType joinedSlotType = joined.getSlot("local" + i).getType();
        if (i % 6 == 0) {
            assertTypeEquals(createUnionType(getNativeStringType(), getNativeNumberType()), joinedSlotType);
        } else if (i % 2 == 0) {
            assertTypeEquals(createUnionType(getNativeNumberType(), getNativeBooleanType()), joinedSlotType);
        } else if (i % 3 == 0) {
            assertTypeEquals(createUnionType(getNativeStringType(), getNativeBooleanType()), joinedSlotType);
        } else {
            assertTypeEquals(getNativeBooleanType(), joinedSlotType);
        }
    }
    assertScopesDiffer(chainA, chainB);
    assertScopesDiffer(chainA, joined);
    assertScopesDiffer(chainB, joined);
}
Also used : JSType(com.google.javascript.rhino.jstype.JSType) FlowScope(com.google.javascript.jscomp.type.FlowScope) Test(org.junit.Test)

Example 17 with FlowScope

use of com.google.javascript.jscomp.type.FlowScope in project closure-compiler by google.

the class LinkedFlowScopeTest method testJoin2.

@Test
public void testJoin2() {
    FlowScope childA = localEntry.inferSlotType("localA", getNativeStringType());
    FlowScope childB = localEntry.inferSlotType("globalB", getNativeBooleanType());
    assertTypeEquals(getNativeStringType(), childA.getSlot("localA").getType());
    assertTypeEquals(getNativeBooleanType(), childB.getSlot("globalB").getType());
    assertThat(childB.getSlot("localB").getType()).isNull();
    FlowScope joined = join(childB, childA);
    assertTypeEquals(getNativeStringType(), joined.getSlot("localA").getType());
    assertTypeEquals(getNativeBooleanType(), joined.getSlot("globalB").getType());
    joined = join(childA, childB);
    assertTypeEquals(getNativeStringType(), joined.getSlot("localA").getType());
    assertTypeEquals(getNativeBooleanType(), joined.getSlot("globalB").getType());
    assertWithMessage("Join should be symmetric").that(join(childA, childB)).isEqualTo(join(childB, childA));
}
Also used : FlowScope(com.google.javascript.jscomp.type.FlowScope) Test(org.junit.Test)

Example 18 with FlowScope

use of com.google.javascript.jscomp.type.FlowScope in project closure-compiler by google.

the class LinkedFlowScopeTest method testDiffer1.

@Test
public void testDiffer1() {
    FlowScope childA = localEntry.inferSlotType("localB", getNativeNumberType());
    FlowScope childAB = childA.inferSlotType("localB", getNativeStringType());
    FlowScope childABC = childAB.inferSlotType("localA", getNativeBooleanType());
    FlowScope childB = childAB.inferSlotType("localB", getNativeStringType());
    FlowScope childBC = childB.inferSlotType("localA", getNativeNoType());
    assertScopesSame(childAB, childB);
    assertScopesDiffer(childABC, childBC);
    assertScopesDiffer(childABC, childB);
    assertScopesDiffer(childAB, childBC);
    assertScopesDiffer(childA, childAB);
    assertScopesDiffer(childA, childABC);
    assertScopesDiffer(childA, childB);
    assertScopesDiffer(childA, childBC);
}
Also used : FlowScope(com.google.javascript.jscomp.type.FlowScope) Test(org.junit.Test)

Example 19 with FlowScope

use of com.google.javascript.jscomp.type.FlowScope in project closure-compiler by google.

the class TypeInferenceTest method parseAndRunTypeInference.

@SuppressWarnings({ "MustBeClosedChecker" })
private void parseAndRunTypeInference(Node root, Node cfgRoot) {
    this.closer.close();
    TypedScopeCreator scopeCreator = new TypedScopeCreator(compiler);
    TypedScope assumedScope;
    try (JSTypeResolver.Closer closer = this.registry.getResolver().openForDefinition()) {
        // Create the scope with the assumptions.
        // Also populate a map allowing us to look up labeled statements later.
        labeledStatementMap = new HashMap<>();
        NodeTraversal.builder().setCompiler(compiler).setCallback(new AbstractScopedCallback() {

            @Override
            public void enterScope(NodeTraversal t) {
                t.getTypedScope();
            }

            @Override
            public void visit(NodeTraversal t, Node n, Node parent) {
                TypedScope scope = t.getTypedScope();
                if (parent != null && parent.isLabel() && !n.isLabelName()) {
                    // First child of a LABEL is a LABEL_NAME, n is the second child.
                    Node labelNameNode = checkNotNull(n.getPrevious(), n);
                    checkState(labelNameNode.isLabelName(), labelNameNode);
                    String labelName = labelNameNode.getString();
                    assertWithMessage("Duplicate label name: %s", labelName).that(labeledStatementMap).doesNotContainKey(labelName);
                    labeledStatementMap.put(labelName, new LabeledStatement(n, scope));
                }
            }
        }).setScopeCreator(scopeCreator).traverse(root);
        assumedScope = scopeCreator.createScope(cfgRoot);
        for (Map.Entry<String, JSType> entry : assumptions.entrySet()) {
            assumedScope.declare(entry.getKey(), null, entry.getValue(), null, false);
        }
        scopeCreator.resolveWeakImportsPreResolution();
    }
    scopeCreator.finishAndFreeze();
    // Create the control graph.
    ControlFlowAnalysis cfa = new ControlFlowAnalysis(compiler, false, true);
    cfa.process(null, cfgRoot);
    ControlFlowGraph<Node> cfg = cfa.getCfg();
    // Create a simple reverse abstract interpreter.
    ReverseAbstractInterpreter rai = compiler.getReverseAbstractInterpreter();
    // Do the type inference by data-flow analysis.
    TypeInference dfa = new TypeInference(compiler, cfg, rai, assumedScope, scopeCreator, ASSERTION_FUNCTION_MAP);
    dfa.analyze();
    // Get the scope of the implicit return.
    LinearFlowState<FlowScope> rtnState = cfg.getImplicitReturn().getAnnotation();
    if (cfgRoot.isFunction()) {
        // Reset the flow scope's syntactic scope to the function block, rather than the function
        // node
        // itself.  This allows pulling out local vars from the function by name to verify their
        // types.
        returnScope = rtnState.getIn().withSyntacticScope(scopeCreator.createScope(cfgRoot.getLastChild()));
    } else {
        returnScope = rtnState.getIn();
    }
    this.closer = this.registry.getResolver().openForDefinition();
}
Also used : ReverseAbstractInterpreter(com.google.javascript.jscomp.type.ReverseAbstractInterpreter) JSType(com.google.javascript.rhino.jstype.JSType) StaticTypedScope(com.google.javascript.rhino.jstype.StaticTypedScope) Node(com.google.javascript.rhino.Node) NodeSubject.assertNode(com.google.javascript.rhino.testing.NodeSubject.assertNode) AbstractScopedCallback(com.google.javascript.jscomp.NodeTraversal.AbstractScopedCallback) JSTypeResolver(com.google.javascript.rhino.jstype.JSTypeResolver) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) HashMap(java.util.HashMap) FlowScope(com.google.javascript.jscomp.type.FlowScope)

Example 20 with FlowScope

use of com.google.javascript.jscomp.type.FlowScope in project closure-compiler by google.

the class SemanticReverseAbstractInterpreterTest method testNegatedNameCondition.

/**
 * Tests reverse interpretation of a NOT(NAME) expression.
 */
@Test
public void testNegatedNameCondition() {
    FlowScope[] blind = newScope();
    Node a = createVar(blind, "a", createNullableType(getNativeStringType()));
    Node condition = new Node(Token.NOT);
    condition.addChildToBack(a);
    // true outcome.
    FlowScope informedTrue = interpreter.getPreciserScopeKnowingConditionOutcome(condition, blind[0], Outcome.TRUE);
    assertTypeEquals(createNullableType(getNativeStringType()), getVarType(informedTrue, "a"));
    // false outcome.
    FlowScope informedFalse = interpreter.getPreciserScopeKnowingConditionOutcome(condition, blind[0], Outcome.FALSE);
    assertTypeEquals(getNativeStringType(), getVarType(informedFalse, "a"));
}
Also used : Node(com.google.javascript.rhino.Node) FlowScope(com.google.javascript.jscomp.type.FlowScope) Test(org.junit.Test)

Aggregations

FlowScope (com.google.javascript.jscomp.type.FlowScope)60 Node (com.google.javascript.rhino.Node)20 Test (org.junit.Test)16 JSType (com.google.javascript.rhino.jstype.JSType)12 Token (com.google.javascript.rhino.Token)3 ImmutableMap (com.google.common.collect.ImmutableMap)1 CheckReturnValue (com.google.errorprone.annotations.CheckReturnValue)1 Branch (com.google.javascript.jscomp.ControlFlowGraph.Branch)1 AbstractScopedCallback (com.google.javascript.jscomp.NodeTraversal.AbstractScopedCallback)1 DiGraphEdge (com.google.javascript.jscomp.graph.DiGraph.DiGraphEdge)1 Module (com.google.javascript.jscomp.modules.Module)1 ClosureReverseAbstractInterpreter (com.google.javascript.jscomp.type.ClosureReverseAbstractInterpreter)1 ReverseAbstractInterpreter (com.google.javascript.jscomp.type.ReverseAbstractInterpreter)1 JSTypeResolver (com.google.javascript.rhino.jstype.JSTypeResolver)1 ObjectType (com.google.javascript.rhino.jstype.ObjectType)1 StaticTypedScope (com.google.javascript.rhino.jstype.StaticTypedScope)1 TemplateType (com.google.javascript.rhino.jstype.TemplateType)1 NodeSubject.assertNode (com.google.javascript.rhino.testing.NodeSubject.assertNode)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1