mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
restore event registration timestamp check to properly handle files changed during compilation
This commit is contained in:
@@ -210,7 +210,7 @@ public class BuildRunner {
|
||||
}
|
||||
fileSet.add(file);
|
||||
if (targetTypesToForceBuild.contains(descriptor.getTarget().getTargetType())) {
|
||||
pd.fsState.markDirty(null, file, descriptor, timestamps);
|
||||
pd.fsState.markDirty(null, file, descriptor, timestamps, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,7 +253,7 @@ final class BuildSession implements Runnable, CanceledStatus {
|
||||
else {
|
||||
// apply events to already loaded state
|
||||
try {
|
||||
applyFSEvent(pd, myInitialFSDelta);
|
||||
applyFSEvent(pd, myInitialFSDelta, false);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
LOG.error(e);
|
||||
@@ -269,7 +269,7 @@ final class BuildSession implements Runnable, CanceledStatus {
|
||||
try {
|
||||
try {
|
||||
fsState.load(fsStateStream, pd.getModel(), pd.getBuildRootIndex());
|
||||
applyFSEvent(pd, myInitialFSDelta);
|
||||
applyFSEvent(pd, myInitialFSDelta, false);
|
||||
TimingLog.LOG.debug("FS Delta loaded");
|
||||
}
|
||||
finally {
|
||||
@@ -349,7 +349,7 @@ final class BuildSession implements Runnable, CanceledStatus {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
applyFSEvent(myProjectDescriptor, event);
|
||||
applyFSEvent(myProjectDescriptor, event, true);
|
||||
myLastEventOrdinal += 1;
|
||||
}
|
||||
catch (IOException e) {
|
||||
@@ -378,7 +378,7 @@ final class BuildSession implements Runnable, CanceledStatus {
|
||||
}
|
||||
}
|
||||
|
||||
private static void applyFSEvent(ProjectDescriptor pd, @Nullable CmdlineRemoteProto.Message.ControllerMessage.FSEvent event) throws IOException {
|
||||
private static void applyFSEvent(ProjectDescriptor pd, @Nullable CmdlineRemoteProto.Message.ControllerMessage.FSEvent event, final boolean saveEventStamp) throws IOException {
|
||||
if (event == null) {
|
||||
return;
|
||||
}
|
||||
@@ -425,7 +425,7 @@ final class BuildSession implements Runnable, CanceledStatus {
|
||||
pd.getFSCache().clear();
|
||||
cacheCleared = true;
|
||||
}
|
||||
pd.fsState.markDirty(null, file, descriptor, timestamps);
|
||||
pd.fsState.markDirty(null, file, descriptor, timestamps, saveEventStamp);
|
||||
}
|
||||
else {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
|
||||
@@ -47,7 +47,7 @@ class ChainedTargetsBuildListener implements BuildListener {
|
||||
Collection<BuildRootDescriptor> descriptors = rootsIndex.findAllParentDescriptors(file, null, myContext);
|
||||
for (BuildRootDescriptor descriptor : descriptors) {
|
||||
try {
|
||||
fsState.markDirty(myContext, file, descriptor, myContext.getProjectDescriptor().timestamps.getStorage());
|
||||
fsState.markDirty(myContext, file, descriptor, myContext.getProjectDescriptor().timestamps.getStorage(), false);
|
||||
}
|
||||
catch (IOException ignored) {
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ public class FSOperations {
|
||||
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());
|
||||
pd.fsState.markDirty(context, round, file, rd, pd.timestamps.getStorage(), false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,7 +245,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, round, file, rd, marker);
|
||||
context.getProjectDescriptor().fsState.markDirty(context, round, file, rd, marker, false);
|
||||
}
|
||||
if (currentFiles != null) {
|
||||
currentFiles.add(file);
|
||||
|
||||
@@ -18,9 +18,11 @@ 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.SmartList;
|
||||
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;
|
||||
@@ -51,6 +53,7 @@ public class BuildFSState {
|
||||
// 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) {
|
||||
@@ -105,6 +108,10 @@ public class BuildFSState {
|
||||
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;
|
||||
@@ -185,11 +192,11 @@ public class BuildFSState {
|
||||
* Note: marked file will well be visible as "dirty" only on the next compilation round!
|
||||
* @throws IOException
|
||||
*/
|
||||
public final boolean markDirty(@Nullable CompileContext context, File file, final BuildRootDescriptor rd, @Nullable Timestamps tsStorage) throws IOException {
|
||||
return markDirty(context, CompilationRound.NEXT, file, rd, tsStorage);
|
||||
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) throws IOException {
|
||||
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);
|
||||
@@ -203,6 +210,9 @@ public class BuildFSState {
|
||||
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());
|
||||
}
|
||||
@@ -248,6 +258,7 @@ public class BuildFSState {
|
||||
clearContextChunk(null);
|
||||
myInitialScanPerformed.clear();
|
||||
myDeltas.clear();
|
||||
myRegistrationStamps.clear();
|
||||
}
|
||||
|
||||
public void clearContextRoundData(@Nullable CompileContext context) {
|
||||
@@ -323,9 +334,12 @@ public class BuildFSState {
|
||||
for (File file : files) {
|
||||
if (scope.isAffected(target, file)) {
|
||||
final long currentFileStamp = FileSystemUtil.lastModified(file);
|
||||
if (!rd.isGenerated() && currentFileStamp > targetBuildStartStamp) {
|
||||
if (!rd.isGenerated() && (currentFileStamp > targetBuildStartStamp || getEventRegistrationStamp(file) > targetBuildStartStamp)) {
|
||||
// if the file was modified after the compilation had started,
|
||||
// do not save the stamp considering file dirty
|
||||
// Important!
|
||||
// Event registration stamp check is essential for the files that were actually changed _before_ targetBuildStart,
|
||||
// but corresponding change event was received and processed _after_ targetBuildStart
|
||||
if (Utils.IS_TEST_MODE) {
|
||||
LOG.info("Timestamp after compilation started; marking dirty again: " + file.getPath());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user