private JSType getType(
      StaticTypedScope scope,
      String jsTypeName,
      String sourceName,
      int lineno,
      int charno,
      boolean recordUnresolvedTypes) {
    switch (jsTypeName) {
      case "boolean":
        return getNativeType(JSTypeNative.BOOLEAN_TYPE);
      case "number":
        return getNativeType(JSTypeNative.NUMBER_TYPE);
      case "string":
        return getNativeType(JSTypeNative.STRING_TYPE);
      case "undefined":
      case "void":
        return getNativeType(JSTypeNative.VOID_TYPE);
    }
    // Resolve template type names
    JSType type = null;
    JSType thisType = null;
    if (scope != null && scope.getTypeOfThis() != null) {
      thisType = scope.getTypeOfThis().toObjectType();
    }
    if (thisType != null) {
      type = thisType.getTemplateTypeMap().getTemplateTypeKeyByName(jsTypeName);
      if (type != null) {
        Preconditions.checkState(type.isTemplateType(), "expected:%s", type);
        return type;
      }
    }

    // TODO(sdh): The use of "getType" here is incorrect. This currently will pick up a type
    // in an outer scope if it will be shadowed by a local type.  But creating a unique NamedType
    // object for every name referenced (even if interned) in every scope would be expensive.
    //
    // Instead perhaps a standard (untyped) scope object might be used to pick the right scope
    // during type construction.
    type = getType(scope, jsTypeName);
    if (type == null) {
      // TODO(user): Each instance should support named type creation using
      // interning.
      NamedType namedType = createNamedType(scope, jsTypeName, sourceName, lineno, charno);
      if (recordUnresolvedTypes) {
        unresolvedNamedTypes.add(namedType);
      }
      type = namedType;
    }
    return type;
  }
private JSType getType ( StaticTypedScope scope , String jsTypeName , String sourceName , int lineno , int charno , boolean recordUnresolvedTypes ) { switch ( jsTypeName ) { case "boolean" : return getNativeType ( JSTypeNative . BOOLEAN_TYPE ) ; case "number" : return getNativeType ( JSTypeNative . NUMBER_TYPE ) ; case "string" : return getNativeType ( JSTypeNative . STRING_TYPE ) ; case "undefined" : case "void" : return getNativeType ( JSTypeNative . VOID_TYPE ) ; } JSType type = null ; JSType thisType = null ; if ( scope != null && scope . getTypeOfThis ( ) != null ) { thisType = scope . getTypeOfThis ( ) . toObjectType ( ) ; } if ( thisType != null ) { type = thisType . getTemplateTypeMap ( ) . getTemplateTypeKeyByName ( jsTypeName ) ; if ( type != null ) { Preconditions . checkState ( type . isTemplateType ( ) , "expected:%s" , type ) ; return type ; } } type = getType ( scope , jsTypeName ) ; if ( type == null ) { NamedType namedType = createNamedType ( scope , jsTypeName , sourceName , lineno , charno ) ; if ( recordUnresolvedTypes ) { unresolvedNamedTypes . add ( namedType ) ; } type = namedType ; } return type ; }
@param recordUnresolvedTypes record unresolved named types and resolve them later. Set to false
if types should be ignored for backwards compatibility (i.e. previously unparsed template
type args).