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

Introduce support for creating a MethodParameter from a Java 8 Parameter [SPR-14055] #18627

Closed
spring-projects-issues opened this issue Mar 15, 2016 · 4 comments
Assignees
Labels
in: core type: enhancement
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

@spring-projects-issues spring-projects-issues commented Mar 15, 2016

Sam Brannen opened SPR-14055 and commented

Status Quo

A MethodParameter or SynthesizingMethodParameter can be created from a Method and an index; however, there is currently no first-class support for creating a MethodParameter from a java.lang.reflect.Parameter.

Related Resources

The MethodParameterFactory in the spring-test project has factory methods for creating a MethodParameter or SynthesizingMethodParameter from a Java 8 Parameter.

The trick involves retrieving the java.lang.reflect.Executable from the supplied Parameter and then determining the index of the corresponding parameter.

The following code excerpts demonstrate the technique.

public static MethodParameter createMethodParameter(Parameter parameter) {
	Assert.notNull(parameter, "Parameter must not be null");
	Executable executable = parameter.getDeclaringExecutable();
	if (executable instanceof Method) {
		return new MethodParameter((Method) executable, getIndex(parameter));
	}
	// else
	return new MethodParameter((Constructor<?>) executable, getIndex(parameter));
}

private static int getIndex(Parameter parameter) {
	Assert.notNull(parameter, "Parameter must not be null");
	Executable executable = parameter.getDeclaringExecutable();
	Parameter[] parameters = executable.getParameters();
	for (int i = 0; i < parameters.length; i++) {
		if (parameters[i] == parameter) {
			return i;
		}
	}
	throw new IllegalStateException(String.format("Failed to resolve index of parameter [%s] in executable [%s]",
		parameter, executable.toGenericString()));
}

Deliverables

  1. Support creation of a MethodParameter from a java.lang.reflect.Parameter.
  2. Support creation of a SynthesizingMethodParameter from a java.lang.reflect.Parameter.

Issue Links:

  • #18151 Introduce support for JUnit 5 in the TestContext framework ("is depended on by")
  • #18626 Support creation of SynthesizingMethodParameter for constructor parameter
  • #19009 MethodParameter should not be equal to SynthesizingMethodParameter
  • #18036 Validate method parameter index via Java 8 Method.getParameterCount()

Referenced from: commits 7e783dd, 5f53a60, 39e3f2e

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Mar 15, 2016

Sam Brannen commented

This issue is related to #18626.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Mar 15, 2016

Juergen Hoeller commented

I'm leaning towards only doing this in 5.0 but then rearchitecting MethodParameter on java.lang.reflect.Parameter to begin with: internally just using Parameter but allowing construction from a given Method / Constructor and an index (which then just leads to immediate Parameter lookup for all subsequent purposes).

This would also allow us to simply introduce overloaded MethodParameter / SynthesizingMethodParameter constructors which accept a Parameter argument, with no need for a separate factory class. For that reason in particular, I'd rather only do it in 5.0.

Juergen

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Mar 16, 2016

Sam Brannen commented

Sounds good, Juergen.

I'd also like to avoid the introduction for a factory for this. I only introduced the factory in spring-test-junit5 in order to have better separation of concerns.

In any case, spring-test-junit5 has an interim solution for this until it's officially supported in Spring 5.

Cheers,

Sam

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Jul 6, 2016

Juergen Hoeller commented

I ended up adapting from Parameter since that class is no more sophisticated in its metadata caching than our MethodParameter is already. Also, we couldn't point to a return type (parameter index -1) in a uniform way then.

So as of 5.0, MethodParameter and SynthesizingMethodParameter have corresponding forParameter(Parameter)) factory methods, as well as forExecutable(Executable, parameterIndex)) as a replacement for the now-deprecated forMethodOrConstructor.

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

No branches or pull requests

2 participants