Skip to content

Commit 01f4cfe

Browse files
committed
Unified: Update rewrite rules to use split AST
Mainly just using `OutputId` instead of `Id`, and `ctx.output` instead of `ctx.ast`. Also fixes a few places where we were pointlessly translating captures that could have been raw.
1 parent 9498f0d commit 01f4cfe

3 files changed

Lines changed: 28 additions & 24 deletions

File tree

‎unified/extractor/src/languages/swift/swift.rs‎

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,17 @@ struct SwiftContext {
1111
/// Name node for the property name. Set by the accessor-bearing
1212
/// `variableDecl` rule before translating the accessor block; read by the
1313
/// inner `accessorDecl` rules to name each `accessor_declaration`.
14-
property_name_node: Option<yeast::Id>,
14+
property_name_node: Option<yeast::OutputId>,
1515
/// Translated type node for the property type. Set (for computed
1616
/// properties) by the accessor-bearing `variableDecl` rule; read by the
1717
/// inner `accessorDecl` rules. Left `None` for stored properties with
1818
/// observers, so their `willSet`/`didSet` accessors carry no type.
19-
property_type: Option<yeast::Id>,
19+
property_type: Option<yeast::OutputId>,
2020
/// Translated outer modifiers to attach to each child of a flattening
2121
/// outer rule — e.g. the `let`/`var` binding modifier on each
2222
/// `patternBinding` of a `variableDecl`, or the binding modifier on each
2323
/// accessor of a property.
24-
outer_modifiers: Vec<yeast::Id>,
24+
outer_modifiers: Vec<yeast::OutputId>,
2525
/// True when the current child of a flattening outer rule is not
2626
/// the first one — its inner rule should emit a
2727
/// `chained_declaration` modifier so the original grouping can be
@@ -63,8 +63,8 @@ impl SwiftContext {
6363
/// Build a freshly-created `chained_declaration` modifier node if
6464
/// `ctx.is_chained`, else `None`. Used by inner declaration rules to
6565
/// emit the chained tag for non-first children of a flattening outer
66-
/// rule. Returns `Option<Id>` so it splices via `{…}` to 0 or 1 ids.
67-
fn chained_modifier(ctx: &mut yeast::build::BuildCtx<'_, SwiftContext>) -> Option<yeast::Id> {
66+
/// rule. Returns `Option<OutputId>` so it splices via `{…}` to 0 or 1 ids.
67+
fn chained_modifier(ctx: &mut yeast::build::BuildCtx<'_, SwiftContext>) -> Option<yeast::OutputId> {
6868
if ctx.is_chained {
6969
Some(tree!((modifier "chained_declaration")))
7070
} else {
@@ -74,10 +74,10 @@ fn chained_modifier(ctx: &mut yeast::build::BuildCtx<'_, SwiftContext>) -> Optio
7474

7575
fn implicit_parameterless_initializer(
7676
ctx: &mut yeast::build::BuildCtx<'_, SwiftContext>,
77-
members: &[yeast::Id],
78-
) -> Option<yeast::Id> {
77+
members: &[yeast::OutputId],
78+
) -> Option<yeast::OutputId> {
7979
let has_explicit_initializer = members.iter().any(|member| {
80-
ctx.ast
80+
ctx.output
8181
.get_node(*member)
8282
.is_some_and(|node| node.kind_name() == "constructor_declaration")
8383
});
@@ -98,8 +98,8 @@ fn implicit_parameterless_initializer(
9898
/// condition.
9999
fn and_chain(
100100
ctx: &mut yeast::build::BuildCtx<'_, SwiftContext>,
101-
conds: Vec<yeast::Id>,
102-
) -> yeast::Id {
101+
conds: Vec<yeast::OutputId>,
102+
) -> yeast::OutputId {
103103
conds
104104
.into_iter()
105105
.reduce(|acc, elem| {
@@ -114,8 +114,8 @@ fn and_chain(
114114
/// wrap the list in an `or_pattern`.
115115
fn make_or_pattern(
116116
ctx: &mut yeast::build::BuildCtx<'_, SwiftContext>,
117-
items: Vec<yeast::Id>,
118-
) -> yeast::Id {
117+
items: Vec<yeast::OutputId>,
118+
) -> yeast::OutputId {
119119
if items.len() == 1 {
120120
items[0]
121121
} else {
@@ -130,7 +130,7 @@ fn make_or_pattern(
130130
fn member_chain(
131131
ctx: &mut yeast::build::BuildCtx<'_, SwiftContext>,
132132
parts: Vec<yeast::Id>,
133-
) -> yeast::Id {
133+
) -> yeast::OutputId {
134134
let mut iter = parts.into_iter();
135135
let first = iter
136136
.next()
@@ -272,9 +272,9 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
272272
// to an opaque `unsupported_node`. These bare nodes only occur inside an
273273
// unresolved sequence — folded forms are handled by the dedicated rules
274274
// above (assignment) and below (`ternaryExpr`).
275-
rule!((assignmentExpr) @op => (infix_operator #{op})),
276-
rule!((unresolvedAsExpr) @op => (infix_operator #{op})),
277-
rule!((unresolvedIsExpr) @op => (infix_operator #{op})),
275+
rule!((assignmentExpr) @@op => (infix_operator #{op})),
276+
rule!((unresolvedAsExpr) @@op => (infix_operator #{op})),
277+
rule!((unresolvedIsExpr) @@op => (infix_operator #{op})),
278278
// The ternary is a three-part operator (`? thenExpr :`) that *wraps* a
279279
// nested expression. Splice it into `?`, the then-expression, `:` so the
280280
// then-expression survives as a real (traversable) operand rather than
@@ -1158,12 +1158,12 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
11581158
// A leading attribute (`@objc`) or access/function/member/mutation/
11591159
// ownership modifier (swift-syntax models each as a single `declModifier`)
11601160
// becomes a `modifier`; its source text is the modifier spelling.
1161-
rule!((attribute) @m => (modifier #{m})),
1162-
rule!((declModifier) @m => (modifier #{m})),
1161+
rule!((attribute) @@m => (modifier #{m})),
1162+
rule!((declModifier) @@m => (modifier #{m})),
11631163
// Type specifiers (`inout`, `sending`, ...) are mapped to modifiers.
1164-
rule!((simpleTypeSpecifier) @m => (modifier #{m})),
1165-
rule!((lifetimeTypeSpecifier) @m => (modifier #{m})),
1166-
rule!((nonisolatedTypeSpecifier) @m => (modifier #{m})),
1164+
rule!((simpleTypeSpecifier) @@m => (modifier #{m})),
1165+
rule!((lifetimeTypeSpecifier) @@m => (modifier #{m})),
1166+
rule!((nonisolatedTypeSpecifier) @@m => (modifier #{m})),
11671167
// An attributed type is mapped to a modified type of its base type.
11681168
rule!(
11691169
(attributedType
@@ -1529,7 +1529,10 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
15291529
_ @@node
15301530
=>
15311531
unhandled_node {
1532-
let input = ctx.ast.get_node(node).expect("matched node must exist");
1532+
let input = ctx
1533+
.ast()
1534+
.get_node(node)
1535+
.expect("matched node must exist");
15331536
tracing::error!(
15341537
target: "unified_extractor",
15351538
node_kind = input.kind_name(),

‎unified/extractor/tests/corpus_tests.rs‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::fs;
22
use std::path::Path;
33

44
use codeql_extractor::extractor::desugaring;
5+
use yeast::OutputAst as Ast;
56
use yeast::dump::{DumpOptions, dump_ast, dump_ast_with_type_errors_and_options};
67

78
#[path = "../src/languages/mod.rs"]
@@ -61,7 +62,7 @@ fn render_corpus(case: &CorpusCase) -> String {
6162

6263
/// Parse `input` through the language's parser and desugar it, returning the
6364
/// mapped AST.
64-
fn run_desugaring(lang: &desugaring::LanguageSpec, input: &str) -> Result<yeast::Ast, String> {
65+
fn run_desugaring(lang: &desugaring::LanguageSpec, input: &str) -> Result<Ast, String> {
6566
let parsed = (lang.parser)(input.as_bytes())?;
6667
lang.desugarer
6768
.run_from_ast(parsed.ast)

‎unified/extractor/tests/location_tests.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use yeast::Ast;
1+
use yeast::OutputAst as Ast;
22

33
#[path = "../src/languages/mod.rs"]
44
mod languages;

0 commit comments

Comments
 (0)