private static boolean packageResources( @NotNull AndroidFacet facet, @NotNull CompileContext context) { final Module module = facet.getModule(); try { context.processMessage( new ProgressMessage( AndroidJpsBundle.message( "android.jps.progress.packaging.resources", module.getName()))); final File manifestFile = AndroidJpsUtil.getManifestFileForCompilationPath(facet); if (manifestFile == null) { context.processMessage( new CompilerMessage( BUILDER_NAME, BuildMessage.Kind.ERROR, AndroidJpsBundle.message( "android.jps.errors.manifest.not.found", module.getName()))); return false; } final ArrayList<String> assetsDirPaths = new ArrayList<String>(); collectAssetDirs(facet, assetsDirPaths); final File outputDir = AndroidJpsUtil.getOutputDirectoryForPackagedFiles(context.getProjectPaths(), module); if (outputDir == null) { context.processMessage( new CompilerMessage( BUILDER_NAME, BuildMessage.Kind.ERROR, AndroidJpsBundle.message( "android.jps.errors.output.dir.not.specified", module.getName()))); return false; } final Pair<AndroidSdk, IAndroidTarget> pair = AndroidJpsUtil.getAndroidPlatform(module, context, BUILDER_NAME); if (pair == null) { return false; } final IAndroidTarget target = pair.getSecond(); final String outputFilePath = getPackagedResourcesFile(module, outputDir).getPath(); final String[] resourceDirPaths = AndroidJpsUtil.collectResourceDirsForCompilation(facet, true, context); return doPackageResources( context, manifestFile, target, resourceDirPaths, ArrayUtil.toStringArray(assetsDirPaths), outputFilePath, AndroidJpsUtil.isReleaseBuild(context)); } catch (IOException e) { AndroidJpsUtil.reportExceptionError(context, null, e, BUILDER_NAME); return false; } }
private static boolean runPngCaching( @NotNull CompileContext context, @NotNull Module module, @NotNull AndroidFileSetStorage storage, @Nullable AndroidFileSetState state) throws IOException { final AndroidFileSetState savedState = storage.getState(module.getName()); if (context.isMake() && savedState != null && savedState.equalsTo(state)) { return true; } final AndroidFacet facet = AndroidJpsUtil.getFacet(module); if (facet == null) { return true; } context.processMessage( new CompilerMessage( BUILDER_NAME, BuildMessage.Kind.INFO, AndroidJpsBundle.message("android.jps.progress.res.caching", module.getName()))); final File resourceDir = AndroidJpsUtil.getResourceDirForCompilationPath(facet); if (resourceDir == null) { return true; } final Pair<AndroidSdk, IAndroidTarget> pair = AndroidJpsUtil.getAndroidPlatform(module, context, BUILDER_NAME); if (pair == null) { return false; } final File resCacheDir = AndroidJpsUtil.getResourcesCacheDir(context, module); if (!resCacheDir.exists()) { if (!resCacheDir.mkdirs()) { context.processMessage( new CompilerMessage( BUILDER_NAME, BuildMessage.Kind.ERROR, "Cannot create directory " + resCacheDir.getPath())); return false; } } final IAndroidTarget target = pair.second; final Map<AndroidCompilerMessageKind, List<String>> messages = AndroidApt.crunch( target, Collections.singletonList(resourceDir.getPath()), resCacheDir.getPath()); AndroidJpsUtil.addMessages(context, messages, BUILDER_NAME); final boolean success = messages.get(AndroidCompilerMessageKind.ERROR).isEmpty(); storage.update(module.getName(), success ? state : null); return success; }
private boolean performCompilation( List<String> args, StringWriter out, StringWriter err, Map<String, List<String>> outputs, CompileContext context, ModuleChunk chunk) { try { Class<?> mainClass = Class.forName(GreclipseMain.class.getName(), true, myGreclipseLoader); Constructor<?> constructor = mainClass.getConstructor(PrintWriter.class, PrintWriter.class, Map.class, Map.class); Method compileMethod = mainClass.getMethod("compile", String[].class); HashMap<String, Object> customDefaultOptions = ContainerUtil.newHashMap(); // without this greclipse won't load AST transformations customDefaultOptions.put( "org.eclipse.jdt.core.compiler.groovy.groovyClassLoaderPath", getClasspathString(chunk)); // used by greclipse to cache transform loaders // names should be different for production & tests customDefaultOptions.put( "org.eclipse.jdt.core.compiler.groovy.groovyProjectName", chunk.getPresentableShortName()); Object main = constructor.newInstance( new PrintWriter(out), new PrintWriter(err), customDefaultOptions, outputs); return (Boolean) compileMethod.invoke(main, new Object[] {ArrayUtil.toStringArray(args)}); } catch (Exception e) { context.processMessage(new CompilerMessage(getPresentableName(), e)); return false; } }
@Override public void build( @NotNull ErlangTarget target, @NotNull DirtyFilesHolder<ErlangSourceRootDescriptor, ErlangTarget> holder, @NotNull BuildOutputConsumer outputConsumer, @NotNull CompileContext context) throws ProjectBuildException, IOException { if (!holder.hasDirtyFiles() && !holder.hasRemovedFiles()) return; JpsModule module = target.getModule(); JpsProject project = module.getProject(); ErlangCompilerOptions compilerOptions = JpsErlangCompilerOptionsExtension.getOrCreateExtension(project).getOptions(); if (!compilerOptions.myUseRebarCompiler) return; String rebarExecutablePath = getRebarExecutablePath(project); if (rebarExecutablePath == null) { String errorMessage = "Rebar path is not set"; context.processMessage(new CompilerMessage(NAME, BuildMessage.Kind.ERROR, errorMessage)); throw new ProjectBuildException(errorMessage); } for (String contentRootUrl : module.getContentRootsList().getUrls()) { String contentRootPath = new URL(contentRootUrl).getPath(); File contentRootDir = new File(contentRootPath); File rebarConfigFile = new File(contentRootDir, REBAR_CONFIG_FILE_NAME); if (!rebarConfigFile.exists()) continue; runRebar( contentRootPath, rebarExecutablePath, compilerOptions.myAddDebugInfoEnabled, context); } }
public void save(@NotNull final OutputFileObject fileObject) { if (JavaFileObject.Kind.CLASS != fileObject.getKind()) { // generated sources or resources must be saved synchronously, because some compilers (e.g. // eclipse) // may want to read generated text for further compilation try { final BinaryContent content = fileObject.getContent(); if (content != null) { content.saveToFile(fileObject.getFile()); } } catch (IOException e) { myContext.processMessage( new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, e.getMessage())); } } submitAsyncTask( myContext, new Runnable() { public void run() { try { for (ClassPostProcessor processor : ourClassProcessors) { processor.process(myContext, fileObject); } } finally { myDelegateOutputFileSink.save(fileObject); } } }); }
public void outputLineAvailable(String line) { if (!StringUtil.isEmpty(line)) { if (line.contains("java.lang.OutOfMemoryError")) { myContext.processMessage( new CompilerMessage( BUILDER_NAME, BuildMessage.Kind.ERROR, "OutOfMemoryError: insufficient memory")); myErrorCount++; } else { final BuildMessage.Kind kind = getKindByMessageText(line); if (kind == BuildMessage.Kind.ERROR) { myErrorCount++; } else if (kind == BuildMessage.Kind.WARNING) { myWarningCount++; } myContext.processMessage(new CompilerMessage(BUILDER_NAME, kind, line)); } } }
public ExitCode build( final CompileContext context, final ModuleChunk chunk, DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder, OutputConsumer outputConsumer) throws ProjectBuildException { if (!IS_ENABLED.get(context, Boolean.TRUE)) { return ExitCode.NOTHING_DONE; } try { final Map<File, ModuleBuildTarget> filesToCompile = new THashMap<File, ModuleBuildTarget>(FileUtil.FILE_HASHING_STRATEGY); dirtyFilesHolder.processDirtyFiles( new FileProcessor<JavaSourceRootDescriptor, ModuleBuildTarget>() { public boolean apply( ModuleBuildTarget target, File file, JavaSourceRootDescriptor descriptor) throws IOException { if (JAVA_SOURCES_FILTER.accept(file)) { filesToCompile.put(file, target); } return true; } }); if (context.isMake()) { final ProjectBuilderLogger logger = context.getLoggingManager().getProjectBuilderLogger(); if (logger.isEnabled()) { if (filesToCompile.size() > 0) { logger.logCompiledFiles(filesToCompile.keySet(), BUILDER_NAME, "Compiling files:"); } } } return compile(context, chunk, dirtyFilesHolder, filesToCompile.keySet(), outputConsumer); } catch (ProjectBuildException e) { throw e; } catch (Exception e) { String message = e.getMessage(); if (message == null) { final ByteArrayOutputStream out = new ByteArrayOutputStream(); final PrintStream stream = new PrintStream(out); try { e.printStackTrace(stream); } finally { stream.close(); } message = "Internal error: \n" + out.toString(); } context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, message)); throw new ProjectBuildException(message, e); } }
@Override public final ExitCode build( CompileContext context, ModuleChunk chunk, DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder, OutputConsumer outputConsumer) throws ProjectBuildException, IOException { if (outputConsumer.getCompiledClasses().isEmpty() || !isEnabled(context, chunk)) { return ExitCode.NOTHING_DONE; } final String progress = getProgressMessage(); final boolean shouldShowProgress = !StringUtil.isEmptyOrSpaces(progress); if (shouldShowProgress) { context.processMessage(new ProgressMessage(progress + " [" + chunk.getName() + "]")); } ExitCode exitCode = ExitCode.NOTHING_DONE; try { InstrumentationClassFinder finder = CLASS_FINDER.get(context); // try using shared finder if (finder == null) { final Collection<File> platformCp = ProjectPaths.getPlatformCompilationClasspath(chunk, false); final Collection<File> classpath = new ArrayList<File>(); classpath.addAll(ProjectPaths.getCompilationClasspath(chunk, false)); classpath.addAll(ProjectPaths.getSourceRootsWithDependents(chunk).keySet()); finder = createInstrumentationClassFinder(platformCp, classpath, outputConsumer); CLASS_FINDER.set(context, finder); } exitCode = performBuild(context, chunk, finder, outputConsumer); } finally { if (shouldShowProgress) { context.processMessage(new ProgressMessage("")); // cleanup progress } } return exitCode; }
@Override public void buildStarted(CompileContext context) { if (myForStubs) { File stubRoot = getStubRoot(context); if (stubRoot.exists() && !FileUtil.deleteWithRenaming(stubRoot)) { context.processMessage( new CompilerMessage( myBuilderName, BuildMessage.Kind.ERROR, "External make cannot clean " + stubRoot.getPath())); } } }
public static void updateDependencies( CompileContext context, List<File> toCompile, Map<ModuleBuildTarget, Collection<GroovycOutputParser.OutputItem>> successfullyCompiled, OutputConsumer outputConsumer, Builder builder) throws IOException { JavaBuilderUtil.registerFilesToCompile(context, toCompile); if (!successfullyCompiled.isEmpty()) { final Callbacks.Backend callback = JavaBuilderUtil.getDependenciesRegistrar(context); for (Map.Entry<ModuleBuildTarget, Collection<GroovycOutputParser.OutputItem>> entry : successfullyCompiled.entrySet()) { final ModuleBuildTarget target = entry.getKey(); final Collection<GroovycOutputParser.OutputItem> compiled = entry.getValue(); for (GroovycOutputParser.OutputItem item : compiled) { final String sourcePath = FileUtil.toSystemIndependentName(item.sourcePath); final String outputPath = FileUtil.toSystemIndependentName(item.outputPath); final File outputFile = new File(outputPath); final File srcFile = new File(sourcePath); try { final byte[] bytes = FileUtil.loadFileBytes(outputFile); if (Utils.IS_TEST_MODE || LOG.isDebugEnabled()) { LOG.info("registerCompiledClass " + outputFile + " from " + srcFile); } outputConsumer.registerCompiledClass( target, new CompiledClass( outputFile, srcFile, readClassName(bytes), new BinaryContent(bytes))); callback.associate(outputPath, sourcePath, new FailSafeClassReader(bytes)); } catch (Throwable e) { // need this to make sure that unexpected errors in, for example, ASM will not ruin the // compilation final String message = "Class dependency information may be incomplete! Error parsing generated class " + item.outputPath; LOG.info(message, e); context.processMessage( new CompilerMessage( builder.getPresentableName(), BuildMessage.Kind.WARNING, message + "\n" + CompilerMessage.getTextFromThrowable(e), sourcePath)); } JavaBuilderUtil.registerSuccessfullyCompiled(context, srcFile); } } } }
public void report(Diagnostic<? extends JavaFileObject> diagnostic) { final CompilerMessage.Kind kind; switch (diagnostic.getKind()) { case ERROR: kind = BuildMessage.Kind.ERROR; myErrorCount++; break; case MANDATORY_WARNING: case WARNING: case NOTE: kind = BuildMessage.Kind.WARNING; myWarningCount++; break; default: kind = BuildMessage.Kind.INFO; } File sourceFile = null; try { // for eclipse compiler just an attempt to call getSource() may lead to an NPE, // so calling this method under try/catch to avoid induced compiler errors final JavaFileObject source = diagnostic.getSource(); sourceFile = source != null ? Utils.convertToFile(source.toUri()) : null; } catch (Exception e) { LOG.info(e); } final String srcPath = sourceFile != null ? FileUtil.toSystemIndependentName(sourceFile.getPath()) : null; String message = diagnostic.getMessage(Locale.US); if (Utils.IS_TEST_MODE) { LOG.info(message); } myContext.processMessage( new CompilerMessage( BUILDER_NAME, kind, message, srcPath, diagnostic.getStartPosition(), diagnostic.getEndPosition(), diagnostic.getPosition(), diagnostic.getLineNumber(), diagnostic.getColumnNumber())); }
private boolean updateDependencies( CompileContext context, ModuleChunk chunk, List<File> toCompile, String moduleOutputPath, List<GroovycOSProcessHandler.OutputItem> successfullyCompiled) throws IOException { final Mappings delta = context.createDelta(); final List<File> successfullyCompiledFiles = new ArrayList<File>(); if (!successfullyCompiled.isEmpty()) { final Callbacks.Backend callback = delta.getCallback(); final FileGeneratedEvent generatedEvent = new FileGeneratedEvent(); for (GroovycOSProcessHandler.OutputItem item : successfullyCompiled) { final String sourcePath = FileUtil.toSystemIndependentName(item.sourcePath); final String outputPath = FileUtil.toSystemIndependentName(item.outputPath); final RootDescriptor moduleAndRoot = context.getModuleAndRoot(new File(sourcePath)); if (moduleAndRoot != null) { final String moduleName = moduleAndRoot.module.getName().toLowerCase(Locale.US); context .getDataManager() .getSourceToOutputMap(moduleName, moduleAndRoot.isTestRoot) .appendData(sourcePath, outputPath); } callback.associate( outputPath, Callbacks.getDefaultLookup(sourcePath), new ClassReader(FileUtil.loadFileBytes(new File(outputPath)))); successfullyCompiledFiles.add(new File(sourcePath)); generatedEvent.add( moduleOutputPath, FileUtil.getRelativePath(moduleOutputPath, outputPath, '/')); } context.processMessage(generatedEvent); } return updateMappings(context, delta, chunk, toCompile, successfullyCompiledFiles); }
@Nullable public static Map<ModuleBuildTarget, String> getCanonicalModuleOutputs( CompileContext context, ModuleChunk chunk, Builder builder) { Map<ModuleBuildTarget, String> finalOutputs = new LinkedHashMap<ModuleBuildTarget, String>(); for (ModuleBuildTarget target : chunk.getTargets()) { File moduleOutputDir = target.getOutputDir(); if (moduleOutputDir == null) { context.processMessage( new CompilerMessage( builder.getPresentableName(), BuildMessage.Kind.ERROR, "Output directory not specified for module " + target.getModule().getName())); return null; } //noinspection ResultOfMethodCallIgnored moduleOutputDir.mkdirs(); String moduleOutputPath = FileUtil.toCanonicalPath(moduleOutputDir.getPath()); assert moduleOutputPath != null; finalOutputs.put( target, moduleOutputPath.endsWith("/") ? moduleOutputPath : moduleOutputPath + "/"); } return finalOutputs; }
public ModuleLevelBuilder.ExitCode build( final CompileContext context, final ModuleChunk chunk, DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder, OutputConsumer outputConsumer) throws ProjectBuildException { if (GreclipseBuilder.useGreclipse(context)) return ExitCode.NOTHING_DONE; long start = 0; try { JpsGroovySettings settings = JpsGroovySettings.getSettings(context.getProjectDescriptor().getProject()); Ref<Boolean> hasStubExcludes = Ref.create(false); final List<File> toCompile = collectChangedFiles(context, dirtyFilesHolder, myForStubs, false, hasStubExcludes); if (toCompile.isEmpty()) { return hasFilesToCompileForNextRound(context) ? ExitCode.ADDITIONAL_PASS_REQUIRED : ExitCode.NOTHING_DONE; } if (Utils.IS_TEST_MODE || LOG.isDebugEnabled()) { LOG.info("forStubs=" + myForStubs); } Map<ModuleBuildTarget, String> finalOutputs = getCanonicalModuleOutputs(context, chunk, this); if (finalOutputs == null) { return ExitCode.ABORT; } start = System.currentTimeMillis(); Map<ModuleBuildTarget, String> generationOutputs = myForStubs ? getStubGenerationOutputs(chunk, context) : finalOutputs; String compilerOutput = generationOutputs.get(chunk.representativeTarget()); GroovycOutputParser parser = runGroovycOrContinuation( context, chunk, settings, finalOutputs, compilerOutput, toCompile, hasStubExcludes.get()); Map<ModuleBuildTarget, Collection<GroovycOutputParser.OutputItem>> compiled = processCompiledFiles( context, chunk, generationOutputs, compilerOutput, parser.getSuccessfullyCompiled()); if (checkChunkRebuildNeeded(context, parser)) { clearContinuation(context, chunk); return ExitCode.CHUNK_REBUILD_REQUIRED; } if (myForStubs) { addStubRootsToJavacSourcePath(context, generationOutputs); rememberStubSources(context, compiled); } for (CompilerMessage message : parser.getCompilerMessages()) { context.processMessage(message); } if (!myForStubs) { updateDependencies(context, toCompile, compiled, outputConsumer, this); } return hasFilesToCompileForNextRound(context) ? ExitCode.ADDITIONAL_PASS_REQUIRED : ExitCode.OK; } catch (Exception e) { throw new ProjectBuildException(e); } finally { if (start > 0 && LOG.isDebugEnabled()) { LOG.debug( myBuilderName + " took " + (System.currentTimeMillis() - start) + " on " + chunk.getName()); } if (!myForStubs) { FILES_MARKED_DIRTY_FOR_NEXT_ROUND.set(context, null); } } }
private ExitCode compile( final CompileContext context, ModuleChunk chunk, DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder, Collection<File> files, OutputConsumer outputConsumer) throws Exception { ExitCode exitCode = ExitCode.NOTHING_DONE; final boolean hasSourcesToCompile = !files.isEmpty(); if (!hasSourcesToCompile && !dirtyFilesHolder.hasRemovedFiles()) { return exitCode; } final ProjectDescriptor pd = context.getProjectDescriptor(); JavaBuilderUtil.ensureModuleHasJdk( chunk.representativeTarget().getModule(), context, BUILDER_NAME); final Collection<File> classpath = ProjectPaths.getCompilationClasspath(chunk, false /*context.isProjectRebuild()*/); final Collection<File> platformCp = ProjectPaths.getPlatformCompilationClasspath(chunk, false /*context.isProjectRebuild()*/); // begin compilation round final DiagnosticSink diagnosticSink = new DiagnosticSink(context); final Mappings delta = pd.dataManager.getMappings().createDelta(); final Callbacks.Backend mappingsCallback = delta.getCallback(); final OutputFilesSink outputSink = new OutputFilesSink(context, outputConsumer, mappingsCallback, chunk.getName()); try { if (hasSourcesToCompile) { final AtomicReference<String> ref = COMPILER_VERSION_INFO.get(context); final String versionInfo = ref.getAndSet(null); // display compiler version info only once per compile session if (versionInfo != null) { LOG.info(versionInfo); context.processMessage(new CompilerMessage("", BuildMessage.Kind.INFO, versionInfo)); } exitCode = ExitCode.OK; final Set<File> srcPath = new HashSet<File>(); final BuildRootIndex index = pd.getBuildRootIndex(); for (ModuleBuildTarget target : chunk.getTargets()) { for (JavaSourceRootDescriptor rd : index.getTempTargetRoots(target, context)) { srcPath.add(rd.root); } } final String chunkName = chunk.getName(); context.processMessage(new ProgressMessage("Parsing java... [" + chunkName + "]")); final int filesCount = files.size(); boolean compiledOk = true; if (filesCount > 0) { LOG.info( "Compiling " + filesCount + " java files; module: " + chunkName + (chunk.containsTests() ? " (tests)" : "")); if (LOG.isDebugEnabled()) { for (File file : files) { LOG.debug("Compiling " + file.getPath()); } LOG.debug(" classpath for " + chunkName + ":"); for (File file : classpath) { LOG.debug(" " + file.getAbsolutePath()); } LOG.debug(" platform classpath for " + chunkName + ":"); for (File file : platformCp) { LOG.debug(" " + file.getAbsolutePath()); } } compiledOk = compileJava( context, chunk, files, classpath, platformCp, srcPath, diagnosticSink, outputSink); } context.checkCanceled(); if (!compiledOk && diagnosticSink.getErrorCount() == 0) { diagnosticSink.report( new PlainMessageDiagnostic( Diagnostic.Kind.ERROR, "Compilation failed: internal java compiler error")); } if (!Utils.PROCEED_ON_ERROR_KEY.get(context, Boolean.FALSE) && diagnosticSink.getErrorCount() > 0) { if (!compiledOk) { diagnosticSink.report( new PlainMessageDiagnostic( Diagnostic.Kind.OTHER, "Errors occurred while compiling module '" + chunkName + "'")); } throw new ProjectBuildException( "Compilation failed: errors: " + diagnosticSink.getErrorCount() + "; warnings: " + diagnosticSink.getWarningCount()); } } } finally { if (JavaBuilderUtil.updateMappings( context, delta, dirtyFilesHolder, chunk, files, outputSink.getSuccessfullyCompiled())) { exitCode = ExitCode.ADDITIONAL_PASS_REQUIRED; } } return exitCode; }
private void compileFiles( final CompileContext context, File frameworkHome, List<String> includes, ModuleBuildTarget buildTarget, List<File> sourceFiles, IceComponent target, File outputDir) throws StopBuildException { final JpsModule module = buildTarget.getModule(); final String translatorName = target.getTranslatorName(); if (outputDir == null) { context.processMessage( new CompilerMessage( getPresentableName(), BuildMessage.Kind.WARNING, "Output folder is not specified for " + translatorName + " in module " + module.getName() + ". Check facet configuration.")); return; } List<String> command = new ArrayList<String>(); command.add(target.getTranslatorPath(frameworkHome).getAbsolutePath()); command.add("--list-generated"); command.add("--output-dir"); final String outputDirPath = outputDir.getAbsolutePath(); command.add(outputDirPath); for (String include : includes) { command.add("-I" + include); } for (JpsModuleSourceRoot contentRoot : module.getSourceRoots()) { command.add("-I" + contentRoot.getFile().getAbsolutePath()); } for (File source : sourceFiles) { command.add(source.getAbsolutePath()); } try { Process process = new ProcessBuilder().command(command).start(); BaseOSProcessHandler handler = new BaseOSProcessHandler( process, StringUtil.join(command, " "), CharsetToolkit.UTF8_CHARSET); final AtomicBoolean hasErrors = new AtomicBoolean(); handler.addProcessListener( new ProcessAdapter() { final StringBuilder errorOutput = new StringBuilder(); final StringBuilder stdOutput = new StringBuilder(); @Override public void onTextAvailable(ProcessEvent event, Key outputType) { if (outputType == ProcessOutputTypes.STDERR) { errorOutput.append(event.getText()); } else if (outputType == ProcessOutputTypes.STDOUT) { stdOutput.append(event.getText()); } } @Override public void processTerminated(ProcessEvent event) { Document res; final String stdout = stdOutput.toString(); try { res = JDOMUtil.loadDocument(stdout); } catch (Exception e) { context.processMessage( new CompilerMessage( BUILDER_NAME, BuildMessage.Kind.ERROR, "Can't process compiler output: " + stdout)); hasErrors.set(true); return; } int exitCode = event.getExitCode(); if (exitCode != 0) { for (Element source : res.getRootElement().getChildren("source")) { final Element output = source.getChild("output"); if (output != null) { String message = output.getTextTrim(); for (String line : message.split("\n")) { int separatorIndex = line.indexOf(": "); final String path; final long lineNumber; if (separatorIndex <= 0) { path = null; lineNumber = -1L; } else { int lineSep = line.lastIndexOf(':', separatorIndex - 1); if (lineSep == -1) { path = null; lineNumber = -1L; } else { path = line.substring(0, lineSep); long l; try { l = Long.parseLong(line.substring(lineSep + 1, separatorIndex)); } catch (NumberFormatException e) { l = -1L; } lineNumber = l; } } context.processMessage( new CompilerMessage( BUILDER_NAME, BuildMessage.Kind.ERROR, line, path, -1L, -1L, -1L, lineNumber, -1L)); } } } final String stdErr = errorOutput.toString(); if (stdErr.length() > 0) { context.processMessage( new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, stdErr)); } context.processMessage( new CompilerMessage( BUILDER_NAME, BuildMessage.Kind.ERROR, "translator '" + translatorName + "' for '" + module.getName() + "' finished with exit code " + exitCode)); hasErrors.set(true); } else { final FileGeneratedEvent msg = new FileGeneratedEvent(); for (Element source : res.getRootElement().getChildren("source")) { for (Element file : source.getChildren("file")) { final String fileName = file.getAttributeValue("name"); if (fileName.startsWith(outputDirPath)) { msg.add(outputDirPath, fileName.substring(outputDirPath.length() + 1)); } } } context.processMessage(msg); } } }); handler.startNotify(); handler.waitFor(); if (hasErrors.get()) { throw new StopBuildException(); } } catch (IOException e) { context.processMessage( new CompilerMessage( getPresentableName(), BuildMessage.Kind.ERROR, "Failed to translate files with " + translatorName + ". Error: " + e.getMessage())); } }
public Builder.ExitCode build(final CompileContext context, ModuleChunk chunk) throws ProjectBuildException { ExitCode exitCode = ExitCode.OK; final Map<File, Module> toCompile = new HashMap<File, Module>(); try { context.processFilesToRecompile( chunk, new FileProcessor() { @Override public boolean apply(Module module, File file, String sourceRoot) throws Exception { final String path = file.getPath(); if (isGroovyFile(path)) { // todo file type check toCompile.put(file, module); } return true; } }); if (toCompile.isEmpty()) { return exitCode; } final Set<String> cp = new LinkedHashSet<String>(); // groovy_rt.jar // IMPORTANT! must be the first in classpath cp.add(ClasspathBootstrap.getResourcePath(GroovyCompilerWrapper.class).getPath()); for (File file : context .getProjectPaths() .getClasspathFiles(chunk, ClasspathKind.compile(context.isCompilingTests()), false)) { cp.add(FileUtil.toCanonicalPath(file.getPath())); } for (File file : context .getProjectPaths() .getClasspathFiles(chunk, ClasspathKind.runtime(context.isCompilingTests()), false)) { cp.add(FileUtil.toCanonicalPath(file.getPath())); } final File tempFile = FileUtil.createTempFile("ideaGroovyToCompile", ".txt", true); final Module representativeModule = chunk.getModules().iterator().next(); File moduleOutputDir = context .getProjectPaths() .getModuleOutputDir(representativeModule, context.isCompilingTests()); final File dir = myForStubs ? FileUtil.createTempDirectory(/*new File("/tmp/stubs/"), */ "groovyStubs", null) : moduleOutputDir; assert dir != null; final Set<String> toCompilePaths = new LinkedHashSet<String>(); for (File file : toCompile.keySet()) { toCompilePaths.add(FileUtil.toSystemIndependentName(file.getPath())); } String moduleOutputPath = FileUtil.toCanonicalPath(moduleOutputDir.getPath()); if (!moduleOutputPath.endsWith("/")) { moduleOutputPath += "/"; } Map<String, String> class2Src = buildClassToSourceMap(chunk, context, toCompilePaths, moduleOutputPath); String encoding = "UTF-8"; // todo encoding List<String> patchers = Collections.emptyList(); // todo patchers GroovycOSProcessHandler.fillFileWithGroovycParameters( tempFile, FileUtil.toCanonicalPath(dir.getPath()), toCompilePaths, FileUtil.toSystemDependentName(moduleOutputPath), class2Src, encoding, patchers); if (myForStubs) { JavaBuilder.addTempSourcePathRoot(context, dir); } // todo CompilerUtil.addLocaleOptions() // todo different outputs in a chunk // todo module jdk path final List<String> cmd = ExternalProcessUtil.buildJavaCommandLine( SystemProperties.getJavaHome() + "/bin/java", "org.jetbrains.groovy.compiler.rt.GroovycRunner", Collections.<String>emptyList(), new ArrayList<String>(cp), Arrays.asList( "-Xmx384m" /*, "-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5858"*/), Arrays.<String>asList(myForStubs ? "stubs" : "groovyc", tempFile.getPath())); deleteCorrespondingOutputFiles(context, toCompile); List<GroovycOSProcessHandler.OutputItem> successfullyCompiled = Collections.emptyList(); try { final Process process = Runtime.getRuntime().exec(cmd.toArray(new String[cmd.size()])); GroovycOSProcessHandler handler = new GroovycOSProcessHandler(process, null) { @Override protected void updateStatus(@Nullable String status) { context.processMessage( new ProgressMessage(status == null ? GROOVY_COMPILER_IN_OPERATION : status)); } }; handler.startNotify(); handler.waitFor(); successfullyCompiled = handler.getSuccessfullyCompiled(); final List<CompilerMessage> messages = handler.getCompilerMessages(); for (CompilerMessage message : messages) { context.processMessage(message); } boolean hasMessages = !messages.isEmpty(); final StringBuffer unparsedBuffer = handler.getStdErr(); if (unparsedBuffer.length() != 0) { context.processMessage( new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.INFO, unparsedBuffer.toString())); } final int exitValue = handler.getProcess().exitValue(); if (!hasMessages && exitValue != 0) { context.processMessage( new CompilerMessage( BUILDER_NAME, BuildMessage.Kind.ERROR, "Internal groovyc error: code " + exitValue)); } } finally { if (!myForStubs) { final Mappings delta = context.createDelta(); final List<File> successfullyCompiledFiles = new ArrayList<File>(); if (!successfullyCompiled.isEmpty()) { final Callbacks.Backend callback = delta.getCallback(); for (GroovycOSProcessHandler.OutputItem item : successfullyCompiled) { final String sourcePath = FileUtil.toSystemIndependentName(item.sourcePath); final String outputPath = FileUtil.toSystemIndependentName(item.outputPath); final RootDescriptor moduleAndRoot = context.getModuleAndRoot(new File(sourcePath)); if (moduleAndRoot != null) { final String moduleName = moduleAndRoot.module.getName().toLowerCase(Locale.US); context .getDataManager() .getSourceToOutputMap(moduleName, moduleAndRoot.isTestRoot) .appendData(sourcePath, outputPath); } callback.associate( outputPath, Callbacks.getDefaultLookup(sourcePath), new ClassReader(FileUtil.loadFileBytes(new File(outputPath)))); successfullyCompiledFiles.add(new File(sourcePath)); } } final boolean needSecondPass = updateMappings(context, delta, chunk, toCompile.keySet(), successfullyCompiledFiles); if (needSecondPass) { exitCode = ExitCode.ADDITIONAL_PASS_REQUIRED; } } } return exitCode; } catch (Exception e) { throw new ProjectBuildException(e); } }
@Override public void build( @NotNull ErlangTarget target, @NotNull DirtyFilesHolder<ErlangSourceRootDescriptor, ErlangTarget> holder, @NotNull BuildOutputConsumer outputConsumer, @NotNull final CompileContext context) throws ProjectBuildException, IOException { LOG.debug(target.getPresentableName()); final Ref<Boolean> hasDirtyFiles = Ref.create(false); holder.processDirtyFiles( new FileProcessor<ErlangSourceRootDescriptor, ErlangTarget>() { @Override public boolean apply(ErlangTarget target, File file, ErlangSourceRootDescriptor root) throws IOException { hasDirtyFiles.set(true); return true; } }); if (!hasDirtyFiles.get() && !holder.hasRemovedFiles()) { return; } JpsModule module = target.getModule(); JpsJavaExtensionService instance = JpsJavaExtensionService.getInstance(); File outputDirectory = instance.getOutputDirectory(module, target.isTests()); if (outputDirectory == null) { context.processMessage( new CompilerMessage( NAME, BuildMessage.Kind.ERROR, "No output dir for module " + module.getName())); throw new ProjectBuildException(); } if (!outputDirectory.exists()) FileUtil.createDirectory(outputDirectory); JpsSdk<JpsDummyElement> sdk = module.getSdk(JpsErlangSdkType.INSTANCE); if (sdk == null) { context.processMessage( new CompilerMessage( NAME, BuildMessage.Kind.ERROR, "No SDK for module " + module.getName())); throw new ProjectBuildException(); } File executable = JpsErlangSdkType.getByteCodeCompilerExecutable(sdk.getHomePath()); List<String> commandList = new ArrayList<String>(); commandList.add(executable.getAbsolutePath()); CommonProcessors.CollectProcessor<File> processor = new CommonProcessors.CollectProcessor<File>() { @Override protected boolean accept(File file) { return !file.isDirectory() && FileUtilRt.extensionEquals(file.getName(), "erl"); } }; for (JpsModuleSourceRoot root : module.getSourceRoots()) { commandList.add("-I"); commandList.add(root.getFile().getAbsolutePath()); FileUtil.processFilesRecursively(root.getFile(), processor); } for (File f : processor.getResults()) { commandList.add(f.getAbsolutePath()); } LOG.debug(StringUtil.join(commandList, " ")); Process process = new ProcessBuilder(commandList).directory(outputDirectory).start(); BaseOSProcessHandler handler = new BaseOSProcessHandler(process, null, Charset.defaultCharset()); ProcessAdapter adapter = new ProcessAdapter() { @Override public void onTextAvailable(ProcessEvent event, Key outputType) { ErlangCompilerError error = ErlangCompilerError.create("", event.getText()); if (error != null) { boolean isError = error.getCategory() == CompilerMessageCategory.ERROR; BuildMessage.Kind kind = isError ? BuildMessage.Kind.ERROR : BuildMessage.Kind.WARNING; CompilerMessage msg = new CompilerMessage( NAME, kind, error.getErrorMessage(), VirtualFileManager.extractPath(error.getUrl()), -1, -1, -1, error.getLine(), -1); context.processMessage(msg); } } }; handler.addProcessListener(adapter); handler.startNotify(); handler.waitFor(); }
public static void addCompilationOptions( List<String> options, CompileContext context, ModuleChunk chunk, @Nullable ProcessorConfigProfile profile) { if (!isEncodingSet(options)) { final CompilerEncodingConfiguration config = context.getProjectDescriptor().getEncodingConfiguration(); final String encoding = config.getPreferredModuleChunkEncoding(chunk); if (config.getAllModuleChunkEncodings(chunk).size() > 1) { final StringBuilder msgBuilder = new StringBuilder(); msgBuilder.append("Multiple encodings set for module chunk ").append(chunk.getName()); if (encoding != null) { msgBuilder.append("\n\"").append(encoding).append("\" will be used by compiler"); } context.processMessage( new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.INFO, msgBuilder.toString())); } if (!StringUtil.isEmpty(encoding)) { options.add("-encoding"); options.add(encoding); } } final String langLevel = getLanguageLevel(chunk.getModules().iterator().next()); if (!StringUtil.isEmpty(langLevel)) { options.add("-source"); options.add(langLevel); } JpsJavaCompilerConfiguration compilerConfiguration = JpsJavaExtensionService.getInstance() .getOrCreateCompilerConfiguration(context.getProjectDescriptor().getProject()); String bytecodeTarget = null; int chunkSdkVersion = -1; for (JpsModule module : chunk.getModules()) { final JpsSdk<JpsDummyElement> sdk = module.getSdk(JpsJavaSdkType.INSTANCE); if (sdk != null) { final int moduleSdkVersion = convertToNumber(sdk.getVersionString()); if (moduleSdkVersion != 0 /*could determine the version*/ && (chunkSdkVersion < 0 || chunkSdkVersion > moduleSdkVersion)) { chunkSdkVersion = moduleSdkVersion; } } final String moduleTarget = compilerConfiguration.getByteCodeTargetLevel(module.getName()); if (moduleTarget == null) { continue; } if (bytecodeTarget == null) { bytecodeTarget = moduleTarget; } else { if (moduleTarget.compareTo(bytecodeTarget) < 0) { bytecodeTarget = moduleTarget; // use the lower possible target among modules that form the chunk } } } if (bytecodeTarget != null) { options.add("-target"); options.add(bytecodeTarget); } else { if (chunkSdkVersion > 0 && getCompilerSdkVersion(context) > chunkSdkVersion) { // force lower bytecode target level to match the version of sdk assigned to this chunk options.add("-target"); options.add("1." + chunkSdkVersion); } } if (profile != null && profile.isEnabled()) { // configuring annotation processing if (!profile.isObtainProcessorsFromClasspath()) { final String processorsPath = profile.getProcessorPath(); options.add("-processorpath"); options.add( processorsPath == null ? "" : FileUtil.toSystemDependentName(processorsPath.trim())); } final Set<String> processors = profile.getProcessors(); if (!processors.isEmpty()) { options.add("-processor"); options.add(StringUtil.join(processors, ",")); } for (Map.Entry<String, String> optionEntry : profile.getProcessorOptions().entrySet()) { options.add("-A" + optionEntry.getKey() + "=" + optionEntry.getValue()); } final File srcOutput = ProjectPaths.getAnnotationProcessorGeneratedSourcesOutputDir( chunk.getModules().iterator().next(), chunk.containsTests(), profile); if (srcOutput != null) { srcOutput.mkdirs(); options.add("-s"); options.add(srcOutput.getPath()); } } else { options.add("-proc:none"); } }
public ModuleLevelBuilder.ExitCode build(final CompileContext context, ModuleChunk chunk) throws ProjectBuildException { try { final List<File> toCompile = collectChangedFiles(context, chunk); if (toCompile.isEmpty()) { return ExitCode.NOTHING_DONE; } String moduleOutput = getModuleOutput(context, chunk); String compilerOutput = getCompilerOutput(moduleOutput); final Set<String> toCompilePaths = new LinkedHashSet<String>(); for (File file : toCompile) { toCompilePaths.add(FileUtil.toSystemIndependentName(file.getPath())); } Map<String, String> class2Src = buildClassToSourceMap(chunk, context, toCompilePaths, moduleOutput); String ideCharset = chunk.getProject().getProjectCharset(); String encoding = !Comparing.equal(CharsetToolkit.getDefaultSystemCharset().name(), ideCharset) ? ideCharset : null; List<String> patchers = Collections.emptyList(); // todo patchers final File tempFile = GroovycOSProcessHandler.fillFileWithGroovycParameters( compilerOutput, toCompilePaths, FileUtil.toSystemDependentName(moduleOutput), class2Src, encoding, patchers); // todo different outputs in a chunk // todo xmx final List<String> cmd = ExternalProcessUtil.buildJavaCommandLine( getJavaExecutable(chunk), "org.jetbrains.groovy.compiler.rt.GroovycRunner", Collections.<String>emptyList(), new ArrayList<String>(generateClasspath(context, chunk)), Arrays.asList( "-Xmx384m", "-Dfile.encoding=" + CharsetToolkit.getDefaultSystemCharset().name() /*, "-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5239"*/), Arrays.<String>asList(myForStubs ? "stubs" : "groovyc", tempFile.getPath())); final Process process = Runtime.getRuntime().exec(ArrayUtil.toStringArray(cmd)); GroovycOSProcessHandler handler = GroovycOSProcessHandler.runGroovyc( process, new Consumer<String>() { public void consume(String s) { context.processMessage(new ProgressMessage(s)); } }); if (handler.shouldRetry()) { if (CHUNK_REBUILD_ORDERED.get(context) != null) { CHUNK_REBUILD_ORDERED.set(context, null); } else { CHUNK_REBUILD_ORDERED.set(context, Boolean.TRUE); return ExitCode.CHUNK_REBUILD_REQUIRED; } } if (myForStubs) { JavaBuilder.addTempSourcePathRoot(context, new File(compilerOutput)); } for (CompilerMessage message : handler.getCompilerMessages()) { context.processMessage(message); } if (!myForStubs && updateDependencies( context, chunk, toCompile, moduleOutput, handler.getSuccessfullyCompiled())) { return ExitCode.ADDITIONAL_PASS_REQUIRED; } return ExitCode.OK; } catch (Exception e) { throw new ProjectBuildException(e); } }
private static boolean doPackagingForModule( @NotNull CompileContext context, @NotNull Module module, @NotNull AndroidFileSetStorage apkFileSetStorage, @NotNull AndroidApkBuilderConfigStateStorage apkBuilderConfigStateStorage, boolean release) throws IOException { final AndroidFacet facet = AndroidJpsUtil.getFacet(module); if (facet == null || facet.isLibrary()) { return true; } final String[] sourceRoots = AndroidJpsUtil.toPaths(AndroidJpsUtil.getSourceRootsForModuleAndDependencies(module)); final ProjectPaths paths = context.getProjectPaths(); final File outputDir = AndroidJpsUtil.getOutputDirectoryForPackagedFiles(paths, module); if (outputDir == null) { context.processMessage( new CompilerMessage( BUILDER_NAME, BuildMessage.Kind.ERROR, AndroidJpsBundle.message( "android.jps.errors.output.dir.not.specified", module.getName()))); return false; } final Pair<AndroidSdk, IAndroidTarget> pair = AndroidJpsUtil.getAndroidPlatform(module, context, BUILDER_NAME); if (pair == null) { return false; } final Set<String> externalJarsSet = AndroidJpsUtil.getExternalLibraries(paths, module); final File resPackage = getPackagedResourcesFile(module, outputDir); final File classesDexFile = new File(outputDir.getPath(), AndroidCommonUtils.CLASSES_FILE_NAME); final String sdkPath = pair.getFirst().getSdkPath(); final String outputPath = AndroidJpsUtil.getApkPath(facet, outputDir); if (outputPath == null) { context.processMessage( new CompilerMessage( BUILDER_NAME, BuildMessage.Kind.ERROR, "Cannot compute output path for file " + AndroidJpsUtil.getApkName(module))); return false; } final String customKeyStorePath = FileUtil.toSystemDependentName(facet.getCustomDebugKeyStorePath()); final String[] nativeLibDirs = collectNativeLibsFolders(facet); final String resPackagePath = release ? resPackage.getPath() + RELEASE_SUFFIX : resPackage.getPath(); final String outputApkPath = release ? outputPath + UNSIGNED_SUFFIX : outputPath; final String classesDexFilePath = classesDexFile.getPath(); final String[] externalJars = ArrayUtil.toStringArray(externalJarsSet); final AndroidFileSetState currentFileSetState = buildCurrentApkBuilderState( context.getProject(), resPackagePath, classesDexFilePath, nativeLibDirs, sourceRoots, externalJars, release); final AndroidApkBuilderConfigState currentApkBuilderConfigState = new AndroidApkBuilderConfigState(outputApkPath, customKeyStorePath); final AndroidFileSetState savedApkFileSetState = apkFileSetStorage.getState(module.getName()); final AndroidApkBuilderConfigState savedApkBuilderConfigState = apkBuilderConfigStateStorage.getState(module.getName()); if (context.isMake() && currentFileSetState.equalsTo(savedApkFileSetState) && currentApkBuilderConfigState.equalsTo(savedApkBuilderConfigState)) { return true; } context.processMessage( new ProgressMessage( AndroidJpsBundle.message( "android.jps.progress.packaging", AndroidJpsUtil.getApkName(module)))); final Map<AndroidCompilerMessageKind, List<String>> messages = AndroidApkBuilder.execute( resPackagePath, classesDexFilePath, sourceRoots, externalJars, nativeLibDirs, outputApkPath, release, sdkPath, customKeyStorePath, new MyExcludedSourcesFilter(context.getProject())); AndroidJpsUtil.addMessages(context, messages, BUILDER_NAME); final boolean success = messages.get(AndroidCompilerMessageKind.ERROR).isEmpty(); apkFileSetStorage.update(module.getName(), success ? currentFileSetState : null); apkBuilderConfigStateStorage.update( module.getName(), success ? currentApkBuilderConfigState : null); return success; }
@Override public ExitCode build( CompileContext context, ModuleChunk chunk, DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder, OutputConsumer outputConsumer) throws ProjectBuildException, IOException { final IceConfig config = context.getProjectDescriptor().getProject().getContainer().getChild(IceConfig.ROLE); IceConfig iceConfig = config == null ? new IceConfig("") : config; File frameworkHome = JpsPathUtil.urlToFile(iceConfig.getFrameworkHomeUrl()); List<String> includes = new ArrayList<String>(); for (String include : iceConfig.getIncludeUrls()) { includes.add(JpsPathUtil.urlToFile(include).getAbsolutePath()); } final Map<ModuleBuildTarget, List<File>> toCompile = collectChangedFiles(context, dirtyFilesHolder); if (toCompile.isEmpty()) { return ExitCode.NOTHING_DONE; } for (Map.Entry<ModuleBuildTarget, List<File>> e : toCompile.entrySet()) { final ModuleBuildTarget target = e.getKey(); final JpsModule module = target.getModule(); SliceCompilerSettings settings = module.getContainer().getChild(SliceCompilerSettings.ROLE); final SliceCompilerSettings facetConfig = settings == null ? new SliceCompilerSettings() : settings; final List<File> sourceFiles = e.getValue(); List<Target> translators = facetConfig.getComponents(); if (translators.isEmpty()) { context.processMessage( new CompilerMessage( getPresentableName(), BuildMessage.Kind.WARNING, "No valid translators found for module " + module.getName() + ". Check facet configuration.")); continue; } // Translate files for (Target c : translators) { final File outputDir = c.getOutputFile(); if (facetConfig.isCleanOutput()) { try { FileUtils.cleanDirectory(outputDir); } catch (IOException ex) { context.processMessage( new CompilerMessage( getPresentableName(), BuildMessage.Kind.ERROR, "Failed to empty target directory: " + outputDir.getPath() + " . Error: " + ex.getMessage())); return ExitCode.ABORT; } } compileFiles( context, frameworkHome, includes, target, sourceFiles, c.getComponent(), outputDir); } } return ExitCode.OK; }
@Override public ExitCode build( final CompileContext context, ModuleChunk chunk, DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder, OutputConsumer outputConsumer) throws ProjectBuildException, IOException { if (!useGreclipse(context)) return ModuleLevelBuilder.ExitCode.NOTHING_DONE; try { final List<File> toCompile = GroovyBuilder.collectChangedFiles( context, dirtyFilesHolder, false, true, Ref.create(false)); if (toCompile.isEmpty()) { return ExitCode.NOTHING_DONE; } Map<ModuleBuildTarget, String> outputDirs = GroovyBuilder.getCanonicalModuleOutputs(context, chunk, this); if (outputDirs == null) { return ExitCode.ABORT; } JpsProject project = context.getProjectDescriptor().getProject(); GreclipseSettings greclipseSettings = GreclipseJpsCompilerSettings.getSettings(project); if (greclipseSettings == null) { String message = "Compiler settings component not initialized for " + project; LOG.error(message); context.processMessage( new CompilerMessage(getPresentableName(), BuildMessage.Kind.ERROR, message)); return ExitCode.ABORT; } ClassLoader loader = createGreclipseLoader(greclipseSettings.greclipsePath); if (loader == null) { context.processMessage( new CompilerMessage( getPresentableName(), BuildMessage.Kind.ERROR, "Invalid jar path in the compiler settings: '" + greclipseSettings.greclipsePath + "'")); return ExitCode.ABORT; } final JpsJavaExtensionService javaExt = JpsJavaExtensionService.getInstance(); final JpsJavaCompilerConfiguration compilerConfig = javaExt.getCompilerConfiguration(project); assert compilerConfig != null; final Set<JpsModule> modules = chunk.getModules(); ProcessorConfigProfile profile = null; if (modules.size() == 1) { profile = compilerConfig.getAnnotationProcessingProfile(modules.iterator().next()); } else { String message = JavaBuilder.validateCycle(chunk, javaExt, compilerConfig, modules); if (message != null) { context.processMessage( new CompilerMessage(getPresentableName(), BuildMessage.Kind.ERROR, message)); return ExitCode.ABORT; } } String mainOutputDir = outputDirs.get(chunk.representativeTarget()); final List<String> args = createCommandLine(context, chunk, toCompile, mainOutputDir, profile, greclipseSettings); if (Utils.IS_TEST_MODE || LOG.isDebugEnabled()) { LOG.debug("Compiling with args: " + args); } Boolean notified = COMPILER_VERSION_INFO.get(context); if (notified != Boolean.TRUE) { context.processMessage( new CompilerMessage( "", BuildMessage.Kind.INFO, "Using Groovy-Eclipse to compile Java & Groovy sources")); COMPILER_VERSION_INFO.set(context, Boolean.TRUE); } context.processMessage( new ProgressMessage("Compiling java & groovy [" + chunk.getPresentableShortName() + "]")); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); HashMap<String, List<String>> outputMap = ContainerUtil.newHashMap(); boolean success = performCompilation(args, out, err, outputMap, context, chunk); List<GroovycOutputParser.OutputItem> items = ContainerUtil.newArrayList(); for (String src : outputMap.keySet()) { //noinspection ConstantConditions for (String classFile : outputMap.get(src)) { items.add( new GroovycOutputParser.OutputItem( FileUtil.toSystemIndependentName(mainOutputDir + classFile), FileUtil.toSystemIndependentName(src))); } } Map<ModuleBuildTarget, Collection<GroovycOutputParser.OutputItem>> successfullyCompiled = GroovyBuilder.processCompiledFiles(context, chunk, outputDirs, mainOutputDir, items); EclipseOutputParser parser = new EclipseOutputParser(getPresentableName(), chunk); List<CompilerMessage> messages = ContainerUtil.concat( parser.parseMessages(out.toString()), parser.parseMessages(err.toString())); boolean hasError = false; for (CompilerMessage message : messages) { if (message.getKind() == BuildMessage.Kind.ERROR) { hasError = true; } context.processMessage(message); } if (!success && !hasError) { context.processMessage( new CompilerMessage( getPresentableName(), BuildMessage.Kind.ERROR, "Compilation failed")); } GroovyBuilder.updateDependencies( context, toCompile, successfullyCompiled, outputConsumer, this); return ExitCode.OK; } catch (Exception e) { throw new ProjectBuildException(e); } }