3232import java .util .Set ;
3333import java .util .concurrent .ArrayBlockingQueue ;
3434import java .util .concurrent .BlockingQueue ;
35- import java .util .concurrent .ExecutionException ;
36- import java .util .concurrent .Future ;
35+ import java .util .concurrent .ExecutorService ;
3736
3837import javax .annotation .Nonnull ;
38+ import javax .annotation .Nullable ;
3939
4040import org .jetbrains .annotations .NonNls ;
4141import com .intellij .compiler .CompilerEncodingService ;
4848import com .intellij .compiler .impl .CompilerUtil ;
4949import com .intellij .compiler .impl .ModuleChunk ;
5050import com .intellij .compiler .make .CacheCorruptedException ;
51+ import com .intellij .execution .ExecutionException ;
52+ import com .intellij .execution .configurations .GeneralCommandLine ;
53+ import com .intellij .execution .process .OSProcessHandler ;
54+ import com .intellij .execution .process .ProcessHandler ;
55+ import com .intellij .execution .process .ProcessHandlerFactory ;
5156import com .intellij .openapi .application .Application ;
5257import com .intellij .openapi .application .ApplicationManager ;
5358import com .intellij .openapi .compiler .CompileContext ;
6974import com .intellij .openapi .roots .ProjectRootManager ;
7075import com .intellij .openapi .util .Comparing ;
7176import com .intellij .openapi .util .Computable ;
72- import consulo .util .dataholder .Key ;
7377import com .intellij .openapi .util .Pair ;
7478import com .intellij .openapi .util .Ref ;
7579import com .intellij .openapi .util .io .FileUtil ;
8488import com .intellij .psi .search .GlobalSearchScopes ;
8589import com .intellij .util .Chunk ;
8690import com .intellij .util .cls .ClsFormatException ;
91+ import com .intellij .util .concurrency .AppExecutorUtil ;
92+ import consulo .application .AccessRule ;
8793import consulo .compiler .make .impl .CompositeDependencyCache ;
94+ import consulo .util .dataholder .Key ;
8895
8996/**
9097 * @author Eugene Zhuravlev
@@ -114,12 +121,12 @@ public class BackendCompilerWrapper
114121 private boolean myForceCompileTestsSeparately = false ;
115122
116123 public BackendCompilerWrapper (TranslatingCompiler translatingCompiler ,
117- Chunk <Module > chunk ,
118- @ Nonnull final Project project ,
119- @ Nonnull List <VirtualFile > filesToCompile ,
120- @ Nonnull CompileContextEx compileContext ,
121- @ Nonnull BackendCompiler compiler ,
122- TranslatingCompiler .OutputSink sink )
124+ Chunk <Module > chunk ,
125+ @ Nonnull final Project project ,
126+ @ Nonnull List <VirtualFile > filesToCompile ,
127+ @ Nonnull CompileContextEx compileContext ,
128+ @ Nonnull BackendCompiler compiler ,
129+ TranslatingCompiler .OutputSink sink )
123130 {
124131 myTranslatingCompiler = translatingCompiler ;
125132 myChunk = chunk ;
@@ -329,7 +336,7 @@ public String compute()
329336 });
330337 }
331338
332- @ javax . annotation . Nullable
339+ @ Nullable
333340 private File getOutputDirsToCompileTo (ModuleChunk chunk , final List <OutputDir > dirs ) throws IOException
334341 {
335342 File fileToDelete = null ;
@@ -414,110 +421,80 @@ public void run() {
414421 }); */
415422 }
416423
417- private final Object lock = new Object ();
418-
419- private class SynchedCompilerParsing extends CompilerParsingThread
424+ private class CompilerParsingHandler extends CompilerParsingThread
420425 {
421- private final ClassParsingThread myClassParsingThread ;
422-
423- private SynchedCompilerParsing ( Process process ,
424- final CompileContext context ,
425- OutputParser outputParser ,
426- ClassParsingThread classParsingThread ,
427- boolean readErrorStream ,
428- boolean trimLines )
426+ private final ClassParsingHandler myClassParsingThread ;
427+
428+ private CompilerParsingHandler ( ProcessHandler processHandler ,
429+ CompileContext context ,
430+ OutputParser outputParser ,
431+ ClassParsingHandler classParsingThread ,
432+ boolean readErrorStream ,
433+ boolean trimLines )
429434 {
430- super (process , outputParser , readErrorStream , trimLines , context );
435+ super (processHandler , outputParser , readErrorStream , trimLines , context );
431436 myClassParsingThread = classParsingThread ;
432437 }
433438
434- @ Override
435- public void setProgressText (String text )
436- {
437- synchronized (lock )
438- {
439- super .setProgressText (text );
440- }
441- }
442-
443- @ Override
444- public void message (CompilerMessageCategory category , String message , String url , int lineNum , int columnNum )
445- {
446- synchronized (lock )
447- {
448- super .message (category , message , url , lineNum , columnNum );
449- }
450- }
451-
452- @ Override
453- public void fileProcessed (String path )
454- {
455- synchronized (lock )
456- {
457- sourceFileProcessed ();
458- }
459- }
460-
461439 @ Override
462440 protected void processCompiledClass (final FileObject classFileToProcess ) throws CacheCorruptedException
463441 {
464- synchronized (lock )
465- {
466- myClassParsingThread .addPath (classFileToProcess );
467- }
442+ myClassParsingThread .addPath (classFileToProcess );
468443 }
469444 }
470445
471446 private void doCompile (@ Nonnull final ModuleChunk chunk , @ Nonnull String outputDir , Map <File , FileObject > parsingInfo ) throws IOException
472447 {
473448 myCompileContext .getProgressIndicator ().checkCanceled ();
474449
475- if (ApplicationManager .getApplication ().runReadAction ((Computable <Boolean >) () -> chunk .getFilesToCompile ().isEmpty () ? Boolean .TRUE :
476- Boolean .FALSE ))
450+ if (AccessRule .read (() -> chunk .getFilesToCompile ().isEmpty ()))
477451 {
478452 return ; // should not invoke javac with empty sources list
479453 }
480454
481455 int exitValue = 0 ;
482456 try
483457 {
484- final Process process = myCompiler .launchProcess (chunk , outputDir , myCompileContext );
485- final long compilationStart = System .currentTimeMillis ();
486- final ClassParsingThread classParsingThread = new ClassParsingThread (parsingInfo );
487- final Future <?> classParsingThreadFuture = ApplicationManager .getApplication ().executeOnPooledThread (classParsingThread );
458+ final GeneralCommandLine commandLine = myCompiler .launchProcess (chunk , outputDir , myCompileContext );
459+
460+ OSProcessHandler process ;
461+ try
462+ {
463+ process = ProcessHandlerFactory .getInstance ().createProcessHandler (commandLine );
464+ }
465+ catch (ExecutionException e )
466+ {
467+ throw new IOException (e );
468+ }
469+
470+ ClassParsingHandler classParsingThread = new ClassParsingHandler (parsingInfo );
471+ ExecutorService executorService = AppExecutorUtil .getAppExecutorService ();
472+ executorService .execute (classParsingThread );
488473
489474 OutputParser errorParser = myCompiler .createErrorParser (outputDir , process );
490- CompilerParsingThread errorParsingThread = errorParser == null ? null : new SynchedCompilerParsing (process , myCompileContext ,
491- errorParser , classParsingThread , true , errorParser .isTrimLines ());
492- Future <?> errorParsingThreadFuture = null ;
475+ CompilerParsingThread errorParsingThread = errorParser == null ? null : new CompilerParsingHandler (process , myCompileContext , errorParser , classParsingThread , true , errorParser .isTrimLines ());
476+
493477 if (errorParsingThread != null )
494478 {
495- errorParsingThreadFuture = ApplicationManager . getApplication (). executeOnPooledThread (errorParsingThread );
479+ executorService . execute (errorParsingThread );
496480 }
497481
498482 OutputParser outputParser = myCompiler .createOutputParser (outputDir );
499- CompilerParsingThread outputParsingThread = outputParser == null ? null : new SynchedCompilerParsing (process , myCompileContext ,
500- outputParser , classParsingThread , false , outputParser .isTrimLines ());
501- Future <?> outputParsingThreadFuture = null ;
502- if (outputParsingThread != null )
483+ CompilerParsingThread outputParsingHandler = outputParser == null ? null : new CompilerParsingHandler (process , myCompileContext , outputParser , classParsingThread , false , outputParser .isTrimLines ());
484+ if (outputParsingHandler != null )
503485 {
504- outputParsingThreadFuture = ApplicationManager . getApplication (). executeOnPooledThread ( outputParsingThread );
486+ executorService . submit ( outputParsingHandler );
505487 }
506488
507489 try
508490 {
509- exitValue = process .waitFor ();
510- }
511- catch (InterruptedException e )
512- {
513- process .destroy ();
514- exitValue = process .exitValue ();
491+ process .startNotify ();
492+
493+ process .waitFor ();
515494 }
516- catch (Error e )
495+ catch (Throwable e )
517496 {
518- process .destroy ();
519- exitValue = process .exitValue ();
520- throw e ;
497+ throw new IOException (e );
521498 }
522499 finally
523500 {
@@ -529,18 +506,17 @@ private void doCompile(@Nonnull final ModuleChunk chunk, @Nonnull String outputD
529506 {
530507 errorParsingThread .setProcessTerminated (true );
531508 }
532- if (outputParsingThread != null )
509+
510+ if (outputParsingHandler != null )
533511 {
534- outputParsingThread .setProcessTerminated (true );
512+ outputParsingHandler .setProcessTerminated (true );
535513 }
536- joinThread (errorParsingThreadFuture );
537- joinThread (outputParsingThreadFuture );
538514 classParsingThread .stopParsing ();
539- joinThread (classParsingThreadFuture );
540515
541- registerParsingException (outputParsingThread );
516+ registerParsingException (outputParsingHandler );
542517 registerParsingException (errorParsingThread );
543- assert outputParsingThread == null || !outputParsingThread .processing ;
518+
519+ assert outputParsingHandler == null || !outputParsingHandler .processing ;
544520 assert errorParsingThread == null || !errorParsingThread .processing ;
545521 assert classParsingThread == null || !classParsingThread .processing ;
546522 }
@@ -552,25 +528,6 @@ private void doCompile(@Nonnull final ModuleChunk chunk, @Nonnull String outputD
552528 }
553529 }
554530
555- private static void joinThread (final Future <?> threadFuture )
556- {
557- if (threadFuture != null )
558- {
559- try
560- {
561- threadFuture .get ();
562- }
563- catch (InterruptedException ignored )
564- {
565- LOG .info ("Thread interrupted" , ignored );
566- }
567- catch (ExecutionException ignored )
568- {
569- LOG .info ("Thread interrupted" , ignored );
570- }
571- }
572- }
573-
574531 private void registerParsingException (final CompilerParsingThread outputParsingThread )
575532 {
576533 Throwable error = outputParsingThread == null ? null : outputParsingThread .getError ();
@@ -590,8 +547,7 @@ private void registerParsingException(final CompilerParsingThread outputParsingT
590547
591548 private void runTransformingCompilers (final ModuleChunk chunk )
592549 {
593- final JavaSourceTransformingCompiler [] transformers = CompilerManager .getInstance (myProject ).getCompilers (JavaSourceTransformingCompiler
594- .class );
550+ final JavaSourceTransformingCompiler [] transformers = CompilerManager .getInstance (myProject ).getCompilers (JavaSourceTransformingCompiler .class );
595551 if (transformers .length == 0 )
596552 {
597553 return ;
@@ -763,13 +719,13 @@ private void compileFinished(int exitValue, final ModuleChunk chunk, final Strin
763719 }
764720
765721 private void buildOutputItemsList (final String outputDir ,
766- final Module module ,
767- VirtualFile from ,
768- final FileTypeManager typeManager ,
769- final VirtualFile sourceRoot ,
770- final String packagePrefix ,
771- final List <File > filesToRefresh ,
772- final Map <String , Collection <TranslatingCompiler .OutputItem >> results ) throws CacheCorruptedException
722+ final Module module ,
723+ VirtualFile from ,
724+ final FileTypeManager typeManager ,
725+ final VirtualFile sourceRoot ,
726+ final String packagePrefix ,
727+ final List <File > filesToRefresh ,
728+ final Map <String , Collection <TranslatingCompiler .OutputItem >> results ) throws CacheCorruptedException
773729 {
774730 final Ref <CacheCorruptedException > exRef = new Ref <>(null );
775731 final ModuleFileIndex fileIndex = ModuleRootManager .getInstance (module ).getFileIndex ();
@@ -847,12 +803,12 @@ private void putName(String sourceFileName, int classQName, String relativePathT
847803 }
848804
849805 private void updateOutputItemsList (final String outputDir ,
850- final VirtualFile srcFile ,
851- VirtualFile sourceRoot ,
852- final String packagePrefix ,
853- final List <File > filesToRefresh ,
854- Map <String , Collection <TranslatingCompiler .OutputItem >> results ,
855- final GlobalSearchScope srcRootScope ) throws CacheCorruptedException
806+ final VirtualFile srcFile ,
807+ VirtualFile sourceRoot ,
808+ final String packagePrefix ,
809+ final List <File > filesToRefresh ,
810+ Map <String , Collection <TranslatingCompiler .OutputItem >> results ,
811+ final GlobalSearchScope srcRootScope ) throws CacheCorruptedException
856812 {
857813 CompositeDependencyCache dependencyCache = myCompileContext .getDependencyCache ();
858814 JavaDependencyCache child = dependencyCache .findChild (JavaDependencyCache .class );
@@ -956,7 +912,7 @@ protected static String calcPackagePath(VirtualFile srcFile, VirtualFile sourceR
956912 return prefix + VfsUtilCore .getRelativePath (srcFile , sourceRoot , '/' );
957913 }
958914
959- @ javax . annotation . Nullable
915+ @ Nullable
960916 private Pair <String , String > moveToRealLocation (String tempOutputDir , String pathToClass , VirtualFile sourceFile , final List <File >
961917 filesToRefresh )
962918 {
@@ -1073,14 +1029,14 @@ private void updateStatistics()
10731029 //myCompileContext.getProgressIndicator().setFraction(1.0* myProcessedFilesCount /myTotalFilesToCompile);
10741030 }
10751031
1076- private class ClassParsingThread implements Runnable
1032+ private class ClassParsingHandler implements Runnable
10771033 {
10781034 private final BlockingQueue <FileObject > myPaths = new ArrayBlockingQueue <>(50000 );
10791035 private CacheCorruptedException myError = null ;
10801036 private final JavaDependencyCache myJavaDependencyCache ;
10811037 private final Map <File , FileObject > myParsingInfo ;
10821038
1083- private ClassParsingThread (Map <File , FileObject > parsingInfo )
1039+ private ClassParsingHandler (Map <File , FileObject > parsingInfo )
10841040 {
10851041 myParsingInfo = parsingInfo ;
10861042 myJavaDependencyCache = myCompileContext .getDependencyCache ().findChild (JavaDependencyCache .class );
0 commit comments