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); } } }