forked from eclipse/lsp4jakarta
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Dependency Injection DiagnosticsCollector and Quick Fix for Injectabl…
…e field (non final) (eclipse#167) (eclipse#175) * Added DiagnosticCollector for Dependency Injection * Added Inject final field conflict quick fix Remove Inject quick fix * Added removing modifier quickfix * Added javadoc comment for DI diagnostics collector * Added entity type in RemoveModifierQuickFix message * formatting/identation fixes * removed unnecessary Apache 2.0 comment
- Loading branch information
1 parent
ae9394a
commit edfeb8f
Showing
7 changed files
with
347 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
139 changes: 139 additions & 0 deletions
139
.../eclipse/lsp4jakarta/jdt/codeAction/proposal/quickfix/RemoveModifierConflictQuickFix.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2021 IBM Corporation and others. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v. 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Himanshu Chotwani - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package org.eclipse.lsp4jakarta.jdt.codeAction.proposal.quickfix; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
|
||
import org.eclipse.core.runtime.CoreException; | ||
import org.eclipse.core.runtime.IProgressMonitor; | ||
import org.eclipse.jdt.core.IJavaElement; | ||
import org.eclipse.jdt.core.dom.ASTNode; | ||
import org.eclipse.jdt.core.dom.IBinding; | ||
import org.eclipse.jdt.core.dom.VariableDeclarationFragment; | ||
import org.eclipse.jdt.internal.corext.dom.Bindings; | ||
import org.eclipse.lsp4j.CodeAction; | ||
import org.eclipse.lsp4j.Diagnostic; | ||
import org.eclipse.lsp4jakarta.jdt.codeAction.IJavaCodeActionParticipant; | ||
import org.eclipse.lsp4jakarta.jdt.codeAction.JavaCodeActionContext; | ||
import org.eclipse.lsp4jakarta.jdt.codeAction.proposal.ModifyModifiersProposal; | ||
import org.eclipse.lsp4jakarta.jdt.core.di.DependencyInjectionConstants; | ||
|
||
|
||
/** | ||
* QuickFix for removing modifiers. | ||
* | ||
* @author Himanshu Chotwani | ||
* | ||
*/ | ||
public class RemoveModifierConflictQuickFix implements IJavaCodeActionParticipant { | ||
|
||
private final String[] modifiers; | ||
|
||
protected final boolean generateOnlyOneCodeAction; | ||
|
||
|
||
/** | ||
* Constructor for remove modifier quick fix. | ||
* | ||
* <p> | ||
* The participant will generate a CodeAction per modifier. | ||
* </p> | ||
* | ||
* @param modifiers list of modifiers to remove. | ||
*/ | ||
public RemoveModifierConflictQuickFix(String... modifiers) { | ||
this(false, modifiers); | ||
} | ||
|
||
|
||
/** | ||
* Constructor for remove modifiers quick fix. | ||
* | ||
* @param generateOnlyOneCodeAction true if the participant must generate a | ||
* CodeAction which remove the list of | ||
* modifiers and false otherwise. | ||
* @param modifiers list of modifiers to remove. | ||
*/ | ||
public RemoveModifierConflictQuickFix(boolean generateOnlyOneCodeAction, String... modifiers) { | ||
this.generateOnlyOneCodeAction = generateOnlyOneCodeAction; | ||
this.modifiers = modifiers; | ||
} | ||
|
||
|
||
@Override | ||
public List<? extends CodeAction> getCodeActions(JavaCodeActionContext context, Diagnostic diagnostic, | ||
IProgressMonitor monitor) throws CoreException { | ||
ASTNode node = context.getCoveredNode(); | ||
IBinding parentType = getBinding(node); | ||
|
||
List<CodeAction> codeActions = new ArrayList<>(); | ||
removeModifiers(diagnostic, context, parentType, codeActions); | ||
|
||
return codeActions; | ||
} | ||
|
||
protected void removeModifiers(Diagnostic diagnostic, JavaCodeActionContext context, IBinding parentType, | ||
List<CodeAction> codeActions) throws CoreException { | ||
if (generateOnlyOneCodeAction) { | ||
removeModifier(diagnostic, context, parentType, codeActions, modifiers); | ||
} else { | ||
for (String modifier : modifiers) { | ||
removeModifier(diagnostic, context, parentType, codeActions, modifier); | ||
} | ||
} | ||
} | ||
|
||
|
||
/** | ||
* use setData() API with diagnostic to pass in ElementType in diagnostic collector class. | ||
* | ||
*/ | ||
private void removeModifier(Diagnostic diagnostic, JavaCodeActionContext context, IBinding parentType, | ||
List<CodeAction> codeActions, String... modifier) throws CoreException { | ||
// Remove the modifier and the proper import by using JDT Core Manipulation | ||
// API | ||
ASTNode coveredNode = context.getCoveredNode().getParent(); | ||
String type = ""; | ||
if (diagnostic.getData().equals(String.valueOf(IJavaElement.LOCAL_VARIABLE))){ | ||
type = "variable"; | ||
} else if (diagnostic.getData().toString().equals(String.valueOf(IJavaElement.FIELD))) { | ||
type = "field"; | ||
} else if (diagnostic.getData().equals(String.valueOf(IJavaElement.METHOD))) { | ||
type = "method"; | ||
} else if (diagnostic.getData().equals(String.valueOf(IJavaElement.CLASS_FILE))) { | ||
type = "class"; | ||
} | ||
|
||
String name = "Remove " + modifier[0] + " modifier from this "; | ||
name = name.concat(type); | ||
ModifyModifiersProposal proposal = new ModifyModifiersProposal(name, context.getCompilationUnit(), | ||
context.getASTRoot(), parentType, 0, coveredNode, new ArrayList<>(), Arrays.asList(modifier)); | ||
CodeAction codeAction = context.convertToCodeAction(proposal, diagnostic); | ||
|
||
if (codeAction != null) { | ||
codeActions.add(codeAction); | ||
} | ||
} | ||
|
||
|
||
protected IBinding getBinding(ASTNode node) { | ||
if (node.getParent() instanceof VariableDeclarationFragment) { | ||
return ((VariableDeclarationFragment) node.getParent()).resolveBinding(); | ||
} | ||
return Bindings.getBindingOfParentType(node); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 30 additions & 0 deletions
30
....core/src/main/java/org/eclipse/lsp4jakarta/jdt/core/di/DependencyInjectionConstants.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2021 IBM Corporation. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v. 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Himanshu Chotwani | ||
*******************************************************************************/ | ||
|
||
package org.eclipse.lsp4jakarta.jdt.core.di; | ||
|
||
import org.eclipse.lsp4j.DiagnosticSeverity; | ||
|
||
public class DependencyInjectionConstants { | ||
/* Annotation Constants */ | ||
public static final String PRODUCES = "Produces"; | ||
public static final String INJECT = "Inject"; | ||
public static final String QUALIFIER = "Qualifier"; | ||
public static final String NAMED = "Named"; | ||
|
||
/* Diagnostics fields constants */ | ||
public static final String DIAGNOSTIC_SOURCE = "jakarta-di"; | ||
public static final String DIAGNOSTIC_CODE_INJECT_FINAL = "RemoveInjectOrFinal"; | ||
|
||
public static final DiagnosticSeverity SEVERITY = DiagnosticSeverity.Error; | ||
} |
92 changes: 92 additions & 0 deletions
92
...ain/java/org/eclipse/lsp4jakarta/jdt/core/di/DependencyInjectionDiagnosticsCollector.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2021 IBM Corporation and others. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v. 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0 | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* IBM Corporation, Himanshu Chotwani - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package org.eclipse.lsp4jakarta.jdt.core.di; | ||
|
||
import static org.eclipse.lsp4jakarta.jdt.core.di.DependencyInjectionConstants.DIAGNOSTIC_SOURCE; | ||
import static org.eclipse.lsp4jakarta.jdt.core.di.DependencyInjectionConstants.SEVERITY; | ||
|
||
import java.util.Arrays; | ||
import java.util.List; | ||
|
||
import org.eclipse.jdt.core.Flags; | ||
import org.eclipse.jdt.core.IAnnotation; | ||
import org.eclipse.jdt.core.ICompilationUnit; | ||
import org.eclipse.jdt.core.IField; | ||
import org.eclipse.jdt.core.ISourceRange; | ||
import org.eclipse.jdt.core.IType; | ||
import org.eclipse.jdt.core.JavaModelException; | ||
import org.eclipse.lsp4j.Diagnostic; | ||
import org.eclipse.lsp4j.Range; | ||
import org.eclipse.lsp4jakarta.jdt.core.DiagnosticsCollector; | ||
import org.eclipse.lsp4jakarta.jdt.core.JDTUtils; | ||
import org.eclipse.lsp4jakarta.jdt.core.JakartaCorePlugin; | ||
|
||
/** | ||
* | ||
* jararta.annotation Diagnostics | ||
* | ||
* <li>Diagnostic 1: @Inject fields cannot be final.</li> | ||
* | ||
* @see https://jakarta.ee/specifications/dependency-injection/2.0/jakarta-injection-spec-2.0.html | ||
* | ||
*/ | ||
public class DependencyInjectionDiagnosticsCollector implements DiagnosticsCollector{ | ||
|
||
@Override | ||
public void completeDiagnostic(Diagnostic diagnostic) { | ||
diagnostic.setSource(DIAGNOSTIC_SOURCE); | ||
diagnostic.setSeverity(SEVERITY); | ||
} | ||
|
||
@Override | ||
public void collectDiagnostics(ICompilationUnit unit, List<Diagnostic> diagnostics) { | ||
if (unit == null) | ||
return; | ||
Diagnostic diagnostic; | ||
IType[] alltypes; | ||
IAnnotation[] allAnnotations; | ||
try { | ||
alltypes = unit.getAllTypes(); | ||
for (IType type : alltypes) { | ||
allAnnotations = type.getAnnotations(); | ||
|
||
IField[] allFields = type.getFields(); | ||
for (IField field : allFields) { | ||
int fieldFlags = field.getFlags(); | ||
List<IAnnotation> fieldAnnotations = Arrays.asList(field.getAnnotations()); | ||
|
||
boolean isInjectField = fieldAnnotations.stream() | ||
.anyMatch(annotation -> annotation.getElementName() | ||
.equals(DependencyInjectionConstants.INJECT)); | ||
|
||
boolean isFinal = Flags.isFinal(fieldFlags); | ||
|
||
if (isFinal && isInjectField) { | ||
ISourceRange nameRange = JDTUtils.getNameRange(field); | ||
Range range = JDTUtils.toRange(unit, nameRange.getOffset(), nameRange.getLength()); | ||
String msg = "Injectable fields cannot be final"; | ||
diagnostic = new Diagnostic(range, msg); | ||
diagnostic.setCode(DependencyInjectionConstants.DIAGNOSTIC_CODE_INJECT_FINAL); | ||
diagnostic.setData(field.getElementType()); | ||
completeDiagnostic(diagnostic); | ||
diagnostics.add(diagnostic); | ||
} | ||
} | ||
} | ||
} catch (JavaModelException e) { | ||
JakartaCorePlugin.logException("Cannot calculate diagnostics", e); | ||
} | ||
} | ||
|
||
} |
30 changes: 30 additions & 0 deletions
30
...t.core/src/main/java/org/eclipse/lsp4jakarta/jdt/core/di/RemoveFinalModifierQuickFix.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2021 IBM Corporation and others. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v. 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0 | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* IBM Corporation, Himanshu Chotwani - initial API and implementation | ||
*******************************************************************************/ | ||
package org.eclipse.lsp4jakarta.jdt.core.di; | ||
|
||
import org.eclipse.lsp4jakarta.jdt.codeAction.proposal.quickfix.RemoveModifierConflictQuickFix; | ||
|
||
|
||
/** | ||
* | ||
* Quick fix for removing final when it is used for @Inject field | ||
* | ||
* @author Himanshu Chotwani | ||
* | ||
*/ | ||
public class RemoveFinalModifierQuickFix extends RemoveModifierConflictQuickFix { | ||
|
||
public RemoveFinalModifierQuickFix() { | ||
super(false, "final"); | ||
} | ||
} |
44 changes: 44 additions & 0 deletions
44
...ore/src/main/java/org/eclipse/lsp4jakarta/jdt/core/di/RemoveInjectAnnotationQuickFix.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2021 IBM Corporation and others. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v. 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* IBM Corporation, Himanshu Chotwani - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package org.eclipse.lsp4jakarta.jdt.core.di; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
|
||
import org.eclipse.core.runtime.CoreException; | ||
import org.eclipse.jdt.core.dom.ASTNode; | ||
import org.eclipse.jdt.core.dom.IBinding; | ||
import org.eclipse.jdt.core.dom.VariableDeclarationFragment; | ||
import org.eclipse.jdt.internal.corext.dom.Bindings; | ||
import org.eclipse.lsp4j.CodeAction; | ||
import org.eclipse.lsp4j.Diagnostic; | ||
import org.eclipse.lsp4jakarta.jdt.codeAction.IJavaCodeActionParticipant; | ||
import org.eclipse.lsp4jakarta.jdt.codeAction.JavaCodeActionContext; | ||
import org.eclipse.lsp4jakarta.jdt.codeAction.proposal.ModifyModifiersProposal; | ||
import org.eclipse.lsp4jakarta.jdt.codeAction.proposal.quickfix.RemoveAnnotationConflictQuickFix; | ||
|
||
/** | ||
* | ||
* Quick fix for removing @Inject when it is used for final field | ||
* | ||
* @author Himanshu Chotwani | ||
* | ||
*/ | ||
|
||
public class RemoveInjectAnnotationQuickFix extends RemoveAnnotationConflictQuickFix { | ||
|
||
public RemoveInjectAnnotationQuickFix() { | ||
super(false, "jakarta.inject.Inject"); | ||
} | ||
} |