Skip to content

Commit

Permalink
Add useful implementations of TransitionFactory.
Browse files Browse the repository at this point in the history
Eventually, the FooTransition classes should be refactored to be
FooTransitionFactory directly, but this can be done after all uses are
updated.

Part of work on bazelbuild#7814.
  • Loading branch information
katre committed Mar 25, 2019
1 parent 738c3e2 commit 0408420
Show file tree
Hide file tree
Showing 6 changed files with 222 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/main/java/com/google/devtools/build/lib/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,7 @@ java_library(
"//src/main/java/com/google/devtools/common/options",
"//src/main/java/com/google/devtools/common/options:invocation_policy",
"//src/main/protobuf:invocation_policy_java_proto",
"//third_party:auto_value",
"//third_party:guava",
"//third_party:jsr305",
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
// limitations under the License.
package com.google.devtools.build.lib.analysis.config;

import com.google.auto.value.AutoValue;
import com.google.devtools.build.lib.analysis.config.transitions.PatchTransition;
import com.google.devtools.build.lib.analysis.config.transitions.TransitionFactory;
import com.google.devtools.build.lib.analysis.config.transitions.TransitionFactory.TransitionFactoryData;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;

/** Dynamic transition to the host configuration. */
Expand Down Expand Up @@ -50,4 +53,37 @@ public BuildOptions patch(BuildOptions options) {
return options.createHostOptions();
}
}

/** Returns a {@link TransitionFactory} instance that generates the host transition. */
public static <T extends TransitionFactoryData> TransitionFactory<T> createFactory() {
return new AutoValue_HostTransition_Factory<>();
}

/**
* Returns {@code true} if the given {@link TransitionFactory} is an instance of the host
* transition.
*/
public static <T extends TransitionFactoryData> boolean isInstance(
TransitionFactory<T> instance) {
return instance instanceof Factory;
}

/** A {@link TransitionFactory} implementation that generates the host transition. */
@AutoValue
abstract static class Factory<T extends TransitionFactoryData> implements TransitionFactory<T> {
@Override
public PatchTransition create(TransitionFactoryData unused) {
return INSTANCE;
}

@Override
public boolean isHost() {
return true;
}

@Override
public boolean isFinal() {
return true;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.google.devtools.build.lib.analysis.config;

import com.google.auto.value.AutoValue;
import com.google.devtools.build.lib.analysis.config.transitions.ConfigurationTransition;
import com.google.devtools.build.lib.analysis.config.transitions.NoTransition;
import com.google.devtools.build.lib.analysis.config.transitions.NullTransition;
import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition;
import com.google.devtools.build.lib.analysis.config.transitions.TransitionFactory;
import com.google.devtools.build.lib.analysis.config.transitions.TransitionFactory.TransitionFactoryData;

/** Useful implementations of {@link TransitionFactory}. */
// This class is in lib.analysis.config in order to access HostTransition, which is not visible to
// lib.analysis.config.transitions.
public final class TransitionFactories {
// Don't instantiate this class.
private TransitionFactories() {}

/** Returns a {@link TransitionFactory} that wraps a static transition. */
public static <T extends TransitionFactoryData> TransitionFactory<T> of(
ConfigurationTransition transition) {
if (transition instanceof HostTransition) {
return HostTransition.createFactory();
} else if (transition instanceof NoTransition) {
return NoTransition.createFactory();
} else if (transition instanceof NullTransition) {
return NullTransition.createFactory();
} else if (transition instanceof SplitTransition) {
return split((SplitTransition) transition);
}
return new AutoValue_TransitionFactories_IdentityFactory(transition);
}

/** Returns a {@link TransitionFactory} that wraps a static split transition. */
public static <T extends TransitionFactoryData> TransitionFactory<T> split(
SplitTransition splitTransition) {
return new AutoValue_TransitionFactories_SplitTransitionFactory<T>(splitTransition);
}

/** A {@link TransitionFactory} implementation that wraps a static transition. */
@AutoValue
abstract static class IdentityFactory<T extends TransitionFactoryData>
implements TransitionFactory<T> {

abstract ConfigurationTransition transition();

@Override
public ConfigurationTransition create(T data) {
return transition();
}
}

/** A {@link TransitionFactory} implementation that wraps a split transition. */
@AutoValue
abstract static class SplitTransitionFactory<T extends TransitionFactoryData>
implements TransitionFactory<T> {
abstract SplitTransition splitTransition();

@Override
public SplitTransition create(T data) {
return splitTransition();
}

@Override
public boolean isSplit() {
return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
// limitations under the License.
package com.google.devtools.build.lib.analysis.config.transitions;

import com.google.auto.value.AutoValue;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.transitions.TransitionFactory.TransitionFactoryData;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;

/** No-op configuration transition. */
Expand All @@ -27,4 +29,27 @@ private NoTransition() {}
public BuildOptions patch(BuildOptions options) {
return options;
}

/** Returns a {@link TransitionFactory} instance that generates the no transition. */
public static <T extends TransitionFactoryData> TransitionFactory<T> createFactory() {
return new AutoValue_NoTransition_Factory<>();
}

/**
* Returns {@code true} if the given {@link TransitionFactory} is an instance of the no
* transition.
*/
public static <T extends TransitionFactoryData> boolean isInstance(
TransitionFactory<T> instance) {
return instance instanceof Factory;
}

/** A {@link TransitionFactory} implementation that generates the no transition. */
@AutoValue
abstract static class Factory<T extends TransitionFactoryData> implements TransitionFactory<T> {
@Override
public ConfigurationTransition create(TransitionFactoryData unused) {
return INSTANCE;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
// limitations under the License.
package com.google.devtools.build.lib.analysis.config.transitions;

import com.google.auto.value.AutoValue;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.transitions.TransitionFactory.TransitionFactoryData;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;

/** A {@link PatchTransition} to a null configuration. */
Expand All @@ -32,4 +34,32 @@ public BuildOptions patch(BuildOptions options) {
+ "method to get results we know ahead of time. If there's ever a need to properly "
+ "implement this method we can always do so.");
}

/** Returns a {@link TransitionFactory} instance that generates the null transition. */
public static <T extends TransitionFactoryData> TransitionFactory<T> createFactory() {
return new AutoValue_NullTransition_Factory<>();
}

/**
* Returns {@code true} if the given {@link TransitionFactory} is an instance of the null
* transition.
*/
public static <T extends TransitionFactoryData> boolean isInstance(
TransitionFactory<T> instance) {
return instance instanceof Factory;
}

/** A {@link TransitionFactory} implementation that generates the null transition. */
@AutoValue
abstract static class Factory<T extends TransitionFactoryData> implements TransitionFactory<T> {
@Override
public ConfigurationTransition create(TransitionFactoryData unused) {
return INSTANCE;
}

@Override
public boolean isFinal() {
return true;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.google.devtools.build.lib.analysis.config;

import static com.google.common.truth.Truth.assertThat;

import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.analysis.config.transitions.NoTransition;
import com.google.devtools.build.lib.analysis.config.transitions.NullTransition;
import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition;
import com.google.devtools.build.lib.analysis.config.transitions.TransitionFactory;
import com.google.devtools.build.lib.analysis.config.transitions.TransitionFactory.TransitionFactoryData;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for {@link TransitionFactories}. */
@RunWith(JUnit4.class)
public class TransitionFactoriesTest {

@Test
public void hostTransition() {
TransitionFactory<TransitionFactoryData> factory =
TransitionFactories.of(HostTransition.INSTANCE);
assertThat(factory).isNotNull();
assertThat(HostTransition.isInstance(factory)).isTrue();
assertThat(factory.isHost()).isTrue();
assertThat(factory.isSplit()).isFalse();
assertThat(factory.isFinal()).isTrue();
}

@Test
public void noTransition() {
TransitionFactory<TransitionFactoryData> factory =
TransitionFactories.of(NoTransition.INSTANCE);
assertThat(factory).isNotNull();
assertThat(NoTransition.isInstance(factory)).isTrue();
assertThat(factory.isHost()).isFalse();
assertThat(factory.isSplit()).isFalse();
assertThat(factory.isFinal()).isFalse();
}

@Test
public void nullTransition() {
TransitionFactory<TransitionFactoryData> factory =
TransitionFactories.of(NullTransition.INSTANCE);
assertThat(factory).isNotNull();
assertThat(NullTransition.isInstance(factory)).isTrue();
assertThat(factory.isHost()).isFalse();
assertThat(factory.isSplit()).isFalse();
assertThat(factory.isFinal()).isTrue();
}

@Test
public void splitTransition() {
TransitionFactory<TransitionFactoryData> factory =
TransitionFactories.of(
(SplitTransition) buildOptions -> ImmutableList.of(buildOptions.clone()));
assertThat(factory).isNotNull();
assertThat(factory.isHost()).isFalse();
assertThat(factory.isSplit()).isTrue();
assertThat(factory.isFinal()).isFalse();
}
}

0 comments on commit 0408420

Please sign in to comment.