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 #512 - Transform the Quick Fixes which extends InsertAnnotationQuickFix to implement the code action participant extension point #523

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
39df73d
Fixes #196
anusreelakshmi934 Sep 8, 2023
a395d29
FIXES #196
anusreelakshmi934 Sep 8, 2023
34f94aa
Update src/main/java/io/openliberty/tools/intellij/util/Constants.java
anusreelakshmi934 Sep 9, 2023
0c37098
Update src/main/java/io/openliberty/tools/intellij/lsp4mp/lsp4ij/serv…
anusreelakshmi934 Sep 11, 2023
a7e87ba
Changes mentioned #196
anusreelakshmi934 Sep 12, 2023
f404759
changes#196
anusreelakshmi934 Sep 19, 2023
498eab3
checkJavaHome return method #196
anusreelakshmi934 Sep 19, 2023
2b452f1
message exported to LibertyBundles.properties #196
anusreelakshmi934 Sep 22, 2023
29389db
Merge branch 'main' into bugfix/#196
TrevCraw Sep 22, 2023
92b2826
Changed the error popup icon to Liberty icon #196
anusreelakshmi934 Sep 26, 2023
956f008
Fixed editing error #196
anusreelakshmi934 Sep 27, 2023
586068e
Merge pull request #493 from anusreelakshmi934/bugfix/#196
anusreelakshmi934 Sep 28, 2023
d348a99
Refactored the InsertAnnotationQuickfix class
aparnamichael Sep 29, 2023
f0f88ab
Added extension point in plugin.xml for AddPathParamsAnnotation
aparnamichael Sep 29, 2023
75b84f1
enabled the code action test case and updated test case
aparnamichael Sep 29, 2023
0f20360
Enabled quick fix testcase and updated the expected value
aparnamichael Oct 4, 2023
a1c53af
Added extension point for AddResourceMissingName and AddResourceMissi…
aparnamichael Oct 9, 2023
0a1e862
Formatted the newly added code and added back the removed comment
aparnamichael Oct 9, 2023
a96dae4
Merge remote-tracking branch 'upstream/main' into issue25_refactor_-I…
aparnamichael Oct 12, 2023
b27b3c8
Revert "Merge remote-tracking branch 'upstream/main' into issue25_ref…
aparnamichael Oct 12, 2023
1b5f461
updated the resource annotation test
aparnamichael Oct 17, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,9 @@ public class AddResourceMissingNameQuickFix extends InsertAnnotationAttributesQu
public AddResourceMissingNameQuickFix() {
super("jakarta.annotation.Resource", false, "name");
}

@Override
public String getParticipantId() {
return AddResourceMissingNameQuickFix.class.getName();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,9 @@ public class AddResourceMissingTypeQuickFix extends InsertAnnotationAttributesQu
public AddResourceMissingTypeQuickFix() {
super("jakarta.annotation.Resource", false, "type");
}

@Override
public String getParticipantId() {
return AddResourceMissingTypeQuickFix.class.getName();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
* @author Lidia Ataupillco Ramos
*
*/
public class InsertAnnotationAttributesQuickFix extends InsertAnnotationQuickFix {
public abstract class InsertAnnotationAttributesQuickFix extends InsertAnnotationQuickFix {
public InsertAnnotationAttributesQuickFix(String annotation, String... attributes) {
this(annotation, false, attributes);
}
Expand All @@ -29,7 +29,8 @@ public InsertAnnotationAttributesQuickFix(String annotation, boolean generateOnl
super(annotation, generateOnlyOneCodeAction, attributes);
}

//@Override
@Override
protected String getLabel(String annotation, String... attributes) {
return Messages.getMessage("AddAtoB", attributes[0], annotation); }

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,23 @@
import com.intellij.psi.util.PsiTreeUtil;
import io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.Messages;
import io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.codeAction.proposal.ModifyAnnotationProposal;
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 adding new annotations with or without attributes
Expand All @@ -33,14 +42,16 @@
* @author Lidia Ataupillco Ramos
*
*/
public class InsertAnnotationQuickFix {
public abstract class InsertAnnotationQuickFix implements IJavaCodeActionParticipant {

private final String[] attributes;

private final String annotation;

protected final boolean generateOnlyOneCodeAction;

private static final Logger LOGGER = Logger.getLogger(InsertAnnotationQuickFix.class.getName());

public InsertAnnotationQuickFix(String annotation, String... attributes) {
this(annotation, false, attributes);
}
Expand All @@ -62,23 +73,38 @@ public InsertAnnotationQuickFix(String annotation, boolean generateOnlyOneCodeAc

public List<? extends CodeAction> getCodeActions(JavaCodeActionContext context, Diagnostic diagnostic) {
PsiElement node = context.getCoveredNode();
List<CodeAction> codeActions = new ArrayList<>();
addAttributes(diagnostic, context, codeActions, this.annotation);
return codeActions;
}

@Override
public CodeAction resolveCodeAction(JavaCodeActionResolveContext context) {
final CodeAction toResolve = context.getUnresolved();
final PsiElement node = context.getCoveredNode();
PsiModifierListOwner binding = getBinding(node);
// annotationNode is null when adding an annotation and non-null when adding attributes.
PsiAnnotation annotationNode = PsiTreeUtil.getParentOfType(node, PsiAnnotation.class);

List<CodeAction> codeActions = new ArrayList<>();
addAttributes(diagnostic, context, binding, annotationNode, codeActions, this.annotation);

return codeActions;
assert binding != null;
String label = getLabel(this.annotation, attributes);
ChangeCorrectionProposal proposal = new ModifyAnnotationProposal(label, context.getSource().getCompilationUnit(),
context.getASTRoot(), binding, annotationNode, 0, this.annotation, Arrays.asList(attributes));
try {
WorkspaceEdit we = context.convertToWorkspaceEdit(proposal);
toResolve.setEdit(we);
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Unable to create workspace edit for code action " + label, e);
}
return toResolve;
}

protected void addAttributes(Diagnostic diagnostic, JavaCodeActionContext context, PsiModifierListOwner binding,
PsiAnnotation annotation, List<CodeAction> codeActions, String name) {
protected void addAttributes(Diagnostic diagnostic, JavaCodeActionContext context, List<CodeAction> codeActions, String name) {
if (generateOnlyOneCodeAction) {
addAttribute(diagnostic, context, binding, annotation, codeActions, name, attributes);
addAttribute(diagnostic, context, codeActions, name, attributes);
} else {
for (String attribute : attributes) {
addAttribute(diagnostic, context, binding, annotation, codeActions, name, attribute);
addAttribute(diagnostic, context, codeActions, name, attribute);
}
}
}
Expand All @@ -88,16 +114,9 @@ protected void addAttributes(Diagnostic diagnostic, JavaCodeActionContext contex
* collector class.
*
*/
private void addAttribute(Diagnostic diagnostic, JavaCodeActionContext context, PsiModifierListOwner binding,
PsiAnnotation annotation, List<CodeAction> codeActions, String name, String... attributes) {
private void addAttribute(Diagnostic diagnostic, JavaCodeActionContext context, List<CodeAction> codeActions, String name, String... attributes) {
String label = getLabel(name, attributes);
ChangeCorrectionProposal proposal = new ModifyAnnotationProposal(label, context.getSource().getCompilationUnit(),
context.getASTRoot(), binding, annotation, 0, name, Arrays.asList(attributes));
CodeAction codeAction = context.convertToCodeAction(proposal, diagnostic);

if (codeAction != null) {
codeActions.add(codeAction);
}
codeActions.add(createCodeAction(context, diagnostic, label));
}

protected PsiModifierListOwner getBinding(PsiElement node) {
Expand All @@ -112,4 +131,16 @@ protected PsiModifierListOwner getBinding(PsiElement node) {
protected String getLabel(String annotationName, String... attributes) {
return Messages.getMessage("InsertItem", "@" + annotation); // uses Java syntax
}

private CodeAction createCodeAction(JavaCodeActionContext context, Diagnostic diagnostic, String label) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mrglavas - can we raise a separate PR for moving this method to a common file?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aparnamichael Yes. Feel free to open a separate issue and PR for this. Thanks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created PR for the same - #531

ExtendedCodeAction codeAction = new ExtendedCodeAction(label);
codeAction.setRelevance(0);
codeAction.setDiagnostics(Collections.singletonList(diagnostic));
codeAction.setKind(CodeActionKind.QuickFix);
codeAction.setData(new CodeActionResolveData(context.getUri(), getParticipantId(),
context.getParams().getRange(), Collections.emptyMap(),
context.getParams().isResourceOperationSupported(),
context.getParams().isCommandConfigurationUpdateSupported()));
return codeAction;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,9 @@ public class AddPathParamQuickFix extends InsertAnnotationQuickFix {
public AddPathParamQuickFix() {
super("jakarta.websocket.server.PathParam", false, "value");
}

@Override
public String getParticipantId() {
return AddPathParamQuickFix.class.getName();
}
}
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 @@ -167,6 +167,21 @@
targetDiagnostic="jakarta-jax_rs#NonPublicResourceMethod"
implementationClass="io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.jax_rs.NonPublicResourceMethodQuickFix"/>

<javaCodeActionParticipant kind="quickfix"
group="jakarta"
targetDiagnostic="jakarta-websocket#AddPathParamsAnnotation"
implementationClass="io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.websocket.AddPathParamQuickFix"/>

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

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

<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 @@ -60,16 +60,38 @@ public void ResourceAnnotation() throws Exception {

assertJavaDiagnostics(diagnosticsParams, utils, d1, d2);

if (CHECK_CODE_ACTIONS) {
JakartaJavaCodeActionParams codeActionParams = createCodeActionParams(uri, d1);
TextEdit te = te(22, 0, 22, 22, "@Resource(name = \"aa\", type = \"\")");
CodeAction ca = ca(uri, "Add type to jakarta.annotation.Resource", d1, te);
assertJavaCodeAction(codeActionParams, utils, ca);
//TODO: uncomment this if condition, once refactoring is done for all the quick fixes.
// if (CHECK_CODE_ACTIONS) {
JakartaJavaCodeActionParams codeActionParams = createCodeActionParams(uri, d1);
String newText = "package io.openliberty.sample.jakarta.annotations;\n\nimport jakarta.annotation.Resource;" +
"\n\n@Resource(type = Object.class, name = \"aa\")\npublic class ResourceAnnotation " +
"{\n\n private Integer studentId;\n\n\n @Resource(shareable = true)\n " +
"private boolean isHappy;\n\n @Resource(name = \"test\")\n " +
" private boolean isSad;\n\n\n private String emailAddress;\n\n\n}\n\n" +
"@Resource(name = \"aa\",type=\"\")\nclass PostDoctoralStudent {\n\n " +
"private Integer studentId;\n\n\n @Resource(shareable = true)\n " +
"private boolean isHappy;\n\n @Resource\n private boolean isSad;\n\n\n " +
"private String emailAddress;\n\n}\n\n@Resource(type = Object.class)\nclass " +
"MasterStudent {\n\n private Integer studentId;\n\n} \n";
TextEdit te = te(0, 0, 45, 0, newText);
CodeAction ca = ca(uri, "Add type to jakarta.annotation.Resource", d1, te);
assertJavaCodeAction(codeActionParams, utils, ca);

JakartaJavaCodeActionParams codeActionParams1 = createCodeActionParams(uri, d2);
TextEdit te1 = te(39, 0, 39, 30, "@Resource(type = \"\", name = \"\")");
CodeAction ca1 = ca(uri, "Add name to jakarta.annotation.Resource", d2, te1);
assertJavaCodeAction(codeActionParams1, utils, ca1);
}
JakartaJavaCodeActionParams codeActionParams1 = createCodeActionParams(uri, d2);
newText = "package io.openliberty.sample.jakarta.annotations;\n\n" +
"import jakarta.annotation.Resource;\n\n@Resource(type = Object.class, " +
"name = \"aa\")\npublic class ResourceAnnotation {\n\n private Integer studentId;" +
"\n\n\n @Resource(shareable = true)\n private boolean isHappy;\n\n " +
"@Resource(name = \"test\")\n private boolean isSad;\n\n\n " +
"private String emailAddress;\n\n\n}\n\n@Resource(name = \"aa\")\n" +
"class PostDoctoralStudent {\n\n private Integer studentId;\n\n\n " +
"@Resource(shareable = true)\n private boolean isHappy;\n\n @Resource\n " +
"private boolean isSad;\n\n\n private String emailAddress;\n\n}\n\n" +
"@Resource(type = Object.class, name=\"\")\nclass MasterStudent {\n\n " +
"private Integer studentId;\n\n} \n";
TextEdit te1 = te(0, 0, 45, 0, newText);
CodeAction ca1 = ca(uri, "Add name to jakarta.annotation.Resource", d2, te1);
assertJavaCodeAction(codeActionParams1, utils, ca1);
// }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
import java.io.File;
import java.util.Arrays;

import static io.openliberty.tools.intellij.lsp4jakarta.it.core.JakartaForJavaAssert.*;

@RunWith(JUnit4.class)
public class JakartaWebSocketTest extends BaseJakartaTest {

Expand All @@ -56,30 +58,40 @@ public void addPathParamsAnnotation() throws Exception {
"Parameters of type String, any Java primitive type, or boxed version thereof must be annotated with @PathParams.",
DiagnosticSeverity.Error, "jakarta-websocket", "AddPathParamsAnnotation"
);

// OnClose PathParams Annotation check
Diagnostic d2 = JakartaForJavaAssert.d(24, 49, 67,
"Parameters of type String, any Java primitive type, or boxed version thereof must be annotated with @PathParams.",
DiagnosticSeverity.Error, "jakarta-websocket", "AddPathParamsAnnotation"
);

Diagnostic d3 = JakartaForJavaAssert.d(24, 76, 94,
"Parameters of type String, any Java primitive type, or boxed version thereof must be annotated with @PathParams.",
DiagnosticSeverity.Error, "jakarta-websocket", "AddPathParamsAnnotation"
);

JakartaForJavaAssert.assertJavaDiagnostics(diagnosticsParams, utils, d1, d2, d3);

if (CHECK_CODE_ACTIONS) {
// Expected code actions
JakartaJavaCodeActionParams codeActionsParams = JakartaForJavaAssert.createCodeActionParams(uri, d1);
String newText = "\nimport jakarta.websocket.server.PathParam;\nimport jakarta.websocket.server.ServerEndpoint;\nimport jakarta.websocket.Session;\n\n"
+ "/**\n * Expected Diagnostics are related to validating that the parameters have the \n * valid annotation @PathParam (code: AddPathParamsAnnotation)\n * See issue #247 (onOpen) and #248 (onClose)\n */\n"
+ "@ServerEndpoint(value = \"/infos\")\npublic class AnnotationTest {\n // @PathParam missing annotation for \"String missingAnnotation\"\n @OnOpen\n public void OnOpen(Session session, @PathParam(value = \"\") ";
TextEdit te = JakartaForJavaAssert.te(5, 32, 18, 40, newText);
CodeAction ca = JakartaForJavaAssert.ca(uri, "Insert @jakarta.websocket.server.PathParam", d1, te);
JakartaForJavaAssert.assertJavaCodeAction(codeActionsParams, utils, ca);
}
//TODO: uncomment this if condition, once refactoring is done for all the quick fixes.
// if (CHECK_CODE_ACTIONS) {
// Expected code actions
JakartaJavaCodeActionParams codeActionsParams = createCodeActionParams(uri, d1);
String newText = "package io.openliberty.sample.jakarta.websocket;\n\nimport java.io.IOException;" +
"\n\nimport jakarta.websocket.OnClose;\nimport jakarta.websocket.OnOpen;\n" +
"import jakarta.websocket.server.PathParam;import jakarta.websocket.server.ServerEndpoint;\n" +
"import jakarta.websocket.Session;\n\n/**\n * Expected Diagnostics are related to validating that the " +
"parameters have the \n * valid annotation @PathParam (code: AddPathParamsAnnotation)\n * " +
"See issue #247 (onOpen) and #248 (onClose)\n */\n@ServerEndpoint(value = \"/infos\")\n" +
"public class AnnotationTest {\n // @PathParam missing annotation for \"String missingAnnotation\"\n" +
" @OnOpen\n public void OnOpen(Session session, @PathParam(\"\") String missingAnnotation) " +
"throws IOException {\n System.out.println(\"Websocket opened: \" + session.getId().toString());" +
"\n }\n \n // Used to check that the expected diagnostic handle more than one case\n " +
"@OnClose\n public void OnClose(Session session, Integer missingAnnotation1, " +
"String missingAnnotation2) {\n System.out.println(\"Websocket opened: \" + " +
"session.getId().toString());\n }\n}\n";
TextEdit te = te(0, 0, 28, 0, newText);
CodeAction ca = ca(uri, "Insert @jakarta.websocket.server.PathParam", d1, te);
JakartaForJavaAssert.assertJavaCodeAction(codeActionsParams, utils, ca);
// }
}

@Test
Expand Down
Loading