1212import com .intellij .openapi .progress .ProgressIndicator ;
1313import com .intellij .openapi .progress .ProgressManager ;
1414import com .intellij .openapi .project .Project ;
15- import com .intellij .openapi .project .ProjectManager ;
1615import com .intellij .openapi .util .TextRange ;
1716import com .intellij .psi .PsiFile ;
1817import org .jetbrains .annotations .NotNull ;
@@ -46,8 +45,7 @@ private AnalysisData() {}
4645
4746 // todo: keep few latest file versions (Guava com.google.common.cache.CacheBuilder ?)
4847 private static final Map <PsiFile , List <SuggestionForFile >> mapFile2Suggestions =
49- // deepcode ignore ApiMigration~java.util.Hashtable: we need read and write full data lock
50- new Hashtable <>(); // new ConcurrentHashMap<>();
48+ new ConcurrentHashMap <>();
5149
5250 private static final Map <PsiFile , String > mapPsiFile2Hash = new ConcurrentHashMap <>();
5351
@@ -111,6 +109,7 @@ static void removeFilesFromCache(@NotNull Collection<PsiFile> files) {
111109 info ("Request to remove from cache " + files .size () + " files: " + files );
112110 // todo: do we really need mutex here?
113111 MUTEX .lock ();
112+ info ("MUTEX LOCK" );
114113 int removeCounter = 0 ;
115114 for (PsiFile file : files ) {
116115 if (file != null && isFileInCache (file )) {
@@ -125,13 +124,12 @@ static void removeFilesFromCache(@NotNull Collection<PsiFile> files) {
125124 + " files. Were not in cache: "
126125 + (files .size () - removeCounter ));
127126 } finally {
127+ info ("MUTEX RELEASED" );
128128 MUTEX .unlock ();
129129 }
130130 }
131131
132132 static void removeProjectFromCache (@ NotNull Project project ) {
133- // lets all running ProgressIndicators release MUTEX first
134- RunUtils .cancelRunningIndicators (project );
135133 if (mapProject2BundleId .remove (project ) != null ) {
136134 info ("Removed from cache: " + project );
137135 }
@@ -174,6 +172,7 @@ public static void updateCachedResultsForFiles(
174172 Collection <PsiFile > filesToProceed = null ;
175173 try {
176174 MUTEX .lock ();
175+ info ("MUTEX LOCK" );
177176 updateInProgress = true ;
178177 filesToProceed =
179178 // DeepCodeUtils.computeNonBlockingReadAction(
@@ -209,7 +208,8 @@ public static void updateCachedResultsForFiles(
209208 updateInProgress = false ;
210209
211210 } finally {
212- if (filesToProceed != null && !filesToProceed .isEmpty ()) info ("MUTEX RELEASED" );
211+ // if (filesToProceed != null && !filesToProceed.isEmpty())
212+ info ("MUTEX RELEASED" );
213213 MUTEX .unlock ();
214214 }
215215 }
@@ -266,6 +266,10 @@ private static Map<PsiFile, List<SuggestionForFile>> retrieveSuggestions(
266266 ProgressManager .checkCanceled ();
267267 progress .setFraction (((double ) fileCounter ++) / totalFiles );
268268 progress .setText (PREPARE_FILES_TEXT + fileCounter + " of " + totalFiles + " files done." );
269+ if (!file .isValid ()) {
270+ DCLogger .warn ("Invalid PsiFile: " + psiFiles );
271+ continue ;
272+ }
269273 final String path = DeepCodeUtils .getDeepCodedFilePath (file );
270274 // info("getHash requested");
271275 final String hash = getHash (file );
@@ -285,24 +289,58 @@ private static Map<PsiFile, List<SuggestionForFile>> retrieveSuggestions(
285289 CreateBundleResponse createBundleResponse = makeNewBundle (project , mapPath2Hash , filesToRemove );
286290 if (isNotSucceed (project , createBundleResponse , "Bad Create/Extend Bundle request: " ))
287291 return EMPTY_MAP ;
292+ final String bundleId = createBundleResponse .getBundleId ();
293+ List <String > missingFiles = createBundleResponse .getMissingFiles ();
288294 info (
289295 "--- Create/Extend Bundle took: "
290296 + (System .currentTimeMillis () - startTime )
291- + " milliseconds" );
292-
293- final String bundleId = createBundleResponse .getBundleId ();
294- info ("bundleId: " + bundleId );
295-
296- final List <String > missingFiles = createBundleResponse .getMissingFiles ();
297- info ("missingFiles: " + missingFiles .size ());
297+ + " milliseconds"
298+ + "\n bundleId: "
299+ + bundleId
300+ + "\n missingFiles: "
301+ + missingFiles .size ());
298302
299303 // ---------------------------------------- Upload Files
300304 startTime = System .currentTimeMillis ();
301305 progress .setText (UPLOADING_FILES_TEXT );
302306 ProgressManager .checkCanceled ();
303307
304- fileCounter = 0 ;
305- totalFiles = missingFiles .size ();
308+ for (int counter = 0 ; counter < 10 ; counter ++) {
309+ uploadFiles (project , psiFiles , missingFiles , bundleId , progress );
310+ missingFiles = checkBundle (project , bundleId , progress );
311+ if (missingFiles .isEmpty ()) {
312+ break ;
313+ } else {
314+ warn (
315+ "Check Bundle found some missingFiles to be NOT uploaded, will try to upload "
316+ + (10 - counter )
317+ + " more times:\n missingFiles = "
318+ + missingFiles );
319+ }
320+ }
321+ // mapPsiFile2Hash.clear();
322+ mapPsiFile2Content .clear ();
323+ info ("--- Upload Files took: " + (System .currentTimeMillis () - startTime ) + " milliseconds" );
324+
325+ // ---------------------------------------- Get Analysis
326+ startTime = System .currentTimeMillis ();
327+ progress .setText (WAITING_FOR_ANALYSIS_TEXT );
328+ ProgressManager .checkCanceled ();
329+ GetAnalysisResponse getAnalysisResponse = doRetrieveSuggestions (project , bundleId , progress );
330+ result = parseGetAnalysisResponse (project , psiFiles , getAnalysisResponse , progress );
331+ info ("--- Get Analysis took: " + (System .currentTimeMillis () - startTime ) + " milliseconds" );
332+ // progress.stop();
333+ return result ;
334+ }
335+
336+ private static void uploadFiles (
337+ @ NotNull Project project ,
338+ @ NotNull Collection <PsiFile > psiFiles ,
339+ @ NotNull List <String > missingFiles ,
340+ @ NotNull String bundleId ,
341+ @ NotNull ProgressIndicator progress ) {
342+ int fileCounter = 0 ;
343+ int totalFiles = missingFiles .size ();
306344 long fileChunkSize = 0 ;
307345 int brokenMissingFilesCount = 0 ;
308346 String brokenMissingFilesMessage = "" ;
@@ -335,7 +373,7 @@ private static Map<PsiFile, List<SuggestionForFile>> retrieveSuggestions(
335373 final long fileSize = psiFile .getVirtualFile ().getLength ();
336374 if (fileChunkSize + fileSize > MAX_BUNDLE_SIZE ) {
337375 info ("Files-chunk size: " + fileChunkSize );
338- uploadFiles (project , filesChunk , bundleId , progress );
376+ doUploadFiles (project , filesChunk , bundleId , progress );
339377 fileChunkSize = 0 ;
340378 filesChunk .clear ();
341379 }
@@ -344,21 +382,18 @@ private static Map<PsiFile, List<SuggestionForFile>> retrieveSuggestions(
344382 }
345383 if (brokenMissingFilesCount > 0 ) warn (brokenMissingFilesCount + brokenMissingFilesMessage );
346384 info ("Last files-chunk size: " + fileChunkSize );
347- uploadFiles (project , filesChunk , bundleId , progress );
348-
349- // mapPsiFile2Hash.clear();
350- mapPsiFile2Content .clear ();
351- info ("--- Upload Files took: " + (System .currentTimeMillis () - startTime ) + " milliseconds" );
385+ doUploadFiles (project , filesChunk , bundleId , progress );
386+ }
352387
353- // ---------------------------------------- Get Analysis
354- startTime = System . currentTimeMillis ();
355- progress . setText ( WAITING_FOR_ANALYSIS_TEXT );
356- ProgressManager . checkCanceled ();
357- GetAnalysisResponse getAnalysisResponse = doRetrieveSuggestions ( project , bundleId , progress );
358- result = parseGetAnalysisResponse ( project , psiFiles , getAnalysisResponse , progress );
359- info ( "--- Get Analysis took: " + ( System . currentTimeMillis () - startTime ) + " milliseconds" );
360- // progress.stop();
361- return result ;
388+ @ NotNull
389+ private static List < String > checkBundle (
390+ @ NotNull Project project , @ NotNull String bundleId , @ NotNull ProgressIndicator progress ) {
391+ CreateBundleResponse checkBundleResponse =
392+ DeepCodeRestApi . checkBundle ( DeepCodeParams . getSessionToken () , bundleId );
393+ if ( isNotSucceed ( project , checkBundleResponse , "Bad CheckBundle request: " )) {
394+ return Collections . emptyList ( );
395+ }
396+ return checkBundleResponse . getMissingFiles () ;
362397 }
363398
364399 private static CreateBundleResponse makeNewBundle (
@@ -479,7 +514,7 @@ private static String doGetFileContent(@NotNull PsiFile psiFile) {
479514 */
480515 }
481516
482- private static void uploadFiles (
517+ private static void doUploadFiles (
483518 @ NotNull Project project ,
484519 @ NotNull Collection <PsiFile > psiFiles ,
485520 @ NotNull String bundleId ,
@@ -609,6 +644,8 @@ private static FileContent createFileContent(PsiFile psiFile) {
609644 public static Set <PsiFile > getAllFilesWithSuggestions (@ NotNull final Project project ) {
610645 return mapFile2Suggestions .entrySet ().stream ()
611646 .filter (e -> e .getKey ().getProject ().equals (project ))
647+ // otherwise ai.deepcode.jbplugin.ui.TodoTreeBuilder.getAllFiles may fail
648+ .filter (e -> e .getKey ().isValid ())
612649 .filter (e -> !e .getValue ().isEmpty ())
613650 .map (Map .Entry ::getKey )
614651 .collect (Collectors .toSet ());
@@ -618,13 +655,16 @@ public static boolean isFileInCache(@NotNull PsiFile psiFile) {
618655 return mapFile2Suggestions .containsKey (psiFile );
619656 }
620657
658+ /** Remove project from all Caches and <b>CANCEL</b> all background tasks for it */
621659 public static void clearCache (@ Nullable final Project project ) {
622660 info ("Cache clearance requested for project: " + project );
623661 mapPsiFile2Hash .clear ();
624662 mapPsiFile2Content .clear ();
625663 final Set <Project > projects =
626664 (project == null ) ? getAllCachedProject () : Collections .singleton (project );
627665 for (Project prj : projects ) {
666+ // lets all running ProgressIndicators release MUTEX first
667+ RunUtils .cancelRunningIndicators (prj );
628668 removeProjectFromCache (prj );
629669 ServiceManager .getService (prj , myTodoView .class ).refresh ();
630670 mapProject2analysisUrl .put (prj , "" );
0 commit comments