private void compileFinished(int exitValue, final ModuleChunk chunk, final String outputDir) { if (exitValue != 0 && !myCompileContext.getProgressIndicator().isCanceled() && myCompileContext.getMessageCount(CompilerMessageCategory.ERROR) == 0) { myCompileContext.addMessage( CompilerMessageCategory.ERROR, CompilerBundle.message("error.compiler.internal.error", exitValue), null, -1, -1); } myCompiler.compileFinished(); final List<File> toRefresh = new ArrayList<File>(); final Map<String, Collection<TranslatingCompiler.OutputItem>> results = new HashMap<String, Collection<TranslatingCompiler.OutputItem>>(); try { final FileTypeManager typeManager = FileTypeManager.getInstance(); final String outputDirPath = outputDir.replace(File.separatorChar, '/'); try { for (final Module module : chunk.getModules()) { for (final VirtualFile root : chunk.getSourceRoots(module)) { final String packagePrefix = myProjectFileIndex.getPackageNameByDirectory(root); if (LOG.isDebugEnabled()) { LOG.debug( "Building output items for " + root.getPresentableUrl() + "; output dir = " + outputDirPath + "; packagePrefix = \"" + packagePrefix + "\""); } buildOutputItemsList( outputDirPath, module, root, typeManager, root, packagePrefix, toRefresh, results); } } } catch (CacheCorruptedException e) { myCompileContext.requestRebuildNextTime( CompilerBundle.message("error.compiler.caches.corrupted")); if (LOG.isDebugEnabled()) { LOG.debug(e); } } } finally { CompilerUtil.refreshIOFiles(toRefresh); for (Iterator<Map.Entry<String, Collection<TranslatingCompiler.OutputItem>>> it = results.entrySet().iterator(); it.hasNext(); ) { Map.Entry<String, Collection<TranslatingCompiler.OutputItem>> entry = it.next(); mySink.add(entry.getKey(), entry.getValue(), VirtualFile.EMPTY_ARRAY); it.remove(); // to free memory } } myFileNameToSourceMap.clear(); // clear the map before the next use }
private void updateStatistics() { final String msg; String moduleName = myModuleName; if (moduleName != null) { msg = CompilerBundle.message( "statistics.files.classes.module", myStatistics.getFilesCount(), myStatistics.getClassesCount(), moduleName); } else { msg = CompilerBundle.message( "statistics.files.classes", myStatistics.getFilesCount(), myStatistics.getClassesCount()); } myCompileContext.getProgressIndicator().setText2(msg); // myCompileContext.getProgressIndicator().setFraction(1.0* myProcessedFilesCount // /myTotalFilesToCompile); }
private void updateOutputItemsList( final String outputDir, final VirtualFile srcFile, VirtualFile sourceRoot, final String packagePrefix, final List<File> filesToRefresh, Map<String, Collection<TranslatingCompiler.OutputItem>> results, final GlobalSearchScope srcRootScope) throws CacheCorruptedException { CompositeDependencyCache dependencyCache = myCompileContext.getDependencyCache(); JavaDependencyCache child = dependencyCache.findChild(JavaDependencyCache.class); final Cache newCache = child.getNewClassesCache(); final Set<CompiledClass> paths = myFileNameToSourceMap.get(srcFile.getName()); if (paths == null || paths.isEmpty()) { return; } final String filePath = "/" + calcPackagePath(srcFile, sourceRoot, packagePrefix); for (final CompiledClass cc : paths) { myCompileContext.getProgressIndicator().checkCanceled(); if (LOG.isDebugEnabled()) { LOG.debug("Checking [pathToClass; relPathToSource] = " + cc); } boolean pathsEquals = FileUtil.pathsEqual(filePath, cc.relativePathToSource); if (!pathsEquals) { final String qName = child.resolve(cc.qName); if (qName != null) { pathsEquals = ApplicationManager.getApplication() .runReadAction( new Computable<Boolean>() { public Boolean compute() { final JavaPsiFacade facade = JavaPsiFacade.getInstance(myProject); PsiClass psiClass = facade.findClass(qName, srcRootScope); if (psiClass == null) { final int dollarIndex = qName.indexOf("$"); if (dollarIndex >= 0) { final String topLevelClassName = qName.substring(0, dollarIndex); psiClass = facade.findClass(topLevelClassName, srcRootScope); } } if (psiClass != null) { final VirtualFile vFile = psiClass.getContainingFile().getVirtualFile(); return vFile != null && vFile.equals(srcFile); } return false; } }); } } if (pathsEquals) { final String outputPath = cc.pathToClass.replace(File.separatorChar, '/'); final Pair<String, String> realLocation = moveToRealLocation(outputDir, outputPath, srcFile, filesToRefresh); if (realLocation != null) { Collection<TranslatingCompiler.OutputItem> outputs = results.get(realLocation.getFirst()); if (outputs == null) { outputs = new ArrayList<TranslatingCompiler.OutputItem>(); results.put(realLocation.getFirst(), outputs); } outputs.add(new OutputItemImpl(realLocation.getSecond(), srcFile)); if (PACKAGE_ANNOTATION_FILE_NAME.equals(srcFile.getName())) { myProcessedPackageInfos.add(srcFile); } if (CompilerManager.MAKE_ENABLED) { newCache.setPath(cc.qName, realLocation.getSecond()); } if (LOG.isDebugEnabled()) { LOG.debug( "Added output item: [outputDir; outputPath; sourceFile] = [" + realLocation.getFirst() + "; " + realLocation.getSecond() + "; " + srcFile.getPresentableUrl() + "]"); } } else { myCompileContext.addMessage( CompilerMessageCategory.ERROR, "Failed to copy from temporary location to output directory: " + outputPath + " (see idea.log for details)", null, -1, -1); if (LOG.isDebugEnabled()) { LOG.debug("Failed to move to real location: " + outputPath + "; from " + outputDir); } } } } }
private void runTransformingCompilers(final ModuleChunk chunk) { final JavaSourceTransformingCompiler[] transformers = CompilerManager.getInstance(myProject).getCompilers(JavaSourceTransformingCompiler.class); if (transformers.length == 0) { return; } if (LOG.isDebugEnabled()) { LOG.debug("Running transforming compilers..."); } final Module[] modules = chunk.getModules(); for (final JavaSourceTransformingCompiler transformer : transformers) { final Map<VirtualFile, VirtualFile> originalToCopyFileMap = new HashMap<VirtualFile, VirtualFile>(); final Application application = ApplicationManager.getApplication(); application.invokeAndWait( new Runnable() { public void run() { for (final Module module : modules) { for (final VirtualFile file : chunk.getFilesToCompile(module)) { final VirtualFile untransformed = chunk.getOriginalFile(file); if (transformer.isTransformable(untransformed)) { application.runWriteAction( new Runnable() { public void run() { try { // if untransformed != file, the file is already a (possibly // transformed) copy of the original 'untransformed' file. // If this is the case, just use already created copy and do not copy // file content once again final VirtualFile fileCopy = untransformed.equals(file) ? createFileCopy(getTempDir(module), file) : file; originalToCopyFileMap.put(file, fileCopy); } catch (IOException e) { // skip it } } }); } } } } }, myCompileContext.getProgressIndicator().getModalityState()); // do actual transform for (final Module module : modules) { final List<VirtualFile> filesToCompile = chunk.getFilesToCompile(module); for (int j = 0; j < filesToCompile.size(); j++) { final VirtualFile file = filesToCompile.get(j); final VirtualFile fileCopy = originalToCopyFileMap.get(file); if (fileCopy != null) { final boolean ok = transformer.transform(myCompileContext, fileCopy, chunk.getOriginalFile(file)); if (ok) { chunk.substituteWithTransformedVersion(module, j, fileCopy); } } } } } }
private void doCompile(@NotNull final ModuleChunk chunk, @NotNull String outputDir) throws IOException { myCompileContext.getProgressIndicator().checkCanceled(); if (ApplicationManager.getApplication() .runReadAction( new Computable<Boolean>() { public Boolean compute() { return chunk.getFilesToCompile().isEmpty() ? Boolean.TRUE : Boolean.FALSE; } }) .booleanValue()) { return; // should not invoke javac with empty sources list } int exitValue = 0; try { final Process process = myCompiler.launchProcess(chunk, outputDir, myCompileContext); final long compilationStart = System.currentTimeMillis(); final ClassParsingThread classParsingThread = new ClassParsingThread(isJdk6(JavaSdkUtil.getSdkForCompilation(chunk)), outputDir); final Future<?> classParsingThreadFuture = ApplicationManager.getApplication().executeOnPooledThread(classParsingThread); OutputParser errorParser = myCompiler.createErrorParser(outputDir, process); CompilerParsingThread errorParsingThread = errorParser == null ? null : new SynchedCompilerParsing( process, myCompileContext, errorParser, classParsingThread, true, errorParser.isTrimLines()); Future<?> errorParsingThreadFuture = null; if (errorParsingThread != null) { errorParsingThreadFuture = ApplicationManager.getApplication().executeOnPooledThread(errorParsingThread); } OutputParser outputParser = myCompiler.createOutputParser(outputDir); CompilerParsingThread outputParsingThread = outputParser == null ? null : new SynchedCompilerParsing( process, myCompileContext, outputParser, classParsingThread, false, outputParser.isTrimLines()); Future<?> outputParsingThreadFuture = null; if (outputParsingThread != null) { outputParsingThreadFuture = ApplicationManager.getApplication().executeOnPooledThread(outputParsingThread); } try { exitValue = process.waitFor(); } catch (InterruptedException e) { process.destroy(); exitValue = process.exitValue(); } catch (Error e) { process.destroy(); exitValue = process.exitValue(); throw e; } finally { if (CompileDriver.ourDebugMode) { System.out.println("Compiler exit code is " + exitValue); } if (errorParsingThread != null) { errorParsingThread.setProcessTerminated(true); } if (outputParsingThread != null) { outputParsingThread.setProcessTerminated(true); } joinThread(errorParsingThreadFuture); joinThread(outputParsingThreadFuture); classParsingThread.stopParsing(); joinThread(classParsingThreadFuture); registerParsingException(outputParsingThread); registerParsingException(errorParsingThread); assert outputParsingThread == null || !outputParsingThread.processing; assert errorParsingThread == null || !errorParsingThread.processing; assert classParsingThread == null || !classParsingThread.processing; } } finally { compileFinished(exitValue, chunk, outputDir); myModuleName = null; } }