IDEA-CR-17317 digest if module ext doesn't implement state tracker

This commit is contained in:
Vladimir Krivosheev
2017-01-23 15:59:29 +01:00
parent 1a895a2315
commit 6d5e2bcf49
3 changed files with 53 additions and 1 deletions
@@ -52,6 +52,9 @@ public class ModifiableModelCommitter {
ModuleRootManagerImpl.doCommit(model);
}
for (ModifiableRootModel model : modelsToDispose) {
if (model instanceof RootModelImpl) {
((RootModelImpl)model).checkModuleExtensionModification();
}
model.dispose();
}
});
@@ -364,7 +364,7 @@ public class ModuleRootManagerImpl extends ModuleRootManager implements Disposab
}
}
private void stateChanged() {
void stateChanged() {
if (Registry.is("store.track.module.root.manager.changes", false)) {
LOG.error("ModelRootManager state changed");
}
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.roots.impl;
import com.intellij.configurationStore.Scheme_implKt;
import com.intellij.configurationStore.SerializationUtilKt;
import com.intellij.openapi.CompositeDisposable;
import com.intellij.openapi.Disposable;
@@ -38,6 +39,7 @@ import com.intellij.util.ArrayUtil;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.xmlb.XmlSerializer;
import gnu.trove.THashMap;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -63,6 +65,8 @@ public class RootModelImpl extends RootModelBase implements ModifiableRootModel
private boolean myDisposed = false;
private final Set<ModuleExtension> myExtensions = new TreeSet<>((o1, o2) -> Comparing.compare(o1.getClass().getName(),
o2.getClass().getName()));
@Nullable
private final Map<ModuleExtension, byte[]> myExtensionToStateDigest;
private final RootConfigurationAccessor myConfigurationAccessor;
@@ -88,6 +92,7 @@ public class RootModelImpl extends RootModelBase implements ModifiableRootModel
myExtensions.add(model);
}
myConfigurationAccessor = new RootConfigurationAccessor();
myExtensionToStateDigest = null;
}
private void addSourceOrderEntries() {
@@ -140,6 +145,7 @@ public class RootModelImpl extends RootModelBase implements ModifiableRootModel
myExtensions.add(model);
}
myConfigurationAccessor = new RootConfigurationAccessor();
myExtensionToStateDigest = null;
}
@Override
@@ -176,10 +182,24 @@ public class RootModelImpl extends RootModelBase implements ModifiableRootModel
setOrderEntriesFrom(rootModel);
myExtensionToStateDigest = writable ? new THashMap<>() : null;
for (ModuleExtension extension : rootModel.myExtensions) {
ModuleExtension model = extension.getModifiableModel(writable);
registerOnDispose(model);
myExtensions.add(model);
if (myExtensionToStateDigest != null && !(extension instanceof PersistentStateComponentWithModificationTracker)) {
Element state = new Element("state");
try {
//noinspection deprecation
extension.writeExternal(state);
myExtensionToStateDigest.put(extension, Scheme_implKt.digest(state));
}
catch (Exception e) {
LOG.warn(e);
}
}
}
}
@@ -654,6 +674,12 @@ public class RootModelImpl extends RootModelBase implements ModifiableRootModel
assert !myDisposed;
Disposer.dispose(myDisposable);
myExtensions.clear();
if (myExtensionToStateDigest != null) {
myExtensionToStateDigest.clear();
}
myWritable = false;
myDisposed = true;
}
@@ -786,4 +812,27 @@ public class RootModelImpl extends RootModelBase implements ModifiableRootModel
void registerOnDispose(@NotNull Disposable disposable) {
myDisposable.add(disposable);
}
void checkModuleExtensionModification() {
if (myExtensionToStateDigest == null || myExtensionToStateDigest.isEmpty()) {
return;
}
for (Map.Entry<ModuleExtension, byte[]> entry : myExtensionToStateDigest.entrySet()) {
Element state = new Element("state");
try {
ModuleExtension extension = entry.getKey();
//noinspection deprecation
extension.writeExternal(state);
byte[] newDigest = Scheme_implKt.digest(state);
if (!Arrays.equals(newDigest, entry.getValue())) {
myModuleRootManager.stateChanged();
return;
}
}
catch (Exception e) {
LOG.warn(e);
}
}
}
}