All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.javascript.rhino.TypeDeclarationsIR Maven / Gradle / Ivy

/*
 *
 * ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Rhino code, released
 * May 6, 1999.
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1997-1999
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   Michael Zhou
 *
 * Alternatively, the contents of this file may be used under the terms of
 * the GNU General Public License Version 2 or later (the "GPL"), in which
 * case the provisions of the GPL are applicable instead of those above. If
 * you wish to allow use of your version of this file only under the terms of
 * the GPL and not to allow others to use your version of this file under the
 * MPL, indicate your decision by deleting the provisions above and replacing
 * them with the notice and other provisions required by the GPL. If you do
 * not delete the provisions above, a recipient may use your version of this
 * file under either the MPL or the GPL.
 *
 * ***** END LICENSE BLOCK ***** */

package com.google.javascript.rhino;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import com.google.javascript.rhino.Node.TypeDeclarationNode;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * An AST construction helper class for TypeDeclarationNode
 * @author [email protected] (Alex Eagle)
 * @author [email protected] (Michael Zhou)
 */
public class TypeDeclarationsIR {

  /**
   * @return a new node representing the string built-in type.
   */
  public static TypeDeclarationNode stringType() {
    return new TypeDeclarationNode(Token.STRING_TYPE);
  }

  /**
   * @return a new node representing the number built-in type.
   */
  public static TypeDeclarationNode numberType() {
    return new TypeDeclarationNode(Token.NUMBER_TYPE);
  }

  /**
   * @return a new node representing the boolean built-in type.
   */
  public static TypeDeclarationNode booleanType() {
    return new TypeDeclarationNode(Token.BOOLEAN_TYPE);
  }

  /**
   * Equivalent to the UNKNOWN type in Closure, expressed with {@code {?}}
   * @return a new node representing any type, without type checking.
   */
  public static TypeDeclarationNode anyType() {
    return new TypeDeclarationNode(Token.ANY_TYPE);
  }

  /**
   * @return a new node representing the Void type as defined by TypeScript.
   */
  public static TypeDeclarationNode voidType() {
    return new TypeDeclarationNode(Token.VOID_TYPE);
  }

  /**
   * @return a new node representing the Undefined type as defined by TypeScript.
   */
  public static TypeDeclarationNode undefinedType() {
    return new TypeDeclarationNode(Token.UNDEFINED_TYPE);
  }

  /**
   * Splits a '.' separated qualified name into a tree of type segments.
   *
   * @param typeName a qualified name such as "goog.ui.Window"
   * @return a new node representing the type
   * @see #namedType(Iterable)
   */
  public static TypeDeclarationNode namedType(String typeName) {
    return namedType(Splitter.on('.').split(typeName));
  }

  /**
   * Produces a tree structure similar to the Rhino AST of a qualified name
   * expression, under a top-level NAMED_TYPE node.
   *
   * 

Example: *

   * NAMED_TYPE
   *   NAME goog
   *     STRING ui
   *       STRING Window
   * 
*/ public static TypeDeclarationNode namedType(Iterable segments) { Iterator 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 structural type. * Closure calls this a Record Type and accepts the syntax * {@code {myNum: number, myObject}} * *

Example: *

   * RECORD_TYPE
   *   STRING_KEY myNum
   *     NUMBER_TYPE
   *   STRING_KEY myObject
   * 
* @param properties a map from property name to property type * @return a new node representing the record type */ public static TypeDeclarationNode recordType( LinkedHashMap properties) { TypeDeclarationNode node = new TypeDeclarationNode(Token.RECORD_TYPE); for (Map.Entry prop : properties.entrySet()) { Node stringKey = IR.stringKey(prop.getKey()); node.addChildToBack(stringKey); if (prop.getValue() != null) { stringKey.addChildToFront(prop.getValue()); } } return node; } private static Node maybeAddType(Node node, TypeDeclarationNode type) { if (type != null) { node.setDeclaredTypeExpression(type); } return node; } /** * Represents a function type. * Closure has syntax like {@code {function(string, boolean):number}} * Closure doesn't include parameter names. If the parameter types are unnamed, * arbitrary names can be substituted, eg. p1, p2, etc. * *

Example: *

   * FUNCTION_TYPE
   *   NUMBER_TYPE
   *   STRING_KEY p1 [declared_type_expr: STRING_TYPE]
   *   STRING_KEY p2 [declared_type_expr: BOOLEAN_TYPE]
   * 
* @param returnType the type returned by the function, possibly ANY_TYPE * @param requiredParams the names and types of the required parameters. * @param optionalParams the names and types of the optional parameters. * @param restName the name of the rest parameter, if any. * @param restType the type of the rest parameter, if any. */ public static TypeDeclarationNode functionType( Node returnType, LinkedHashMap requiredParams, LinkedHashMap optionalParams, String restName, TypeDeclarationNode restType) { TypeDeclarationNode node = new TypeDeclarationNode(Token.FUNCTION_TYPE, returnType); checkNotNull(requiredParams); checkNotNull(optionalParams); for (Map.Entry param : requiredParams.entrySet()) { Node name = IR.name(param.getKey()); node.addChildToBack(maybeAddType(name, param.getValue())); } for (Map.Entry param : optionalParams.entrySet()) { Node name = IR.name(param.getKey()); name.putBooleanProp(Node.OPT_ES6_TYPED, true); node.addChildToBack(maybeAddType(name, param.getValue())); } if (restName != null) { Node rest = new Node(Token.ITER_REST, IR.name(restName)); node.addChildToBack(maybeAddType(rest, restType)); } return node; } /** * Represents a parameterized, or generic, type. * Closure calls this a Type Application and accepts syntax like * {@code {Object.}} * *

Example: *

   * PARAMETERIZED_TYPE
   *   NAMED_TYPE
   *     NAME Object
   *   STRING_TYPE
   *   NUMBER_TYPE
   * 
* @param baseType * @param typeParameters */ public static TypeDeclarationNode parameterizedType( TypeDeclarationNode baseType, Iterable 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 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. * *

Example *

   * ARRAY_TYPE
   *   elementType
   * 
*/ public static TypeDeclarationNode arrayType(Node elementType) { return new TypeDeclarationNode(Token.ARRAY_TYPE, elementType); } /** * Represents a union type, which can be one of the given types. * Closure accepts syntax like {@code {(number|boolean)}} * *

Example: *

   * UNION_TYPE
   *   NUMBER_TYPE
   *   BOOLEAN_TYPE
   * 
* @param options the types which are accepted * @return a new node representing the union type */ public static TypeDeclarationNode unionType(Iterable 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; } public static TypeDeclarationNode unionType(TypeDeclarationNode... options) { return unionType(Arrays.asList(options)); } /** * Represents a function parameter that is optional. * In closure syntax, this is {@code function(?string=, number=)} * In TypeScript syntax, it is * {@code (firstName: string, lastName?: string)=>string} * @param parameterType the type of the parameter * @return a new node representing the function parameter type */ public static TypeDeclarationNode optionalParameter(TypeDeclarationNode parameterType) { return new TypeDeclarationNode(Token.OPTIONAL_PARAMETER, parameterType); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy