Remove ComposingTransition, all uses should be of ComposingTransitionFactory. Work towards composable starlark transitions: #22248. PiperOrigin-RevId: 640178803 Change-Id: Ida2f94e61679fbe4687545ab9fbb700ebe856877
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/BUILD b/src/main/java/com/google/devtools/build/lib/analysis/BUILD index d628bdb..604229b 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/BUILD +++ b/src/main/java/com/google/devtools/build/lib/analysis/BUILD
@@ -72,7 +72,6 @@ ":config/run_under", ":config/run_under_converter", ":config/starlark_defined_config_transition", - ":config/transitions/composing_transition", ":config/transitions/composing_transition_factory", ":config/transitions/configuration_transition", ":config/transitions/no_transition", @@ -2111,29 +2110,18 @@ ], ) -# TODO(b/144899336): This should be config/transitions/BUILD +# TODO(b/144899336): These should be config/transitions/BUILD java_library( - name = "config/transitions/composing_transition", - srcs = ["config/transitions/ComposingTransition.java"], + name = "config/transitions/composing_transition_factory", + srcs = ["config/transitions/ComposingTransitionFactory.java"], deps = [ ":config/build_option_details", ":config/build_options", ":config/transitions/configuration_transition", ":config/transitions/no_transition", + ":config/transitions/transition_factory", ":required_config_fragments_provider", "//src/main/java/com/google/devtools/build/lib/events", - "//third_party:guava", - ], -) - -java_library( - name = "config/transitions/composing_transition_factory", - srcs = ["config/transitions/ComposingTransitionFactory.java"], - deps = [ - ":config/transitions/composing_transition", - ":config/transitions/configuration_transition", - ":config/transitions/no_transition", - ":config/transitions/transition_factory", "//third_party:auto_value", "//third_party:guava", ],
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/StarlarkTransitionCache.java b/src/main/java/com/google/devtools/build/lib/analysis/config/StarlarkTransitionCache.java index 9128c5b..096ee3db 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/config/StarlarkTransitionCache.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/config/StarlarkTransitionCache.java
@@ -32,7 +32,7 @@ * * <p>This trivially includes {@link StarlarkTransition}s. But it also includes transitions that * delegate to {@link StarlarkTransition}s, like some {@link - * com.google.devtools.build.lib.analysis.config.transitions.ComposingTransition}s. + * com.google.devtools.build.lib.analysis.config.transitions.ComposingTransitionFactory} instances. * * <p>This cache was added to keep builds that heavily rely on Starlark transitions performant. The * inspiring build is a large Apple binary that heavily relies on {@code objc_library.bzl}, which
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/transitions/ComposingTransition.java b/src/main/java/com/google/devtools/build/lib/analysis/config/transitions/ComposingTransition.java deleted file mode 100644 index 0c5a47f..0000000 --- a/src/main/java/com/google/devtools/build/lib/analysis/config/transitions/ComposingTransition.java +++ /dev/null
@@ -1,151 +0,0 @@ -// Copyright 2017 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.lib.analysis.config.transitions; - -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableMap; -import com.google.devtools.build.lib.analysis.RequiredConfigFragmentsProvider; -import com.google.devtools.build.lib.analysis.config.BuildOptionDetails; -import com.google.devtools.build.lib.analysis.config.BuildOptions; -import com.google.devtools.build.lib.analysis.config.BuildOptionsView; -import com.google.devtools.build.lib.events.EventHandler; -import java.util.Map; -import java.util.Objects; - -/** - * A configuration transition that composes two other transitions in an ordered sequence. - * - * <p>Example: - * - * <pre> - * transition1: { someSetting = $oldVal + " foo" } - * transition2: { someSetting = $oldVal + " bar" } - * ComposingTransition(transition1, transition2): { someSetting = $oldVal + " foo bar" } - * </pre> - */ -public final class ComposingTransition implements ConfigurationTransition { - private final ConfigurationTransition transition1; - private final ConfigurationTransition transition2; - - /** - * Creates a {@link ComposingTransition} that applies the sequence: {@code fromOptions -> - * transition1 -> transition2 -> toOptions }. - */ - ComposingTransition(ConfigurationTransition transition1, ConfigurationTransition transition2) { - this.transition1 = transition1; - this.transition2 = transition2; - } - - @Override - public void addRequiredFragments( - RequiredConfigFragmentsProvider.Builder requiredFragments, BuildOptionDetails optionDetails) { - // At first glance this code looks wrong. A composing transition applies transition2 over - // transition1's outputs, not the original options. We don't have to worry about that here - // because the reason we pass the options is so Starlark transitions can map individual flags - // like "//command_line_option:copts" to the fragments that own them. This doesn't depend on the - // flags' values. This is fortunate, because it producers simpler, faster code and cleaner - // interfaces. - transition1.addRequiredFragments(requiredFragments, optionDetails); - transition2.addRequiredFragments(requiredFragments, optionDetails); - } - - @Override - public Map<String, BuildOptions> apply(BuildOptionsView buildOptions, EventHandler eventHandler) - throws InterruptedException { - ImmutableMap.Builder<String, BuildOptions> toOptions = ImmutableMap.builder(); - Map<String, BuildOptions> transition1Output = - transition1.apply( - TransitionUtil.restrict(transition1, buildOptions.underlying()), eventHandler); - for (Map.Entry<String, BuildOptions> entry1 : transition1Output.entrySet()) { - Map<String, BuildOptions> transition2Output = - transition2.apply(TransitionUtil.restrict(transition2, entry1.getValue()), eventHandler); - for (Map.Entry<String, BuildOptions> entry2 : transition2Output.entrySet()) { - toOptions.put(composeKeys(entry1.getKey(), entry2.getKey()), entry2.getValue()); - } - } - return toOptions.buildOrThrow(); - } - - @Override - public String reasonForOverride() { - return "Basic abstraction for combining other transitions"; - } - - @Override - public String getName() { - return "(" + transition1.getName() + " + " + transition2.getName() + ")"; - } - - // Override to allow recursive visiting. - @Override - public <E extends Exception> void visit(Visitor<E> visitor) throws E { - this.transition1.visit(visitor); - this.transition2.visit(visitor); - } - - @Override - public int hashCode() { - return Objects.hash(transition1, transition2); - } - - @Override - public boolean equals(Object other) { - return other instanceof ComposingTransition composingTransition - && composingTransition.transition1.equals(this.transition1) - && ((ComposingTransition) other).transition2.equals(this.transition2); - } - - /** - * Creates a {@link ComposingTransition} that applies the sequence: {@code fromOptions -> - * transition1 -> transition2 -> toOptions }. - * - * <p>Note that this method checks for transitions that cannot be composed, such as if one of the - * transitions is {@link NoTransition}, and returns an efficiently composed transition. - */ - public static ConfigurationTransition of( - ConfigurationTransition transition1, ConfigurationTransition transition2) { - Preconditions.checkNotNull(transition1); - Preconditions.checkNotNull(transition2); - - if (transition1 == NoTransition.INSTANCE) { - // Since transition1 causes no changes, use transition2 directly. - return transition2; - } else if (transition2 == NoTransition.INSTANCE) { - // Since transition2 causes no changes, use transition 1 directly. - return transition1; - } - - return new ComposingTransition(transition1, transition2); - } - - /** - * Composes a new key out of two given keys. Composing two split transitions is not allowed at the - * moment, so what this essentially does are (1) make sure not both transitions are split and (2) - * choose one from a split transition, if there's any, or return {@code PATCH_TRANSITION_KEY), - * if there isn't. - */ - private String composeKeys(String key1, String key2) { - if (!key1.equals(PATCH_TRANSITION_KEY)) { - if (!key2.equals(PATCH_TRANSITION_KEY)) { - throw new IllegalStateException( - String.format( - "can't compose two split transitions %s and %s", - transition1.getName(), transition2.getName())); - } - return key1; - } - return key2; - } -}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/transitions/ComposingTransitionFactory.java b/src/main/java/com/google/devtools/build/lib/analysis/config/transitions/ComposingTransitionFactory.java index 8efe769..09bfcff 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/config/transitions/ComposingTransitionFactory.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/config/transitions/ComposingTransitionFactory.java
@@ -15,6 +15,14 @@ import com.google.auto.value.AutoValue; import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; +import com.google.devtools.build.lib.analysis.RequiredConfigFragmentsProvider; +import com.google.devtools.build.lib.analysis.config.BuildOptionDetails; +import com.google.devtools.build.lib.analysis.config.BuildOptions; +import com.google.devtools.build.lib.analysis.config.BuildOptionsView; +import com.google.devtools.build.lib.events.EventHandler; +import java.util.Map; +import java.util.Objects; /** * A transition factory that composes two other transition factories in an ordered sequence. @@ -99,4 +107,101 @@ this.transitionFactory1().visit(visitor); this.transitionFactory2().visit(visitor); } + + /** A configuration transition that composes two other transitions in an ordered sequence. */ + private static final class ComposingTransition implements ConfigurationTransition { + private final ConfigurationTransition transition1; + private final ConfigurationTransition transition2; + + /** + * Creates a {@link ComposingTransition} that applies the sequence: {@code fromOptions -> + * transition1 -> transition2 -> toOptions }. + */ + private ComposingTransition( + ConfigurationTransition transition1, ConfigurationTransition transition2) { + this.transition1 = transition1; + this.transition2 = transition2; + } + + @Override + public void addRequiredFragments( + RequiredConfigFragmentsProvider.Builder requiredFragments, + BuildOptionDetails optionDetails) { + // At first glance this code looks wrong. A composing transition applies transition2 over + // transition1's outputs, not the original options. We don't have to worry about that here + // because the reason we pass the options is so Starlark transitions can map individual flags + // like "//command_line_option:copts" to the fragments that own them. This doesn't depend on + // the + // flags' values. This is fortunate, because it producers simpler, faster code and cleaner + // interfaces. + transition1.addRequiredFragments(requiredFragments, optionDetails); + transition2.addRequiredFragments(requiredFragments, optionDetails); + } + + @Override + public ImmutableMap<String, BuildOptions> apply( + BuildOptionsView buildOptions, EventHandler eventHandler) throws InterruptedException { + ImmutableMap.Builder<String, BuildOptions> toOptions = ImmutableMap.builder(); + Map<String, BuildOptions> transition1Output = + transition1.apply( + TransitionUtil.restrict(transition1, buildOptions.underlying()), eventHandler); + for (Map.Entry<String, BuildOptions> entry1 : transition1Output.entrySet()) { + Map<String, BuildOptions> transition2Output = + transition2.apply( + TransitionUtil.restrict(transition2, entry1.getValue()), eventHandler); + for (Map.Entry<String, BuildOptions> entry2 : transition2Output.entrySet()) { + toOptions.put(composeKeys(entry1.getKey(), entry2.getKey()), entry2.getValue()); + } + } + return toOptions.buildOrThrow(); + } + + @Override + public String reasonForOverride() { + return "Basic abstraction for combining other transitions"; + } + + @Override + public String getName() { + return "(" + transition1.getName() + " + " + transition2.getName() + ")"; + } + + // Override to allow recursive visiting. + @Override + public <E extends Exception> void visit(Visitor<E> visitor) throws E { + this.transition1.visit(visitor); + this.transition2.visit(visitor); + } + + @Override + public int hashCode() { + return Objects.hash(transition1, transition2); + } + + @Override + public boolean equals(Object other) { + return other instanceof ComposingTransition composingTransition + && composingTransition.transition1.equals(this.transition1) + && ((ComposingTransition) other).transition2.equals(this.transition2); + } + + /** + * Composes a new key out of two given keys. Composing two split transitions is not allowed at + * the moment, so what this essentially does are (1) make sure not both transitions are split + * and (2) choose one from a split transition, if there's any, or return {@code + * PATCH_TRANSITION_KEY}, if there isn't. + */ + private String composeKeys(String key1, String key2) { + if (!key1.equals(PATCH_TRANSITION_KEY)) { + if (!key2.equals(PATCH_TRANSITION_KEY)) { + throw new IllegalStateException( + String.format( + "can't compose two split transitions %s and %s", + transition1.getName(), transition2.getName())); + } + return key1; + } + return key2; + } + } }
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkTransition.java b/src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkTransition.java index 0584a4c..01cf552 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkTransition.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkTransition.java
@@ -133,7 +133,7 @@ * same configuration. * * @param root transition that was applied. Likely a {@link - * com.google.devtools.build.lib.analysis.config.transitions.ComposingTransition} so we + * com.google.devtools.build.lib.analysis.config.transitions.ComposingTransitionFactory} so we * decompose and post-process all StarlarkTransitions out of whatever transition is passed * here. * @param details a StarlarkBuildSettingsDetailsValue whose corresponding key was all the input
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/config/transitions/BUILD b/src/test/java/com/google/devtools/build/lib/analysis/config/transitions/BUILD index a6fd1a5..18b192d 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/config/transitions/BUILD +++ b/src/test/java/com/google/devtools/build/lib/analysis/config/transitions/BUILD
@@ -23,7 +23,6 @@ "//src/main/java/com/google/devtools/build/lib/analysis:config/core_options", "//src/main/java/com/google/devtools/build/lib/analysis:config/fragment_options", "//src/main/java/com/google/devtools/build/lib/analysis:config/transitions/comparing_transition", - "//src/main/java/com/google/devtools/build/lib/analysis:config/transitions/composing_transition", "//src/main/java/com/google/devtools/build/lib/analysis:config/transitions/composing_transition_factory", "//src/main/java/com/google/devtools/build/lib/analysis:config/transitions/configuration_transition", "//src/main/java/com/google/devtools/build/lib/analysis:config/transitions/no_config_transition",
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/config/transitions/ComposingTransitionFactoryTest.java b/src/test/java/com/google/devtools/build/lib/analysis/config/transitions/ComposingTransitionFactoryTest.java index b0ab587..2ea0e26 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/config/transitions/ComposingTransitionFactoryTest.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/config/transitions/ComposingTransitionFactoryTest.java
@@ -18,11 +18,17 @@ import static org.junit.Assert.assertThrows; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; +import com.google.devtools.build.lib.analysis.RequiredConfigFragmentsProvider; import com.google.devtools.build.lib.analysis.config.BuildOptions; +import com.google.devtools.build.lib.analysis.config.BuildOptionsView; +import com.google.devtools.build.lib.analysis.config.FragmentOptions; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.events.EventHandler; import com.google.devtools.build.lib.events.StoredEventHandler; +import com.google.devtools.build.lib.rules.cpp.CppOptions; +import com.google.devtools.build.lib.rules.java.JavaOptions; import java.util.Collection; import java.util.Map; import java.util.stream.IntStream; @@ -212,4 +218,48 @@ return true; } } + + /** Custom fragment for use in tests. */ + private static final class TransitionFactoryWithCustomFragments + implements TransitionFactory<StubData> { + private final ImmutableSet<Class<? extends FragmentOptions>> fragments; + + TransitionFactoryWithCustomFragments(ImmutableSet<Class<? extends FragmentOptions>> fragments) { + this.fragments = fragments; + } + + @Override + public ConfigurationTransition create(StubData data) { + return new PatchTransition() { + @Override + public ImmutableSet<Class<? extends FragmentOptions>> requiresOptionFragments() { + return fragments; + } + + @Override + public BuildOptions patch(BuildOptionsView options, EventHandler eventHandler) { + return options.underlying(); + } + }; + } + + @Override + public TransitionType transitionType() { + return TransitionType.ANY; + } + } + + @Test + public void composed_required_fragments() throws Exception { + TransitionFactory<StubData> composed = + ComposingTransitionFactory.of( + new TransitionFactoryWithCustomFragments(ImmutableSet.of(CppOptions.class)), + new TransitionFactoryWithCustomFragments(ImmutableSet.of(JavaOptions.class))); + RequiredConfigFragmentsProvider.Builder requiredFragments = + RequiredConfigFragmentsProvider.builder(); + ConfigurationTransition transition = composed.create(new StubData()); + transition.addRequiredFragments(requiredFragments, null); + assertThat(requiredFragments.build().getOptionsClasses()) + .containsExactly(CppOptions.class, JavaOptions.class); + } }
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/config/transitions/ComposingTransitionTest.java b/src/test/java/com/google/devtools/build/lib/analysis/config/transitions/ComposingTransitionTest.java deleted file mode 100644 index d7ee20d..0000000 --- a/src/test/java/com/google/devtools/build/lib/analysis/config/transitions/ComposingTransitionTest.java +++ /dev/null
@@ -1,225 +0,0 @@ -// Copyright 2019 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -package com.google.devtools.build.lib.analysis.config.transitions; - -import static com.google.common.collect.ImmutableMap.toImmutableMap; -import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.assertThrows; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; -import com.google.devtools.build.lib.analysis.RequiredConfigFragmentsProvider; -import com.google.devtools.build.lib.analysis.config.BuildOptions; -import com.google.devtools.build.lib.analysis.config.BuildOptionsView; -import com.google.devtools.build.lib.analysis.config.FragmentOptions; -import com.google.devtools.build.lib.cmdline.Label; -import com.google.devtools.build.lib.events.EventHandler; -import com.google.devtools.build.lib.events.StoredEventHandler; -import com.google.devtools.build.lib.rules.cpp.CppOptions; -import com.google.devtools.build.lib.rules.java.JavaOptions; -import java.util.Map; -import java.util.stream.IntStream; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** Tests for {@link ComposingTransition}. */ -@RunWith(JUnit4.class) -public final class ComposingTransitionTest { - // Use starlark flags for the test since they are easy to set and check. - private static final Label FLAG_1 = Label.parseCanonicalUnchecked("//flag1"); - private static final Label FLAG_2 = Label.parseCanonicalUnchecked("//flag2"); - private EventHandler eventHandler; - - @Before - public void init() { - eventHandler = new StoredEventHandler(); - } - - @Test - public void compose_patch_patch() throws Exception { - // Same flag, will overwrite. - ConfigurationTransition composed = - ComposingTransition.of(new StubPatch(FLAG_1, "value1"), new StubPatch(FLAG_1, "value2")); - - assertThat(composed).isNotNull(); - Map<String, BuildOptions> results = - composed.apply( - TransitionUtil.restrict(composed, BuildOptions.builder().build()), eventHandler); - assertThat(results).isNotNull(); - assertThat(results).hasSize(1); - BuildOptions result = Iterables.getOnlyElement(results.values()); - assertThat(result).isNotNull(); - assertThat(result.getStarlarkOptions()).containsEntry(FLAG_1, "value2"); - } - - @Test - public void compose_patch_split() throws Exception { - // Different flags, will combine. - ConfigurationTransition composed = - ComposingTransition.of( - new StubPatch(FLAG_1, "value1"), new StubSplit(FLAG_2, "value2a", "value2b")); - - assertThat(composed).isNotNull(); - Map<String, BuildOptions> results = - composed.apply( - TransitionUtil.restrict(composed, BuildOptions.builder().build()), eventHandler); - assertThat(results).isNotNull(); - assertThat(results).hasSize(2); - - BuildOptions result0 = results.get("stub_split0"); - assertThat(result0).isNotNull(); - assertThat(result0.getStarlarkOptions()).containsEntry(FLAG_1, "value1"); - assertThat(result0.getStarlarkOptions()).containsEntry(FLAG_2, "value2a"); - - BuildOptions result1 = results.get("stub_split1"); - assertThat(result1).isNotNull(); - assertThat(result1.getStarlarkOptions()).containsEntry(FLAG_1, "value1"); - assertThat(result1.getStarlarkOptions()).containsEntry(FLAG_2, "value2b"); - } - - @Test - public void compose_split_patch() throws Exception { - // Different flags, will combine. - ConfigurationTransition composed = - ComposingTransition.of( - new StubSplit(FLAG_1, "value1a", "value1b"), new StubPatch(FLAG_2, "value2")); - - assertThat(composed).isNotNull(); - Map<String, BuildOptions> results = - composed.apply( - TransitionUtil.restrict(composed, BuildOptions.builder().build()), eventHandler); - assertThat(results).isNotNull(); - assertThat(results).hasSize(2); - - BuildOptions result0 = results.get("stub_split0"); - assertThat(result0).isNotNull(); - assertThat(result0.getStarlarkOptions()).containsEntry(FLAG_1, "value1a"); - assertThat(result0.getStarlarkOptions()).containsEntry(FLAG_2, "value2"); - - BuildOptions result1 = results.get("stub_split1"); - assertThat(result1).isNotNull(); - assertThat(result1.getStarlarkOptions()).containsEntry(FLAG_1, "value1b"); - assertThat(result1.getStarlarkOptions()).containsEntry(FLAG_2, "value2"); - } - - @Test - public void compose_split_split_disallowed() { - // Combining two split transitions is not allowed. - ConfigurationTransition composed = - ComposingTransition.of( - new StubSplit(FLAG_1, "value1a", "value1b"), - new StubSplit(FLAG_2, "value2a", "value2b")); - - assertThat(composed).isNotNull(); - assertThrows( - IllegalStateException.class, - () -> - composed.apply( - TransitionUtil.restrict(composed, BuildOptions.builder().build()), eventHandler)); - } - - @Test - public void compose_noTrans_first() { - StubPatch patch = new StubPatch(FLAG_1, "value"); - ConfigurationTransition composed = ComposingTransition.of(NoTransition.INSTANCE, patch); - - assertThat(composed).isNotNull(); - assertThat(composed).isEqualTo(patch); - } - - @Test - public void compose_noTrans_second() { - StubPatch patch = new StubPatch(FLAG_1, "value"); - ConfigurationTransition composed = ComposingTransition.of(patch, NoTransition.INSTANCE); - - assertThat(composed).isNotNull(); - assertThat(composed).isEqualTo(patch); - } - - // Helper methods and classes for the tests. - private static BuildOptions updateOptions(BuildOptions source, Label flag, String value) { - return source.clone().toBuilder().addStarlarkOption(flag, value).build(); - } - - private static final class StubPatch implements PatchTransition { - private final Label flagLabel; - private final String flagValue; - - StubPatch(Label flagLabel, String flagValue) { - this.flagLabel = flagLabel; - this.flagValue = flagValue; - } - - @Override - public BuildOptions patch(BuildOptionsView options, EventHandler eventHandler) { - return updateOptions(options.underlying(), flagLabel, flagValue); - } - } - - private static final class StubSplit implements SplitTransition { - private final Label flagLabel; - private final ImmutableList<String> flagValues; - - StubSplit(Label flagLabel, String... flagValues) { - this.flagLabel = flagLabel; - this.flagValues = ImmutableList.copyOf(flagValues); - } - - @Override - public ImmutableMap<String, BuildOptions> split( - BuildOptionsView options, EventHandler eventHandler) { - return IntStream.range(0, flagValues.size()) - .boxed() - .collect( - toImmutableMap( - i -> "stub_split" + i, - i -> updateOptions(options.underlying(), flagLabel, flagValues.get(i)))); - } - } - - private static final class TransitionWithCustomFragments implements PatchTransition { - private final ImmutableSet<Class<? extends FragmentOptions>> fragments; - - TransitionWithCustomFragments(ImmutableSet<Class<? extends FragmentOptions>> fragments) { - this.fragments = fragments; - } - - @Override - public ImmutableSet<Class<? extends FragmentOptions>> requiresOptionFragments() { - return fragments; - } - - @Override - public BuildOptions patch(BuildOptionsView options, EventHandler eventHandler) { - return options.underlying(); - } - } - - @Test - public void composed_required_fragments() throws Exception { - ConfigurationTransition composed = - ComposingTransition.of( - new TransitionWithCustomFragments(ImmutableSet.of(CppOptions.class)), - new TransitionWithCustomFragments(ImmutableSet.of(JavaOptions.class))); - RequiredConfigFragmentsProvider.Builder requiredFragments = - RequiredConfigFragmentsProvider.builder(); - composed.addRequiredFragments(requiredFragments, null); - assertThat(requiredFragments.build().getOptionsClasses()) - .containsExactly(CppOptions.class, JavaOptions.class); - } -}
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/BUILD b/src/test/java/com/google/devtools/build/lib/skyframe/BUILD index 4dc80ca..ddc1fab 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/BUILD +++ b/src/test/java/com/google/devtools/build/lib/skyframe/BUILD
@@ -138,7 +138,6 @@ "//src/main/java/com/google/devtools/build/lib/analysis:config/fragment_options", "//src/main/java/com/google/devtools/build/lib/analysis:config/starlark_exec_transition_loader", "//src/main/java/com/google/devtools/build/lib/analysis:config/toolchain_type_requirement", - "//src/main/java/com/google/devtools/build/lib/analysis:config/transitions/composing_transition", "//src/main/java/com/google/devtools/build/lib/analysis:config/transitions/configuration_transition", "//src/main/java/com/google/devtools/build/lib/analysis:config/transitions/no_transition", "//src/main/java/com/google/devtools/build/lib/analysis:config/transitions/patch_transition",