diff options
6 files changed, 137 insertions, 190 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/packages/AbstractAttributeMapper.java b/src/main/java/com/google/devtools/build/lib/packages/AbstractAttributeMapper.java index c4c47b4b7a..4f67d959e0 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/AbstractAttributeMapper.java +++ b/src/main/java/com/google/devtools/build/lib/packages/AbstractAttributeMapper.java @@ -15,7 +15,6 @@ package com.google.devtools.build.lib.packages; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.packages.BuildType.SelectorList; import com.google.devtools.build.lib.syntax.Type; @@ -149,15 +148,20 @@ public abstract class AbstractAttributeMapper implements AttributeMap { } /** Visits all labels reachable from the given attribute. */ - protected void visitLabels(Attribute attribute, AcceptsLabelAttribute observer) + protected void visitLabels(final Attribute attribute, final AcceptsLabelAttribute observer) throws InterruptedException { Type<?> type = attribute.getType(); Object value = get(attribute.getName(), type); if (value != null) { // null values are particularly possible for computed defaults. - for (Label label : extractLabels(type, value)) { - Label absoluteLabel = ruleLabel.resolveRepositoryRelative(label); - observer.acceptLabelAttribute(absoluteLabel, attribute); - } + type.visitLabels(new Type.LabelVisitor() { + @Override + public void visit(@Nullable Object object) throws InterruptedException { + if (object != null) { + Label absoluteLabel = ruleLabel.resolveRepositoryRelative((Label) object); + observer.acceptLabelAttribute(absoluteLabel, attribute); + } + } + }, value); } } @@ -244,10 +248,4 @@ public abstract class AbstractAttributeMapper implements AttributeMap { Attribute attribute = ruleClass.getAttributeByNameMaybe(attrName); return attribute != null && attribute.getType() == type; } - - protected static Iterable<Label> extractLabels(Type<?> type, Object value) { - return value == null - ? ImmutableList.<Label>of() - : Iterables.filter(type.extractLabels(value), Label.class); - } } diff --git a/src/main/java/com/google/devtools/build/lib/packages/AggregatingAttributeMapper.java b/src/main/java/com/google/devtools/build/lib/packages/AggregatingAttributeMapper.java index abaccccdff..39dec2719f 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/AggregatingAttributeMapper.java +++ b/src/main/java/com/google/devtools/build/lib/packages/AggregatingAttributeMapper.java @@ -105,7 +105,7 @@ public class AggregatingAttributeMapper extends AbstractAttributeMapper { } private void visitLabels( - Attribute attribute, boolean includeSelectKeys, AcceptsLabelAttribute observer) + final Attribute attribute, boolean includeSelectKeys, final AcceptsLabelAttribute observer) throws InterruptedException { Type<?> type = attribute.getType(); SelectorList<?> selectorList = getSelectorList(attribute.getName(), type); @@ -115,9 +115,15 @@ public class AggregatingAttributeMapper extends AbstractAttributeMapper { // (computed) values and look for labels. for (Object value : visitAttribute(attribute.getName(), attribute.getType())) { if (value != null) { - for (Label label : extractLabels(type, value)) { - observer.acceptLabelAttribute(getLabel().resolveRepositoryRelative(label), attribute); - } + type.visitLabels(new Type.LabelVisitor() { + @Override + public void visit(@Nullable Object label) throws InterruptedException { + if (label != null) { + observer.acceptLabelAttribute( + getLabel().resolveRepositoryRelative((Label) label), attribute); + } + } + }, value); } } } else { @@ -133,9 +139,15 @@ public class AggregatingAttributeMapper extends AbstractAttributeMapper { Object value = selector.isValueSet(selectorEntry.getKey()) ? selectorEntry.getValue() : attribute.getDefaultValue(null); - for (Label label : extractLabels(type, value)) { - observer.acceptLabelAttribute(getLabel().resolveRepositoryRelative(label), attribute); - } + type.visitLabels(new Type.LabelVisitor() { + @Override + public void visit(@Nullable Object label) throws InterruptedException { + if (label != null) { + observer.acceptLabelAttribute( + getLabel().resolveRepositoryRelative((Label) label), attribute); + } + } + }, value); } } } @@ -178,8 +190,9 @@ public class AggregatingAttributeMapper extends AbstractAttributeMapper { // 3) "attr = select({...})". With just a single select, visitAttribute runs efficiently. for (Object value : visitAttribute(attrName, attrType)) { if (value != null) { - duplicates.addAll(CollectionUtils.duplicatedElementsOf( - ImmutableList.copyOf(extractLabels(attrType, value)))); + // TODO(bazel-team): Calculate duplicates directly using attrType.visitLabels in order to + // avoid intermediate collections here. + duplicates.addAll(CollectionUtils.duplicatedElementsOf(extractLabels(attrType, value))); } } } else { @@ -194,7 +207,7 @@ public class AggregatingAttributeMapper extends AbstractAttributeMapper { // they're in different selector paths (since only one path can actually get chosen). Set<Label> selectorLabels = new LinkedHashSet<>(); for (Object selectorValue : selector.getEntries().values()) { - Iterable<Label> labelsInSelectorValue = extractLabels(attrType, selectorValue); + List<Label> labelsInSelectorValue = extractLabels(attrType, selectorValue); // Duplicates within a single path are not okay. duplicates.addAll(CollectionUtils.duplicatedElementsOf(labelsInSelectorValue)); Iterables.addAll(selectorLabels, labelsInSelectorValue); @@ -610,4 +623,21 @@ public class AggregatingAttributeMapper extends AbstractAttributeMapper { } }; } + + private static ImmutableList<Label> extractLabels(Type<?> type, Object value) { + try { + final ImmutableList.Builder<Label> result = ImmutableList.builder(); + type.visitLabels(new Type.LabelVisitor() { + @Override + public void visit(@Nullable Object object) { + if (object != null) { + result.add((Label) object); + } + } + }, value); + return result.build(); + } catch (InterruptedException e) { + throw new IllegalStateException("Unexpected InterruptedException", e); + } + } } diff --git a/src/main/java/com/google/devtools/build/lib/packages/BuildType.java b/src/main/java/com/google/devtools/build/lib/packages/BuildType.java index 825efb5a54..1481aa1707 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/BuildType.java +++ b/src/main/java/com/google/devtools/build/lib/packages/BuildType.java @@ -28,7 +28,6 @@ import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.syntax.Type.ConversionException; import com.google.devtools.build.lib.syntax.Type.DictType; import com.google.devtools.build.lib.syntax.Type.ListType; -import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; @@ -95,13 +94,7 @@ public final class BuildType { } @Override - protected boolean containsLabels() { - return false; - } - - @Override - public Collection<Object> extractLabels(Object value) { - return NO_LABELS; + public void visitLabels(LabelVisitor visitor, Object value) { } @Override @@ -194,13 +187,10 @@ public final class BuildType { } @Override - protected boolean containsLabels() { - return true; - } - - @Override - public Collection<? extends Object> extractLabels(Object value) { - return cast(value).getLabels(); + public void visitLabels(LabelVisitor visitor, Object value) throws InterruptedException { + for (Object label : cast(value).getLabels()) { + visitor.visit(label); + } } } @@ -216,13 +206,8 @@ public final class BuildType { } @Override - protected boolean containsLabels() { - return true; - } - - @Override - public Iterable<Label> extractLabels(Object value) { - return ImmutableList.of(cast(value)); + public void visitLabels(LabelVisitor visitor, Object value) throws InterruptedException { + visitor.visit(cast(value)); } @Override @@ -272,13 +257,7 @@ public final class BuildType { } @Override - protected boolean containsLabels() { - return false; - } - - @Override - public Collection<Object> extractLabels(Object value) { - return NO_LABELS; + public void visitLabels(LabelVisitor visitor, Object value) { } @Override @@ -317,13 +296,7 @@ public final class BuildType { } @Override - protected boolean containsLabels() { - return false; - } - - @Override - public Collection<Object> extractLabels(Object what) { - return NO_LABELS; + public void visitLabels(LabelVisitor visitor, Object value) { } @Override @@ -349,13 +322,8 @@ public final class BuildType { } @Override - protected boolean containsLabels() { - return true; - } - - @Override - public Collection<Label> extractLabels(Object value) { - return ImmutableList.of(cast(value)); + public void visitLabels(LabelVisitor visitor, Object value) throws InterruptedException { + visitor.visit(cast(value)); } @Override @@ -615,13 +583,7 @@ public final class BuildType { } @Override - protected boolean containsLabels() { - return false; - } - - @Override - public Collection<Object> extractLabels(Object value) { - return NO_LABELS; + public void visitLabels(LabelVisitor visitor, Object value) { } @Override diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Type.java b/src/main/java/com/google/devtools/build/lib/syntax/Type.java index 37c280c26c..714cb5da31 100644 --- a/src/main/java/com/google/devtools/build/lib/syntax/Type.java +++ b/src/main/java/com/google/devtools/build/lib/syntax/Type.java @@ -14,7 +14,6 @@ package com.google.devtools.build.lib.syntax; -import com.google.common.base.Function; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -24,7 +23,6 @@ import com.google.devtools.build.lib.syntax.SkylarkList.MutableList; import com.google.devtools.build.lib.util.LoggingUtil; import com.google.devtools.build.lib.util.StringCanonicalizer; import java.util.ArrayList; -import java.util.Collection; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -51,14 +49,6 @@ import javax.annotation.Nullable; */ public abstract class Type<T> { - private final Function<Object, Iterable<? extends Object>> flattenFunction = - new Function<Object, Iterable<? extends Object>>() { - @Override - public Iterable<? extends Object> apply(Object value) { - return extractLabels(value); - } - }; - protected Type() {} /** @@ -132,14 +122,13 @@ public abstract class Type<T> { */ public abstract T getDefaultValue(); - /** - * Returns whether there exists an {@code x} such that {@code extractLabels(x)} will return a - * non-{@code NO_LABELS} value. - */ - protected abstract boolean containsLabels(); + /** Function accepting a (potentially null) object value. See {@link #visitLabels}. */ + public static interface LabelVisitor { + void visit(@Nullable Object object) throws InterruptedException; + } /** - * Extracts all the labels from the given instance of the type. + * Pall labels associated with the instance of the type to visitor. * * <p>This is used to support reliable label visitation in * {@link com.google.devtools.build.lib.packages.AbstractAttributeMapper#visitLabels}. To preserve @@ -147,12 +136,7 @@ public abstract class Type<T> { * words, be careful about defining default instances in base types that get auto-inherited by * their children. Keep all definitions as explicit as possible. */ - public abstract Iterable<? extends Object> extractLabels(Object value); - - /** - * {@link #extractLabels} return value for types that don't contain labels. - */ - protected static final ImmutableList<Object> NO_LABELS = ImmutableList.of(); + public abstract void visitLabels(LabelVisitor visitor, Object value) throws InterruptedException; /** * Implementation of concatenation for this type (e.g. "val1 + val2"). Returns null to @@ -278,13 +262,7 @@ public abstract class Type<T> { } @Override - protected boolean containsLabels() { - return false; - } - - @Override - public Iterable<? extends Object> extractLabels(Object value) { - return NO_LABELS; + public void visitLabels(LabelVisitor visitor, Object value) { } @Override @@ -310,13 +288,7 @@ public abstract class Type<T> { } @Override - protected boolean containsLabels() { - return false; - } - - @Override - public Collection<Object> extractLabels(Object value) { - return NO_LABELS; + public void visitLabels(LabelVisitor visitor, Object value) { } @Override @@ -355,13 +327,7 @@ public abstract class Type<T> { } @Override - protected boolean containsLabels() { - return false; - } - - @Override - public Iterable<Object> extractLabels(Object value) { - return NO_LABELS; + public void visitLabels(LabelVisitor visitor, Object value) { } @Override @@ -411,13 +377,7 @@ public abstract class Type<T> { } @Override - protected boolean containsLabels() { - return false; - } - - @Override - public Collection<Object> extractLabels(Object value) { - return NO_LABELS; + public void visitLabels(LabelVisitor visitor, Object value) { } @Override @@ -462,23 +422,13 @@ public abstract class Type<T> { private final Map<KeyT, ValueT> empty = ImmutableMap.of(); - private final Function< - Map.Entry<KeyT, ValueT>, Iterable<? extends Object>> mapEntryFlattenFunction = - new Function<Map.Entry<KeyT, ValueT>, Iterable<? extends Object>>() { - @Override - public Iterable<? extends Object> apply(Entry<KeyT, ValueT> entry) { - Iterable<? extends Object> flattenedKeys = keyType.extractLabels(entry.getKey()); - Iterable<? extends Object> flattenedValues = valueType.extractLabels(entry.getValue()); - if (keyType.containsLabels() && valueType.containsLabels()) { - return Iterables.concat(flattenedKeys, flattenedValues); - } else if (keyType.containsLabels()) { - return flattenedKeys; - } else if (valueType.containsLabels()) { - return flattenedValues; - } - throw new IllegalStateException(this.toString()); - } - }; + @Override + public void visitLabels(LabelVisitor visitor, Object value) throws InterruptedException { + for (Entry<KeyT, ValueT> entry : cast(value).entrySet()) { + keyType.visitLabels(visitor, entry.getKey()); + valueType.visitLabels(visitor, entry.getValue()); + } + } public static <KEY, VALUE> DictType<KEY, VALUE> create( Type<KEY> keyType, Type<VALUE> valueType) { @@ -531,18 +481,6 @@ public abstract class Type<T> { public Map<KeyT, ValueT> getDefaultValue() { return empty; } - - @Override - protected boolean containsLabels() { - return keyType.containsLabels() || valueType.containsLabels(); - } - - @Override - public Iterable<Object> extractLabels(Object value) { - return containsLabels() - ? Iterables.concat(Iterables.transform(cast(value).entrySet(), mapEntryFlattenFunction)) - : NO_LABELS; - } } /** A type for lists of a given element type */ @@ -577,15 +515,10 @@ public abstract class Type<T> { } @Override - protected boolean containsLabels() { - return elemType.containsLabels(); - } - - @Override - public Iterable<? extends Object> extractLabels(Object value) { - return containsLabels() - ? Iterables.concat(Iterables.transform(cast(value), elemType.flattenFunction)) - : NO_LABELS; + public void visitLabels(LabelVisitor visitor, Object value) throws InterruptedException { + for (ElemT elem : cast(value)) { + elemType.visitLabels(visitor, elem); + } } @Override diff --git a/src/test/java/com/google/devtools/build/lib/packages/BuildTypeTest.java b/src/test/java/com/google/devtools/build/lib/packages/BuildTypeTest.java index dfd4f28cef..f01fc05945 100644 --- a/src/test/java/com/google/devtools/build/lib/packages/BuildTypeTest.java +++ b/src/test/java/com/google/devtools/build/lib/packages/BuildTypeTest.java @@ -30,17 +30,16 @@ import com.google.devtools.build.lib.syntax.EvalUtils; import com.google.devtools.build.lib.syntax.Printer; import com.google.devtools.build.lib.syntax.SelectorList; import com.google.devtools.build.lib.syntax.SelectorValue; +import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.syntax.Type.ConversionException; - +import java.util.Arrays; +import java.util.List; +import java.util.Map; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - /** * Test of type-conversions for build-specific types. */ @@ -66,7 +65,7 @@ public class BuildTypeTest { /* symlinkBehavior */ null, /* stripPrefix */ null); assertEquals(input, BuildType.FILESET_ENTRY.convert(input, null, currentRule)); - assertThat(BuildType.FILESET_ENTRY.extractLabels(input)).containsExactly(entryLabel); + assertThat(collectLabels(BuildType.FILESET_ENTRY, input)).containsExactly(entryLabel); } @Test @@ -90,7 +89,7 @@ public class BuildTypeTest { /* symlinkBehavior */ null, /* stripPrefix */ null)); assertEquals(input, BuildType.FILESET_ENTRY_LIST.convert(input, null, currentRule)); - assertThat(BuildType.FILESET_ENTRY_LIST.extractLabels(input)).containsExactly( + assertThat(collectLabels(BuildType.FILESET_ENTRY_LIST, input)).containsExactly( entry1Label, entry2Label); } @@ -124,7 +123,7 @@ public class BuildTypeTest { "//conditions:b", "also not a label", BuildType.Selector.DEFAULT_CONDITION_KEY, "whatever"); try { - new Selector<Label>(input, null, currentRule, BuildType.LABEL); + new Selector<>(input, null, currentRule, BuildType.LABEL); fail("Expected Selector instantiation to fail since the input isn't a selection of labels"); } catch (ConversionException e) { assertThat(e.getMessage()).contains("invalid label 'not a label'"); @@ -140,7 +139,7 @@ public class BuildTypeTest { "not a label", "//a:a", BuildType.Selector.DEFAULT_CONDITION_KEY, "whatever"); try { - new Selector<Label>(input, null, currentRule, BuildType.LABEL); + new Selector<>(input, null, currentRule, BuildType.LABEL); fail("Expected Selector instantiation to fail since the key isn't a label"); } catch (ConversionException e) { assertThat(e.getMessage()).contains("invalid label 'not a label'"); @@ -158,7 +157,7 @@ public class BuildTypeTest { BuildType.Selector.DEFAULT_CONDITION_KEY, "//d:d"); assertEquals( Label.create("@//d", "d"), - new Selector<Label>(input, null, currentRule, BuildType.LABEL).getDefault()); + new Selector<>(input, null, currentRule, BuildType.LABEL).getDefault()); } @Test @@ -271,19 +270,19 @@ public class BuildTypeTest { @Test public void testUnconditionalSelects() throws Exception { assertFalse( - new Selector<Label>( + new Selector<>( ImmutableMap.of("//conditions:a", "//a:a"), null, currentRule, BuildType.LABEL ).isUnconditional()); assertFalse( - new Selector<Label>( + new Selector<>( ImmutableMap.of( "//conditions:a", "//a:a", BuildType.Selector.DEFAULT_CONDITION_KEY, "//b:b"), null, currentRule, BuildType.LABEL ).isUnconditional()); assertTrue( - new Selector<Label>( + new Selector<>( ImmutableMap.of( BuildType.Selector.DEFAULT_CONDITION_KEY, "//b:b"), null, currentRule, BuildType.LABEL @@ -415,4 +414,17 @@ public class BuildTypeTest { assertEquals("FilesetEntry", EvalUtils.getDataTypeName(makeFilesetEntry())); assertFalse(EvalUtils.isImmutable(makeFilesetEntry())); } + + private static <T> Iterable<T> collectLabels(Type<T> type, Object value) + throws InterruptedException { + ImmutableList.Builder<T> result = ImmutableList.builder(); + type.visitLabels(new Type.LabelVisitor() { + @SuppressWarnings("unchecked") + @Override + public void visit(Object object) throws InterruptedException { + result.add((T) object); + } + }, value); + return result.build(); + } } diff --git a/src/test/java/com/google/devtools/build/lib/syntax/TypeTest.java b/src/test/java/com/google/devtools/build/lib/syntax/TypeTest.java index 0714c83362..4179666e47 100644 --- a/src/test/java/com/google/devtools/build/lib/syntax/TypeTest.java +++ b/src/test/java/com/google/devtools/build/lib/syntax/TypeTest.java @@ -20,6 +20,7 @@ import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.common.collect.Sets; @@ -31,17 +32,15 @@ import com.google.devtools.build.lib.syntax.SkylarkList.MutableList; import com.google.devtools.build.lib.syntax.SkylarkList.Tuple; import com.google.devtools.build.lib.syntax.Type.ConversionException; import com.google.devtools.build.lib.testutil.MoreAsserts; - +import java.util.Arrays; +import java.util.List; +import java.util.Map; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - /** * Test of type-conversions using Type. */ @@ -59,7 +58,7 @@ public class TypeTest { public void testInteger() throws Exception { Object x = 3; assertEquals(x, Type.INTEGER.convert(x, null)); - assertThat(Type.INTEGER.extractLabels(x)).isEmpty(); + assertThat(collectLabels(Type.INTEGER, x)).isEmpty(); } @Test @@ -91,7 +90,7 @@ public class TypeTest { public void testString() throws Exception { Object s = "foo"; assertEquals(s, Type.STRING.convert(s, null)); - assertThat(Type.STRING.extractLabels(s)).isEmpty(); + assertThat(collectLabels(Type.STRING, s)).isEmpty(); } @Test @@ -114,7 +113,7 @@ public class TypeTest { assertTrue(Type.BOOLEAN.convert(myTrue, null)); assertFalse(Type.BOOLEAN.convert(false, null)); assertFalse(Type.BOOLEAN.convert(myFalse, null)); - assertThat(Type.BOOLEAN.extractLabels(myTrue)).isEmpty(); + assertThat(collectLabels(Type.BOOLEAN, myTrue)).isEmpty(); } @Test @@ -151,7 +150,7 @@ public class TypeTest { assertEquals(TriState.YES, BuildType.TRISTATE.convert(TriState.YES, null)); assertEquals(TriState.NO, BuildType.TRISTATE.convert(TriState.NO, null)); assertEquals(TriState.AUTO, BuildType.TRISTATE.convert(TriState.AUTO, null)); - assertThat(BuildType.TRISTATE.extractLabels(TriState.YES)).isEmpty(); + assertThat(collectLabels(BuildType.TRISTATE, TriState.YES)).isEmpty(); } @Test @@ -227,7 +226,7 @@ public class TypeTest { Label label = Label .parseAbsolute("//foo:bar"); assertEquals(label, BuildType.LABEL.convert("//foo:bar", null, currentRule)); - assertThat(BuildType.LABEL.extractLabels(label)).containsExactly(label); + assertThat(collectLabels(BuildType.LABEL, label)).containsExactly(label); } @Test @@ -235,7 +234,7 @@ public class TypeTest { Label label = Label .parseAbsolute("//foo:bar"); assertEquals(label, BuildType.NODEP_LABEL.convert("//foo:bar", null, currentRule)); - assertThat(BuildType.NODEP_LABEL.extractLabels(label)).containsExactly(label); + assertThat(collectLabels(BuildType.NODEP_LABEL, label)).containsExactly(label); } @Test @@ -279,7 +278,7 @@ public class TypeTest { Type.STRING_LIST.convert(input, null); assertEquals(input, converted); assertNotSame(input, converted); - assertThat(Type.STRING_LIST.extractLabels(input)).isEmpty(); + assertThat(collectLabels(Type.STRING_LIST, input)).isEmpty(); } @Test @@ -289,7 +288,7 @@ public class TypeTest { Map<String, String> converted = Type.STRING_DICT.convert(input, null); assertEquals(input, converted); assertNotSame(input, converted); - assertThat(Type.STRING_DICT.extractLabels(converted)).isEmpty(); + assertThat(collectLabels(Type.STRING_DICT, converted)).isEmpty(); } @Test @@ -336,7 +335,7 @@ public class TypeTest { Label.parseAbsolute("//quux:wiz")); assertEquals(expected, converted); assertNotSame(expected, converted); - assertThat(BuildType.LABEL_LIST.extractLabels(converted)).containsExactlyElementsIn(expected); + assertThat(collectLabels(BuildType.LABEL_LIST, converted)).containsExactlyElementsIn(expected); } @Test @@ -385,7 +384,7 @@ public class TypeTest { "wiz", Arrays.asList("bang")); assertEquals(expected, converted); assertNotSame(expected, converted); - assertThat(Type.STRING_LIST_DICT.extractLabels(converted)).isEmpty(); + assertThat(collectLabels(Type.STRING_LIST_DICT, converted)).isEmpty(); } @Test @@ -438,7 +437,7 @@ public class TypeTest { "wiz", "bang"); assertEquals(expected, converted); assertNotSame(expected, converted); - assertThat(Type.STRING_DICT_UNARY.extractLabels(converted)).isEmpty(); + assertThat(collectLabels(Type.STRING_DICT_UNARY, converted)).isEmpty(); } @Test @@ -487,4 +486,17 @@ public class TypeTest { assertThat(e).hasMessage("Expected a map for dictionary but got a java.lang.String"); } } -} + + private static <T> Iterable<T> collectLabels(Type<T> type, Object value) + throws InterruptedException { + ImmutableList.Builder<T> result = ImmutableList.builder(); + type.visitLabels(new Type.LabelVisitor() { + @SuppressWarnings("unchecked") + @Override + public void visit(Object object) throws InterruptedException { + result.add((T) object); + } + }, value); + return result.build(); + } +}
\ No newline at end of file |