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

Fixes #534: Refactored quick fixes and test cases for RemoveParamsProposal #575

Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ protected RemoveElementsProposal(String label, PsiFile sourceCU, PsiFile invocat
@Override
public final Change getChange() {
elementsToRemove.forEach(PsiElement::delete);
if(isFormatRequired) {
if (isFormatRequired) {
PositionUtils.formatDocument(binding); // fix up whitespace
}
final Document document = invocationNode.getViewProvider().getDocument();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,10 @@ public RemoveParamsProposal(String label, PsiFile sourceCU, PsiFile invocationNo
List<PsiParameter> parametersToRemove) {
super(label, sourceCU, invocationNode, binding, relevance, parametersToRemove);
}

public RemoveParamsProposal(String label, PsiFile sourceCU, PsiFile invocationNode,
PsiModifierListOwner binding, int relevance,
List<PsiParameter> parametersToRemove, boolean isFormatRequired) {
super(label, sourceCU, invocationNode, binding, relevance, parametersToRemove, isFormatRequired);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,41 +18,70 @@
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiParameterList;
import com.intellij.psi.util.PsiTreeUtil;
import io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.JDTUtils;
import io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.Messages;
import io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.codeAction.proposal.RemoveParamsProposal;
import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.codeaction.ExtendedCodeAction;
import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.codeaction.IJavaCodeActionParticipant;
import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.codeaction.JavaCodeActionContext;
import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.codeaction.JavaCodeActionResolveContext;
import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.corrections.proposal.ChangeCorrectionProposal;
import org.eclipse.lsp4j.CodeAction;
import org.eclipse.lsp4j.CodeActionKind;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.WorkspaceEdit;
import org.eclipse.lsp4mp.commons.CodeActionResolveData;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* Quickfix for removing all parameters from a method
*
* @author Zijian Pei
*/
public class RemoveMethodParametersQuickFix {
public class RemoveMethodParametersQuickFix implements IJavaCodeActionParticipant {

private static final String NAME = Messages.getMessage("RemoveAllParameters");
private static final Logger LOGGER = Logger.getLogger(RemoveMethodParametersQuickFix.class.getName());

@Override
public String getParticipantId() {
return RemoveMethodParametersQuickFix.class.getName();
}

public List<? extends CodeAction> getCodeActions(JavaCodeActionContext context, Diagnostic diagnostic) {

List<CodeAction> codeActions = new ArrayList<>();
final PsiElement node = context.getCoveredNode();
final PsiMethod parentMethod = PsiTreeUtil.getParentOfType(node, PsiMethod.class);
if (parentMethod != null) {
codeActions.add(JDTUtils.createCodeAction(context, diagnostic, NAME, getParticipantId()));
}
return codeActions;
}

@Override
public CodeAction resolveCodeAction(JavaCodeActionResolveContext context) {
final CodeAction toResolve = context.getUnresolved();
final PsiElement node = context.getCoveredNode();
final PsiClass parentType = PsiTreeUtil.getParentOfType(node, PsiClass.class);
final PsiMethod parentMethod = PsiTreeUtil.getParentOfType(node, PsiMethod.class);

if (parentMethod != null) {
final PsiParameterList parameterList = parentMethod.getParameterList();
if (parameterList != null && parameterList.getParametersCount() > 0) {
ChangeCorrectionProposal proposal = new RemoveParamsProposal(NAME, context.getSource().getCompilationUnit(),
context.getASTRoot(), parentType, 0, Arrays.asList(parameterList.getParameters()));
CodeAction codeAction = context.convertToCodeAction(proposal, diagnostic);
return Collections.singletonList(codeAction);
}
assert parentMethod != null;
final PsiParameterList parameterList = parentMethod.getParameterList();
ChangeCorrectionProposal proposal = new RemoveParamsProposal(NAME, context.getSource().getCompilationUnit(),
context.getASTRoot(), parentType, 0, Arrays.asList(parameterList.getParameters()), false);
try {
WorkspaceEdit we = context.convertToWorkspaceEdit(proposal);
toResolve.setEdit(we);
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Unable to create workspace edit for code action", e);
}
return Collections.emptyList();
return toResolve;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,21 @@

import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.JDTUtils;
import io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.Messages;
import io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.codeAction.proposal.RemoveParamsProposal;
import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.codeaction.IJavaCodeActionParticipant;
import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.codeaction.JavaCodeActionContext;
import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.codeaction.JavaCodeActionResolveContext;
import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.corrections.proposal.ChangeCorrectionProposal;
import org.eclipse.lsp4j.CodeAction;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.WorkspaceEdit;
import org.eclipse.lsp4mp.commons.CodeActionResolveData;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* Quick fix for the ResourceMethodMultipleEntityParams diagnostic in
Expand All @@ -35,54 +39,97 @@
* @author Bera Sogut
*
*/
public class ResourceMethodMultipleEntityParamsQuickFix {
public class ResourceMethodMultipleEntityParamsQuickFix implements IJavaCodeActionParticipant {

private static final Logger LOGGER = Logger.getLogger(ResourceMethodMultipleEntityParamsQuickFix.class.getName());
private static final String ENTITY_PARAM_INDEX_KEY = "entityParamIndex";
private static final String ENTITY_PARAM_INDEXES_KEY = "entityParamIndexes";

@Override
public String getParticipantId() {
return ResourceMethodMultipleEntityParamsQuickFix.class.getName();
}

public List<? extends CodeAction> getCodeActions(JavaCodeActionContext context, Diagnostic diagnostic) {

final PsiElement node = context.getCoveredNode();
final PsiMethod parentMethod = PsiTreeUtil.getParentOfType(node, PsiMethod.class);
final List<CodeAction> codeActions = new ArrayList<>();

if (parentMethod != null) {
final List<CodeAction> codeActions = new ArrayList<>();
final List<Integer> entityParamIndexes = new ArrayList<>();

final PsiParameterList parameterList = parentMethod.getParameterList();
if (parameterList != null && parameterList.getParametersCount() > 0) {
final PsiParameter[] parameters = parameterList.getParameters();
for (int i = 0; i < parameters.length; ++i) {
if (isEntityParam(parameters[i])) {
entityParamIndexes.add(i);
}
return addCodeActions(context, diagnostic, parentMethod, codeActions);
}
return codeActions;
}

private List<CodeAction> addCodeActions(JavaCodeActionContext context, Diagnostic diagnostic, PsiMethod parentMethod, List<CodeAction> codeActions) {
final List<Integer> entityParamIndexes = new ArrayList<>();
final PsiParameterList parameterList = parentMethod.getParameterList();
final PsiParameter[] parameters = parameterList.getParameters();
if (parameterList.getParametersCount() > 0) {
for (int i = 0; i < parameters.length; ++i) {
if (isEntityParam(parameters[i])) {
entityParamIndexes.add(i);
}
}
}
return iterateAndCreateCodeAction(context, diagnostic, codeActions, entityParamIndexes);
}

private List<CodeAction> iterateAndCreateCodeAction(JavaCodeActionContext context, Diagnostic diagnostic, List<CodeAction> codeActions, List<Integer> entityParamIndexes) {
entityParamIndexes.forEach(entityParamIndex -> {
addCreateCodeAction(context, diagnostic, codeActions, entityParamIndex, entityParamIndexes);
});
return codeActions;
}

private void addCreateCodeAction(JavaCodeActionContext context, Diagnostic diagnostic, List<CodeAction> codeActions, Integer entityParamIndex, List<Integer> entityParamIndexes) {
final JavaCodeActionContext targetContext = context.copy();
final PsiElement targetNode = targetContext.getCoveredNode();
final PsiParameter[] parameters = Objects.requireNonNull(PsiTreeUtil.getParentOfType(targetNode, PsiMethod.class)).getParameterList().getParameters();
final String title = getTitle(parameters[entityParamIndex]);
Map<String, Object> extendedData = new HashMap<>();
extendedData.put(ENTITY_PARAM_INDEX_KEY, entityParamIndex);
extendedData.put(ENTITY_PARAM_INDEXES_KEY, entityParamIndexes);
codeActions.add(JDTUtils.createCodeAction(context, diagnostic, title, getParticipantId(), extendedData));
}

private static String getTitle(PsiParameter parameters) {
return Messages.getMessage("RemoveAllEntityParametersExcept",
parameters.getName());
}

@Override
public CodeAction resolveCodeAction(JavaCodeActionResolveContext context) {
final CodeAction toResolve = context.getUnresolved();
final PsiElement node = context.getCoveredNode();
final PsiClass parentType = PsiTreeUtil.getParentOfType(node, PsiClass.class);
final PsiMethod parentMethod = PsiTreeUtil.getParentOfType(node, PsiMethod.class);
String title = toResolve.getTitle();
CodeActionResolveData data = (CodeActionResolveData) toResolve.getData();
Integer currentEntityParamIndex = (Integer) data.getExtendedDataEntry(ENTITY_PARAM_INDEX_KEY);
List<Integer> entityParamIndexes = (List<Integer>) data.getExtendedDataEntry(ENTITY_PARAM_INDEXES_KEY);

assert parentMethod != null;
final PsiParameter[] parameters = parentMethod.getParameterList().getParameters();

final List<PsiParameter> entityParams = new ArrayList<>();
entityParamIndexes.forEach(x -> {
if (!x.equals(currentEntityParamIndex)) {
entityParams.add(parameters[x]);
}
});

ChangeCorrectionProposal proposal = new RemoveParamsProposal(title, context.getSource().getCompilationUnit(),
context.getASTRoot(), parentType, 0, entityParams, false);

entityParamIndexes.forEach(entityParamIndex -> {
final JavaCodeActionContext targetContext = context.copy();
final PsiElement targetNode = targetContext.getCoveredNode();
final PsiClass parentType = PsiTreeUtil.getParentOfType(targetNode, PsiClass.class);
final PsiParameter[] parameters = PsiTreeUtil.getParentOfType(targetNode, PsiMethod.class).getParameterList().getParameters();

final String TITLE_MESSAGE = Messages.getMessage("RemoveAllEntityParametersExcept",
parameters[entityParamIndex].getName());

final List<PsiParameter> entityParams = new ArrayList<>();
entityParamIndexes.forEach(x -> {
if (!x.equals(entityParamIndex)) {
entityParams.add(parameters[x]);
}
});

ChangeCorrectionProposal proposal = new RemoveParamsProposal(TITLE_MESSAGE, targetContext.getSource().getCompilationUnit(),
targetContext.getASTRoot(), parentType, 0, entityParams);

// Convert the proposal to LSP4J CodeAction
CodeAction codeAction = targetContext.convertToCodeAction(proposal, diagnostic);
codeAction.setTitle(TITLE_MESSAGE);
codeActions.add(codeAction);
});
return codeActions;
try {
WorkspaceEdit we = context.convertToWorkspaceEdit(proposal);
toResolve.setEdit(we);
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Unable to create workspace edit for code action", e);
}
return Collections.emptyList();
return toResolve;
}

/**
Expand Down
15 changes: 15 additions & 0 deletions src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,21 @@
targetDiagnostic="jakarta-bean-validation#FixTypeOfElement"
implementationClass="io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.beanvalidation.BeanValidationQuickFix"/>

<javaCodeActionParticipant kind="quickfix"
group="jakarta"
targetDiagnostic="jakarta-jax_rs#ResourceMethodMultipleEntityParams"
implementationClass="io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.jax_rs.ResourceMethodMultipleEntityParamsQuickFix"/>

<javaCodeActionParticipant kind="quickfix"
group="jakarta"
targetDiagnostic="jakarta-annotations#PreDestroyParams"
implementationClass="io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.codeAction.proposal.quickfix.RemoveMethodParametersQuickFix"/>

<javaCodeActionParticipant kind="quickfix"
group="jakarta"
targetDiagnostic="jakarta-annotations#PostConstructParams"
implementationClass="io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.codeAction.proposal.quickfix.RemoveMethodParametersQuickFix"/>

<configSourceProvider
implementation="io.openliberty.tools.intellij.lsp4mp4ij.psi.internal.core.providers.MicroProfileConfigSourceProvider"/>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,31 @@ public void GeneratedAnnotation() throws Exception {

JakartaJavaCodeActionParams codeActionParams1 = createCodeActionParams(uri, d2);
TextEdit te1 = te(19, 4, 20, 4, "");
TextEdit te2 = te(20, 29, 20, 40, "");
CodeAction ca1 = ca(uri, "Remove @PostConstruct", d2, te1);
CodeAction ca2 = ca(uri, "Remove all parameters", d2, te2);
assertJavaCodeAction(codeActionParams1, utils, ca1, ca2);
assertJavaCodeAction(codeActionParams1, utils, ca1);

}

JakartaJavaCodeActionParams codeActionParams1 = createCodeActionParams(uri, d2);
String newText = "package io.openliberty.sample.jakarta.annotations;\n\n" +
"import jakarta.annotation.PostConstruct;\n" +
"import jakarta.annotation.Resource;\n\n" +
"@Resource(type = Object.class, name = \"aa\")\n" +
"public class PostConstructAnnotation {\n\n " +
"private Integer studentId;\n\n " +
"private boolean isHappy;\n\n " +
"private boolean isSad;\n\n " +
"@PostConstruct()\n " +
"public Integer getStudentId() {\n " +
"return this.studentId;\n }\n\n " +
"@PostConstruct\n " +
"public void getHappiness() {\n\n }\n\n " +
"@PostConstruct\n " +
"public void throwTantrum() throws Exception {\n " +
"System.out.println(\"I'm sad\");\n }\n\n " +
"private String emailAddress;\n\n}";
TextEdit te = te(0, 0, 31, 1, newText);
CodeAction ca = ca(uri, "Remove all parameters", d2, te);
assertJavaCodeAction(codeActionParams1, utils, ca);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,8 @@ public void GeneratedAnnotation() throws Exception {
if (CHECK_CODE_ACTIONS) {
JakartaJavaCodeActionParams codeActionParams = createCodeActionParams(uri, d1);
TextEdit te = te(19, 1, 20, 1, "");
TextEdit te1 = te(20, 29, 20, 40, "");
CodeAction ca = ca(uri, "Remove @PreDestroy", d1, te);
CodeAction ca1 = ca(uri, "Remove all parameters", d1, te1);
assertJavaCodeAction(codeActionParams, utils, ca, ca1);
assertJavaCodeAction(codeActionParams, utils, ca);

JakartaJavaCodeActionParams codeActionParams1 = createCodeActionParams(uri, d2);
TextEdit te2 = te(25, 1, 26, 1, "");
Expand All @@ -80,6 +78,34 @@ public void GeneratedAnnotation() throws Exception {
CodeAction ca3 = ca(uri, "Remove the 'static' modifier from this method", d2, te3);
assertJavaCodeAction(codeActionParams1, utils, ca2, ca3);
}

JakartaJavaCodeActionParams codeActionParams = createCodeActionParams(uri, d1);
String newText = "package io.openliberty.sample.jakarta.annotations;\n\n" +
"import jakarta.annotation.PreDestroy;\n" +
"import jakarta.annotation.Resource;\n\n" +
"@Resource(type = Object.class, name = \"aa\") \n" +
"public class PreDestroyAnnotation { \n\n " +
"private Integer studentId;\n \n " +
"private boolean isHappy;\n\n " +
"private boolean isSad;\n \n " +
"@PreDestroy()\n " +
"public Integer getStudentId() {\n " +
"return this.studentId;\n }\n \n " +
"@PreDestroy()\n " +
"public boolean getHappiness() {\n " +
"if (type.equals(\"happy\")) return this.isHappy;\n " +
"return this.isSad;\n }\n \n " +
"@PreDestroy()\n " +
"public static void makeUnhappy() {\n " +
"System.out.println(\"I'm sad\");\n }\n \n " +
"@PreDestroy()\n " +
"public void throwTantrum() throws Exception {\n " +
"System.out.println(\"I'm sad\");\n }\n\n\n " +
"private String emailAddress;\n\n\n}\n\n\n\n";

TextEdit te = te(0, 0, 43, 0, newText);
CodeAction ca = ca(uri, "Remove all parameters", d1, te);
assertJavaCodeAction(codeActionParams, utils, ca);
}

}
Loading
Loading