external compiler: load model before loading BuildTargets to ensure that ModuleBuildTarget always refers to an existing module

This commit is contained in:
nik
2012-09-03 12:01:29 +04:00
parent bbc8ab771e
commit 3be2076196
18 changed files with 79 additions and 78 deletions
@@ -4,7 +4,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.NotNullFunction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType;
import org.jetbrains.jps.incremental.RealModuleBuildTarget;
import org.jetbrains.jps.incremental.ModuleBuildTarget;
import org.jetbrains.jps.model.JpsProject;
import org.jetbrains.jps.model.module.JpsModule;
@@ -24,14 +24,14 @@ public class ModuleChunk {
};
private Set<JpsModule> myModules;
private final boolean myTests;
private Set<RealModuleBuildTarget> myTargets;
private Set<ModuleBuildTarget> myTargets;
public ModuleChunk(Set<JpsModule> modules, boolean tests) {
myModules = modules;
myTests = tests;
myTargets = new LinkedHashSet<RealModuleBuildTarget>();
myTargets = new LinkedHashSet<ModuleBuildTarget>();
for (JpsModule module : modules) {
myTargets.add(new RealModuleBuildTarget(module, JavaModuleBuildTargetType.getInstance(tests)));
myTargets.add(new ModuleBuildTarget(module, JavaModuleBuildTargetType.getInstance(tests)));
}
}
@@ -48,7 +48,7 @@ public class ModuleChunk {
return myTests;
}
public Set<RealModuleBuildTarget> getTargets() {
public Set<ModuleBuildTarget> getTargets() {
return myTargets;
}
@@ -1,6 +1,8 @@
package org.jetbrains.jps.builders;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.cmdline.ProjectDescriptor;
/**
* @author nik
@@ -16,5 +18,6 @@ public abstract class BuildTargetType {
return myTypeId;
}
public abstract BuildTarget createTarget(@NotNull String targetId);
@Nullable
public abstract BuildTarget createTarget(@NotNull String targetId, @NotNull ProjectDescriptor projectDescriptor);
}
@@ -1,9 +1,12 @@
package org.jetbrains.jps.builders.java;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.builders.BuildTarget;
import org.jetbrains.jps.builders.BuildTargetType;
import org.jetbrains.jps.cmdline.ProjectDescriptor;
import org.jetbrains.jps.incremental.ModuleBuildTarget;
import org.jetbrains.jps.model.module.JpsModule;
/**
* @author nik
@@ -18,9 +21,11 @@ public class JavaModuleBuildTargetType extends BuildTargetType {
myTests = tests;
}
@Nullable
@Override
public BuildTarget createTarget(@NotNull String targetId) {
return new ModuleBuildTarget(targetId, this);
public BuildTarget createTarget(@NotNull String targetId, @NotNull ProjectDescriptor projectDescriptor) {
JpsModule module = projectDescriptor.rootsIndex.getModuleByName(targetId);
return module != null ? new ModuleBuildTarget(module, this) : null;
}
public boolean isTests() {
@@ -21,6 +21,7 @@ import org.jetbrains.jps.incremental.fs.FSState;
import org.jetbrains.jps.incremental.fs.RootDescriptor;
import org.jetbrains.jps.incremental.messages.*;
import org.jetbrains.jps.incremental.storage.Timestamps;
import org.jetbrains.jps.model.JpsModel;
import org.jetbrains.jps.service.SharedThreadPool;
import java.io.*;
@@ -147,17 +148,14 @@ final class BuildSession implements Runnable, CanceledStatus {
final BuildFSState fsState = new BuildFSState(false);
try {
final boolean shouldApplyEvent = loadFsState(fsState, dataStorageRoot, myInitialFSDelta);
if (shouldApplyEvent && myBuildType == BuildType.MAKE && !containsChanges(myInitialFSDelta) && !fsState.hasWorkToDo()) {
applyFSEvent(null, myInitialFSDelta);
return;
}
if (!dataStorageRoot.exists()) {
// invoked the very first time for this project. Force full rebuild
myBuildType = BuildType.PROJECT_REBUILD;
}
ProjectDescriptor pd = myBuildRunner.load(msgHandler, dataStorageRoot, fsState);
myProjectDescriptor = pd;
final boolean shouldApplyEvent = loadFsState(fsState, dataStorageRoot, myInitialFSDelta, myProjectDescriptor);
if (shouldApplyEvent) {
applyFSEvent(myProjectDescriptor, myInitialFSDelta);
}
@@ -323,7 +321,10 @@ final class BuildSession implements Runnable, CanceledStatus {
}
}
private boolean loadFsState(final BuildFSState fsState, File dataStorageRoot, CmdlineRemoteProto.Message.ControllerMessage.FSEvent initialEvent) {
private boolean loadFsState(final BuildFSState fsState,
File dataStorageRoot,
CmdlineRemoteProto.Message.ControllerMessage.FSEvent initialEvent,
ProjectDescriptor projectDescriptor) {
boolean shouldApplyEvent = false;
final File file = new File(dataStorageRoot, FS_STATE_FILE);
try {
@@ -342,7 +343,7 @@ final class BuildSession implements Runnable, CanceledStatus {
if (version == FSState.VERSION) {
final long savedOrdinal = in.readLong();
if (initialEvent != null && (savedOrdinal + 1L == initialEvent.getOrdinal())) {
fsState.load(in);
fsState.load(in, projectDescriptor);
myLastEventOrdinal = savedOrdinal;
shouldApplyEvent = true;
//applyFSEvent(pd, initialEvent);
@@ -55,7 +55,7 @@ public interface CompileContext extends UserDataHolder, MessageHandler {
long getCompilationStartStamp();
void markNonIncremental(RealModuleBuildTarget target);
void markNonIncremental(ModuleBuildTarget target);
void clearNonIncrementalMark(RealModuleBuildTarget target);
void clearNonIncrementalMark(ModuleBuildTarget target);
}
@@ -141,11 +141,11 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon
}
@Override
public void markNonIncremental(RealModuleBuildTarget target) {
public void markNonIncremental(ModuleBuildTarget target) {
if (!isCompilingTests()) {
myNonIncrementalModules.add(new RealModuleBuildTarget(target.getModule(), JavaModuleBuildTargetType.PRODUCTION));
myNonIncrementalModules.add(new ModuleBuildTarget(target.getModule(), JavaModuleBuildTargetType.PRODUCTION));
}
myNonIncrementalModules.add(new RealModuleBuildTarget(target.getModule(), JavaModuleBuildTargetType.TEST));
myNonIncrementalModules.add(new ModuleBuildTarget(target.getModule(), JavaModuleBuildTargetType.TEST));
}
@Override
@@ -184,7 +184,7 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon
}
@Override
public void clearNonIncrementalMark(RealModuleBuildTarget target) {
public void clearNonIncrementalMark(ModuleBuildTarget target) {
myNonIncrementalModules.remove(target);
}
@@ -53,7 +53,7 @@ public abstract class CompileScope {
public abstract boolean isRecompilationForced(@NotNull BuildTarget target);
public final boolean isAffected(ModuleChunk chunk) {
for (RealModuleBuildTarget target : chunk.getTargets()) {
for (ModuleBuildTarget target : chunk.getTargets()) {
if (isAffected(target)) {
return true;
}
@@ -54,15 +54,15 @@ public class FSOperations {
public static void markDirty(CompileContext context, final ModuleChunk chunk) throws IOException {
final ProjectDescriptor pd = context.getProjectDescriptor();
pd.fsState.clearContextRoundData(context);
for (RealModuleBuildTarget target : chunk.getTargets()) {
for (ModuleBuildTarget target : chunk.getTargets()) {
markDirtyFiles(context, target, pd.timestamps.getStorage(), true, target.isTests() ? DirtyMarkScope.TESTS : DirtyMarkScope.PRODUCTION, null);
}
}
public static void markDirtyRecursively(CompileContext context, ModuleChunk chunk) throws IOException {
Set<JpsModule> modules = chunk.getModules();
Set<RealModuleBuildTarget> targets = chunk.getTargets();
final Set<RealModuleBuildTarget> dirtyTargets = new HashSet<RealModuleBuildTarget>(targets);
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.isTests());
@@ -86,13 +86,13 @@ public class FSOperations {
}
final Timestamps timestamps = context.getProjectDescriptor().timestamps.getStorage();
for (RealModuleBuildTarget target : dirtyTargets) {
for (ModuleBuildTarget target : dirtyTargets) {
markDirtyFiles(context, target, timestamps, true, target.isTests() ? DirtyMarkScope.TESTS : DirtyMarkScope.BOTH, null);
}
if (context.isMake()) {
// mark as non-incremental only the module that triggered non-incremental change
for (RealModuleBuildTarget target : targets) {
for (ModuleBuildTarget target : targets) {
context.markNonIncremental(target);
}
}
@@ -125,7 +125,7 @@ public class FSOperations {
final Condition<JpsModule> moduleFilter,
final FileProcessor processor) throws IOException {
final BuildFSState fsState = context.getProjectDescriptor().fsState;
for (RealModuleBuildTarget target : chunk.getTargets()) {
for (ModuleBuildTarget target : chunk.getTargets()) {
if (moduleFilter.value(target.getModule())) {
fsState.processFilesToRecompile(context, target, processor);
}
@@ -133,7 +133,7 @@ public class FSOperations {
}
static void markDirtyFiles(CompileContext context,
RealModuleBuildTarget target,
ModuleBuildTarget target,
final Timestamps tsStorage,
final boolean forceMarkDirty,
@NotNull final DirtyMarkScope scope,
@@ -600,7 +600,7 @@ public class IncProjectBuilder {
private static void createClasspathIndex(final ModuleChunk chunk) {
final Set<File> outputPaths = new LinkedHashSet<File>();
for (RealModuleBuildTarget target : chunk.getTargets()) {
for (ModuleBuildTarget target : chunk.getTargets()) {
final File outputDir = JpsJavaExtensionService.getInstance().getOutputDirectory(target.getModule(), target.isTests());
if (outputDir != null) {
outputPaths.add(outputDir);
@@ -902,7 +902,7 @@ public class IncProjectBuilder {
if (!Utils.errorsDetected(context) && !context.getCancelStatus().isCanceled()) {
boolean marked = false;
for (RealModuleBuildTarget target : chunk.getTargets()) {
for (ModuleBuildTarget target : chunk.getTargets()) {
if (context.isMake()) {
// ensure non-incremental flag cleared
context.clearNonIncrementalMark(target);
@@ -928,7 +928,7 @@ public class IncProjectBuilder {
private static void ensureFSStateInitialized(CompileContext context, ModuleChunk chunk) throws IOException {
final ProjectDescriptor pd = context.getProjectDescriptor();
final Timestamps timestamps = pd.timestamps.getStorage();
for (RealModuleBuildTarget target : chunk.getTargets()) {
for (ModuleBuildTarget target : chunk.getTargets()) {
if (context.isProjectRebuild()) {
FSOperations.markDirtyFiles(context, target, timestamps, true,
target.isTests() ? FSOperations.DirtyMarkScope.TESTS : FSOperations.DirtyMarkScope.PRODUCTION, null);
@@ -954,7 +954,7 @@ public class IncProjectBuilder {
}
}
private static void initModuleFSState(CompileContext context, RealModuleBuildTarget target) throws IOException {
private static void initModuleFSState(CompileContext context, ModuleBuildTarget target) throws IOException {
boolean forceMarkDirty = false;
final File currentOutput = context.getProjectPaths().getModuleOutputDir(target.getModule(), target.isTests());
final ProjectDescriptor pd = context.getProjectDescriptor();
@@ -987,7 +987,7 @@ public class IncProjectBuilder {
}
}
private static void updateOutputRootsLayout(CompileContext context, RealModuleBuildTarget target) throws IOException {
private static void updateOutputRootsLayout(CompileContext context, ModuleBuildTarget target) throws IOException {
final File currentOutput = context.getProjectPaths().getModuleOutputDir(target.getModule(), target.isTests());
if (currentOutput == null) {
return;
@@ -1,19 +1,28 @@
package org.jetbrains.jps.incremental;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.BuildTarget;
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType;
import org.jetbrains.jps.model.module.JpsModule;
/**
* @author nik
*/
public class ModuleBuildTarget extends BuildTarget {
private final JpsModule myModule;
private final String myModuleName;
private final boolean myTests;
public ModuleBuildTarget(String moduleName, JavaModuleBuildTargetType targetType) {
public ModuleBuildTarget(@NotNull JpsModule module, JavaModuleBuildTargetType targetType) {
super(targetType);
myModuleName = moduleName;
myModuleName = module.getName();
myTests = targetType.isTests();
myModule = module;
}
@NotNull
public JpsModule getModule() {
return myModule;
}
public String getModuleName() {
@@ -51,7 +51,7 @@ public class ModuleRootsIndex {
for (JpsModuleSourceRoot sourceRoot : module.getSourceRoots()) {
final File root = JpsPathUtil.urlToFile(sourceRoot.getUrl());
final boolean testRoot = JavaSourceRootType.TEST_SOURCE.equals(sourceRoot.getRootType());
final RootDescriptor descriptor = new RootDescriptor(moduleName, root, new RealModuleBuildTarget(module, JavaModuleBuildTargetType.getInstance(testRoot)), testRoot, false, false);
final RootDescriptor descriptor = new RootDescriptor(moduleName, root, new ModuleBuildTarget(module, JavaModuleBuildTargetType.getInstance(testRoot)), testRoot, false, false);
myRootToDescriptorMap.put(root, descriptor);
moduleRoots.add(descriptor);
}
@@ -59,7 +59,7 @@ public class ModuleRootsIndex {
final List<String> roots = provider.getAdditionalSourceRoots(module, dataManager);
for (String path : roots) {
File root = new File(path);
final RootDescriptor descriptor = new RootDescriptor(moduleName, root, new RealModuleBuildTarget(module, JavaModuleBuildTargetType.PRODUCTION), false, true, false);
final RootDescriptor descriptor = new RootDescriptor(moduleName, root, new ModuleBuildTarget(module, JavaModuleBuildTargetType.PRODUCTION), false, true, false);
moduleRoots.add(descriptor);
myRootToDescriptorMap.put(root, descriptor);
}
@@ -181,7 +181,7 @@ public class ModuleRootsIndex {
moduleRoots = new ArrayList<RootDescriptor>();
moduleToRootMap.put(module, moduleRoots);
}
final RootDescriptor descriptor = new RootDescriptor(module.getName(), root, new RealModuleBuildTarget(module, JavaModuleBuildTargetType.getInstance(isTestRoot)), isTestRoot, true, true);
final RootDescriptor descriptor = new RootDescriptor(module.getName(), root, new ModuleBuildTarget(module, JavaModuleBuildTargetType.getInstance(isTestRoot)), isTestRoot, true, true);
rootToDescriptorMap.put(root, descriptor);
moduleRoots.add(descriptor);
return descriptor;
@@ -28,8 +28,8 @@ public class ModulesAndFilesScope extends CompileScope {
myFiles = files;
myTargets = new HashSet<BuildTarget>();
for (JpsModule module : targets) {
myTargets.add(new RealModuleBuildTarget(module, JavaModuleBuildTargetType.PRODUCTION));
myTargets.add(new RealModuleBuildTarget(module, JavaModuleBuildTargetType.TEST));
myTargets.add(new ModuleBuildTarget(module, JavaModuleBuildTargetType.PRODUCTION));
myTargets.add(new ModuleBuildTarget(module, JavaModuleBuildTargetType.TEST));
}
}
@@ -28,9 +28,9 @@ public class ModulesScope extends CompileScope {
super(project, jpsProject, artifacts, isForcedCompilation, includeTests);
myTargets = new HashSet<BuildTarget>();
for (JpsModule module : modules) {
myTargets.add(new RealModuleBuildTarget(module, JavaModuleBuildTargetType.PRODUCTION));
myTargets.add(new ModuleBuildTarget(module, JavaModuleBuildTargetType.PRODUCTION));
if (includeTests) {
myTargets.add(new RealModuleBuildTarget(module, JavaModuleBuildTargetType.TEST));
myTargets.add(new ModuleBuildTarget(module, JavaModuleBuildTargetType.TEST));
}
}
}
@@ -1,22 +0,0 @@
package org.jetbrains.jps.incremental;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType;
import org.jetbrains.jps.model.module.JpsModule;
/**
* @author nik
*/
public class RealModuleBuildTarget extends ModuleBuildTarget {
private final JpsModule myModule;
public RealModuleBuildTarget(@NotNull JpsModule module, JavaModuleBuildTargetType targetType) {
super(module.getName(), targetType);
myModule = module;
}
@NotNull
public JpsModule getModule() {
return myModule;
}
}
@@ -26,7 +26,7 @@ import java.util.Set;
*/
public class BuildFSState extends FSState {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.fs.BuildFSState");
private static final Key<Set<RealModuleBuildTarget>> CONTEXT_TARGETS_KEY = Key.create("_fssfate_context_modules_");
private static final Key<Set<ModuleBuildTarget>> CONTEXT_TARGETS_KEY = Key.create("_fssfate_context_modules_");
private static final Key<FilesDelta> CURRENT_ROUND_DELTA_KEY = Key.create("_current_round_delta_");
private static final Key<FilesDelta> LAST_ROUND_DELTA_KEY = Key.create("_last_round_delta_");
@@ -74,7 +74,7 @@ public class BuildFSState extends FSState {
if (context == null) {
return false;
}
Set<? extends ModuleBuildTarget> targets = CONTEXT_TARGETS_KEY.get(context, Collections.<RealModuleBuildTarget>emptySet());
Set<? extends ModuleBuildTarget> targets = CONTEXT_TARGETS_KEY.get(context, Collections.<ModuleBuildTarget>emptySet());
return targets.contains(rd.target);
}
@@ -117,7 +117,7 @@ public class BuildFSState extends FSState {
setRoundDelta(CURRENT_ROUND_DELTA_KEY, context, new FilesDelta());
}
public boolean processFilesToRecompile(CompileContext context, final RealModuleBuildTarget target, final FileProcessor processor) throws IOException {
public boolean processFilesToRecompile(CompileContext context, final ModuleBuildTarget target, final FileProcessor processor) throws IOException {
final Map<File, Set<File>> data = getSourcesToRecompile(context, target);
final CompilerExcludes excludes = context.getProjectDescriptor().project.getCompilerConfiguration().getExcludes();
final CompileScope scope = context.getScope();
@@ -197,7 +197,7 @@ public class BuildFSState extends FSState {
return marked;
}
private static void setContextTargets(@Nullable CompileContext context, @Nullable Set<RealModuleBuildTarget> targets) {
private static void setContextTargets(@Nullable CompileContext context, @Nullable Set<ModuleBuildTarget> targets) {
if (context != null) {
CONTEXT_TARGETS_KEY.set(context, targets);
}
@@ -7,6 +7,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.builders.BuildTarget;
import org.jetbrains.jps.builders.BuildTargetType;
import org.jetbrains.jps.cmdline.ProjectDescriptor;
import org.jetbrains.jps.incremental.BuilderService;
import org.jetbrains.jps.incremental.CompileContext;
import org.jetbrains.jps.incremental.ModuleBuildTarget;
@@ -56,7 +57,7 @@ public class FSState {
}
}
public void load(DataInputStream in) throws IOException {
public void load(DataInputStream in, ProjectDescriptor projectDescriptor) throws IOException {
Map<String, BuildTargetType> types = new HashMap<String, BuildTargetType>();
for (BuilderService service : JpsServiceManager.getInstance().getExtensions(BuilderService.class)) {
for (BuildTargetType type : service.getTargetTypes()) {
@@ -74,13 +75,17 @@ public class FSState {
while (targetCount-- > 0) {
final String id = IOUtil.readString(in);
BuildTargetType type = types.get(typeId);
boolean loaded = false;
if (type != null) {
BuildTarget target = type.createTarget(id);
getDelta(target).load(in);
myInitialScanPerformed.add(target);
BuildTarget target = type.createTarget(id, projectDescriptor);
if (target != null) {
getDelta(target).load(in);
myInitialScanPerformed.add(target);
loaded = true;
}
}
else {
LOG.info("Unknown build type id: " + typeId);
if (!loaded) {
LOG.info("Skipping unknown target (typeId=" + typeId + ", type=" + type + ", id=" + id + ")");
new FilesDelta().load(in);
}
}
@@ -846,7 +846,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
private static Map<File, Set<File>> buildOutputDirectoriesMap(CompileContext context, ModuleChunk chunk) {
final Map<File, Set<File>> map = new LinkedHashMap<File, Set<File>>();
for (RealModuleBuildTarget target : chunk.getTargets()) {
for (ModuleBuildTarget target : chunk.getTargets()) {
final File outputDir = JpsJavaExtensionService.getInstance().getOutputDirectory(target.getModule(), target.isTests());
if (outputDir == null) {
continue;
@@ -181,7 +181,7 @@ public class GroovyBuilder extends ModuleLevelBuilder {
@Nullable private static Map<JpsModule, String> getCanonicalModuleOutputs(CompileContext context, ModuleChunk chunk) {
Map<JpsModule, String> finalOutputs = new HashMap<JpsModule, String>();
for (RealModuleBuildTarget target : chunk.getTargets()) {
for (ModuleBuildTarget target : chunk.getTargets()) {
File moduleOutputDir = context.getProjectPaths().getModuleOutputDir(target.getModule(), target.isTests());
if (moduleOutputDir == null) {
context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, "Output directory not specified for module " + target.getModuleName()));
@@ -297,7 +297,7 @@ public class GroovyBuilder extends ModuleLevelBuilder {
private static Map<String, String> buildClassToSourceMap(ModuleChunk chunk, CompileContext context, Set<String> toCompilePaths, Map<JpsModule, String> finalOutputs) throws IOException {
final Map<String, String> class2Src = new HashMap<String, String>();
for (RealModuleBuildTarget target : chunk.getTargets()) {
for (ModuleBuildTarget target : chunk.getTargets()) {
String moduleOutputPath = finalOutputs.get(target.getModule());
final SourceToOutputMapping srcToOut = context.getProjectDescriptor().dataManager.getSourceToOutputMap(target.getModuleName(), target.isTests());
for (String src : srcToOut.getKeys()) {