Java Code Examples for com.google.javascript.rhino.jstype.JSType#isTemplatizedType()

The following examples show how to use com.google.javascript.rhino.jstype.JSType#isTemplatizedType() . 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: DeclarationGenerator.java    From clutz with MIT License 6 votes vote down vote up
/**
 * Special handling for simple typing returning polymorphic this type in TypeScript. Prefer
 * `func(): this` instead of `func<T>(this: T): T` when any params are not templatized.
 */
private boolean shouldEmitThisParam(FunctionType ftype) {
  final JSType typeOfThis = ftype.getTypeOfThis();
  if (typeOfThis == null
      || !typeOfThis.isTemplateType()
      || !typeOfThis.equals(ftype.getReturnType())) {
    return true;
  }

  for (Parameter parameter : ftype.getParameters()) {
    JSType paramType = parameter.getJSType();
    if (!paramType.isTemplatizedType()) {
      continue;
    }

    final TemplateTypeMap templateTypeMap = paramType.getTemplateTypeMap();
    for (TemplateType key : templateTypeMap.getTemplateKeys()) {
      if (templateTypeMap.getResolvedTemplateType(key).equals(typeOfThis)) {
        return true;
      }
    }
  }

  return false;
}
 
Example 2
Source File: AbstractClosureVisitor.java    From jsinterop-generator with Apache License 2.0 5 votes vote down vote up
private void acceptType(JSType type) {
  type = type.restrictByNotNullOrUndefined();

  if (type.isRecordType()) {
    acceptRecordType(toRecordType(type), null);
  } else if (isAnonymousFunctionType(type)) {
    acceptFunctionType(toFunctionType(type), null);
  } else if (type.isTemplatizedType()) {
    type.toMaybeTemplatizedType().getTemplateTypes().forEach(this::acceptType);
  } else if (type.isUnionType()) {
    type.toMaybeUnionType().getAlternates().forEach(this::acceptType);
  }
}
 
Example 3
Source File: DeclarationGenerator.java    From clutz with MIT License 4 votes vote down vote up
/**
 * Closure Compiler does not support tuple types, and thus cannot express the proper type for
 * "Map<K, V>.entries()", which is an IterableIterator of a [K, V] tuple. The tighter tuple type
 * [K, V] allows destructuring loops "for (const [x, y] of ...)" with the tuple values getting
 * the right types assigned.
 *
 * <p>Given that maps are very common, as are for loops over them, this special cases methods
 * called "entries" that have the right return type.
 */
private boolean specialCaseMapEntries(String propName, FunctionType propertyType) {
  if (propertyType.getMaxArity() != 0 || !propName.equals("entries")) {
    return false;
  }

  // we have entries(): returnType
  JSType returnType = propertyType.getReturnType();
  if (!returnType.getDisplayName().equals("IteratorIterable")) {
    return false;
  }

  // we have entries(): IteratorIterable<valueType, iteratorReturnType, nextParamType>
  // TODO(b/140560697): Stop ignoring return and param types when upgrade to TS 3.6 is complete.
  //
  // In incremental mode IteratorIterable is noResolvedType, while in total mode it is
  // TemplatizedType.
  // They both have getTemplateTypes, but neither extends the other in the class hierarchy.
  final JSType valueType;
  if (returnType.isTemplatizedType()) {
    valueType = returnType.toMaybeTemplatizedType().getTemplateTypes().get(0);
  } else {
    // IteratorIterable must always have template types, even if they're unknown
    checkState(returnType.isNoResolvedType(), returnType);
    valueType = ((NoResolvedType) returnType).getTemplateTypes().get(0);
  }

  if (!isTemplateOf(valueType, "Array")) {
    return false;
  }

  // we have entries() : IteratorIterable<Array<arrayMembers>>
  JSType arrayMembers = valueType.toMaybeTemplatizedType().getTemplateTypes().get(0);
  if (!arrayMembers.isUnionType()
      || arrayMembers.toMaybeUnionType().getAlternates().size() != 2) {
    return false;
  }

  // we have entries() : IteratorIterable<Array<KEY|VALUE>
  emit("(): IterableIterator<[");
  Iterator<JSType> it = arrayMembers.toMaybeUnionType().getAlternates().iterator();
  visitType(it.next());
  emit(",");
  visitType(it.next());
  emit("]>;");
  emitBreak();
  return true;
}
 
Example 4
Source File: DeclarationGenerator.java    From clutz with MIT License 4 votes vote down vote up
private boolean isTemplateOf(JSType type, String typeName) {
  return type.isTemplatizedType()
      && type.toMaybeTemplatizedType().getReferenceName().equals(typeName);
}
 
Example 5
Source File: Closure_112_TypeInference_t.java    From coming with MIT License 4 votes vote down vote up
private void maybeResolveTemplatedType(
    JSType paramType,
    JSType argType,
    Map<TemplateType, JSType> resolvedTypes) {
  if (paramType.isTemplateType()) {
    // @param {T}
    resolvedTemplateType(
        resolvedTypes, paramType.toMaybeTemplateType(), argType);
  } else if (paramType.isUnionType()) {
    // @param {Array.<T>|NodeList|Arguments|{length:number}}
    UnionType unionType = paramType.toMaybeUnionType();
    for (JSType alernative : unionType.getAlternates()) {
      maybeResolveTemplatedType(alernative, argType, resolvedTypes);
    }
  } else if (paramType.isFunctionType()) {
    FunctionType paramFunctionType = paramType.toMaybeFunctionType();
    FunctionType argFunctionType = argType
        .restrictByNotNullOrUndefined()
        .collapseUnion()
        .toMaybeFunctionType();
    if (argFunctionType != null && argFunctionType.isSubtype(paramType)) {
      // infer from return type of the function type
      maybeResolveTemplatedType(
          paramFunctionType.getTypeOfThis(),
          argFunctionType.getTypeOfThis(), resolvedTypes);
      // infer from return type of the function type
      maybeResolveTemplatedType(
          paramFunctionType.getReturnType(),
          argFunctionType.getReturnType(), resolvedTypes);
      // infer from parameter types of the function type
      maybeResolveTemplateTypeFromNodes(
          paramFunctionType.getParameters(),
          argFunctionType.getParameters(), resolvedTypes);
    }
  } else if (paramType.isTemplatizedType()) {
    // @param {Array.<T>}
    ObjectType referencedParamType = paramType
        .toMaybeTemplatizedType()
        .getReferencedType();
    JSType argObjectType = argType
        .restrictByNotNullOrUndefined()
        .collapseUnion();

    if (argObjectType.isSubtype(referencedParamType)) {
      // If the argument type is a subtype of the parameter type, resolve any
      // template types amongst their templatized types.
      TemplateTypeMap paramTypeMap = paramType.getTemplateTypeMap();
      TemplateTypeMap argTypeMap = argObjectType.getTemplateTypeMap();
      for (TemplateType key : paramTypeMap.getTemplateKeys()) {
        maybeResolveTemplatedType(
            paramTypeMap.getTemplateType(key),
            argTypeMap.getTemplateType(key),
            resolvedTypes);
      }
    }
  }
}
 
Example 6
Source File: Closure_112_TypeInference_s.java    From coming with MIT License 4 votes vote down vote up
private void maybeResolveTemplatedType(
    JSType paramType,
    JSType argType,
    Map<TemplateType, JSType> resolvedTypes) {
  if (paramType.isTemplateType()) {
    // @param {T}
    resolvedTemplateType(
        resolvedTypes, paramType.toMaybeTemplateType(), argType);
  } else if (paramType.isUnionType()) {
    // @param {Array.<T>|NodeList|Arguments|{length:number}}
    UnionType unionType = paramType.toMaybeUnionType();
    for (JSType alernative : unionType.getAlternates()) {
      maybeResolveTemplatedType(alernative, argType, resolvedTypes);
    }
  } else if (paramType.isFunctionType()) {
    FunctionType paramFunctionType = paramType.toMaybeFunctionType();
    FunctionType argFunctionType = argType
        .restrictByNotNullOrUndefined()
        .collapseUnion()
        .toMaybeFunctionType();
    if (argFunctionType != null && argFunctionType.isSubtype(paramType)) {
      // infer from return type of the function type
      maybeResolveTemplatedType(
          paramFunctionType.getTypeOfThis(),
          argFunctionType.getTypeOfThis(), resolvedTypes);
      // infer from return type of the function type
      maybeResolveTemplatedType(
          paramFunctionType.getReturnType(),
          argFunctionType.getReturnType(), resolvedTypes);
      // infer from parameter types of the function type
      maybeResolveTemplateTypeFromNodes(
          paramFunctionType.getParameters(),
          argFunctionType.getParameters(), resolvedTypes);
    }
  } else if (paramType.isTemplatizedType()) {
    // @param {Array.<T>}
    ObjectType referencedParamType = paramType
        .toMaybeTemplatizedType()
        .getReferencedType();
    JSType argObjectType = argType
        .restrictByNotNullOrUndefined()
        .collapseUnion();

    if (argObjectType.isSubtype(referencedParamType)) {
      // If the argument type is a subtype of the parameter type, resolve any
      // template types amongst their templatized types.
      TemplateTypeMap paramTypeMap = paramType.getTemplateTypeMap();
      TemplateTypeMap argTypeMap = argObjectType.getTemplateTypeMap();
      for (TemplateType key : paramTypeMap.getTemplateKeys()) {
        maybeResolveTemplatedType(
            paramTypeMap.getTemplateType(key),
            argTypeMap.getTemplateType(key),
            resolvedTypes);
      }
    }
  }
}
 
Example 7
Source File: TypeInspector.java    From js-dossier with Apache License 2.0 4 votes vote down vote up
@Nullable
private TypeExpression getReturnType(
    PropertyDocs docs, Iterable<InstanceProperty> overrides, FunctionType function) {
  PropertyDocs returnDocs =
      findPropertyDocs(
          docs,
          overrides,
          input -> input != null && input.getReturnClause().getType().isPresent());

  JSType returnType = function.getReturnType();

  // Try to compensate for loss of information (how does this happen?). If the type compiler
  // says it is a templatized type, but does not have template types, or if it is an instance
  // type with a non-empty template type map, resort to JSDoc to figure out what the user wanted.
  boolean isUnknownType = returnType.isUnknownType() && !returnType.isTemplateType();
  boolean isEmptyTemplatizedType =
      returnType.isTemplatizedType() && returnType.getTemplateTypeMap().isEmpty();
  boolean isUnresolvedTemplateInstance =
      returnType.isInstanceType() && !returnType.getTemplateTypeMap().isEmpty();

  if (isUnknownType || isEmptyTemplatizedType || isUnresolvedTemplateInstance) {
    if (returnDocs != null && isKnownType(returnDocs.getJsDoc().getReturnClause())) {
      @SuppressWarnings("OptionalGetWithoutIsPresent") // Implied by isKnownType check above.
      JSTypeExpression expression = returnDocs.getJsDoc().getReturnClause().getType().get();
      returnType = evaluate(expression);
    } else {
      for (InstanceProperty property : overrides) {
        if (property.getType() != null && property.getType().isFunctionType()) {
          FunctionType fn = (FunctionType) property.getType();
          if (fn.getReturnType() != null && !fn.getReturnType().isUnknownType()) {
            returnType = fn.getReturnType();
            break;
          }
        }
      }
    }
  }

  if (returnType.isVoidType() || (returnType.isUnknownType() && !returnType.isTemplateType())) {
    return null;
  }

  NominalType context;
  if (returnDocs != null) {
    context = returnDocs.getContextType();
  } else {
    context = docs.getContextType();
  }

  TypeExpressionParser parser =
      expressionParserFactory.create(linkFactory.withTypeContext(context));
  return parser.parse(returnType);
}
 
Example 8
Source File: TypeInspector.java    From js-dossier with Apache License 2.0 4 votes vote down vote up
private static JSType stripTemplateTypeInformation(JSType type) {
  if (type.isTemplatizedType()) {
    return ((TemplatizedType) type).getReferencedType();
  }
  return type;
}
 
Example 9
Source File: DeclarationGenerator.java    From clutz with MIT License 2 votes vote down vote up
/**
 * Whether the typedef should be emitted by name or by the type it is defining.
 *
 * <p>Because, we do not access the original type signature, the replacement is done for all
 * references of the type (through the typedef or direct). Thus it is undesirable to always emit
 * by name. For example:
 *
 * <pre>
 * \@constructor A;
 * \@typedef {A} B;
 * \@const {A} var a;
 * </pre>
 *
 * If we emit the name, we would emit `var a: B;`, which is undesirable (consider A being string).
 *
 * <p>For now, only emit by name typedefs that are unlikely to have more than one name referring
 * to them - record types, templatized types and function types.
 */
private boolean shouldEmitTypedefByName(JSType realType) {
  return realType.isRecordType() || realType.isTemplatizedType() || realType.isFunctionType();
}