Skip to content

Commit 7134303

Browse files
authored
:bugfix: Try to fit annotations into on-demand imports for member checking (#208) (#209)
* Try to fit annotations into on-demand imports for member checking * Remove unneeded document * Address automatic PR review comments --------- Signed-off-by: Juan Manuel Leflet Estrada <jleflete@redhat.com>
1 parent fbefe25 commit 7134303

1 file changed

Lines changed: 49 additions & 27 deletions

File tree

java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/WithAnnotationQuery.java

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.eclipse.jdt.internal.core.SourceMethod;
1111
import org.eclipse.jdt.internal.core.SourceRefElement;
1212

13+
import java.util.ArrayList;
1314
import java.util.Arrays;
1415
import java.util.List;
1516
import java.util.Map;
@@ -47,28 +48,33 @@ default boolean matchesAnnotationQuery(SearchMatch match, List<Class<? extends S
4748

4849
// Iterate over the annotation this symbol is annotated with
4950
for (IAnnotation annotation : annotations) {
50-
// See if the annotation's name matches the pattern given in the query for the annotation
51-
String fqn = getFQN(annotation);
52-
if (getAnnotationQuery().matchesAnnotation(fqn)) {
53-
return doElementsMatch((Annotation) annotation);
54-
} else {
55-
// The LS doesn't seem to be able to match on annotations within annotations, but
56-
// if the main annotation doesn't match, there might be some annotations inside:
57-
for (IMemberValuePair member : annotation.getMemberValuePairs()) {
58-
if (member.getValueKind() == IMemberValuePair.K_ANNOTATION) {
59-
if (member.getValue() instanceof Object[]) {
60-
Object[] objs = (Object[]) member.getValue();
61-
for (int i = 0; i < objs.length; i++) {
62-
Annotation innerAnnotation = (Annotation) objs[i];
63-
fqn = getFQN(innerAnnotation);
51+
for (String fqn : getFQNCandidates(annotation)) {
52+
if (getAnnotationQuery().matchesAnnotation(fqn)) {
53+
return doElementsMatch((Annotation) annotation);
54+
}
55+
}
56+
// Nested annotations (e.g. in member value pairs)
57+
for (IMemberValuePair member : annotation.getMemberValuePairs()) {
58+
if (member.getValueKind() == IMemberValuePair.K_ANNOTATION) {
59+
if (member.getValue() instanceof Object[]) {
60+
Object[] objs = (Object[]) member.getValue();
61+
for (int i = 0; i < objs.length; i++) {
62+
Annotation innerAnnotation = (Annotation) objs[i];
63+
for (String fqn : getFQNCandidates(innerAnnotation)) {
6464
if (getAnnotationQuery().matchesAnnotation(fqn)) {
6565
return doElementsMatch(innerAnnotation);
6666
}
6767
}
6868
}
69+
} else if (member.getValue() instanceof IAnnotation) {
70+
Annotation innerAnnotation = (Annotation) member.getValue();
71+
for (String fqn : getFQNCandidates(innerAnnotation)) {
72+
if (getAnnotationQuery().matchesAnnotation(fqn)) {
73+
return doElementsMatch(innerAnnotation);
74+
}
75+
}
6976
}
7077
}
71-
7278
}
7379
}
7480
return false;
@@ -178,21 +184,37 @@ private IAnnotation[] tryToGetAnnotations(SourceRefElement t) {
178184
}
179185

180186
/**
181-
* Tries to extract the fqn of the annotation from the list of imports of the compilation unit.
187+
* Returns all possible FQNs for this annotation from the CU's imports: single-type match (if any)
188+
* first, then one candidate per on-demand import. Caller tries each until the rule matches.
182189
*/
183-
private String getFQN(IAnnotation annotation) {
190+
private List<String> getFQNCandidates(IAnnotation annotation) {
184191
String name = annotation.getElementName();
185-
if (Pattern.matches(".*\\.", name)) {
186-
// If the name of the annotation has a dot on it, it's a fqn
187-
return name;
188-
} else {
189-
// If not, the annotation must have been imported. Look in the imports:
190-
return tryToGetImports(annotation).stream()
191-
.filter(i -> i.getElementName().endsWith(name))
192-
.findFirst()
193-
.map(IImportDeclaration::getElementName)
194-
.orElse("");
192+
if (name == null || name.isEmpty()) {
193+
return List.of();
194+
}
195+
// Already fully qualified in source (e.g. @com.example.MyAnnotation)
196+
if (name.contains(".")) {
197+
return List.of(name);
198+
}
199+
List<IImportDeclaration> imports = tryToGetImports(annotation);
200+
List<String> candidates = new ArrayList<>();
201+
// Single-type: at most one
202+
imports.stream()
203+
.filter(i -> i.getElementName().endsWith(name))
204+
.findFirst()
205+
.map(IImportDeclaration::getElementName)
206+
.ifPresent(candidates::add);
207+
// On-demand: one candidate per pkg.*
208+
for (IImportDeclaration imp : imports) {
209+
String elementName = imp.getElementName();
210+
if (elementName != null && elementName.endsWith(".*")) {
211+
String prefix = elementName.substring(0, elementName.length() - 2);
212+
if (!prefix.isEmpty()) {
213+
candidates.add(prefix + "." + name);
214+
}
215+
}
195216
}
217+
return candidates;
196218
}
197219

198220
private List<IImportDeclaration> tryToGetImports(IAnnotation annotation) {

0 commit comments

Comments
 (0)