-
Notifications
You must be signed in to change notification settings - Fork 51
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
add quickfix fn to handle composite annotations #513
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2021, 2023 IBM Corporation and others. | ||
* Copyright (c) 2021, 2023, 2024 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 | ||
|
@@ -65,7 +65,8 @@ public List<Diagnostic> collectDiagnostics(JavaDiagnosticsContext context, IProg | |
ArrayList<Tuple.Two<IAnnotation, IAnnotatable>> annotatables = new ArrayList<Two<IAnnotation, IAnnotatable>>(); | ||
String[] validAnnotations = { Constants.GENERATED_FQ_NAME }; | ||
String[] validTypeAnnotations = { Constants.GENERATED_FQ_NAME, | ||
Constants.RESOURCE_FQ_NAME }; | ||
Constants.RESOURCE_FQ_NAME, | ||
Constants.RESOURCES_FQ_NAME }; | ||
String[] validMethodAnnotations = { Constants.GENERATED_FQ_NAME, | ||
Constants.POST_CONSTRUCT_FQ_NAME, Constants.PRE_DESTROY_FQ_NAME, | ||
Constants.RESOURCE_FQ_NAME }; | ||
|
@@ -120,6 +121,7 @@ public List<Diagnostic> collectDiagnostics(JavaDiagnosticsContext context, IProg | |
IAnnotation annotation = annotatable.getFirst(); | ||
IAnnotatable element = annotatable.getSecond(); | ||
|
||
// process Types? (class declarations) | ||
if (DiagnosticUtils.isMatchedAnnotation(unit, annotation, Constants.GENERATED_FQ_NAME)) { | ||
for (IMemberValuePair pair : annotation.getMemberValuePairs()) { | ||
// If date element exists and is non-empty, it must follow ISO 8601 format. | ||
|
@@ -178,7 +180,74 @@ public List<Diagnostic> collectDiagnostics(JavaDiagnosticsContext context, IProg | |
} | ||
} | ||
} | ||
} else if (DiagnosticUtils.isMatchedAnnotation(unit, annotation, Constants.RESOURCES_FQ_NAME)) { | ||
if (element instanceof IType) { | ||
for (IMemberValuePair internalAnnotation : annotation.getMemberValuePairs()) { | ||
Object[] valuePairs = (Object[]) internalAnnotation.getValue(); | ||
String diagnosticMessage; | ||
Range annotationRange = null; | ||
if (valuePairs.length == 0) { | ||
annotationRange = PositionUtils.toNameRange(annotation, context.getUtils()); | ||
diagnosticMessage = Messages.getMessage("ResourcesAnnotationMustDefineResourceAnnotation", | ||
"@Resources", "@Resource"); | ||
diagnostics.add(context.createDiagnostic(uri, diagnosticMessage, annotationRange, | ||
Constants.DIAGNOSTIC_SOURCE, | ||
ErrorCode.MissingResourceAnnotation, | ||
DiagnosticSeverity.Error)); | ||
} | ||
int objKind = internalAnnotation.getValueKind(); | ||
for (Object childAnnotationObj : valuePairs) { | ||
if (objKind == IMemberValuePair.K_ANNOTATION) { | ||
IAnnotation childAnnotation = (IAnnotation) childAnnotationObj; | ||
if (DiagnosticUtils.isMatchedAnnotation(unit, childAnnotation, | ||
Constants.RESOURCE_FQ_NAME)) { | ||
if (element instanceof IType) { | ||
IType type = (IType) element; | ||
if (type.getElementType() == IJavaElement.TYPE | ||
&& ((IType) type).isClass()) { | ||
annotationRange = PositionUtils.toNameRange(childAnnotation, | ||
context.getUtils()); | ||
Boolean nameEmpty = true; | ||
Boolean typeEmpty = true; | ||
for (IMemberValuePair pair : childAnnotation.getMemberValuePairs()) { | ||
if (pair.getMemberName().equals("name")) { | ||
nameEmpty = false; | ||
} | ||
if (pair.getMemberName().equals("type")) { | ||
typeEmpty = false; | ||
} | ||
} | ||
if (nameEmpty) { | ||
diagnosticMessage = Messages.getMessage( | ||
"AnnotationMustDefineAttribute", | ||
"@Resource", "name"); | ||
diagnostics.add(context.createDiagnostic(uri, diagnosticMessage, | ||
annotationRange, | ||
Constants.DIAGNOSTIC_SOURCE, | ||
ErrorCode.MissingResourceNameAttribute, | ||
DiagnosticSeverity.Error)); | ||
} | ||
|
||
if (typeEmpty) { | ||
diagnosticMessage = Messages.getMessage( | ||
"AnnotationMustDefineAttribute", | ||
"@Resource", "type"); | ||
diagnostics.add(context.createDiagnostic(uri, diagnosticMessage, | ||
annotationRange, | ||
Constants.DIAGNOSTIC_SOURCE, | ||
ErrorCode.MissingResourceTypeAttribute, | ||
DiagnosticSeverity.Error)); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
// process methods now? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove: // process methods now? |
||
if (DiagnosticUtils.isMatchedAnnotation(unit, annotation, Constants.POST_CONSTRUCT_FQ_NAME)) { | ||
if (element instanceof IMethod) { | ||
IMethod method = (IMethod) element; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2021, 2023 IBM Corporation and others. | ||
* Copyright (c) 2021, 2023, 2024 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 | ||
|
@@ -30,6 +30,10 @@ public class Constants { | |
public static final String RESOURCE = "Resource"; | ||
public static final String RESOURCE_FQ_NAME = "jakarta.annotation.Resource"; | ||
|
||
/* @Resources */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Update Copyright year to 2024 |
||
public static final String RESOURCES = "Resources"; | ||
public static final String RESOURCES_FQ_NAME = "jakarta.annotation.Resources"; | ||
|
||
/* @PostConstruct */ | ||
public static final String POST_CONSTRUCT = "PostConstruct"; | ||
public static final String POST_CONSTRUCT_FQ_NAME = "jakarta.annotation.PostConstruct"; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2024 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 - initial API and implementation | ||
*******************************************************************************/ | ||
package org.eclipse.lsp4jakarta.jdt.internal.annotations; | ||
|
||
import org.eclipse.lsp4jakarta.commons.codeaction.ICodeActionId; | ||
import org.eclipse.lsp4jakarta.commons.codeaction.JakartaCodeActionId; | ||
import org.eclipse.lsp4jakarta.jdt.core.java.codeaction.InsertAnnotationAttributesQuickFix; | ||
|
||
/** | ||
* Inserts the name attribute to the @Resource annotation to the active element. | ||
*/ | ||
public class InsertDefaultResourceAnnotationToResourcesAnnotation extends InsertAnnotationAttributesQuickFix { | ||
|
||
/** | ||
* Constructor. | ||
*/ | ||
public InsertDefaultResourceAnnotationToResourcesAnnotation() { | ||
super("jakarta.annotation.Resource", "name", "type"); | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
@Override | ||
public String getParticipantId() { | ||
return InsertDefaultResourceAnnotationToResourcesAnnotation.class.getName(); | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
@Override | ||
protected ICodeActionId getCodeActionId() { | ||
return JakartaCodeActionId.InsertDefaultResourceAnnotationToResourcesAnnotation; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,7 @@ MethodMustNotHaveParameters = A method with the {0} annotation must not have any | |
MethodMustBeVoid = A method with the {0} annotation must be void. | ||
MethodMustNotBeStatic = A method with the {0} annotation must not be static. | ||
MethodMustNotThrow = A method with the {0} annotation must not throw checked exceptions. | ||
ResourcesAnnotationMustDefineResourceAnnotation = The {0} annotation must define at least one sub-annotation ''{1}''. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Update Copyright year to 2024 |
||
|
||
# HttpServletQuickFix | ||
LetClassExtend = Let ''{0}'' extend ''{1}'' | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2024 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 - initial API and implementation | ||
*******************************************************************************/ | ||
package io.openliberty.sample.jakarta.annotations; | ||
|
||
import jakarta.annotation.Resource; | ||
import jakarta.annotation.Resources; | ||
|
||
@Resources ({ @Resource(name = "aaa"), @Resource(type = Object.class) }) | ||
public class ResourcesAnnotation { | ||
} | ||
|
||
@Resources ({}) | ||
class ResourcesAnnotationEmpty { | ||
} | ||
|
||
@Resource(name = "aa", type = Object.class) | ||
class DoctoralStudent { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/******************************************************************************* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since this is a new file the first like should be: |
||
* Copyright (c) 2024 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 - initial API and implementation | ||
*******************************************************************************/ | ||
package org.eclipse.lsp4jakarta.jdt.annotations; | ||
|
||
import static org.eclipse.lsp4jakarta.jdt.core.JakartaForJavaAssert.assertJavaCodeAction; | ||
import static org.eclipse.lsp4jakarta.jdt.core.JakartaForJavaAssert.assertJavaDiagnostics; | ||
import static org.eclipse.lsp4jakarta.jdt.core.JakartaForJavaAssert.ca; | ||
import static org.eclipse.lsp4jakarta.jdt.core.JakartaForJavaAssert.createCodeActionParams; | ||
import static org.eclipse.lsp4jakarta.jdt.core.JakartaForJavaAssert.d; | ||
import static org.eclipse.lsp4jakarta.jdt.core.JakartaForJavaAssert.te; | ||
|
||
import java.util.Arrays; | ||
|
||
import org.eclipse.core.resources.IFile; | ||
import org.eclipse.core.runtime.Path; | ||
import org.eclipse.jdt.core.IJavaProject; | ||
import org.eclipse.lsp4j.CodeAction; | ||
import org.eclipse.lsp4j.Diagnostic; | ||
import org.eclipse.lsp4j.DiagnosticSeverity; | ||
import org.eclipse.lsp4j.TextEdit; | ||
import org.eclipse.lsp4jakarta.commons.JakartaJavaCodeActionParams; | ||
import org.eclipse.lsp4jakarta.commons.JakartaJavaDiagnosticsParams; | ||
import org.eclipse.lsp4jakarta.jdt.core.BaseJakartaTest; | ||
import org.eclipse.lsp4jakarta.jdt.core.utils.IJDTUtils; | ||
import org.eclipse.lsp4jakarta.jdt.internal.core.ls.JDTUtilsLSImpl; | ||
import org.junit.Test; | ||
|
||
public class ResourcesAnnotationTest extends BaseJakartaTest { | ||
|
||
protected static IJDTUtils IJDT_UTILS = JDTUtilsLSImpl.getInstance(); | ||
|
||
@Test | ||
public void GeneratedAnnotation() throws Exception { | ||
IJavaProject javaProject = loadJavaProject("jakarta-sample", ""); | ||
IFile javaFile = javaProject.getProject().getFile(new Path("src/main/java/io/openliberty/sample/jakarta/annotations/ResourcesAnnotation.java")); | ||
String uri = javaFile.getLocation().toFile().toURI().toString(); | ||
|
||
JakartaJavaDiagnosticsParams diagnosticsParams = new JakartaJavaDiagnosticsParams(); | ||
diagnosticsParams.setUris(Arrays.asList(uri)); | ||
|
||
// expected annotations | ||
Diagnostic d1 = d(17, 14, 37, "The @Resource annotation must define the attribute 'type'.", | ||
DiagnosticSeverity.Error, "jakarta-annotations", "MissingResourceTypeAttribute"); | ||
|
||
Diagnostic d2 = d(17, 39, 69, "The @Resource annotation must define the attribute 'name'.", | ||
DiagnosticSeverity.Error, "jakarta-annotations", "MissingResourceNameAttribute"); | ||
|
||
Diagnostic d3 = d(21, 0, 15, "The @Resources annotation must define at least one sub-annotation '@Resource'.", | ||
DiagnosticSeverity.Error, "jakarta-annotations", "MissingResourceAnnotation"); | ||
|
||
assertJavaDiagnostics(diagnosticsParams, IJDT_UTILS, d1, d2, d3); | ||
|
||
JakartaJavaCodeActionParams codeActionParams = createCodeActionParams(uri, d1); | ||
TextEdit te1 = te(17, 0, 18, 0, "@Resources({ @Resource(name = \"aaa\", type = \"\"), @Resource(type = Object.class) })\n"); | ||
CodeAction ca1 = ca(uri, "Insert 'type' attribute to @Resource", d1, te1); | ||
assertJavaCodeAction(codeActionParams, IJDT_UTILS, ca1); | ||
|
||
JakartaJavaCodeActionParams codeActionParams1 = createCodeActionParams(uri, d2); | ||
TextEdit te2 = te(17, 0, 18, 0, "@Resources({ @Resource(name = \"aaa\"), @Resource(type = Object.class, name = \"\") })\n"); | ||
CodeAction ca2 = ca(uri, "Insert 'name' attribute to @Resource", d2, te2); | ||
assertJavaCodeAction(codeActionParams1, IJDT_UTILS, ca2); | ||
|
||
JakartaJavaCodeActionParams codeActionParams2 = createCodeActionParams(uri, d3); | ||
TextEdit te3 = te(21, 0, 21, 15, "@Resources({ @Resource(name = \"\", type = \"\") })"); | ||
CodeAction ca3 = ca(uri, "Insert 'name,type' attributes to @Resource", d3, te3); | ||
assertJavaCodeAction(codeActionParams2, IJDT_UTILS, ca3); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update Copyright year to 2024