Skip to content

Add constructor calls to RemoveMethodInvocations #5267

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

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

davidh44
Copy link

@davidh44 davidh44 commented Apr 8, 2025

Recipe RemoveMethodInvocations currently does not cover constructor calls. This PR adds functionality for that

What's your motivation?

Would like to remove certain POJO instantiations.

Have you considered any alternatives or workarounds?

As a workaround for my use case, I used a JavaVisitor, checked the JavaType, and returned null.

@timtebeek
Copy link
Member

Thanks for the runnable example! Had a brief look. We'll likely need to add something like

    @Override
    public J visitNewClass(J.NewClass newClass, ExecutionContext ctx) {
        J nc = super.visitNewClass(newClass, ctx);
        
        // TODO
        
        return nc;
    }

And then do something very similar to

@Override
public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) {
J.MethodInvocation m = (J.MethodInvocation) super.visitMethodInvocation(method, ctx);
if (inMethodCallChain()) {
List<Expression> newArgs = ListUtils.map(m.getArguments(), arg -> (Expression) this.visit(arg, ctx));
return m.withArguments(newArgs);
}
J j = removeMethods(m, 0, isLambdaBody(), new Stack<>());
if (j != null) {
j = j.withPrefix(m.getPrefix());
// There should always be
if (!m.getArguments().isEmpty() && m.getArguments().stream().allMatch(ToBeRemoved::hasMarker)) {
return ToBeRemoved.withMarker(j);
}
}
//noinspection DataFlowIssue allow returning null to remove the element
return j;
}

Where we need a bit more care is to adapt

private @Nullable J removeMethods(@Nullable Expression expression, int depth, boolean isLambdaBody, Stack<Space> selectAfter) {
if (!(expression instanceof J.MethodInvocation) || ((J.MethodInvocation) expression).getMethodType() == null) {
return expression;
}

As right now we'd fail on that first conditional; we need to also allow where expression instanceof J.NewClass.

@timtebeek timtebeek added enhancement New feature or request recipe Requested Recipe labels Apr 8, 2025
@davidh44 davidh44 changed the title Add RemoveMethodInvocationsTest for constructor call Add constructor calls to RemoveMethodInvocations Apr 9, 2025
@davidh44
Copy link
Author

davidh44 commented Apr 9, 2025

Added logic for constructor removal and additional tests.

Two issues came up, wondering if you could provide some pointers:

a)
Given that almost all constructor calls will be assigned to a variable, how can we remove the entire line? Should we use visitVariableDeclaration()? Can we view the assignment method there?

b)
As above, we want to remove the entire line, including chained method calls, e.g., new Date().toInstant(). What's the proper way to get rid of the chained method calls?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request recipe Requested Recipe
Projects
Status: In Progress
Development

Successfully merging this pull request may close these issues.

2 participants