--- name: feature-flag-removal description: Use when removing a `base::Feature` and its associated code --- Your task is to clean up a `base::Feature` flag and its associated code. 01. **Determine flag's default state**: - Search for the `BASE_FEATURE` that defines the flag's default state (either `ENABLED_BY_DEFAULT` or `DISABLED_BY_DEFAULT`). - If the default is platform-specific (i.e., guarded by `#if BUILDFLAG()`), ask the user to clarify which should be considered the final state. - If no definition exists, check `//third_party/blink/renderer/platform/runtime_enabled_features.json5`, which is a config that generates `base::Feature`s at build time. Treat the "stable" status as `ENABLED_BY_DEFAULT` and all other statuses as `DISABLED_BY_DEFAULT`. - If the flag has a uniform default state but is explicitly overridden (e.g., force-disabled) for specific platforms via runtime overrides, bring this discrepancy to the user's attention before cleaning it up. 02. **Remove C++ flag enablement checks**: - Find C++ callsites where the feature enablement is checked. This usually takes the form of `base::FeatureList::IsEnabled(kFeature)` calls or a free `IsEnabled()` helper function that wraps the former. - Simplify each enablement check as if the default state were inlined. Usually, you will need to delete one branch of an if-else condition and dedent the other. - The final code should almost never contain `true` or `false` literals. Any `true` or `false` in a larger boolean expression should be simplified as much as possible. 03. **Remove obsolete `base::FeatureParam`s**: - Search for `BASE_FEATURE_PARAM`s that are linked to the obsolete feature flag. - Replace each retrieval of the parameter's value with the default value. Improve readability by using a constant (if the same value needs to be shared in multiple places) or a named call parameter (e.g., `FunctionCall(/*param=*/67)`). 04. **Remove obsolete C++ test coverage**: - Remove `base::test::ScopedFeatureList`s that explicitly set the feature in the default state. - If keeping the **enabled** state (deleting the disabled path): - Remove tests that only exercise the disabled state. - Remove `base::test::ScopedFeatureList`s that forced-enable the feature. - If keeping the **disabled** state (deleting the enabled path): - Remove tests that only exercise the enabled state and are no longer relevant. - Update tests that previously forced-enabled the feature to verify the permanent disabled behavior (instead of deleting them, if the test covers general functionality). - Ensure helper test listener/observer implementations handle the absence of feature-specific events safely (e.g., check for null pointers when casting events). - Remove references to the obsolete feature in test names. 05. **Clean up Java code**: - Check if the `base::Feature` is used in Java code by searching for the constant case version of the `base::Feature` name (e.g., `FOO_BAR` for `kFooBar`). - Simplify the Java code in the same way as the C++ case (enablement checks, parameters, tests). 06. **Clean up WebUI frontend code**: - If the `base::Feature` state was formerly sent to a WebUI frontend (e.g., with `AddBoolean("isFooEnabled", base::FeatureList::IsEnabled(kFoo))`), clean up `isFooEnabled` flags from WebUI frontend files (TypeScript/HTML/CSS) in the same way as the C++ case. 07. **Simplify APIs and expressions**: - Try to simplify APIs or expressions. For example: - Suppose a method takes a `std::optional` that's `std::nullopt` with the feature disabled, and `T` with the feature enabled. If the feature-disabled case is being removed, then the parameter can just become a value of type `T`. - Inline trivial local variable assignments. For example, ```cpp const auto x = base::FeatureList::IsEnabled(kFoo) ? Enum::A : Enum::B; Bar(x); ``` ... will become: ```cpp const auto x = Enum::A; Bar(x); ``` ... if one naively removes an `ENABLED_BY_DEFAULT` flag `kFoo`, but this can be simplified further as: ```cpp Bar(Enum::A); ``` ... since the assignment to `x` is adding unnecessary indirection. 08. **Remove dead code**: - In all removed lines, check for functions, classes, and constants that are no longer referenced and delete their declarations and definitions. You may need to delete entire source files. - Continue this process for all code that becomes unreferenced. - Remove declarations and definitions for the obsolete flag and its parameters. 09. **Delete unused imports and build deps**: - Remove `#include`s, `#import`s, and forward declarations that are no longer needed. - Remove `BUILD.gn` deps that are no longer needed. - Remove deleted source files from `BUILD.gn`. 10. **Delete `flag-metadata.json` entry**: - If you modified `//chrome/browser/about_flags.cc` or `//ios/chrome/browser/flags/about_flags.mm`, remove the corresponding entry from `//chrome/browser/flag-metadata.json`. By convention, a `base::Feature` declared as `kFooBar` has `foo-bar` as its `about:flags` name. 11. **Clean up `//testing/variations/fieldtrial_testing_config.json`**: - Remove references to the obsolete feature flag and its parameters. - Delete any experiments or studies that become empty. 12. **Delete unused strings or resources**: - At build time, `.grd` and `.grdp` files generate identifiers starting with `IDR_` and `IDS_` for resources and localized strings, respectively. In Java, these are static members on an `R` class (e.g., `R.string.foo` corresponds to `IDS_FOO`). - If any string or resource has no more users in either C++ or Java: - Delete its definition in a `.grd(p)` file. - Delete orphaned resource files. - For an orphaned string `IDS_FOO`, delete its corresponding `IDS_FOO.png.sha1` file, which references a screenshot to help translators. 13. **Update metrics**: - If an enumerated histogram no longer emits certain values, find the obsolete values in a `enums.xml` file under `//tools/metrics/histograms/` and prepend `(Obsolete) ` to the ``. - If an entire histogram is no longer emitted, remove it from its `histograms.xml` file under `//tools/metrics/histograms/`. - Never rename histograms or renumber enum `` values. - Do not touch the flag enums in `//tools/metrics/histograms/enums.xml`. The entries are still needed for decoding data in future Chrome versions. 14. **Update comments**: - Check immediately above each modified code block for obsolete comments. - If a comment still partially applies, reword it. Otherwise, delete it. - Search the codebase for references to the feature flag name in other comments (e.g., both the C++ constant `kMyFeature` and the user-facing name `MyFeature`) to clean up obsolete discussions, TODOs, or design notes. 15. **Verify the build is not broken**: - Determine what build directory the user wants to use (either from system context, or by asking). - Build everything with `autoninja -C `. - Fix any breakages. 16. **Verify all tests still pass**: - Determine what build directory the user wants to use. - Use `git diff` to determine modified test files. - Run each test file with `tools/autotest.py -C ` to confirm the tests still pass. - Fix any failures. 17. **Format the code**: - Run `git cl format`. - Remove extraneous whitespace (more than one consecutive blank lines, or whitespace starting or ending a class or method). - Adhere strictly to existing naming conventions. Do not rename variables or constants for stylistic preference. The goal is removal and simplification, not renaming. - Do not modify any logic for unrelated features. You'll often see families of related features that share a prefix, but you should only focus on the stale feature.