Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a way to resolve bounded types directly #15

Open
leonard84 opened this issue Nov 22, 2021 · 2 comments
Open

Add a way to resolve bounded types directly #15

leonard84 opened this issue Nov 22, 2021 · 2 comments

Comments

@leonard84
Copy link

Coming from coekie#5 (comment)

I gave it a spin and came up with this:

  public static Type getResolvedReturnType(Method m, Type declaringType) {
    return resolveTypeVariableIfNecessary(GenericTypeReflector.getReturnType(m, declaringType));
  }

  public static Type getResolvedFieldType(Field f, Type declaringType) {
    return resolveTypeVariableIfNecessary(GenericTypeReflector.getFieldType(f, declaringType));
  }

  public static List<Type> getResolvedParameterTypes(Method m, Type declaringType) {
    return Arrays.stream(GenericTypeReflector.getParameterTypes(m, declaringType))
      .map(ReflectionUtil::resolveTypeVariableIfNecessary)
      .collect(Collectors.toList());
  }

  private static Type resolveTypeVariableIfNecessary(Type returnType) {
    if (returnType instanceof TypeVariable) {
      AnnotatedType annotatedType = GenericTypeReflector.annotate(returnType);
      return GenericTypeReflector.reduceBounded(annotatedType).getType();
    }
    return returnType;
  }

it seems to work, but I'm not sure its the best way. You can see the full change here https://github.com/leonard84/spock/tree/replace_gentyref_with_geantyref

I think that it might have value to have something like this in GenericTypeReflector directly, this way it could be optimized as well, the current implementation has to re-annotate the type that was discarded in GenericTypeReflector internally.

@kaqqao
Copy link
Member

kaqqao commented Nov 23, 2021

I'll look into adding an optional leaf transformation step during type resolution, that way an extra descent down the structure wouldn't be needed. But at the very least I'll add methods that avoid re-annotation. I'll notify you here when the next version is out.

Btw, you might want to always call reduceBounded in your current code, not only for variables, because I assume you'd also want wildcards and parameterized types reduced e.g. ? extends Number to Number or List<T extends Number to List<Number> etc.

@leonard84
Copy link
Author

I just wanted to avoid calling reduceBounded for the cases where it is already a simple type, e.g., String.

Do you have any performance measurements? Is it worth caching results or is it so cheap to calculate that it doesn't really matter?

On a related note, what would you suggest to resolve cases like this one below, where I have access to the parameter array of an invocation and would like to know the return type for that invocation? Of course the class param could be one of multiple parameters at different indexes and with different type variables.

<T> T create(Class<T> clazz)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants