iOS: clean up swiftc.py after migration to target triples#189240
Conversation
|
It looks like this pull request may not have tests. Please make sure to add tests or get an explicit test exemption before merging. If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix? Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. If you believe this PR qualifies for a test exemption, contact "@test-exemption-reviewer" in the #hackers channel in Discord (don't just cc them here, they won't see it!). The test exemption team is a small volunteer group, so all reviewers should feel empowered to ask for tests, without delegating that responsibility entirely to the test exemption group. |
There was a problem hiding this comment.
Code Review
This pull request refactors the Swift compiler invocation script by removing the 'target_triple' parameter from the 'invoke_swift_compiler' and 'compile_module' function signatures, accessing it directly from the 'args' object instead. However, a critical issue was found where 'invoke_swift_compiler' is still called with the 'target_triple' keyword argument, which will result in a TypeError at runtime.
35ed00f to
5f63773
Compare
In flutter#189174, we migrated back to using target triples in swiftc.py in order to more closely mirror the commandline interface to `swiftc` itself. This is a followup that cleans up some extra function parameters that are no longer necessary now that we're getting the target triple in args. This cleans up a few remaining diffs from the reversion of the target triple splitting from https://github.com/flutter/flutter/pull/185712/changes#diff-d57f937ed2d743b17635dd069689072eba124f649f307228915c25d55b19ed62. Issue: flutter#185741
5f63773 to
734176e
Compare
flutter/flutter@f7b66f3...cf9e8af 2026-07-12 [email protected] Flip from deprecated strict analysis modes to lint rules (flutter/flutter#187692) 2026-07-12 [email protected] Roll Skia from 6ecffccd32d5 to 8bf65996caba (5 revisions) (flutter/flutter#189333) 2026-07-11 [email protected] Roll Fuchsia Linux SDK from czpzDg9ABY2oKLAOY... to vhIlDkWIy21IrlB9E... (flutter/flutter#189309) 2026-07-11 [email protected] iOS: clean up swiftc.py after migration to target triples (flutter/flutter#189240) 2026-07-10 [email protected] Increase number of 'Mac tool_integration_tests' subshards from 5 to 10 (flutter/flutter#189040) 2026-07-10 [email protected] Fix PopupWindowControllerLinux missing WindowControllerLinux implementation (flutter/flutter#189189) 2026-07-10 [email protected] [android_hardware_smoke_test] Synchronize platform view compositing (flutter/flutter#189151) 2026-07-10 [email protected] UberSDF thin roundrect handling (flutter/flutter#189224) 2026-07-10 [email protected] Roll Skia from ab3a7b98c94d to 6ecffccd32d5 (15 revisions) (flutter/flutter#189270) 2026-07-10 [email protected] [skwasm][canvaskit] Honor Paint.filterQuality in Canvas.drawAtlas (flutter/flutter#186108) 2026-07-10 [email protected] Android_hardware_smoke_test: Cache flutter engine when running vulkan backend instrumented tests (flutter/flutter#189026) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC [email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
GN's `--export-compile-commands` only understands its built-in `cc`/`cxx`/`objc`/`objcxx` tool types, so the custom `swift` tool we use to invoke `swiftc.py` never shows up in `compile_commands.json`. Swift code under `flutter/shell/platform/darwin` was therefore invisible to any tooling that reads that file, including SourceKit-LSP, which is what drives Swift diagnostics/completion/go-to-definition in VS Code and other editors. This adds a post-processing step to `gn gen` that fixes this up. Since GN's own compdb export omits the swift targets entirely, we now shell out to `ninja -t compdb` to get the full compilation database instead (falling back to the existing `compile_commands.json` on disk if that fails), then rewrite the result in two passes: * `stripCompilerWrappers` strips the `rewrapper`/`ccache` prefix off `clang`/`clang++` invocations, same as before, so `clangd` doesn't choke on RBE wrapper commands (flutter#147767). * `expandSwiftcCommands` turns each `swiftc.py`-wrapped entry into one or more native `swiftc` invocations, one per compiled Swift file, with all relative paths resolved to absolute against the entry's `directory`. This mirrors the argument translation `swiftc.py` itself does (`-import-objc-header`, `-whole-module-optimization`, `-I`/`-isystem`/`-F`/`-Fsystem`/`-D` mirrored to `-Xcc`, etc.) so SourceKit-LSP sees the same flags the real build uses. Also wires up `.sourcekit-lsp/config.json` and the `swift.sourcekit-lsp.supported-languages` setting in `engine.code-workspace`/`engine-workspace.yaml` so VS Code's Swift extension picks up the generated compdb automatically. Both regexes in `update_compdb.dart` scan the raw ninja output directly rather than decoding the full `compile_commands.json`, which can run past 20MB and is slow to parse in Dart; we only `jsonDecode` the handful of matched `swiftc.py` entries. While tightening this up I found the `clang`/`clang++` wrapper-stripping regex could match a `clang` substring anywhere later on the line -- e.g. an `-Xclang` flag, or a source file whose name happens to contain "clang" -- rather than the actual compiler token, silently truncating the command. Anchored the match to require `clang`/`clang++` be preceded by `/` (or start-of-word) and followed by a word boundary, and added regression tests for both cases. Pre-factored in flutter#189174 and flutter#189240.
GN's `--export-compile-commands` only understands its built-in `cc`/`cxx`/`objc`/`objcxx` tool types, so the custom `swift` tool we use to invoke `swiftc.py` never shows up in `compile_commands.json`. Swift code under `flutter/shell/platform/darwin` was therefore invisible to any tooling that reads that file, including SourceKit-LSP, which is what drives Swift diagnostics/completion/go-to-definition in VS Code and other editors. This adds a post-processing step to `gn gen` that fixes this up. Since GN's own compdb export omits the swift targets entirely, we now shell out to `ninja -t compdb` to get the full compilation database instead (falling back to the existing `compile_commands.json` on disk if that fails), then rewrite the result in two passes: * `stripCompilerWrappers` strips the `rewrapper`/`ccache` prefix off `clang`/`clang++` invocations, same as before, so `clangd` doesn't choke on RBE wrapper commands (flutter#147767). * `expandSwiftcCommands` turns each `swiftc.py`-wrapped entry into one or more native `swiftc` invocations, one per compiled Swift file, with all relative paths resolved to absolute against the entry's `directory`. This mirrors the argument translation `swiftc.py` itself does (`-import-objc-header`, `-whole-module-optimization`, `-I`/`-isystem`/`-F`/`-Fsystem`/`-D` mirrored to `-Xcc`, etc.) so SourceKit-LSP sees the same flags the real build uses. Also wires up `.sourcekit-lsp/config.json` and the `swift.sourcekit-lsp.supported-languages` setting in `engine.code-workspace`/`engine-workspace.yaml` so VS Code's Swift extension picks up the generated compdb automatically. Both regexes in `update_compdb.dart` scan the raw ninja output directly rather than decoding the full `compile_commands.json`, which can run past 20MB and is slow to parse in Dart; we only `jsonDecode` the handful of matched `swiftc.py` entries. While tightening this up I found the `clang`/`clang++` wrapper-stripping regex could match a `clang` substring anywhere later on the line -- e.g. an `-Xclang` flag, or a source file whose name happens to contain "clang" -- rather than the actual compiler token, silently truncating the command. Anchored the match to require `clang`/`clang++` be preceded by `/` (or start-of-word) and followed by a word boundary, and added regression tests for both cases. A design pass on `update_compdb.dart` also cleaned up a few things: * Dropped `update_compdb.dart` from the package's public barrel export (`engine_build_configs.dart`). Nothing needs it there -- `_postGn()` imports it directly as a sibling file, and the tests import `package:engine_build_configs/src/update_compdb.dart` rather than the barrel -- so exporting it only widened the package's public API for no reason. * `swiftc.py` args now flow as `List<String>` end to end and get quoted into a shell command exactly once, at the very end, instead of being joined into a string and immediately re-split back into a list to resolve paths. * Replaced the `CommandString` utility class (private constructor, only static members) with top-level functions `splitShellWords` and `quoteShellWord`. * `expandSwiftEntry` no longer mutates the `entry` map it's given; it and its helpers (`_absolutizeEntryFile`, `_duplicateEntryPerSwiftFile`) build fresh maps via spread syntax instead. * Collapsed `_SwiftCommand`/`_ParsedSwiftCommand`/`_CommandPathResolver` -- three classes, each with exactly one call site -- into two functions, `_translateSwiftcArgs` and `_resolveCommandPaths`, linked by a `_SwiftcTranslation` record typedef instead of a dedicated value class. Pre-factored in flutter#189174 and flutter#189240.
GN's `--export-compile-commands` only understands its built-in `cc`/`cxx`/`objc`/`objcxx` tool types, so the custom `swift` tool we use to invoke `swiftc.py` never shows up in `compile_commands.json`. Swift code under `flutter/shell/platform/darwin` was therefore invisible to any tooling that reads that file, including SourceKit-LSP, which is what drives Swift diagnostics/completion/go-to-definition in VS Code and other editors. This adds a post-processing step to `gn gen` that fixes this up. Since GN's own compdb export omits the swift targets entirely, we now shell out to `ninja -t compdb` to get the full compilation database instead (falling back to the existing `compile_commands.json` on disk if that fails), then rewrite the result in two passes: * `stripCompilerWrappers` strips the `rewrapper`/`ccache` prefix off `clang`/`clang++` invocations, same as before, so `clangd` doesn't choke on RBE wrapper commands (flutter#147767). * `expandSwiftcCommands` turns each `swiftc.py`-wrapped entry into one or more native `swiftc` invocations, one per compiled Swift file, with all relative paths resolved to absolute against the entry's `directory`. This mirrors the argument translation `swiftc.py` itself does (`-import-objc-header`, `-whole-module-optimization`, `-I`/`-isystem`/`-F`/`-Fsystem`/`-D` mirrored to `-Xcc`, etc.) so SourceKit-LSP sees the same flags the real build uses. Also wires up `.sourcekit-lsp/config.json` and the `swift.sourcekit-lsp.supported-languages` setting in `engine.code-workspace`/`engine-workspace.yaml` so VS Code's Swift extension picks up the generated compdb automatically. Both regexes in `update_compdb.dart` scan the raw ninja output directly rather than decoding the full `compile_commands.json`, which can run past 20MB and is slow to parse in Dart; we only `jsonDecode` the handful of matched `swiftc.py` entries. While tightening this up I found the `clang`/`clang++` wrapper-stripping regex could match a `clang` substring anywhere later on the line -- e.g. an `-Xclang` flag, or a source file whose name happens to contain "clang" -- rather than the actual compiler token, silently truncating the command. Anchored the match to require `clang`/`clang++` be preceded by `/` (or start-of-word) and followed by a word boundary, and added regression tests for both cases. A design pass on `update_compdb.dart` also cleaned up a few things: * Dropped `update_compdb.dart` from the package's public barrel export (`engine_build_configs.dart`). Nothing needs it there -- `_postGn()` imports it directly as a sibling file, and the tests import `package:engine_build_configs/src/update_compdb.dart` rather than the barrel -- so exporting it only widened the package's public API for no reason. * `swiftc.py` args now flow as `List<String>` end to end and get quoted into a shell command exactly once, at the very end, instead of being joined into a string and immediately re-split back into a list to resolve paths. * Replaced the `CommandString` utility class (private constructor, only static members) with top-level functions `splitShellWords` and `quoteShellWord`. * `expandSwiftEntry` no longer mutates the `entry` map it's given; it and its helpers (`_absolutizeEntryFile`, `_duplicateEntryPerSwiftFile`) build fresh maps via spread syntax instead. * Collapsed `_SwiftCommand`/`_ParsedSwiftCommand`/`_CommandPathResolver` -- three classes, each with exactly one call site -- into two functions, `_translateSwiftcArgs` and `_resolveCommandPaths`, linked by a `_SwiftcTranslation` record typedef instead of a dedicated value class. A correctness pass traced the flag translation against `swiftc.py`'s actual `ArgumentForwarder` logic (`build/toolchain/darwin/swiftc.py`) and found two mismatches, both currently dormant since no target in this repo wires `{{defines}}` or `{{system_include_dirs}}` into the swift tool's GN command template today, but worth fixing for fidelity: * `-isystem` was forwarded to `swiftc` itself as a bare flag in addition to the `-Xcc -isystem -Xcc <path>` mirror. `swiftc.py`'s `IncludeArgumentForwarder` excludes `-isystem` from the swift-side forward entirely (`to_swift=lambda _: arg_name != '-isystem'`) -- it's clang-only. Fixed in `_resolveCommandPaths` for both the attached and separated forms. * `-D key=value` was forwarded to `swiftc`'s `-D`, which only accepts bare conditional-compilation flags. `swiftc.py`'s `DefineArgumentForwarder` only forwards to swift when the value has no `=`; value-defines go to clang only. Fixed in `_translateSwiftcArgs`. Bare flags like `-D FOO` are unaffected. Also dropped a dead `--fix-module-imports` branch (not an actual swiftc.py argparse flag -- only `--fix-generated-header` is; the name only ever existed in a stale docstring), and fixed `splitShellWords` to preserve an empty quoted argument (`""`/`''`) as an empty-string token instead of dropping it, which had been silently swallowing the following flag whenever `-import-objc-header ""` appeared on a real command line. Pre-factored in flutter#189174 and flutter#189240.
GN's `--export-compile-commands` only understands its built-in `cc`/`cxx`/`objc`/`objcxx` tool types, so the custom `swift` tool we use to invoke `swiftc.py` never shows up in `compile_commands.json`. Swift code under `flutter/shell/platform/darwin` was therefore invisible to any tooling that reads that file, including SourceKit-LSP, which is what drives Swift diagnostics/completion/go-to-definition in VS Code and other editors. This adds a post-processing step to `gn gen` that fixes this up. Since GN's own compdb export omits the swift targets entirely, we now shell out to `ninja -t compdb` to get the full compilation database instead (falling back to the existing `compile_commands.json` on disk if that fails), then rewrite the result in two passes: * `stripCompilerWrappers` strips the `rewrapper`/`ccache` prefix off `clang`/`clang++` invocations, same as before, so `clangd` doesn't choke on RBE wrapper commands (flutter#147767). * `expandSwiftcCommands` turns each `swiftc.py`-wrapped entry into one or more native `swiftc` invocations, one per compiled Swift file, with all relative paths resolved to absolute against the entry's `directory`. This mirrors the argument translation `swiftc.py` itself does (`-import-objc-header`, `-whole-module-optimization`, `-I`/`-isystem`/`-F`/`-Fsystem`/`-D` mirrored to `-Xcc`, etc.) so SourceKit-LSP sees the same flags the real build uses. Also wires up `.sourcekit-lsp/config.json` and the `swift.sourcekit-lsp.supported-languages` setting in `engine.code-workspace`/`engine-workspace.yaml` so VS Code's Swift extension picks up the generated compdb automatically. Both regexes in `update_compdb.dart` scan the raw ninja output directly rather than decoding the full `compile_commands.json`, which can run past 20MB and is slow to parse in Dart; we only `jsonDecode` the handful of matched `swiftc.py` entries. While tightening this up I found the `clang`/`clang++` wrapper-stripping regex could match a `clang` substring anywhere later on the line -- e.g. an `-Xclang` flag, or a source file whose name happens to contain "clang" -- rather than the actual compiler token, silently truncating the command. Anchored the match to require `clang`/`clang++` be preceded by `/` (or start-of-word) and followed by a word boundary, and added regression tests for both cases. A design pass on `update_compdb.dart` also cleaned up a few things: * Dropped `update_compdb.dart` from the package's public barrel export (`engine_build_configs.dart`). Nothing needs it there -- `_postGn()` imports it directly as a sibling file, and the tests import `package:engine_build_configs/src/update_compdb.dart` rather than the barrel -- so exporting it only widened the package's public API for no reason. * `swiftc.py` args now flow as `List<String>` end to end and get quoted into a shell command exactly once, at the very end, instead of being joined into a string and immediately re-split back into a list to resolve paths. * Replaced the `CommandString` utility class (private constructor, only static members) with top-level functions `splitShellWords` and `quoteShellWord`. * `expandSwiftEntry` no longer mutates the `entry` map it's given; it and its helpers (`_absolutizeEntryFile`, `_duplicateEntryPerSwiftFile`) build fresh maps via spread syntax instead. * Collapsed `_SwiftCommand`/`_ParsedSwiftCommand`/`_CommandPathResolver` -- three classes, each with exactly one call site -- into two functions, `_translateSwiftcArgs` and `_resolveCommandPaths`, linked by a `_SwiftcTranslation` record typedef instead of a dedicated value class. A correctness pass traced the flag translation against `swiftc.py`'s actual `ArgumentForwarder` logic (`build/toolchain/darwin/swiftc.py`) and found two mismatches, both currently dormant since no target in this repo wires `{{defines}}` or `{{system_include_dirs}}` into the swift tool's GN command template today, but worth fixing for fidelity: * `-isystem` was forwarded to `swiftc` itself as a bare flag in addition to the `-Xcc -isystem -Xcc <path>` mirror. `swiftc.py`'s `IncludeArgumentForwarder` excludes `-isystem` from the swift-side forward entirely (`to_swift=lambda _: arg_name != '-isystem'`) -- it's clang-only. Fixed in `_resolveCommandPaths` for both the attached and separated forms, and consolidated into a single named `isClangOnly()` check instead of three separate comparisons, so the same class of bug (a special case duplicated instead of centralized) can't creep back in. * `-D key=value` was forwarded to `swiftc`'s `-D`, which only accepts bare conditional-compilation flags. `swiftc.py`'s `DefineArgumentForwarder` only forwards to swift when the value has no `=`; value-defines go to clang only. Fixed in `_translateSwiftcArgs`. Bare flags like `-D FOO` are unaffected. Also dropped a dead `--fix-module-imports` branch (not an actual swiftc.py argparse flag -- only `--fix-generated-header` is; the name only ever existed in a stale docstring), and fixed `splitShellWords` to preserve an empty quoted argument (`""`/`''`) as an empty-string token instead of dropping it, which had been silently swallowing the following flag whenever `-import-objc-header ""` appeared on a real command line. Ran `dart format` for the first time (fixed a missing blank line between import groups) and grouped the test file's 15 tests by the function they exercise now that it's grown past being easy to scan as a flat list. Pre-factored in flutter#189174 and flutter#189240.
In #189174, we migrated back to using target triples in swiftc.py in order to more closely mirror the commandline interface to
swiftcitself.This is a followup that cleans up some extra function parameters that are no longer necessary now that we're getting the target triple in args.
This cleans up a few remaining diffs from the reversion of the target triple splitting from https://github.com/flutter/flutter/pull/185712/changes#diff-d57f937ed2d743b17635dd069689072eba124f649f307228915c25d55b19ed62.
No test changes since this is a refactor with no semantic change. The test is the build (and transitively, all the tests it builds and runs).
Issue: #185741
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.
If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance.
Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the
gemini-code-assistbot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.