Skip to content

Commit

Permalink
👻 improve logic / structure a bit
Browse files Browse the repository at this point in the history
Signed-off-by: Pranav Gaikwad <[email protected]>
  • Loading branch information
pranavgaikwad committed Jun 28, 2024
1 parent 63380d9 commit 87175e6
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,31 +48,11 @@ public List<SymbolInformation> get(SearchMatch match) throws CoreException {
astParser.setSource(unit);
astParser.setResolveBindings(true);
CompilationUnit cu = (CompilationUnit) astParser.createAST(null);
cu.accept(new ASTVisitor() {
// we are only doing this for MethodInvocation right now
// look into MethodDeclaration if needed
public boolean visit(MethodInvocation node) {
try {
IMethodBinding binding = node.resolveMethodBinding();
if (binding != null) {
// get fqn of the method being called
ITypeBinding declaringClass = binding.getDeclaringClass();
if (declaringClass != null) {
String fullyQualifiedName = declaringClass.getQualifiedName() + "." + binding.getName();
// match fqn with query pattern
if (fullyQualifiedName.matches(getCleanedQuery(query))) {
symbols.add(symbol);
} else {
logInfo("fqn " + fullyQualifiedName + " did not match with " + query);
}
}
}
} catch (Exception e) {
logInfo("error determining accuracy of match: " + e);
}
return true;
}
});
CustomASTVisitor visitor = new CustomASTVisitor(query, match);
cu.accept(visitor);
if (visitor.symbolMatches()) {
symbols.add(symbol);
}
} else {
symbols.add(symbol);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package io.konveyor.tackle.core.internal.symbol;

import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.search.SearchMatch;

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

public class CustomASTVisitor extends ASTVisitor {
private String query;
private SearchMatch match;
private boolean symbolMatches;


public CustomASTVisitor(String query, SearchMatch match) {
/*
* When comparing query pattern with an actual java element's fqn
* we need to make sure that * not preceded with a . are replaced
* by .* so that java regex works as expected on them
*/
this.query = query.replaceAll("(?<!\\.)\\*", ".*");
this.symbolMatches = false;
this.match = match;
}

/*
* When visiting AST nodes, it may happen that we visit more nodes
* than needed. We need to ensure that we are only visiting ones
* that are found in the given search match. I wrote this for methods
* where I observed that a node starts at the beginning of line whereas match
* starts at an offset within that line. However, both end on the same position.
* This could differ for other locations. In that case, change logic based
* on type of the node you get.
*/
private boolean shouldVisit(ASTNode node) {
return (this.match.getOffset() + this.match.getLength()) ==
(node.getStartPosition() + node.getLength());
}

/*
* This is to get information from a MethodInvocation
* used for METHOD_CALL and CONSTRUCTOR_CALL matches
* we only discard a match only when we can tell for sure
* returning false stops further visits
*/
@Override
public boolean visit(MethodInvocation node) {
try {
if (!this.shouldVisit(node)) {
return true;
}
IMethodBinding binding = node.resolveMethodBinding();
if (binding != null) {
// get fqn of the method being called
ITypeBinding declaringClass = binding.getDeclaringClass();
if (declaringClass != null) {
String fullyQualifiedName = declaringClass.getQualifiedName() + "." + binding.getName();
// match fqn with query pattern
if (fullyQualifiedName.matches(this.query)) {
this.symbolMatches = true;
return false;
} else {
logInfo("method fqn " + fullyQualifiedName + " did not match with " + query);
return true;
}
}
}
// sometimes binding or declaring class cannot be found, usually due to errors
// in source code. in that case, we will fallback and accept the match
this.symbolMatches = true;
return false;
} catch (Exception e) {
logInfo("error visiting MethodInvocation node: " + e);
// this is so that we fallback to old approach and we dont lose a result
this.symbolMatches = true;
return false;
}
}

public boolean symbolMatches() {
return this.symbolMatches;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,31 +44,11 @@ public List<SymbolInformation> get(SearchMatch match) {
astParser.setSource(unit);
astParser.setResolveBindings(true);
CompilationUnit cu = (CompilationUnit) astParser.createAST(null);
cu.accept(new ASTVisitor() {
// we are only doing this for MethodInvocation right now
// look into MethodDeclaration if needed
public boolean visit(MethodInvocation node) {
try {
IMethodBinding binding = node.resolveMethodBinding();
if (binding != null) {
// get fqn of the method being called
ITypeBinding declaringClass = binding.getDeclaringClass();
if (declaringClass != null) {
String fullyQualifiedName = declaringClass.getQualifiedName() + "." + binding.getName();
// match fqn with query pattern
if (fullyQualifiedName.matches(getCleanedQuery(query))) {
symbols.add(symbol);
} else {
logInfo("fqn " + fullyQualifiedName + " did not match with " + query);
}
}
}
} catch (Exception e) {
logInfo("error determining accuracy of match: " + e);
}
return true;
}
});
CustomASTVisitor visitor = new CustomASTVisitor(query, match);
cu.accept(visitor);
if (visitor.symbolMatches()) {
symbols.add(symbol);
}
} else {
symbols.add(symbol);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,13 +167,4 @@ private static void setPosition(Position position, int[] coords) {
position.setLine(coords[0]);
position.setCharacter(coords[1]);
}

/*
* When comparing query pattern with an actual found java element's fqn
* we need to make sure that * that are not preceded with a . are replaced
* by .* so that java regex works as expected on them
*/
default String getCleanedQuery(String query) {
return query.replaceAll("(?<!\\.)\\*", ".*");
}
}

0 comments on commit 87175e6

Please sign in to comment.