Skip to content

Commit e70b3b0

Browse files
authored
Merge branch 'main' into wenyt/changelog
2 parents 4f73467 + 1d4ac3f commit e70b3b0

File tree

7 files changed

+811
-211
lines changed

7 files changed

+811
-211
lines changed

jdtls.ext/com.microsoft.jdtls.ext.core/plugin.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
<command id="java.project.generateJar" />
1212
<command id="java.project.checkImportStatus" />
1313
<command id="java.project.getImportClassContent" />
14+
<command id="java.project.getDependencies" />
1415
</delegateCommandHandler>
1516
</extension>
1617
<extension

jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/CommandHandler.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ public Object executeCommand(String commandId, List<Object> arguments, IProgress
3939
return ProjectCommand.checkImportStatus();
4040
case "java.project.getImportClassContent":
4141
return ProjectCommand.getImportClassContent(arguments, monitor);
42+
case "java.project.getDependencies":
43+
return ProjectCommand.getProjectDependencies(arguments, monitor);
4244
default:
4345
break;
4446
}

jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/ProjectCommand.java

Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
import com.google.gson.GsonBuilder;
7272
import com.microsoft.jdtls.ext.core.parser.ContextResolver;
7373
import com.microsoft.jdtls.ext.core.parser.ContextResolver.ImportClassInfo;
74+
import com.microsoft.jdtls.ext.core.parser.ProjectResolver;
7475
import com.microsoft.jdtls.ext.core.model.PackageNode;
7576

7677
public final class ProjectCommand {
@@ -87,7 +88,15 @@ public MainClassInfo(String name, String path) {
8788
}
8889
}
8990

91+
private static class DependencyInfo {
92+
public String key;
93+
public String value;
9094

95+
public DependencyInfo(String key, String value) {
96+
this.key = key;
97+
this.value = value;
98+
}
99+
}
91100

92101
private static class Classpath {
93102
public String source;
@@ -344,6 +353,7 @@ public static boolean checkImportStatus() {
344353
/**
345354
* Get import class content for Copilot integration.
346355
* This method extracts information about imported classes from a Java file.
356+
* Uses a time-controlled strategy: prioritizes internal classes, adds external classes only if time permits.
347357
*
348358
* @param arguments List containing the file URI as the first element
349359
* @param monitor Progress monitor for cancellation support
@@ -354,6 +364,11 @@ public static List<ImportClassInfo> getImportClassContent(List<Object> arguments
354364
return Collections.emptyList();
355365
}
356366

367+
// Time control: total budget 80ms, early return at 75ms
368+
long startTime = System.currentTimeMillis();
369+
final long TIME_BUDGET_MS = 80;
370+
final long EARLY_RETURN_MS = 75;
371+
357372
try {
358373
String fileUri = (String) arguments.get(0);
359374

@@ -388,16 +403,18 @@ public static List<ImportClassInfo> getImportClassContent(List<Object> arguments
388403
org.eclipse.jdt.core.ICompilationUnit compilationUnit = (org.eclipse.jdt.core.ICompilationUnit) javaElement;
389404

390405
// Parse imports and resolve local project files
391-
// Delegate to JavaContentParser for processing
392406
List<ImportClassInfo> classInfoList = new ArrayList<>();
393407

394408
// Get all imports from the compilation unit
395409
org.eclipse.jdt.core.IImportDeclaration[] imports = compilationUnit.getImports();
396410
Set<String> processedTypes = new HashSet<>();
397411

412+
// Phase 1: Priority - Resolve project source classes (internal)
398413
for (org.eclipse.jdt.core.IImportDeclaration importDecl : imports) {
399-
if (monitor.isCanceled()) {
400-
break;
414+
// Check time budget before each operation
415+
long elapsed = System.currentTimeMillis() - startTime;
416+
if (monitor.isCanceled() || elapsed >= EARLY_RETURN_MS) {
417+
return classInfoList; // Early return if approaching time limit
401418
}
402419

403420
String importName = importDecl.getElementName();
@@ -416,6 +433,43 @@ public static List<ImportClassInfo> getImportClassContent(List<Object> arguments
416433
}
417434
}
418435

436+
// Phase 2: If time permits, resolve external dependencies
437+
long elapsedAfterInternal = System.currentTimeMillis() - startTime;
438+
if (elapsedAfterInternal < EARLY_RETURN_MS && !monitor.isCanceled()) {
439+
// Calculate remaining time budget for external classes
440+
long remainingTime = TIME_BUDGET_MS - elapsedAfterInternal;
441+
442+
// Only proceed with external if we have reasonable time left (at least 15ms)
443+
if (remainingTime >= 15) {
444+
List<ImportClassInfo> externalClasses = new ArrayList<>();
445+
446+
for (org.eclipse.jdt.core.IImportDeclaration importDecl : imports) {
447+
// Check time before each external resolution
448+
long currentElapsed = System.currentTimeMillis() - startTime;
449+
if (monitor.isCanceled() || currentElapsed >= EARLY_RETURN_MS) {
450+
break;
451+
}
452+
453+
String importName = importDecl.getElementName();
454+
boolean isStatic = (importDecl.getFlags() & org.eclipse.jdt.core.Flags.AccStatic) != 0;
455+
456+
// Skip package imports (*.* ) - too broad for external dependencies
457+
if (importName.endsWith(".*")) {
458+
continue;
459+
}
460+
461+
// Resolve external (binary) types with simplified content
462+
if (!isStatic) {
463+
ContextResolver.resolveBinaryType(javaProject, importName, externalClasses,
464+
processedTypes, Integer.MAX_VALUE, monitor);
465+
}
466+
}
467+
468+
// Append external classes after project sources
469+
classInfoList.addAll(externalClasses);
470+
}
471+
}
472+
419473
return classInfoList;
420474

421475
} catch (Exception e) {
@@ -449,6 +503,30 @@ private static String getSeverityString(int severity) {
449503
}
450504
}
451505

506+
/**
507+
* Get project dependencies information including JDK version.
508+
*
509+
* @param arguments List containing the project URI as the first element
510+
* @param monitor Progress monitor for cancellation support
511+
* @return List of DependencyInfo containing key-value pairs of project information
512+
*/
513+
public static List<DependencyInfo> getProjectDependencies(List<Object> arguments, IProgressMonitor monitor) {
514+
if (arguments == null || arguments.isEmpty()) {
515+
return new ArrayList<>();
516+
}
517+
518+
String projectUri = (String) arguments.get(0);
519+
List<ProjectResolver.DependencyInfo> resolverResult = ProjectResolver.resolveProjectDependencies(projectUri, monitor);
520+
521+
// Convert ProjectResolver.DependencyInfo to ProjectCommand.DependencyInfo
522+
List<DependencyInfo> result = new ArrayList<>();
523+
for (ProjectResolver.DependencyInfo info : resolverResult) {
524+
result.add(new DependencyInfo(info.key, info.value));
525+
}
526+
527+
return result;
528+
}
529+
452530
private static final class LinkedFolderVisitor implements IResourceVisitor {
453531

454532
private boolean belongsToWorkspace;

0 commit comments

Comments
 (0)