package jetbrains.mps.vcs.changesmanager;
/*Generated by MPS */
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
import com.intellij.openapi.project.Project;
import org.jetbrains.mps.openapi.model.EditableSModel;
import jetbrains.mps.smodel.event.SModelCommandListener;
import com.intellij.util.containers.BidirectionalMultiMap;
import org.jetbrains.mps.openapi.model.SNodeId;
import jetbrains.mps.vcs.diff.changes.ModelChange;
import java.util.Set;
import jetbrains.mps.internal.collections.runtime.SetSequence;
import java.util.HashSet;
import com.intellij.util.containers.BidirectionalMap;
import jetbrains.mps.baseLanguage.tuples.runtime.Tuples;
import java.util.List;
import com.intellij.openapi.vcs.FileStatus;
import org.jetbrains.annotations.NotNull;
import jetbrains.mps.vcs.diff.changes.MetadataChange;
import jetbrains.mps.vcs.diff.changes.AddRootChange;
import jetbrains.mps.internal.collections.runtime.MapSequence;
import jetbrains.mps.vcs.diff.changes.NodeGroupChange;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import jetbrains.mps.vcs.platform.util.ConflictsUtil;
import org.jetbrains.mps.openapi.module.SRepository;
import jetbrains.mps.ide.project.ProjectHelper;
import jetbrains.mps.baseLanguage.closures.runtime.Wrappers;
import org.jetbrains.mps.openapi.model.SModel;
import jetbrains.mps.vcs.diff.merge.MergeTemporaryModel;
import jetbrains.mps.internal.collections.runtime.IWhereFilter;
import org.apache.log4j.Level;
import jetbrains.mps.vcs.diff.ui.common.DiffModelUtil;
import jetbrains.mps.vcs.diff.ChangeSet;
import jetbrains.mps.vcs.diff.ChangeSetBuilder;
import jetbrains.mps.vcs.diff.ChangeSetImpl;
import org.jetbrains.mps.openapi.persistence.DataSource;
import jetbrains.mps.vfs.IFile;
import jetbrains.mps.extapi.persistence.FileDataSource;
import jetbrains.mps.persistence.FilePerRootDataSource;
import jetbrains.mps.ide.vfs.IdeaFile;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import jetbrains.mps.ide.vfs.VirtualFileUtils;
import com.intellij.openapi.vcs.FileStatusManager;
import jetbrains.mps.baseLanguage.closures.runtime._FunctionTypes;
import jetbrains.mps.internal.collections.runtime.IVisitor;
import org.jetbrains.mps.openapi.language.SContainmentLink;
import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.util.IterableUtil;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import org.jetbrains.mps.openapi.language.SAbstractConcept;
import org.jetbrains.annotations.Nullable;
import jetbrains.mps.smodel.event.SModelEvent;
import jetbrains.mps.internal.collections.runtime.ISelector;
import jetbrains.mps.project.MPSProject;
import jetbrains.mps.vcs.diff.changes.NodeChange;
import jetbrains.mps.vcs.diff.changes.DeleteRootChange;
import jetbrains.mps.smodel.event.SModelEventVisitorAdapter;
import java.util.Map;
import java.util.HashMap;
import jetbrains.mps.smodel.persistence.def.FilePerRootFormatUtil;
import jetbrains.mps.extapi.model.SModelBase;
import com.intellij.openapi.vcs.impl.VcsFileStatusProvider;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import jetbrains.mps.smodel.event.SModelPropertyEvent;
import org.jetbrains.mps.openapi.language.SProperty;
import jetbrains.mps.vcs.diff.changes.SetPropertyChange;
import jetbrains.mps.smodel.event.SModelReferenceEvent;
import org.jetbrains.mps.openapi.model.SReference;
import org.jetbrains.mps.openapi.language.SReferenceLink;
import jetbrains.mps.vcs.diff.changes.SetReferenceChange;
import jetbrains.mps.smodel.event.SModelChildEvent;
import jetbrains.mps.smodel.CopyUtil;
import jetbrains.mps.baseLanguage.tuples.runtime.MultiTuple;
import jetbrains.mps.smodel.event.SModelRootEvent;
import jetbrains.mps.smodel.event.SModelLanguageEvent;
import org.jetbrains.mps.openapi.language.SLanguage;
import jetbrains.mps.vcs.diff.changes.UsedLanguageChange;
import jetbrains.mps.smodel.event.SModelDevKitEvent;
import jetbrains.mps.vcs.diff.changes.ModuleDependencyChange;
import org.jetbrains.mps.openapi.module.SModuleReference;
import jetbrains.mps.smodel.event.SModelImportEvent;
import org.jetbrains.mps.openapi.model.SModelReference;
import jetbrains.mps.vcs.diff.changes.ImportedModelChange;
public class ChangesTracking {
private static final Logger LOG = LogManager.getLogger(ChangesTracking.class);
private static final Object LOCK = new Object();
private final Project myProject;
private final CurrentDifference myDifference;
private final SimpleCommandQueue myQueue;
private final EditableSModel myModelDescriptor;
private final CurrentDifferenceRegistry myRegistry;
private final SModelCommandListener myEventCollector = new ChangesTracking.MyEventsCollector();
private boolean myDisposed = false;
private BidirectionalMultiMap<SNodeId, ModelChange> myNodesToChanges = new BidirectionalMultiMap<SNodeId, ModelChange>();
private Set<ModelChange> myMetadataChanges = SetSequence.fromSet(new HashSet<ModelChange>());
private BidirectionalMap<SNodeId, ModelChange> myAddedNodesToChanges = new BidirectionalMap<SNodeId, ModelChange>();
private Tuples._2<SNodeId, List<SNodeId>> myLastParentAndNewChildrenIds;
private FileStatus myStatusOnLastUpdate;
private EventConsumingMapping myEventConsumingMapping = new EventConsumingMapping();
public ChangesTracking(@NotNull CurrentDifferenceRegistry registry, @NotNull CurrentDifference difference) {
myDifference = difference;
myProject = registry.getProject();
myModelDescriptor = myDifference.getModelDescriptor();
myQueue = registry.getCommandQueue();
myRegistry = registry;
registry.addEventCollector(myModelDescriptor, myEventCollector);
}
public void dispose() {
synchronized (LOCK) {
if (!(myDisposed)) {
myDisposed = true;
myRegistry.removeEventCollector(myModelDescriptor, myEventCollector);
myQueue.runTask(new Runnable() {
public void run() {
myDifference.removeChangeSet();
}
});
}
}
}
private void updateCacheForChange(@NotNull ModelChange change) {
SNodeId id = getNodeIdForChange(change);
if (id != null) {
myNodesToChanges.put(id, change);
} else {
SetSequence.fromSet(myMetadataChanges).addElement((MetadataChange) change);
}
if (change instanceof AddRootChange) {
MapSequence.fromMap(myAddedNodesToChanges).put(change.getRootId(), change);
} else if (change instanceof NodeGroupChange) {
for (SNodeId nodeId : Sequence.fromIterable(getNodeIdsForNodeGroupChange((NodeGroupChange) change, myLastParentAndNewChildrenIds))) {
MapSequence.fromMap(myAddedNodesToChanges).put(nodeId, change);
}
}
}
private void buildCaches() {
myNodesToChanges.clear();
SetSequence.fromSet(myMetadataChanges).clear();
myAddedNodesToChanges.clear();
myLastParentAndNewChildrenIds = null;
for (ModelChange ch : ListSequence.fromList(myDifference.getChangeSet().getModelChanges())) {
updateCacheForChange(ch);
}
}
/*package*/ void scheduleFullUpdate(final boolean force) {
myQueue.addTask(new Runnable() {
public void run() {
update(force);
}
});
}
private void update(boolean force) {
myQueue.assertSoftlyIsCommandThread();
if (!(myDifference.isEnabled())) {
return;
}
if (!(isUnderVcs(myModelDescriptor))) {
return;
}
boolean isConflict = ConflictsUtil.isModelOrModuleConflicting(myModelDescriptor, myProject);
FileStatus status = (isConflict ? FileStatus.MERGED_WITH_CONFLICTS : getStatus(myModelDescriptor));
// todo: make !force working for per-root persistence (here status==null)
if (status != null && myStatusOnLastUpdate == status && !(force)) {
return;
}
SRepository repo = ProjectHelper.fromIdeaProject(myProject).getRepository();
repo.getModelAccess().runReadAction(new Runnable() {
public void run() {
myDifference.removeChangeSet();
}
});
myStatusOnLastUpdate = status;
if (FileStatus.NOT_CHANGED == status && !(force)) {
return;
}
final Wrappers._T<SModel> baseVersionModel = new Wrappers._T<SModel>(null);
if (isAdded(myModelDescriptor) || isConflict) {
baseVersionModel.value = new MergeTemporaryModel(myModelDescriptor.getReference(), true);
} else {
baseVersionModel.value = BaseVersionUtil.getBaseVersionModel(myModelDescriptor, myProject);
if (baseVersionModel.value == null) {
return;
}
if (Sequence.fromIterable(((Iterable<SModel.Problem>) baseVersionModel.value.getProblems())).any(new IWhereFilter<SModel.Problem>() {
public boolean accept(SModel.Problem it) {
return it.isError();
}
})) {
StringBuilder sb = new StringBuilder();
for (SModel.Problem p : Sequence.fromIterable((Iterable<SModel.Problem>) baseVersionModel.value.getProblems())) {
sb.append((p.isError() ? "error: " : "warn: ")).append(p.getText()).append("\n");
}
if (LOG.isEnabledFor(Level.WARN)) {
LOG.warn(sb.toString());
}
return;
}
}
repo.getModelAccess().runReadAction(new Runnable() {
public void run() {
synchronized (LOCK) {
if (!(myDisposed)) {
DiffModelUtil.renameModel(baseVersionModel.value, "repository");
ChangeSet changeSet = ChangeSetBuilder.buildChangeSet(baseVersionModel.value, myModelDescriptor, true);
myDifference.setChangeSet((ChangeSetImpl) changeSet);
buildCaches();
}
}
}
});
}
private boolean isUnderVcs(@NotNull SModel model) {
DataSource ds = model.getSource();
IFile file = null;
if (ds instanceof FileDataSource) {
file = ((FileDataSource) ds).getFile();
} else if (ds instanceof FilePerRootDataSource) {
file = ((FilePerRootDataSource) ds).getFile(FilePerRootDataSource.HEADER_FILE);
}
if (file == null) {
return false;
}
if (!(file instanceof IdeaFile)) {
if (LOG.isEnabledFor(Level.WARN)) {
LOG.warn("File " + file + " must be a project file and managed by IDEA FS");
}
return false;
}
VirtualFile vFile = ((IdeaFile) file).getVirtualFile();
return vFile != null && ProjectLevelVcsManager.getInstance(myProject).getVcsFor(vFile) != null;
}
private boolean isAdded(SModel model) {
DataSource ds = model.getSource();
IFile file = null;
if (ds instanceof FileDataSource) {
file = ((FileDataSource) ds).getFile();
} else if (ds instanceof FilePerRootDataSource) {
file = ((FilePerRootDataSource) ds).getFile(FilePerRootDataSource.HEADER_FILE);
}
VirtualFile vFile = VirtualFileUtils.getProjectVirtualFile(file);
assert vFile != null;
FileStatus status = FileStatusManager.getInstance(myProject).getStatus(vFile);
return BaseVersionUtil.isAddedFileStatus(status);
}
private FileStatus getStatus(SModel model) {
DataSource ds = model.getSource();
if (ds instanceof FileDataSource) {
VirtualFile file = VirtualFileUtils.getProjectVirtualFile(((FileDataSource) ds).getFile());
return FileStatusManager.getInstance(myProject).getStatus(file);
} else if (ds instanceof FilePerRootDataSource) {
// todo: do we need status at all?
return null;
}
return FileStatus.UNKNOWN;
}
private void addChange(@NotNull ModelChange change) {
updateCacheForChange(change);
myDifference.addChange(change);
}
private void removeChange(@NotNull ModelChange change) {
if (change instanceof MetadataChange) {
SetSequence.fromSet(myMetadataChanges).removeElement((MetadataChange) change);
} else {
myNodesToChanges.removeValue(change);
}
myAddedNodesToChanges.removeValue(change);
myDifference.removeChange(change);
}
private <C extends ModelChange> int removeChanges(SNodeId nodeId, final Class<C> changeClass, final _FunctionTypes._return_P1_E0<? extends Boolean, ? super C> condition) {
Set<ModelChange> changes = (nodeId == null ? myMetadataChanges : myNodesToChanges.getValues(nodeId));
List<ModelChange> toRemove = SetSequence.fromSet(changes).where(new IWhereFilter<ModelChange>() {
public boolean accept(ModelChange ch) {
return changeClass.isInstance(ch) && condition.invoke((C) ch);
}
}).toListSequence();
ListSequence.fromList(toRemove).visitAll(new IVisitor<ModelChange>() {
public void visit(ModelChange it) {
removeChange(it);
}
});
return ListSequence.fromList(toRemove).count();
}
private void removeDescendantChanges(SNodeId parentId, SContainmentLink role) {
SNode oldNode = getOldNode(parentId);
if (oldNode == null) {
return;
}
List<? extends SNode> children = IterableUtil.asList(oldNode.getChildren(role));
ListSequence.fromList(children).visitAll(new IVisitor<SNode>() {
public void visit(SNode c) {
removeDescendantChanges(c.getNodeId());
}
});
}
private void removeDescendantChanges(SNodeId nodeId) {
SNode oldNode = getOldNode(nodeId);
assert oldNode != null;
for (SNode d : ListSequence.fromList(SNodeOperations.getNodeDescendants(oldNode, null, true, new SAbstractConcept[]{}))) {
removeChanges(d.getNodeId(), ModelChange.class, new _FunctionTypes._return_P1_E0<Boolean, ModelChange>() {
public Boolean invoke(ModelChange ch) {
return true;
}
});
}
}
private void buildAndAddChanges(_FunctionTypes._void_P1_E0<? super ChangeSetBuilder> buildAction) {
ChangeSet cs = myDifference.getChangeSet();
ChangeSetBuilder builder = ChangeSetBuilder.createBuilder(cs);
buildAction.invoke(builder);
ListSequence.fromList(builder.getNewChanges()).visitAll(new IVisitor<ModelChange>() {
public void visit(ModelChange ch) {
addChange(ch);
}
});
}
@Nullable
private SNode getOldNode(@NotNull SNodeId id) {
return check_5iuzi5_a0a54(check_5iuzi5_a0a0a54(myDifference.getChangeSet()), id);
}
private void runUpdateTask(final _FunctionTypes._void_P0_E0 task, SNode currentNode, final SModelEvent event) {
myEventConsumingMapping.addEvent(event);
final List<SNodeId> ancestors = ListSequence.fromList(SNodeOperations.getNodeAncestors(currentNode, null, true)).select(new ISelector<SNode, SNodeId>() {
public SNodeId select(SNode a) {
return a.getNodeId();
}
}).toListSequence();
myQueue.runTask(new Runnable() {
public void run() {
if (myDifference.getChangeSet() == null) {
update(true);
} else {
if (ListSequence.fromList(ancestors).any(new IWhereFilter<SNodeId>() {
public boolean accept(SNodeId a) {
return myAddedNodesToChanges.containsKey(a);
}
})) {
// ignore
} else {
if (myEventConsumingMapping.removeEvent(event)) {
myDifference.getBroadcaster().changeUpdateStarted();
MPSProject mpsProject = ProjectHelper.fromIdeaProject(myProject);
mpsProject.getModelAccess().runReadAction(new Runnable() {
public void run() {
synchronized (LOCK) {
if (!(myDisposed)) {
task.invoke();
}
}
}
});
myDifference.getBroadcaster().changeUpdateFinished();
}
}
}
}
});
}
private static Iterable<SNodeId> getNodeIdsForNodeGroupChange(@NotNull NodeGroupChange ngc, @Nullable Tuples._2<SNodeId, List<SNodeId>> lastParentAndNewChildrenIds) {
List<SNodeId> childrenIds;
if (lastParentAndNewChildrenIds == null || neq_5iuzi5_a0a1a05(lastParentAndNewChildrenIds._0(), ngc.getParentNodeId())) {
List<? extends SNode> children = IterableUtil.asList(ngc.getChangeSet().getNewModel().getNode(ngc.getParentNodeId()).getChildren(ngc.getRole()));
childrenIds = ListSequence.fromList(children).select(new ISelector<SNode, SNodeId>() {
public SNodeId select(SNode n) {
return n.getNodeId();
}
}).toListSequence();
} else {
childrenIds = lastParentAndNewChildrenIds._1();
}
return ListSequence.fromList(childrenIds).page(ngc.getResultBegin(), ngc.getResultEnd());
}
@Nullable
private static SNodeId getNodeIdForChange(@NotNull ModelChange change) {
if (change instanceof NodeChange) {
return ((NodeChange) change).getAffectedNodeId();
} else if (change instanceof AddRootChange || change instanceof DeleteRootChange) {
return change.getRootId();
} else if (change instanceof NodeGroupChange) {
return ((NodeGroupChange) change).getParentNodeId();
}
return null;
}
public class MyEventsCollector extends SModelEventVisitorAdapter implements SModelCommandListener {
private Map<SNode, Set<String>> childChanged;
@Override
public void eventsHappenedInCommand(List<SModelEvent> events) {
childChanged = MapSequence.fromMap(new HashMap<SNode, Set<String>>());
for (SModelEvent event : ListSequence.fromList(events)) {
event.accept(this);
}
childChanged = null;
// make model file[s] dirty
Set<IFile> affectedFiles = SetSequence.fromSet(new HashSet<IFile>());
DataSource dataSource = myModelDescriptor.getSource();
if (dataSource instanceof FileDataSource) {
SetSequence.fromSet(affectedFiles).addElement(((FileDataSource) dataSource).getFile());
} else if (dataSource instanceof FilePerRootDataSource) {
FilePerRootDataSource ds = (FilePerRootDataSource) dataSource;
Map<SNodeId, String> streamNames = FilePerRootFormatUtil.getStreamNames(((SModelBase) myModelDescriptor).getSModel());
for (SModelEvent event : ListSequence.fromList(events)) {
SNode root = event.getAffectedRoot();
if (root != null) {
SetSequence.fromSet(affectedFiles).addElement(ds.getFile(streamNames.get(root.getNodeId())));
}
}
// model file can be affected also
SetSequence.fromSet(affectedFiles).addElement(ds.getFile(FilePerRootDataSource.HEADER_FILE));
}
VcsFileStatusProvider provider = myProject.getComponent(VcsFileStatusProvider.class);
for (IFile iFile : SetSequence.fromSet(affectedFiles)) {
VirtualFile vFile = VirtualFileUtils.getVirtualFile(iFile);
if (vFile != null) {
Document document = FileDocumentManager.getInstance().getDocument(vFile);
if (document != null && provider != null) {
provider.refreshFileStatusFromDocument(vFile, document);
}
}
}
}
@Override
public void visitPropertyEvent(SModelPropertyEvent event) {
final SNode node = event.getNode();
if (node.getModel() == null) {
return;
}
final SNodeId nodeId = node.getNodeId();
final SProperty property = event.getProperty();
// get more info for debugging
assert node.getModel().getNode(nodeId) != null : "cannot find node " + nodeId + " in model " + node.getModel();
runUpdateTask(new _FunctionTypes._void_P0_E0() {
public void invoke() {
removeChanges(nodeId, SetPropertyChange.class, new _FunctionTypes._return_P1_E0<Boolean, SetPropertyChange>() {
public Boolean invoke(SetPropertyChange ch) {
return ch.isAbout(property);
}
});
buildAndAddChanges(new _FunctionTypes._void_P1_E0<ChangeSetBuilder>() {
public void invoke(ChangeSetBuilder b) {
b.buildForProperty(getOldNode(nodeId), node, property);
}
});
}
}, node, event);
}
@Override
public void visitReferenceEvent(SModelReferenceEvent event) {
SReference ref = event.getReference();
final SNode sourceNode = ref.getSourceNode();
if (sourceNode.getModel() == null) {
return;
}
final SNodeId nodeId = sourceNode.getNodeId();
final SReferenceLink role = ref.getLink();
runUpdateTask(new _FunctionTypes._void_P0_E0() {
public void invoke() {
removeChanges(nodeId, SetReferenceChange.class, new _FunctionTypes._return_P1_E0<Boolean, SetReferenceChange>() {
public Boolean invoke(SetReferenceChange ch) {
return ch.isAbout(role);
}
});
buildAndAddChanges(new _FunctionTypes._void_P1_E0<ChangeSetBuilder>() {
public void invoke(ChangeSetBuilder b) {
b.buildForReference(getOldNode(nodeId), sourceNode, role);
}
});
}
}, event.getReference().getSourceNode(), event);
}
@Override
public void visitChildEvent(SModelChildEvent event) {
SNode parent = event.getParent();
if (parent.getModel() == null) {
return;
}
String childRoleName = event.getChildRole();
// trying to avoid update task execution for the same child role twice
Set<String> childRoles = MapSequence.fromMap(childChanged).get(parent);
if (childRoles == null) {
childRoles = SetSequence.fromSet(new HashSet<String>());
MapSequence.fromMap(childChanged).put(parent, childRoles);
}
if (SetSequence.fromSet(childRoles).contains(childRoleName)) {
return;
} else {
SetSequence.fromSet(childRoles).addElement(childRoleName);
}
final SNodeId parentId = parent.getNodeId();
final SContainmentLink childRole = event.getAggregationLink();
final Wrappers._T<List<? extends SNode>> childrenRightAfterEvent = new Wrappers._T<List<? extends SNode>>(IterableUtil.asList(parent.getChildren(childRole)));
childrenRightAfterEvent.value = ListSequence.fromList(childrenRightAfterEvent.value).select(new ISelector<SNode, SNode>() {
public SNode select(SNode n) {
return CopyUtil.copyAndPreserveId(n, false);
}
}).toListSequence();
runUpdateTask(new _FunctionTypes._void_P0_E0() {
public void invoke() {
removeChanges(parentId, NodeGroupChange.class, new _FunctionTypes._return_P1_E0<Boolean, NodeGroupChange>() {
public Boolean invoke(NodeGroupChange ch) {
return ch.isAbout(childRole);
}
});
removeDescendantChanges(parentId, childRole);
myLastParentAndNewChildrenIds = MultiTuple.<SNodeId,List<SNodeId>>from(parentId, ListSequence.fromList(childrenRightAfterEvent.value).select(new ISelector<SNode, SNodeId>() {
public SNodeId select(SNode n) {
return n.getNodeId();
}
}).toListSequence());
buildAndAddChanges(new _FunctionTypes._void_P1_E0<ChangeSetBuilder>() {
public void invoke(ChangeSetBuilder b) {
SNode oldParentNode = getOldNode(parentId);
if (oldParentNode != null) {
b.buildForNodeRole(IterableUtil.asList(oldParentNode.getChildren(childRole)), childrenRightAfterEvent.value, parentId, childRole);
}
}
});
}
}, parent, event);
}
@Override
public void visitRootEvent(final SModelRootEvent event) {
SNode root = event.getRoot();
final boolean added = event.isAdded();
if (added) {
if (root.getModel() == null) {
return;
}
} else {
// there are two almost identical SModelRootEvent generated: from beforeRootRemoved and from rootRemoved
// rootRemoved event has SModelRootEvent with rootRef = (null, null)
// we skip the first one
if (event.getRootRef().getNodeId() != null) {
return;
}
}
final SNodeId rootId = root.getNodeId();
runUpdateTask(new _FunctionTypes._void_P0_E0() {
public void invoke() {
if (added) {
removeChanges(rootId, DeleteRootChange.class, new _FunctionTypes._return_P1_E0<Boolean, DeleteRootChange>() {
public Boolean invoke(DeleteRootChange ch) {
return true;
}
});
buildAndAddChanges(new _FunctionTypes._void_P1_E0<ChangeSetBuilder>() {
public void invoke(ChangeSetBuilder b) {
b.buildForNode(getOldNode(rootId), event.getRoot());
}
});
} else {
if (removeChanges(rootId, AddRootChange.class, new _FunctionTypes._return_P1_E0<Boolean, AddRootChange>() {
public Boolean invoke(AddRootChange ch) {
return true;
}
}) == 0) {
// root was not added
removeDescendantChanges(rootId);
buildAndAddChanges(new _FunctionTypes._void_P1_E0<ChangeSetBuilder>() {
public void invoke(ChangeSetBuilder b) {
b.buildForNode(getOldNode(rootId), null);
}
});
}
}
}
}, null, event);
}
@Override
public void visitLanguageEvent(SModelLanguageEvent event) {
final SLanguage eventLang = event.getEventLanguage();
final boolean deleted = !(event.isAdded());
runUpdateTask(new _FunctionTypes._void_P0_E0() {
public void invoke() {
// XXX I have no idea why we skip adding a change object if we successfully removed one or more queued earlier.
// just kept it the way it is in #moduleDependencyEvent
if (removeChanges(null, UsedLanguageChange.class, new _FunctionTypes._return_P1_E0<Boolean, UsedLanguageChange>() {
public Boolean invoke(UsedLanguageChange ulc) {
return eventLang.equals(ulc.getLanguage());
}
}) == 0) {
addChange(new UsedLanguageChange(myDifference.getChangeSet(), deleted, eventLang));
}
}
}, null, event);
}
@Override
public void visitDevKitEvent(SModelDevKitEvent event) {
moduleDependencyEvent(event, event.getDevkitNamespace(), ModuleDependencyChange.DependencyType.USED_DEVKIT, event.isAdded());
}
private void moduleDependencyEvent(SModelEvent event, final SModuleReference moduleRef, final ModuleDependencyChange.DependencyType type, final boolean added) {
runUpdateTask(new _FunctionTypes._void_P0_E0() {
public void invoke() {
if (removeChanges(null, ModuleDependencyChange.class, new _FunctionTypes._return_P1_E0<Boolean, ModuleDependencyChange>() {
public Boolean invoke(ModuleDependencyChange mdc) {
return type == mdc.getDependencyType() && moduleRef.equals(mdc.getModuleReference());
}
}) == 0) {
addChange(new ModuleDependencyChange(myDifference.getChangeSet(), moduleRef, type, !(added)));
}
}
}, null, event);
}
@Override
public void visitImportEvent(final SModelImportEvent event) {
final SModelReference modelRef = event.getModelUID();
runUpdateTask(new _FunctionTypes._void_P0_E0() {
public void invoke() {
if (removeChanges(null, ImportedModelChange.class, new _FunctionTypes._return_P1_E0<Boolean, ImportedModelChange>() {
public Boolean invoke(ImportedModelChange imc) {
return modelRef.equals(imc.getModelReference());
}
}) == 0) {
addChange(new ImportedModelChange(myDifference.getChangeSet(), modelRef, !(event.isAdded())));
}
}
}, null, event);
}
}
private static SNode check_5iuzi5_a0a54(SModel checkedDotOperand, SNodeId id) {
if (null != checkedDotOperand) {
return checkedDotOperand.getNode(id);
}
return null;
}
private static SModel check_5iuzi5_a0a0a54(ChangeSet checkedDotOperand) {
if (null != checkedDotOperand) {
return checkedDotOperand.getOldModel();
}
return null;
}
private static boolean neq_5iuzi5_a0a1a05(Object a, Object b) {
return !(((a != null ? a.equals(b) : a == b)));
}
}