Skip to content
Merged
Changes from 4 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
Expand Up @@ -5,6 +5,7 @@

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

import org.eclipse.core.runtime.IPath;
Expand All @@ -14,20 +15,31 @@
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.ImportDeclaration;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchParticipant;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.internal.core.search.JavaSearchParticipant;
import org.eclipse.jdt.ls.core.internal.IDelegateCommandHandler;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin;
import org.eclipse.jdt.ls.core.internal.JobHelpers;
import org.eclipse.jdt.ls.core.internal.ProjectUtils;
import org.eclipse.jdt.ls.core.internal.ResourceUtils;
import org.eclipse.lsp4j.Location;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.SymbolInformation;
import org.eclipse.lsp4j.SymbolKind;

import io.konveyor.tackle.core.internal.query.AnnotationQuery;
import io.konveyor.tackle.core.internal.symbol.DefaultSymbolProvider;
import io.konveyor.tackle.core.internal.symbol.ImportSymbolProvider;
import io.konveyor.tackle.core.internal.util.OpenSourceFilteredSearchScope;
import io.konveyor.tackle.core.internal.util.OpenSourceLibraryExclusionManager;

Expand Down Expand Up @@ -150,6 +162,8 @@ private static SearchPattern mapLocationToSearchPatternLocation(int location, St
* @param query
* @return
* @throws Exception
*
* TODO: move these to enums
*/
private static SearchPattern getPatternSingleQuery(int location, String query) throws Exception {
var pattern = SearchPattern.R_PATTERN_MATCH;
Expand Down Expand Up @@ -228,6 +242,8 @@ private static List<SymbolInformation> search(String projectName, ArrayList<Stri
return new ArrayList<>();
}

List<ICompilationUnit> units = new ArrayList<>();

if (includedPaths != null && includedPaths.size() > 0) {
ArrayList<IJavaElement> includedFragments = new ArrayList<IJavaElement>();
for (IJavaProject proj : targetProjects) {
Expand Down Expand Up @@ -295,6 +311,11 @@ private static List<SymbolInformation> search(String projectName, ArrayList<Stri
if (includedIPath.segmentCount() <= fragmentPath.segmentCount() &&
includedIPath.matchingFirstSegments(fragmentPath) == includedIPath.segmentCount()) {
includedFragments.add(fragment);

// Get all compilation units for included fragments
if (fragment.getKind() == IPackageFragmentRoot.K_SOURCE) {
units.addAll(List.of(fragment.getCompilationUnits()));
}
}
}
}
Expand All @@ -313,6 +334,8 @@ private static List<SymbolInformation> search(String projectName, ArrayList<Stri
}
logInfo("scope: " + scope);

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

SearchPattern pattern;
try {
pattern = mapLocationToSearchPatternLocation(location, query);
Expand All @@ -325,8 +348,6 @@ private static List<SymbolInformation> search(String projectName, ArrayList<Stri

SearchEngine searchEngine = new SearchEngine();

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

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

//Use the default search participents
Expand All @@ -340,12 +361,64 @@ private static List<SymbolInformation> search(String projectName, ArrayList<Stri
logInfo("KONVEYOR_LOG: unable to get search " + e.toString().replace("\n", " "));
}

symbols.addAll(requestor.getSymbols());

if (location == 8) {
Matcher matcher = Pattern.compile("[^A-Z*]+\\*").matcher(query);
if (matcher.matches()) {
// IMPORT location and package wildcard

// Get all compilation units in scope
for (IJavaProject p : targetProjects) {
for (IPackageFragment pkg : p.getPackageFragments()) {
if (pkg.getKind() == IPackageFragmentRoot.K_SOURCE) {
for (ICompilationUnit unit : pkg.getCompilationUnits()) {
if (scope.encloses(unit)) {
units.add(unit);
}
}
}
}
}
Comment on lines +364 to +375
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Avoid redundant compilation unit collection.

When includedPaths is specified, compilation units are already collected from included fragments at lines 310-313. The code then re-collects all units from all target projects (lines 364-375), creating duplicates and wasting resources.

Apply this fix to collect units only when not already gathered:

-                // Get all compilation units in scope
-                for (IJavaProject p : targetProjects) {
-                    for (IPackageFragment pkg : p.getPackageFragments()) {
-                        if (pkg.getKind() == IPackageFragmentRoot.K_SOURCE) {
-                            for (ICompilationUnit unit : pkg.getCompilationUnits()) {
-                                if (scope.encloses(unit)) {
-                                    units.add(unit);
-                                }
-                            }
-                        }
-                    }
-                }
+                // Get all compilation units in scope (if not already collected via included paths)
+                if (units.isEmpty()) {
+                    for (IJavaProject p : targetProjects) {
+                        for (IPackageFragment pkg : p.getPackageFragments()) {
+                            if (pkg.getKind() == IPackageFragmentRoot.K_SOURCE) {
+                                for (ICompilationUnit unit : pkg.getCompilationUnits()) {
+                                    if (scope.encloses(unit)) {
+                                        units.add(unit);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Get all compilation units in scope
for (IJavaProject p : targetProjects) {
for (IPackageFragment pkg : p.getPackageFragments()) {
if (pkg.getKind() == IPackageFragmentRoot.K_SOURCE) {
for (ICompilationUnit unit : pkg.getCompilationUnits()) {
if (scope.encloses(unit)) {
units.add(unit);
}
}
}
}
}
// Get all compilation units in scope (if not already collected via included paths)
if (units.isEmpty()) {
for (IJavaProject p : targetProjects) {
for (IPackageFragment pkg : p.getPackageFragments()) {
if (pkg.getKind() == IPackageFragmentRoot.K_SOURCE) {
for (ICompilationUnit unit : pkg.getCompilationUnits()) {
if (scope.encloses(unit)) {
units.add(unit);
}
}
}
}
}
}
🤖 Prompt for AI Agents
In
java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/SampleDelegateCommandHandler.java
around lines 364-375, the code re-collects compilation units from all target
projects even when includedPaths already added units earlier, producing
duplicates and wasting resources; change the logic to skip this full-project
collection when units were already gathered from included fragments (e.g., check
a flag or whether includedPaths is non-null/non-empty or units is non-empty) so
the loop over all package fragments only runs if no units were previously
collected; optionally ensure the collection uses a Set or deduplication if you
must merge sources.


// Now run ImportScanner only on units in scope
ASTParser parser = ASTParser.newParser(AST.getJLSLatest());
Pattern regex = Pattern.compile(query);
for (ICompilationUnit unit : units) {
parser.setSource(unit);
CompilationUnit cu = (CompilationUnit) parser.createAST(null);
for (Object o : cu.imports()) {
ImportDeclaration imp = (ImportDeclaration) o;
if (imp.isOnDemand()) {
if (regex.matcher(imp.getName().getFullyQualifiedName()).matches()) {
SymbolInformation symbol = new SymbolInformation();
symbol.setName(imp.getName().getFullyQualifiedName());
symbol.setKind(SymbolKind.Namespace);
symbol.setContainerName(unit.getElementName());
symbol.setLocation(getLocationForImport(unit, imp, cu));
System.out.println("Found in " + unit.getElementName());
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove debug print statement.

The System.out.println statement should be replaced with proper logging using logInfo.

-                                System.out.println("Found in " + unit.getElementName());
+                                logInfo("Found on-demand import in " + unit.getElementName());
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
System.out.println("Found in " + unit.getElementName());
logInfo("Found on-demand import in " + unit.getElementName());
🤖 Prompt for AI Agents
In
java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/SampleDelegateCommandHandler.java
around line 384, replace the debug System.out.println("Found in " +
unit.getElementName()); with a proper logging call using logInfo; remove the
println and invoke logInfo with a clear message (e.g., "Found in " plus
unit.getElementName()) so the information is recorded via the project's logging
facility instead of standard output.

symbols.add(symbol);
}
}
}
}
}
}

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

return requestor.getSymbols();
return symbols;

}
}

public static Location getLocationForImport(ICompilationUnit icu, ImportDeclaration imp, CompilationUnit cuAst) {
try {
return JDTUtils.toLocation(icu, imp.getStartPosition(), imp.getLength());
} catch (Exception e) {
logInfo("Unable to get location for import: " + e);
return null;
}
}
Loading