Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
1 change: 1 addition & 0 deletions jdtls.ext/com.microsoft.jdtls.ext.core/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<command id="java.project.generateJar" />
<command id="java.project.checkImportStatus" />
<command id="java.project.getImportClassContent" />
<command id="java.project.getDependencies" />
</delegateCommandHandler>
</extension>
<extension
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ public Object executeCommand(String commandId, List<Object> arguments, IProgress
return ProjectCommand.checkImportStatus();
case "java.project.getImportClassContent":
return ProjectCommand.getImportClassContent(arguments, monitor);
case "java.project.getDependencies":
return ProjectCommand.getProjectDependencies(arguments, monitor);
default:
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
import com.google.gson.GsonBuilder;
import com.microsoft.jdtls.ext.core.parser.ContextResolver;
import com.microsoft.jdtls.ext.core.parser.ContextResolver.ImportClassInfo;
import com.microsoft.jdtls.ext.core.parser.ProjectResolver;
import com.microsoft.jdtls.ext.core.model.PackageNode;

public final class ProjectCommand {
Expand All @@ -87,7 +88,15 @@ public MainClassInfo(String name, String path) {
}
}

private static class DependencyInfo {
public String key;
public String value;

public DependencyInfo(String key, String value) {
this.key = key;
this.value = value;
}
}

private static class Classpath {
public String source;
Expand Down Expand Up @@ -341,9 +350,20 @@ public static boolean checkImportStatus() {
return hasError;
}

// Threshold for triggering external dependency resolution
// If project source classes < this value, supplement with external dependencies
private static final int MIN_SOURCE_CLASSES_THRESHOLD = 5;

// Maximum number of external dependency classes to include
private static final int MAX_DEPENDENCY_CLASSES = 10;

// Maximum methods to display for binary (external) classes
private static final int MAX_METHODS_FOR_BINARY = 5;
Comment thread
wenytang-ms marked this conversation as resolved.
Outdated

/**
* Get import class content for Copilot integration.
* This method extracts information about imported classes from a Java file.
* Uses an adaptive strategy: only includes external dependencies when project sources are sparse.
*
* @param arguments List containing the file URI as the first element
* @param monitor Progress monitor for cancellation support
Expand Down Expand Up @@ -395,6 +415,7 @@ public static List<ImportClassInfo> getImportClassContent(List<Object> arguments
org.eclipse.jdt.core.IImportDeclaration[] imports = compilationUnit.getImports();
Set<String> processedTypes = new HashSet<>();

// Phase 1: Resolve project source classes only
for (org.eclipse.jdt.core.IImportDeclaration importDecl : imports) {
if (monitor.isCanceled()) {
break;
Expand All @@ -416,6 +437,36 @@ public static List<ImportClassInfo> getImportClassContent(List<Object> arguments
}
}

// Phase 2: Adaptive external dependency resolution
// Only trigger if project source classes are sparse (< threshold)
if (classInfoList.size() < MIN_SOURCE_CLASSES_THRESHOLD && !monitor.isCanceled()) {
Comment thread
wenytang-ms marked this conversation as resolved.
Outdated
// Track external classes separately to apply limits
List<ImportClassInfo> externalClasses = new ArrayList<>();

for (org.eclipse.jdt.core.IImportDeclaration importDecl : imports) {
if (monitor.isCanceled() || externalClasses.size() >= MAX_DEPENDENCY_CLASSES) {
break;
}

String importName = importDecl.getElementName();
boolean isStatic = (importDecl.getFlags() & org.eclipse.jdt.core.Flags.AccStatic) != 0;

// Skip package imports (*.* ) - too broad for external dependencies
if (importName.endsWith(".*")) {
continue;
}

// Resolve external (binary) types with simplified content
if (!isStatic) {
ContextResolver.resolveBinaryType(javaProject, importName, externalClasses,
processedTypes, MAX_METHODS_FOR_BINARY, monitor);
}
}

// Append external classes after project sources
classInfoList.addAll(externalClasses);
}

return classInfoList;

} catch (Exception e) {
Expand Down Expand Up @@ -449,6 +500,30 @@ private static String getSeverityString(int severity) {
}
}

/**
* Get project dependencies information including JDK version.
*
* @param arguments List containing the project URI as the first element
* @param monitor Progress monitor for cancellation support
* @return List of DependencyInfo containing key-value pairs of project information
*/
public static List<DependencyInfo> getProjectDependencies(List<Object> arguments, IProgressMonitor monitor) {
if (arguments == null || arguments.isEmpty()) {
return new ArrayList<>();
}

String projectUri = (String) arguments.get(0);
List<ProjectResolver.DependencyInfo> resolverResult = ProjectResolver.resolveProjectDependencies(projectUri, monitor);

// Convert ProjectResolver.DependencyInfo to ProjectCommand.DependencyInfo
List<DependencyInfo> result = new ArrayList<>();
for (ProjectResolver.DependencyInfo info : resolverResult) {
result.add(new DependencyInfo(info.key, info.value));
}

return result;
}

private static final class LinkedFolderVisitor implements IResourceVisitor {

private boolean belongsToWorkspace;
Expand Down
Loading
Loading