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

The following examples show how to use com.google.javascript.rhino.jstype.JSType#getTemplateTypeMap() . 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: Closure_112_TypeInference_t.java    From coming with MIT License 5 votes vote down vote up
private FlowScope traverseGetElem(Node n, FlowScope scope) {
  scope = traverseChildren(n, scope);
  JSType type = getJSType(n.getFirstChild()).restrictByNotNullOrUndefined();
  TemplateTypeMap typeMap = type.getTemplateTypeMap();
  if (typeMap.hasTemplateType(registry.getObjectElementKey())) {
    n.setJSType(typeMap.getTemplateType(registry.getObjectElementKey()));
  }
  return dereferencePointer(n.getFirstChild(), scope);
}
 
Example 3
Source File: Closure_112_TypeInference_s.java    From coming with MIT License 5 votes vote down vote up
private FlowScope traverseGetElem(Node n, FlowScope scope) {
  scope = traverseChildren(n, scope);
  JSType type = getJSType(n.getFirstChild()).restrictByNotNullOrUndefined();
  TemplateTypeMap typeMap = type.getTemplateTypeMap();
  if (typeMap.hasTemplateType(registry.getObjectElementKey())) {
    n.setJSType(typeMap.getTemplateType(registry.getObjectElementKey()));
  }
  return dereferencePointer(n.getFirstChild(), scope);
}
 
Example 4
Source File: DeclarationGenerator.java    From clutz with MIT License 4 votes vote down vote up
/**
 * Emits a [Symbol.iterator] property on the class if it implements the Iterable interface or
 * IteratorIterable.
 *
 * <p>JSCompiler does not understand nor represent Symbol properties, so we cannot just emit the
 * property in the loop above, and must guess on the actual return type of the iterator method.
 */
private void maybeEmitSymbolIterator(JSType instanceType) {
  if (instanceType == null) {
    return;
  }
  // iteratorIterableType will be null if not found in the current run's externs definitions.
  JSType implemented;
  String returnType;

  // Unfortunately, this method of detecting whether a class implements Iterator, is error-prone
  // in cases where the extension goes through another extends clause. Consider, C extends D,
  // and D implements Iterable.
  // In such cases C doesn't need to emit anything new, because D's emit would have handled
  // that.
  // Here we detect one such case - D being the always-present Array type and skip unnecessary
  // custom emit.
  if (instanceType.isSubtype(arrayType)) {
    return;
  }

  // When extending an unknown base, the isSubtype check always returns true. This is not that
  // surprising, because when the base is unknown the only correct answer is unknown, not true
  // or false.
  //
  // Emitting a [Symbol.iterator()] signature for all record/interfaces that extend an unknown
  // base is too limiting, as it doesn't allow assigning object literal to those interfaces.
  // So instead we skip emitting the extra signature in the case of unknown base.
  if (iteratorIterableType != null && instanceType.isSubtype(iteratorIterableType)) {
    implemented = iteratorIterableType;
    returnType = "IterableIterator";
  } else {
    return;
  }
  emitComment("Symbol.iterator inserted by Clutz for Iterable subtype");
  emit("[Symbol.iterator](): ");
  // The actual implementation of iterator could be an arbitrary subtype of Iterable. Emit
  // the type of the interface as the next best thing.
  emit(returnType);
  emit("<");
  TemplateType templateType = implemented.getTemplateTypeMap().getTemplateKeys().get(0);
  TemplateTypeMap ttMap = instanceType.getTemplateTypeMap();
  // Known issue: ttMap does not expose getUnresolvedTemplateType, which would be required
  // to correctly emit unbound template parameters, e.g. "<T>".
  JSType resolvedTemplateType = ttMap.getResolvedTemplateType(templateType);
  visitType(resolvedTemplateType, false, false);
  emit(">");
  emit(";");
  emitBreak();
}
 
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_t.java    From coming with MIT License 4 votes vote down vote up
private JSType getPropertyType(JSType objType, String propName,
    Node n, FlowScope scope) {
  // We often have a couple of different types to choose from for the
  // property. Ordered by accuracy, we have
  // 1) A locally inferred qualified name (which is in the FlowScope)
  // 2) A globally declared qualified name (which is in the FlowScope)
  // 3) A property on the owner type (which is on objType)
  // 4) A name in the type registry (as a last resort)
  JSType propertyType = null;
  boolean isLocallyInferred = false;

  // Scopes sometimes contain inferred type info about qualified names.
  String qualifiedName = n.getQualifiedName();
  StaticSlot<JSType> var = scope.getSlot(qualifiedName);
  if (var != null) {
    JSType varType = var.getType();
    if (varType != null) {
      boolean isDeclared = !var.isTypeInferred();
      isLocallyInferred = (var != syntacticScope.getSlot(qualifiedName));
      if (isDeclared || isLocallyInferred) {
        propertyType = varType;
      }
    }
  }

  if (propertyType == null && objType != null) {
    JSType foundType = objType.findPropertyType(propName);
    if (foundType != null) {
      propertyType = foundType;
    }
  }

  if (propertyType != null && objType != null) {
    JSType restrictedObjType = objType.restrictByNotNullOrUndefined();
    if (!restrictedObjType.getTemplateTypeMap().isEmpty()
        && propertyType.hasAnyTemplateTypes()) {
      TemplateTypeMap typeMap = restrictedObjType.getTemplateTypeMap();
      TemplateTypeMapReplacer replacer = new TemplateTypeMapReplacer(
          registry, typeMap);
      propertyType = propertyType.visit(replacer);
    }
  }

  if ((propertyType == null || propertyType.isUnknownType())
      && qualifiedName != null) {
    // If we find this node in the registry, then we can infer its type.
    ObjectType regType = ObjectType.cast(registry.getType(qualifiedName));
    if (regType != null) {
      propertyType = regType.getConstructor();
    }
  }

  if (propertyType == null) {
    return unknownType;
  } else if (propertyType.isEquivalentTo(unknownType) && isLocallyInferred) {
    // If the type has been checked in this scope,
    // then use CHECKED_UNKNOWN_TYPE instead to indicate that.
    return getNativeType(CHECKED_UNKNOWN_TYPE);
  } else {
    return propertyType;
  }
}
 
Example 7
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 8
Source File: Closure_112_TypeInference_s.java    From coming with MIT License 4 votes vote down vote up
private JSType getPropertyType(JSType objType, String propName,
    Node n, FlowScope scope) {
  // We often have a couple of different types to choose from for the
  // property. Ordered by accuracy, we have
  // 1) A locally inferred qualified name (which is in the FlowScope)
  // 2) A globally declared qualified name (which is in the FlowScope)
  // 3) A property on the owner type (which is on objType)
  // 4) A name in the type registry (as a last resort)
  JSType propertyType = null;
  boolean isLocallyInferred = false;

  // Scopes sometimes contain inferred type info about qualified names.
  String qualifiedName = n.getQualifiedName();
  StaticSlot<JSType> var = scope.getSlot(qualifiedName);
  if (var != null) {
    JSType varType = var.getType();
    if (varType != null) {
      boolean isDeclared = !var.isTypeInferred();
      isLocallyInferred = (var != syntacticScope.getSlot(qualifiedName));
      if (isDeclared || isLocallyInferred) {
        propertyType = varType;
      }
    }
  }

  if (propertyType == null && objType != null) {
    JSType foundType = objType.findPropertyType(propName);
    if (foundType != null) {
      propertyType = foundType;
    }
  }

  if (propertyType != null && objType != null) {
    JSType restrictedObjType = objType.restrictByNotNullOrUndefined();
    if (!restrictedObjType.getTemplateTypeMap().isEmpty()
        && propertyType.hasAnyTemplateTypes()) {
      TemplateTypeMap typeMap = restrictedObjType.getTemplateTypeMap();
      TemplateTypeMapReplacer replacer = new TemplateTypeMapReplacer(
          registry, typeMap);
      propertyType = propertyType.visit(replacer);
    }
  }

  if ((propertyType == null || propertyType.isUnknownType())
      && qualifiedName != null) {
    // If we find this node in the registry, then we can infer its type.
    ObjectType regType = ObjectType.cast(registry.getType(qualifiedName));
    if (regType != null) {
      propertyType = regType.getConstructor();
    }
  }

  if (propertyType == null) {
    return unknownType;
  } else if (propertyType.isEquivalentTo(unknownType) && isLocallyInferred) {
    // If the type has been checked in this scope,
    // then use CHECKED_UNKNOWN_TYPE instead to indicate that.
    return getNativeType(CHECKED_UNKNOWN_TYPE);
  } else {
    return propertyType;
  }
}