diff options
author | Vladimir Piskarev | 2017-11-21 17:17:29 +0000 |
---|---|---|
committer | Vladimir Piskarev | 2017-11-21 17:17:29 +0000 |
commit | 61d321acb5daa9e8ffd2e6de2d9705e7ae8abd68 (patch) | |
tree | 59d7f78d6a57fa22eaaed5b4d30e09755faeeb62 | |
parent | a08168def310be497ba822909ca1a4c696bf4811 (diff) | |
download | org.eclipse.handly-61d321acb5daa9e8ffd2e6de2d9705e7ae8abd68.tar.gz org.eclipse.handly-61d321acb5daa9e8ffd2e6de2d9705e7ae8abd68.tar.xz org.eclipse.handly-61d321acb5daa9e8ffd2e6de2d9705e7ae8abd68.zip |
https://bugs.eclipse.org/bugs/show_bug.cgi?id=525952#c8
3 files changed, 98 insertions, 87 deletions
diff --git a/org.eclipse.handly.tests/src/org/eclipse/handly/model/ElementsTest.java b/org.eclipse.handly.tests/src/org/eclipse/handly/model/ElementsTest.java index 86d79d48..e27e00ae 100644 --- a/org.eclipse.handly.tests/src/org/eclipse/handly/model/ElementsTest.java +++ b/org.eclipse.handly.tests/src/org/eclipse/handly/model/ElementsTest.java @@ -14,8 +14,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.Map; -import java.util.Set; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -247,20 +245,40 @@ public class ElementsTest assertTrue(Elements.isAncestorOf(foo, foo)); } - public void testWithoutDescendants() + public void testRemoveDescendants() { SimpleElement bar = new SimpleElement(aFile, "bar", manager); SimpleElement baz = bar.getChild("baz"); - assertTrue(Elements.withoutDescendants( - Collections.emptySet()).isEmpty()); - assertEquals(Collections.singleton(root), Elements.withoutDescendants( - Arrays.asList(root, root))); - assertEquals(Collections.singleton(root), Elements.withoutDescendants( - Arrays.asList(root, aFile, foo))); - assertEquals(Collections.singleton(aFile), Elements.withoutDescendants( - Arrays.asList(aFile, foo))); - assertEquals(Arrays.asList(bar, foo), new ArrayList<>( - Elements.withoutDescendants(Arrays.asList(bar, baz, foo)))); + ArrayList<IElement> elements = new ArrayList<>(); + + Elements.removeDescendants(elements); + assertTrue(elements.isEmpty()); + + elements.add(root); + elements.add(root); + Elements.removeDescendants(elements); + assertEquals(Arrays.asList(root, root), elements); + + elements.clear(); + elements.add(root); + elements.add(aFile); + elements.add(aFile); + elements.add(foo); + Elements.removeDescendants(elements); + assertEquals(Collections.singletonList(root), elements); + + elements.clear(); + elements.add(aFile); + elements.add(foo); + Elements.removeDescendants(elements); + assertEquals(Collections.singletonList(aFile), elements); + + elements.clear(); + elements.add(bar); + elements.add(baz); + elements.add(foo); + Elements.removeDescendants(elements); + assertEquals(Arrays.asList(bar, foo), elements); } public void testIsOfModel() @@ -359,26 +377,4 @@ public class ElementsTest elements.clear(); resources.clear(); } - - public void testGroupBySourceFile() - { - SimpleSourceFile bFile = new SimpleSourceFile(root, "bFile", null, - manager); - SimpleElement bar = new SimpleElement(aFile, "bar", manager); - SimpleElement baz = new SimpleElement(bFile, "baz", manager); - assertTrue(Elements.groupBySourceFile( - Collections.emptySet()).isEmpty()); - assertTrue(Elements.groupBySourceFile(Collections.singleton( - root)).isEmpty()); - assertTrue(Elements.groupBySourceFile(Arrays.asList(aFile)).get( - aFile).isEmpty()); - assertEquals(Arrays.asList(foo, bar), new ArrayList<>( - Elements.groupBySourceFile(Arrays.asList(root, aFile, foo, - bar)).get(aFile))); - Map<ISourceFile, Set<IElement>> result = Elements.groupBySourceFile( - Arrays.asList(bFile, bar, baz, root, aFile, foo, bar)); - assertEquals(Arrays.asList(bar, foo), new ArrayList<>(result.get( - aFile))); - assertEquals(Arrays.asList(baz), new ArrayList<>(result.get(bFile))); - } } diff --git a/org.eclipse.handly/src/org/eclipse/handly/model/Elements.java b/org.eclipse.handly/src/org/eclipse/handly/model/Elements.java index 677cbf07..370c8103 100644 --- a/org.eclipse.handly/src/org/eclipse/handly/model/Elements.java +++ b/org.eclipse.handly/src/org/eclipse/handly/model/Elements.java @@ -17,11 +17,9 @@ import static org.eclipse.handly.context.Contexts.of; import java.net.URI; import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedHashSet; import java.util.List; -import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; import java.util.Spliterator; @@ -258,7 +256,7 @@ public class Elements * @param element may be <code>null</code>, in which case no elements * will be added to the given collection * @param collection not <code>null</code> - * @return the given collection + * @return the given <code>collection</code> instance */ public static <T extends Collection<? super IElement>> T collectParentChain( IElement element, T collection) @@ -283,7 +281,7 @@ public class Elements * will be added to the given collection * @param collection not <code>null</code> * @param until may be <code>null</code> - * @return the given collection + * @return the given <code>collection</code> instance */ public static <T extends Collection<? super IElement>> T collectParentChainUntil( IElement element, T collection, Predicate<? super IElement> until) @@ -652,31 +650,77 @@ public class Elements } /** - * Given a collection of elements, returns a subset without descendants, - * i.e. without elements for which an ancestor is also present in the given - * collection. The returned set has predictable iteration order determined - * by that of the given collection. This is a handle-only method. + * Removes descendants from the given collection of elements. In other words, + * removes those elements for which an ancestor is also present in the given + * collection. This is a handle-only method. * * @param elements not <code>null</code>, must not contain nulls - * @return a set excluding any descendant elements present in the given - * collection (never <code>null</code>) */ - public static <T extends IElement> Set<T> withoutDescendants( - Collection<T> elements) + public static void removeDescendants( + Collection<? extends IElement> elements) { - Set<T> result = new LinkedHashSet<>(elements); - for (IElement element : elements) + Set<Key> keys = Key.toKeys(elements); + Iterator<? extends IElement> it = elements.iterator(); + while (it.hasNext()) { - for (IElement other : elements) - { - if (element == other) - continue; + if (Key.hasAncestor(Key.toKey(getParent(it.next())), keys)) + it.remove(); + } + } + + private static class Key + { + final IElement e; + + Key(IElement e) + { + if (e == null) + throw new IllegalArgumentException(); + this.e = e; + } + + static Key toKey(IElement e) + { + return e != null ? new Key(e) : null; + } + + static Set<Key> toKeys(Collection<? extends IElement> elements) + { + Set<Key> result = new HashSet<>(elements.size()); + for (IElement e : elements) + result.add(new Key(e)); + return result; + } - if (isAncestorOf(other, getParent(element))) - result.remove(element); + static boolean hasAncestor(Key key, Set<Key> keys) + { + while (key != null) + { + if (keys.contains(key)) + return true; + key = key.parent(); } + return false; + } + + Key parent() + { + return toKey(getParent(e)); + } + + @Override + public int hashCode() + { + return e.hashCode(); + } + + @Override + public boolean equals(Object o) + { + if (!(o instanceof Key)) + return false; + return equalsAndSameParentChain(e, ((Key)o).e); } - return result; } /** @@ -1225,35 +1269,6 @@ public class Elements } /** - * Groups each of the given elements by its containing source file, ignoring - * elements outside a source file. Returns a mapping from a source file to - * a set of elements grouped by that source file; the order of elements in - * the set is determined by iteration order of the given elements. - * This is a handle-only method. - * - * @param elements not <code>null</code>, must not contain nulls - * @return elements grouped by containing source file (never <code>null</code>) - */ - public static <T extends IElement> Map<ISourceFile, Set<T>> groupBySourceFile( - Iterable<T> elements) - { - Map<ISourceFile, Set<T>> result = new HashMap<>(); - for (T element : elements) - { - ISourceFile sourceFile = getSourceFile(element); - if (sourceFile != null) - { - Set<T> set = result.get(sourceFile); - if (set == null) - result.put(sourceFile, set = new LinkedHashSet<>()); - if (element != sourceFile) - set.add(element); - } - } - return result; - } - - /** * Ensures that, if the given element is contained in a source file, * the source file is reconciled. Note that the call may result in * change of existence status for the given element: if the element diff --git a/org.eclipse.handly/src/org/eclipse/handly/util/ArrayUtil.java b/org.eclipse.handly/src/org/eclipse/handly/util/ArrayUtil.java index 0d1375c8..e01e73f3 100644 --- a/org.eclipse.handly/src/org/eclipse/handly/util/ArrayUtil.java +++ b/org.eclipse.handly/src/org/eclipse/handly/util/ArrayUtil.java @@ -141,7 +141,7 @@ public class ArrayUtil * @param a array (not <code>null</code>) * @param p predicate (not <code>null</code>) * @param c collection (not <code>null</code>) - * @return the given collection + * @return the given collection instance, <code>c</code> */ public static <T, C extends Collection<? super T>> C collectMatching(T[] a, Predicate<? super T> p, C c) |