@Override
  public void build(CompileContext context) throws ProjectBuildException {
    if (!AndroidJpsUtil.containsAndroidFacet(context.getProject())
        || AndroidJpsUtil.isLightBuild(context)) {
      return;
    }
    final Collection<Module> modules = context.getProject().getModules().values();
    final Map<Module, AndroidFileSetState> resourcesStates =
        new HashMap<Module, AndroidFileSetState>();
    final Map<Module, AndroidFileSetState> assetsStates =
        new HashMap<Module, AndroidFileSetState>();

    try {
      fillStates(modules, resourcesStates, assetsStates);

      if (!doCaching(context, modules, resourcesStates)) {
        throw new ProjectBuildException();
      }

      if (!doResourcePackaging(context, modules, resourcesStates, assetsStates)) {
        throw new ProjectBuildException();
      }

      if (!doPackaging(context, modules)) {
        throw new ProjectBuildException();
      }
    } catch (ProjectBuildException e) {
      throw e;
    } catch (Exception e) {
      AndroidJpsUtil.handleException(context, e, BUILDER_NAME);
    }
  }
 private static Map<String, String> buildClassToSourceMap(
     ModuleChunk chunk,
     CompileContext context,
     Set<String> toCompilePaths,
     String moduleOutputPath)
     throws IOException {
   final Map<String, String> class2Src = new HashMap<String, String>();
   for (Module module : chunk.getModules()) {
     final String moduleName = module.getName().toLowerCase(Locale.US);
     final SourceToOutputMapping srcToOut =
         context.getDataManager().getSourceToOutputMap(moduleName, context.isCompilingTests());
     for (String src : srcToOut.getKeys()) {
       if (!toCompilePaths.contains(src) && isGroovyFile(src)) {
         final Collection<String> outs = srcToOut.getState(src);
         if (outs != null) {
           for (String out : outs) {
             if (out.endsWith(".class") && out.startsWith(moduleOutputPath)) {
               final String className =
                   out.substring(moduleOutputPath.length(), out.length() - ".class".length())
                       .replace('/', '.');
               class2Src.put(className, src);
             }
           }
         }
       }
     }
   }
   return class2Src;
 }
 private static void traverseRecursively(
     CompileContext context,
     final JavaSourceRootDescriptor rd,
     final File file,
     Set<File> excludes,
     @NotNull final Timestamps tsStorage,
     final boolean forceDirty,
     @Nullable Set<File> currentFiles)
     throws IOException {
   final File[] children = file.listFiles();
   if (children != null) { // is directory
     if (children.length > 0 && !JpsPathUtil.isUnder(excludes, file)) {
       for (File child : children) {
         traverseRecursively(context, rd, child, excludes, tsStorage, forceDirty, currentFiles);
       }
     }
   } else { // is file
     boolean markDirty = forceDirty;
     if (!markDirty) {
       markDirty = tsStorage.getStamp(file, rd.target) != FileSystemUtil.lastModified(file);
     }
     if (markDirty) {
       // if it is full project rebuild, all storages are already completely cleared;
       // so passing null because there is no need to access the storage to clear non-existing data
       final Timestamps marker = context.isProjectRebuild() ? null : tsStorage;
       context.getProjectDescriptor().fsState.markDirty(context, file, rd, marker);
     }
     if (currentFiles != null) {
       currentFiles.add(file);
     }
   }
 }
 private static Map<String, String> buildClassToSourceMap(
     ModuleChunk chunk,
     CompileContext context,
     Set<String> toCompilePaths,
     Map<ModuleBuildTarget, String> finalOutputs)
     throws IOException {
   final Map<String, String> class2Src = new HashMap<String, String>();
   JpsJavaCompilerConfiguration configuration =
       JpsJavaExtensionService.getInstance()
           .getOrCreateCompilerConfiguration(context.getProjectDescriptor().getProject());
   for (ModuleBuildTarget target : chunk.getTargets()) {
     String moduleOutputPath = finalOutputs.get(target);
     final SourceToOutputMapping srcToOut =
         context.getProjectDescriptor().dataManager.getSourceToOutputMap(target);
     for (String src : srcToOut.getSources()) {
       if (!toCompilePaths.contains(src)
           && isGroovyFile(src)
           && !configuration.getCompilerExcludes().isExcluded(new File(src))) {
         final Collection<String> outs = srcToOut.getOutputs(src);
         if (outs != null) {
           for (String out : outs) {
             if (out.endsWith(".class") && out.startsWith(moduleOutputPath)) {
               final String className =
                   out.substring(moduleOutputPath.length(), out.length() - ".class".length())
                       .replace('/', '.');
               class2Src.put(className, src);
             }
           }
         }
       }
     }
   }
   return class2Src;
 }
  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;
    }
  }
 public static void markDeleted(CompileContext context, File file) throws IOException {
   final JavaSourceRootDescriptor rd =
       context.getProjectDescriptor().getBuildRootIndex().getModuleAndRoot(context, file);
   if (rd != null) {
     final ProjectDescriptor pd = context.getProjectDescriptor();
     pd.fsState.registerDeleted(rd.target, file, pd.timestamps.getStorage());
   }
 }
  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;
  }
 public static void markDirty(
     CompileContext context, final CompilationRound round, final File file) throws IOException {
   final JavaSourceRootDescriptor rd =
       context.getProjectDescriptor().getBuildRootIndex().findJavaRootDescriptor(context, file);
   if (rd != null) {
     final ProjectDescriptor pd = context.getProjectDescriptor();
     pd.fsState.markDirty(context, round, file, rd, pd.timestamps.getStorage());
   }
 }
 private static String getModuleOutput(CompileContext context, ModuleChunk chunk) {
   final Module representativeModule = chunk.getModules().iterator().next();
   File moduleOutputDir =
       context
           .getProjectPaths()
           .getModuleOutputDir(representativeModule, context.isCompilingTests());
   assert moduleOutputDir != null;
   String moduleOutputPath = FileUtil.toCanonicalPath(moduleOutputDir.getPath());
   return moduleOutputPath.endsWith("/") ? moduleOutputPath : moduleOutputPath + "/";
 }
 /**
  * @param context
  * @param round
  * @param file
  * @return true if file is marked as "dirty" in the specified compilation round
  * @throws IOException
  */
 public static boolean isMarkedDirty(
     CompileContext context, final CompilationRound round, final File file) throws IOException {
   final JavaSourceRootDescriptor rd =
       context.getProjectDescriptor().getBuildRootIndex().findJavaRootDescriptor(context, file);
   if (rd != null) {
     final ProjectDescriptor pd = context.getProjectDescriptor();
     return pd.fsState.isMarkedForRecompilation(context, round, rd, file);
   }
   return false;
 }
  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);
    }
  }
  public static void markDirtyRecursively(
      CompileContext context,
      final CompilationRound round,
      ModuleChunk chunk,
      @Nullable FileFilter filter)
      throws IOException {
    Set<JpsModule> modules = chunk.getModules();
    Set<ModuleBuildTarget> targets = chunk.getTargets();
    final Set<ModuleBuildTarget> dirtyTargets = new HashSet<ModuleBuildTarget>(targets);

    // now mark all modules that depend on dirty modules
    final JpsJavaClasspathKind classpathKind = JpsJavaClasspathKind.compile(chunk.containsTests());
    boolean found = false;
    for (BuildTargetChunk targetChunk :
        context.getProjectDescriptor().getBuildTargetIndex().getSortedTargetChunks(context)) {
      if (!found) {
        if (targetChunk.getTargets().equals(chunk.getTargets())) {
          found = true;
        }
      } else {
        for (final BuildTarget<?> target : targetChunk.getTargets()) {
          if (target instanceof ModuleBuildTarget) {
            final Set<JpsModule> deps =
                getDependentModulesRecursively(
                    ((ModuleBuildTarget) target).getModule(), classpathKind);
            if (ContainerUtil.intersects(deps, modules)) {
              for (BuildTarget<?> buildTarget : targetChunk.getTargets()) {
                if (buildTarget instanceof ModuleBuildTarget) {
                  dirtyTargets.add((ModuleBuildTarget) buildTarget);
                }
              }
              break;
            }
          }
        }
      }
    }

    removeTargetsAlreadyMarkedDirty(context, dirtyTargets);

    final Timestamps timestamps = context.getProjectDescriptor().timestamps.getStorage();
    for (ModuleBuildTarget target : dirtyTargets) {
      markDirtyFiles(context, target, round, timestamps, true, null, filter);
    }

    if (JavaBuilderUtil.isCompileJavaIncrementally(context)) {
      // mark as non-incremental only the module that triggered non-incremental change
      for (ModuleBuildTarget target : targets) {
        context.markNonIncremental(target);
      }
    }
  }
  private static boolean doCaching(
      @NotNull CompileContext context,
      @NotNull Collection<Module> modules,
      @NotNull Map<Module, AndroidFileSetState> module2state)
      throws IOException {
    boolean success = true;
    final File dataStorageRoot = context.getDataManager().getDataStorageRoot();
    final AndroidFileSetStorage storage =
        new AndroidFileSetStorage(dataStorageRoot, "resource_caching");

    try {
      for (Module module : modules) {
        final AndroidFileSetState state = module2state.get(module);

        try {
          if (!runPngCaching(context, module, storage, state)) {
            success = false;
          }
        } catch (IOException e) {
          AndroidJpsUtil.reportExceptionError(context, null, e, BUILDER_NAME);
        }
      }
    } finally {
      storage.close();
    }
    return success;
  }
 static boolean useGreclipse(CompileContext context) {
   JpsProject project = context.getProjectDescriptor().getProject();
   return ID.equals(
       JpsJavaExtensionService.getInstance()
           .getOrCreateCompilerConfiguration(project)
           .getJavaCompilerId());
 }
 private static int getJavacServerHeapSize(CompileContext context) {
   final JpsProject project = context.getProjectDescriptor().getProject();
   final JpsJavaCompilerConfiguration config =
       JpsJavaExtensionService.getInstance().getOrCreateCompilerConfiguration(project);
   final JpsJavaCompilerOptions options = config.getCurrentCompilerOptions();
   return options.MAXIMUM_HEAP_SIZE;
 }
  public static void pruneEmptyDirs(
      CompileContext context, @Nullable final Set<File> dirsToDelete) {
    if (dirsToDelete == null || dirsToDelete.isEmpty()) return;

    Set<File> doNotDelete = ALL_OUTPUTS_KEY.get(context);
    if (doNotDelete == null) {
      doNotDelete = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
      for (BuildTarget<?> target :
          context.getProjectDescriptor().getBuildTargetIndex().getAllTargets()) {
        doNotDelete.addAll(target.getOutputRoots(context));
      }
      ALL_OUTPUTS_KEY.set(context, doNotDelete);
    }

    Set<File> additionalDirs = null;
    Set<File> toDelete = dirsToDelete;
    while (toDelete != null) {
      for (File file : toDelete) {
        // important: do not force deletion if the directory is not empty!
        final boolean deleted = !doNotDelete.contains(file) && file.delete();
        if (deleted) {
          final File parentFile = file.getParentFile();
          if (parentFile != null) {
            if (additionalDirs == null) {
              additionalDirs = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
            }
            additionalDirs.add(parentFile);
          }
        }
      }
      toDelete = additionalDirs;
      additionalDirs = null;
    }
  }
 public static void processFilesToRecompile(
     CompileContext context,
     @NotNull ModuleBuildTarget target,
     FileProcessor<JavaSourceRootDescriptor, ModuleBuildTarget> processor)
     throws IOException {
   context.getProjectDescriptor().fsState.processFilesToRecompile(context, target, processor);
 }
 @Override
 public void buildStarted(CompileContext context) {
   final JpsProject project = context.getProjectDescriptor().getProject();
   final JpsJavaCompilerConfiguration config =
       JpsJavaExtensionService.getInstance().getCompilerConfiguration(project);
   final String compilerId = config == null ? JavaCompilers.JAVAC_ID : config.getJavaCompilerId();
   if (LOG.isDebugEnabled()) {
     LOG.debug("Java compiler ID: " + compilerId);
   }
   final boolean isJavac =
       JavaCompilers.JAVAC_ID.equalsIgnoreCase(compilerId)
           || JavaCompilers.JAVAC_API_ID.equalsIgnoreCase(compilerId);
   final boolean isEclipse =
       JavaCompilers.ECLIPSE_ID.equalsIgnoreCase(compilerId)
           || JavaCompilers.ECLIPSE_EMBEDDED_ID.equalsIgnoreCase(compilerId);
   IS_ENABLED.set(context, isJavac || isEclipse);
   String messageText = null;
   if (isJavac) {
     messageText =
         "Using javac " + System.getProperty("java.version") + " to compile java sources";
   } else if (isEclipse) {
     messageText = "Using eclipse compiler to compile java sources";
   }
   COMPILER_VERSION_INFO.set(context, new AtomicReference<String>(messageText));
 }
  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;
    }
  }
    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);
              }
            }
          });
    }
  @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 static void markDirty(CompileContext context, final ModuleChunk chunk) throws IOException {
   final ProjectDescriptor pd = context.getProjectDescriptor();
   pd.fsState.clearContextRoundData(context);
   for (ModuleBuildTarget target : chunk.getTargets()) {
     markDirtyFiles(context, target, pd.timestamps.getStorage(), true, null);
   }
 }
  private static void loadCommonJavacOptions(CompileContext context) {
    final List<String> options = new ArrayList<String>();
    final List<String> vmOptions = new ArrayList<String>();

    final JpsProject project = context.getProjectDescriptor().getProject();
    final JpsJavaCompilerConfiguration compilerConfig =
        JpsJavaExtensionService.getInstance().getOrCreateCompilerConfiguration(project);
    final JpsJavaCompilerOptions compilerOptions = compilerConfig.getCurrentCompilerOptions();
    if (compilerOptions.DEBUGGING_INFO) {
      options.add("-g");
    }
    if (compilerOptions.DEPRECATION) {
      options.add("-deprecation");
    }
    if (compilerOptions.GENERATE_NO_WARNINGS) {
      options.add("-nowarn");
    }
    if (compilerOptions instanceof EclipseCompilerOptions) {
      final EclipseCompilerOptions eclipseOptions = (EclipseCompilerOptions) compilerOptions;
      if (eclipseOptions.PROCEED_ON_ERROR) {
        options.add("-proceedOnError");
      }
    }
    final String customArgs = compilerOptions.ADDITIONAL_OPTIONS_STRING;
    if (customArgs != null) {
      final StringTokenizer customOptsTokenizer = new StringTokenizer(customArgs, " \t\r\n");
      boolean skip = false;
      while (customOptsTokenizer.hasMoreTokens()) {
        final String userOption = customOptsTokenizer.nextToken();
        if (FILTERED_OPTIONS.contains(userOption)) {
          skip = true;
          continue;
        }
        if (!skip) {
          if (!FILTERED_SINGLE_OPTIONS.contains(userOption)) {
            if (userOption.startsWith("-J-")) {
              vmOptions.add(userOption.substring("-J".length()));
            } else {
              options.add(userOption);
            }
          }
        }
      }
    }

    if (useEclipseCompiler(context)) {
      for (String option : options) {
        if (option.startsWith("-proceedOnError")) {
          Utils.PROCEED_ON_ERROR_KEY.set(context, Boolean.TRUE);
          break;
        }
      }
    }

    JAVAC_OPTIONS.set(context, options);
    JAVAC_VM_OPTIONS.set(context, vmOptions);
  }
 static void markDirtyFiles(
     CompileContext context,
     ModuleBuildTarget target,
     Timestamps timestamps,
     boolean forceMarkDirty,
     @Nullable THashSet<File> currentFiles)
     throws IOException {
   final ModuleExcludeIndex rootsIndex = context.getProjectDescriptor().getModuleExcludeIndex();
   final Set<File> excludes = new HashSet<File>(rootsIndex.getModuleExcludes(target.getModule()));
   for (JavaSourceRootDescriptor rd :
       context.getProjectDescriptor().getBuildRootIndex().getTargetRoots(target, context)) {
     if (!rd.root.exists()) {
       continue;
     }
     context.getProjectDescriptor().fsState.clearRecompile(rd);
     traverseRecursively(context, rd, rd.root, excludes, timestamps, forceMarkDirty, currentFiles);
   }
 }
 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));
     }
   }
 }
  private static List<String> generateClasspath(CompileContext context, ModuleChunk chunk) {
    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()));
    }
    return new ArrayList<String>(cp);
  }
 public static void markDirty(
     CompileContext context,
     final CompilationRound round,
     final ModuleChunk chunk,
     @Nullable FileFilter filter)
     throws IOException {
   final ProjectDescriptor pd = context.getProjectDescriptor();
   for (ModuleBuildTarget target : chunk.getTargets()) {
     markDirtyFiles(context, target, round, pd.timestamps.getStorage(), true, null, filter);
   }
 }
 private static boolean useEclipseCompiler(CompileContext context) {
   if (!USE_EMBEDDED_JAVAC) {
     return false;
   }
   JpsProject project = context.getProjectDescriptor().getProject();
   final JpsJavaCompilerConfiguration configuration =
       JpsJavaExtensionService.getInstance().getCompilerConfiguration(project);
   final String compilerId = configuration != null ? configuration.getJavaCompilerId() : null;
   return JavaCompilers.ECLIPSE_ID.equalsIgnoreCase(compilerId)
       || JavaCompilers.ECLIPSE_EMBEDDED_ID.equalsIgnoreCase(compilerId);
 }
 private static void addStubRootsToJavacSourcePath(
     CompileContext context, Map<ModuleBuildTarget, String> generationOutputs) {
   final BuildRootIndex rootsIndex = context.getProjectDescriptor().getBuildRootIndex();
   for (ModuleBuildTarget target : generationOutputs.keySet()) {
     File root = new File(generationOutputs.get(target));
     rootsIndex.associateTempRoot(
         context,
         target,
         new JavaSourceRootDescriptor(root, target, true, true, "", Collections.<File>emptySet()));
   }
 }
  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);
  }