@@ -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