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

🐛 Add annotation inspection support #104

Merged
merged 4 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
@@ -1,5 +1,7 @@
package io.konveyor.tackle.core.internal;

import io.konveyor.tackle.core.internal.query.AnnotationQuery;

import static java.lang.String.format;

import java.util.ArrayList;
Expand All @@ -10,6 +12,7 @@ public class RuleEntryParams {

private final String projectName;
private final String query;
private final AnnotationQuery annotationQuery;
private final int location;
private final String analysisMode;
private final ArrayList<String> includedPaths;
Expand All @@ -22,6 +25,7 @@ public RuleEntryParams(final String commandId, final List<Object> arguments) {

this.projectName = (String) obj.get("project");
this.query = (String) obj.get("query");
this.annotationQuery = AnnotationQuery.fromMap((Map<String, Object>) obj.get("annotationQuery"));
this.location = Integer.parseInt((String) obj.get("location"));
this.analysisMode = (String) obj.get("analysisMode");
this.includedPaths = (ArrayList<String>) obj.get("includedPaths");
Expand All @@ -35,6 +39,10 @@ public String getQuery() {
return query;
}

public AnnotationQuery getAnnotationQuery() {
return annotationQuery;
}

public int getLocation() {
return location;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import io.konveyor.tackle.core.internal.query.AnnotationQuery;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
Expand Down Expand Up @@ -41,7 +43,7 @@ public Object executeCommand(String commandId, List<Object> arguments, IProgress
case RULE_ENTRY_COMMAND_ID:
logInfo("Here we get the arguments for rule entry: "+arguments);
RuleEntryParams params = new RuleEntryParams(commandId, arguments);
return search(params.getProjectName(), params.getIncludedPaths(), params.getQuery(), params.getLocation(), params.getAnalysisMode(), progress);
return search(params.getProjectName(), params.getIncludedPaths(), params.getQuery(), params.getAnnotationQuery(), params.getLocation(), params.getAnalysisMode(), progress);
default:
throw new UnsupportedOperationException(format("Unsupported command '%s'!", commandId));
}
Expand All @@ -60,7 +62,8 @@ private static void waitForJavaSourceDownloads() {
private static SearchPattern mapLocationToSearchPatternLocation(int location, String query) throws Exception {
//TODO: #21 Normalize queries and/or verify for each location.

if (query.contains("(") || query.contains(")")) {
Pattern orPattern = Pattern.compile(".*\\(.*\\|.*\\).*");
if (orPattern.matcher(query).matches()) {
// We know that this is a list of things to loook for, broken by a | command. We should get this intra string and create an OR search pattern for each one.
// ex java.io.((FileWriter|FileReader|PrintStream|File|PrintWriter|RandomAccessFile))*
// startQuery will contain java.io. and endQuery will contain *
Expand Down Expand Up @@ -108,6 +111,28 @@ private static SearchPattern mapLocationToSearchPatternLocation(int location, St
return getPatternSingleQuery(location, query);
}

/**
Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you so much!

* Location correspondence from java provider (TYPE is the default):
* "": 0,
* "inheritance": 1,
* "method_call": 2,
* "constructor_call": 3,
* "annotation": 4,
* "implements_type": 5,
* "enum_constant": 6,
* "return_type": 7,
* "import": 8,
* "variable_declaration": 9,
* "type": 10,
* "package": 11,
* "field": 12,
* "method_declaration": 13,
*
* @param location
* @param query
* @return
* @throws Exception
*/
private static SearchPattern getPatternSingleQuery(int location, String query) throws Exception {
var pattern = SearchPattern.R_PATTERN_MATCH;
if ((!query.contains("?") || !query.contains("*")) && (location != 11)) {
Expand Down Expand Up @@ -139,11 +164,13 @@ private static SearchPattern getPatternSingleQuery(int location, String query) t
return SearchPattern.createPattern(query, IJavaSearchConstants.PACKAGE, IJavaSearchConstants.ALL_OCCURRENCES, pattern);
case 12:
return SearchPattern.createPattern(query, IJavaSearchConstants.TYPE, IJavaSearchConstants.FIELD_DECLARATION_TYPE_REFERENCE, pattern);
case 13:
return SearchPattern.createPattern(query, IJavaSearchConstants.METHOD, IJavaSearchConstants.DECLARATIONS, SearchPattern.R_EXACT_MATCH | SearchPattern.R_PATTERN_MATCH);
}
throw new Exception("unable to create search pattern");
}

private static List<SymbolInformation> search(String projectName, ArrayList<String> includedPaths, String query, int location, String analsysisMode, IProgressMonitor monitor) throws Exception {
private static List<SymbolInformation> search(String projectName, ArrayList<String> includedPaths, String query, AnnotationQuery annotationQuery, int location, String analsysisMode, IProgressMonitor monitor) throws Exception {
IJavaProject[] targetProjects;
IJavaProject project = ProjectUtils.getJavaProject(projectName);
if (project != null) {
Expand All @@ -168,7 +195,7 @@ private static List<SymbolInformation> search(String projectName, ArrayList<Stri
for (IJavaProject iJavaProject : targetProjects) {
var errors = ResourceUtils.getErrorMarkers(iJavaProject.getProject());
var warnings = ResourceUtils.getWarningMarkers(iJavaProject.getProject());
logInfo("KONVEYOR_LOG:" +
logInfo("KONVEYOR_LOG:" +
" found errors: " + errors.toString().replace("\n", " ") +
" warnings: " + warnings.toString().replace("\n", " "));
}
Expand Down Expand Up @@ -227,7 +254,7 @@ private static List<SymbolInformation> search(String projectName, ArrayList<Stri

List<SymbolInformation> symbols = new ArrayList<SymbolInformation>();

SymbolInformationTypeRequestor requestor = new SymbolInformationTypeRequestor(symbols, 0, monitor, location, query);
SymbolInformationTypeRequestor requestor = new SymbolInformationTypeRequestor(symbols, 0, monitor, location, query, annotationQuery);

//Use the default search participents
SearchParticipant participent = new JavaSearchParticipant();
Expand All @@ -240,9 +267,9 @@ private static List<SymbolInformation> search(String projectName, ArrayList<Stri
logInfo("KONVEYOR_LOG: unable to get search " + e.toString().replace("\n", " "));
}

logInfo("KONVEYOR_LOG: got: " + requestor.getAllSearchMatches() +
" search matches for " + query +
" location " + location
logInfo("KONVEYOR_LOG: got: " + requestor.getAllSearchMatches() +
" search matches for " + query +
" location " + location
+ " matches" + requestor.getSymbols().size());

return requestor.getSymbols();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
import org.eclipse.jdt.ls.core.internal.ResourceUtils;
import org.eclipse.lsp4j.SymbolInformation;

import io.konveyor.tackle.core.internal.query.AnnotationQuery;
import io.konveyor.tackle.core.internal.symbol.SymbolProvider;
import io.konveyor.tackle.core.internal.symbol.SymbolProviderResolver;
import io.konveyor.tackle.core.internal.symbol.WithAnnotationQuery;
import io.konveyor.tackle.core.internal.symbol.WithMaxResults;
import io.konveyor.tackle.core.internal.symbol.WithQuery;

Expand All @@ -29,14 +31,16 @@ public class SymbolInformationTypeRequestor extends SearchRequestor {
private IProgressMonitor monitor;
private int symbolKind;
private String query;
private AnnotationQuery annotationQuery;

public SymbolInformationTypeRequestor(List<SymbolInformation> symbols, int maxResults, IProgressMonitor monitor, int symbolKind, String query) {
public SymbolInformationTypeRequestor(List<SymbolInformation> symbols, int maxResults, IProgressMonitor monitor, int symbolKind, String query, AnnotationQuery annotationQuery) {
this.symbols = symbols;
this.maxResults = maxResults;
this.monitor = monitor;
this.symbolKind = symbolKind;
this.query = query;
this.numberSearchMatches = 0;
this.annotationQuery = annotationQuery;
if (maxResults == 0) {
this.maxResults = 10000;
}
Expand Down Expand Up @@ -66,10 +70,13 @@ public void acceptSearchMatch(SearchMatch match) throws CoreException {

}

SymbolProvider symbolProvider = SymbolProviderResolver.resolve(this.symbolKind, match);
SymbolProvider symbolProvider = SymbolProviderResolver.resolve(this.symbolKind);
if (symbolProvider instanceof WithQuery) {
((WithQuery) symbolProvider).setQuery(this.query);
}
if (symbolProvider instanceof WithAnnotationQuery) {
((WithAnnotationQuery) symbolProvider).setAnnotationQuery(this.annotationQuery);
}
if (symbolProvider instanceof WithMaxResults) {
((WithMaxResults) symbolProvider).setMaxResultes(this.maxResults);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package io.konveyor.tackle.core.internal.query;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* Represents additional query information to inspect annotations in annotated symbols.
*/
public class AnnotationQuery {

/**
* The annotation type, ie: <code>@org.business.BeanAnnotation</code>
*/
private String type;

/**
* The elements within the annotation, ie, "value" in <code>@BeanAnnotation(value = "value")</code>
*/
private Map<String, String> elements;

public AnnotationQuery(String type, Map<String, String> elements) {
this.type = type;
this.elements = elements;
}

public String getType() {
return type;
}

public Map<String, String> getElements() {
return elements;
}

public static AnnotationQuery fromMap(Map<String, Object> query) {
if (query == null) {
return null;
}

String typePattern = (String) query.get("pattern");
final Map<String, String> elements = new HashMap<>();
List<Map<String, String>> mapElements = (List<Map<String, String>>) query.get("elements");
for (int i = 0; mapElements != null && i < mapElements.size(); i++) {
String key = mapElements.get(i).get("name");
String value = mapElements.get(i).get("value");
elements.put(key, value);
}

return new AnnotationQuery(typePattern, elements);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package io.konveyor.tackle.core.internal.symbol;

import static org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin.logInfo;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Pattern;

import io.konveyor.tackle.core.internal.query.AnnotationQuery;
import org.eclipse.core.runtime.URIUtil;
import org.eclipse.jdt.core.IAnnotation;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IImportDeclaration;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMemberValuePair;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageDeclaration;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.search.FieldDeclarationMatch;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.core.search.MethodDeclarationMatch;
import org.eclipse.jdt.core.search.TypeReferenceMatch;
import org.eclipse.jdt.internal.core.Annotation;
import org.eclipse.jdt.internal.core.ResolvedSourceField;
import org.eclipse.jdt.internal.core.ResolvedSourceMethod;
import org.eclipse.jdt.internal.core.ResolvedSourceType;
import org.eclipse.jdt.internal.core.SourceMethod;
import org.eclipse.jdt.internal.core.SourceRefElement;
import org.eclipse.lsp4j.Location;
import org.eclipse.lsp4j.SymbolInformation;
import org.eclipse.lsp4j.SymbolKind;

public class FieldSymbolProvider implements SymbolProvider, WithQuery, WithAnnotationQuery {
private String query;
private AnnotationQuery annotationQuery;

public List<SymbolInformation> get(SearchMatch match) {
SymbolKind k = convertSymbolKind((IJavaElement) match.getElement());
List<SymbolInformation> symbols = new ArrayList<>();
try {
TypeReferenceMatch m = (TypeReferenceMatch) match;
ResolvedSourceField e = (ResolvedSourceField) m.getElement();
SymbolInformation symbol = new SymbolInformation();
symbol.setName(e.getElementName());
symbol.setKind(convertSymbolKind(e));
symbol.setContainerName(e.getParent().getElementName());
symbol.setLocation(getLocation(e, match));

List<Class<? extends SourceRefElement>> classes = new ArrayList<>();
classes.add(ResolvedSourceField.class);
if (matchesAnnotationQuery(match, classes)) {
symbols.add(symbol);
}
} catch (Exception e) {
logInfo("unable to convert for variable: " + e);
}

return symbols;
}

public void setQuery(String query) {
this.query = query;
}

@Override
public AnnotationQuery getAnnotationQuery() {
return this.annotationQuery;
}

public void setAnnotationQuery(AnnotationQuery annotationQuery) {
this.annotationQuery = annotationQuery;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@
import java.util.ArrayList;
import java.util.List;

import io.konveyor.tackle.core.internal.query.AnnotationQuery;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.internal.core.ResolvedSourceMethod;
import org.eclipse.jdt.internal.core.ResolvedSourceType;
import org.eclipse.jdt.internal.core.SourceRefElement;
import org.eclipse.lsp4j.SymbolInformation;

public class ImplementsTypeSymbolProvider implements SymbolProvider {
public class ImplementsTypeSymbolProvider implements SymbolProvider, WithAnnotationQuery {
private AnnotationQuery annotationQuery;

@Override
public List<SymbolInformation> get(SearchMatch match) throws CoreException {
List<SymbolInformation> symbols = new ArrayList<>();
Expand All @@ -26,11 +32,26 @@ public List<SymbolInformation> get(SearchMatch match) throws CoreException {
symbol.setKind(convertSymbolKind(mod));
symbol.setContainerName(mod.getParent().getElementName());
symbol.setLocation(getLocation(mod, match));
symbols.add(symbol);

List<Class<? extends SourceRefElement>> classes = new ArrayList<>();
classes.add(ResolvedSourceType.class);
if (matchesAnnotationQuery(match, classes)) {
symbols.add(symbol);
}
} catch (Exception e) {
logInfo("unable to convert for implements type: " + e);
return null;
}
return symbols;
}

@Override
public AnnotationQuery getAnnotationQuery() {
return this.annotationQuery;
}

@Override
public void setAnnotationQuery(AnnotationQuery annotationQuery) {
this.annotationQuery = annotationQuery;
}
}
Loading
Loading