Report fragments Starlark transitions use.

Also add some straggler native transitions.

With all transitions converted, also remove legacy
PatchTransition.patch(BuildOptions) and
SplitTransition.split(BuildOptions).

In service of https://github.com/bazelbuild/bazel/issues/11258.

PiperOrigin-RevId: 317383960
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/CircularDependencyTest.java b/src/test/java/com/google/devtools/build/lib/analysis/CircularDependencyTest.java
index 47f1fcb..077af5b 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/CircularDependencyTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/CircularDependencyTest.java
@@ -23,9 +23,12 @@
 import static org.junit.Assert.assertThrows;
 
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
 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.CoreOptions;
+import com.google.devtools.build.lib.analysis.config.FragmentOptions;
 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.util.BuildViewTestCase;
@@ -268,17 +271,24 @@
                         @Override
                         public SplitTransition create(AttributeTransitionData data) {
                           return new SplitTransition() {
+
+                            @Override
+                            public ImmutableSet<Class<? extends FragmentOptions>>
+                                requiresOptionFragments() {
+                              return ImmutableSet.of(CoreOptions.class);
+                            }
+
                             @Override
                             public Map<String, BuildOptions> split(
-                                BuildOptions options, EventHandler eventHandler) {
+                                BuildOptionsView options, EventHandler eventHandler) {
                               String define = data.attributes().get("define", STRING);
-                              BuildOptions newOptions = options.clone();
+                              BuildOptionsView newOptions = options.clone();
                               CoreOptions optionsFragment = newOptions.get(CoreOptions.class);
                               optionsFragment.commandLineBuildVariables =
                                   optionsFragment.commandLineBuildVariables.stream()
                                       .filter((pair) -> !pair.getKey().equals(define))
                                       .collect(toImmutableList());
-                              return ImmutableMap.of("define_cleaner", newOptions);
+                              return ImmutableMap.of("define_cleaner", newOptions.underlying());
                             }
                           };
                         }
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/StarlarkAttrTransitionProviderTest.java b/src/test/java/com/google/devtools/build/lib/analysis/StarlarkAttrTransitionProviderTest.java
index 7206364..012886b 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/StarlarkAttrTransitionProviderTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/StarlarkAttrTransitionProviderTest.java
@@ -25,13 +25,19 @@
 import com.google.common.eventbus.EventBus;
 import com.google.devtools.build.lib.analysis.StarlarkRuleTransitionProviderTest.DummyTestLoader;
 import com.google.devtools.build.lib.analysis.config.CoreOptions;
+import com.google.devtools.build.lib.analysis.config.transitions.ConfigurationTransition;
 import com.google.devtools.build.lib.analysis.test.TestConfiguration.TestOptions;
 import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
 import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.packages.AttributeTransitionData;
+import com.google.devtools.build.lib.packages.ConfiguredAttributeMapper;
 import com.google.devtools.build.lib.packages.Provider;
+import com.google.devtools.build.lib.packages.Rule;
 import com.google.devtools.build.lib.packages.StarlarkProvider;
 import com.google.devtools.build.lib.packages.StructImpl;
 import com.google.devtools.build.lib.packages.util.BazelMockAndroidSupport;
+import com.google.devtools.build.lib.rules.cpp.CppOptions;
+import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData;
 import com.google.devtools.build.lib.syntax.Starlark;
 import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
 import com.google.devtools.build.lib.util.Fingerprint;
@@ -1795,6 +1801,52 @@
   }
 
   @Test
+  public void starlarkSplitTransitionRequiredFragments() throws Exception {
+    // All Starlark rule transitions are patch transitions, while all Starlark attribute transitions
+    // are split transitions.
+    writeAllowlistFile();
+    scratch.file(
+        "test/my_rule.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
+        "def transition_func(settings, attr):",
+        "  return [",
+        "    {'//command_line_option:copt': []}", // --copt is a C++ option.
+        "  ]",
+        "my_transition = transition(",
+        "  implementation = transition_func,",
+        "  inputs = [],",
+        "  outputs = ['//command_line_option:copt'])",
+        "def impl(ctx): ",
+        "  return []",
+        "my_rule = rule(",
+        "  implementation = impl,",
+        "  attrs = {",
+        "    'dep': attr.label(cfg = my_transition),",
+        "    '_whitelist_function_transition': attr.label(",
+        "        default = '//tools/whitelists/function_transition_whitelist',",
+        "    ),",
+        "  })");
+    scratch.file(
+        "test/BUILD",
+        "load('//test:my_rule.bzl', 'my_rule')",
+        "my_rule(name = 'test', dep = ':dep')",
+        "cc_library(name = 'dep', srcs = ['dep.c'])");
+
+    ConfiguredTargetAndData ct = getConfiguredTargetAndData("//test");
+    assertNoEvents();
+    Rule testTarget = (Rule) ct.getTarget();
+    ConfiguredAttributeMapper attributes =
+        ConfiguredAttributeMapper.of(testTarget, ImmutableMap.of());
+    ConfigurationTransition attrTransition =
+        attributes
+            .getAttributeDefinition("dep")
+            .getTransitionFactory()
+            .create(AttributeTransitionData.builder().attributes(attributes).build());
+    assertThat(attrTransition.requiresOptionFragments(ct.getConfiguration().getOptions()))
+        .containsExactly(CppOptions.class);
+  }
+
+  @Test
   public void testOptionConversionDynamicMode() throws Exception {
     // TODO(waltl): check that dynamic_mode is parsed properly.
   }
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/StarlarkRuleTransitionProviderTest.java b/src/test/java/com/google/devtools/build/lib/analysis/StarlarkRuleTransitionProviderTest.java
index 6f00086..e84713d 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/StarlarkRuleTransitionProviderTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/StarlarkRuleTransitionProviderTest.java
@@ -24,10 +24,13 @@
 import com.google.devtools.build.lib.analysis.config.Fragment;
 import com.google.devtools.build.lib.analysis.config.FragmentOptions;
 import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
+import com.google.devtools.build.lib.analysis.config.transitions.ConfigurationTransition;
 import com.google.devtools.build.lib.analysis.test.TestConfiguration.TestOptions;
 import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
 import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.packages.Rule;
 import com.google.devtools.build.lib.rules.cpp.CppOptions;
+import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData;
 import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
 import com.google.devtools.common.options.Option;
 import com.google.devtools.common.options.OptionDocumentationCategory;
@@ -1366,4 +1369,43 @@
     assertNoEvents();
     assertThat(getConfiguration(ct).getOptions().get(CppOptions.class).fissionModes).isEmpty();
   }
+
+  @Test
+  public void starlarkPatchTransitionRequiredFragments() throws Exception {
+    // All Starlark rule transitions are patch transitions, while all Starlark attribute transitions
+    // are split transitions.
+    writeAllowlistFile();
+    scratch.file(
+        "test/transitions.bzl",
+        "def _impl(settings, attr):",
+        "  return {'//command_line_option:copt': []}", // --copt is a C++ option.
+        "my_transition = transition(implementation = _impl, inputs = [],",
+        "  outputs = ['//command_line_option:copt'])");
+    scratch.file(
+        "test/rules.bzl",
+        "load('//test:transitions.bzl', 'my_transition')",
+        "def _impl(ctx):",
+        "  return []",
+        "my_rule = rule(",
+        "  implementation = _impl,",
+        "  cfg = my_transition,",
+        "  attrs = {",
+        "    '_whitelist_function_transition': attr.label(",
+        "        default = '//tools/whitelists/function_transition_whitelist',",
+        "    ),",
+        "  })");
+    scratch.file(
+        "test/BUILD",
+        "load('//test:rules.bzl', 'my_rule')",
+        "platform(name = 'my_platform')",
+        "my_rule(name = 'test')");
+
+    ConfiguredTargetAndData ct = getConfiguredTargetAndData("//test");
+    assertNoEvents();
+    Rule testTarget = (Rule) ct.getTarget();
+    ConfigurationTransition ruleTransition =
+        testTarget.getRuleClassObject().getTransitionFactory().create(testTarget);
+    assertThat(ruleTransition.requiresOptionFragments(ct.getConfiguration().getOptions()))
+        .containsExactly(CppOptions.class);
+  }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/config/TransitionFactoriesTest.java b/src/test/java/com/google/devtools/build/lib/analysis/config/TransitionFactoriesTest.java
index 67dcf08..3c00b5b 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/config/TransitionFactoriesTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/config/TransitionFactoriesTest.java
@@ -20,8 +20,6 @@
 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.events.EventHandler;
-import java.util.Map;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
@@ -61,13 +59,9 @@
   public void splitTransition() {
     TransitionFactory<Object> factory =
         TransitionFactories.of(
-            new SplitTransition() {
-              @Override
-              public Map<String, BuildOptions> split(
-                  BuildOptions buildOptions, EventHandler eventHandler) {
-                return ImmutableMap.of("test0", buildOptions.clone());
-              }
-            });
+            (SplitTransition)
+                (buildOptions, eventHandler) ->
+                    ImmutableMap.of("test0", buildOptions.clone().underlying()));
     assertThat(factory).isNotNull();
     assertThat(factory.isHost()).isFalse();
     assertThat(factory.isSplit()).isTrue();