diff --git a/rewrite-java-test/src/test/java/org/openrewrite/java/ReorderMethodArgumentsTest.java b/rewrite-java-test/src/test/java/org/openrewrite/java/ReorderMethodArgumentsTest.java index e17ce740684..1d6e4fb5971 100644 --- a/rewrite-java-test/src/test/java/org/openrewrite/java/ReorderMethodArgumentsTest.java +++ b/rewrite-java-test/src/test/java/org/openrewrite/java/ReorderMethodArgumentsTest.java @@ -167,4 +167,48 @@ public void test() { ) ); } + + @Test + void reorderArgumentsOnConstructor() { + rewriteRun( + spec -> spec.recipes( + new ReorderMethodArguments("a.A (String, Integer, Integer)", + new String[]{"n", "m", "s"}, null, null, null)), + java( + """ + package a; + public class A extends Exception { + public A(String s, Integer m, Integer n) {} + public A(Integer n, Integer m, String s) {} + } + """ + ), + java( + """ + import a.A; + public class B { + public void test() { + throw new A( + "mystring", + 1, + 2 + ); + } + } + """, + """ + import a.A; + public class B { + public void test() { + throw new A( + 2, + 1, + "mystring" + ); + } + } + """ + ) + ); + } } diff --git a/rewrite-java/src/main/java/org/openrewrite/java/ReorderMethodArguments.java b/rewrite-java/src/main/java/org/openrewrite/java/ReorderMethodArguments.java index 405b4c70a56..2a00d92e287 100644 --- a/rewrite-java/src/main/java/org/openrewrite/java/ReorderMethodArguments.java +++ b/rewrite-java/src/main/java/org/openrewrite/java/ReorderMethodArguments.java @@ -123,7 +123,6 @@ private ReorderMethodArgumentsVisitor(MethodMatcher methodMatcher) { @Override public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { J.MethodInvocation m = super.visitMethodInvocation(method, ctx); - if (methodMatcher.matches(m) && m.getMethodType() != null) { @SuppressWarnings("ConstantConditions") List paramNames = oldParameterNames == null || oldParameterNames.length == 0 ? @@ -133,51 +132,14 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Execu List> originalArgs = m.getPadding().getArguments().getPadding().getElements(); int resolvedParamCount = m.getMethodType().getParameterTypes().size(); - int i = 0; List> reordered = new ArrayList<>(originalArgs.size()); List reorderedNames = new ArrayList<>(originalArgs.size()); List reorderedTypes = new ArrayList<>(originalArgs.size()); List formattings = new ArrayList<>(originalArgs.size()); List rightFormattings = new ArrayList<>(originalArgs.size()); - for (String name : newParameterNames) { - int fromPos = paramNames.indexOf(name); - if (originalArgs.size() > resolvedParamCount && fromPos == resolvedParamCount - 1) { - // this is a varargs argument - List> varargs = originalArgs.subList(fromPos, originalArgs.size()); - reordered.addAll(varargs); - for (int j = 0; j < varargs.size(); j++) { - reorderedNames.add(name + j); - reorderedTypes.add(varargs.get(j).getElement().getType()); - } - for (JRightPadded exp : originalArgs.subList(i, (i++) + varargs.size())) { - formattings.add(exp.getElement().getPrefix()); - rightFormattings.add(exp.getAfter()); - } - } else if (fromPos >= 0 && originalArgs.size() > fromPos) { - JRightPadded originalArg = originalArgs.get(fromPos); - reordered.add(originalArg); - reorderedNames.add(name); - reorderedTypes.add(originalArg.getElement().getType()); - formattings.add(originalArgs.get(i).getElement().getPrefix()); - rightFormattings.add(originalArgs.get(i++).getAfter()); - } - } - - boolean changed = false; - i = 0; - for (JRightPadded expression : reordered) { - final int index = i; - reordered.set(i, expression - .map(e -> e.withPrefix(formattings.get(index))) - .withAfter(rightFormattings.get(index))); - if (reordered.get(i) != originalArgs.get(i)) { - changed = true; - } - i++; - } - - if (changed) { + reorder(paramNames, originalArgs, resolvedParamCount, reordered, reorderedNames, reorderedTypes, formattings, rightFormattings); + if (isChanged(originalArgs, reordered, formattings, rightFormattings)) { m = m.getPadding() .withArguments(m.getPadding().getArguments().getPadding().withElements(reordered)) .withMethodType(m.getMethodType() @@ -188,5 +150,91 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Execu } return m; } + + @Override + public J.NewClass visitNewClass(J.NewClass newClass, ExecutionContext ctx) { + J.NewClass n = super.visitNewClass(newClass, ctx); + if (methodMatcher.matches(n) && n.getMethodType() != null) { + @SuppressWarnings("ConstantConditions") List paramNames = + oldParameterNames == null || oldParameterNames.length == 0 ? + n.getMethodType().getParameterNames() : + asList(oldParameterNames); + + List> originalArgs = n.getPadding().getArguments().getPadding().getElements(); + int resolvedParamCount = n.getMethodType().getParameterTypes().size(); + + List> reordered = new ArrayList<>(originalArgs.size()); + List reorderedNames = new ArrayList<>(originalArgs.size()); + List reorderedTypes = new ArrayList<>(originalArgs.size()); + List formattings = new ArrayList<>(originalArgs.size()); + List rightFormattings = new ArrayList<>(originalArgs.size()); + + reorder(paramNames, originalArgs, resolvedParamCount, reordered, reorderedNames, reorderedTypes, formattings, rightFormattings); + if (isChanged(originalArgs, reordered, formattings, rightFormattings)) { + n = n.getPadding() + .withArguments(n.getPadding().getArguments().getPadding().withElements(reordered)) + .withMethodType(n.getMethodType() + .withParameterNames(reorderedNames) + .withParameterTypes(reorderedTypes) + ); + } + } + return n; + } + + private void reorder( + List paramNames, + List> originalArgs, + int resolvedParamCount, + List> reordered, + List reorderedNames, + List reorderedTypes, + List formattings, + List rightFormattings) { + int i = 0; + for (String name : newParameterNames) { + int fromPos = paramNames.indexOf(name); + if (originalArgs.size() > resolvedParamCount && fromPos == resolvedParamCount - 1) { + // this is a varargs argument + List> varargs = originalArgs.subList(fromPos, originalArgs.size()); + reordered.addAll(varargs); + for (int j = 0; j < varargs.size(); j++) { + reorderedNames.add(name + j); + reorderedTypes.add(varargs.get(j).getElement().getType()); + } + for (JRightPadded exp : originalArgs.subList(i, (i++) + varargs.size())) { + formattings.add(exp.getElement().getPrefix()); + rightFormattings.add(exp.getAfter()); + } + } else if (fromPos >= 0 && originalArgs.size() > fromPos) { + JRightPadded originalArg = originalArgs.get(fromPos); + reordered.add(originalArg); + reorderedNames.add(name); + reorderedTypes.add(originalArg.getElement().getType()); + formattings.add(originalArgs.get(i).getElement().getPrefix()); + rightFormattings.add(originalArgs.get(i++).getAfter()); + } + } + } + + private boolean isChanged( + List> originalArgs, + List> reordered, + List formattings, + List rightFormattings) { + boolean changed = false; + int j = 0; + for (JRightPadded expression : reordered) { + final int index = j; + reordered.set(j, expression + .map(e -> e.withPrefix(formattings.get(index))) + .withAfter(rightFormattings.get(index))); + if (reordered.get(j) != originalArgs.get(j)) { + changed = true; + } + j++; + } + return changed; + } } }