[debugger] fixed compiling evaluator cases with assignment return

GitOrigin-RevId: a3c2e127b2f240d2e0537be545ead539812d6517
This commit is contained in:
Egor Ushakov
2025-05-23 20:52:09 +00:00
committed by intellij-monorepo-bot
parent 8b6dd5ef89
commit 7af2822d11
8 changed files with 47 additions and 53 deletions
@@ -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();
@@ -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);
}
@@ -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;
@@ -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
@@ -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));
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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;
}
}""");