/**
   * Infers the type of {@code this}.
   *
   * @param info The JSDocInfo for this function.
   * @param owner The node for the object whose prototype "owns" this function. For example, {@code
   *     A} in the expression {@code A.prototype.foo}. May be null to indicate that this is not a
   *     prototype property.
   */
  FunctionTypeBuilder inferThisType(JSDocInfo info, @Nullable Node owner) {
    ObjectType maybeThisType = null;
    if (info != null && info.hasThisType()) {
      maybeThisType = ObjectType.cast(info.getThisType().evaluate(scope, typeRegistry));
    }
    if (maybeThisType != null) {
      thisType = maybeThisType;
      thisType.setValidator(new ThisTypeValidator());
    } else if (owner != null && (info == null || !info.hasType())) {
      // If the function is of the form:
      // x.prototype.y = function() {}
      // then we can assume "x" is the @this type. On the other hand,
      // if it's of the form:
      // /** @type {Function} */ x.prototype.y;
      // then we should not give it a @this type.
      String ownerTypeName = owner.getQualifiedName();
      ObjectType ownerType =
          ObjectType.cast(
              typeRegistry.getForgivingType(
                  scope, ownerTypeName, sourceName, owner.getLineno(), owner.getCharno()));
      if (ownerType != null) {
        thisType = ownerType;
      }
    }

    return this;
  }