Skip to content

Commit a39eab3

Browse files
authored
Merge pull request #22195 from github/tausbn/swift-syntax-rs
unified: Add Swift parser based on `swift-syntax`
2 parents 9836c1d + 38c9c84 commit a39eab3

30 files changed

Lines changed: 1929 additions & 41 deletions

File tree

Cargo.lock

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ members = [
1010
"ruby/extractor",
1111
"unified/extractor",
1212
"unified/extractor/tree-sitter-swift",
13+
"unified/swift-syntax-rs",
1314
"rust/extractor",
1415
"rust/extractor/macros",
1516
"rust/ast-generator",

MODULE.bazel

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ bazel_dep(name = "gazelle", version = "0.50.0")
3131
bazel_dep(name = "rules_dotnet", version = "0.21.5-codeql.1")
3232
bazel_dep(name = "googletest", version = "1.17.0.bcr.2")
3333
bazel_dep(name = "rules_rust", version = "0.69.0")
34+
bazel_dep(name = "rules_swift", version = "4.0.0-rc4")
35+
bazel_dep(name = "swift-syntax", version = "603.0.2")
36+
37+
# Needed so we can `use_repo` `local_config_xcode` and
38+
# `local_config_apple_cc_toolchains` below (referenced by the per-target
39+
# Xcode-config transition in `unified/swift-syntax-rs/xcode_transition.bzl`).
40+
bazel_dep(name = "apple_support", version = "2.6.1")
3441
bazel_dep(name = "zstd", version = "1.5.7.bcr.1")
3542

3643
bazel_dep(name = "buildifier_prebuilt", version = "6.4.0", dev_dependency = True)
@@ -219,6 +226,41 @@ use_repo(
219226
"swift-resource-dir-macos",
220227
)
221228

229+
# Swift toolchain for building `unified/swift-syntax-rs`. On Linux we register
230+
# a hermetic swift.org toolchain as the exec toolchain; on macOS `rules_swift`
231+
# auto-registers `xcode_swift_toolchain` (host Xcode + OS-provided Swift
232+
# runtime), which is not hermetic.
233+
#
234+
# The version is pinned as a literal rather than read from
235+
# `unified/swift-syntax-rs/.swift-version` via `swift_version_file`: the latter
236+
# makes the extension `module_ctx.read` a `//unified/...` label, which fails to
237+
# resolve when this repo is consumed as a dependency module (`@@ql+`) whose
238+
# `unified/swift-syntax-rs` package is not loadable in that context. Keep this
239+
# in sync with `unified/swift-syntax-rs/.swift-version` (used by the `cargo`
240+
# build) and the `swift-syntax` release in `swift/Package.swift`.
241+
swift = use_extension("@rules_swift//swift:extensions.bzl", "swift")
242+
swift.toolchain(
243+
name = "swift_toolchain",
244+
swift_version = "6.3.2",
245+
)
246+
use_repo(
247+
swift,
248+
"swift_toolchain",
249+
"swift_toolchain_ubuntu22.04",
250+
)
251+
252+
register_toolchains(
253+
"@swift_toolchain//:swift_toolchain_exec_ubuntu22.04",
254+
)
255+
256+
# `apple_support`'s xcode_config and CC toolchains, needed by the Xcode
257+
# transition in `unified/swift-syntax-rs/xcode_transition.bzl`.
258+
xcode_configure = use_extension("@apple_support//xcode:xcode_configure.bzl", "xcode_configure_extension")
259+
use_repo(xcode_configure, "local_config_xcode")
260+
261+
apple_cc_configure = use_extension("@apple_support//crosstool:setup.bzl", "apple_cc_configure_extension")
262+
use_repo(apple_cc_configure, "local_config_apple_cc_toolchains")
263+
222264
node = use_extension("@rules_nodejs//nodejs:extensions.bzl", "node")
223265
node.toolchain(
224266
name = "nodejs",

misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl

Lines changed: 28 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

shared/tree-sitter-extractor/src/extractor/mod.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,18 @@ impl AstNode for yeast::Node {
8181
yeast::Node::is_extra(self)
8282
}
8383
fn start_position(&self) -> tree_sitter::Point {
84-
yeast::Node::start_position(self)
84+
let p = yeast::Node::start_position(self);
85+
tree_sitter::Point {
86+
row: p.row,
87+
column: p.column,
88+
}
8589
}
8690
fn end_position(&self) -> tree_sitter::Point {
87-
yeast::Node::end_position(self)
91+
let p = yeast::Node::end_position(self);
92+
tree_sitter::Point {
93+
row: p.row,
94+
column: p.column,
95+
}
8896
}
8997
fn byte_range(&self) -> std::ops::Range<usize> {
9098
yeast::Node::byte_range(self)

shared/yeast-macros/src/parse.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -903,7 +903,7 @@ pub fn parse_rule_top(input: TokenStream) -> Result<TokenStream> {
903903
Ok(quote! {
904904
{
905905
let __query = #query_code;
906-
yeast::Rule::new(__query, Box::new(|__ast: &mut yeast::Ast, mut __captures: yeast::captures::Captures, __fresh: &yeast::tree_builder::FreshScope, __source_range: Option<tree_sitter::Range>, __user_ctx: &mut _, __translator: yeast::TranslatorHandle<'_, _>| {
906+
yeast::Rule::new(__query, Box::new(|__ast: &mut yeast::Ast, mut __captures: yeast::captures::Captures, __fresh: &yeast::tree_builder::FreshScope, __source_range: Option<yeast::Range>, __user_ctx: &mut _, __translator: yeast::TranslatorHandle<'_, _>| {
907907
// Auto-translation prefix: recursively translate every
908908
// captured node before invoking the user's transform body,
909909
// except for `@@name` captures listed in `__skip` which the

shared/yeast-schema/src/schema.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,28 @@ impl Schema {
167167
id
168168
}
169169

170+
/// Register every kind (named and unnamed) and field *name* from `other`
171+
/// into this schema (idempotent). Ids are assigned in this schema's own id
172+
/// space; existing ids are unchanged.
173+
///
174+
/// This is used when running desugaring rules over an AST that was built
175+
/// against a different schema (e.g. from an external parser): the rules
176+
/// build output nodes whose kind/field names come from `other`, and those
177+
/// names must resolve in the AST's own schema. Only names are needed — the
178+
/// rule engine resolves kinds/fields by name and does not consult
179+
/// `other`'s field-type or supertype information.
180+
pub fn register_names_from(&mut self, other: &Schema) {
181+
for name in other.kind_ids.keys() {
182+
self.register_kind(name);
183+
}
184+
for name in other.unnamed_kind_ids.keys() {
185+
self.register_unnamed_kind(name);
186+
}
187+
for name in other.field_ids.keys() {
188+
self.register_field(name);
189+
}
190+
}
191+
170192
/// Track a name for a kind ID without registering it as named or
171193
/// unnamed. Useful when importing tree-sitter ID tables that may
172194
/// contain duplicate IDs across the named/unnamed split.

shared/yeast/src/build.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::collections::BTreeMap;
22

33
use crate::captures::Captures;
44
use crate::tree_builder::FreshScope;
5-
use crate::{Ast, FieldId, Id, NodeContent, TranslatorHandle};
5+
use crate::{Ast, FieldId, Id, NodeContent, Range, TranslatorHandle};
66

77
/// Context for building new AST nodes during a transformation.
88
///
@@ -34,7 +34,7 @@ pub struct BuildCtx<'a, C: 'a = ()> {
3434
pub captures: &'a Captures,
3535
pub fresh: &'a FreshScope,
3636
/// Source range of the matched node, inherited by synthetic nodes.
37-
pub source_range: Option<tree_sitter::Range>,
37+
pub source_range: Option<Range>,
3838
/// User-supplied context, accessible directly via `ctx.field` (via Deref).
3939
pub user_ctx: &'a mut C,
4040
/// Optional translator handle, populated when the context is built by
@@ -63,7 +63,7 @@ impl<'a, C> BuildCtx<'a, C> {
6363
ast: &'a mut Ast,
6464
captures: &'a Captures,
6565
fresh: &'a FreshScope,
66-
source_range: Option<tree_sitter::Range>,
66+
source_range: Option<Range>,
6767
user_ctx: &'a mut C,
6868
) -> Self {
6969
Self {
@@ -82,7 +82,7 @@ impl<'a, C> BuildCtx<'a, C> {
8282
ast: &'a mut Ast,
8383
captures: &'a Captures,
8484
fresh: &'a FreshScope,
85-
source_range: Option<tree_sitter::Range>,
85+
source_range: Option<Range>,
8686
user_ctx: &'a mut C,
8787
translator: TranslatorHandle<'a, C>,
8888
) -> Self {
@@ -143,7 +143,7 @@ impl<'a, C> BuildCtx<'a, C> {
143143
&mut self,
144144
kind: &'static str,
145145
value: &str,
146-
source_range: Option<tree_sitter::Range>,
146+
source_range: Option<Range>,
147147
) -> Id {
148148
self.ast.create_named_token_with_range(
149149
kind,

0 commit comments

Comments
 (0)