Skip to content

Commit

Permalink
Merge pull request #518 from anusreelakshmi934/feature/#514
Browse files Browse the repository at this point in the history
Fixes #514 Transforming Quickfixes related to AddConstructorProposal
  • Loading branch information
anusreelakshmi934 authored Oct 19, 2023
2 parents a636bd8 + 1d27092 commit 4d0b84e
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 91 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,25 @@

import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiModifierListOwner;
import com.intellij.psi.util.PsiTreeUtil;
import io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.Messages;
import io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.codeAction.proposal.AddConstructorProposal;
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.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
*
Expand All @@ -37,57 +44,70 @@
*
*/

public class ManagedBeanNoArgConstructorQuickFix {
public class ManagedBeanNoArgConstructorQuickFix implements IJavaCodeActionParticipant {
private static final Logger LOGGER = Logger.getLogger(ManagedBeanNoArgConstructorQuickFix.class.getName());

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

public List<? extends CodeAction> getCodeActions(JavaCodeActionContext context, Diagnostic diagnostic) {
PsiElement node = context.getCoveredNode();
PsiClass parentType = getBinding(node);

if (parentType != null) {
List<CodeAction> codeActions = new ArrayList<>();
return addConstructor(diagnostic, context);
}
return Collections.emptyList();
}

@Override
public CodeAction resolveCodeAction(JavaCodeActionResolveContext context) {
final CodeAction toResolve = context.getUnresolved();
PsiElement node = context.getCoveredNode();
PsiClass parentType = getBinding(node);

codeActions.addAll(addConstructor(diagnostic, context, parentType));
String constructorName = toResolve.getTitle();
ChangeCorrectionProposal proposal = new AddConstructorProposal(constructorName,
context.getSource().getCompilationUnit(), context.getASTRoot(), parentType, 0,
constructorName.equals(Messages.getMessage("AddProtectedConstructor")) ? "protected" : "public");

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 actions to add constructors", e);
}
return Collections.emptyList();

return toResolve;
}

protected PsiClass getBinding(PsiElement node) {
return PsiTreeUtil.getParentOfType(node, PsiClass.class);
}

private List<CodeAction> addConstructor(Diagnostic diagnostic, JavaCodeActionContext context, PsiClass notUsed) {
private List<CodeAction> addConstructor(Diagnostic diagnostic, JavaCodeActionContext context) {
List<CodeAction> codeActions = new ArrayList<>();
JavaCodeActionContext targetContext = null;
PsiElement node = null;
PsiClass parentType = null;

// option for protected constructor
targetContext = context.copy();
node = targetContext.getCoveredNode();
parentType = getBinding(node);
String name = Messages.getMessage("AddProtectedConstructor");
ChangeCorrectionProposal proposal = new AddConstructorProposal(name,
targetContext.getSource().getCompilationUnit(), targetContext.getASTRoot(), parentType, 0);
CodeAction codeAction = targetContext.convertToCodeAction(proposal, diagnostic);

if (codeAction != null) {
codeActions.add(codeAction);
}
String[] constructorNames = {Messages.getMessage("AddProtectedConstructor"), Messages.getMessage("AddPublicConstructor")};

// option for public constructor
targetContext = context.copy();
node = targetContext.getCoveredNode();
parentType = getBinding(node);
name = Messages.getMessage("AddPublicConstructor");
proposal = new AddConstructorProposal(name,
targetContext.getSource().getCompilationUnit(), targetContext.getASTRoot(), parentType, 0, "public");
codeAction = targetContext.convertToCodeAction(proposal, diagnostic);

if (codeAction != null) {
for (String name : constructorNames) {
CodeAction codeAction = createCodeAction(context, diagnostic, name);
codeActions.add(codeAction);
}

return codeActions;
}
}

private CodeAction createCodeAction(JavaCodeActionContext context, Diagnostic diagnostic, String label) {
ExtendedCodeAction codeAction = new ExtendedCodeAction(label);
codeAction.setRelevance(0);
codeAction.setDiagnostics(Collections.singletonList(diagnostic));
codeAction.setKind(CodeActionKind.QuickFix);
codeAction.setTitle(label);
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 @@ -18,13 +18,22 @@
import com.intellij.psi.util.PsiTreeUtil;
import io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.Messages;
import io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.codeAction.proposal.AddConstructorProposal;
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.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* QuickFix for fixing {@link PersistenceConstants#DIAGNOSTIC_CODE_MISSING_ATTRIBUTES} error
Expand Down Expand Up @@ -54,59 +63,70 @@
* @author Leslie Dawson (lamminade)
*
*/
public class PersistenceEntityQuickFix {
public class PersistenceEntityQuickFix implements IJavaCodeActionParticipant {
private static final Logger LOGGER = Logger.getLogger(PersistenceEntityQuickFix.class.getName());

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

public List<? extends CodeAction> getCodeActions(JavaCodeActionContext context, Diagnostic diagnostic) {
List<CodeAction> codeActions = new ArrayList<>();
PsiElement node = context.getCoveredNode();
PsiClass parentType = getBinding(node);

if (parentType != null) {
codeActions.addAll(addConstructor(diagnostic, context));
}
return codeActions;
}

@Override
public CodeAction resolveCodeAction(JavaCodeActionResolveContext context) {
final CodeAction toResolve = context.getUnresolved();
PsiElement node = context.getCoveredNode();
PsiClass parentType = getBinding(node);

// add constructor
if (diagnostic.getCode().getLeft().equals(PersistenceConstants.DIAGNOSTIC_CODE_MISSING_EMPTY_CONSTRUCTOR)) {
codeActions.addAll(addConstructor(diagnostic, context, parentType));
}
String constructorName = toResolve.getTitle();
ChangeCorrectionProposal proposal = new AddConstructorProposal(constructorName,
context.getSource().getCompilationUnit(), context.getASTRoot(), parentType, 0,
constructorName.equals(Messages.getMessage("AddNoArgProtectedConstructor")) ? "protected" : "public");

try {
WorkspaceEdit we = context.convertToWorkspaceEdit(proposal);
toResolve.setEdit(we);
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Unable to create workspace edit for code actions to add constructors", e);
}
return codeActions;
return toResolve;
}

protected PsiClass getBinding(PsiElement node) {
return PsiTreeUtil.getParentOfType(node, PsiClass.class);
}

private List<CodeAction> addConstructor(Diagnostic diagnostic, JavaCodeActionContext context, PsiClass notUsed) {
private List<CodeAction> addConstructor(Diagnostic diagnostic, JavaCodeActionContext context) {
List<CodeAction> codeActions = new ArrayList<>();
JavaCodeActionContext targetContext = null;
PsiElement node = null;
PsiClass parentType = null;

// option for protected constructor
targetContext = context.copy();
node = targetContext.getCoveredNode();
parentType = getBinding(node);
String name = Messages.getMessage("AddNoArgProtectedConstructor");
ChangeCorrectionProposal proposal = new AddConstructorProposal(name,
targetContext.getSource().getCompilationUnit(), targetContext.getASTRoot(), parentType, 0);
CodeAction codeAction = targetContext.convertToCodeAction(proposal, diagnostic);
String[] constructorNames = {Messages.getMessage("AddNoArgProtectedConstructor"), Messages.getMessage("AddNoArgPublicConstructor")};

if (codeAction != null) {
for (String name : constructorNames) {
CodeAction codeAction = createCodeAction(context, diagnostic, name);
codeActions.add(codeAction);
}

// option for public constructor
targetContext = context.copy();
node = targetContext.getCoveredNode();
parentType = getBinding(node);
name = Messages.getMessage("AddNoArgPublicConstructor");
proposal = new AddConstructorProposal(name,
targetContext.getSource().getCompilationUnit(), targetContext.getASTRoot(), parentType, 0, "public");
codeAction = targetContext.convertToCodeAction(proposal, diagnostic);

if (codeAction != null) {
codeActions.add(codeAction);
}

return codeActions;
}

}
private CodeAction createCodeAction(JavaCodeActionContext context, Diagnostic diagnostic, String label) {
ExtendedCodeAction codeAction = new ExtendedCodeAction(label);
codeAction.setRelevance(0);
codeAction.setDiagnostics(Collections.singletonList(diagnostic));
codeAction.setKind(CodeActionKind.QuickFix);
codeAction.setTitle(label);
codeAction.setData(new CodeActionResolveData(context.getUri(), getParticipantId(),
context.getParams().getRange(), Collections.emptyMap(),
context.getParams().isResourceOperationSupported(),
context.getParams().isCommandConfigurationUpdateSupported()));
return codeAction;
}
}
10 changes: 10 additions & 0 deletions src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,16 @@
targetDiagnostic="jakarta-annotations#PostConstructReturnType"
implementationClass="io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.annotations.PostConstructReturnTypeQuickFix"/>

<javaCodeActionParticipant kind="quickfix"
group="jakarta"
targetDiagnostic="jakarta-persistence#MissingEmptyConstructor"
implementationClass="io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.persistence.PersistenceEntityQuickFix"/>

<javaCodeActionParticipant kind="quickfix"
group="jakarta"
targetDiagnostic="jakarta-cdi#InvalidManagedBeanConstructor"
implementationClass="io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.cdi.ManagedBeanNoArgConstructorQuickFix"/>

<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 @@ -19,6 +19,7 @@
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import io.openliberty.tools.intellij.lsp4jakarta.it.core.BaseJakartaTest;
import io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.Messages;
import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.utils.IPsiUtils;
import io.openliberty.tools.intellij.lsp4mp4ij.psi.internal.core.ls.PsiUtilsLSImpl;
import org.eclipse.lsp4j.CodeAction;
Expand All @@ -27,7 +28,6 @@
import org.eclipse.lsp4j.TextEdit;
import org.eclipse.lsp4jakarta.commons.JakartaDiagnosticsParams;
import org.eclipse.lsp4jakarta.commons.JakartaJavaCodeActionParams;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
Expand Down Expand Up @@ -59,20 +59,20 @@ public void managedBeanAnnotations() throws Exception {

assertJavaDiagnostics(diagnosticsParams, utils, d);

//TODO Enable the remaining test cases once the refactoring is completed
if (CHECK_CODE_ACTIONS) {
// test expected quick-fix
JakartaJavaCodeActionParams codeActionParams1 = createCodeActionParams(uri, d);
TextEdit te1 = te(15, 44, 21, 1,
"\nimport jakarta.inject.Inject;\n\n@Dependent\npublic class ManagedBeanConstructor {\n private int a;\n \n @Inject\n ");
TextEdit te2 = te(19, 1, 19, 1,
"protected ManagedBeanConstructor() {\n\t}\n\n\t");
TextEdit te3 = te(19, 1, 19, 1,
"public ManagedBeanConstructor() {\n\t}\n\n\t");
CodeAction ca1 = ca(uri, "Insert @Inject", d, te1);
CodeAction ca2 = ca(uri, "Add a no-arg protected constructor to this class", d, te2);
CodeAction ca3 = ca(uri, "Add a no-arg public constructor to this class", d, te3);
assertJavaCodeAction(codeActionParams1, utils, ca1, ca2, ca3);
}
}

// test expected quick-fix
JakartaJavaCodeActionParams codeActionParams1 = createCodeActionParams(uri, d);
TextEdit te2 = te(0, 0, 25, 0, "/*******************************************************************************\n * Copyright (c) 2021 IBM Corporation.\n *\n * This program and the accompanying materials are made available under the\n * terms of the Eclipse Public License v. 2.0 which is available at\n * http://www.eclipse.org/legal/epl-2.0.\n *\n * SPDX-License-Identifier: EPL-2.0\n *\n * Contributors:\n * Hani Damlaj\n *******************************************************************************/\n\npackage io.openliberty.sample.jakarta.cdi;\n\nimport jakarta.enterprise.context.Dependent;\n\n@Dependent\npublic class ManagedBeanConstructor {\n private int a;\n\n protected ManagedBeanConstructor() {\n }\n\n public ManagedBeanConstructor(int a) {\n this.a = a;\n }\n}\n");
TextEdit te3 = te(0, 0, 25, 0, "/*******************************************************************************\n * Copyright (c) 2021 IBM Corporation.\n *\n * This program and the accompanying materials are made available under the\n * terms of the Eclipse Public License v. 2.0 which is available at\n * http://www.eclipse.org/legal/epl-2.0.\n *\n * SPDX-License-Identifier: EPL-2.0\n *\n * Contributors:\n * Hani Damlaj\n *******************************************************************************/\n\npackage io.openliberty.sample.jakarta.cdi;\n\nimport jakarta.enterprise.context.Dependent;\n\n@Dependent\npublic class ManagedBeanConstructor {\n private int a;\n\n public ManagedBeanConstructor() {\n }\n\n public ManagedBeanConstructor(int a) {\n this.a = a;\n }\n}\n");
CodeAction ca2 = ca(uri, Messages.getMessage("AddProtectedConstructor"), d, te2);
CodeAction ca3 = ca(uri, Messages.getMessage("AddPublicConstructor"), d, te3);
assertJavaCodeAction(codeActionParams1, utils, ca2, ca3);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import io.openliberty.tools.intellij.lsp4jakarta.it.core.BaseJakartaTest;
import io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.Messages;
import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.utils.IPsiUtils;
import io.openliberty.tools.intellij.lsp4mp4ij.psi.internal.core.ls.PsiUtilsLSImpl;
import org.eclipse.lsp4j.CodeAction;
Expand All @@ -26,7 +27,6 @@
import org.eclipse.lsp4j.TextEdit;
import org.eclipse.lsp4jakarta.commons.JakartaDiagnosticsParams;
import org.eclipse.lsp4jakarta.commons.JakartaJavaCodeActionParams;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
Expand Down Expand Up @@ -156,16 +156,16 @@ public void addEmptyConstructor() throws Exception {

assertJavaDiagnostics(diagnosticsParams, utils, d);

if (CHECK_CODE_ACTIONS) {
// test quick fixes
JakartaJavaCodeActionParams codeActionParams1 = createCodeActionParams(uri, d);
TextEdit te1 = te(7, 4, 7, 4, "protected EntityMissingConstructor() {\n\t}\n\n\t");
CodeAction ca1 = ca(uri, "Add a no-arg protected constructor to this class", d, te1);
TextEdit te2 = te(7, 4, 7, 4, "public EntityMissingConstructor() {\n\t}\n\n\t");
CodeAction ca2 = ca(uri, "Add a no-arg public constructor to this class", d, te2);
// if (CHECK_CODE_ACTIONS) {
// test quick fixes
JakartaJavaCodeActionParams codeActionParams1 = createCodeActionParams(uri, d);
TextEdit te1 = te(0, 0, 9, 1, "package io.openliberty.sample.jakarta.persistence;\n\nimport jakarta.persistence.Entity;\n\n@Entity\npublic class EntityMissingConstructor {\n\n protected EntityMissingConstructor() {\n }\n\n private EntityMissingConstructor(int x) {\n }\n\n}");
CodeAction ca1 = ca(uri, Messages.getMessage("AddNoArgProtectedConstructor"), d, te1);
TextEdit te2 = te(0, 0, 9, 1, "package io.openliberty.sample.jakarta.persistence;\n\nimport jakarta.persistence.Entity;\n\n@Entity\npublic class EntityMissingConstructor {\n\n public EntityMissingConstructor() {\n }\n\n private EntityMissingConstructor(int x) {\n }\n\n}");
CodeAction ca2 = ca(uri, Messages.getMessage("AddNoArgPublicConstructor"), d, te2);

assertJavaCodeAction(codeActionParams1, utils, ca1, ca2);
}
assertJavaCodeAction(codeActionParams1, utils, ca1, ca2);
// }
}

@Test
Expand Down

0 comments on commit 4d0b84e

Please sign in to comment.