From 25dce3b87b726321d0f11521222c42e7cf2bdd56 Mon Sep 17 00:00:00 2001 From: Pranav Gaikwad Date: Tue, 25 Jun 2024 17:49:12 -0400 Subject: [PATCH 1/3] :bug: improve accuracy of MethodReference matches Signed-off-by: Pranav Gaikwad --- .../symbol/MethodCallSymbolProvider.java | 58 +++++++++++++++++-- .../core/internal/symbol/SymbolProvider.java | 9 +++ 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/MethodCallSymbolProvider.java b/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/MethodCallSymbolProvider.java index 7e62ac0..8577107 100644 --- a/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/MethodCallSymbolProvider.java +++ b/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/MethodCallSymbolProvider.java @@ -5,10 +5,18 @@ import java.util.ArrayList; import java.util.List; +import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.ITypeRoot; +import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.ASTParser; +import org.eclipse.jdt.core.dom.ASTVisitor; +import org.eclipse.jdt.core.dom.CompilationUnit; +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.MethodReferenceMatch; import org.eclipse.jdt.core.search.SearchMatch; import org.eclipse.lsp4j.SymbolInformation; @@ -25,12 +33,50 @@ public List get(SearchMatch match) { try { MethodReferenceMatch m = (MethodReferenceMatch) match; IMethod e = (IMethod) m.getElement(); - SymbolInformation symbol = new SymbolInformation(); - symbol.setName(e.getElementName()); - symbol.setKind(convertSymbolKind(e)); - symbol.setContainerName(e.getParent().getElementName()); - symbol.setLocation(getLocation(e, match)); - symbols.add(symbol); + if (this.query.contains(".")) { + ICompilationUnit unit = e.getCompilationUnit(); + ASTParser astParser = ASTParser.newParser(AST.getJLSLatest()); + 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))) { + SymbolInformation symbol = new SymbolInformation(); + symbol.setName(e.getElementName()); + symbol.setKind(convertSymbolKind(e)); + symbol.setContainerName(e.getParent().getElementName()); + symbol.setLocation(getLocation(e, match)); + symbols.add(symbol); + } else { + logInfo("fqn " + fullyQualifiedName + " did not match with " + query); + } + } + } + } catch (Exception e) { + logInfo("error determining accuracy of match: " + e); + } + return true; + } + }); + } else { + SymbolInformation symbol = new SymbolInformation(); + symbol.setName(e.getElementName()); + symbol.setKind(convertSymbolKind(e)); + symbol.setContainerName(e.getParent().getElementName()); + symbol.setLocation(getLocation(e, match)); + symbols.add(symbol); + } } catch (Exception e) { logInfo("unable to convert for variable: " + e); } diff --git a/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/SymbolProvider.java b/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/SymbolProvider.java index 382574b..e3331f2 100644 --- a/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/SymbolProvider.java +++ b/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/SymbolProvider.java @@ -167,4 +167,13 @@ 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("(? Date: Wed, 26 Jun 2024 09:46:24 -0400 Subject: [PATCH 2/3] improve accuracy of constructor call Signed-off-by: Pranav Gaikwad --- .../symbol/ConstructorCallSymbolProvider.java | 53 ++++++++++++++++++- .../symbol/MethodCallSymbolProvider.java | 15 ++---- 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/ConstructorCallSymbolProvider.java b/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/ConstructorCallSymbolProvider.java index 2b016b1..670da70 100644 --- a/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/ConstructorCallSymbolProvider.java +++ b/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/ConstructorCallSymbolProvider.java @@ -6,14 +6,24 @@ import java.util.List; import org.eclipse.core.runtime.CoreException; +import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.ASTParser; +import org.eclipse.jdt.core.dom.ASTVisitor; +import org.eclipse.jdt.core.dom.CompilationUnit; +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.MethodReferenceMatch; import org.eclipse.jdt.core.search.SearchMatch; import org.eclipse.jdt.internal.core.JavaElement; import org.eclipse.lsp4j.SymbolInformation; import org.eclipse.lsp4j.SymbolKind; -public class ConstructorCallSymbolProvider implements SymbolProvider { +public class ConstructorCallSymbolProvider implements SymbolProvider, WithQuery { + public String query; + @Override public List get(SearchMatch match) throws CoreException { List symbols = new ArrayList<>(); @@ -32,11 +42,50 @@ public List get(SearchMatch match) throws CoreException { } symbol.setContainerName(mod.getParent().getElementName()); symbol.setLocation(getLocation(mod, match)); - symbols.add(symbol); + if (this.query.contains(".")) { + ICompilationUnit unit = mod.getCompilationUnit(); + ASTParser astParser = ASTParser.newParser(AST.getJLSLatest()); + 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; + } + }); + } else { + symbols.add(symbol); + } } catch (Exception e) { logInfo("unable to get constructor: " + e); return null; } return symbols; } + + @Override + public void setQuery(String query) { + // TODO Auto-generated method stub + this.query = query; + } } diff --git a/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/MethodCallSymbolProvider.java b/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/MethodCallSymbolProvider.java index 8577107..52bb007 100644 --- a/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/MethodCallSymbolProvider.java +++ b/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/MethodCallSymbolProvider.java @@ -33,6 +33,11 @@ public List get(SearchMatch match) { try { MethodReferenceMatch m = (MethodReferenceMatch) match; IMethod e = (IMethod) m.getElement(); + SymbolInformation symbol = new SymbolInformation(); + symbol.setName(e.getElementName()); + symbol.setKind(convertSymbolKind(e)); + symbol.setContainerName(e.getParent().getElementName()); + symbol.setLocation(getLocation(e, match)); if (this.query.contains(".")) { ICompilationUnit unit = e.getCompilationUnit(); ASTParser astParser = ASTParser.newParser(AST.getJLSLatest()); @@ -52,11 +57,6 @@ public boolean visit(MethodInvocation node) { String fullyQualifiedName = declaringClass.getQualifiedName() + "." + binding.getName(); // match fqn with query pattern if (fullyQualifiedName.matches(getCleanedQuery(query))) { - SymbolInformation symbol = new SymbolInformation(); - symbol.setName(e.getElementName()); - symbol.setKind(convertSymbolKind(e)); - symbol.setContainerName(e.getParent().getElementName()); - symbol.setLocation(getLocation(e, match)); symbols.add(symbol); } else { logInfo("fqn " + fullyQualifiedName + " did not match with " + query); @@ -70,11 +70,6 @@ public boolean visit(MethodInvocation node) { } }); } else { - SymbolInformation symbol = new SymbolInformation(); - symbol.setName(e.getElementName()); - symbol.setKind(convertSymbolKind(e)); - symbol.setContainerName(e.getParent().getElementName()); - symbol.setLocation(getLocation(e, match)); symbols.add(symbol); } } catch (Exception e) { From 87175e67ad0162fa828f6460fedddd80e8c8f078 Mon Sep 17 00:00:00 2001 From: Pranav Gaikwad Date: Wed, 26 Jun 2024 12:40:12 -0400 Subject: [PATCH 3/3] :ghost: improve logic / structure a bit Signed-off-by: Pranav Gaikwad --- .../symbol/ConstructorCallSymbolProvider.java | 30 ++----- .../internal/symbol/CustomASTVisitor.java | 86 +++++++++++++++++++ .../symbol/MethodCallSymbolProvider.java | 30 ++----- .../core/internal/symbol/SymbolProvider.java | 9 -- 4 files changed, 96 insertions(+), 59 deletions(-) create mode 100644 java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/CustomASTVisitor.java diff --git a/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/ConstructorCallSymbolProvider.java b/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/ConstructorCallSymbolProvider.java index 670da70..1bf8cdb 100644 --- a/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/ConstructorCallSymbolProvider.java +++ b/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/ConstructorCallSymbolProvider.java @@ -48,31 +48,11 @@ public List 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); } diff --git a/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/CustomASTVisitor.java b/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/CustomASTVisitor.java new file mode 100644 index 0000000..7251e70 --- /dev/null +++ b/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/CustomASTVisitor.java @@ -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("(? 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); } diff --git a/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/SymbolProvider.java b/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/SymbolProvider.java index e3331f2..382574b 100644 --- a/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/SymbolProvider.java +++ b/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/symbol/SymbolProvider.java @@ -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("(?