Skip to content

Commit 135bdaa

Browse files
committed
perf: update the empty reason
1 parent 34691cf commit 135bdaa

File tree

1 file changed

+115
-73
lines changed

1 file changed

+115
-73
lines changed

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

Lines changed: 115 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -103,18 +103,18 @@ public DependencyInfo(String key, String value) {
103103
*/
104104
public enum ImportClassContentErrorReason {
105105
NULL_ARGUMENTS("NullArgs"),
106-
INVALID_URI("InvalidUri"),
107-
URI_PARSE_FAILED("UriParseFail"),
108-
FILE_NOT_FOUND("FileNotFound"),
109-
FILE_NOT_EXISTS("FileNotExists"),
110-
NOT_JAVA_PROJECT("NotJavaProject"),
111-
PROJECT_NOT_EXISTS("ProjectNotExists"),
112-
NOT_COMPILATION_UNIT("NotCompilationUnit"),
106+
INVALID_URI("InvalidURI"),
107+
URI_PARSE_FAILED("ParseFail"),
108+
FILE_NOT_FOUND("NotFound"),
109+
FILE_NOT_EXISTS("NotExists"),
110+
NOT_JAVA_PROJECT("NotJava"),
111+
PROJECT_NOT_EXISTS("ProjNotExists"),
112+
NOT_COMPILATION_UNIT("NotCU"),
113113
NO_IMPORTS("NoImports"),
114114
OPERATION_CANCELLED("Cancelled"),
115115
TIME_LIMIT_EXCEEDED("Timeout"),
116116
NO_RESULTS("NoResults"),
117-
PROCESSING_EXCEPTION("ProcessingError");
117+
PROCESSING_EXCEPTION("Error");
118118

119119
private final String message;
120120

@@ -132,13 +132,13 @@ public String getMessage() {
132132
*/
133133
public enum ProjectDependenciesErrorReason {
134134
NULL_ARGUMENTS("NullArgs"),
135-
INVALID_URI("InvalidUri"),
136-
URI_PARSE_FAILED("UriParseFail"),
137-
MALFORMED_URI("MalformedUri"),
135+
INVALID_URI("InvalidURI"),
136+
URI_PARSE_FAILED("ParseFail"),
137+
MALFORMED_URI("MalformedURI"),
138138
OPERATION_CANCELLED("Cancelled"),
139139
RESOLVER_NULL_RESULT("ResolverNull"),
140-
NO_DEPENDENCIES("NoDependencies"),
141-
PROCESSING_EXCEPTION("ProcessingError");
140+
NO_DEPENDENCIES("NoDeps"),
141+
PROCESSING_EXCEPTION("Error");
142142

143143
private final String message;
144144

@@ -151,24 +151,49 @@ public String getMessage() {
151151
}
152152
}
153153

154+
/**
155+
* Error context information for ImportClassContent operations
156+
*/
157+
public static class ErrorContext {
158+
public final String uri; // Original URI from arguments
159+
public final String parsedPath; // Parsed file path (if successful)
160+
public final String projectName; // Project name (if found)
161+
162+
public ErrorContext(String uri, String parsedPath, String projectName) {
163+
this.uri = uri;
164+
this.parsedPath = parsedPath;
165+
this.projectName = projectName;
166+
}
167+
}
168+
154169
/**
155170
* Result wrapper for getImportClassContent method
156171
*/
157172
public static class ImportClassContentResult {
158173
public List<ImportClassInfo> classInfoList;
159174
public String emptyReason; // Reason why the result is empty
160175
public boolean isEmpty;
176+
public ErrorContext errorContext; // Error context (only set when isEmpty = true)
161177

162178
public ImportClassContentResult(List<ImportClassInfo> classInfoList) {
163179
this.classInfoList = classInfoList;
164180
this.emptyReason = null;
165181
this.isEmpty = false;
182+
this.errorContext = null;
166183
}
167184

168185
public ImportClassContentResult(ImportClassContentErrorReason errorReason) {
169186
this.classInfoList = Collections.emptyList();
170187
this.emptyReason = errorReason.getMessage(); // Use enum message
171188
this.isEmpty = true;
189+
this.errorContext = null;
190+
}
191+
192+
public ImportClassContentResult(ImportClassContentErrorReason errorReason, String uri, String parsedPath, String projectName) {
193+
this.classInfoList = Collections.emptyList();
194+
this.emptyReason = errorReason.getMessage();
195+
this.isEmpty = true;
196+
this.errorContext = new ErrorContext(uri, parsedPath, projectName);
172197
}
173198
}
174199

@@ -179,17 +204,27 @@ public static class ProjectDependenciesResult {
179204
public List<DependencyInfo> dependencyInfoList;
180205
public String emptyReason; // Reason why the result is empty
181206
public boolean isEmpty;
207+
public ErrorContext errorContext; // Error context (only set when isEmpty = true)
182208

183209
public ProjectDependenciesResult(List<DependencyInfo> dependencyInfoList) {
184210
this.dependencyInfoList = dependencyInfoList;
185211
this.emptyReason = null;
186212
this.isEmpty = false;
213+
this.errorContext = null;
187214
}
188215

189216
public ProjectDependenciesResult(ProjectDependenciesErrorReason errorReason) {
190217
this.dependencyInfoList = new ArrayList<>();
191218
this.emptyReason = errorReason.getMessage(); // Use enum message
192219
this.isEmpty = true;
220+
this.errorContext = null;
221+
}
222+
223+
public ProjectDependenciesResult(ProjectDependenciesErrorReason errorReason, String uri, String parsedPath, String projectName) {
224+
this.dependencyInfoList = new ArrayList<>();
225+
this.emptyReason = errorReason.getMessage();
226+
this.isEmpty = true;
227+
this.errorContext = new ErrorContext(uri, parsedPath, projectName);
193228
}
194229
}
195230

@@ -476,24 +511,19 @@ public static List<ImportClassInfo> getImportClassContent(List<Object> arguments
476511
public static ImportClassContentResult getImportClassContentWithResult(List<Object> arguments,
477512
IProgressMonitor monitor) {
478513
if (arguments == null || arguments.isEmpty()) {
479-
return new ImportClassContentResult(ImportClassContentErrorReason.NULL_ARGUMENTS);
514+
return new ImportClassContentResult(ImportClassContentErrorReason.NULL_ARGUMENTS, null, null, null);
480515
}
481516

482-
// Time control: total budget 80ms, early return at 75ms
483-
long startTime = System.currentTimeMillis();
484-
final long TIME_BUDGET_MS = 80;
485-
final long EARLY_RETURN_MS = 75;
486-
487517
try {
488518
String fileUri = (String) arguments.get(0);
489519
if (fileUri == null || fileUri.trim().isEmpty()) {
490-
return new ImportClassContentResult(ImportClassContentErrorReason.INVALID_URI);
520+
return new ImportClassContentResult(ImportClassContentErrorReason.INVALID_URI, fileUri, null, null);
491521
}
492522
// Parse URI manually to avoid restricted API
493523
java.net.URI uri = new java.net.URI(fileUri);
494524
String filePath = uri.getPath();
495525
if (filePath == null) {
496-
return new ImportClassContentResult(ImportClassContentErrorReason.URI_PARSE_FAILED);
526+
return new ImportClassContentResult(ImportClassContentErrorReason.URI_PARSE_FAILED, fileUri, null, null);
497527
}
498528

499529
IPath path = new Path(filePath);
@@ -502,25 +532,27 @@ public static ImportClassContentResult getImportClassContentWithResult(List<Obje
502532
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
503533
IFile file = root.getFileForLocation(path);
504534
if (file == null || !file.exists()) {
505-
return new ImportClassContentResult(ImportClassContentErrorReason.FILE_NOT_FOUND);
535+
return new ImportClassContentResult(ImportClassContentErrorReason.FILE_NOT_FOUND, fileUri, filePath, null);
506536
}
507537
if (!file.exists()) {
508-
return new ImportClassContentResult(ImportClassContentErrorReason.FILE_NOT_EXISTS);
538+
return new ImportClassContentResult(ImportClassContentErrorReason.FILE_NOT_EXISTS, fileUri, filePath, null);
509539
}
510540

511541
// Get the Java project
512542
IJavaProject javaProject = JavaCore.create(file.getProject());
513543
if (javaProject == null) {
514-
return new ImportClassContentResult(ImportClassContentErrorReason.NOT_JAVA_PROJECT);
544+
return new ImportClassContentResult(ImportClassContentErrorReason.NOT_JAVA_PROJECT, fileUri, filePath, null);
515545
}
516546
if (!javaProject.exists()) {
517-
return new ImportClassContentResult(ImportClassContentErrorReason.PROJECT_NOT_EXISTS);
547+
String projectName = javaProject.getProject().getName();
548+
return new ImportClassContentResult(ImportClassContentErrorReason.PROJECT_NOT_EXISTS, fileUri, filePath, projectName);
518549
}
519550

520551
// Find the compilation unit
521552
IJavaElement javaElement = JavaCore.create(file);
522553
if (!(javaElement instanceof org.eclipse.jdt.core.ICompilationUnit)) {
523-
return new ImportClassContentResult(ImportClassContentErrorReason.NOT_COMPILATION_UNIT);
554+
String projectName = javaProject.getProject().getName();
555+
return new ImportClassContentResult(ImportClassContentErrorReason.NOT_COMPILATION_UNIT, fileUri, filePath, projectName);
524556
}
525557

526558
org.eclipse.jdt.core.ICompilationUnit compilationUnit = (org.eclipse.jdt.core.ICompilationUnit) javaElement;
@@ -534,18 +566,16 @@ public static ImportClassContentResult getImportClassContentWithResult(List<Obje
534566

535567
// Check if file has no imports
536568
if (imports == null || imports.length == 0) {
537-
return new ImportClassContentResult(ImportClassContentErrorReason.NO_IMPORTS);
569+
String projectName = javaProject.getProject().getName();
570+
return new ImportClassContentResult(ImportClassContentErrorReason.NO_IMPORTS, fileUri, filePath, projectName);
538571
}
539572

540573
// Phase 1: Priority - Resolve project source classes (internal)
574+
String projectName = javaProject.getProject().getName();
541575
for (org.eclipse.jdt.core.IImportDeclaration importDecl : imports) {
542-
// Check time budget before each operation
543-
long elapsed = System.currentTimeMillis() - startTime;
576+
// Check cancellation before each operation
544577
if (monitor.isCanceled()) {
545-
return new ImportClassContentResult(ImportClassContentErrorReason.OPERATION_CANCELLED);
546-
}
547-
if (elapsed >= EARLY_RETURN_MS) {
548-
return new ImportClassContentResult(ImportClassContentErrorReason.TIME_LIMIT_EXCEEDED);
578+
return new ImportClassContentResult(ImportClassContentErrorReason.OPERATION_CANCELLED, fileUri, filePath, projectName);
549579
}
550580

551581
String importName = importDecl.getElementName();
@@ -566,51 +596,52 @@ public static ImportClassContentResult getImportClassContentWithResult(List<Obje
566596
}
567597
}
568598

569-
// Phase 2: If time permits, resolve external dependencies
570-
long elapsedAfterInternal = System.currentTimeMillis() - startTime;
571-
if (elapsedAfterInternal < EARLY_RETURN_MS && !monitor.isCanceled()) {
572-
// Calculate remaining time budget for external classes
573-
long remainingTime = TIME_BUDGET_MS - elapsedAfterInternal;
599+
// Phase 2: Resolve external dependencies if not cancelled
600+
if (!monitor.isCanceled()) {
601+
List<ImportClassInfo> externalClasses = new ArrayList<>();
574602

575-
// Only proceed with external if we have reasonable time left (at least 15ms)
576-
if (remainingTime >= 15) {
577-
List<ImportClassInfo> externalClasses = new ArrayList<>();
578-
579-
for (org.eclipse.jdt.core.IImportDeclaration importDecl : imports) {
580-
// Check time before each external resolution
581-
long currentElapsed = System.currentTimeMillis() - startTime;
582-
if (monitor.isCanceled() || currentElapsed >= EARLY_RETURN_MS) {
583-
break;
584-
}
585-
586-
String importName = importDecl.getElementName();
587-
boolean isStatic = (importDecl.getFlags() & org.eclipse.jdt.core.Flags.AccStatic) != 0;
603+
for (org.eclipse.jdt.core.IImportDeclaration importDecl : imports) {
604+
// Check cancellation before each external resolution
605+
if (monitor.isCanceled()) {
606+
break;
607+
}
588608

589-
// Skip package imports (*.* ) - too broad for external dependencies
590-
if (importName.endsWith(".*")) {
591-
continue;
592-
}
609+
String importName = importDecl.getElementName();
610+
boolean isStatic = (importDecl.getFlags() & org.eclipse.jdt.core.Flags.AccStatic) != 0;
593611

594-
// Resolve external (binary) types with simplified content
595-
if (!isStatic) {
596-
ContextResolver.resolveBinaryType(javaProject, importName, externalClasses,
597-
processedTypes, Integer.MAX_VALUE, monitor);
598-
}
612+
// Skip package imports (*.* ) - too broad for external dependencies
613+
if (importName.endsWith(".*")) {
614+
continue;
599615
}
600616

601-
// Append external classes after project sources
602-
classInfoList.addAll(externalClasses);
617+
// Resolve external (binary) types with simplified content
618+
if (!isStatic) {
619+
ContextResolver.resolveBinaryType(javaProject, importName, externalClasses,
620+
processedTypes, Integer.MAX_VALUE, monitor);
621+
}
603622
}
623+
624+
// Append external classes after project sources
625+
classInfoList.addAll(externalClasses);
604626
}
605627
// Success case - return the resolved class information
606628
if (classInfoList.isEmpty()) {
607-
return new ImportClassContentResult(ImportClassContentErrorReason.NO_RESULTS);
629+
return new ImportClassContentResult(ImportClassContentErrorReason.NO_RESULTS, fileUri, filePath, projectName);
608630
}
609631
return new ImportClassContentResult(classInfoList);
610632

611633
} catch (Exception e) {
612634
JdtlsExtActivator.logException("Error in getImportClassContent", e);
613-
return new ImportClassContentResult(ImportClassContentErrorReason.PROCESSING_EXCEPTION);
635+
// Try to get context from arguments if available
636+
String errorUri = null;
637+
try {
638+
if (arguments != null && !arguments.isEmpty()) {
639+
errorUri = (String) arguments.get(0);
640+
}
641+
} catch (Exception ignored) {
642+
// Ignore any further exceptions when trying to get context
643+
}
644+
return new ImportClassContentResult(ImportClassContentErrorReason.PROCESSING_EXCEPTION, errorUri, null, null);
614645
}
615646
}
616647

@@ -654,35 +685,37 @@ public static List<DependencyInfo> getProjectDependencies(List<Object> arguments
654685
public static ProjectDependenciesResult getProjectDependenciesWithResult(List<Object> arguments,
655686
IProgressMonitor monitor) {
656687
if (arguments == null || arguments.isEmpty()) {
657-
return new ProjectDependenciesResult(ProjectDependenciesErrorReason.NULL_ARGUMENTS);
688+
return new ProjectDependenciesResult(ProjectDependenciesErrorReason.NULL_ARGUMENTS, null, null, null);
658689
}
659690

660691
try {
661692
String projectUri = (String) arguments.get(0);
662693
if (projectUri == null || projectUri.trim().isEmpty()) {
663-
return new ProjectDependenciesResult(ProjectDependenciesErrorReason.INVALID_URI);
694+
return new ProjectDependenciesResult(ProjectDependenciesErrorReason.INVALID_URI, projectUri, null, null);
664695
}
665696

666697
// Validate URI format
698+
String parsedPath = null;
667699
try {
668700
java.net.URI uri = new java.net.URI(projectUri);
669-
if (uri.getPath() == null) {
670-
return new ProjectDependenciesResult(ProjectDependenciesErrorReason.URI_PARSE_FAILED);
701+
parsedPath = uri.getPath();
702+
if (parsedPath == null) {
703+
return new ProjectDependenciesResult(ProjectDependenciesErrorReason.URI_PARSE_FAILED, projectUri, null, null);
671704
}
672705
} catch (java.net.URISyntaxException e) {
673-
return new ProjectDependenciesResult(ProjectDependenciesErrorReason.MALFORMED_URI);
706+
return new ProjectDependenciesResult(ProjectDependenciesErrorReason.MALFORMED_URI, projectUri, null, null);
674707
}
675708

676709
// Check if monitor is cancelled before processing
677710
if (monitor.isCanceled()) {
678-
return new ProjectDependenciesResult(ProjectDependenciesErrorReason.OPERATION_CANCELLED);
711+
return new ProjectDependenciesResult(ProjectDependenciesErrorReason.OPERATION_CANCELLED, projectUri, parsedPath, null);
679712
}
680713
List<ProjectResolver.DependencyInfo> resolverResult = ProjectResolver.resolveProjectDependencies(projectUri,
681714
monitor);
682715
// Check if resolver returned null (should not happen, but defensive
683716
// programming)
684717
if (resolverResult == null) {
685-
return new ProjectDependenciesResult(ProjectDependenciesErrorReason.RESOLVER_NULL_RESULT);
718+
return new ProjectDependenciesResult(ProjectDependenciesErrorReason.RESOLVER_NULL_RESULT, projectUri, parsedPath, null);
686719
}
687720
// Convert ProjectResolver.DependencyInfo to ProjectCommand.DependencyInfo
688721
List<DependencyInfo> result = new ArrayList<>();
@@ -694,13 +727,22 @@ public static ProjectDependenciesResult getProjectDependenciesWithResult(List<Ob
694727

695728
// Check if no dependencies were resolved
696729
if (result.isEmpty()) {
697-
return new ProjectDependenciesResult(ProjectDependenciesErrorReason.NO_DEPENDENCIES);
730+
return new ProjectDependenciesResult(ProjectDependenciesErrorReason.NO_DEPENDENCIES, projectUri, parsedPath, null);
698731
}
699732

700733
return new ProjectDependenciesResult(result);
701734
} catch (Exception e) {
702735
JdtlsExtActivator.logException("Error in getProjectDependenciesWithReason", e);
703-
return new ProjectDependenciesResult(ProjectDependenciesErrorReason.PROCESSING_EXCEPTION);
736+
// Try to get context from arguments if available
737+
String errorUri = null;
738+
try {
739+
if (arguments != null && !arguments.isEmpty()) {
740+
errorUri = (String) arguments.get(0);
741+
}
742+
} catch (Exception ignored) {
743+
// Ignore any further exceptions when trying to get context
744+
}
745+
return new ProjectDependenciesResult(ProjectDependenciesErrorReason.PROCESSING_EXCEPTION, errorUri, null, null);
704746
}
705747
}
706748

0 commit comments

Comments
 (0)