diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethodObject/ExtractLightMethodObjectHandler.java b/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethodObject/ExtractLightMethodObjectHandler.java index 96db089e7ac9..24a25b923abf 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethodObject/ExtractLightMethodObjectHandler.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethodObject/ExtractLightMethodObjectHandler.java @@ -130,9 +130,7 @@ public final class ExtractLightMethodObjectHandler { PsiElement lastElement = ArrayUtil.getLastElement(elementsCopy); if (lastElement instanceof PsiExpressionStatement expressionStatement) { PsiExpression expr = expressionStatement.getExpression(); - if (!(expr instanceof PsiAssignmentExpression)) { - generateResult(project, expr, elementsCopy, elementFactory); - } + generateResult(project, expr, elementsCopy, elementFactory); } else if (lastElement instanceof PsiReturnStatement returnStatement) { PsiExpression expr = returnStatement.getReturnValue(); diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethodObject/reflect/FieldDescriptor.java b/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethodObject/reflect/FieldDescriptor.java index 15937dcc855b..6df8cda33876 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethodObject/reflect/FieldDescriptor.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethodObject/reflect/FieldDescriptor.java @@ -70,7 +70,7 @@ public final class FieldDescriptor implements ItemToReplaceDescriptor { outerClass.add(newMethod); String object = MemberQualifierUtil.findObjectExpression(myExpression, myField, outerClass, generatedCall, elementFactory); - String methodCall = newMethod.getName() + "(" + (object == null ? "null" : object) + ", null)"; + String methodCall = newMethod.getName() + "(" + object + ")"; myExpression.replace(elementFactory.createExpressionFromText(methodCall, myExpression)); } @@ -90,8 +90,7 @@ public final class FieldDescriptor implements ItemToReplaceDescriptor { String newValue = rightExpression.getText(); String objectForReference = MemberQualifierUtil.findObjectExpression(myExpression, myField, outerClass, generatedCall, elementFactory); - String args = (objectForReference == null ? "null" : objectForReference) + ", " + newValue; - String methodCallExpression = newMethod.getName() + "(" + args + ")"; + String methodCallExpression = newMethod.getName() + "(" + objectForReference + ", " + newValue + ")"; PsiExpression newMethodCallExpression = elementFactory.createExpressionFromText(methodCallExpression, myExpression); assignmentExpression.replace(newMethodCallExpression); @@ -109,16 +108,20 @@ public final class FieldDescriptor implements ItemToReplaceDescriptor { String methodName = PsiReflectionAccessUtil.getUniqueMethodName(outerClass, "accessToField" + StringUtil.capitalize(fieldName)); ReflectionAccessMethodBuilder methodBuilder = new ReflectionAccessMethodBuilder(methodName); if (FieldAccessType.GET.equals(accessType)) { - methodBuilder.accessedField(className, fieldName).setReturnType(myAccessibleType); + methodBuilder.accessedField(className, fieldName); } else { - methodBuilder.updatedField(className, fieldName) - .setReturnType("void"); + methodBuilder.updatedField(className, fieldName); } - methodBuilder.setStatic(outerClass.hasModifierProperty(PsiModifier.STATIC)) - .addParameter(CommonClassNames.JAVA_LANG_OBJECT, "object") - .addParameter(CommonClassNames.JAVA_LANG_OBJECT, "value"); + methodBuilder + .setReturnType(myAccessibleType) + .setStatic(outerClass.hasModifierProperty(PsiModifier.STATIC)) + .addParameter(CommonClassNames.JAVA_LANG_OBJECT, "object"); + + if (!FieldAccessType.GET.equals(accessType)) { + methodBuilder.addParameter(myAccessibleType, "value"); + } return methodBuilder.build(elementFactory, outerClass); } diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethodObject/reflect/MethodDescriptor.java b/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethodObject/reflect/MethodDescriptor.java index bd1074616efe..341a5c0a9a80 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethodObject/reflect/MethodDescriptor.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethodObject/reflect/MethodDescriptor.java @@ -1,4 +1,4 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.refactoring.extractMethodObject.reflect; import com.intellij.openapi.diagnostic.Logger; @@ -69,7 +69,7 @@ public class MethodDescriptor implements ItemToReplaceDescriptor { .findObjectExpression(myCallExpression.getMethodExpression(), myMethod, outerClass, callExpression, elementFactory); String args = StreamEx.of(myCallExpression.getArgumentList().getExpressions()) .map(x -> x.getText()) - .prepend(objectToCallOn == null ? "null" : objectToCallOn) + .prepend(objectToCallOn) .joining(", ", "(", ")"); String newMethodCallExpression = newMethod.getName() + args; diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethodObject/reflect/ReflectionAccessMethodBuilder.java b/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethodObject/reflect/ReflectionAccessMethodBuilder.java index 76f014c2143e..4e5f44e3cd77 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethodObject/reflect/ReflectionAccessMethodBuilder.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethodObject/reflect/ReflectionAccessMethodBuilder.java @@ -195,13 +195,11 @@ public class ReflectionAccessMethodBuilder { private static abstract class MyMemberAccessor implements MyBodyProvider { abstract String getMemberLookupExpression(); abstract String getClassLookupExpression(); - abstract String getAccessExpression(); + abstract String getReturnExpression(String returnType); abstract String getMemberType(); @Override public String createBody(String returnType) { - String returnExpression = - ("void".equals(returnType) ? "member." : "return (" + returnType + ")member.") + getAccessExpression(); return " java.lang.Class klass = " + getClassLookupExpression() + ";\n" + " " + getMemberType() + " member = null;\n" + " int interfaceNumber = -1;\n" + @@ -225,7 +223,7 @@ public class ReflectionAccessMethodBuilder { " }\n" + " }\n" + " member.setAccessible(true);\n" + - " " + returnExpression + ";\n"; + " " + getReturnExpression(returnType) + ";\n"; } } @@ -254,8 +252,10 @@ public class ReflectionAccessMethodBuilder { } @Override - public String getAccessExpression() { - return FieldAccessType.GET.equals(myAccessType) ? "get(object)" : "set(object, value)"; + String getReturnExpression(String returnType) { + return FieldAccessType.GET.equals(myAccessType) + ? "return (" + returnType + ")member.get(object)" + : "member.set(object, value); \n return value"; } @Override @@ -303,8 +303,9 @@ public class ReflectionAccessMethodBuilder { } @Override - public String getAccessExpression() { - return "invoke" + parametersStringForInvoke(); + String getReturnExpression(String returnType) { + String invokeString = "member.invoke" + parametersStringForInvoke(); + return "void".equals(returnType) ? invokeString : "return (" + returnType + ")" + invokeString; } } @@ -327,8 +328,8 @@ public class ReflectionAccessMethodBuilder { } @Override - public String getAccessExpression() { - return "newInstance" + parametersStringForInvoke(); + String getReturnExpression(String returnType) { + return "return (" + returnType + ")member.newInstance" + parametersStringForInvoke(); } @Override diff --git a/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/accessField.out b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/accessField.out index be0f204d69d2..94ec0cfe20fd 100644 --- a/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/accessField.out +++ b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/accessField.out @@ -7,7 +7,7 @@ public class GeneratedEvaluationClass { this.instance = instance; } - public static int accessToFieldField1(Object object, Object value) { + public static int accessToFieldField1(Object object) { try { Class klass = Class.forName("WithReflectionAccess"); java.lang.reflect.Field member = null; @@ -39,6 +39,6 @@ public class GeneratedEvaluationClass { } public void invoke() { - System.out.println(accessToFieldField1(instance, null)); + System.out.println(accessToFieldField1(instance)); } } \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/twiceAccessToTheSameField.out b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/twiceAccessToTheSameField.out index a0fbee58769e..b3f3ceb34625 100644 --- a/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/twiceAccessToTheSameField.out +++ b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/twiceAccessToTheSameField.out @@ -7,7 +7,7 @@ public class GeneratedEvaluationClass { this.instance = instance; } - public static int accessToFieldField1(Object object, Object value) { + public static int accessToFieldField1(Object object) { try { Class klass = Class.forName("WithReflectionAccess"); java.lang.reflect.Field member = null; @@ -38,7 +38,7 @@ public class GeneratedEvaluationClass { } } - public static int accessToFieldField2(Object object, Object value) { + public static int accessToFieldField2(Object object) { try { Class klass = Class.forName("WithReflectionAccess"); java.lang.reflect.Field member = null; @@ -70,6 +70,6 @@ public class GeneratedEvaluationClass { } public int invoke() { - return accessToFieldField1(instance, null) + accessToFieldField2(instance, null); + return accessToFieldField1(instance) + accessToFieldField2(instance); } } \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/updateField.out b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/updateField.out index 8fdc28c7ba19..bc097a6a9162 100644 --- a/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/updateField.out +++ b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/updateField.out @@ -1,4 +1,4 @@ -call text: new Test(instance).invoke(); +call text: int result = new Test(instance).invoke(); class: public class GeneratedEvaluationClass { private Object instance; @@ -7,7 +7,7 @@ public class GeneratedEvaluationClass { this.instance = instance; } - public static void accessToFieldField1(Object object, Object value) { + public static int accessToFieldField1(Object object, int value) { try { Class klass = Class.forName("WithReflectionAccess"); java.lang.reflect.Field member = null; @@ -33,12 +33,13 @@ public class GeneratedEvaluationClass { } member.setAccessible(true); member.set(object, value); + return value; } catch (ReflectiveOperationException e) { throw new RuntimeException(e); } } - public void invoke() { - accessToFieldField1(instance, 50); + public int invoke() { + return accessToFieldField1(instance, 50); } } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodObject4DebuggerTest.java b/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodObject4DebuggerTest.java index 696fa464dff4..75ee135ceb23 100644 --- a/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodObject4DebuggerTest.java +++ b/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodObject4DebuggerTest.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.java.refactoring; @@ -102,24 +88,29 @@ public class ExtractMethodObject4DebuggerTest extends LightRefactoringTestCase { } public void testInvokeReturnType() throws Exception { - doTest("x = 6; y = 6;", "Test test = new Test().invoke();x = test.getX();y = test.getY();", + doTest("x = 6; y = 6;", "Test test = new Test().invoke();x = test.getX();y = test.getY();int result = test.getResult();", """ static class Test { private int x; private int y; - + private int result; + public int getX() { return x; } - + public int getY() { return y; } - + + public int getResult() { + return result; + } + public Test invoke() { x = 6; - y = 6; + result = y = 6; return this; } }""");