com.google.javascript.rhino.JSTypeExpression Java Examples

The following examples show how to use com.google.javascript.rhino.JSTypeExpression. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: TypeCollectionPass.java    From js-dossier with Apache License 2.0 6 votes vote down vote up
private boolean isExternAlias(JSType type, JSDocInfo info) {
  if (externTypes.contains(type)) {
    return true;
  }

  // If something is typed as {function(new: Foo)}, it will actually be represented as
  // {function(new: Foo): ?}, which is different than the real constructor. We can get the real
  // constructor, however, with a little type manipulation.
  if (type.isConstructor() && type.toMaybeFunctionType() != null) {
    JSType ctorType = type.toMaybeFunctionType().getInstanceType().getConstructor();
    if (externTypes.contains(ctorType)) {
      return true;
    }
  }

  if (info != null && info.getTypedefType() != null) {
    JSTypeExpression expression = info.getTypedefType();
    type = Types.evaluate(expression, compiler.getTopScope(), compiler.getTypeRegistry());
    return externTypes.contains(type);
  }

  return false;
}
 
Example #2
Source File: TypeExpressionParserTest.java    From js-dossier with Apache License 2.0 6 votes vote down vote up
@Test
public void parseFunctionTypeExpressionWithReturnType() {
  util.compile(
      fs.getPath("foo.js"),
      "class Person {}",
      "/**",
      " * @param {function(): Person} a .",
      " * @constructor",
      " */",
      "function Greeter(a) {}");

  NominalType type = typeRegistry.getType("Greeter");
  TypeExpressionParser parser = parserFactory.create(linkFactoryBuilder.create(type));
  JSTypeExpression jsExpression = type.getJsDoc().getParameter("a").getType();
  JSType jsType = util.evaluate(jsExpression);
  TypeExpression expression = parser.parse(jsType);
  assertThat(expression)
      .isEqualTo(
          TypeExpression.newBuilder()
              .setFunctionType(
                  FunctionType.newBuilder()
                      .setReturnType(
                          unionType(namedTypeExpression("Person", "Person.html"), NULL_TYPE)))
              .build());
}
 
Example #3
Source File: Closure_109_JsDocInfoParser_t.java    From coming with MIT License 6 votes vote down vote up
/**
 * Parse a description as a {@code @type}.
 */
public JSDocInfo parseInlineTypeDoc() {
  skipEOLs();

  JsDocToken token = next();
  int lineno = stream.getLineno();
  int startCharno = stream.getCharno();
  Node typeAst = parseTypeExpression(token);
  recordTypeNode(lineno, startCharno, typeAst, token == JsDocToken.LC);

  JSTypeExpression expr = createJSTypeExpression(typeAst);
  if (expr != null) {
    jsdocBuilder.recordType(expr);
    return retrieveAndResetParsedJSDocInfo();
  }
  return null;
}
 
Example #4
Source File: JsDocInfoParserTest.java    From astor with GNU General Public License v2.0 6 votes vote down vote up
public void testInterfaceMultiExtends2() throws Exception {
  JSDocInfo jsdoc = parse(
      " * @extends {Extended1} \n" +
      " * @interface \n" +
      " * @extends {Extended2} \n" +
      " * @extends {Extended3} */");
  assertTrue(jsdoc.isInterface());
  assertNull(jsdoc.getBaseType());
  assertEquals(3, jsdoc.getExtendedInterfacesCount());
  List<JSTypeExpression> types = jsdoc.getExtendedInterfaces();
  assertTypeEquals(registry.createNamedType("Extended1", null, -1, -1),
     types.get(0));
  assertTypeEquals(registry.createNamedType("Extended2", null, -1, -1),
      types.get(1));
  assertTypeEquals(registry.createNamedType("Extended3", null, -1, -1),
      types.get(2));
}
 
Example #5
Source File: TypeExpressionParserTest.java    From js-dossier with Apache License 2.0 6 votes vote down vote up
@Test
public void parseFunctionTypeExpressionWithNoReturnType() {
  util.compile(
      fs.getPath("foo.js"),
      "class Person {}",
      "/**",
      " * @param {function(this: Person)} a .",
      " * @constructor",
      " */",
      "function Greeter(a) {}");

  NominalType type = typeRegistry.getType("Greeter");
  TypeExpressionParser parser = parserFactory.create(linkFactoryBuilder.create(type));
  JSTypeExpression jsExpression = type.getJsDoc().getParameter("a").getType();
  JSType jsType = util.evaluate(jsExpression);
  TypeExpression expression = parser.parse(jsType);
  assertThat(expression)
      .isEqualTo(
          TypeExpression.newBuilder()
              .setFunctionType(
                  FunctionType.newBuilder()
                      .setInstanceType(namedTypeExpression("Person", "Person.html"))
                      .setReturnType(TypeExpression.newBuilder().setUnknownType(true)))
              .build());
}
 
Example #6
Source File: TypeConversionPass.java    From clutz with MIT License 6 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  switch (n.getToken()) {
    case VAR:
    case LET:
    case CONST:
      if (n.getJSDocInfo() == null || n.getJSDocInfo().getEnumParameterType() == null) return;
      JSTypeExpression enumExp = n.getJSDocInfo().getEnumParameterType();
      if (!enumExp.getRoot().isString()) return;
      String enumTypeStr = enumExp.getRoot().getString();
      if (!enumTypeStr.equals("number") && !enumTypeStr.equals("string")) return;

      Node name = n.removeFirstChild();
      Node members = name.removeFirstChild();

      Node enumMembers = transformMembers(members, enumTypeStr.equals("number"));
      Node enumNode = new Node(Token.ENUM, name, enumMembers);
      parent.replaceChild(n, enumNode);
      compiler.reportChangeToEnclosingScope(parent);
      break;
    default:
      break;
  }
}
 
Example #7
Source File: TypeAnnotationPass.java    From clutz with MIT License 6 votes vote down vote up
private void maybeSetInlineTypeExpression(
    Node nameNode, Node commentNode, JSDocInfo docInfo, boolean isReturnType) {
  if (docInfo == null) {
    return;
  }
  JSTypeExpression type = docInfo.getType();
  if (type == null) {
    return;
  }
  setTypeExpression(nameNode, type, isReturnType);
  // Remove the part of comment that sets the inline type.
  String toRemove = docInfo.getOriginalCommentString();
  List<GeneralComment> comments = nodeComments.getComments(commentNode);
  if (comments == null) {
    return;
  }

  List<GeneralComment> newComments = Lists.newArrayList();
  for (GeneralComment c : comments) {
    String newText = c.getText().replaceFirst("\\n?" + Pattern.quote(toRemove), "");
    newComments.add(GeneralComment.from(newText, c.getOffset()));
  }

  nodeComments.setComments(commentNode, newComments);
  compiler.reportChangeToEnclosingScope(commentNode);
}
 
Example #8
Source File: TypeAnnotationPass.java    From clutz with MIT License 6 votes vote down vote up
/** Sets the annotated type expression corresponding to Node {@code n}. */
private void setTypeExpression(Node n, @Nullable JSTypeExpression type, boolean isReturnType) {
  TypeDeclarationNode typeNode = convert(type, isReturnType);

  // If the type of a member variable contains "undefined", we emit prop? and drop the undefined in TypeScript.
  // This is a better translation which matches closure semantics that a field with
  // optional undefined can be completely omitted from the assigned object.
  //   /** @private {string|undefined} */ this.a -> a? : string
  if (n.isMemberVariableDef() &&
      typeNode.getToken() == Token.UNION_TYPE &&
      unionContainsUndefined(typeNode)) {
    n.setString(n.getString() + "?");
    typeNode = getUnionTypeNoUndefined(typeNode);
  }

  setTypeExpression(n, typeNode);
}
 
Example #9
Source File: TypeInspector.java    From js-dossier with Apache License 2.0 6 votes vote down vote up
private com.github.jsdossier.proto.Property getPropertyData(
    String name,
    JSType type,
    Node node,
    PropertyDocs docs,
    @Nullable DefinedByType definedBy,
    Iterable<InstanceProperty> overrides) {
  com.github.jsdossier.proto.Property.Builder builder =
      com.github.jsdossier.proto.Property.newBuilder()
          .setBase(getBasePropertyDetails(name, type, node, docs, definedBy, overrides));

  TypeExpressionParser parser =
      expressionParserFactory.create(linkFactory.withTypeContext(docs.getContextType()));
  if (docs.getJsDoc().getType() != null) {
    JSTypeExpression typeExpression = docs.getJsDoc().getType();
    type = evaluate(typeExpression);
  }

  if (type != null) {
    TypeExpression expression = parser.parse(type);
    builder.setType(expression);
  }

  return builder.build();
}
 
Example #10
Source File: Nopol2017_0025_t.java    From coming with MIT License 5 votes vote down vote up
public JSDocInfo parseInlineTypeDoc() {
  Node typeAst = parseAndRecordTypeNode(next());
  JSTypeExpression expr = createJSTypeExpression(typeAst);
  if (expr != null) {
    jsdocBuilder.recordType(expr);
    return retrieveAndResetParsedJSDocInfo();
  }
  return null;
}
 
Example #11
Source File: Cardumen_0017_t.java    From coming with MIT License 5 votes vote down vote up
public JSDocInfo parseInlineTypeDoc() {
  Node typeAst = parseAndRecordTypeNode(next());
  JSTypeExpression expr = createJSTypeExpression(typeAst);
  if (expr != null) {
    jsdocBuilder.recordType(expr);
    return retrieveAndResetParsedJSDocInfo();
  }
  return null;
}
 
Example #12
Source File: TypeAnnotationPass.java    From clutz with MIT License 5 votes vote down vote up
@Nullable
private TypeDeclarationNode convert(@Nullable JSTypeExpression typeExpr, boolean isReturnType) {
  if (typeExpr == null) {
    return null;
  }
  return convertTypeNodeAST(typeExpr.getRoot(), isReturnType);
}
 
Example #13
Source File: TypeExpressionParserTest.java    From js-dossier with Apache License 2.0 5 votes vote down vote up
@Test
public void parseExpressionWithTemplatizedTypeFromAnotherModule() {
  util.compile(
      createSourceFile(
          fs.getPath("source/modules/one.js"), "/** @template T */", "export class Container {}"),
      createSourceFile(
          fs.getPath("source/modules/two.js"),
          "import {Container} from './one';",
          "export class Person {",
          "  /** @return {!Container<string>} . */",
          "  name() { return new Container; }",
          "}"));

  NominalType type = typeRegistry.getType("module$source$modules$two.Person");
  JSDocInfo info =
      type.getType().toMaybeFunctionType().getPrototype().getOwnPropertyJSDocInfo("name");
  JSTypeExpression jsExpression = info.getReturnType();
  JSType jsType = util.evaluate(jsExpression);

  TypeExpressionParser parser =
      parserFactory.create(linkFactoryBuilder.create(type).withTypeContext(type));
  TypeExpression expression = parser.parse(jsType);
  assertThat(expression)
      .isEqualTo(
          TypeExpression.newBuilder()
              .setNamedType(
                  namedType("Container", "one.Container", "one_exports_Container.html")
                      .toBuilder()
                      .addTemplateType(stringType()))
              .build());
}
 
Example #14
Source File: JsDoc.java    From js-dossier with Apache License 2.0 5 votes vote down vote up
@Nullable
private JSTypeExpression getJsTypeExpression(JSDocInfo.Marker marker) {
  if (marker.getType() == null) {
    return null;
  }
  return new JSTypeExpression(marker.getType().getItem(), "");
}
 
Example #15
Source File: JsDoc.java    From js-dossier with Apache License 2.0 5 votes vote down vote up
@Nullable
public JSTypeExpression getType() {
  if (isEnum()) {
    return info.getEnumParameterType();
  } else if (isTypedef()) {
    return info.getTypedefType();
  } else {
    return info.getType();
  }
}
 
Example #16
Source File: TypeInspector.java    From js-dossier with Apache License 2.0 5 votes vote down vote up
private JSType evaluate(JSTypeExpression expression) {
  if (!resolvedExpressions.contains(expression)) {
    resolveNames(expression.getRoot());
    resolvedExpressions.add(expression);
  }

  JSType type = Types.evaluate(expression, globalScope, jsRegistry);
  return type.visit(typeMapReplacer);
}
 
Example #17
Source File: TypeExpressionParserTest.java    From js-dossier with Apache License 2.0 5 votes vote down vote up
@Test
public void parseFunctionTypeExpressionWithVarArgs() {
  util.compile(
      fs.getPath("foo.js"),
      "class Person {}",
      "/**",
      " * @param {function(...!Person)} a .",
      " * @constructor",
      " */",
      "function Greeter(a) {}");

  NominalType type = typeRegistry.getType("Greeter");
  TypeExpressionParser parser = parserFactory.create(linkFactoryBuilder.create(type));
  JSTypeExpression expression = type.getJsDoc().getParameter("a").getType();
  JSType jsType = util.evaluate(expression);

  TypeExpression typeExpression = parser.parse(jsType);
  assertThat(typeExpression)
      .isEqualTo(
          TypeExpression.newBuilder()
              .setFunctionType(
                  FunctionType.newBuilder()
                      .addParameter(
                          TypeExpression.newBuilder()
                              .setIsVarargs(true)
                              .setNamedType(namedType("Person", "Person.html")))
                      .setReturnType(UNKNOWN_TYPE))
              .build());
}
 
Example #18
Source File: TypeAnnotationPass.java    From clutz with MIT License 5 votes vote down vote up
/**
 * Attempts to set the type of parameter represented by node by extracting it from @param
 * annotations in the function's jsDoc. Returns true if it succeeds (i.e. if it finds the type).
 */
private boolean setParameterTypeFromFunctionDoc(Node node, Node parent) {
  JSDocInfo parentDocInfo = NodeUtil.getBestJSDocInfo(parent.getParent());
  if (parentDocInfo == null) {
    return false;
  }
  String parameterName =
      node.isObjectPattern()
          ? parentDocInfo.getParameterNameAt(parent.getIndexOfChild(node))
          : node.getString();
  JSTypeExpression parameterType = parentDocInfo.getParameterType(parameterName);
  if (parameterType == null) {
    return false;
  }
  TypeDeclarationNode parameterTypeNode = convertTypeNodeAST(parameterType.getRoot());
  // Parameter is declared using verbose @param syntax before the function definition.
  Node attachTypeExpr = node;
  // Modify the primary AST to represent a function parameter as a
  // REST node, if the type indicates it is a rest parameter.
  if (parameterType.getRoot().getToken() == Token.ITER_REST) {
    attachTypeExpr = IR.iterRest(IR.name(node.getString()));
    nodeComments.replaceWithComment(node, attachTypeExpr);
  }
  // Modify the AST to represent an optional parameter
  if (parameterType.getRoot().getToken() == Token.EQUALS) {
    attachTypeExpr = IR.name(node.getString());
    if (!node.getParent().isDefaultValue()) {
      attachTypeExpr.putBooleanProp(Node.OPT_ES6_TYPED, true);
    } else if (node.getParent().getSecondChild().isName()
        && node.getParent().getSecondChild().getString().equals("undefined")) {
      // if default value is "undefined" add undefined to the type
      parameterTypeNode = flatUnionType(ImmutableList.of(parameterTypeNode, undefinedType()));
    }
    nodeComments.replaceWithComment(node, attachTypeExpr);
  }
  setTypeExpression(attachTypeExpr, parameterTypeNode);
  return true;
}
 
Example #19
Source File: TypeInspector.java    From js-dossier with Apache License 2.0 5 votes vote down vote up
private List<Parameter> extractParameters(JSDocInfo info) {
  List<Parameter> parameters = Lists.newArrayListWithExpectedSize(info.getParameterCount());
  for (int i = 0; i < info.getParameterCount(); i++) {
    String name = info.getParameterNameAt(i);
    JSTypeExpression expression = info.getParameterType(name);
    String description = info.getDescriptionForParameter(name);
    parameters.add(new Parameter(name, expression, description));
  }
  return parameters;
}
 
Example #20
Source File: Cardumen_0017_s.java    From coming with MIT License 5 votes vote down vote up
public JSDocInfo parseInlineTypeDoc() {
  Node typeAst = parseAndRecordTypeNode(next());
  JSTypeExpression expr = createJSTypeExpression(typeAst);
  if (expr != null) {
    jsdocBuilder.recordType(expr);
    return retrieveAndResetParsedJSDocInfo();
  }
  return null;
}
 
Example #21
Source File: TypeExpressionParserTest.java    From js-dossier with Apache License 2.0 5 votes vote down vote up
@Test
public void parseFunctionTypeExpressionWithVarArgs_withContext() {
  util.compile(
      fs.getPath("foo.js"),
      "class Person {}",
      "/**",
      " * @param {function(this: Person, ...!Person)} a .",
      " * @constructor",
      " */",
      "function Greeter(a) {}");

  NominalType type = typeRegistry.getType("Greeter");
  TypeExpressionParser parser = parserFactory.create(linkFactoryBuilder.create(type));
  JSTypeExpression jsExpression = type.getJsDoc().getParameter("a").getType();
  JSType jsType = util.evaluate(jsExpression);
  TypeExpression expression = parser.parse(jsType);
  assertThat(expression)
      .isEqualTo(
          TypeExpression.newBuilder()
              .setFunctionType(
                  FunctionType.newBuilder()
                      .setInstanceType(namedTypeExpression("Person", "Person.html"))
                      .addParameter(
                          namedTypeExpression("Person", "Person.html")
                              .toBuilder()
                              .setIsVarargs(true))
                      .setReturnType(TypeExpression.newBuilder().setUnknownType(true)))
              .build());
}
 
Example #22
Source File: TypeRegistry.java    From js-dossier with Apache License 2.0 5 votes vote down vote up
private JSType getSuperInstance(
    ObjectType instance,
    FunctionType ctor,
    StaticTypedScope globalScope,
    JSTypeRegistry jsRegistry) {
  JSType superInstance;
  if (ctor.getJSDocInfo() != null && ctor.getJSDocInfo().getBaseType() != null) {
    List<TemplateType> templateTypes = instance.getTemplateTypeMap().getTemplateKeys();
    StaticTypedScope scope =
        templateTypes.isEmpty()
            ? globalScope
            : jsRegistry.createScopeWithTemplates(globalScope, templateTypes);

    JSTypeExpression baseTypeExpression = ctor.getJSDocInfo().getBaseType();
    superInstance = Types.evaluate(baseTypeExpression, scope, jsRegistry);

    // The type expression will resolve to a named type if it is an aliased reference to
    // a module's exported type. Compensate by checking dossier's type registry, which
    // tracks exported types by their exported name (whereas the compiler tracks them by
    // their initially declared name from within the module).
    if (superInstance.isNamedType()
        && isType(superInstance.toMaybeNamedType().getReferenceName())) {
      superInstance = getType(superInstance.toMaybeNamedType().getReferenceName()).getType();
      if (superInstance.isConstructor() || superInstance.isInterface()) {
        superInstance = superInstance.toMaybeFunctionType().getTypeOfThis();
      }
    }

  } else {
    FunctionType superCtor = ctor.getSuperClassConstructor();
    if (superCtor == null) {
      return null;
    }
    superInstance = superCtor.getTypeOfThis();
  }
  return superInstance;
}
 
Example #23
Source File: JsDocInfoParserTest.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
public void testInterfaceExtends() throws Exception {
   JSDocInfo jsdoc = parse(
       " * @interface \n" +
       " * @extends {Extended} */");
  assertTrue(jsdoc.isInterface());
  assertEquals(1, jsdoc.getExtendedInterfacesCount());
  List<JSTypeExpression> types = jsdoc.getExtendedInterfaces();
  assertTypeEquals(registry.createNamedType("Extended", null, -1, -1),
      types.get(0));
}
 
Example #24
Source File: JsDocInfoParserTest.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
public void testParseImplementsTwo() throws Exception {
  List<JSTypeExpression> interfaces =
      parse(
          "* @implements {SomeInterface1}\n" +
          "* @implements {SomeInterface2}\n" +
          "*/")
      .getImplementedInterfaces();
  assertEquals(2, interfaces.size());
  assertTypeEquals(registry.createNamedType("SomeInterface1", null, -1, -1),
      interfaces.get(0));
  assertTypeEquals(registry.createNamedType("SomeInterface2", null, -1, -1),
      interfaces.get(1));
}
 
Example #25
Source File: JsDocInfoParserTest.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
public void testParseImplements() throws Exception {
  List<JSTypeExpression> interfaces = parse("@implements {SomeInterface}*/")
      .getImplementedInterfaces();
  assertEquals(1, interfaces.size());
  assertTypeEquals(registry.createNamedType("SomeInterface", null, -1, -1),
      interfaces.get(0));
}
 
Example #26
Source File: JsDocInfoParserTest.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
public void testParseImplementsGenerics() throws Exception {
  // we ignore things inside <> for now
  List<JSTypeExpression> interfaces =
      parse("@implements {SomeInterface.<*>} */")
      .getImplementedInterfaces();
  assertEquals(1, interfaces.size());
  assertTypeEquals(registry.createNamedType("SomeInterface", null, -1, -1),
      interfaces.get(0));
}
 
Example #27
Source File: TypeExpressionParserTest.java    From js-dossier with Apache License 2.0 5 votes vote down vote up
@Test
public void parseExpressionWithTemplatizedType() {
  util.compile(
      createSourceFile(
          fs.getPath("source/global.js"),
          "/** @template T */",
          "class Container {}",
          "class Person {",
          "  /** @return {!Container<string>} . */",
          "  name() { return new Container; }",
          "}"));

  NominalType type = typeRegistry.getType("Person");
  JSDocInfo info =
      type.getType().toMaybeFunctionType().getPrototype().getOwnPropertyJSDocInfo("name");
  JSTypeExpression jsExpression = info.getReturnType();
  JSType jsType = util.evaluate(jsExpression);

  TypeExpressionParser parser =
      parserFactory.create(linkFactoryBuilder.create(type).withTypeContext(type));
  TypeExpression expression = parser.parse(jsType);
  assertThat(expression)
      .isEqualTo(
          TypeExpression.newBuilder()
              .setNamedType(
                  namedType("Container", "Container.html")
                      .toBuilder()
                      .addTemplateType(stringType()))
              .build());
}
 
Example #28
Source File: ProcessDefines.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Only defines of literal number, string, or boolean are supported.
 */
private boolean isValidDefineType(JSTypeExpression expression) {
  JSType type = expression.evaluate(null, compiler.getTypeRegistry());
  return !type.isUnknownType() && type.isSubtype(
      compiler.getTypeRegistry().getNativeType(
          JSTypeNative.NUMBER_STRING_BOOLEAN));
}
 
Example #29
Source File: TypeExpressionParserTest.java    From js-dossier with Apache License 2.0 5 votes vote down vote up
private TypeExpression compileExpression(String expressionText) {
  util.compile(
      createSourceFile(
          fs.getPath("one.js"),
          "/**",
          " * @param {" + expressionText + "} x .",
          " * @constructor",
          " */",
          "function Widget(x) {}"));
  NominalType type = typeRegistry.getType("Widget");
  JSTypeExpression expression = type.getJsDoc().getParameter("x").getType();
  JSType jsType = util.evaluate(expression);
  return parserFactory.create(linkFactoryBuilder.create(type)).parse(jsType);
}
 
Example #30
Source File: Closure_133_JsDocInfoParser_t.java    From coming with MIT License 5 votes vote down vote up
public JSDocInfo parseInlineTypeDoc() {
  Node typeAst = parseAndRecordTypeNode(next());
  JSTypeExpression expr = createJSTypeExpression(typeAst);
  if (expr != null) {
    jsdocBuilder.recordType(expr);
    return retrieveAndResetParsedJSDocInfo();
  }
  return null;
}