<commit_before>package org.jetbrains.jps

import org.codehaus.gant.GantBinding
import org.jetbrains.jps.dag.DagBuilder
import org.jetbrains.jps.builders.*
import org.jetbrains.jps.listeners.JpsBuildListener
import org.jetbrains.jps.listeners.BuildStatisticsListener
import org.jetbrains.jps.listeners.BuildInfoPrinter
import org.jetbrains.jps.listeners.DefaultBuildInfoPrinter

/**
 * @author max
 */
class ProjectBuilder {
  final Map<Module, ModuleChunk> mapping = [:]
  final Map<ModuleChunk, String> outputs = [:]
  final Map<ModuleChunk, String> testOutputs = [:]
  final Map<ClasspathKind, Map<ModuleChunk, List<String>>> cachedClasspaths = [:]
  final Map<ModuleChunk, List<String>> testCp = [:]
  List<ModuleChunk> chunks = null

  final Project project;
  final GantBinding binding;

  final List<ModuleBuilder> sourceGeneratingBuilders = []
  final List<ModuleBuilder> sourceModifyingBuilders = []
  final List<ModuleBuilder> translatingBuilders = []
  final List<ModuleBuilder> weavingBuilders = []
  final CustomTasksBuilder preTasksBuilder = new CustomTasksBuilder()
  final CustomTasksBuilder postTasksBuilder = new CustomTasksBuilder()

  final List<JpsBuildListener> listeners = [new BuildStatisticsListener()]
  BuildInfoPrinter buildInfoPrinter = new DefaultBuildInfoPrinter()
  boolean useInProcessJavac

  def ProjectBuilder(GantBinding binding, Project project) {
    this.project = project
    this.binding = binding
    sourceGeneratingBuilders << new GroovyStubGenerator(project)
    translatingBuilders << new JavacBuilder()
    translatingBuilders << new GroovycBuilder(project)
    translatingBuilders << new ResourceCopier()
    weavingBuilders << new JetBrainsInstrumentations(project)
  }

  private def List<ModuleBuilder> builders() {
    [preTasksBuilder, sourceGeneratingBuilders, sourceModifyingBuilders, translatingBuilders, weavingBuilders, postTasksBuilder].flatten()
  }

  private def buildChunks() {
    if (chunks == null) {
      def iterator = { Module module, Closure processor ->
        module.getFullClasspath().each {entry ->
          if (entry instanceof Module) {
            processor(entry)
          }
        }
      }
      def dagBuilder = new DagBuilder<Module>({new ModuleChunk()}, iterator)
      chunks = dagBuilder.build(project, project.modules.values())
      chunks.each { ModuleChunk chunk ->
        chunk.modules.each {
          mapping[it] = chunk
        }
      }
      project.info("Total ${chunks.size()} chunks detected")
    }
  }

  public def clean() {
    outputs.clear()
    testOutputs.clear()
    cachedClasspaths.clear();
  }

  public def buildAll() {
    buildAllModules(true)
  }

  public def buildProduction() {
    buildAllModules(false)
  }

  private def buildAllModules(boolean includeTests) {
    listeners*.onBuildStarted(project)
    buildChunks()
    chunks.each {
      makeChunk(it, false)
      if (includeTests) {
        makeChunk(it, true)
      }
    }
    listeners*.onBuildFinished(project)
  }

  def preModuleBuildTask(String moduleName, Closure task) {
    preTasksBuilder.registerTask(moduleName, task)
  }

  def postModuleBuildTask(String moduleName, Closure task) {
    postTasksBuilder.registerTask(moduleName, task)
  }

  private ModuleChunk chunkForModule(Module m) {
    buildChunks();
    mapping[m]
  }

  def makeModule(Module module) {
    return makeChunkWithDependencies(chunkForModule(module), false);
  }

  def makeModuleTests(Module module) {
    return makeChunkWithDependencies(chunkForModule(module), true);
  }

  private def makeChunkWithDependencies(ModuleChunk chunk, boolean tests) {
    Set<Module> dependencies = new HashSet<Module>()
    chunk.modules.each {
      collectModulesFromClasspath(it, getCompileClasspathKind(tests), dependencies)
    }
    buildChunks()
    chunks.each {
      if (!dependencies.intersect(it.modules).isEmpty()) {
        makeChunk(it, tests)
      }
    }
  }

  private def makeChunk(ModuleChunk chunk, boolean tests) {
    Map outputsMap = tests ? testOutputs : outputs
    String currentOutput = outputsMap[chunk]<commit_msg>module.makeTests() also compiles production sources<commit_after>package org.jetbrains.jps

import org.codehaus.gant.GantBinding
import org.jetbrains.jps.dag.DagBuilder
import org.jetbrains.jps.builders.*
import org.jetbrains.jps.listeners.JpsBuildListener
import org.jetbrains.jps.listeners.BuildStatisticsListener
import org.jetbrains.jps.listeners.BuildInfoPrinter
import org.jetbrains.jps.listeners.DefaultBuildInfoPrinter

/**
 * @author max
 */
class ProjectBuilder {
  final Map<Module, ModuleChunk> mapping = [:]
  final Map<ModuleChunk, String> outputs = [:]
  final Map<ModuleChunk, String> testOutputs = [:]
  final Map<ClasspathKind, Map<ModuleChunk, List<String>>> cachedClasspaths = [:]
  final Map<ModuleChunk, List<String>> testCp = [:]
  List<ModuleChunk> chunks = null

  final Project project;
  final GantBinding binding;

  final List<ModuleBuilder> sourceGeneratingBuilders = []
  final List<ModuleBuilder> sourceModifyingBuilders = []
  final List<ModuleBuilder> translatingBuilders = []
  final List<ModuleBuilder> weavingBuilders = []
  final CustomTasksBuilder preTasksBuilder = new CustomTasksBuilder()
  final CustomTasksBuilder postTasksBuilder = new CustomTasksBuilder()

  final List<JpsBuildListener> listeners = [new BuildStatisticsListener()]
  BuildInfoPrinter buildInfoPrinter = new DefaultBuildInfoPrinter()
  boolean useInProcessJavac

  def ProjectBuilder(GantBinding binding, Project project) {
    this.project = project
    this.binding = binding
    sourceGeneratingBuilders << new GroovyStubGenerator(project)
    translatingBuilders << new JavacBuilder()
    translatingBuilders << new GroovycBuilder(project)
    translatingBuilders << new ResourceCopier()
    weavingBuilders << new JetBrainsInstrumentations(project)
  }

  private def List<ModuleBuilder> builders() {
    [preTasksBuilder, sourceGeneratingBuilders, sourceModifyingBuilders, translatingBuilders, weavingBuilders, postTasksBuilder].flatten()
  }

  private def buildChunks() {
    if (chunks == null) {
      def iterator = { Module module, Closure processor ->
        module.getFullClasspath().each {entry ->
          if (entry instanceof Module) {
            processor(entry)
          }
        }
      }
      def dagBuilder = new DagBuilder<Module>({new ModuleChunk()}, iterator)
      chunks = dagBuilder.build(project, project.modules.values())
      chunks.each { ModuleChunk chunk ->
        chunk.modules.each {
          mapping[it] = chunk
        }
      }
      project.info("Total ${chunks.size()} chunks detected")
    }
  }

  public def clean() {
    outputs.clear()
    testOutputs.clear()
    cachedClasspaths.clear();
  }

  public def buildAll() {
    buildAllModules(true)
  }

  public def buildProduction() {
    buildAllModules(false)
  }

  private def buildAllModules(boolean includeTests) {
    listeners*.onBuildStarted(project)
    buildChunks()
    chunks.each {
      makeChunk(it, false)
      if (includeTests) {
        makeChunk(it, true)
      }
    }
    listeners*.onBuildFinished(project)
  }

  def preModuleBuildTask(String moduleName, Closure task) {
    preTasksBuilder.registerTask(moduleName, task)
  }

  def postModuleBuildTask(String moduleName, Closure task) {
    postTasksBuilder.registerTask(moduleName, task)
  }

  private ModuleChunk chunkForModule(Module m) {
    buildChunks();
    mapping[m]
  }

  def makeModule(Module module) {
    return makeChunkWithDependencies(chunkForModule(module), false);
  }

  def makeModuleTests(Module module) {
    return makeChunkWithDependencies(chunkForModule(module), true);
  }

  private def makeChunkWithDependencies(ModuleChunk chunk, boolean includeTests) {
    Set<Module> dependencies = new HashSet<Module>()
    chunk.modules.each {
      collectModulesFromClasspath(it, getCompileClasspathKind(includeTests), dependencies)
    }
    buildChunks()
    chunks.each {
      if (!dependencies.intersect(it.modules).isEmpty()) {
        makeChunk(it, false)
        if (includeTests) {
          makeChunk(it, true)
        }
      }
    }
  }

  private def makeChunk(ModuleChunk chunk, boolean tests) {
    Map outputsMap = tests ? testOutputs : outputs
    String currentOutput = outputsMap[chunk]
{'fraction_non_alphanumeric': 0.09571909571909572, 'fraction_numerical': 0.0, 'mean_word_length': 3.974282296650718, 'pattern_counts': {'":': 0, '<': 59, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6030494', 'n_tokens_mistral': 2421, 'n_tokens_neox': 2356, 'n_words': 505}