unified: Switch the Swift front-end to swift-syntax

Flip the runtime Swift front-end from tree-sitter to swift-syntax. The
mapping rules were already ported, so the mapped AST is unchanged; this
makes the switch live.

- `language_spec` now builds a language-free desugarer
  (`ConcreteDesugarer::without_language`) and wires the swift-syntax
  parser (`swift_parse::parse`) as the front-end, dropping the
  tree-sitter language and node types. The desugarer supplies the output
  schema, so `node_types` is left empty.
- The `swift_adapter`/`swift_parse` modules are no longer
  `allow(dead_code)`: they are now reached from the live extraction
  path.
- `corpus_tests` skips (rather than fails) when the external
  `swift-syntax-parse` binary is unavailable, since it cannot run
  without the Swift-backed parser.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Taus
2026-07-23 12:44:23 +00:00
parent c4fbd74cfe
commit 5c5fd5e1cc
3 changed files with 23 additions and 18 deletions

View File

@@ -4,23 +4,13 @@ use codeql_extractor::extractor::desugaring;
mod swift;
/// swift-syntax JSON -> `yeast::Ast` adapter for the Swift front-end.
///
/// Currently exercised by tests and the forthcoming runtime extraction path;
/// `allow(dead_code)` because this is a binary crate, so its public API isn't
/// counted as used until the binary itself calls it.
#[path = "swift/adapter.rs"]
#[allow(dead_code)]
pub mod swift_adapter;
/// Swift front-end parser: shells out to `swift-syntax-parse` and adapts its
/// JSON output via [`swift_adapter`].
///
/// Dormant for now: the runtime Swift front-end is still tree-sitter, so
/// nothing in the binary calls this yet. `allow(dead_code)` for the same
/// binary-crate reason as [`swift_adapter`]; both allows are removed once the
/// runtime switches the Swift front-end to swift-syntax.
/// JSON output via [`swift_adapter`]. This is the live Swift front-end used by
/// [`all_language_specs`].
#[path = "swift/parse.rs"]
#[allow(dead_code)]
pub mod swift_parse;
/// Shared YEAST output AST schema for all languages.

View File

@@ -1155,16 +1155,15 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
}
pub fn language_spec(desugared_ast_schema: &'static str) -> desugaring::LanguageSpec {
let ts_language: tree_sitter::Language = tree_sitter_swift::LANGUAGE.into();
let config = DesugaringConfig::<SwiftContext>::new()
.add_phase("translate", PhaseKind::OneShot, translation_rules())
.with_output_node_types_yaml(desugared_ast_schema);
let desugarer = ConcreteDesugarer::new(ts_language.clone(), config)
.expect("failed to build Swift desugarer");
let desugarer =
ConcreteDesugarer::without_language(config).expect("failed to build Swift desugarer");
desugaring::LanguageSpec {
prefix: "swift",
parser: Box::new(codeql_extractor::extractor::tree_sitter_parser(ts_language)),
node_types: tree_sitter_swift::NODE_TYPES,
parser: Box::new(super::swift_parse::parse),
node_types: "",
file_globs: vec!["*.swift".into(), "*.swiftinterface".into()],
desugarer: Box::new(desugarer),
}

View File

@@ -20,6 +20,14 @@ fn update_mode_enabled() -> bool {
.unwrap_or(false)
}
/// Whether the external swift-syntax parser is available. When it is not (e.g.
/// no Swift toolchain / the `swift-syntax-parse` binary is not on `PATH` and
/// `CODEQL_EXTRACTOR_UNIFIED_SWIFT_SYNTAX_PARSE` is unset), the corpus test is
/// skipped rather than failed — it cannot run without the Swift-backed parser.
fn parser_available() -> bool {
languages::swift_parse::parse(b"").is_ok()
}
/// Parse a corpus `.output` file. The file holds a single test case made of
/// three sections separated by `---` delimiter lines:
///
@@ -28,7 +36,7 @@ fn update_mode_enabled() -> bool {
///
/// ---
///
/// <raw tree-sitter parse tree>
/// <raw swift-syntax AST (the yeast tree the adapter builds, pre-desugaring)>
///
/// ---
///
@@ -98,6 +106,14 @@ fn collect_corpus_stems(dir: &Path, out: &mut Vec<std::path::PathBuf>) {
#[test]
fn test_corpus() {
if !parser_available() {
eprintln!(
"skipping test_corpus: the swift-syntax parser is unavailable \
(set CODEQL_EXTRACTOR_UNIFIED_SWIFT_SYNTAX_PARSE or put \
`swift-syntax-parse` on PATH)"
);
return;
}
let update_mode = update_mode_enabled();
let all_languages = languages::all_language_specs();
let corpus_dir = Path::new("tests/corpus");