mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-05-06 13:20:53 +07:00
merge BuildFSState and FSState into one class;
explicit API to mark file dirty for the current or the next compilation round
This commit is contained in:
@@ -30,6 +30,7 @@ import org.jetbrains.jps.builders.java.dependencyView.Callbacks;
|
||||
import org.jetbrains.jps.builders.java.dependencyView.Mappings;
|
||||
import org.jetbrains.jps.builders.storage.BuildDataCorruptedException;
|
||||
import org.jetbrains.jps.incremental.*;
|
||||
import org.jetbrains.jps.incremental.fs.CompilationRound;
|
||||
import org.jetbrains.jps.incremental.messages.BuildMessage;
|
||||
import org.jetbrains.jps.incremental.messages.CompilerMessage;
|
||||
import org.jetbrains.jps.incremental.messages.ProgressMessage;
|
||||
@@ -140,7 +141,7 @@ public class JavaBuilderUtil {
|
||||
}
|
||||
|
||||
for (File file : newlyAffectedFiles) {
|
||||
FSOperations.markDirtyIfNotDeleted(context, file);
|
||||
FSOperations.markDirtyIfNotDeleted(context, CompilationRound.NEXT, file);
|
||||
}
|
||||
additionalPassRequired = isCompileJavaIncrementally(context) && chunkContainsAffectedFiles(context, chunk, newlyAffectedFiles);
|
||||
}
|
||||
@@ -151,7 +152,7 @@ public class JavaBuilderUtil {
|
||||
context.processMessage(new ProgressMessage(messageText));
|
||||
|
||||
additionalPassRequired = isCompileJavaIncrementally(context);
|
||||
FSOperations.markDirtyRecursively(context, chunk);
|
||||
FSOperations.markDirtyRecursively(context, CompilationRound.NEXT, chunk);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -43,7 +43,6 @@ import org.jetbrains.jps.incremental.BuilderRegistry;
|
||||
import org.jetbrains.jps.incremental.MessageHandler;
|
||||
import org.jetbrains.jps.incremental.Utils;
|
||||
import org.jetbrains.jps.incremental.fs.BuildFSState;
|
||||
import org.jetbrains.jps.incremental.fs.FSState;
|
||||
import org.jetbrains.jps.incremental.messages.BuildMessage;
|
||||
import org.jetbrains.jps.incremental.storage.BuildTargetsState;
|
||||
import org.jetbrains.jps.service.SharedThreadPool;
|
||||
@@ -154,7 +153,7 @@ public class BuildMain {
|
||||
final DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(fsStateFile)));
|
||||
try {
|
||||
final int version = in.readInt();
|
||||
if (version == FSState.VERSION) {
|
||||
if (version == BuildFSState.VERSION) {
|
||||
final long savedOrdinal = in.readLong();
|
||||
final boolean hasWorkToDo = in.readBoolean();// must skip "has-work-to-do" flag
|
||||
fsState.load(in, pd.getModel(), pd.getBuildRootIndex());
|
||||
|
||||
@@ -36,7 +36,6 @@ import org.jetbrains.jps.incremental.MessageHandler;
|
||||
import org.jetbrains.jps.incremental.TargetTypeRegistry;
|
||||
import org.jetbrains.jps.incremental.Utils;
|
||||
import org.jetbrains.jps.incremental.fs.BuildFSState;
|
||||
import org.jetbrains.jps.incremental.fs.FSState;
|
||||
import org.jetbrains.jps.incremental.messages.*;
|
||||
import org.jetbrains.jps.incremental.storage.Timestamps;
|
||||
import org.jetbrains.jps.model.module.JpsModule;
|
||||
@@ -445,7 +444,7 @@ final class BuildSession implements Runnable, CanceledStatus {
|
||||
final BufferExposingByteArrayOutputStream bytes = new BufferExposingByteArrayOutputStream();
|
||||
final DataOutputStream out = new DataOutputStream(bytes);
|
||||
try {
|
||||
out.writeInt(FSState.VERSION);
|
||||
out.writeInt(BuildFSState.VERSION);
|
||||
out.writeLong(ordinal);
|
||||
out.writeBoolean(false);
|
||||
while (true) {
|
||||
@@ -475,7 +474,7 @@ final class BuildSession implements Runnable, CanceledStatus {
|
||||
final BufferExposingByteArrayOutputStream bytes = new BufferExposingByteArrayOutputStream();
|
||||
final DataOutputStream out = new DataOutputStream(bytes);
|
||||
try {
|
||||
out.writeInt(FSState.VERSION);
|
||||
out.writeInt(BuildFSState.VERSION);
|
||||
out.writeLong(myLastEventOrdinal);
|
||||
out.writeBoolean(hasWorkToDo(state, pd));
|
||||
state.save(out);
|
||||
@@ -542,7 +541,7 @@ final class BuildSession implements Runnable, CanceledStatus {
|
||||
}
|
||||
final DataInputStream in = new DataInputStream(new ByteArrayInputStream(bytes));
|
||||
final int version = in.readInt();
|
||||
if (version != FSState.VERSION) {
|
||||
if (version != BuildFSState.VERSION) {
|
||||
return null;
|
||||
}
|
||||
final long savedOrdinal = in.readLong();
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.jetbrains.jps.builders.logging.ProjectBuilderLogger;
|
||||
import org.jetbrains.jps.builders.storage.SourceToOutputMapping;
|
||||
import org.jetbrains.jps.cmdline.ProjectDescriptor;
|
||||
import org.jetbrains.jps.incremental.fs.BuildFSState;
|
||||
import org.jetbrains.jps.incremental.fs.CompilationRound;
|
||||
import org.jetbrains.jps.incremental.messages.DoneSomethingNotification;
|
||||
import org.jetbrains.jps.incremental.messages.FileDeletedEvent;
|
||||
import org.jetbrains.jps.incremental.storage.BuildDataManager;
|
||||
@@ -49,7 +50,7 @@ public class BuildOperations {
|
||||
final Timestamps timestamps = pd.timestamps.getStorage();
|
||||
final BuildTargetConfiguration configuration = pd.getTargetsState().getTargetConfiguration(target);
|
||||
if (context.isProjectRebuild()) {
|
||||
FSOperations.markDirtyFiles(context, target, timestamps, true, null, null);
|
||||
FSOperations.markDirtyFiles(context, target, CompilationRound.CURRENT, timestamps, true, null, null);
|
||||
pd.fsState.markInitialScanPerformed(target);
|
||||
configuration.save(context);
|
||||
}
|
||||
@@ -68,7 +69,7 @@ public class BuildOperations {
|
||||
final ProjectDescriptor pd = context.getProjectDescriptor();
|
||||
final Timestamps timestamps = pd.timestamps.getStorage();
|
||||
final THashSet<File> currentFiles = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
|
||||
FSOperations.markDirtyFiles(context, target, timestamps, forceMarkDirty, currentFiles, null);
|
||||
FSOperations.markDirtyFiles(context, target, CompilationRound.CURRENT, timestamps, forceMarkDirty, currentFiles, null);
|
||||
|
||||
// handle deleted paths
|
||||
final BuildFSState fsState = pd.fsState;
|
||||
|
||||
@@ -29,7 +29,7 @@ import org.jetbrains.jps.builders.impl.BuildTargetChunk;
|
||||
import org.jetbrains.jps.builders.java.JavaBuilderUtil;
|
||||
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor;
|
||||
import org.jetbrains.jps.cmdline.ProjectDescriptor;
|
||||
import org.jetbrains.jps.incremental.fs.BuildFSState;
|
||||
import org.jetbrains.jps.incremental.fs.CompilationRound;
|
||||
import org.jetbrains.jps.incremental.storage.Timestamps;
|
||||
import org.jetbrains.jps.model.java.JpsJavaClasspathKind;
|
||||
import org.jetbrains.jps.model.java.JpsJavaExtensionService;
|
||||
@@ -50,52 +50,51 @@ public class FSOperations {
|
||||
|
||||
/**
|
||||
* @param context
|
||||
* @param round
|
||||
* @param file
|
||||
* @return true if file is marked as "dirty" in the <b>current</b> compilation round
|
||||
* @return true if file is marked as "dirty" in the specified compilation round
|
||||
* @throws IOException
|
||||
*/
|
||||
public static boolean isMarkedDirty(CompileContext context, final File file) 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, rd, file);
|
||||
return pd.fsState.isMarkedForRecompilation(context, round, rd, file);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated use markDirty(CompileContext context, final CompilationRound round, final File file)
|
||||
*
|
||||
* Note: marked file will well be visible as "dirty" only on the <b>next</b> compilation round!
|
||||
* @throws IOException
|
||||
*
|
||||
*/
|
||||
public static void markDirty(CompileContext context, final File file) throws IOException {
|
||||
markDirty(context, CompilationRound.NEXT, file);
|
||||
}
|
||||
|
||||
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, file, rd, pd.timestamps.getStorage(), false);
|
||||
pd.fsState.markDirty(context, round, file, rd, pd.timestamps.getStorage(), false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: marked file will well be visible as "dirty" for the current compilation round,
|
||||
* all builders that run in this compilation round after the one that marked the file, will see the 'dirty' state.
|
||||
* @throws IOException
|
||||
* @deprecated use markDirtyIfNotDeleted(CompileContext context, final CompilationRound round, final File file)
|
||||
*/
|
||||
public static void markDirtyForCurrentRound(CompileContext context, final File file) throws IOException {
|
||||
final ProjectDescriptor pd = context.getProjectDescriptor();
|
||||
final BuildFSState.CompilationRound previous = pd.fsState.selectTargetRound(context, BuildFSState.CompilationRound.CURRENT);
|
||||
try {
|
||||
markDirty(context, file);
|
||||
}
|
||||
finally {
|
||||
pd.fsState.selectTargetRound(context, previous);
|
||||
}
|
||||
public static void markDirtyIfNotDeleted(CompileContext context, final File file) throws IOException {
|
||||
markDirtyIfNotDeleted(context, CompilationRound.NEXT, file);
|
||||
}
|
||||
|
||||
public static void markDirtyIfNotDeleted(CompileContext context, final File file) throws IOException {
|
||||
public static void markDirtyIfNotDeleted(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.markDirtyIfNotDeleted(context, file, rd, pd.timestamps.getStorage());
|
||||
pd.fsState.markDirtyIfNotDeleted(context, round, file, rd, pd.timestamps.getStorage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,30 +106,28 @@ public class FSOperations {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use markDirty(CompileContext context, final CompilationRound round, final ModuleChunk chunk, @Nullable FileFilter filter)
|
||||
*/
|
||||
public static void markDirty(CompileContext context, final ModuleChunk chunk, @Nullable FileFilter filter) throws IOException {
|
||||
markDirty(context, CompilationRound.NEXT, chunk, filter);
|
||||
}
|
||||
|
||||
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, pd.timestamps.getStorage(), true, null, filter);
|
||||
markDirtyFiles(context, target, round, pd.timestamps.getStorage(), true, null, filter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: marked files will be visible as "dirty" for the current compilation round,
|
||||
* all builders that run in this compilation round after the one that marked files, will see the 'dirty' state.
|
||||
* @throws IOException
|
||||
* @deprecated use markDirtyRecursively(CompileContext context, final CompilationRound round, ModuleChunk chunk)
|
||||
*/
|
||||
public static void markDirtyForCurrentRound(CompileContext context, final ModuleChunk chunk, @Nullable FileFilter filter) throws IOException {
|
||||
final ProjectDescriptor pd = context.getProjectDescriptor();
|
||||
final BuildFSState.CompilationRound previous = pd.fsState.selectTargetRound(context, BuildFSState.CompilationRound.CURRENT);
|
||||
try {
|
||||
markDirty(context, chunk, filter);
|
||||
}
|
||||
finally {
|
||||
pd.fsState.selectTargetRound(context, previous);
|
||||
}
|
||||
public static void markDirtyRecursively(CompileContext context, ModuleChunk chunk) throws IOException {
|
||||
markDirtyRecursively(context, CompilationRound.NEXT, chunk);
|
||||
}
|
||||
|
||||
public static void markDirtyRecursively(CompileContext context, ModuleChunk chunk) throws IOException {
|
||||
public static void markDirtyRecursively(CompileContext context, final CompilationRound round, ModuleChunk chunk) throws IOException {
|
||||
Set<JpsModule> modules = chunk.getModules();
|
||||
Set<ModuleBuildTarget> targets = chunk.getTargets();
|
||||
final Set<ModuleBuildTarget> dirtyTargets = new HashSet<ModuleBuildTarget>(targets);
|
||||
@@ -163,7 +160,7 @@ public class FSOperations {
|
||||
|
||||
final Timestamps timestamps = context.getProjectDescriptor().timestamps.getStorage();
|
||||
for (ModuleBuildTarget target : dirtyTargets) {
|
||||
markDirtyFiles(context, target, timestamps, true, null, null);
|
||||
markDirtyFiles(context, target, round, timestamps, true, null, null);
|
||||
}
|
||||
|
||||
if (JavaBuilderUtil.isCompileJavaIncrementally(context)) {
|
||||
@@ -173,17 +170,7 @@ public class FSOperations {
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void markDirtyRecursivelyForCurrentRound(CompileContext context, ModuleChunk chunk) throws IOException {
|
||||
final ProjectDescriptor pd = context.getProjectDescriptor();
|
||||
final BuildFSState.CompilationRound previous = pd.fsState.selectTargetRound(context, BuildFSState.CompilationRound.CURRENT);
|
||||
try {
|
||||
markDirtyRecursively(context, chunk);
|
||||
}
|
||||
finally {
|
||||
pd.fsState.selectTargetRound(context, previous);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static Set<JpsModule> getDependentModulesRecursively(final JpsModule module, final JpsJavaClasspathKind kind) {
|
||||
return JpsJavaExtensionService.dependencies(module).includedIn(kind).recursivelyExportedOnly().getModules();
|
||||
}
|
||||
@@ -200,6 +187,7 @@ public class FSOperations {
|
||||
|
||||
static void markDirtyFiles(CompileContext context,
|
||||
BuildTarget<?> target,
|
||||
final CompilationRound round,
|
||||
Timestamps timestamps,
|
||||
boolean forceMarkDirty,
|
||||
@Nullable THashSet<File> currentFiles,
|
||||
@@ -214,12 +202,13 @@ public class FSOperations {
|
||||
context.getProjectDescriptor().fsState.clearRecompile(rd);
|
||||
}
|
||||
final FSCache fsCache = rd.canUseFileCache() ? context.getProjectDescriptor().getFSCache() : FSCache.NO_CACHE;
|
||||
traverseRecursively(context, rd, rd.getRootFile(), timestamps, forceMarkDirty, currentFiles, filter, fsCache);
|
||||
traverseRecursively(context, rd, round, rd.getRootFile(), timestamps, forceMarkDirty, currentFiles, filter, fsCache);
|
||||
}
|
||||
}
|
||||
|
||||
private static void traverseRecursively(CompileContext context,
|
||||
final BuildRootDescriptor rd,
|
||||
final CompilationRound round,
|
||||
final File file,
|
||||
@NotNull final Timestamps tsStorage,
|
||||
final boolean forceDirty,
|
||||
@@ -229,7 +218,7 @@ public class FSOperations {
|
||||
if (children != null) { // is directory
|
||||
if (children.length > 0 && rootIndex.isDirectoryAccepted(file, rd)) {
|
||||
for (File child : children) {
|
||||
traverseRecursively(context, rd, child, tsStorage, forceDirty, currentFiles, filter, fsCache);
|
||||
traverseRecursively(context, rd, round, child, tsStorage, forceDirty, currentFiles, filter, fsCache);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -243,7 +232,7 @@ public class FSOperations {
|
||||
// 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, false);
|
||||
context.getProjectDescriptor().fsState.markDirty(context, round, file, rd, marker, false);
|
||||
}
|
||||
if (currentFiles != null) {
|
||||
currentFiles.add(file);
|
||||
|
||||
@@ -49,6 +49,7 @@ import org.jetbrains.jps.builders.storage.SourceToOutputMapping;
|
||||
import org.jetbrains.jps.cmdline.BuildRunner;
|
||||
import org.jetbrains.jps.cmdline.ProjectDescriptor;
|
||||
import org.jetbrains.jps.incremental.fs.BuildFSState;
|
||||
import org.jetbrains.jps.incremental.fs.CompilationRound;
|
||||
import org.jetbrains.jps.incremental.messages.*;
|
||||
import org.jetbrains.jps.incremental.storage.BuildTargetConfiguration;
|
||||
import org.jetbrains.jps.incremental.storage.OneToManyPathsMapping;
|
||||
@@ -1048,7 +1049,7 @@ public class IncProjectBuilder {
|
||||
for (String formPath : boundForms) {
|
||||
final File formFile = new File(formPath);
|
||||
if (formFile.exists()) {
|
||||
FSOperations.markDirty(context, formFile);
|
||||
FSOperations.markDirty(context, CompilationRound.CURRENT, formFile);
|
||||
}
|
||||
}
|
||||
sourceToFormMap.remove(deletedSource);
|
||||
@@ -1163,7 +1164,7 @@ public class IncProjectBuilder {
|
||||
try {
|
||||
// forcibly mark all files in the chunk dirty
|
||||
context.getProjectDescriptor().fsState.clearContextRoundData(context);
|
||||
FSOperations.markDirty(context, chunk, null);
|
||||
FSOperations.markDirty(context, CompilationRound.NEXT, chunk, null);
|
||||
// reverting to the beginning
|
||||
myTargetsProcessed -= (buildersPassed * modulesInChunk) / stageCount;
|
||||
stageCount = myTotalModuleLevelBuilderCount;
|
||||
|
||||
@@ -18,61 +18,154 @@ package org.jetbrains.jps.incremental.fs;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.io.FileSystemUtil;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.util.io.IOUtil;
|
||||
import gnu.trove.TObjectLongHashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.ModuleChunk;
|
||||
import org.jetbrains.jps.builders.BuildRootDescriptor;
|
||||
import org.jetbrains.jps.builders.BuildTarget;
|
||||
import org.jetbrains.jps.builders.FileProcessor;
|
||||
import org.jetbrains.jps.builders.*;
|
||||
import org.jetbrains.jps.builders.impl.BuildTargetChunk;
|
||||
import org.jetbrains.jps.incremental.CompileContext;
|
||||
import org.jetbrains.jps.incremental.CompileScope;
|
||||
import org.jetbrains.jps.incremental.ModuleBuildTarget;
|
||||
import org.jetbrains.jps.incremental.Utils;
|
||||
import org.jetbrains.jps.incremental.*;
|
||||
import org.jetbrains.jps.incremental.storage.Timestamps;
|
||||
import org.jetbrains.jps.model.JpsModel;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutput;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: 12/16/11
|
||||
*/
|
||||
public class BuildFSState extends FSState {
|
||||
public class BuildFSState {
|
||||
public static final int VERSION = 3;
|
||||
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.fs.BuildFSState");
|
||||
private static final Key<Set<? extends BuildTarget<?>>> CONTEXT_TARGETS_KEY = Key.create("_fssfate_context_targets_");
|
||||
private static final Key<Key<FilesDelta>> DELTA_KEY_SELECTOR = Key.create("_round_delta_key_selector_");
|
||||
private static final Key<FilesDelta> NEXT_ROUND_DELTA_KEY = Key.create("_current_round_delta_");
|
||||
private static final Key<FilesDelta> CURRENT_ROUND_DELTA_KEY = Key.create("_last_round_delta_");
|
||||
|
||||
// when true, will always determine dirty files by scanning FS and comparing timestamps
|
||||
// alternatively, when false, after first scan will rely on external notifications about changes
|
||||
private final boolean myAlwaysScanFS;
|
||||
private final Set<BuildTarget<?>> myInitialScanPerformed = Collections.synchronizedSet(new HashSet<BuildTarget<?>>());
|
||||
private final TObjectLongHashMap<File> myRegistrationStamps = new TObjectLongHashMap<File>(FileUtil.FILE_HASHING_STRATEGY);
|
||||
private final Map<BuildTarget<?>, FilesDelta> myDeltas = Collections.synchronizedMap(new HashMap<BuildTarget<?>, FilesDelta>());
|
||||
|
||||
public BuildFSState(boolean alwaysScanFS) {
|
||||
myAlwaysScanFS = alwaysScanFS;
|
||||
}
|
||||
|
||||
public enum CompilationRound {CURRENT, NEXT}
|
||||
|
||||
public CompilationRound selectTargetRound(CompileContext context, CompilationRound targetRound) {
|
||||
final Key<FilesDelta> previous = DELTA_KEY_SELECTOR.get(context);
|
||||
DELTA_KEY_SELECTOR.set(context, targetRound == CompilationRound.CURRENT? CURRENT_ROUND_DELTA_KEY : null);
|
||||
if (previous == null) {
|
||||
return CompilationRound.NEXT;
|
||||
public void save(DataOutput out) throws IOException {
|
||||
MultiMap<BuildTargetType<?>, BuildTarget<?>> targetsByType = new MultiMap<BuildTargetType<?>, BuildTarget<?>>();
|
||||
for (BuildTarget<?> target : myInitialScanPerformed) {
|
||||
targetsByType.putValue(target.getTargetType(), target);
|
||||
}
|
||||
out.writeInt(targetsByType.size());
|
||||
for (BuildTargetType<?> type : targetsByType.keySet()) {
|
||||
IOUtil.writeString(type.getTypeId(), out);
|
||||
Collection<BuildTarget<?>> targets = targetsByType.get(type);
|
||||
out.writeInt(targets.size());
|
||||
for (BuildTarget<?> target : targets) {
|
||||
IOUtil.writeString(target.getId(), out);
|
||||
getDelta(target).save(out);
|
||||
}
|
||||
}
|
||||
return previous == NEXT_ROUND_DELTA_KEY? CompilationRound.NEXT : CompilationRound.CURRENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInitialScanPerformed(BuildTarget<?> target) {
|
||||
return !myAlwaysScanFS && super.isInitialScanPerformed(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(DataInputStream in, JpsModel model, final BuildRootIndex buildRootIndex) throws IOException {
|
||||
final TargetTypeRegistry registry = TargetTypeRegistry.getInstance();
|
||||
int typeCount = in.readInt();
|
||||
while (typeCount-- > 0) {
|
||||
final String typeId = IOUtil.readString(in);
|
||||
int targetCount = in.readInt();
|
||||
BuildTargetType<?> type = registry.getTargetType(typeId);
|
||||
BuildTargetLoader<?> loader = type != null ? type.createLoader(model) : null;
|
||||
while (targetCount-- > 0) {
|
||||
final String id = IOUtil.readString(in);
|
||||
boolean loaded = false;
|
||||
if (loader != null) {
|
||||
BuildTarget<?> target = loader.createTarget(id);
|
||||
if (target != null) {
|
||||
getDelta(target).load(in, target, buildRootIndex);
|
||||
myInitialScanPerformed.add(target);
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
if (!loaded) {
|
||||
LOG.info("Skipping unknown target (typeId=" + typeId + ", type=" + type + ", id=" + id + ")");
|
||||
FilesDelta.skip(in);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final void clearRecompile(final BuildRootDescriptor rd) {
|
||||
getDelta(rd.getTarget()).clearRecompile(rd);
|
||||
}
|
||||
|
||||
public long getEventRegistrationStamp(File file) {
|
||||
return myRegistrationStamps.get(file);
|
||||
}
|
||||
|
||||
public boolean hasWorkToDo(BuildTarget<?> target) {
|
||||
if (!myInitialScanPerformed.contains(target)) {
|
||||
return true;
|
||||
}
|
||||
FilesDelta delta = myDeltas.get(target);
|
||||
return delta != null && delta.hasChanges();
|
||||
}
|
||||
|
||||
public void markInitialScanPerformed(BuildTarget<?> target) {
|
||||
myInitialScanPerformed.add(target);
|
||||
}
|
||||
|
||||
public void registerDeleted(BuildTarget<?> target, final File file, @Nullable Timestamps tsStorage) throws IOException {
|
||||
registerDeleted(target, file);
|
||||
if (tsStorage != null) {
|
||||
tsStorage.removeStamp(file, target);
|
||||
}
|
||||
}
|
||||
|
||||
public void registerDeleted(BuildTarget<?> target, File file) {
|
||||
getDelta(target).addDeleted(file);
|
||||
}
|
||||
|
||||
public void clearDeletedPaths(BuildTarget<?> target) {
|
||||
final FilesDelta delta = myDeltas.get(target);
|
||||
if (delta != null) {
|
||||
delta.clearDeletedPaths();
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<String> getAndClearDeletedPaths(BuildTarget<?> target) {
|
||||
final FilesDelta delta = myDeltas.get(target);
|
||||
if (delta != null) {
|
||||
return delta.getAndClearDeletedPaths();
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private FilesDelta getDelta(BuildTarget<?> buildTarget) {
|
||||
synchronized (myDeltas) {
|
||||
FilesDelta delta = myDeltas.get(buildTarget);
|
||||
if (delta == null) {
|
||||
delta = new FilesDelta();
|
||||
myDeltas.put(buildTarget, delta);
|
||||
}
|
||||
return delta;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean isInitialScanPerformed(BuildTarget<?> target) {
|
||||
return !myAlwaysScanFS && myInitialScanPerformed.contains(target);
|
||||
}
|
||||
|
||||
public Map<BuildRootDescriptor, Set<File>> getSourcesToRecompile(@NotNull CompileContext context, BuildTarget<?> target) {
|
||||
if (target instanceof ModuleBuildTarget) {
|
||||
// multiple compilation rounds are applicable to ModuleBuildTarget only
|
||||
@@ -81,11 +174,11 @@ public class BuildFSState extends FSState {
|
||||
return lastRoundDelta.getSourcesToRecompile();
|
||||
}
|
||||
}
|
||||
return super.getSourcesToRecompile(context, target);
|
||||
return getDelta(target).getSourcesToRecompile();
|
||||
}
|
||||
|
||||
public boolean isMarkedForRecompilation(@Nullable CompileContext context, BuildRootDescriptor rd, File file) {
|
||||
FilesDelta delta = getRoundDelta(CURRENT_ROUND_DELTA_KEY, context);
|
||||
public boolean isMarkedForRecompilation(@Nullable CompileContext context, CompilationRound round, BuildRootDescriptor rd, File file) {
|
||||
FilesDelta delta = getRoundDelta(round == CompilationRound.NEXT? NEXT_ROUND_DELTA_KEY : CURRENT_ROUND_DELTA_KEY, context);
|
||||
if (delta == null) {
|
||||
delta = getDelta(rd.getTarget());
|
||||
}
|
||||
@@ -102,14 +195,34 @@ public class BuildFSState extends FSState {
|
||||
* Note: marked file will well be visible as "dirty" only on the next compilation round!
|
||||
* @throws IOException
|
||||
*/
|
||||
@Override
|
||||
public boolean markDirty(@Nullable CompileContext context, File file, final BuildRootDescriptor rd, @Nullable Timestamps tsStorage, boolean saveEventStamp) throws IOException {
|
||||
final Key<FilesDelta> deltaKey = DELTA_KEY_SELECTOR.get(context, NEXT_ROUND_DELTA_KEY);
|
||||
final FilesDelta roundDelta = getRoundDelta(deltaKey, context);
|
||||
public final boolean markDirty(@Nullable CompileContext context, File file, final BuildRootDescriptor rd, @Nullable Timestamps tsStorage, boolean saveEventStamp) throws IOException {
|
||||
return markDirty(context, CompilationRound.NEXT, file, rd, tsStorage, saveEventStamp);
|
||||
}
|
||||
|
||||
public boolean markDirty(@Nullable CompileContext context, CompilationRound round, File file, final BuildRootDescriptor rd, @Nullable Timestamps tsStorage, boolean saveEventStamp) throws IOException {
|
||||
final FilesDelta roundDelta = getRoundDelta(round == CompilationRound.NEXT? NEXT_ROUND_DELTA_KEY : CURRENT_ROUND_DELTA_KEY, context);
|
||||
if (roundDelta != null && isInCurrentContextTargets(context, rd)) {
|
||||
roundDelta.markRecompile(rd, file);
|
||||
}
|
||||
return super.markDirty(context, file, rd, tsStorage, saveEventStamp);
|
||||
|
||||
final boolean marked = getDelta(rd.getTarget()).markRecompile(rd, file);
|
||||
if (marked) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(rd.getTarget() + ": MARKED DIRTY: " + file.getPath());
|
||||
}
|
||||
if (saveEventStamp) {
|
||||
myRegistrationStamps.put(file, System.currentTimeMillis());
|
||||
}
|
||||
if (tsStorage != null) {
|
||||
tsStorage.removeStamp(file, rd.getTarget());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(rd.getTarget() + ": NOT MARKED DIRTY: " + file.getPath());
|
||||
}
|
||||
}
|
||||
return marked;
|
||||
}
|
||||
|
||||
private static boolean isInCurrentContextTargets(CompileContext context, BuildRootDescriptor rd) {
|
||||
@@ -120,12 +233,13 @@ public class BuildFSState extends FSState {
|
||||
return targets.contains(rd.getTarget());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean markDirtyIfNotDeleted(@Nullable CompileContext context, File file, final BuildRootDescriptor rd, @Nullable Timestamps tsStorage) throws IOException {
|
||||
final boolean marked = super.markDirtyIfNotDeleted(context, file, rd, tsStorage);
|
||||
public boolean markDirtyIfNotDeleted(@Nullable CompileContext context, CompilationRound round, File file, final BuildRootDescriptor rd, @Nullable Timestamps tsStorage) throws IOException {
|
||||
final boolean marked = getDelta(rd.getTarget()).markRecompileIfNotDeleted(rd, file);
|
||||
if (marked && tsStorage != null) {
|
||||
tsStorage.removeStamp(file, rd.getTarget());
|
||||
}
|
||||
if (marked) {
|
||||
final Key<FilesDelta> deltaKey = DELTA_KEY_SELECTOR.get(context, NEXT_ROUND_DELTA_KEY);
|
||||
final FilesDelta roundDelta = getRoundDelta(deltaKey, context);
|
||||
final FilesDelta roundDelta = getRoundDelta(round == CompilationRound.NEXT? NEXT_ROUND_DELTA_KEY : CURRENT_ROUND_DELTA_KEY, context);
|
||||
if (roundDelta != null) {
|
||||
if (isInCurrentContextTargets(context, rd)) {
|
||||
roundDelta.markRecompile(rd, file);
|
||||
@@ -138,7 +252,9 @@ public class BuildFSState extends FSState {
|
||||
public void clearAll() {
|
||||
clearContextRoundData(null);
|
||||
clearContextChunk(null);
|
||||
super.clearAll();
|
||||
myInitialScanPerformed.clear();
|
||||
myDeltas.clear();
|
||||
myRegistrationStamps.clear();
|
||||
}
|
||||
|
||||
public void clearContextRoundData(@Nullable CompileContext context) {
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.jps.incremental.fs;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: 22-Nov-14
|
||||
*/
|
||||
public enum CompilationRound {
|
||||
CURRENT, NEXT
|
||||
}
|
||||
@@ -1,193 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.jps.incremental.fs;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.util.io.IOUtil;
|
||||
import gnu.trove.TObjectLongHashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.builders.*;
|
||||
import org.jetbrains.jps.incremental.CompileContext;
|
||||
import org.jetbrains.jps.incremental.TargetTypeRegistry;
|
||||
import org.jetbrains.jps.incremental.storage.Timestamps;
|
||||
import org.jetbrains.jps.model.JpsModel;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutput;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: 4/20/12
|
||||
*/
|
||||
public class FSState {
|
||||
public static final int VERSION = 3;
|
||||
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.fs.FSState");
|
||||
private final Map<BuildTarget<?>, FilesDelta> myDeltas = Collections.synchronizedMap(new HashMap<BuildTarget<?>, FilesDelta>());
|
||||
private final Set<BuildTarget<?>> myInitialScanPerformed = Collections.synchronizedSet(new HashSet<BuildTarget<?>>());
|
||||
private final TObjectLongHashMap<File> myRegistrationStamps = new TObjectLongHashMap<File>(FileUtil.FILE_HASHING_STRATEGY);
|
||||
|
||||
public void save(DataOutput out) throws IOException {
|
||||
MultiMap<BuildTargetType<?>, BuildTarget<?>> targetsByType = new MultiMap<BuildTargetType<?>, BuildTarget<?>>();
|
||||
for (BuildTarget<?> target : myInitialScanPerformed) {
|
||||
targetsByType.putValue(target.getTargetType(), target);
|
||||
}
|
||||
out.writeInt(targetsByType.size());
|
||||
for (BuildTargetType<?> type : targetsByType.keySet()) {
|
||||
IOUtil.writeString(type.getTypeId(), out);
|
||||
Collection<BuildTarget<?>> targets = targetsByType.get(type);
|
||||
out.writeInt(targets.size());
|
||||
for (BuildTarget<?> target : targets) {
|
||||
IOUtil.writeString(target.getId(), out);
|
||||
getDelta(target).save(out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void load(DataInputStream in, JpsModel model, final BuildRootIndex buildRootIndex) throws IOException {
|
||||
final TargetTypeRegistry registry = TargetTypeRegistry.getInstance();
|
||||
int typeCount = in.readInt();
|
||||
while (typeCount-- > 0) {
|
||||
final String typeId = IOUtil.readString(in);
|
||||
int targetCount = in.readInt();
|
||||
BuildTargetType<?> type = registry.getTargetType(typeId);
|
||||
BuildTargetLoader<?> loader = type != null ? type.createLoader(model) : null;
|
||||
while (targetCount-- > 0) {
|
||||
final String id = IOUtil.readString(in);
|
||||
boolean loaded = false;
|
||||
if (loader != null) {
|
||||
BuildTarget<?> target = loader.createTarget(id);
|
||||
if (target != null) {
|
||||
getDelta(target).load(in, target, buildRootIndex);
|
||||
myInitialScanPerformed.add(target);
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
if (!loaded) {
|
||||
LOG.info("Skipping unknown target (typeId=" + typeId + ", type=" + type + ", id=" + id + ")");
|
||||
FilesDelta.skip(in);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void clearAll() {
|
||||
myInitialScanPerformed.clear();
|
||||
myDeltas.clear();
|
||||
myRegistrationStamps.clear();
|
||||
}
|
||||
|
||||
public final void clearRecompile(final BuildRootDescriptor rd) {
|
||||
getDelta(rd.getTarget()).clearRecompile(rd);
|
||||
}
|
||||
|
||||
public boolean markDirty(@Nullable CompileContext context, final File file, final BuildRootDescriptor rd, final @Nullable Timestamps tsStorage, boolean saveEventStamp) throws IOException {
|
||||
final boolean marked = getDelta(rd.getTarget()).markRecompile(rd, file);
|
||||
if (marked) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(rd.getTarget() + ": MARKED DIRTY: " + file.getPath());
|
||||
}
|
||||
if (saveEventStamp) {
|
||||
myRegistrationStamps.put(file, System.currentTimeMillis());
|
||||
}
|
||||
if (tsStorage != null) {
|
||||
tsStorage.removeStamp(file, rd.getTarget());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(rd.getTarget() + ": NOT MARKED DIRTY: " + file.getPath());
|
||||
}
|
||||
}
|
||||
return marked;
|
||||
}
|
||||
|
||||
public long getEventRegistrationStamp(File file) {
|
||||
return myRegistrationStamps.get(file);
|
||||
}
|
||||
|
||||
public boolean markDirtyIfNotDeleted(@Nullable CompileContext context,
|
||||
final File file,
|
||||
final BuildRootDescriptor rd,
|
||||
final @Nullable Timestamps tsStorage) throws IOException {
|
||||
final boolean marked = getDelta(rd.getTarget()).markRecompileIfNotDeleted(rd, file);
|
||||
if (marked && tsStorage != null) {
|
||||
tsStorage.removeStamp(file, rd.getTarget());
|
||||
}
|
||||
return marked;
|
||||
}
|
||||
|
||||
public void registerDeleted(BuildTarget<?> target, final File file, @Nullable Timestamps tsStorage) throws IOException {
|
||||
registerDeleted(target, file);
|
||||
if (tsStorage != null) {
|
||||
tsStorage.removeStamp(file, target);
|
||||
}
|
||||
}
|
||||
|
||||
public void registerDeleted(BuildTarget<?> target, File file) {
|
||||
getDelta(target).addDeleted(file);
|
||||
}
|
||||
|
||||
public Map<BuildRootDescriptor, Set<File>> getSourcesToRecompile(@NotNull CompileContext context, BuildTarget<?> target) {
|
||||
return getDelta(target).getSourcesToRecompile();
|
||||
}
|
||||
|
||||
public void clearDeletedPaths(BuildTarget<?> target) {
|
||||
final FilesDelta delta = myDeltas.get(target);
|
||||
if (delta != null) {
|
||||
delta.clearDeletedPaths();
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<String> getAndClearDeletedPaths(BuildTarget<?> target) {
|
||||
final FilesDelta delta = myDeltas.get(target);
|
||||
if (delta != null) {
|
||||
return delta.getAndClearDeletedPaths();
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected final FilesDelta getDelta(BuildTarget<?> buildTarget) {
|
||||
synchronized (myDeltas) {
|
||||
FilesDelta delta = myDeltas.get(buildTarget);
|
||||
if (delta == null) {
|
||||
delta = new FilesDelta();
|
||||
myDeltas.put(buildTarget, delta);
|
||||
}
|
||||
return delta;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasWorkToDo(BuildTarget<?> target) {
|
||||
if (!myInitialScanPerformed.contains(target)) return true;
|
||||
FilesDelta delta = myDeltas.get(target);
|
||||
return delta != null && delta.hasChanges();
|
||||
}
|
||||
|
||||
public void markInitialScanPerformed(BuildTarget<?> target) {
|
||||
myInitialScanPerformed.add(target);
|
||||
}
|
||||
|
||||
public boolean isInitialScanPerformed(BuildTarget<?> target) {
|
||||
return myInitialScanPerformed.contains(target);
|
||||
}
|
||||
}
|
||||
@@ -45,6 +45,7 @@ import org.jetbrains.jps.builders.storage.SourceToOutputMapping;
|
||||
import org.jetbrains.jps.cmdline.ClasspathBootstrap;
|
||||
import org.jetbrains.jps.cmdline.ProjectDescriptor;
|
||||
import org.jetbrains.jps.incremental.*;
|
||||
import org.jetbrains.jps.incremental.fs.CompilationRound;
|
||||
import org.jetbrains.jps.incremental.java.ClassPostProcessor;
|
||||
import org.jetbrains.jps.incremental.java.JavaBuilder;
|
||||
import org.jetbrains.jps.incremental.messages.BuildMessage;
|
||||
@@ -568,8 +569,8 @@ public class GroovyBuilder extends ModuleLevelBuilder {
|
||||
}
|
||||
try {
|
||||
final File groovyFile = new File(groovy);
|
||||
if (!FSOperations.isMarkedDirty(context, groovyFile)) {
|
||||
FSOperations.markDirty(context, groovyFile);
|
||||
if (!FSOperations.isMarkedDirty(context, CompilationRound.CURRENT, groovyFile)) {
|
||||
FSOperations.markDirty(context, CompilationRound.NEXT, groovyFile);
|
||||
FILES_MARKED_DIRTY_FOR_NEXT_ROUND.set(context, Boolean.TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.jetbrains.jps.builders.FileProcessor;
|
||||
import org.jetbrains.jps.builders.java.JavaBuilderUtil;
|
||||
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor;
|
||||
import org.jetbrains.jps.incremental.*;
|
||||
import org.jetbrains.jps.incremental.fs.CompilationRound;
|
||||
import org.jetbrains.jps.incremental.java.CopyResourcesUtil;
|
||||
import org.jetbrains.jps.incremental.java.FormsParsing;
|
||||
import org.jetbrains.jps.incremental.storage.OneToManyPathsMapping;
|
||||
@@ -89,7 +90,7 @@ public class FormsBindingManager extends FormsBuilder {
|
||||
|
||||
@Override
|
||||
public List<String> getCompilableFileExtensions() {
|
||||
return Arrays.asList(FORM_EXTENSION);
|
||||
return Collections.singletonList(FORM_EXTENSION);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -110,7 +111,7 @@ public class FormsBindingManager extends FormsBuilder {
|
||||
// force compilation of all forms, but only once per chunk
|
||||
if (!FORMS_REBUILD_FORCED.get(context, Boolean.FALSE)) {
|
||||
FORMS_REBUILD_FORCED.set(context, Boolean.TRUE);
|
||||
FSOperations.markDirtyForCurrentRound(context, chunk, FORM_SOURCES_FILTER);
|
||||
FSOperations.markDirty(context, CompilationRound.CURRENT, chunk, FORM_SOURCES_FILTER);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +139,7 @@ public class FormsBindingManager extends FormsBuilder {
|
||||
for (File boundSource : sources) {
|
||||
if (!excludes.isExcluded(boundSource)) {
|
||||
addBinding(boundSource, form, srcToForms);
|
||||
FSOperations.markDirtyForCurrentRound(context, boundSource);
|
||||
FSOperations.markDirty(context, CompilationRound.CURRENT, boundSource);
|
||||
filesToCompile.put(boundSource, target);
|
||||
exitCode = ExitCode.OK;
|
||||
}
|
||||
@@ -156,7 +157,7 @@ public class FormsBindingManager extends FormsBuilder {
|
||||
final File formFile = new File(formPath);
|
||||
if (!excludes.isExcluded(formFile) && formFile.exists()) {
|
||||
addBinding(srcFile, formFile, srcToForms);
|
||||
FSOperations.markDirtyForCurrentRound(context, formFile);
|
||||
FSOperations.markDirty(context, CompilationRound.CURRENT, formFile);
|
||||
formsToCompile.put(formFile, target);
|
||||
exitCode = ExitCode.OK;
|
||||
}
|
||||
@@ -245,7 +246,7 @@ public class FormsBindingManager extends FormsBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NotNull
|
||||
private static Collection<File> findPossibleSourcesForClass(JavaSourceRootDescriptor rd, final @Nullable String boundClassName) throws IOException {
|
||||
if (boundClassName == null) {
|
||||
return Collections.emptyList();
|
||||
|
||||
Reference in New Issue
Block a user