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

Java 8 ReflectionParanamer using compiled parameter names #42

Open
mjustin opened this issue Aug 27, 2021 · 1 comment
Open

Java 8 ReflectionParanamer using compiled parameter names #42

mjustin opened this issue Aug 27, 2021 · 1 comment

Comments

@mjustin
Copy link
Contributor

mjustin commented Aug 27, 2021

Now that this project is being upgraded to Java 8, it occurs to me that a Java 8 reflection-based paranamer could add some value, using the compiled parameters provided per the javac -parameters flag.

I can see a few scenarios where this would be useful, but I think the main one would be for code being run against classes that may or may not have been compiled using -parameters (e.g. third party libraries), and the developer wants to fall back to other strategies if the parameter names were not compiled. This could use an AdaptiveParanamer which wants to fall back to a different strategy if the parameters were not compiled. Note that this is the scenario I personally ran into that is causing me to take a look at Paranamer despite the Java 8 support for parameter names.

The implementation would be dirt simple:

package com.thoughtworks.paranamer;

import com.thoughtworks.paranamer.ParameterNamesNotFoundException;
import com.thoughtworks.paranamer.Paranamer;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Executable;
import java.lang.reflect.Parameter;
import java.util.Arrays;

public class ReflectionParanamer implements Paranamer {
    @Override
    public String[] lookupParameterNames(AccessibleObject methodOrConstructor) {
        return lookupParameterNames(methodOrConstructor, true);
    }

    @Override
    public String[] lookupParameterNames(AccessibleObject methodOrConstructor, boolean throwExceptionIfMissing) {
        Executable executable = (Executable) methodOrConstructor;
        Parameter[] parameters = executable.getParameters();
        if (Arrays.stream(parameters).anyMatch(p -> !p.isNamePresent())) {
            if (throwExceptionIfMissing) {
                throw new ParameterNamesNotFoundException("Parameter names not present: " + methodOrConstructor);
            } else {
                return Paranamer.EMPTY_NAMES;
            }
        }

        return Arrays.stream(parameters).map(Parameter::getName).toArray(String[]::new);
    }
}
@paul-hammant
Copy link
Owner

Pull requests accepted :)

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