} else { ImmutableList<TypeDeclarationNode> types = ImmutableList.of(convertTypeNodeAST(child), new TypeDeclarationNode(Token.NULL)); return flatUnionType(types); case "null": return new TypeDeclarationNode(Token.NULL);
LinkedHashMap<String, TypeDeclarationNode> optionalParams, String restName, TypeDeclarationNode restType) { TypeDeclarationNode node = new TypeDeclarationNode(Token.FUNCTION_TYPE, returnType); Preconditions.checkNotNull(requiredParams); Preconditions.checkNotNull(optionalParams); node.addChildToBack(maybeAddType(name, param.getValue())); Node name = IR.name(param.getKey()); name.putBooleanProp(Node.OPT_ES6_TYPED, true); node.addChildToBack(maybeAddType(name, param.getValue())); node.addChildrenToBack(maybeAddType(rest, restType));
/** Helper function to recursively flatten union types. */ void flatten( Iterable<TypeDeclarationNode> types, List<TypeDeclarationNode> result, boolean hasNull) { for (TypeDeclarationNode t : types) { switch (t.getToken()) { case NULL: if (!hasNull) { result.add(new TypeDeclarationNode(Token.NULL)); hasNull = true; } break; case UNION_TYPE: Iterable<TypeDeclarationNode> children = FluentIterable.from(t.children()) .transform(node -> (TypeDeclarationNode) node) .toList(); // We had to invoke .toList() as detachChildren() breaks the Iterable. t.detachChildren(); flatten(children, result, hasNull); break; default: result.add(t); break; } } }
&& (thisTDN == null || thatTDN == null || !thisTDN.isEquivalentTo(thatTDN, compareType, recurse, jsDoc))) { return false;
if (numParams != Iterables.size(type.children()) - 1) { break; Node newNode = type.getFirstChild(); Node nextNode = newNode.getNext(); newNode.detach();
if ((thisTDN != null || thatTDN != null) && (thisTDN == null || thatTDN == null || !thisTDN.isEquivalentTo(thatTDN, compareType, recurse, jsDoc))) { return false;
LinkedHashMap<String, TypeDeclarationNode> optionalParams, String restName, TypeDeclarationNode restType) { TypeDeclarationNode node = new TypeDeclarationNode(Token.FUNCTION_TYPE, returnType); checkNotNull(requiredParams); checkNotNull(optionalParams); node.addChildToBack(maybeAddType(name, param.getValue())); Node name = IR.name(param.getKey()); name.putBooleanProp(Node.OPT_ES6_TYPED, true); node.addChildToBack(maybeAddType(name, param.getValue())); node.addChildToBack(maybeAddType(rest, restType));
/** * Represents a parameterized, or generic, type. * Closure calls this a Type Application and accepts syntax like * {@code {Object.<string, number>}} * * <p>Example: * <pre> * PARAMETERIZED_TYPE * NAMED_TYPE * NAME Object * STRING_TYPE * NUMBER_TYPE * </pre> * @param baseType * @param typeParameters */ public static TypeDeclarationNode parameterizedType( TypeDeclarationNode baseType, Iterable<TypeDeclarationNode> typeParameters) { if (Iterables.isEmpty(typeParameters)) { return baseType; } TypeDeclarationNode node = new TypeDeclarationNode(Token.PARAMETERIZED_TYPE, baseType); for (Node typeParameter : typeParameters) { node.addChildToBack(typeParameter); } return node; }
/** * Represents a structural type. * Closure calls this a Record Type and accepts the syntax * {@code {myNum: number, myObject}} * * <p>Example: * <pre> * RECORD_TYPE * STRING_KEY myNum * NUMBER_TYPE * STRING_KEY myObject * </pre> * @param properties a map from property name to property type * @return a new node representing the record type */ public static TypeDeclarationNode recordType( LinkedHashMap<String, TypeDeclarationNode> properties) { TypeDeclarationNode node = new TypeDeclarationNode(Token.RECORD_TYPE); for (Map.Entry<String, TypeDeclarationNode> prop : properties.entrySet()) { Node stringKey = IR.stringKey(prop.getKey()); node.addChildToBack(stringKey); if (prop.getValue() != null) { stringKey.addChildToFront(prop.getValue()); } } return node; }
/** * Represents a structural type. * Closure calls this a Record Type and accepts the syntax * {@code {myNum: number, myObject}} * * <p>Example: * <pre> * RECORD_TYPE * STRING_KEY myNum * NUMBER_TYPE * STRING_KEY myObject * </pre> * @param properties a map from property name to property type * @return a new node representing the record type */ public static TypeDeclarationNode recordType( LinkedHashMap<String, TypeDeclarationNode> properties) { TypeDeclarationNode node = new TypeDeclarationNode(Token.RECORD_TYPE); for (Map.Entry<String, TypeDeclarationNode> prop : properties.entrySet()) { Node stringKey = IR.stringKey(prop.getKey()); node.addChildToBack(stringKey); if (prop.getValue() != null) { stringKey.addChildToFront(prop.getValue()); } } return node; }
/** * Represents a parameterized, or generic, type. * Closure calls this a Type Application and accepts syntax like * {@code {Object.<string, number>}} * * <p>Example: * <pre> * PARAMETERIZED_TYPE * NAMED_TYPE * NAME Object * STRING_TYPE * NUMBER_TYPE * </pre> * @param baseType * @param typeParameters */ public static TypeDeclarationNode parameterizedType( TypeDeclarationNode baseType, Iterable<TypeDeclarationNode> typeParameters) { if (Iterables.isEmpty(typeParameters)) { return baseType; } TypeDeclarationNode node = new TypeDeclarationNode(Token.PARAMETERIZED_TYPE, baseType); for (Node typeParameter : typeParameters) { node.addChildToBack(typeParameter); } return node; }
/** * Produces a tree structure similar to the Rhino AST of a qualified name * expression, under a top-level NAMED_TYPE node. * * <p>Example: * <pre> * NAMED_TYPE * NAME goog * STRING ui * STRING Window * </pre> */ public static TypeDeclarationNode namedType(Iterable<String> segments) { Iterator<String> segmentsIt = segments.iterator(); Node node = IR.name(segmentsIt.next()); while (segmentsIt.hasNext()) { node = IR.getprop(node, IR.string(segmentsIt.next())); } return new TypeDeclarationNode(Token.NAMED_TYPE, node); }
/** * Represents a union type, which can be one of the given types. * Closure accepts syntax like {@code {(number|boolean)}} * * <p>Example: * <pre> * UNION_TYPE * NUMBER_TYPE * BOOLEAN_TYPE * </pre> * @param options the types which are accepted * @return a new node representing the union type */ public static TypeDeclarationNode unionType(Iterable<TypeDeclarationNode> options) { Preconditions.checkArgument(!Iterables.isEmpty(options), "union must have at least one option"); TypeDeclarationNode node = new TypeDeclarationNode(Token.UNION_TYPE); for (Node option : options) { node.addChildToBack(option); } return node; }
/** * Represents a union type, which can be one of the given types. * Closure accepts syntax like {@code {(number|boolean)}} * * <p>Example: * <pre> * UNION_TYPE * NUMBER_TYPE * BOOLEAN_TYPE * </pre> * @param options the types which are accepted * @return a new node representing the union type */ public static TypeDeclarationNode unionType(Iterable<TypeDeclarationNode> options) { checkArgument(!Iterables.isEmpty(options), "union must have at least one option"); TypeDeclarationNode node = new TypeDeclarationNode(Token.UNION_TYPE); for (Node option : options) { node.addChildToBack(option); } return node; }
/** * Produces a tree structure similar to the Rhino AST of a qualified name * expression, under a top-level NAMED_TYPE node. * * <p>Example: * <pre> * NAMED_TYPE * NAME goog * STRING ui * STRING Window * </pre> */ public static TypeDeclarationNode namedType(Iterable<String> segments) { Iterator<String> segmentsIt = segments.iterator(); Node node = IR.name(segmentsIt.next()); while (segmentsIt.hasNext()) { node = IR.getprop(node, IR.string(segmentsIt.next())); } return new TypeDeclarationNode(Token.NAMED_TYPE, node); }
/** * Represents an array type. In Closure, this is represented by a * {@link #parameterizedType(TypeDeclarationNode, Iterable) parameterized type} of {@code Array} * with {@code elementType} as the sole type parameter. * * <p>Example * <pre> * ARRAY_TYPE * elementType * </pre> */ public static TypeDeclarationNode arrayType(Node elementType) { return new TypeDeclarationNode(Token.ARRAY_TYPE, elementType); }
private Node maybeCreateAnyType(Node n, Node type) { return type == null ? TypeDeclarationsIR.anyType().useSourceInfoIfMissingFrom(n) : type; }
/** * Represents an array type. In Closure, this is represented by a * {@link #parameterizedType(TypeDeclarationNode, Iterable) parameterized type} of {@code Array} * with {@code elementType} as the sole type parameter. * * <p>Example * <pre> * ARRAY_TYPE * elementType * </pre> */ public static TypeDeclarationNode arrayType(Node elementType) { return new TypeDeclarationNode(Token.ARRAY_TYPE, elementType); }
private Node maybeCreateAnyType(Node n, Node type) { return type == null ? TypeDeclarationsIR.anyType().useSourceInfoIfMissingFrom(n) : type; }
Node processTypeQuery(TypeQueryTree tree) { Iterator<String> segmentsIt = tree.segments.iterator(); Node node = newStringNode(Token.NAME, segmentsIt.next()); while (segmentsIt.hasNext()) { node = IR.getprop(node, IR.string(segmentsIt.next())); } return cloneProps(new TypeDeclarationNode(Token.TYPEOF, node)); }