33import com .devoxx .genie .model .ScanContentResult ;
44import com .devoxx .genie .service .DevoxxGenieSettingsService ;
55import com .devoxx .genie .ui .settings .DevoxxGenieStateService ;
6+ import com .devoxx .genie .ui .util .NotificationUtil ;
7+ import com .intellij .openapi .application .ApplicationManager ;
68import com .intellij .openapi .project .Project ;
79import com .intellij .openapi .project .ProjectUtil ;
810import com .intellij .openapi .roots .ProjectFileIndex ;
911import com .intellij .openapi .roots .ProjectRootManager ;
12+ import com .intellij .openapi .util .Computable ;
1013import com .intellij .openapi .vfs .VfsUtilCore ;
1114import com .intellij .openapi .vfs .VirtualFile ;
1215import com .intellij .openapi .vfs .VirtualFileVisitor ;
@@ -64,7 +67,7 @@ public void initGitignoreParser(Project project, VirtualFile startDirectory) {
6467 if (startDirectory == null ) {
6568 // Use project base path when no specific directory is provided
6669 projectBasePath = project .getBasePath ();
67- log .info ("Using project base path as startDirectory is null: " + projectBasePath );
70+ log .info ("Using project base path as startDirectory is null: {}" , projectBasePath );
6871 } else {
6972 projectBasePath = determineCorrectProjectBaseDir (project , startDirectory );
7073 }
@@ -74,20 +77,28 @@ public void initGitignoreParser(Project project, VirtualFile startDirectory) {
7477 return ;
7578 }
7679
77- log .info ("Initializing GitIgnore parser with resolved project base directory: " + projectBasePath );
80+ log .info ("Initializing GitIgnore parser with resolved project base directory: {}" , projectBasePath );
7881 this .gitIgnoreFileSet = new GitIgnoreFileSet (new File (projectBasePath ), false );
7982
80- collectGitignoreFiles (startDirectory );
83+ if (startDirectory == null ) {
84+ log .error ("The start directory for the file scanner is null" );
85+ NotificationUtil .sendNotification (project , "The start directory for the file scanner is null" );
86+ } else {
87+ collectGitignoreFiles (startDirectory );
88+ }
8189 }
8290
8391 /**
8492 * Determines the most appropriate base directory, considering project modules (workspaces).
8593 */
8694 private @ Nullable String determineCorrectProjectBaseDir (@ NotNull Project project , @ NotNull VirtualFile startDirectory ) {
8795 // First check if startDirectory belongs to an explicit module's content root
88- ProjectFileIndex fileIndex = ProjectRootManager .getInstance (project ).getFileIndex ();
89-
90- VirtualFile contentRoot = fileIndex .getContentRootForFile (startDirectory );
96+ // Wrap file index access in a read action to prevent threading issues
97+ VirtualFile contentRoot = ApplicationManager .getApplication ().runReadAction ((Computable <VirtualFile >) () -> {
98+ ProjectFileIndex fileIndex = ProjectRootManager .getInstance (project ).getFileIndex ();
99+ return fileIndex .getContentRootForFile (startDirectory );
100+ });
101+
91102 if (contentRoot != null ) {
92103 log .info ("Content root determined from workspace (module): " + contentRoot .getPath ());
93104 return contentRoot .getPath ();
@@ -180,7 +191,8 @@ public boolean visitFile(@NotNull VirtualFile file) {
180191 }
181192 } else {
182193 log .info ("Checking file: " + file .getPath ());
183- boolean isInContent = fileIndex .isInContent (file );
194+ // Wrap file index access in a read action to prevent threading issues
195+ boolean isInContent = ApplicationManager .getApplication ().runReadAction ((Computable <Boolean >) () -> fileIndex .isInContent (file ));
184196 boolean shouldNotExclude = !shouldExcludeFile (file );
185197 boolean shouldInclude = shouldIncludeFile (file );
186198 log .info ("File checks: isInContent=" + isInContent + ", shouldNotExclude=" + shouldNotExclude + ", shouldInclude=" + shouldInclude );
@@ -213,7 +225,9 @@ public boolean visitFile(@NotNull VirtualFile file) {
213225 * @return the reason for skipping the file
214226 */
215227 private String determineSkipReason (VirtualFile file , ProjectFileIndex fileIndex ) {
216- if (!fileIndex .isInContent (file )) {
228+ // Wrap file index access in a read action to prevent threading issues
229+ boolean isInContent = ApplicationManager .getApplication ().runReadAction ((Computable <Boolean >) () -> fileIndex .isInContent (file ));
230+ if (!isInContent ) {
217231 return "not in project content" ;
218232 }
219233
0 commit comments