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();
}
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);
}
}
}
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;
}
}
}
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));
}
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());
}
}
Aggregations