From b099292d4f513012c1c63a4e73cec043015a55fc Mon Sep 17 00:00:00 2001 From: gregce Date: Thu, 4 Jan 2018 14:04:13 -0800 Subject: Move PatchTransition and kin to analysis.config.transitions. HostTransition can't be migrated yet because it depends on BuildConfiguration. PiperOrigin-RevId: 180842784 --- .../lib/analysis/config/BuildConfiguration.java | 2 + .../analysis/config/ComposingPatchTransition.java | 36 --------- .../config/ComposingRuleTransitionFactory.java | 2 + .../analysis/config/ComposingSplitTransition.java | 93 ---------------------- .../lib/analysis/config/ConfigurationResolver.java | 3 +- .../analysis/config/DynamicTransitionMapper.java | 1 + .../build/lib/analysis/config/HostTransition.java | 2 + .../build/lib/analysis/config/PatchTransition.java | 61 -------------- .../lib/analysis/config/TransitionResolver.java | 2 + .../transitions/ComposingPatchTransition.java | 37 +++++++++ .../transitions/ComposingSplitTransition.java | 91 +++++++++++++++++++++ .../config/transitions/PatchTransition.java | 61 ++++++++++++++ 12 files changed, 200 insertions(+), 191 deletions(-) delete mode 100644 src/main/java/com/google/devtools/build/lib/analysis/config/ComposingPatchTransition.java delete mode 100644 src/main/java/com/google/devtools/build/lib/analysis/config/ComposingSplitTransition.java delete mode 100644 src/main/java/com/google/devtools/build/lib/analysis/config/PatchTransition.java create mode 100644 src/main/java/com/google/devtools/build/lib/analysis/config/transitions/ComposingPatchTransition.java create mode 100644 src/main/java/com/google/devtools/build/lib/analysis/config/transitions/ComposingSplitTransition.java create mode 100644 src/main/java/com/google/devtools/build/lib/analysis/config/transitions/PatchTransition.java (limited to 'src/main/java/com/google/devtools/build/lib/analysis/config') diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java index 3eb69668f7..9ddd66e29d 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java @@ -39,6 +39,8 @@ import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.actions.FileWriteAction; +import com.google.devtools.build.lib.analysis.config.transitions.ComposingPatchTransition; +import com.google.devtools.build.lib.analysis.config.transitions.PatchTransition; import com.google.devtools.build.lib.buildeventstream.BuildEvent; import com.google.devtools.build.lib.buildeventstream.BuildEventConverters; import com.google.devtools.build.lib.buildeventstream.BuildEventId; diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/ComposingPatchTransition.java b/src/main/java/com/google/devtools/build/lib/analysis/config/ComposingPatchTransition.java deleted file mode 100644 index 83fcf6dbb9..0000000000 --- a/src/main/java/com/google/devtools/build/lib/analysis/config/ComposingPatchTransition.java +++ /dev/null @@ -1,36 +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; - -import com.google.common.collect.Iterables; - -/** - * A {@link ComposingSplitTransition} that only supports {@link PatchTransition}s - * - *

Calling code that doesn't want to have to handle splits should prefer this version. - */ -public class ComposingPatchTransition implements PatchTransition { - private final ComposingSplitTransition delegate; - - public ComposingPatchTransition(PatchTransition transition1, PatchTransition transition2) { - this.delegate = new ComposingSplitTransition(transition1, transition2); - } - - @Override - public BuildOptions apply(BuildOptions options) { - return Iterables.getOnlyElement(delegate.split(options)); - } -} - diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/ComposingRuleTransitionFactory.java b/src/main/java/com/google/devtools/build/lib/analysis/config/ComposingRuleTransitionFactory.java index a6a54a28a6..f5f489f655 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/config/ComposingRuleTransitionFactory.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/config/ComposingRuleTransitionFactory.java @@ -15,6 +15,8 @@ package com.google.devtools.build.lib.analysis.config; +import com.google.devtools.build.lib.analysis.config.transitions.ComposingPatchTransition; +import com.google.devtools.build.lib.analysis.config.transitions.PatchTransition; import com.google.devtools.build.lib.analysis.config.transitions.Transition; import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.packages.RuleTransitionFactory; diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/ComposingSplitTransition.java b/src/main/java/com/google/devtools/build/lib/analysis/config/ComposingSplitTransition.java deleted file mode 100644 index e0f40f88ec..0000000000 --- a/src/main/java/com/google/devtools/build/lib/analysis/config/ComposingSplitTransition.java +++ /dev/null @@ -1,93 +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; - -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import com.google.devtools.build.lib.analysis.config.transitions.ConfigurationTransitionProxy; -import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition; -import com.google.devtools.build.lib.analysis.config.transitions.Transition; -import java.util.List; - -/** - * A configuration transition that composes two other transitions in an ordered sequence. - * - *

Example: - *

- *   transition1: { someSetting = $oldVal + " foo" }
- *   transition2: { someSetting = $oldVal + " bar" }
- *   ComposingSplitTransition(transition1, transition2): { someSetting = $oldVal + " foo bar" }
- * 
- * - *

Child transitions can be {@link SplitTransition}s, {@link PatchTransition}s, or any - * combination thereof. We implement this class as a {@link SplitTransition} since that abstraction - * captures all possible combinations. - */ -public class ComposingSplitTransition implements SplitTransition { - private Transition transition1; - private Transition transition2; - - /** - * Creates a {@link ComposingSplitTransition} that applies the sequence: - * {@code fromOptions -> transition1 -> transition2 -> toOptions }. - */ - public ComposingSplitTransition(Transition transition1, Transition transition2) { - this.transition1 = verifySupported(transition1); - this.transition2 = verifySupported(transition2); - } - - @Override - public List split(BuildOptions buildOptions) { - ImmutableList.Builder toOptions = ImmutableList.builder(); - for (BuildOptions transition1Options : apply(buildOptions, transition1)) { - toOptions.addAll(apply(transition1Options, transition2)); - } - return toOptions.build(); - } - - /** - * Verifies support for the given transition type. Throws an {@link IllegalArgumentException} if - * unsupported. - */ - private Transition verifySupported(Transition transition) { - Preconditions.checkArgument(transition instanceof PatchTransition - || transition instanceof SplitTransition); - return transition; - } - - /** - * Applies the given transition over the given {@link BuildOptions}, returns the result. - */ - // TODO(gregce): move this somewhere more general. This isn't intrinsic to composed splits. - static List apply(BuildOptions fromOptions, Transition transition) { - if (transition == ConfigurationTransitionProxy.NONE) { - return ImmutableList.of(fromOptions); - } else if (transition instanceof PatchTransition) { - return ImmutableList.of(((PatchTransition) transition).apply(fromOptions)); - } else if (transition instanceof SplitTransition) { - SplitTransition split = (SplitTransition) transition; - List splitOptions = split.split(fromOptions); - if (splitOptions.isEmpty()) { - return ImmutableList.of(fromOptions); - } else { - return splitOptions; - } - } else { - throw new IllegalStateException( - String.format("Unsupported composite transition type: %s", - transition.getClass().getName())); - } - } -} diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigurationResolver.java b/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigurationResolver.java index c10e265399..3bce74d771 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigurationResolver.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigurationResolver.java @@ -27,6 +27,7 @@ import com.google.common.collect.Sets; import com.google.devtools.build.lib.analysis.Dependency; import com.google.devtools.build.lib.analysis.TargetAndConfiguration; import com.google.devtools.build.lib.analysis.config.transitions.ConfigurationTransitionProxy; +import com.google.devtools.build.lib.analysis.config.transitions.PatchTransition; import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition; import com.google.devtools.build.lib.analysis.config.transitions.Transition; import com.google.devtools.build.lib.cmdline.Label; @@ -418,7 +419,7 @@ public final class ConfigurationResolver { result = ImmutableList.of(fromOptions); } else if (transition instanceof PatchTransition) { // TODO(bazel-team): safety-check that this never mutates fromOptions. - result = ImmutableList.of(((PatchTransition) transition).apply(fromOptions)); + result = ImmutableList.of(((PatchTransition) transition).apply(fromOptions)); } else if (transition instanceof SplitTransition) { List toOptions = ((SplitTransition) transition).split(fromOptions); if (toOptions.isEmpty()) { diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/DynamicTransitionMapper.java b/src/main/java/com/google/devtools/build/lib/analysis/config/DynamicTransitionMapper.java index 96316ebce5..e481fb1c45 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/config/DynamicTransitionMapper.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/config/DynamicTransitionMapper.java @@ -14,6 +14,7 @@ package com.google.devtools.build.lib.analysis.config; import com.google.common.collect.ImmutableMap; +import com.google.devtools.build.lib.analysis.config.transitions.PatchTransition; import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition; import com.google.devtools.build.lib.analysis.config.transitions.Transition; import com.google.devtools.build.lib.packages.Attribute; diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/HostTransition.java b/src/main/java/com/google/devtools/build/lib/analysis/config/HostTransition.java index 099c8fdf2f..08fd6095d0 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/config/HostTransition.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/config/HostTransition.java @@ -13,6 +13,8 @@ // limitations under the License. package com.google.devtools.build.lib.analysis.config; +import com.google.devtools.build.lib.analysis.config.transitions.PatchTransition; + /** * Dynamic transition to the host configuration. */ diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/PatchTransition.java b/src/main/java/com/google/devtools/build/lib/analysis/config/PatchTransition.java deleted file mode 100644 index fea95bac6a..0000000000 --- a/src/main/java/com/google/devtools/build/lib/analysis/config/PatchTransition.java +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2015 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; - -import com.google.devtools.build.lib.analysis.config.transitions.Transition; - -/** - * Interface for a configuration transition. - * - *

The concept is simple: given the input configuration's build options, the - * transition does whatever it wants to them and returns the modified result. - * - *

Implementations must be stateless: the output must exclusively depend on the - * input build options and any immutable member fields. Implementations must also override - * {@link Object#equals} and {@link Object#hashCode} unless exclusively accessed as - * singletons. For example: - * - *

- * public class MyTransition implements PatchTransition {
- *   public MyTransition INSTANCE = new MyTransition();
- *
- *   private MyTransition() {}
- *
- *   {@literal @}Override
- *   public BuildOptions apply(BuildOptions options) {
- *     BuildOptions toOptions = options.clone();
- *     // Change some setting on toOptions
- *     return toOptions;
- *   }
- * }
- * 
- * - *

For performance reasons, the input options are passed as a reference, not a - * copy. Implementations should always treat these as immutable, and call - * {@link com.google.devtools.build.lib.analysis.config.BuildOptions#clone} - * before making changes. Unfortunately, - * {@link com.google.devtools.build.lib.analysis.config.BuildOptions} doesn't currently - * enforce immutability. So care must be taken not to modify the wrong instance. - */ -public interface PatchTransition extends Transition { - - /** - * Applies the transition. - * - * @param options the options representing the input configuration to this transition. DO NOT - * MODIFY THIS VARIABLE WITHOUT CLONING IT FIRST. - * @return the options representing the desired post-transition configuration - */ - BuildOptions apply(BuildOptions options); -} diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/TransitionResolver.java b/src/main/java/com/google/devtools/build/lib/analysis/config/TransitionResolver.java index fe1a0f8f10..09fa8a1741 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/config/TransitionResolver.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/config/TransitionResolver.java @@ -17,7 +17,9 @@ package com.google.devtools.build.lib.analysis.config; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.devtools.build.lib.analysis.TargetAndConfiguration; +import com.google.devtools.build.lib.analysis.config.transitions.ComposingSplitTransition; import com.google.devtools.build.lib.analysis.config.transitions.ConfigurationTransitionProxy; +import com.google.devtools.build.lib.analysis.config.transitions.PatchTransition; import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition; import com.google.devtools.build.lib.analysis.config.transitions.Transition; import com.google.devtools.build.lib.packages.Attribute; diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/transitions/ComposingPatchTransition.java b/src/main/java/com/google/devtools/build/lib/analysis/config/transitions/ComposingPatchTransition.java new file mode 100644 index 0000000000..eade44b9e7 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/analysis/config/transitions/ComposingPatchTransition.java @@ -0,0 +1,37 @@ +// 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.collect.Iterables; +import com.google.devtools.build.lib.analysis.config.BuildOptions; + +/** + * A {@link ComposingSplitTransition} that only supports {@link PatchTransition}s + * + *

Calling code that doesn't want to have to handle splits should prefer this version. + */ +public class ComposingPatchTransition implements PatchTransition { + private final ComposingSplitTransition delegate; + + public ComposingPatchTransition(PatchTransition transition1, PatchTransition transition2) { + this.delegate = new ComposingSplitTransition(transition1, transition2); + } + + @Override + public BuildOptions apply(BuildOptions options) { + return Iterables.getOnlyElement(delegate.split(options)); + } +} + diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/transitions/ComposingSplitTransition.java b/src/main/java/com/google/devtools/build/lib/analysis/config/transitions/ComposingSplitTransition.java new file mode 100644 index 0000000000..d58bafd917 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/analysis/config/transitions/ComposingSplitTransition.java @@ -0,0 +1,91 @@ +// 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.ImmutableList; +import com.google.devtools.build.lib.analysis.config.BuildOptions; +import java.util.List; + +/** + * A configuration transition that composes two other transitions in an ordered sequence. + * + *

Example: + *

+ *   transition1: { someSetting = $oldVal + " foo" }
+ *   transition2: { someSetting = $oldVal + " bar" }
+ *   ComposingSplitTransition(transition1, transition2): { someSetting = $oldVal + " foo bar" }
+ * 
+ * + *

Child transitions can be {@link SplitTransition}s, {@link PatchTransition}s, or any + * combination thereof. We implement this class as a {@link SplitTransition} since that abstraction + * captures all possible combinations. + */ +public class ComposingSplitTransition implements SplitTransition { + private Transition transition1; + private Transition transition2; + + /** + * Creates a {@link ComposingSplitTransition} that applies the sequence: + * {@code fromOptions -> transition1 -> transition2 -> toOptions }. + */ + public ComposingSplitTransition(Transition transition1, Transition transition2) { + this.transition1 = verifySupported(transition1); + this.transition2 = verifySupported(transition2); + } + + @Override + public List split(BuildOptions buildOptions) { + ImmutableList.Builder toOptions = ImmutableList.builder(); + for (BuildOptions transition1Options : apply(buildOptions, transition1)) { + toOptions.addAll(apply(transition1Options, transition2)); + } + return toOptions.build(); + } + + /** + * Verifies support for the given transition type. Throws an {@link IllegalArgumentException} if + * unsupported. + */ + private Transition verifySupported(Transition transition) { + Preconditions.checkArgument(transition instanceof PatchTransition + || transition instanceof SplitTransition); + return transition; + } + + /** + * Applies the given transition over the given {@link BuildOptions}, returns the result. + */ + // TODO(gregce): move this somewhere more general. This isn't intrinsic to composed splits. + static List apply(BuildOptions fromOptions, Transition transition) { + if (transition == ConfigurationTransitionProxy.NONE) { + return ImmutableList.of(fromOptions); + } else if (transition instanceof PatchTransition) { + return ImmutableList.of(((PatchTransition) transition).apply(fromOptions)); + } else if (transition instanceof SplitTransition) { + SplitTransition split = (SplitTransition) transition; + List splitOptions = split.split(fromOptions); + if (splitOptions.isEmpty()) { + return ImmutableList.of(fromOptions); + } else { + return splitOptions; + } + } else { + throw new IllegalStateException( + String.format("Unsupported composite transition type: %s", + transition.getClass().getName())); + } + } +} diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/transitions/PatchTransition.java b/src/main/java/com/google/devtools/build/lib/analysis/config/transitions/PatchTransition.java new file mode 100644 index 0000000000..3fd096e89d --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/analysis/config/transitions/PatchTransition.java @@ -0,0 +1,61 @@ +// Copyright 2015 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.devtools.build.lib.analysis.config.BuildOptions; + +/** + * Interface for a configuration transition. + * + *

The concept is simple: given the input configuration's build options, the + * transition does whatever it wants to them and returns the modified result. + * + *

Implementations must be stateless: the output must exclusively depend on the + * input build options and any immutable member fields. Implementations must also override + * {@link Object#equals} and {@link Object#hashCode} unless exclusively accessed as + * singletons. For example: + * + *

+ * public class MyTransition implements PatchTransition {
+ *   public MyTransition INSTANCE = new MyTransition();
+ *
+ *   private MyTransition() {}
+ *
+ *   {@literal @}Override
+ *   public BuildOptions apply(BuildOptions options) {
+ *     BuildOptions toOptions = options.clone();
+ *     // Change some setting on toOptions
+ *     return toOptions;
+ *   }
+ * }
+ * 
+ * + *

For performance reasons, the input options are passed as a reference, not a + * copy. Implementations should always treat these as immutable, and call + * {@link com.google.devtools.build.lib.analysis.config.BuildOptions#clone} + * before making changes. Unfortunately, + * {@link com.google.devtools.build.lib.analysis.config.BuildOptions} doesn't currently + * enforce immutability. So care must be taken not to modify the wrong instance. + */ +public interface PatchTransition extends Transition { + + /** + * Applies the transition. + * + * @param options the options representing the input configuration to this transition. DO NOT + * MODIFY THIS VARIABLE WITHOUT CLONING IT FIRST. + * @return the options representing the desired post-transition configuration + */ + BuildOptions apply(BuildOptions options); +} -- cgit v1.2.3