use of com.intellij.util.containers.LinkedMultiMap in project intellij-community by JetBrains.
the class CommittedChangesTreeBrowser method zipChanges.
/**
* Zips changes by removing duplicates (changes in the same file) and compounding the diff.
* <b>NB:</b> changes must be given in the time-ascending order, i.e the first change in the list should be the oldest one.
*/
@NotNull
public static List<Change> zipChanges(@NotNull List<Change> changes) {
// TODO: further improvements needed
// We may want to process collisions more consistent
// Possible solution: avoid creating duplicate entries for the same FilePath. No changes in the output should have same beforePath or afterPath.
// We may take earliest and latest revisions for each file.
//
// The main problem would be to keep existing movements in non-conflicting cases (where input changes are taken from linear sequence of commits)
// case1: "a -> b; b -> c" - file renamed twice in the same revision (as source and as target)
// case2: "a -> b" "b -> c" - file renamed twice in consequent commits
// case3: "a -> b; b -> a" - files swapped vs "a -> b" "b -> a" - file rename canceled
// case4: "delete a" "b -> a" "modify a"
// ...
// but return "good enough" result for input with conflicting changes
// case1: "new a", "new a"
// case2: "a -> b", "new b"
// ...
//
// getting "actually good" results is impossible without knowledge of commits topology.
// key - after path (nullable)
LinkedMultiMap<FilePath, Change> map = new LinkedMultiMap<>();
for (Change change : changes) {
ContentRevision bRev = change.getBeforeRevision();
ContentRevision aRev = change.getAfterRevision();
FilePath bPath = bRev != null ? bRev.getFile() : null;
FilePath aPath = aRev != null ? aRev.getFile() : null;
if (bRev == null) {
map.putValue(aPath, change);
continue;
}
Collection<Change> bucket = map.get(bPath);
if (bucket.isEmpty()) {
map.putValue(aPath, change);
continue;
}
Change oldChange = bucket.iterator().next();
bucket.remove(oldChange);
ContentRevision oldRevision = oldChange.getBeforeRevision();
if (oldRevision != null || aRev != null) {
map.putValue(aPath, new Change(oldRevision, aRev));
}
}
// put deletions into appropriate place in list
Collection<Change> deleted = map.remove(null);
if (deleted != null) {
for (Change change : deleted) {
//noinspection ConstantConditions
map.putValue(change.getBeforeRevision().getFile(), change);
}
}
return new ArrayList<>(map.values());
}
use of com.intellij.util.containers.LinkedMultiMap in project intellij-community by JetBrains.
the class MavenFoldersImporter method configSourceFolders.
private void configSourceFolders() {
final MultiMap<JpsModuleSourceRootType<?>, String> roots = new LinkedMultiMap<>();
roots.putValues(JavaSourceRootType.SOURCE, myMavenProject.getSources());
roots.putValues(JavaSourceRootType.TEST_SOURCE, myMavenProject.getTestSources());
for (MavenImporter each : MavenImporter.getSuitableImporters(myMavenProject)) {
each.collectSourceRoots(myMavenProject, (s, type) -> roots.putValue(type, s));
}
for (MavenResource each : myMavenProject.getResources()) {
roots.putValue(JavaResourceRootType.RESOURCE, each.getDirectory());
}
for (MavenResource each : myMavenProject.getTestResources()) {
roots.putValue(JavaResourceRootType.TEST_RESOURCE, each.getDirectory());
}
addBuilderHelperPaths("add-source", roots.getModifiable(JavaSourceRootType.SOURCE));
addBuilderHelperPaths("add-test-source", roots.getModifiable(JavaSourceRootType.TEST_SOURCE));
List<String> addedPaths = new ArrayList<>();
for (JpsModuleSourceRootType<?> type : roots.keySet()) {
for (String path : roots.get(type)) {
addSourceFolderIfNotOverlap(path, type, addedPaths);
}
}
}
Aggregations