Search in sources :

Example 11 with TypeI

use of com.google.javascript.rhino.TypeI in project closure-compiler by google.

the class Es6TemplateLiterals method visitTaggedTemplateLiteral.

/**
 * Converts tag`a\tb${bar}` to:
 *   // A global (module) scoped variable
 *   var $jscomp$templatelit$0 = ["a\tb"];   // cooked string array
 *   $jscomp$templatelit$0.raw = ["a\\tb"];  // raw string array
 *   ...
 *   // A call to the tagging function
 *   tag($jscomp$templatelit$0, bar);
 *
 *   See template_literal_test.js for more examples.
 *
 * @param n A TAGGED_TEMPLATELIT node
 */
static void visitTaggedTemplateLiteral(NodeTraversal t, Node n, boolean addTypes) {
    TypeIRegistry registry = t.getCompiler().getTypeIRegistry();
    TypeI stringType = createType(addTypes, registry, JSTypeNative.STRING_TYPE);
    TypeI arrayType = createGenericType(addTypes, registry, JSTypeNative.ARRAY_TYPE, stringType);
    TypeI templateArrayType = createType(addTypes, registry, JSTypeNative.I_TEMPLATE_ARRAY_TYPE);
    Node templateLit = n.getLastChild();
    // Prepare the raw and cooked string arrays.
    Node raw = createRawStringArray(templateLit, arrayType, stringType);
    Node cooked = createCookedStringArray(templateLit, templateArrayType, stringType);
    // Specify the type of the first argument to be ITemplateArray.
    JSTypeExpression nonNullSiteObject = new JSTypeExpression(JsDocInfoParser.parseTypeString("!ITemplateArray"), "<Es6TemplateLiterals.java>");
    JSDocInfoBuilder info = new JSDocInfoBuilder(false);
    info.recordType(nonNullSiteObject);
    Node siteObject = withType(IR.cast(cooked, info.build()), templateArrayType);
    // Create a variable representing the template literal.
    Node callsiteId = withType(IR.name(TEMPLATELIT_VAR + t.getCompiler().getUniqueNameIdSupplier().get()), templateArrayType);
    Node var = IR.var(callsiteId, siteObject).useSourceInfoIfMissingFromForTree(n);
    Node script = NodeUtil.getEnclosingScript(n);
    script.addChildToFront(var);
    t.reportCodeChange(var);
    // Define the "raw" property on the introduced variable.
    Node defineRaw = IR.exprResult(withType(IR.assign(withType(IR.getprop(callsiteId.cloneNode(), withType(IR.string("raw"), stringType)), arrayType), raw), arrayType)).useSourceInfoIfMissingFromForTree(n);
    script.addChildAfter(defineRaw, var);
    // Generate the call expression.
    Node call = withType(IR.call(n.removeFirstChild(), callsiteId.cloneNode()), n.getTypeI());
    for (Node child = templateLit.getFirstChild(); child != null; child = child.getNext()) {
        if (!child.isString()) {
            call.addChildToBack(child.removeFirstChild());
        }
    }
    call.useSourceInfoIfMissingFromForTree(templateLit);
    call.putBooleanProp(Node.FREE_CALL, !call.getFirstChild().isGetProp());
    n.replaceWith(call);
    t.reportCodeChange();
}
Also used : TypeI(com.google.javascript.rhino.TypeI) Node(com.google.javascript.rhino.Node) JSTypeExpression(com.google.javascript.rhino.JSTypeExpression) TypeIRegistry(com.google.javascript.rhino.TypeIRegistry) JSDocInfoBuilder(com.google.javascript.rhino.JSDocInfoBuilder)

Example 12 with TypeI

use of com.google.javascript.rhino.TypeI in project closure-compiler by google.

the class AmbiguateProperties method computeRelatedTypes.

/**
 * Adds subtypes - and implementors, in the case of interfaces - of the type
 * to its JSTypeBitSet of related types. Union types are decomposed into their
 * alternative types.
 *
 * <p>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.
 *
 * <p>Example with Foo extends Bar which extends Baz and Bar implements I:
 * <pre>{@code
 * Foo -> Bar.prototype -> Bar -> Baz.prototype -> Baz
 *                          ^
 *                          |
 *                          I
 * }</pre>
 *
 * <p>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 computeRelatedTypes(TypeI type) {
    if (type.isUnionType()) {
        type = type.restrictByNotNullOrUndefined();
        if (type.isUnionType()) {
            for (TypeI alt : type.getUnionMembers()) {
                computeRelatedTypes(alt);
            }
            return;
        }
    }
    if (relatedBitsets.containsKey(type)) {
        // We only need to generate the bit set once.
        return;
    }
    JSTypeBitSet related = new JSTypeBitSet(intForType.size());
    relatedBitsets.put(type, related);
    related.set(getIntForType(type));
    // A prototype is related to its instance.
    if (type.isPrototypeObject()) {
        FunctionTypeI maybeCtor = type.toMaybeObjectType().getOwnerFunction();
        if (maybeCtor.isConstructor() || maybeCtor.isInterface()) {
            addRelatedInstance(maybeCtor, related);
        }
        return;
    }
    // A class/interface is related to its subclasses/implementors.
    FunctionTypeI constructor = type.toMaybeObjectType().getConstructor();
    if (constructor != null) {
        for (FunctionTypeI subType : constructor.getDirectSubTypes()) {
            addRelatedInstance(subType, related);
        }
    }
}
Also used : FunctionTypeI(com.google.javascript.rhino.FunctionTypeI) TypeI(com.google.javascript.rhino.TypeI) ObjectTypeI(com.google.javascript.rhino.ObjectTypeI) FunctionTypeI(com.google.javascript.rhino.FunctionTypeI)

Example 13 with TypeI

use of com.google.javascript.rhino.TypeI in project closure-compiler by google.

the class DisambiguateProperties method recordInterfaces.

/**
 * Records that this property could be referenced from any interface that
 * this type inherits from.
 *
 * If the property p is defined only on a subtype of constructor, then this
 * method has no effect. But we tried modifying getTypeWithProperty to tell us
 * when the returned type is a subtype, and then skip those calls to
 * recordInterface, and there was no speed-up.
 * And it made the code harder to understand, so we don't do it.
 */
private void recordInterfaces(FunctionTypeI constructor, TypeI relatedType, Property p) {
    Iterable<ObjectTypeI> interfaces = ancestorInterfaces.get(constructor);
    if (interfaces == null) {
        interfaces = constructor.getAncestorInterfaces();
        ancestorInterfaces.put(constructor, interfaces);
    }
    for (ObjectTypeI itype : interfaces) {
        TypeI top = getTypeWithProperty(p.name, itype);
        if (top != null) {
            p.addType(itype, relatedType);
        }
        // If this interface invalidated this property, return now.
        if (p.skipRenaming) {
            return;
        }
    }
}
Also used : ObjectTypeI(com.google.javascript.rhino.ObjectTypeI) FunctionTypeI(com.google.javascript.rhino.FunctionTypeI) TypeI(com.google.javascript.rhino.TypeI) ObjectTypeI(com.google.javascript.rhino.ObjectTypeI)

Example 14 with TypeI

use of com.google.javascript.rhino.TypeI in project closure-compiler by google.

the class DisambiguateProperties method getTypesToSkipForType.

/**
 * Returns a set of types that should be skipped given the given type. This is
 * necessary for interfaces, as all super interfaces must also be skipped.
 */
private ImmutableSet<TypeI> getTypesToSkipForType(TypeI type) {
    type = type.restrictByNotNullOrUndefined();
    if (type.isUnionType()) {
        ImmutableSet.Builder<TypeI> types = ImmutableSet.builder();
        types.add(type);
        for (TypeI alt : type.getUnionMembers()) {
            types.addAll(getTypesToSkipForTypeNonUnion(alt));
        }
        return types.build();
    } else if (type.isEnumElement()) {
        return getTypesToSkipForType(type.getEnumeratedTypeOfEnumElement());
    }
    return ImmutableSet.copyOf(getTypesToSkipForTypeNonUnion(type));
}
Also used : ImmutableSet(com.google.common.collect.ImmutableSet) FunctionTypeI(com.google.javascript.rhino.FunctionTypeI) TypeI(com.google.javascript.rhino.TypeI) ObjectTypeI(com.google.javascript.rhino.ObjectTypeI)

Example 15 with TypeI

use of com.google.javascript.rhino.TypeI in project closure-compiler by google.

the class DevirtualizePrototypeMethods method fixFunctionType.

/**
 * Creates a new type based on the original function type by
 * adding the original this pointer type to the beginning of the
 * argument type list and replacing the this pointer type with bottom.
 */
private void fixFunctionType(Node functionNode) {
    TypeI t = functionNode.getTypeI();
    if (t == null) {
        return;
    }
    FunctionTypeI ft = t.toMaybeFunctionType();
    if (ft != null) {
        functionNode.setTypeI(ft.convertMethodToFunction());
    }
}
Also used : TypeI(com.google.javascript.rhino.TypeI) FunctionTypeI(com.google.javascript.rhino.FunctionTypeI) FunctionTypeI(com.google.javascript.rhino.FunctionTypeI)

Aggregations

TypeI (com.google.javascript.rhino.TypeI)37 ObjectTypeI (com.google.javascript.rhino.ObjectTypeI)24 FunctionTypeI (com.google.javascript.rhino.FunctionTypeI)23 Node (com.google.javascript.rhino.Node)10 TypeIRegistry (com.google.javascript.rhino.TypeIRegistry)4 LinkedHashMap (java.util.LinkedHashMap)4 JSType (com.google.javascript.jscomp.newtypes.JSType)3 JSDocInfo (com.google.javascript.rhino.JSDocInfo)2 HashMap (java.util.HashMap)2 HashSet (java.util.HashSet)2 IdentityHashMap (java.util.IdentityHashMap)2 Map (java.util.Map)2 ImmutableMap (com.google.common.collect.ImmutableMap)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 DiGraphNode (com.google.javascript.jscomp.graph.DiGraph.DiGraphNode)1 Visibility (com.google.javascript.rhino.JSDocInfo.Visibility)1 JSDocInfoBuilder (com.google.javascript.rhino.JSDocInfoBuilder)1 JSTypeExpression (com.google.javascript.rhino.JSTypeExpression)1 Token (com.google.javascript.rhino.Token)1 ArrayList (java.util.ArrayList)1