void (final CompileScope scope, final boolean isRebuild, final boolean forceCompile, final boolean withModalProgress, final CompileStatusNotification callback, final CompilerMessage message) { ThreadingAssertions.assertEventDispatchThread(); ModalityState modalityState = ModalityState.current(); final boolean isUnitTestMode = ApplicationManager.getApplication().isUnitTestMode(); final String name = JavaCompilerBundle.message( isRebuild ? "compiler.content.name.rebuild" : forceCompile ? "compiler.content.name.recompile" : "compiler.content.name.make" ); Tracer.Span span = Tracer.start(name + " preparation"); final CompilerTask compileTask = new CompilerTask( myProject, name, isUnitTestMode, !withModalProgress, true, isCompilationStartedAutomatically(scope), withModalProgress ); StatusBar.Info.set("", myProject, "Compiler"); PsiDocumentManager.getInstance(myProject).commitAllDocuments(); FileDocumentManager.getInstance().saveAllDocuments(); final CompileContextImpl compileContext = new CompileContextImpl(myProject, compileTask, scope, !isRebuild && !forceCompile, isRebuild); span.complete(); final Runnable compileWork = () -> { final ProgressIndicator indicator = compileContext.getProgressIndicator(); if (indicator.isCanceled() || myProject.isDisposed() || !validateCompilerConfiguration(scope, indicator)) { if (callback != null) { callback.finished(true, 0, 0, compileContext); } return; } // ensure the project model seen by build process is up-to-date CompilerDriverHelperKt.saveSettings(myProject, modalityState, isUnitTestMode); Tracer.Span compileWorkSpan = Tracer.start("compileWork"); CompilerCacheManager compilerCacheManager = CompilerCacheManager.getInstance(myProject); final BuildManager buildManager = BuildManager.getInstance(); try { buildManager.postponeBackgroundTasks(); buildManager.cancelAutoMakeTasks(myProject); LOG.info("COMPILATION STARTED (BUILD PROCESS)"); if (message != null) { compileContext.addMessage(message); } if (isRebuild) { CompilerUtil.runInContext(compileContext, JavaCompilerBundle.message("progress.text.clearing.build.system.data"), (ThrowableRunnable<Throwable>)() -> compilerCacheManager .clearCaches(compileContext)); } final boolean beforeTasksOk = executeCompileTasks(compileContext, true); final int errorCount = compileContext.getMessageCount(CompilerMessageCategory.ERROR); if (!beforeTasksOk || errorCount > 0) { COMPILE_SERVER_BUILD_STATUS.set(compileContext, errorCount > 0 ? ExitStatus.ERRORS : ExitStatus.CANCELLED); return; } TaskFuture<?> future = compileInExternalProcess(compileContext, false); if (future != null) { Tracer.Span compileInExternalProcessSpan = Tracer.start("compile in external process"); while (!future.waitFor(200L, TimeUnit.MILLISECONDS)) { if (indicator.isCanceled()) { future.cancel(false); } } compileInExternalProcessSpan.complete(); if (!executeCompileTasks(compileContext, false)) { COMPILE_SERVER_BUILD_STATUS.set(compileContext, ExitStatus.CANCELLED); } if (compileContext.getMessageCount(CompilerMessageCategory.ERROR) > 0) { COMPILE_SERVER_BUILD_STATUS.set(compileContext, ExitStatus.ERRORS); } } } catch (ProcessCanceledException ignored) { compileContext.putUserDataIfAbsent(COMPILE_SERVER_BUILD_STATUS, ExitStatus.CANCELLED); } catch (Throwable e) { LOG.error(e); // todo } finally { compileWorkSpan.complete(); buildManager.allowBackgroundTasks( true // reset state on explicit build to compensate possibly unbalanced postpone/allow calls (e.g. via BatchFileChangeListener.start/stop) ); Tracer.Span flushCompilerCaches = Tracer.start("flush compiler caches"); compilerCacheManager.flushCaches(); flushCompilerCaches.complete(); final ExitStatus status = COMPILE_SERVER_BUILD_STATUS.get(compileContext); final long duration = notifyCompilationCompleted(compileContext, callback, status); CompilerUtil.logDuration( "\tCOMPILATION FINISHED (BUILD PROCESS); Errors: " + compileContext.getMessageCount(CompilerMessageCategory.ERROR) + "; warnings: " + compileContext.getMessageCount(CompilerMessageCategory.WARNING), duration ); if (status == ExitStatus.SUCCESS) { BuildUsageCollector.logBuildCompleted(duration, isRebuild, false); } } }; compileTask.start(compileWork, () -> { if (isRebuild) { final int rv = Messages.showOkCancelDialog( myProject, JavaCompilerBundle.message("you.are.about.to.rebuild.the.whole.project"), JavaCompilerBundle.message("confirm.project.rebuild"), CommonBundle.message("button.build"), JavaCompilerBundle.message("button.rebuild"), Messages.getQuestionIcon() ); if (rv == Messages.OK /*yes, please, do run make*/) { startup(scope, false, false, false, callback, null); return; } } startup(scope, isRebuild, forceCompile, false, callback, message); }); }