diff --git a/shared/tree-sitter-extractor/src/extractor/mod.rs b/shared/tree-sitter-extractor/src/extractor/mod.rs index 00816a00fd04..115f6f405d46 100644 --- a/shared/tree-sitter-extractor/src/extractor/mod.rs +++ b/shared/tree-sitter-extractor/src/extractor/mod.rs @@ -326,7 +326,7 @@ pub fn extract( if let Some(yeast_runner) = yeast_runner { let ast = yeast_runner - .run_from_tree(&tree) + .run_from_tree(&tree, source) .unwrap_or_else(|e| panic!("Desugaring failed for {path_str}: {e}")); traverse_yeast(&ast, &mut visitor); } else { diff --git a/shared/tree-sitter-extractor/src/generator/mod.rs b/shared/tree-sitter-extractor/src/generator/mod.rs index d2521c51b3ec..8167dc2574e0 100644 --- a/shared/tree-sitter-extractor/src/generator/mod.rs +++ b/shared/tree-sitter-extractor/src/generator/mod.rs @@ -115,8 +115,19 @@ pub fn generate( &node_parent_table_name, )), ql::TopLevel::Class(ql_gen::create_token_class(&token_name, &tokeninfo_name)), - ql::TopLevel::Class(ql_gen::create_reserved_word_class(&reserved_word_name)), ]; + // Only emit the ReservedWord class when there are actually unnamed token + // types in the schema (i.e., @{prefix}_reserved_word exists in the dbscheme). + // When converting from a YEAST YAML schema that has no unnamed tokens, this + // type is absent and referencing it would cause a QL compilation error. + let has_reserved_words = nodes + .values() + .any(|n| n.dbscheme_name == reserved_word_name); + if has_reserved_words { + body.push(ql::TopLevel::Class(ql_gen::create_reserved_word_class( + &reserved_word_name, + ))); + } // Overlay discard predicates body.push(ql::TopLevel::Predicate( diff --git a/shared/yeast-macros/src/parse.rs b/shared/yeast-macros/src/parse.rs index 70bd46d5b6f6..608c332d47e8 100644 --- a/shared/yeast-macros/src/parse.rs +++ b/shared/yeast-macros/src/parse.rs @@ -113,8 +113,24 @@ fn parse_query_node_inner(tokens: &mut Tokens) -> Result { /// appear in any order; bare patterns are accumulated and emitted as a /// single `("child", ...)` entry. fn parse_query_fields(tokens: &mut Tokens) -> Result> { - let mut fields = Vec::new(); + // Accumulate per-field elems in declaration order; multiple uses of the + // same field name extend the same list (so e.g. `cond: (foo) cond: (bar)` + // matches a `cond` field whose first child is `foo` and second is `bar`). + let mut field_order: Vec = Vec::new(); + let mut field_elems: std::collections::HashMap> = + std::collections::HashMap::new(); let mut bare_children: Vec = Vec::new(); + let push_field_elem = |order: &mut Vec, + map: &mut std::collections::HashMap>, + name: String, + elem: TokenStream| { + if !map.contains_key(&name) { + order.push(name.clone()); + map.insert(name, vec![elem]); + } else { + map.get_mut(&name).unwrap().push(elem); + } + }; while tokens.peek().is_some() { if peek_is_field(tokens) { let field_name = expect_ident(tokens, "expected field name")?; @@ -122,10 +138,40 @@ fn parse_query_fields(tokens: &mut Tokens) -> Result> { expect_punct(tokens, ':', "expected `:` after field name")?; - let child = parse_query_node(tokens)?; - fields.push(quote! { - (#field_str, vec![yeast::query::QueryListElem::SingleNode(#child)]) - }); + // Parse the field's pattern. To support repetition like + // `field: (kind)* @cap`, parse the atom first, then check for + // a quantifier, and lastly handle a trailing `@capture`. + let atom = parse_query_atom(tokens)?; + if peek_is_repetition(tokens) { + let rep = expect_repetition(tokens)?; + let elem = quote! { + yeast::query::QueryListElem::Repeated { + children: vec![yeast::query::QueryListElem::SingleNode(#atom)], + rep: #rep, + } + }; + let elem = maybe_wrap_list_capture(tokens, elem)?; + push_field_elem(&mut field_order, &mut field_elems, field_str, elem); + } else { + let child = if peek_is_at(tokens) { + tokens.next(); + let capture_name = + expect_ident(tokens, "expected capture name after @")?; + let name_str = capture_name.to_string(); + quote! { + yeast::query::QueryNode::Capture { + capture: #name_str, + node: Box::new(#atom), + } + } + } else { + atom + }; + let elem = quote! { + yeast::query::QueryListElem::SingleNode(#child) + }; + push_field_elem(&mut field_order, &mut field_elems, field_str, elem); + } } else { // Bare patterns — accumulate into the implicit `child` field. // We don't break here, so we can interleave with named fields. @@ -137,6 +183,13 @@ fn parse_query_fields(tokens: &mut Tokens) -> Result> { bare_children.extend(elems); } } + let mut fields: Vec = Vec::new(); + for name in field_order { + let elems = field_elems.remove(&name).unwrap(); + fields.push(quote! { + (#name, vec![#(#elems),*]) + }); + } if !bare_children.is_empty() { fields.push(quote! { ("child", vec![#(#bare_children),*]) @@ -299,7 +352,7 @@ fn parse_direct_node(tokens: &mut Tokens, ctx: &Ident) -> Result { Some(TokenTree::Group(g)) if g.delimiter() == Delimiter::Brace => { let group = expect_group(tokens, Delimiter::Brace)?; let expr = group.stream(); - Ok(quote! { #expr }) + Ok(quote! { ::std::convert::Into::::into(#expr) }) } Some(TokenTree::Group(g)) if g.delimiter() == Delimiter::Parenthesis => { let group = expect_group(tokens, Delimiter::Parenthesis)?; @@ -329,12 +382,17 @@ fn parse_direct_node_inner(tokens: &mut Tokens, ctx: &Ident) -> Result Result = #expr; }); + stmts.push(quote! { + let #temp: Vec = (#expr).into_iter() + .map(::std::convert::Into::::into) + .collect(); + }); field_args.push(quote! { (#field_str, #temp) }); continue; } @@ -382,7 +444,7 @@ fn parse_direct_node_inner(tokens: &mut Tokens, ctx: &Ident) -> Result Result::into) + ); + }); } else { let expr = group.stream(); - items.push(quote! { __nodes.push(#expr); }); + items.push(quote! { + __nodes.push(::std::convert::Into::::into(#expr)); + }); } continue; } @@ -580,13 +648,24 @@ pub fn parse_rule_top(input: TokenStream) -> Result { let name_str = &cap.name; match cap.multiplicity { CaptureMultiplicity::Repeated => { - quote! { let #name: Vec = __captures.get_all(#name_str); } + quote! { + let #name: Vec = __captures.get_all(#name_str) + .into_iter() + .map(yeast::NodeRef) + .collect(); + } } CaptureMultiplicity::Optional => { - quote! { let #name: Option = __captures.get_opt(#name_str); } + quote! { + let #name: Option = + __captures.get_opt(#name_str).map(yeast::NodeRef); + } } CaptureMultiplicity::Single => { - quote! { let #name: usize = __captures.get_var(#name_str).unwrap(); } + quote! { + let #name: yeast::NodeRef = + yeast::NodeRef(__captures.get_var(#name_str).unwrap()); + } } } }) @@ -613,19 +692,26 @@ pub fn parse_rule_top(input: TokenStream) -> Result { CaptureMultiplicity::Repeated => quote! { let __field_id = #ctx_ident.ast.field_id_for_name(#name_str) .unwrap_or_else(|| panic!("field '{}' not found", #name_str)); - __fields.insert(__field_id, #name); + __fields.insert( + __field_id, + #name.into_iter() + .map(::std::convert::Into::::into) + .collect(), + ); }, CaptureMultiplicity::Optional => quote! { let __field_id = #ctx_ident.ast.field_id_for_name(#name_str) .unwrap_or_else(|| panic!("field '{}' not found", #name_str)); if let Some(__id) = #name { - __fields.entry(__field_id).or_insert_with(Vec::new).push(__id); + __fields.entry(__field_id).or_insert_with(Vec::new) + .push(::std::convert::Into::::into(__id)); } }, CaptureMultiplicity::Single => quote! { let __field_id = #ctx_ident.ast.field_id_for_name(#name_str) .unwrap_or_else(|| panic!("field '{}' not found", #name_str)); - __fields.entry(__field_id).or_insert_with(Vec::new).push(#name); + __fields.entry(__field_id).or_insert_with(Vec::new) + .push(::std::convert::Into::::into(#name)); }, } }) diff --git a/shared/yeast/doc/yeast.md b/shared/yeast/doc/yeast.md index 893cdea24dde..823bf1c19425 100644 --- a/shared/yeast/doc/yeast.md +++ b/shared/yeast/doc/yeast.md @@ -349,8 +349,8 @@ to enable rewriting: ```rust let desugar = yeast::DesugaringConfig::new() - .add_phase("cleanup", cleanup_rules()) - .add_phase("desugar", desugar_rules()) + .add_phase("cleanup", yeast::PhaseKind::Repeating, cleanup_rules()) + .add_phase("translate", yeast::PhaseKind::OneShot, translate_rules()) .with_output_node_types_yaml(include_str!("output-node-types.yml")); let lang = simple::LanguageSpec { @@ -365,6 +365,15 @@ let lang = simple::LanguageSpec { A single-phase config is just `.add_phase(...)` called once. Phase names appear in error messages so you can tell which phase failed. +There are two kinds of phases: +- **Repeating**: + Each node is re-processed until none of the rules in the phase matches. + When a node no longer matches any rules, its children are recursively processed. In practice this is used to desugar or simplify an AST, while staying mostly within the same schema. +- **One-shot**: + Each node is processed by the first matching rule, and the engine panics if no rule matches. + Rules are then recursively applied to every captured node. + In practice this is used when translating from one AST schema to another, where an exhaustive match is required. + The same YAML node-types is used for both the runtime yeast `Schema` (so rules can refer to output-only kinds and fields) and TRAP validation (it is converted to JSON internally). diff --git a/shared/yeast/src/captures.rs b/shared/yeast/src/captures.rs index a92c5096e94e..ef184cd9f69a 100644 --- a/shared/yeast/src/captures.rs +++ b/shared/yeast/src/captures.rs @@ -61,6 +61,21 @@ impl Captures { } } } + + /// Apply a fallible function to every captured id (across all keys), + /// replacing each id with the result. Stops and returns the error on + /// the first failure. + pub fn try_map_all_captures( + &mut self, + mut f: impl FnMut(Id) -> Result, + ) -> Result<(), E> { + for ids in self.captures.values_mut() { + for id in ids { + *id = f(*id)?; + } + } + Ok(()) + } pub fn map_captures_to(&mut self, from: &str, to: &'static str, f: &mut impl FnMut(Id) -> Id) { if let Some(from_ids) = self.captures.get(from) { let new_values = from_ids.iter().copied().map(f).collect(); diff --git a/shared/yeast/src/dump.rs b/shared/yeast/src/dump.rs index 99ba019cc3ea..07ee134e058c 100644 --- a/shared/yeast/src/dump.rs +++ b/shared/yeast/src/dump.rs @@ -1,6 +1,6 @@ use std::fmt::Write; -use crate::{Ast, Node, NodeContent, CHILD_FIELD}; +use crate::{schema::Schema, Ast, Node, NodeContent, CHILD_FIELD}; /// Options for controlling AST dump output. pub struct DumpOptions { @@ -45,16 +45,143 @@ pub fn dump_ast_with_options( options: &DumpOptions, ) -> String { let mut out = String::new(); - dump_node(ast, root, source, options, 0, &mut out); + dump_node(ast, root, source, options, 0, None, &mut out); out } +/// Dump an AST and annotate type mismatches against a schema inline. +/// +/// Any node that does not match the expected type set for its parent field is +/// rendered with a trailing `" <-- ERROR: ..."` annotation on the same line. +pub fn dump_ast_with_type_errors( + ast: &Ast, + root: usize, + source: &str, + schema: &Schema, +) -> String { + dump_ast_with_type_errors_and_options(ast, root, source, schema, &DumpOptions::default()) +} + +/// Dump an AST and annotate type mismatches against a schema inline. +/// +/// Any node that does not match the expected type set for its parent field is +/// rendered with a trailing `" <-- ERROR: ..."` annotation on the same line. +pub fn dump_ast_with_type_errors_and_options( + ast: &Ast, + root: usize, + source: &str, + schema: &Schema, + options: &DumpOptions, +) -> String { + let mut out = String::new(); + dump_node(ast, root, source, options, 0, Some((schema, None, None)), &mut out); + out +} + +fn format_node_types(node_types: &[crate::schema::NodeType]) -> String { + node_types + .iter() + .map(|t| { + if t.named { + t.kind.clone() + } else { + format!("\"{}\"", t.kind) + } + }) + .collect::>() + .join(" | ") +} + +const EMPTY_NODE_TYPES: &[crate::schema::NodeType] = &[]; + +/// Generate a type-checking error message for a node if it doesn't match expected types. +/// +/// # Arguments +/// - `schema`: The AST schema to validate against. +/// - `node`: The node being checked. +/// - `expected`: The set of allowed types for this node, or `None` if type-checking is disabled. +/// - `parent_field`: Optional tuple of (parent_kind, field_name) for context in error messages. +/// +/// # Returns +/// `Some(error_message)` if the node violates the schema (e.g., wrong kind, missing field declaration). +/// `None` if the node matches the expected types or if type-checking is disabled. +fn type_error_for_node( + schema: &Schema, + node: &Node, + expected: Option<&[crate::schema::NodeType]>, + parent_field: Option<(&str, &str)>, +) -> Option { + if schema.id_for_node_kind(node.kind_name()).is_none() + && schema.id_for_unnamed_node_kind(node.kind_name()).is_none() + { + return Some(format!("node kind '{}' not in schema", node.kind_name())); + } + + let expected = expected?; + if expected.is_empty() { + if let Some((kind, field)) = parent_field { + return Some(format!("the node '{kind}' has no field '{field}'")); + } + return Some("field not declared in schema for this parent node".to_string()); + } + if schema.node_matches_types(node.kind_name(), node.is_named(), expected) { + None + } else { + let actual = if node.is_named() { + node.kind_name().to_string() + } else { + format!("\"{}\"", node.kind_name()) + }; + + if let Some((kind, field)) = parent_field { + Some(format!( + "The field {}.{} should contain {}, but got {}", + kind, + field, + format_node_types(expected), + actual + )) + } else { + Some(format!( + "expected {}, got {}", + format_node_types(expected), + actual + )) + } + } +} + +/// Look up the allowed types for a field in the schema. +/// +/// # Arguments +/// - `schema`: The AST schema to query. +/// - `parent_kind`: The node kind of the parent that contains this field. +/// - `field_id`: The field ID within that parent node. +/// +/// # Returns +/// `Some(&[NodeType])` if the field is declared in the schema and has type constraints. +/// `None` if the field is not declared or has no constraints (undeclared field). +fn expected_for_field<'a>( + schema: &'a Schema, + parent_kind: &str, + field_id: u16, +) -> Option<&'a [crate::schema::NodeType]> { + schema + .field_types(parent_kind, field_id) + .map(|v| v.as_slice()) +} + fn dump_node( ast: &Ast, id: usize, source: &str, options: &DumpOptions, indent: usize, + type_check: Option<( + &Schema, + Option<&[crate::schema::NodeType]>, + Option<(&str, &str)>, + )>, out: &mut String, ) { let node = match ast.get_node(id) { @@ -90,6 +217,12 @@ fn dump_node( } } + if let Some((schema, expected, parent_field)) = type_check { + if let Some(err) = type_error_for_node(schema, node, expected, parent_field) { + write!(out, " <-- ERROR: {err}").unwrap(); + } + } + writeln!(out).unwrap(); // Named fields first @@ -98,31 +231,68 @@ fn dump_node( continue; // Handle unnamed children last } let field_name = ast.field_name_for_id(field_id).unwrap_or("?"); + let child_type_check = type_check.map(|(schema, _, _)| { + let expected = expected_for_field(schema, node.kind_name(), field_id) + .or(Some(EMPTY_NODE_TYPES)); + let parent_field = Some((node.kind_name(), field_name)); + (schema, expected, parent_field) + }); + if children.len() == 1 { write!(out, "{prefix} {field_name}:").unwrap(); // Inline single child let child = ast.get_node(children[0]); if child.is_some_and(is_leaf) { write!(out, " ").unwrap(); - dump_node_inline(ast, children[0], source, options, out); + dump_node_inline(ast, children[0], source, options, child_type_check, out); } else { writeln!(out).unwrap(); - dump_node(ast, children[0], source, options, indent + 2, out); + dump_node( + ast, + children[0], + source, + options, + indent + 2, + child_type_check, + out, + ); } } else { writeln!(out, "{prefix} {field_name}:").unwrap(); for &child_id in children { - dump_node(ast, child_id, source, options, indent + 2, out); + dump_node( + ast, + child_id, + source, + options, + indent + 2, + child_type_check, + out, + ); } } } // Unnamed children — skip unnamed tokens (keywords, punctuation) if let Some(children) = node.fields.get(&CHILD_FIELD) { + let child_type_check = type_check.map(|(schema, _, _)| { + let expected = expected_for_field(schema, node.kind_name(), CHILD_FIELD) + .or(Some(EMPTY_NODE_TYPES)); + let parent_field = Some((node.kind_name(), "children")); + (schema, expected, parent_field) + }); for &child_id in children { if let Some(child) = ast.get_node(child_id) { if child.is_named() { - dump_node(ast, child_id, source, options, indent + 1, out); + dump_node( + ast, + child_id, + source, + options, + indent + 1, + child_type_check, + out, + ); } } } @@ -130,7 +300,18 @@ fn dump_node( } /// Dump a leaf node inline (no newline prefix, caller provides context). -fn dump_node_inline(ast: &Ast, id: usize, source: &str, options: &DumpOptions, out: &mut String) { +fn dump_node_inline( + ast: &Ast, + id: usize, + source: &str, + options: &DumpOptions, + type_check: Option<( + &Schema, + Option<&[crate::schema::NodeType]>, + Option<(&str, &str)>, + )>, + out: &mut String, +) { let node = match ast.get_node(id) { Some(n) => n, None => return, @@ -159,6 +340,12 @@ fn dump_node_inline(ast: &Ast, id: usize, source: &str, options: &DumpOptions, o } } + if let Some((schema, expected, parent_field)) = type_check { + if let Some(err) = type_error_for_node(schema, node, expected, parent_field) { + write!(out, " <-- ERROR: {err}").unwrap(); + } + } + writeln!(out).unwrap(); } diff --git a/shared/yeast/src/lib.rs b/shared/yeast/src/lib.rs index 281f44a98b26..8826c3d6c1e3 100644 --- a/shared/yeast/src/lib.rs +++ b/shared/yeast/src/lib.rs @@ -23,12 +23,73 @@ pub use cursor::Cursor; use query::QueryNode; /// Node ids are indexes into the arena -type Id = usize; +pub type Id = usize; /// Field and Kind ids are provided by tree-sitter type FieldId = u16; type KindId = u16; +/// A typed reference to a node in an [`Ast`] arena. Wraps an [`Id`] but +/// deliberately does not implement [`std::fmt::Display`]: rendering a node +/// requires the [`Ast`] it lives in (to resolve [`NodeContent::Range`] back +/// to source text). Use [`YeastDisplay::yeast_to_string`] to format it. +#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)] +pub struct NodeRef(pub Id); + +impl NodeRef { + pub fn id(self) -> Id { + self.0 + } +} + +impl From for Id { + fn from(value: NodeRef) -> Self { + value.0 + } +} + +/// Like [`std::fmt::Display`], but the formatting routine is given access to +/// the [`Ast`] so that node references can resolve to their source text. +/// +/// All standard primitive and string types implement [`YeastDisplay`] via +/// the [`impl_yeast_display_via_display`] macro below. Coherence prevents a +/// blanket `impl`, so additional types must be added explicitly. +pub trait YeastDisplay { + fn yeast_to_string(&self, ast: &Ast) -> String; +} + +impl YeastDisplay for NodeRef { + fn yeast_to_string(&self, ast: &Ast) -> String { + ast.source_text(self.0) + } +} + +macro_rules! impl_yeast_display_via_display { + ($($t:ty),* $(,)?) => { + $( + impl YeastDisplay for $t { + fn yeast_to_string(&self, _ast: &Ast) -> String { + ::std::string::ToString::to_string(self) + } + } + )* + }; +} + +impl_yeast_display_via_display! { + i8, i16, i32, i64, i128, isize, + u8, u16, u32, u64, u128, usize, + f32, f64, + bool, char, + str, String, +} + +impl YeastDisplay for &T { + fn yeast_to_string(&self, ast: &Ast) -> String { + (**self).yeast_to_string(ast) + } +} + pub const CHILD_FIELD: u16 = u16::MAX; #[derive(Debug)] @@ -160,6 +221,9 @@ pub struct Ast { root: Id, nodes: Vec, schema: schema::Schema, + /// Original source bytes the tree was parsed from. Used to resolve + /// `NodeContent::Range` to text for synthesized literal nodes. + source: Vec, } impl std::fmt::Debug for Ast { @@ -182,21 +246,93 @@ impl Ast { schema: schema::Schema, tree: &tree_sitter::Tree, language: &tree_sitter::Language, + ) -> Self { + Self::from_tree_with_schema_and_source(schema, tree, language, Vec::new()) + } + + pub fn from_tree_with_schema_and_source( + schema: schema::Schema, + tree: &tree_sitter::Tree, + language: &tree_sitter::Language, + source: Vec, ) -> Self { let mut visitor = visitor::Visitor::new(language.clone()); visitor.visit(tree); - visitor.build_with_schema(schema) + let mut ast = visitor.build_with_schema(schema); + ast.source = source; + ast + } + + /// Returns the source text for `id`, resolving `NodeContent::Range` + /// against the stored source bytes when available. + pub fn source_text(&self, id: Id) -> String { + let Some(node) = self.get_node(id) else { return String::new(); }; + let read_range = |range: &tree_sitter::Range| { + let start = range.start_byte; + let end = range.end_byte; + if end <= self.source.len() && start <= end { + String::from_utf8_lossy(&self.source[start..end]).into_owned() + } else { + String::new() + } + }; + match &node.content { + NodeContent::Range(range) => read_range(range), + NodeContent::String(s) => s.to_string(), + NodeContent::DynamicString(s) if !s.is_empty() => s.clone(), + // Synthesized nodes (from rule transforms) carry an empty + // `DynamicString`; resolve them against the inherited source + // range so `#{capture}` after a translation still yields the + // original source text. + NodeContent::DynamicString(_) => match node.source_range { + Some(range) => read_range(&range), + None => String::new(), + }, + } } pub fn walk(&self) -> AstCursor { AstCursor::new(self) } + /// Return all nodes currently allocated in the AST arena. + /// + /// This includes nodes that are no longer reachable from `get_root()` + /// after desugaring rewrites. Use `reachable_node_ids()` for output-level + /// validation/traversal semantics. pub fn nodes(&self) -> &[Node] { &self.nodes } + /// Return node ids reachable from `get_root()` by following child edges. + /// + /// This reflects the effective AST after desugaring and excludes orphaned + /// arena nodes left behind by rewrite operations. + pub fn reachable_node_ids(&self) -> Vec { + let mut reachable = Vec::new(); + let mut stack = vec![self.root]; + let mut seen = vec![false; self.nodes.len()]; + + while let Some(id) = stack.pop() { + if id >= self.nodes.len() || seen[id] { + continue; + } + seen[id] = true; + reachable.push(id); + + if let Some(node) = self.get_node(id) { + for children in node.fields.values() { + for &child in children { + stack.push(child); + } + } + } + } + + reachable + } + pub fn get_root(&self) -> Id { self.root } @@ -493,18 +629,39 @@ impl Rule { node: Id, fresh: &tree_builder::FreshScope, ) -> Result>, String> { + match self.try_match(ast, node)? { + Some(captures) => Ok(Some(self.run_transform(ast, captures, node, fresh))), + None => Ok(None), + } + } + + /// Attempt to match this rule's query against `node`, returning the + /// resulting captures on success. Does not invoke the transform. + fn try_match(&self, ast: &Ast, node: Id) -> Result, String> { let mut captures = Captures::new(); if self.query.do_match(ast, node, &mut captures)? { - fresh.next_scope(); - let source_range = ast.get_node(node).and_then(|n| match n.content { - NodeContent::Range(r) => Some(r), - _ => n.source_range, - }); - Ok(Some((self.transform)(ast, captures, fresh, source_range))) + Ok(Some(captures)) } else { Ok(None) } } + + /// Run this rule's transform with the given captures, using `node`'s + /// source range as the source range of the produced nodes. + fn run_transform( + &self, + ast: &mut Ast, + captures: Captures, + node: Id, + fresh: &tree_builder::FreshScope, + ) -> Vec { + fresh.next_scope(); + let source_range = ast.get_node(node).and_then(|n| match n.content { + NodeContent::Range(r) => Some(r), + _ => n.source_range, + }); + (self.transform)(ast, captures, fresh, source_range) + } } const MAX_REWRITE_DEPTH: usize = 100; @@ -539,17 +696,17 @@ impl<'a> RuleIndex<'a> { } } -fn apply_rules( +fn apply_repeating_rules( rules: &[Rule], ast: &mut Ast, id: Id, fresh: &tree_builder::FreshScope, ) -> Result, String> { let index = RuleIndex::new(rules); - apply_rules_inner(&index, ast, id, fresh, 0, None) + apply_repeating_rules_inner(&index, ast, id, fresh, 0, None) } -fn apply_rules_inner( +fn apply_repeating_rules_inner( index: &RuleIndex, ast: &mut Ast, id: Id, @@ -578,7 +735,7 @@ fn apply_rules_inner( let next_skip = if rule.repeated { None } else { Some(rule_ptr) }; let mut results = Vec::new(); for node in result_node { - results.extend(apply_rules_inner( + results.extend(apply_repeating_rules_inner( index, ast, node, @@ -603,7 +760,7 @@ fn apply_rules_inner( for children in fields.values_mut() { let mut new_children: Option> = None; for (i, &child_id) in children.iter().enumerate() { - let result = apply_rules_inner(index, ast, child_id, fresh, rewrite_depth, None)?; + let result = apply_repeating_rules_inner(index, ast, child_id, fresh, rewrite_depth, None)?; let unchanged = result.len() == 1 && result[0] == child_id; match (&mut new_children, unchanged) { (None, true) => {} // unchanged so far, no allocation needed @@ -628,6 +785,92 @@ fn apply_rules_inner( Ok(vec![id]) } +/// Apply rules using `OneShot` semantics: the first matching rule fires on +/// each visited node, recursion proceeds only through captured nodes (not +/// through the input node's children directly), and an error is returned if +/// no rule matches a visited node. +fn apply_one_shot_rules( + rules: &[Rule], + ast: &mut Ast, + id: Id, + fresh: &tree_builder::FreshScope, +) -> Result, String> { + let index = RuleIndex::new(rules); + apply_one_shot_rules_inner(&index, ast, id, fresh, 0) +} + +fn apply_one_shot_rules_inner( + index: &RuleIndex, + ast: &mut Ast, + id: Id, + fresh: &tree_builder::FreshScope, + rewrite_depth: usize, +) -> Result, String> { + + if rewrite_depth > MAX_REWRITE_DEPTH { + return Err(format!( + "Desugaring exceeded maximum rewrite depth ({MAX_REWRITE_DEPTH}). \ + This likely indicates a non-terminating rule cycle." + )); + } + + let node_kind = ast.get_node(id).map(|n| n.kind()).unwrap_or(""); + + // Don't rewrite unnamed nodes (punctuation, keywords, etc.); leave them + // as-is. Rules target named nodes only. + if let Some(node) = ast.get_node(id) { + if !node.is_named() { + return Ok(vec![id]); + } + } + + for rule in index.rules_for_kind(node_kind) { + if let Some(mut captures) = rule.try_match(ast, id)? { + // Recursively translate every captured node before invoking the + // transform. The transform's output uses output-schema kinds, so + // we must translate captured input-schema nodes to their + // output-schema equivalents first. + captures.try_map_all_captures(|captured_id| { + // Avoid infinite recursion when a capture refers to the root + // node of the matched tree (e.g. an `@_` capture on the + // pattern root): re-analyzing it would match the same rule + // again indefinitely. + if captured_id == id { + return Ok(captured_id); + } + let result = + apply_one_shot_rules_inner(index, ast, captured_id, fresh, rewrite_depth + 1)?; + if result.len() != 1 { + return Err(format!( + "OneShot: recursion on captured node produced {} results, expected exactly 1", + result.len() + )); + } + Ok(result[0]) + })?; + return Ok(rule.run_transform(ast, captures, id, fresh)); + } + } + + Err(format!( + "OneShot: no rule matched node of kind '{node_kind}'" + )) +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum PhaseKind { + /// A node is re-processed until none of the rules in the phase matches, + /// albeit a single rule cannot be applied twice in a row unless that rule is also marked as repeating. + /// When a node no longer matches any rules, its children are recursively processed (top down). + Repeating, + + /// A node is processed by the first matching rule, and the engine panics if no rule matches. + /// Rules are then recursively applied to every captured node. + /// In practice this is used when translating from one AST schema to another, where every node must be rewritten, + /// and it would be a type error to match the rule patterns (based on the input schema) against the output nodes (which conform to the output schema). + OneShot, +} + /// One phase of a desugaring pass: a named bundle of rules that runs to /// completion (a full traversal applying its rules) before the next phase /// starts. Rules within a phase compete for matches as usual; rules in @@ -637,13 +880,15 @@ pub struct Phase { /// Name used in error messages. pub name: String, pub rules: Vec, + pub kind: PhaseKind, } impl Phase { - pub fn new(name: impl Into, rules: Vec) -> Self { + pub fn new(name: impl Into, kind: PhaseKind, rules: Vec) -> Self { Self { name: name.into(), rules, + kind, } } } @@ -661,8 +906,8 @@ impl Phase { /// /// ```ignore /// let config = yeast::DesugaringConfig::new() -/// .add_phase("cleanup", cleanup_rules) -/// .add_phase("desugar", desugar_rules) +/// .add_phase("cleanup", PhaseKind::Repeating, cleanup_rules) +/// .add_phase("desugar", PhaseKind::Repeating, desugar_rules) /// .with_output_node_types_yaml(yaml); /// ``` #[derive(Default)] @@ -682,9 +927,14 @@ impl DesugaringConfig { Self::default() } - /// Append a new phase with the given name and rules. - pub fn add_phase(mut self, name: impl Into, rules: Vec) -> Self { - self.phases.push(Phase::new(name, rules)); + /// Append a new phase with the given name, kind, and rules. + pub fn add_phase( + mut self, + name: impl Into, + kind: PhaseKind, + rules: Vec, + ) -> Self { + self.phases.push(Phase::new(name, kind, rules)); self } @@ -747,8 +997,17 @@ impl<'a> Runner<'a> { }) } - pub fn run_from_tree(&self, tree: &tree_sitter::Tree) -> Result { - let mut ast = Ast::from_tree_with_schema(self.schema.clone(), tree, &self.language); + pub fn run_from_tree( + &self, + tree: &tree_sitter::Tree, + source: &[u8], + ) -> Result { + let mut ast = Ast::from_tree_with_schema_and_source( + self.schema.clone(), + tree, + &self.language, + source.to_vec(), + ); self.run_phases(&mut ast)?; Ok(ast) } @@ -761,7 +1020,12 @@ impl<'a> Runner<'a> { let tree = parser .parse(input, None) .ok_or_else(|| "Failed to parse input".to_string())?; - let mut ast = Ast::from_tree_with_schema(self.schema.clone(), &tree, &self.language); + let mut ast = Ast::from_tree_with_schema_and_source( + self.schema.clone(), + &tree, + &self.language, + input.as_bytes().to_vec(), + ); self.run_phases(&mut ast)?; Ok(ast) } @@ -773,8 +1037,11 @@ impl<'a> Runner<'a> { let fresh = tree_builder::FreshScope::new(); let mut root = ast.get_root(); for phase in self.phases { - let res = apply_rules(&phase.rules, ast, root, &fresh) - .map_err(|e| format!("Phase `{}`: {e}", phase.name))?; + let res = match phase.kind { + PhaseKind::Repeating => apply_repeating_rules(&phase.rules, ast, root, &fresh), + PhaseKind::OneShot => apply_one_shot_rules(&phase.rules, ast, root, &fresh), + } + .map_err(|e| format!("Phase `{}`: {e}", phase.name))?; if res.len() != 1 { return Err(format!( "Phase `{}`: expected exactly one result node, got {}", diff --git a/shared/yeast/src/node_types_yaml.rs b/shared/yeast/src/node_types_yaml.rs index d321ba8a2cf0..eb191076be48 100644 --- a/shared/yeast/src/node_types_yaml.rs +++ b/shared/yeast/src/node_types_yaml.rs @@ -23,6 +23,7 @@ use std::collections::{BTreeMap, BTreeSet}; use std::fmt::Write; +use crate::CHILD_FIELD; use serde::Deserialize; use serde_json::json; @@ -100,32 +101,38 @@ fn parse_field_name(raw: &str) -> FieldSpec { /// Resolve a TypeRef to a (type, named) pair, given the sets of known named /// and unnamed types. -fn resolve_type_ref( +fn resolve_type_ref_pair( type_ref: &TypeRef, named_types: &BTreeSet, unnamed_types: &BTreeSet, -) -> serde_json::Value { +) -> (String, bool) { match type_ref { - TypeRef::Explicit { unnamed } => { - json!({"type": unnamed, "named": false}) - } + TypeRef::Explicit { unnamed } => (unnamed.clone(), false), TypeRef::Name(name) => { let is_named = named_types.contains(name); let is_unnamed = unnamed_types.contains(name); - if is_named && is_unnamed { - // Ambiguous: default to named - json!({"type": name, "named": true}) + (name.clone(), true) } else if is_unnamed { - json!({"type": name, "named": false}) + (name.clone(), false) } else { - // Named, or unknown (assume named) - json!({"type": name, "named": true}) + (name.clone(), true) } } } } +/// Resolve a TypeRef to a {type, named} JSON record, given the sets of known named +/// and unnamed types. +fn resolve_type_ref( + type_ref: &TypeRef, + named_types: &BTreeSet, + unnamed_types: &BTreeSet, +) -> serde_json::Value { + let (kind, named) = resolve_type_ref_pair(type_ref, named_types, unnamed_types); + json!({"type": kind, "named": named}) +} + /// Convert YAML string to node-types JSON string. pub fn convert(yaml_input: &str) -> Result { let yaml: YamlNodeTypes = @@ -233,14 +240,12 @@ pub fn convert(yaml_input: &str) -> Result { serde_json::to_string_pretty(&output).map_err(|e| format!("Failed to serialize JSON: {e}")) } -/// Build a Schema from a YAML node-types string. -/// Registers all node kinds and field names found in the YAML. -pub fn schema_from_yaml(yaml_input: &str) -> Result { - let yaml: YamlNodeTypes = - serde_yaml::from_str(yaml_input).map_err(|e| format!("Failed to parse YAML: {e}"))?; - - let mut schema = crate::schema::Schema::new(); - +/// Apply YAML node-type definitions to a mutable Schema. +/// Registers all types, fields, and allowed types from the YAML into the schema. +fn apply_yaml_to_schema( + yaml: &YamlNodeTypes, + schema: &mut crate::schema::Schema, +) { // Register all supertypes as node kinds for name in yaml.supertypes.keys() { schema.register_kind(name); @@ -264,6 +269,62 @@ pub fn schema_from_yaml(yaml_input: &str) -> Result = yaml.unnamed.iter().cloned().collect(); + + for (supertype, members) in &yaml.supertypes { + let node_types = members + .iter() + .map(|m| { + let (kind, named) = resolve_type_ref_pair(m, &named_types, &unnamed_types); + crate::schema::NodeType { kind, named } + }) + .collect(); + schema.set_supertype_members(supertype, node_types); + } + + // Register allowed field child types for type checking. + for (parent_kind, fields_opt) in &yaml.named { + let Some(fields) = fields_opt else { + continue; + }; + + for (raw_field_name, type_refs) in fields { + let spec = parse_field_name(raw_field_name); + let field_id = match &spec.name { + Some(name) => schema.register_field(name), + None => CHILD_FIELD, + }; + + let mut node_types = type_refs + .clone() + .into_vec() + .into_iter() + .map(|type_ref| { + let (kind, named) = resolve_type_ref_pair(&type_ref, &named_types, &unnamed_types); + crate::schema::NodeType { kind, named } + }) + .collect::>(); + node_types.sort_by(|a, b| a.kind.cmp(&b.kind).then(a.named.cmp(&b.named))); + node_types.dedup_by(|a, b| a.kind == b.kind && a.named == b.named); + schema.set_field_types(parent_kind, field_id, node_types); + } + } +} + +pub fn schema_from_yaml(yaml_input: &str) -> Result { + let yaml: YamlNodeTypes = + serde_yaml::from_str(yaml_input).map_err(|e| format!("Failed to parse YAML: {e}"))?; + + let mut schema = crate::schema::Schema::new(); + apply_yaml_to_schema(&yaml, &mut schema); + Ok(schema) } @@ -278,29 +339,7 @@ pub fn schema_from_yaml_with_language( serde_yaml::from_str(yaml_input).map_err(|e| format!("Failed to parse YAML: {e}"))?; let mut schema = crate::schema::Schema::from_language(language); - - // Register supertypes - for name in yaml.supertypes.keys() { - schema.register_kind(name); - } - - // Register named node kinds and their fields - for (name, fields_opt) in &yaml.named { - schema.register_kind(name); - if let Some(fields) = fields_opt { - for raw_field_name in fields.keys() { - let spec = parse_field_name(raw_field_name); - if let Some(field_name) = &spec.name { - schema.register_field(field_name); - } - } - } - } - - // Register unnamed tokens - for name in &yaml.unnamed { - schema.register_unnamed_kind(name); - } + apply_yaml_to_schema(&yaml, &mut schema); Ok(schema) } diff --git a/shared/yeast/src/schema.rs b/shared/yeast/src/schema.rs index 12554d9c8692..c832a57b23ad 100644 --- a/shared/yeast/src/schema.rs +++ b/shared/yeast/src/schema.rs @@ -1,7 +1,13 @@ -use std::collections::BTreeMap; +use std::collections::{BTreeMap, BTreeSet}; use crate::{FieldId, KindId, CHILD_FIELD}; +#[derive(Clone, Debug)] +pub struct NodeType { + pub kind: String, + pub named: bool, +} + /// A schema defining node kinds and field names for the output AST. /// Built from a node-types.yml file, independent of any tree-sitter grammar. /// @@ -25,6 +31,8 @@ pub struct Schema { unnamed_kind_ids: BTreeMap, kind_names: BTreeMap, next_kind_id: KindId, + field_types: BTreeMap<(String, FieldId), Vec>, + supertypes: BTreeMap>, } impl Default for Schema { @@ -43,6 +51,8 @@ impl Schema { unnamed_kind_ids: BTreeMap::new(), kind_names: BTreeMap::new(), next_kind_id: 1, // 0 is reserved + field_types: BTreeMap::new(), + supertypes: BTreeMap::new(), } } @@ -166,4 +176,68 @@ impl Schema { pub fn node_kind_for_id(&self, id: KindId) -> Option<&'static str> { self.kind_names.get(&id).copied() } + + pub fn set_field_types( + &mut self, + parent_kind: &str, + field_id: FieldId, + node_types: Vec, + ) { + self.field_types + .insert((parent_kind.to_string(), field_id), node_types); + } + + pub fn field_types( + &self, + parent_kind: &str, + field_id: FieldId, + ) -> Option<&Vec> { + self.field_types + .get(&(parent_kind.to_string(), field_id)) + } + + pub fn set_supertype_members(&mut self, supertype: &str, node_types: Vec) { + self.supertypes.insert(supertype.to_string(), node_types); + } + + fn allows_node( + &self, + node_type: &NodeType, + node_kind: &str, + node_named: bool, + active: &mut BTreeSet, + ) -> bool { + if node_type.kind == node_kind && node_type.named == node_named { + return true; + } + + if !node_type.named { + return false; + } + + let Some(members) = self.supertypes.get(&node_type.kind) else { + return false; + }; + + if !active.insert(node_type.kind.clone()) { + return false; + } + + let matched = members + .iter() + .any(|member| self.allows_node(member, node_kind, node_named, active)); + active.remove(&node_type.kind); + matched + } + + pub fn node_matches_types( + &self, + node_kind: &str, + node_named: bool, + node_types: &[NodeType], + ) -> bool { + node_types.iter().any(|node_type| { + self.allows_node(node_type, node_kind, node_named, &mut BTreeSet::new()) + }) + } } diff --git a/shared/yeast/src/visitor.rs b/shared/yeast/src/visitor.rs index 1b9c5eab3627..4bd2606c958b 100644 --- a/shared/yeast/src/visitor.rs +++ b/shared/yeast/src/visitor.rs @@ -52,6 +52,7 @@ impl Visitor { root: 0, schema, nodes: self.nodes.into_iter().map(|n| n.inner).collect(), + source: Vec::new(), } } diff --git a/shared/yeast/tests/test.rs b/shared/yeast/tests/test.rs index ed4202493a46..7f4db1541836 100644 --- a/shared/yeast/tests/test.rs +++ b/shared/yeast/tests/test.rs @@ -1,6 +1,6 @@ #![cfg(test)] -use yeast::dump::dump_ast; +use yeast::dump::{dump_ast, dump_ast_with_type_errors}; use yeast::*; const OUTPUT_SCHEMA_YAML: &str = include_str!("node-types.yml"); @@ -15,7 +15,7 @@ fn parse_and_dump(input: &str) -> String { /// Helper: parse Ruby source with a custom output schema and a single /// phase of rules, return dump. fn run_and_dump(input: &str, rules: Vec) -> String { - run_phased_and_dump(input, vec![Phase::new("test", rules)]) + run_phased_and_dump(input, vec![Phase::new("test", PhaseKind::Repeating, rules)]) } /// Helper: parse Ruby source with a custom output schema and multiple @@ -35,13 +35,42 @@ fn run_and_get_error(input: &str, rules: Vec) -> String { let lang: tree_sitter::Language = tree_sitter_ruby::LANGUAGE.into(); let schema = yeast::node_types_yaml::schema_from_yaml_with_language(OUTPUT_SCHEMA_YAML, &lang).unwrap(); - let phases = vec![Phase::new("test", rules)]; + let phases = vec![Phase::new("test", PhaseKind::Repeating, rules)]; let runner = Runner::with_schema(lang, &schema, &phases); runner .run(input) .expect_err("expected runner to return an error") } +/// Helper: parse Ruby source with no rules and dump with schema type errors. +fn parse_and_dump_typed(input: &str, schema_yaml: &str) -> String { + let runner = Runner::new(tree_sitter_ruby::LANGUAGE.into(), &[]); + let ast = runner.run(input).unwrap(); + let schema = yeast::node_types_yaml::schema_from_yaml(schema_yaml).unwrap(); + dump_ast_with_type_errors(&ast, ast.get_root(), input, &schema) +} + +/// Helper: parse Ruby source with no rules and dump with schema type errors, +/// building schema with language IDs so field checks align with parser fields. +fn parse_and_dump_typed_with_language(input: &str, schema_yaml: &str) -> String { + let lang: tree_sitter::Language = tree_sitter_ruby::LANGUAGE.into(); + let runner = Runner::new(lang.clone(), &[]); + let ast = runner.run(input).unwrap(); + let schema = yeast::node_types_yaml::schema_from_yaml_with_language(schema_yaml, &lang) + .unwrap(); + dump_ast_with_type_errors(&ast, ast.get_root(), input, &schema) +} + +/// Helper: parse Ruby source with custom rules and dump with schema type errors. +fn run_and_dump_typed(input: &str, rules: Vec, schema_yaml: &str) -> String { + let lang: tree_sitter::Language = tree_sitter_ruby::LANGUAGE.into(); + let schema = yeast::node_types_yaml::schema_from_yaml(schema_yaml).unwrap(); + let phases = vec![Phase::new("test", PhaseKind::Repeating, rules)]; + let runner = Runner::with_schema(lang, &schema, &phases); + let ast = runner.run(input).unwrap(); + dump_ast_with_type_errors(&ast, ast.get_root(), input, &schema) +} + /// Assert that a dump equals the expected string, treating the expected /// string as an indented multiline literal: leading/trailing blank lines /// are stripped, and the common leading indentation is removed from every @@ -125,6 +154,85 @@ fn test_parse_for_loop() { ); } +#[test] +fn test_dump_highlights_type_errors_inline() { + let schema_yaml = r#" +named: + program: + $children*: assignment + assignment: + left: identifier + right: identifier + identifier: +"#; + + let dump = parse_and_dump_typed("x = 1", schema_yaml); + assert!(dump.contains("integer \"1\" <-- ERROR:")); +} + +#[test] +fn test_dump_reports_preserved_unknown_kind_after_transformation() { + let schema_yaml = r#" +named: + program: + $children*: assignment + assignment: + left: identifier + right: identifier + identifier: +"#; + + // This rewrite runs and preserves the RHS node kind via capture. + // With schema above, preserving `integer` should be reported inline. + let rules = vec![yeast::rule!( + (assignment left: (_) @left right: (_) @right) + => + (assignment + left: {left} + right: {right} + ) + )]; + + let dump = run_and_dump_typed("x = 1", rules, schema_yaml); + assert!(dump.contains("integer \"1\" <-- ERROR:")); + assert!(dump.contains("node kind 'integer' not in schema")); +} + +#[test] +fn test_dump_reports_undeclared_field_on_node() { + let schema_yaml = r#" +named: + program: + $children*: assignment + assignment: + left: identifier + identifier: +"#; + + let dump = parse_and_dump_typed_with_language("x = y", schema_yaml); + assert!(dump.contains("right: identifier \"y\" <-- ERROR:")); + assert!(dump.contains("the node 'assignment' has no field 'right'")); +} + +#[test] +fn test_dump_reports_disallowed_kind_in_field_type() { + let schema_yaml = r#" +named: + program: + $children*: assignment + assignment: + left: identifier + right: identifier + identifier: + integer: +"#; + + let dump = parse_and_dump_typed_with_language("x = 1", schema_yaml); + assert!(dump.contains("right: integer \"1\" <-- ERROR:")); + assert!(dump.contains("should contain")); + assert!(dump.contains("but got integer")); +} + // ---- Query tests ---- #[test] @@ -166,6 +274,32 @@ fn test_query_no_match() { assert!(!matched); } +#[test] +fn test_reachable_nodes_excludes_orphaned_rewrite_nodes() { + let lang: tree_sitter::Language = tree_sitter_ruby::LANGUAGE.into(); + let schema = yeast::node_types_yaml::schema_from_yaml_with_language(OUTPUT_SCHEMA_YAML, &lang) + .unwrap(); + let phases = vec![Phase::new( + "test", + PhaseKind::Repeating, + vec![yeast::rule!((integer) => (identifier "replaced"))], + )]; + let runner = Runner::with_schema(lang, &schema, &phases); + + let input = "x = 1"; + let ast = runner.run(input).unwrap(); + let reachable_ids = ast.reachable_node_ids(); + + assert!( + ast.nodes().len() > reachable_ids.len(), + "expected rewrite to leave orphaned arena nodes" + ); + + let dump = dump_ast(&ast, ast.get_root(), input); + assert!(dump.contains("identifier \"replaced\"")); + assert!(!dump.contains("integer \"1\"")); +} + #[test] fn test_query_repeated_capture() { let runner = Runner::new(tree_sitter_ruby::LANGUAGE.into(), &[]); @@ -653,8 +787,8 @@ fn test_phased_desugaring() { let dump = run_phased_and_dump( "x = 1", vec![ - Phase::new("cleanup", cleanup), - Phase::new("desugar", desugar), + Phase::new("cleanup", PhaseKind::Repeating, cleanup), + Phase::new("desugar", PhaseKind::Repeating, desugar), ], ); assert_dump_eq( @@ -675,7 +809,11 @@ fn test_phase_error_includes_phase_name() { let lang: tree_sitter::Language = tree_sitter_ruby::LANGUAGE.into(); let schema = yeast::node_types_yaml::schema_from_yaml_with_language(OUTPUT_SCHEMA_YAML, &lang).unwrap(); - let phases = vec![Phase::new("buggy", vec![swap_assignment_rule().repeated()])]; + let phases = vec![Phase::new( + "buggy", + PhaseKind::Repeating, + vec![swap_assignment_rule().repeated()], + )]; let runner = Runner::with_schema(lang, &schema, &phases); let err = runner .run("x = 1") @@ -690,6 +828,168 @@ fn test_phase_error_includes_phase_name() { ); } +/// Helper: an exhaustive set of OneShot rules covering every node reachable +/// (via captures) when translating `"x = 1"`. +fn one_shot_xeq1_rules() -> Vec { + vec![ + yeast::rule!( + (program (_)* @stmts) + => + (program stmt: {..stmts}) + ), + yeast::rule!( + (assignment left: (_) @left right: (_) @right) + => + (first_node left: {left} right: {right}) + ), + yeast::rule!((identifier) => (identifier "ID")), + yeast::rule!((integer) => (integer "INT")), + ] +} + +#[test] +fn test_one_shot_phase() { + let lang: tree_sitter::Language = tree_sitter_ruby::LANGUAGE.into(); + let schema = + yeast::node_types_yaml::schema_from_yaml_with_language(OUTPUT_SCHEMA_YAML, &lang).unwrap(); + let phases = vec![Phase::new( + "translate", + PhaseKind::OneShot, + one_shot_xeq1_rules(), + )]; + let runner = Runner::with_schema(lang, &schema, &phases); + + let input = "x = 1"; + let ast = runner.run(input).unwrap(); + let dump = dump_ast(&ast, ast.get_root(), input); + assert_dump_eq( + &dump, + r#" + program + stmt: + first_node + left: identifier "ID" + right: integer "INT" + "#, + ); +} + +#[test] +fn test_one_shot_phase_errors_when_no_rule_matches() { + let lang: tree_sitter::Language = tree_sitter_ruby::LANGUAGE.into(); + let schema = + yeast::node_types_yaml::schema_from_yaml_with_language(OUTPUT_SCHEMA_YAML, &lang).unwrap(); + // Drop the `integer` rule so the recursion has no rule for `integer`. + let mut rules = one_shot_xeq1_rules(); + rules.pop(); + let phases = vec![Phase::new("translate", PhaseKind::OneShot, rules)]; + let runner = Runner::with_schema(lang, &schema, &phases); + + let err = runner + .run("x = 1") + .expect_err("expected OneShot to error on unmatched node"); + assert!( + err.contains("Phase `translate`"), + "error should name the phase, got: {err}" + ); + assert!( + err.contains("no rule matched") && err.contains("integer"), + "error should describe the unmatched node kind, got: {err}" + ); +} + +/// OneShot recursion must apply rules to *captured* nodes, even if the rule +/// returns a captured child verbatim. A buggy implementation that only +/// recurses into the children of the rule's output (rather than into the +/// captures) would leave the returned capture untransformed. +#[test] +fn test_one_shot_recurses_into_returned_capture() { + let lang: tree_sitter::Language = tree_sitter_ruby::LANGUAGE.into(); + let schema = + yeast::node_types_yaml::schema_from_yaml_with_language(OUTPUT_SCHEMA_YAML, &lang).unwrap(); + let rules = vec![ + yeast::rule!( + (program (_)* @stmts) + => + (program stmt: {..stmts}) + ), + // Returns the captured `left` verbatim, discarding `right`. + yeast::rule!( + (assignment left: (_) @left right: (_) @right) + => + {left} + ), + yeast::rule!((identifier) => (identifier "ID")), + yeast::rule!((integer) => (integer "INT")), + ]; + let phases = vec![Phase::new("translate", PhaseKind::OneShot, rules)]; + let runner = Runner::with_schema(lang, &schema, &phases); + + let input = "x = 1"; + let ast = runner.run(input).unwrap(); + let dump = dump_ast(&ast, ast.get_root(), input); + // `left` is an `identifier`; OneShot must apply the identifier rule to + // it before the assignment transform returns it verbatim. + assert_dump_eq( + &dump, + r#" + program + stmt: identifier "ID" + "#, + ); +} + +/// OneShot recursion must NOT descend into the children of the rule's output. +/// A rule may legitimately wrap a captured node in fresh output-schema nodes +/// that have no matching rule of their own (since rule patterns target the +/// input schema). Recursing into the output would erroneously try to find +/// rules for those wrapper kinds and fail. +#[test] +fn test_one_shot_does_not_recurse_into_wrapper_output() { + let lang: tree_sitter::Language = tree_sitter_ruby::LANGUAGE.into(); + let schema = + yeast::node_types_yaml::schema_from_yaml_with_language(OUTPUT_SCHEMA_YAML, &lang).unwrap(); + let rules = vec![ + yeast::rule!( + (program (_)* @stmts) + => + (program stmt: {..stmts}) + ), + // Wraps `left` in nested `first_node`/`second_node` output kinds. + // Neither wrapper kind has a matching rule, so a buggy implementation + // that recurses into the wrapper's children would error. + yeast::rule!( + (assignment left: (_) @left right: (_) @right) + => + (first_node + left: (second_node left: {left} right: {right}) + right: {left} + ) + ), + yeast::rule!((identifier) => (identifier "ID")), + yeast::rule!((integer) => (integer "INT")), + ]; + let phases = vec![Phase::new("translate", PhaseKind::OneShot, rules)]; + let runner = Runner::with_schema(lang, &schema, &phases); + + let input = "x = 1"; + let ast = runner.run(input).unwrap(); + let dump = dump_ast(&ast, ast.get_root(), input); + assert_dump_eq( + &dump, + r#" + program + stmt: + first_node + left: + second_node + left: identifier "ID" + right: integer "INT" + right: identifier "ID" + "#, + ); +} + // ---- Cursor tests ---- #[test] @@ -760,3 +1060,54 @@ fn test_desugar_for_with_multiple_assignment() { "#, ); } + +/// Regression test: `#{capture}` in a template must render the *source text* +/// of the captured node, not its arena `Id`. Previously, captures were bound +/// as `usize`, so `#{cap}` printed the integer id (e.g. `"3"`) via `Display`. +/// Captures are now bound as `NodeRef`, which has no `Display` impl and +/// resolves to the captured node's source text via `YeastDisplay`. +#[test] +fn test_hash_brace_renders_capture_source_text() { + let rule = rule!( + (call + method: (identifier) @name + receiver: (identifier) @recv + ) + => + (call + method: (identifier #{name}) + receiver: (identifier #{recv}) + arguments: (argument_list) + ) + ); + let dump = run_and_dump("foo.bar()", vec![rule]); + assert_dump_eq( + &dump, + r#" + program + call + arguments: argument_list "foo.bar()" + method: identifier "bar" + receiver: identifier "foo" + "#, + ); +} + +/// Regression test: non-`NodeRef` values in `#{expr}` still render via their +/// `Display` impl (covered by `YeastDisplay`'s blanket impls for primitives). +#[test] +fn test_hash_brace_renders_integer_expression() { + let rule = rule!( + (identifier) @_ + => + (identifier #{1 + 2}) + ); + let dump = run_and_dump("foo", vec![rule]); + assert_dump_eq( + &dump, + r#" + program + identifier "3" + "#, + ); +} diff --git a/unified/AGENTS.md b/unified/AGENTS.md index 488a94f44bd4..aa5007a56561 100644 --- a/unified/AGENTS.md +++ b/unified/AGENTS.md @@ -20,10 +20,15 @@ grammar source), run `scripts/regenerate-grammar.sh` to: it shows the impact of a grammar tweak on the named node kinds, fields, and child types in a form much easier to read than the raw JSON. -## Testing -- If you changed the extractor code, always rebuild it before running tests. +## Extractor Testing +- To run extractor tests, run `cargo test` in the `extractor` directory. -- To run all tests, run `codeql test run --search-path extractor-pack ql/test` +- Do not edit the printed ASTs in `extractor/test/corpus` directly. To regenerate the ASTs, run `scripts/update-corpus.sh`. + +## CodeQL Testing +- If you changed the extractor code, always rebuild it before running CodeQL tests. + +- To run all CodeQL tests, run `codeql test run --search-path extractor-pack ql/test` - Do not edit `.expected` files manually. To update the expected output, pass `--learn` to the `codeql test run` command. diff --git a/unified/extractor/ast_types.yml b/unified/extractor/ast_types.yml new file mode 100644 index 000000000000..22a5e8b19fb8 --- /dev/null +++ b/unified/extractor/ast_types.yml @@ -0,0 +1,144 @@ +supertypes: + expr: + - name_expr + - int_literal + - string_literal + - binary_expr + - unary_expr + - call_expr + - member_access_expr + - lambda_expr + - unsupported_node + stmt: + - empty_stmt + - block_stmt + - expr_stmt + - if_stmt + - variable_declaration_stmt + - guard_if_stmt + - unsupported_node + condition: + - expr_condition + - let_pattern_condition + - sequence_condition + - unsupported_node + pattern: + - var_pattern + - apply_pattern + - tuple_pattern + - ignore_pattern + - unsupported_node +named: + # Top-level is the root node, currently containing a list of expressions + top_level: + body*: [expr, stmt] + + # An identifier used in the context of an expression + name_expr: + identifier: identifier + + # An integer literal + int_literal: + + # A string literal + string_literal: + + # Application of a binary operator, such as `a + b` + binary_expr: + left: expr + operator: operator + right: expr + + # Application of a unary operator, such as `!x` + unary_expr: + operand: expr + operator: operator + + # A function or method call, such as `f(x)` or `obj.m(x)`. Method calls + # are represented as a call whose `function` is a `member_access_expr`. + call_expr: + function: expr + argument*: expr + + # Member access, such as `obj.member`. + member_access_expr: + target: expr + member: identifier + + lambda_expr: + parameter*: parameter + body: [expr, stmt] + + # A parameter + parameter: + pattern: pattern + + empty_stmt: + + block_stmt: + body*: stmt + + expr_stmt: + expr: expr + + if_stmt: + condition: condition + then?: stmt + else?: stmt + + variable_declaration_stmt: + variable_declarator+: variable_declarator + + # A variable declaration, or assignment to a pattern. + # The initializer is optional (but typically only possible in combination with a simple variable pattern). + variable_declarator: + pattern: pattern + value?: expr + + # Evaluate 'condition', and if false, execute 'else' which must break from the enclosing block scope (return, break, etc). + # Any variables bound by 'condition' will be in scope for the remainder of the enclosing block scope + # (which differs from how if_stmt works). + guard_if_stmt: + condition: condition + else: stmt + + # Evaluates the given condition and interprets it as a boolean (by language conventions) + expr_condition: + expr: expr + + # A series of statements that are executed before evaluating the trailing condition. + # Useful for languages where a conditional clause may be preceded by side-effecting + # syntactic elements (e.g. binding clauses) that don't themselves form a condition. + sequence_condition: + stmt*: stmt + condition: condition + + # Evaluate 'expr' and match its result against 'pattern', and return true if it matches. + # Variables bound by the pattern will be in scope within the 'true' branch controlled by this condition. + let_pattern_condition: + pattern: pattern + value: expr + + # A pattern matching anything, binding its value to the given variable + var_pattern: + identifier: identifier + + # A pattern matching anything, binding no variables, usually using the syntax "_" + ignore_pattern: + + # A pattern such as `Some(x)` where `Some` is the constructor and `x` is an argument + apply_pattern: + constructor: expr + argument*: pattern + + # A tuple pattern such as `(a, b)` in `let (a, b) = pair`. + tuple_pattern: + element*: pattern + + # An simple unqualified identifier token + identifier: + + # A node that we don't yet translate + unsupported_node: + + operator: diff --git a/unified/extractor/src/extractor.rs b/unified/extractor/src/extractor.rs index eb6f06eb259b..7601fa8addbe 100644 --- a/unified/extractor/src/extractor.rs +++ b/unified/extractor/src/extractor.rs @@ -3,9 +3,7 @@ use std::path::PathBuf; use codeql_extractor::extractor::simple; use codeql_extractor::trap; - -#[path = "languages/swift/swift.rs"] -mod swift; +use crate::languages; #[derive(Args)] pub struct Options { @@ -25,11 +23,17 @@ pub struct Options { pub fn run(options: Options) -> std::io::Result<()> { codeql_extractor::extractor::set_tracing_level("unified"); + // The generated dbscheme/QL library uses the unified_* relation namespace. + // Keep per-language specs for parser/rules/file globs, but normalize the + // extraction table prefix so emitted TRAP relations match the dbscheme. + let mut languages = languages::all_language_specs(); + for lang in &mut languages { + lang.prefix = "unified"; + } + let extractor = simple::Extractor { prefix: "unified".to_string(), - languages: vec![ - swift::language_spec(), - ], + languages, trap_dir: options.output_dir, trap_compression: trap::Compression::from_env("CODEQL_EXTRACTOR_UNIFIED_OPTION_TRAP_COMPRESSION"), source_archive_dir: options.source_archive_dir, diff --git a/unified/extractor/src/generator.rs b/unified/extractor/src/generator.rs index ce1f37144a4e..cbf971a8ff25 100644 --- a/unified/extractor/src/generator.rs +++ b/unified/extractor/src/generator.rs @@ -3,6 +3,8 @@ use std::path::PathBuf; use codeql_extractor::generator::{generate, language::Language}; +use crate::languages; + #[derive(Args)] pub struct Options { /// Path of the generated dbscheme file @@ -17,10 +19,16 @@ pub struct Options { pub fn run(options: Options) -> std::io::Result<()> { codeql_extractor::extractor::set_tracing_level("unified"); + // The QL-visible schema is the unified output AST, not the per-language + // input grammars. Pass it via `desugar.output_node_types_yaml` so the + // generator converts the YAML to JSON node-types. + let desugar = yeast::DesugaringConfig::new() + .with_output_node_types_yaml(languages::OUTPUT_AST_SCHEMA); + let languages = vec![Language { - name: "Swift".to_owned(), - node_types: tree_sitter_swift::NODE_TYPES, - desugar: None, + name: "Unified".to_owned(), + node_types: "", // unused: generator picks up output_node_types_yaml above + desugar: Some(desugar), }]; generate(languages, options.dbscheme, options.library, "run unified/scripts/create-extractor-pack.sh") diff --git a/unified/extractor/src/languages/mod.rs b/unified/extractor/src/languages/mod.rs new file mode 100644 index 000000000000..20ad599edfb6 --- /dev/null +++ b/unified/extractor/src/languages/mod.rs @@ -0,0 +1,11 @@ +use codeql_extractor::extractor::simple; + +#[path = "swift/swift.rs"] +mod swift; + +/// Shared YEAST output AST schema for all languages. +pub(crate) const OUTPUT_AST_SCHEMA: &str = include_str!("../../ast_types.yml"); + +pub fn all_language_specs() -> Vec { + vec![swift::language_spec(OUTPUT_AST_SCHEMA)] +} diff --git a/unified/extractor/src/languages/swift/swift.rs b/unified/extractor/src/languages/swift/swift.rs index c3843a5979c5..595f56a0b39a 100644 --- a/unified/extractor/src/languages/swift/swift.rs +++ b/unified/extractor/src/languages/swift/swift.rs @@ -1,18 +1,358 @@ use codeql_extractor::extractor::simple; -use yeast::{rule, DesugaringConfig}; +use yeast::{build::BuildCtx, rule, DesugaringConfig, PhaseKind}; -fn desugaring_rules() -> Vec { +/// Names of output AST kinds that belong to the `expr` supertype. Kept in +/// sync with `ast_types.yml`. `unsupported_node` is intentionally omitted +/// because it is also a member of the `stmt` supertype. +const EXPR_KINDS: &[&str] = &[ + "name_expr", + "int_literal", + "string_literal", + "binary_expr", + "unary_expr", + "call_expr", + "member_access_expr", + "lambda_expr", +]; + +/// If `id` is an `expr`, wrap it in `expr_stmt` so it can sit in a `stmt` +/// position; otherwise return it unchanged. +fn wrap_expr_in_stmt(ctx: &mut BuildCtx, id: usize) -> usize { + let kind = ctx.ast.get_node(id).map(|n| n.kind()).unwrap_or(""); + if EXPR_KINDS.contains(&kind) { + yeast::tree!(ctx, (expr_stmt expr: {id})) + } else { + id + } +} + +fn translation_rules() -> Vec { vec![ rule!( - (additive_expression) + (source_file (_)* @children) + => + (top_level + body: {..children} + ) + ), + // ---- Binary expressions ---- + // Swift's parser produces a different node kind for each operator + // family, but the field shape (`lhs` / `op` / `rhs`) is uniform, so + // each maps onto `binary_expr`. + rule!( + (additive_expression + lhs: (_) @left + op: _ @operator + rhs: (_) @right) + => + (binary_expr + left: {left} + operator: (operator #{operator}) + right: {right}) + ), + rule!( + (multiplicative_expression + lhs: (_) @left + op: _ @operator + rhs: (_) @right) + => + (binary_expr + left: {left} + operator: (operator #{operator}) + right: {right}) + ), + rule!( + (comparison_expression + lhs: (_) @left + op: _ @operator + rhs: (_) @right) + => + (binary_expr + left: {left} + operator: (operator #{operator}) + right: {right}) + ), + rule!( + (equality_expression + lhs: (_) @left + op: _ @operator + rhs: (_) @right) + => + (binary_expr + left: {left} + operator: (operator #{operator}) + right: {right}) + ), + rule!( + (conjunction_expression + lhs: (_) @left + op: _ @operator + rhs: (_) @right) + => + (binary_expr + left: {left} + operator: (operator #{operator}) + right: {right}) + ), + rule!( + (disjunction_expression + lhs: (_) @left + op: _ @operator + rhs: (_) @right) + => + (binary_expr + left: {left} + operator: (operator #{operator}) + right: {right}) + ), + rule!( + (nil_coalescing_expression + lhs: (_) @left + op: _ @operator + rhs: (_) @right) + => + (binary_expr + left: {left} + operator: (operator #{operator}) + right: {right}) + ), + rule!( + (range_expression + start: (_) @left + op: _ @operator + end: (_) @right) + => + (binary_expr + left: {left} + operator: (operator #{operator}) + right: {right}) + ), + // ---- Unary expressions ---- + rule!( + (prefix_expression + operation: _ @operator + target: (_) @operand) + => + (unary_expr + operand: {operand} + operator: (operator #{operator})) + ), + // ---- Identifiers / name expressions ---- + rule!( + (simple_identifier) @name + => + (name_expr + identifier: (identifier #{name})) + ), + // ---- Literals ---- + rule!( + (integer_literal) @lit + => + (int_literal #{lit}) + ), + // String literals: render the *raw* source text, including the + // surrounding quotes. Interpolations (e.g. `"hi \(x)"`) are not + // yet broken out into structured pieces \u2014 they show up as part + // of the literal's source text. + rule!( + (line_string_literal) @lit + => + (string_literal #{lit}) + ), // ---- Lambdas / closures ---- + // Map a `lambda_literal` whose body is a single statement to + // `lambda_expr`. Multi-statement bodies fall through to + // `unsupported_node` because `lambda_expr.body` is single-valued + // in the current `ast_types.yml`. Parameters from explicit-typed + // closures (`{ (x: Int) -> Int in ... }`) are not yet captured. + rule!( + (lambda_literal + (statements (_) @body)) + => + (lambda_expr + body: {body}) + ), + // ---- Block / statement wrapping ---- + // A `(statements ...)` node corresponds to a brace-delimited block. + // Each child is mapped through translation; bare expression results + // get wrapped in `expr_stmt` so they fit the `body*: stmt` field. + rule!( + (statements (_)* @stmts) + => + (block_stmt body: {..stmts.iter().copied().map(|n| + wrap_expr_in_stmt(&mut __yeast_ctx, n.into()) + ).collect::>()}) + ), + // ---- Calls and member access ---- + // Member access, e.g. `obj.member`. The Swift parser wraps the + // member name as `(navigation_suffix suffix: (simple_identifier))`. + rule!( + (navigation_expression + target: (_) @target + suffix: (navigation_suffix + suffix: (simple_identifier) @member)) + => + (member_access_expr + target: {target} + member: (identifier #{member})) + ), + // Function / method call. The callee is the first child of + // `call_expression`; the second is a `call_suffix` whose + // `value_arguments` (if present) hold the parenthesized args. A + // trailing closure (`call_suffix` with a `lambda_literal` child) + // is appended as a final argument. + rule!( + (call_expression + (_) @callee + (call_suffix + (value_arguments + (value_argument value: (_) @args)*)? + (lambda_literal)? @trailing)) + => + (call_expr + function: {callee} + argument: {..args} + argument: {..trailing} + ) + ), + // ---- Guard statement ---- + // `guard let x = e else { ... }` — currently only handles the + // let-binding form. The Swift parser models the `let` keyword as a + // `value_binding_pattern` child of `condition`, followed by an + // unnamed `=` and the source expression. + rule!( + (guard_statement + bound_identifier: (simple_identifier) @id + condition: (value_binding_pattern) + condition: (_) @value + (else) + (statements) @else_branch) + => + (guard_if_stmt + condition: (let_pattern_condition + pattern: (var_pattern identifier: (identifier #{id})) + value: {value}) + else: {else_branch}) + ), + // ---- If statement ---- + // if-let binding (with optional else branch). The Swift parser puts + // the bound name in `bound_identifier`, the `let` keyword as a + // `value_binding_pattern` child of `condition`, and the source + // expression as a separate child of `condition`. + rule!( + (if_statement + bound_identifier: (simple_identifier) @id + condition: (value_binding_pattern) + condition: (_) @value + (statements) @then + (else) + (_) @else_branch) + => + (if_stmt + condition: (let_pattern_condition + pattern: (var_pattern identifier: (identifier #{id})) + value: {value}) + then: {then} + else: {else_branch}) + ), + rule!( + (if_statement + bound_identifier: (simple_identifier) @id + condition: (value_binding_pattern) + condition: (_) @value + (statements) @then) + => + (if_stmt + condition: (let_pattern_condition + pattern: (var_pattern identifier: (identifier #{id})) + value: {value}) + then: {then}) + ), + // With explicit else branch (block or chained if). + rule!( + (if_statement + condition: (_) @cond + (statements) @then + (else) + (_) @else_branch) + => + (if_stmt + condition: (expr_condition expr: {cond}) + then: {then} + else: {else_branch}) + ), + // Without else branch. + rule!( + (if_statement + condition: (_) @cond + (statements) @then) + => + (if_stmt + condition: (expr_condition expr: {cond}) + then: {then}) + ), // ---- Patterns ---- + // The Swift parser uses a `pattern` node with a `bound_identifier` + // field for simple bindings such as `let x = ...`. + rule!( + (pattern bound_identifier: (simple_identifier) @id) + => + (var_pattern + identifier: (identifier #{id})) + ), + // Inside tuple patterns, the inner `pattern` node holds a bare + // `simple_identifier` (with no `bound_identifier` field). + rule!( + (pattern (simple_identifier) @id) + => + (var_pattern + identifier: (identifier #{id})) + ), + // Tuple destructuring pattern, e.g. `let (a, b) = pair`. The parser + // emits a `pattern` node whose unnamed children are themselves + // `pattern` nodes. + rule!( + (pattern (pattern)+ @parts) + => + (tuple_pattern element: {..parts}) + ), + // ---- Variable declarations ---- + // Handles single (`let x = e`), multiple (`let x = 1, y = 2`), + // and uninitialized (`var x: T`) bindings. + rule!( + (property_declaration + name: (_)* @pats + value: (_)* @vals) + => + (variable_declaration_stmt + variable_declarator: {..pats.iter().enumerate().map(|(i, &pat)| { + match vals.get(i).copied() { + Some(val) => yeast::tree!( + (variable_declarator + pattern: {pat} + value: {val})), + None => yeast::tree!( + (variable_declarator + pattern: {pat})), + } + })}) + ), + // ---- Fallbacks ---- + rule!( + (_) + => + (unsupported_node) + ), + rule!( + _ @node => - (simple_identifier "blah") + {node} ), ] } -pub fn language_spec() -> simple::LanguageSpec { - let desugar = DesugaringConfig::new().add_phase("desugar", desugaring_rules()); +pub fn language_spec(desugared_ast_schema: &'static str) -> simple::LanguageSpec { + let desugar = DesugaringConfig::new() + .add_phase("translate", PhaseKind::OneShot, translation_rules()) + .with_output_node_types_yaml(desugared_ast_schema); simple::LanguageSpec { prefix: "swift", ts_language: tree_sitter_swift::LANGUAGE.into(), diff --git a/unified/extractor/src/main.rs b/unified/extractor/src/main.rs index e6721d4e2243..5a3407c37a29 100644 --- a/unified/extractor/src/main.rs +++ b/unified/extractor/src/main.rs @@ -3,6 +3,7 @@ use clap::Parser; mod autobuilder; mod extractor; mod generator; +mod languages; #[derive(Parser)] #[command(author, version, about)] diff --git a/unified/extractor/tests/corpus/swift/closures.txt b/unified/extractor/tests/corpus/swift/closures.txt new file mode 100644 index 000000000000..57dbfe793812 --- /dev/null +++ b/unified/extractor/tests/corpus/swift/closures.txt @@ -0,0 +1,281 @@ +=== +Closure with explicit parameters +=== + +let f = { (x: Int) -> Int in x * 2 } + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "f" + value: + lambda_literal + type: + lambda_function_type + return_type: + type + name: + user_type + type_identifier "Int" + lambda_function_type_parameters + lambda_parameter + name: simple_identifier "x" + type: + type + name: + user_type + type_identifier "Int" + statements + multiplicative_expression + lhs: simple_identifier "x" + op: * + rhs: integer_literal "2" + value_binding_pattern + mutability: let + +--- + +top_level + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: + lambda_expr + body: + binary_expr + operator: operator "*" + left: + name_expr + identifier: identifier "x" + right: int_literal "2" + pattern: + var_pattern + identifier: identifier "f" + +=== +Closure with shorthand parameters +=== + +let f = { $0 + $1 } + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "f" + value: + lambda_literal + statements + additive_expression + lhs: simple_identifier "$0" + op: + + rhs: simple_identifier "$1" + value_binding_pattern + mutability: let + +--- + +top_level + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: + lambda_expr + body: + binary_expr + operator: operator "+" + left: + name_expr + identifier: identifier "$0" + right: + name_expr + identifier: identifier "$1" + pattern: + var_pattern + identifier: identifier "f" + +=== +Trailing closure +=== + +xs.map { $0 * 2 } + +--- + +source_file + call_expression + navigation_expression + suffix: + navigation_suffix + suffix: simple_identifier "map" + target: simple_identifier "xs" + call_suffix + lambda_literal + statements + multiplicative_expression + lhs: simple_identifier "$0" + op: * + rhs: integer_literal "2" + +--- + +top_level + body: + call_expr + argument: + lambda_expr + body: + binary_expr + operator: operator "*" + left: + name_expr + identifier: identifier "$0" + right: int_literal "2" + function: + member_access_expr + target: + name_expr + identifier: identifier "xs" + member: identifier "map" + +=== +Closure with capture list +=== + +let f = { [weak self] in self?.doThing() } + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "f" + value: + lambda_literal + captures: + capture_list + capture_list_item + name: simple_identifier "self" + ownership_modifier + statements + call_expression + navigation_expression + suffix: + navigation_suffix + suffix: simple_identifier "doThing" + target: + optional_chain_marker + self_expression + call_suffix + value_arguments + value_binding_pattern + mutability: let + +--- + +top_level + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: + lambda_expr + body: + call_expr + argument: + function: + member_access_expr + target: unsupported_node "self?" + member: identifier "doThing" + pattern: + var_pattern + identifier: identifier "f" + +=== +Multi-statement closure +=== + +let f = { (x: Int) -> Int in + let y = x + 1 + return y * 2 +} + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "f" + value: + lambda_literal + type: + lambda_function_type + return_type: + type + name: + user_type + type_identifier "Int" + lambda_function_type_parameters + lambda_parameter + name: simple_identifier "x" + type: + type + name: + user_type + type_identifier "Int" + statements + property_declaration + name: + pattern + bound_identifier: simple_identifier "y" + value: + additive_expression + lhs: simple_identifier "x" + op: + + rhs: integer_literal "1" + value_binding_pattern + mutability: let + control_transfer_statement + result: + multiplicative_expression + lhs: simple_identifier "y" + op: * + rhs: integer_literal "2" + value_binding_pattern + mutability: let + +--- + +top_level + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: + lambda_expr + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: + binary_expr + operator: operator "+" + left: + name_expr + identifier: identifier "x" + right: int_literal "1" + pattern: + var_pattern + identifier: identifier "y" + pattern: + var_pattern + identifier: identifier "f" diff --git a/unified/extractor/tests/corpus/swift/collections.txt b/unified/extractor/tests/corpus/swift/collections.txt new file mode 100644 index 000000000000..9a1186ac77d5 --- /dev/null +++ b/unified/extractor/tests/corpus/swift/collections.txt @@ -0,0 +1,322 @@ +=== +Array literal +=== + +let xs = [1, 2, 3] + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "xs" + value: + array_literal + element: + integer_literal "1" + integer_literal "2" + integer_literal "3" + value_binding_pattern + mutability: let + +--- + +top_level + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "[1, 2, 3]" + pattern: + var_pattern + identifier: identifier "xs" + +=== +Empty array literal with type +=== + +let xs: [Int] = [] + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "xs" + value: + array_literal + value_binding_pattern + mutability: let + type_annotation + type: + type + name: + array_type + element: + type + name: + user_type + type_identifier "Int" + +--- + +top_level + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "[]" + pattern: + var_pattern + identifier: identifier "xs" + +=== +Dictionary literal +=== + +let d = ["a": 1, "b": 2] + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "d" + value: + dictionary_literal + key: + line_string_literal + text: line_str_text "a" + line_string_literal + text: line_str_text "b" + value: + integer_literal "1" + integer_literal "2" + value_binding_pattern + mutability: let + +--- + +top_level + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "[\"a\": 1, \"b\": 2]" + pattern: + var_pattern + identifier: identifier "d" + +=== +Set literal +=== + +let s: Set = [1, 2, 3] + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "s" + value: + array_literal + element: + integer_literal "1" + integer_literal "2" + integer_literal "3" + value_binding_pattern + mutability: let + type_annotation + type: + type + name: + user_type + type_identifier "Set" + type_arguments + type + name: + user_type + type_identifier "Int" + +--- + +top_level + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "[1, 2, 3]" + pattern: + var_pattern + identifier: identifier "s" + +=== +Tuple literal +=== + +let t = (1, "two", 3.0) + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "t" + value: + tuple_expression + value: + integer_literal "1" + line_string_literal + text: line_str_text "two" + real_literal "3.0" + value_binding_pattern + mutability: let + +--- + +top_level + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "(1, \"two\", 3.0)" + pattern: + var_pattern + identifier: identifier "t" + +=== +Subscript access +=== + +// TODO: tree-sitter-swift parses `xs[0]` as a call_expression (same shape +// as `xs(0)`), so the mapping currently produces a call_expr. Update the +// parser / add a separate subscript_expr node and remap when fixed. +let first = xs[0] + +--- + +source_file + comment "// TODO: tree-sitter-swift parses `xs[0]` as a call_expression (same shape" + comment "// as `xs(0)`), so the mapping currently produces a call_expr. Update the" + comment "// parser / add a separate subscript_expr node and remap when fixed." + property_declaration + name: + pattern + bound_identifier: simple_identifier "first" + value: + call_expression + simple_identifier "xs" + call_suffix + value_arguments + value_argument + value: integer_literal "0" + value_binding_pattern + mutability: let + +--- + +top_level + body: + unsupported_node "// TODO: tree-sitter-swift parses `xs[0]` as a call_expression (same shape" + unsupported_node "// as `xs(0)`), so the mapping currently produces a call_expr. Update the" + unsupported_node "// parser / add a separate subscript_expr node and remap when fixed." + variable_declaration_stmt + variable_declarator: + variable_declarator + value: + call_expr + argument: int_literal "0" + function: + name_expr + identifier: identifier "xs" + pattern: + var_pattern + identifier: identifier "first" + +=== +Dictionary subscript +=== + +// TODO: same parser issue as the array subscript case above — +// `d["key"]` is parsed as `call_expression(d, ("key"))`. +let v = d["key"] + +--- + +source_file + comment "// TODO: same parser issue as the array subscript case above —" + comment "// `d[\"key\"]` is parsed as `call_expression(d, (\"key\"))`." + property_declaration + name: + pattern + bound_identifier: simple_identifier "v" + value: + call_expression + simple_identifier "d" + call_suffix + value_arguments + value_argument + value: + line_string_literal + text: line_str_text "key" + value_binding_pattern + mutability: let + +--- + +top_level + body: + unsupported_node "// TODO: same parser issue as the array subscript case above —" + unsupported_node "// `d[\"key\"]` is parsed as `call_expression(d, (\"key\"))`." + variable_declaration_stmt + variable_declarator: + variable_declarator + value: + call_expr + argument: string_literal "\"key\"" + function: + name_expr + identifier: identifier "d" + pattern: + var_pattern + identifier: identifier "v" + +=== +Tuple member access +=== + +let n = t.0 + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "n" + value: + navigation_expression + suffix: + navigation_suffix + suffix: integer_literal "0" + target: simple_identifier "t" + value_binding_pattern + mutability: let + +--- + +top_level + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "t.0" + pattern: + var_pattern + identifier: identifier "n" diff --git a/unified/extractor/tests/corpus/swift/control-flow.txt b/unified/extractor/tests/corpus/swift/control-flow.txt new file mode 100644 index 000000000000..f8526183d4d9 --- /dev/null +++ b/unified/extractor/tests/corpus/swift/control-flow.txt @@ -0,0 +1,448 @@ +=== +If statement +=== + +if x > 0 { + print(x) +} + +--- + +source_file + if_statement + condition: + if_condition + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "0" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: simple_identifier "x" + +--- + +top_level + body: + if_stmt + condition: + expr_condition + expr: unsupported_node "x > 0" + then: + block_stmt + body: + expr_stmt + expr: + call_expr + argument: + name_expr + identifier: identifier "x" + function: + name_expr + identifier: identifier "print" + +=== +If-else +=== + +if x > 0 { + print(x) +} else { + print(-x) +} + +--- + +source_file + if_statement + condition: + if_condition + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "0" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: simple_identifier "x" + else "else" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: + prefix_expression + operation: - + target: simple_identifier "x" + +--- + +top_level + body: + if_stmt + condition: + expr_condition + expr: unsupported_node "x > 0" + else: + block_stmt + body: + expr_stmt + expr: + call_expr + argument: + unary_expr + operator: operator "-" + operand: + name_expr + identifier: identifier "x" + function: + name_expr + identifier: identifier "print" + then: + block_stmt + body: + expr_stmt + expr: + call_expr + argument: + name_expr + identifier: identifier "x" + function: + name_expr + identifier: identifier "print" + +=== +If-else-if chain +=== + +if x > 0 { + print(1) +} else if x < 0 { + print(2) +} else { + print(3) +} + +--- + +source_file + if_statement + condition: + if_condition + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "0" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: integer_literal "1" + else "else" + if_statement + condition: + if_condition + comparison_expression + lhs: simple_identifier "x" + op: < + rhs: integer_literal "0" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: integer_literal "2" + else "else" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: integer_literal "3" + +--- + +top_level + body: + if_stmt + condition: + expr_condition + expr: unsupported_node "x > 0" + else: + if_stmt + condition: + expr_condition + expr: unsupported_node "x < 0" + else: + block_stmt + body: + expr_stmt + expr: + call_expr + argument: int_literal "3" + function: + name_expr + identifier: identifier "print" + then: + block_stmt + body: + expr_stmt + expr: + call_expr + argument: int_literal "2" + function: + name_expr + identifier: identifier "print" + then: + block_stmt + body: + expr_stmt + expr: + call_expr + argument: int_literal "1" + function: + name_expr + identifier: identifier "print" + +=== +If-let optional binding +=== + +if let value = optional { + print(value) +} + +--- + +source_file + if_statement + condition: + if_condition + if_let_binding + bound_identifier: simple_identifier "value" + value_binding_pattern + mutability: let + simple_identifier "optional" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: simple_identifier "value" + +--- + +top_level + body: + if_stmt + condition: + expr_condition + expr: unsupported_node "let value = optional" + then: + block_stmt + body: + expr_stmt + expr: + call_expr + argument: + name_expr + identifier: identifier "value" + function: + name_expr + identifier: identifier "print" + +=== +Guard let +=== + +guard let value = optional else { return } + +--- + +source_file + guard_statement + condition: + if_condition + if_let_binding + bound_identifier: simple_identifier "value" + value_binding_pattern + mutability: let + simple_identifier "optional" + else "else" + statements + control_transfer_statement + +--- + +top_level + body: unsupported_node "guard let value = optional else { return }" + +=== +Ternary expression +=== + +let y = x > 0 ? 1 : -1 + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "y" + value: + ternary_expression + condition: + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "0" + if_false: + prefix_expression + operation: - + target: integer_literal "1" + if_true: integer_literal "1" + value_binding_pattern + mutability: let + +--- + +top_level + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "x > 0 ? 1 : -1" + pattern: + var_pattern + identifier: identifier "y" + +=== +Switch statement +=== + +switch x { +case 1: + print("one") +case 2, 3: + print("two or three") +default: + print("other") +} + +--- + +source_file + switch_statement + expr: simple_identifier "x" + switch_entry + switch_pattern + pattern + integer_literal "1" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: + line_string_literal + text: line_str_text "one" + switch_entry + switch_pattern + pattern + integer_literal "2" + switch_pattern + pattern + integer_literal "3" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: + line_string_literal + text: line_str_text "two or three" + switch_entry + default_keyword "default" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: + line_string_literal + text: line_str_text "other" + +--- + +top_level + body: unsupported_node "switch x {\ncase 1:\n print(\"one\")\ncase 2, 3:\n print(\"two or three\")\ndefault:\n print(\"other\")\n}" + +=== +Switch with binding pattern +=== + +switch shape { +case .circle(let r): + print(r) +case .square(let s): + print(s) +} + +--- + +source_file + switch_statement + expr: simple_identifier "shape" + switch_entry + switch_pattern + pattern + simple_identifier "circle" + pattern + bound_identifier: simple_identifier "r" + value_binding_pattern + mutability: let + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: simple_identifier "r" + switch_entry + switch_pattern + pattern + simple_identifier "square" + pattern + bound_identifier: simple_identifier "s" + value_binding_pattern + mutability: let + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: simple_identifier "s" + +--- + +top_level + body: unsupported_node "switch shape {\ncase .circle(let r):\n print(r)\ncase .square(let s):\n print(s)\n}" diff --git a/unified/extractor/tests/corpus/swift/desugar.txt b/unified/extractor/tests/corpus/swift/desugar.txt new file mode 100644 index 000000000000..4e0defef0226 --- /dev/null +++ b/unified/extractor/tests/corpus/swift/desugar.txt @@ -0,0 +1,49 @@ +=== +Additive expression is desugared +=== + +1 + 2 + +--- + +source_file + additive_expression + lhs: integer_literal "1" + op: + + rhs: integer_literal "2" + +--- + +top_level + body: + binary_expr + operator: operator "+" + left: int_literal "1" + right: int_literal "2" + +=== +Another additive expression is desugared +=== + +foo + bar + +--- + +source_file + additive_expression + lhs: simple_identifier "foo" + op: + + rhs: simple_identifier "bar" + +--- + +top_level + body: + binary_expr + operator: operator "+" + left: + name_expr + identifier: identifier "foo" + right: + name_expr + identifier: identifier "bar" diff --git a/unified/extractor/tests/corpus/swift/functions.txt b/unified/extractor/tests/corpus/swift/functions.txt new file mode 100644 index 000000000000..3329a6255f35 --- /dev/null +++ b/unified/extractor/tests/corpus/swift/functions.txt @@ -0,0 +1,336 @@ +=== +Function with no parameters +=== + +func greet() { + print("hello") +} + +--- + +source_file + function_declaration + body: + function_body + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: + line_string_literal + text: line_str_text "hello" + name: simple_identifier "greet" + +--- + +top_level + body: unsupported_node "func greet() {\n print(\"hello\")\n}" + +=== +Function with parameters and return type +=== + +func add(_ a: Int, _ b: Int) -> Int { + return a + b +} + +--- + +source_file + function_declaration + body: + function_body + statements + control_transfer_statement + result: + additive_expression + lhs: simple_identifier "a" + op: + + rhs: simple_identifier "b" + name: simple_identifier "add" + return_type: + type + name: + user_type + type_identifier "Int" + parameter + external_name: simple_identifier "_" + name: simple_identifier "a" + type: + type + name: + user_type + type_identifier "Int" + parameter + external_name: simple_identifier "_" + name: simple_identifier "b" + type: + type + name: + user_type + type_identifier "Int" + +--- + +top_level + body: unsupported_node "func add(_ a: Int, _ b: Int) -> Int {\n return a + b\n}" + +=== +Function with named parameters +=== + +func greet(person name: String) { + print(name) +} + +--- + +source_file + function_declaration + body: + function_body + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: simple_identifier "name" + name: simple_identifier "greet" + parameter + external_name: simple_identifier "person" + name: simple_identifier "name" + type: + type + name: + user_type + type_identifier "String" + +--- + +top_level + body: unsupported_node "func greet(person name: String) {\n print(name)\n}" + +=== +Function with default parameter value +=== + +func greet(name: String = "world") { + print(name) +} + +--- + +source_file + function_declaration + body: + function_body + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: simple_identifier "name" + default_value: + line_string_literal + text: line_str_text "world" + name: simple_identifier "greet" + parameter + name: simple_identifier "name" + type: + type + name: + user_type + type_identifier "String" + +--- + +top_level + body: unsupported_node "func greet(name: String = \"world\") {\n print(name)\n}" + +=== +Variadic function +=== + +func sum(_ values: Int...) -> Int { + return values.reduce(0, +) +} + +--- + +source_file + function_declaration + body: + function_body + statements + control_transfer_statement + result: + call_expression + navigation_expression + suffix: + navigation_suffix + suffix: simple_identifier "reduce" + target: simple_identifier "values" + call_suffix + value_arguments + value_argument + value: integer_literal "0" + value_argument + value: + referenceable_operator + name: simple_identifier "sum" + return_type: + type + name: + user_type + type_identifier "Int" + parameter + external_name: simple_identifier "_" + name: simple_identifier "values" + type: + type + name: + user_type + type_identifier "Int" + +--- + +top_level + body: unsupported_node "func sum(_ values: Int...) -> Int {\n return values.reduce(0, +)\n}" + +=== +Function call +=== + +foo(1, 2) + +--- + +source_file + call_expression + simple_identifier "foo" + call_suffix + value_arguments + value_argument + value: integer_literal "1" + value_argument + value: integer_literal "2" + +--- + +top_level + body: + call_expr + argument: + int_literal "1" + int_literal "2" + function: + name_expr + identifier: identifier "foo" + +=== +Function call with labelled arguments +=== + +greet(person: "Bob") + +--- + +source_file + call_expression + simple_identifier "greet" + call_suffix + value_arguments + value_argument + name: + value_argument_label + simple_identifier "person" + value: + line_string_literal + text: line_str_text "Bob" + +--- + +top_level + body: + call_expr + argument: string_literal "\"Bob\"" + function: + name_expr + identifier: identifier "greet" + +=== +Method call +=== + +list.append(1) + +--- + +source_file + call_expression + navigation_expression + suffix: + navigation_suffix + suffix: simple_identifier "append" + target: simple_identifier "list" + call_suffix + value_arguments + value_argument + value: integer_literal "1" + +--- + +top_level + body: + call_expr + argument: int_literal "1" + function: + member_access_expr + target: + name_expr + identifier: identifier "list" + member: identifier "append" + +=== +Generic function +=== + +func identity(_ x: T) -> T { + return x +} + +--- + +source_file + function_declaration + body: + function_body + statements + control_transfer_statement + result: simple_identifier "x" + name: simple_identifier "identity" + return_type: + type + name: + user_type + type_identifier "T" + type_parameters + type_parameter + type_identifier "T" + parameter + external_name: simple_identifier "_" + name: simple_identifier "x" + type: + type + name: + user_type + type_identifier "T" + +--- + +top_level + body: unsupported_node "func identity(_ x: T) -> T {\n return x\n}" diff --git a/unified/extractor/tests/corpus/swift/literals.txt b/unified/extractor/tests/corpus/swift/literals.txt new file mode 100644 index 000000000000..5f44733e136e --- /dev/null +++ b/unified/extractor/tests/corpus/swift/literals.txt @@ -0,0 +1,124 @@ +=== +Integer literal +=== + +42 + +--- + +source_file + integer_literal "42" + +--- + +top_level + body: int_literal "42" + +=== +Negative integer literal +=== + +-7 + +--- + +source_file + prefix_expression + operation: - + target: integer_literal "7" + +--- + +top_level + body: + unary_expr + operator: operator "-" + operand: int_literal "7" + +=== +Floating-point literal +=== + +3.14 + +--- + +source_file + real_literal "3.14" + +--- + +top_level + body: unsupported_node "3.14" + +=== +Boolean literals +=== + +true +false + +--- + +source_file + boolean_literal + boolean_literal + +--- + +top_level + body: + unsupported_node "true" + unsupported_node "false" + +=== +Nil literal +=== + +nil + +--- + +source_file + +--- + +top_level + body: + +=== +String literal +=== + +"hello" + +--- + +source_file + line_string_literal + text: line_str_text "hello" + +--- + +top_level + body: string_literal "\"hello\"" + +=== +String with interpolation +=== + +"hello \(name)" + +--- + +source_file + line_string_literal + interpolation: + interpolated_expression + value: simple_identifier "name" + text: line_str_text "hello " + +--- + +top_level + body: string_literal "\"hello \\(name)\"" diff --git a/unified/extractor/tests/corpus/swift/loops.txt b/unified/extractor/tests/corpus/swift/loops.txt new file mode 100644 index 000000000000..62d0d097bb02 --- /dev/null +++ b/unified/extractor/tests/corpus/swift/loops.txt @@ -0,0 +1,212 @@ +=== +For-in over array literal +=== + +for x in [1, 2, 3] { + print(x) +} + +--- + +source_file + for_statement + collection: + array_literal + element: + integer_literal "1" + integer_literal "2" + integer_literal "3" + item: + pattern + bound_identifier: simple_identifier "x" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: simple_identifier "x" + +--- + +top_level + body: unsupported_node "for x in [1, 2, 3] {\n print(x)\n}" + +=== +For-in over range +=== + +for i in 0..<10 { + print(i) +} + +--- + +source_file + for_statement + collection: + range_expression + end: integer_literal "10" + op: ..< + start: integer_literal "0" + item: + pattern + bound_identifier: simple_identifier "i" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: simple_identifier "i" + +--- + +top_level + body: unsupported_node "for i in 0..<10 {\n print(i)\n}" + +=== +For-in with where clause +=== + +for x in xs where x > 0 { + print(x) +} + +--- + +source_file + for_statement + collection: simple_identifier "xs" + item: + pattern + bound_identifier: simple_identifier "x" + where_clause + where_keyword "where" + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "0" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: simple_identifier "x" + +--- + +top_level + body: unsupported_node "for x in xs where x > 0 {\n print(x)\n}" + +=== +While loop +=== + +while x > 0 { + x -= 1 +} + +--- + +source_file + while_statement + condition: + if_condition + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "0" + statements + assignment + operator: -= + result: integer_literal "1" + target: + directly_assignable_expression + simple_identifier "x" + +--- + +top_level + body: unsupported_node "while x > 0 {\n x -= 1\n}" + +=== +Repeat-while loop +=== + +repeat { + x -= 1 +} while x > 0 + +--- + +source_file + repeat_while_statement + condition: + if_condition + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "0" + statements + assignment + operator: -= + result: integer_literal "1" + target: + directly_assignable_expression + simple_identifier "x" + +--- + +top_level + body: unsupported_node "repeat {\n x -= 1\n} while x > 0" + +=== +Break and continue +=== + +for x in xs { + if x < 0 { continue } + if x > 100 { break } + print(x) +} + +--- + +source_file + for_statement + collection: simple_identifier "xs" + item: + pattern + bound_identifier: simple_identifier "x" + statements + if_statement + condition: + if_condition + comparison_expression + lhs: simple_identifier "x" + op: < + rhs: integer_literal "0" + statements + control_transfer_statement + if_statement + condition: + if_condition + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "100" + statements + control_transfer_statement + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: simple_identifier "x" + +--- + +top_level + body: unsupported_node "for x in xs {\n if x < 0 { continue }\n if x > 100 { break }\n print(x)\n}" diff --git a/unified/extractor/tests/corpus/swift/operators.txt b/unified/extractor/tests/corpus/swift/operators.txt new file mode 100644 index 000000000000..173f6e929769 --- /dev/null +++ b/unified/extractor/tests/corpus/swift/operators.txt @@ -0,0 +1,329 @@ +=== +Addition +=== + +a + b + +--- + +source_file + additive_expression + lhs: simple_identifier "a" + op: + + rhs: simple_identifier "b" + +--- + +top_level + body: + binary_expr + operator: operator "+" + left: + name_expr + identifier: identifier "a" + right: + name_expr + identifier: identifier "b" + +=== +Subtraction +=== + +a - b + +--- + +source_file + additive_expression + lhs: simple_identifier "a" + op: - + rhs: simple_identifier "b" + +--- + +top_level + body: + binary_expr + operator: operator "-" + left: + name_expr + identifier: identifier "a" + right: + name_expr + identifier: identifier "b" + +=== +Multiplication +=== + +a * b + +--- + +source_file + multiplicative_expression + lhs: simple_identifier "a" + op: * + rhs: simple_identifier "b" + +--- + +top_level + body: + binary_expr + operator: operator "*" + left: + name_expr + identifier: identifier "a" + right: + name_expr + identifier: identifier "b" + +=== +Division +=== + +a / b + +--- + +source_file + multiplicative_expression + lhs: simple_identifier "a" + op: / + rhs: simple_identifier "b" + +--- + +top_level + body: + binary_expr + operator: operator "/" + left: + name_expr + identifier: identifier "a" + right: + name_expr + identifier: identifier "b" + +=== +Operator precedence: addition and multiplication +=== + +a + b * c + +--- + +source_file + additive_expression + lhs: simple_identifier "a" + op: + + rhs: + multiplicative_expression + lhs: simple_identifier "b" + op: * + rhs: simple_identifier "c" + +--- + +top_level + body: + binary_expr + operator: operator "+" + left: + name_expr + identifier: identifier "a" + right: + binary_expr + operator: operator "*" + left: + name_expr + identifier: identifier "b" + right: + name_expr + identifier: identifier "c" + +=== +Parenthesised expression +=== + +(a + b) * c + +--- + +source_file + multiplicative_expression + lhs: + tuple_expression + value: + additive_expression + lhs: simple_identifier "a" + op: + + rhs: simple_identifier "b" + op: * + rhs: simple_identifier "c" + +--- + +top_level + body: + binary_expr + operator: operator "*" + left: unsupported_node "(a + b)" + right: + name_expr + identifier: identifier "c" + +=== +Comparison +=== + +a < b + +--- + +source_file + comparison_expression + lhs: simple_identifier "a" + op: < + rhs: simple_identifier "b" + +--- + +top_level + body: + binary_expr + operator: operator "<" + left: + name_expr + identifier: identifier "a" + right: + name_expr + identifier: identifier "b" + +=== +Equality +=== + +a == b + +--- + +source_file + equality_expression + lhs: simple_identifier "a" + op: == + rhs: simple_identifier "b" + +--- + +top_level + body: + binary_expr + operator: operator "==" + left: + name_expr + identifier: identifier "a" + right: + name_expr + identifier: identifier "b" + +=== +Logical and +=== + +a && b + +--- + +source_file + conjunction_expression + lhs: simple_identifier "a" + op: && + rhs: simple_identifier "b" + +--- + +top_level + body: + binary_expr + operator: operator "&&" + left: + name_expr + identifier: identifier "a" + right: + name_expr + identifier: identifier "b" + +=== +Logical or +=== + +a || b + +--- + +source_file + disjunction_expression + lhs: simple_identifier "a" + op: || + rhs: simple_identifier "b" + +--- + +top_level + body: + binary_expr + operator: operator "||" + left: + name_expr + identifier: identifier "a" + right: + name_expr + identifier: identifier "b" + +=== +Logical not +=== + +!a + +--- + +source_file + prefix_expression + operation: bang "!" + target: simple_identifier "a" + +--- + +top_level + body: + unary_expr + operator: operator "!" + operand: + name_expr + identifier: identifier "a" + +=== +Range operator +=== + +1...10 + +--- + +source_file + range_expression + end: integer_literal "10" + op: ... + start: integer_literal "1" + +--- + +top_level + body: + binary_expr + operator: operator "..." + left: int_literal "1" + right: int_literal "10" diff --git a/unified/extractor/tests/corpus/swift/optionals-and-errors.txt b/unified/extractor/tests/corpus/swift/optionals-and-errors.txt new file mode 100644 index 000000000000..c4f9118eedca --- /dev/null +++ b/unified/extractor/tests/corpus/swift/optionals-and-errors.txt @@ -0,0 +1,284 @@ +=== +Optional type annotation +=== + +let x: Int? = nil + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "x" + value: nil + value_binding_pattern + mutability: let + type_annotation + type: + type + name: + optional_type + wrapped: + user_type + type_identifier "Int" + +--- + +top_level + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + pattern: + var_pattern + identifier: identifier "x" + +=== +Optional chaining +=== + +let n = obj?.foo?.bar + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "n" + value: + navigation_expression + suffix: + navigation_suffix + suffix: simple_identifier "bar" + target: + optional_chain_marker + navigation_expression + suffix: + navigation_suffix + suffix: simple_identifier "foo" + target: + optional_chain_marker + simple_identifier "obj" + value_binding_pattern + mutability: let + +--- + +top_level + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: + member_access_expr + target: unsupported_node "obj?.foo?" + member: identifier "bar" + pattern: + var_pattern + identifier: identifier "n" + +=== +Force unwrap +=== + +let n = opt! + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "n" + value: + postfix_expression + operation: bang "!" + target: simple_identifier "opt" + value_binding_pattern + mutability: let + +--- + +top_level + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "opt!" + pattern: + var_pattern + identifier: identifier "n" + +=== +Nil-coalescing +=== + +let n = opt ?? 0 + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "n" + value: + nil_coalescing_expression + if_nil: integer_literal "0" + value: simple_identifier "opt" + value_binding_pattern + mutability: let + +--- + +top_level + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "opt ?? 0" + pattern: + var_pattern + identifier: identifier "n" + +=== +Throwing function +=== + +func read() throws -> String { + return "" +} + +--- + +source_file + function_declaration + body: + function_body + statements + control_transfer_statement + result: + line_string_literal + name: simple_identifier "read" + return_type: + type + name: + user_type + type_identifier "String" + throws "throws" + +--- + +top_level + body: unsupported_node "func read() throws -> String {\n return \"\"\n}" + +=== +Do-catch +=== + +do { + try foo() +} catch { + print(error) +} + +--- + +source_file + do_statement + statements + try_expression + expr: + call_expression + simple_identifier "foo" + call_suffix + value_arguments + try_operator + catch_block + catch_keyword "catch" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: simple_identifier "error" + +--- + +top_level + body: unsupported_node "do {\n try foo()\n} catch {\n print(error)\n}" + +=== +Try? expression +=== + +let result = try? foo() + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "result" + value: + try_expression + expr: + call_expression + simple_identifier "foo" + call_suffix + value_arguments + try_operator + value_binding_pattern + mutability: let + +--- + +top_level + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "try? foo()" + pattern: + var_pattern + identifier: identifier "result" + +=== +Try! expression +=== + +let result = try! foo() + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "result" + value: + try_expression + expr: + call_expression + simple_identifier "foo" + call_suffix + value_arguments + try_operator + value_binding_pattern + mutability: let + +--- + +top_level + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "try! foo()" + pattern: + var_pattern + identifier: identifier "result" diff --git a/unified/extractor/tests/corpus/swift/types.txt b/unified/extractor/tests/corpus/swift/types.txt new file mode 100644 index 000000000000..873749aa6ce6 --- /dev/null +++ b/unified/extractor/tests/corpus/swift/types.txt @@ -0,0 +1,514 @@ +=== +Empty class +=== + +class Foo {} + +--- + +source_file + class_declaration + body: + class_body + declaration_kind: class + name: type_identifier "Foo" + +--- + +top_level + body: unsupported_node "class Foo {}" + +=== +Class with stored properties +=== + +class Point { + var x: Int + var y: Int +} + +--- + +source_file + class_declaration + body: + class_body + property_declaration + name: + pattern + bound_identifier: simple_identifier "x" + value_binding_pattern + mutability: var + type_annotation + type: + type + name: + user_type + type_identifier "Int" + property_declaration + name: + pattern + bound_identifier: simple_identifier "y" + value_binding_pattern + mutability: var + type_annotation + type: + type + name: + user_type + type_identifier "Int" + declaration_kind: class + name: type_identifier "Point" + +--- + +top_level + body: unsupported_node "class Point {\n var x: Int\n var y: Int\n}" + +=== +Class with initializer +=== + +class Point { + var x: Int + init(x: Int) { + self.x = x + } +} + +--- + +source_file + class_declaration + body: + class_body + property_declaration + name: + pattern + bound_identifier: simple_identifier "x" + value_binding_pattern + mutability: var + type_annotation + type: + type + name: + user_type + type_identifier "Int" + init_declaration + body: + function_body + statements + assignment + operator: = + result: simple_identifier "x" + target: + directly_assignable_expression + navigation_expression + suffix: + navigation_suffix + suffix: simple_identifier "x" + target: + self_expression + name: init + parameter + name: simple_identifier "x" + type: + type + name: + user_type + type_identifier "Int" + declaration_kind: class + name: type_identifier "Point" + +--- + +top_level + body: unsupported_node "class Point {\n var x: Int\n init(x: Int) {\n self.x = x\n }\n}" + +=== +Class with method +=== + +class Counter { + var n = 0 + func bump() { + n += 1 + } +} + +--- + +source_file + class_declaration + body: + class_body + property_declaration + name: + pattern + bound_identifier: simple_identifier "n" + value: integer_literal "0" + value_binding_pattern + mutability: var + function_declaration + body: + function_body + statements + assignment + operator: += + result: integer_literal "1" + target: + directly_assignable_expression + simple_identifier "n" + name: simple_identifier "bump" + declaration_kind: class + name: type_identifier "Counter" + +--- + +top_level + body: unsupported_node "class Counter {\n var n = 0\n func bump() {\n n += 1\n }\n}" + +=== +Class inheritance +=== + +class Dog: Animal {} + +--- + +source_file + class_declaration + body: + class_body + declaration_kind: class + name: type_identifier "Dog" + inheritance_specifier + inherits_from: + user_type + type_identifier "Animal" + +--- + +top_level + body: unsupported_node "class Dog: Animal {}" + +=== +Struct +=== + +struct Point { + let x: Int + let y: Int +} + +--- + +source_file + class_declaration + body: + class_body + property_declaration + name: + pattern + bound_identifier: simple_identifier "x" + value_binding_pattern + mutability: let + type_annotation + type: + type + name: + user_type + type_identifier "Int" + property_declaration + name: + pattern + bound_identifier: simple_identifier "y" + value_binding_pattern + mutability: let + type_annotation + type: + type + name: + user_type + type_identifier "Int" + declaration_kind: struct + name: type_identifier "Point" + +--- + +top_level + body: unsupported_node "struct Point {\n let x: Int\n let y: Int\n}" + +=== +Enum with cases +=== + +enum Direction { + case north + case south + case east + case west +} + +--- + +source_file + class_declaration + body: + enum_class_body + enum_entry + name: simple_identifier "north" + enum_entry + name: simple_identifier "south" + enum_entry + name: simple_identifier "east" + enum_entry + name: simple_identifier "west" + declaration_kind: enum + name: type_identifier "Direction" + +--- + +top_level + body: unsupported_node "enum Direction {\n case north\n case south\n case east\n case west\n}" + +=== +Enum with associated values +=== + +enum Shape { + case circle(radius: Double) + case square(side: Double) +} + +--- + +source_file + class_declaration + body: + enum_class_body + enum_entry + data_contents: + enum_type_parameters + simple_identifier "radius" + type + name: + user_type + type_identifier "Double" + name: simple_identifier "circle" + enum_entry + data_contents: + enum_type_parameters + simple_identifier "side" + type + name: + user_type + type_identifier "Double" + name: simple_identifier "square" + declaration_kind: enum + name: type_identifier "Shape" + +--- + +top_level + body: unsupported_node "enum Shape {\n case circle(radius: Double)\n case square(side: Double)\n}" + +=== +Protocol declaration +=== + +protocol Drawable { + func draw() +} + +--- + +source_file + protocol_declaration + body: + protocol_body + protocol_function_declaration + name: simple_identifier "draw" + declaration_kind: protocol + name: type_identifier "Drawable" + +--- + +top_level + body: unsupported_node "protocol Drawable {\n func draw()\n}" + +=== +Extension +=== + +extension Int { + func squared() -> Int { return self * self } +} + +--- + +source_file + class_declaration + body: + class_body + function_declaration + body: + function_body + statements + control_transfer_statement + result: + multiplicative_expression + lhs: + self_expression + op: * + rhs: + self_expression + name: simple_identifier "squared" + return_type: + type + name: + user_type + type_identifier "Int" + declaration_kind: extension + name: + user_type + type_identifier "Int" + +--- + +top_level + body: unsupported_node "extension Int {\n func squared() -> Int { return self * self }\n}" + +=== +Computed property +=== + +class Rect { + var w: Double + var h: Double + var area: Double { + return w * h + } +} + +--- + +source_file + class_declaration + body: + class_body + property_declaration + name: + pattern + bound_identifier: simple_identifier "w" + value_binding_pattern + mutability: var + type_annotation + type: + type + name: + user_type + type_identifier "Double" + property_declaration + name: + pattern + bound_identifier: simple_identifier "h" + value_binding_pattern + mutability: var + type_annotation + type: + type + name: + user_type + type_identifier "Double" + property_declaration + computed_value: + computed_property + statements + control_transfer_statement + result: + multiplicative_expression + lhs: simple_identifier "w" + op: * + rhs: simple_identifier "h" + name: + pattern + bound_identifier: simple_identifier "area" + value_binding_pattern + mutability: var + type_annotation + type: + type + name: + user_type + type_identifier "Double" + declaration_kind: class + name: type_identifier "Rect" + +--- + +top_level + body: unsupported_node "class Rect {\n var w: Double\n var h: Double\n var area: Double {\n return w * h\n }\n}" + +=== +Property with getter and setter +=== + +class Box { + private var _v = 0 + var v: Int { + get { return _v } + set { _v = newValue } + } +} + +--- + +source_file + class_declaration + body: + class_body + property_declaration + name: + pattern + bound_identifier: simple_identifier "_v" + value: integer_literal "0" + modifiers + visibility_modifier + value_binding_pattern + mutability: var + property_declaration + computed_value: + computed_property + computed_getter + getter_specifier + statements + control_transfer_statement + result: simple_identifier "_v" + computed_setter + setter_specifier + statements + assignment + operator: = + result: simple_identifier "newValue" + target: + directly_assignable_expression + simple_identifier "_v" + name: + pattern + bound_identifier: simple_identifier "v" + value_binding_pattern + mutability: var + type_annotation + type: + type + name: + user_type + type_identifier "Int" + declaration_kind: class + name: type_identifier "Box" + +--- + +top_level + body: unsupported_node "class Box {\n private var _v = 0\n var v: Int {\n get { return _v }\n set { _v = newValue }\n }\n}" diff --git a/unified/extractor/tests/corpus/swift/variables.txt b/unified/extractor/tests/corpus/swift/variables.txt new file mode 100644 index 000000000000..3fe7686a8c31 --- /dev/null +++ b/unified/extractor/tests/corpus/swift/variables.txt @@ -0,0 +1,243 @@ +=== +Let binding +=== + +let x = 1 + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "x" + value: integer_literal "1" + value_binding_pattern + mutability: let + +--- + +top_level + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: int_literal "1" + pattern: + var_pattern + identifier: identifier "x" + +=== +Var binding +=== + +var x = 1 + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "x" + value: integer_literal "1" + value_binding_pattern + mutability: var + +--- + +top_level + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: int_literal "1" + pattern: + var_pattern + identifier: identifier "x" + +=== +Let with type annotation +=== + +let x: Int = 1 + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "x" + value: integer_literal "1" + value_binding_pattern + mutability: let + type_annotation + type: + type + name: + user_type + type_identifier "Int" + +--- + +top_level + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: int_literal "1" + pattern: + var_pattern + identifier: identifier "x" + +=== +Var without initialiser +=== + +var x: Int + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "x" + value_binding_pattern + mutability: var + type_annotation + type: + type + name: + user_type + type_identifier "Int" + +--- + +top_level + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + pattern: + var_pattern + identifier: identifier "x" + +=== +Tuple destructuring binding +=== + +let (a, b) = pair + +--- + +source_file + property_declaration + name: + pattern + pattern + simple_identifier "a" + pattern + simple_identifier "b" + value: simple_identifier "pair" + value_binding_pattern + mutability: let + +--- + +top_level + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: + name_expr + identifier: identifier "pair" + pattern: + tuple_pattern + element: + var_pattern + identifier: identifier "a" + var_pattern + identifier: identifier "b" + +=== +Multiple bindings on one line +=== + +let x = 1, y = 2 + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "x" + pattern + bound_identifier: simple_identifier "y" + value: + integer_literal "1" + integer_literal "2" + value_binding_pattern + mutability: let + +--- + +top_level + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: int_literal "1" + pattern: + var_pattern + identifier: identifier "x" + variable_declarator + value: int_literal "2" + pattern: + var_pattern + identifier: identifier "y" + +=== +Assignment +=== + +x = 1 + +--- + +source_file + assignment + operator: = + result: integer_literal "1" + target: + directly_assignable_expression + simple_identifier "x" + +--- + +top_level + body: unsupported_node "x = 1" + +=== +Compound assignment +=== + +x += 1 + +--- + +source_file + assignment + operator: += + result: integer_literal "1" + target: + directly_assignable_expression + simple_identifier "x" + +--- + +top_level + body: unsupported_node "x += 1" diff --git a/unified/extractor/tests/corpus_tests.rs b/unified/extractor/tests/corpus_tests.rs new file mode 100644 index 000000000000..ac93dd586ec1 --- /dev/null +++ b/unified/extractor/tests/corpus_tests.rs @@ -0,0 +1,283 @@ +use std::fs; +use std::path::Path; + +use codeql_extractor::extractor::simple; +use yeast::{dump::dump_ast, dump::dump_ast_with_type_errors, Runner}; + +#[path = "../src/languages/mod.rs"] +mod languages; + +#[derive(Debug)] +struct CorpusCase { + name: String, + input: String, + raw: String, + expected: String, +} + +fn update_mode_enabled() -> bool { + std::env::var("UNIFIED_UPDATE_CORPUS") + .map(|v| matches!(v.to_ascii_lowercase().as_str(), "1" | "true" | "yes" | "on")) + .unwrap_or(false) +} + +fn is_header_rule(line: &str) -> bool { + let trimmed = line.trim(); + trimmed.len() >= 3 && trimmed.chars().all(|c| c == '=') +} + +fn parse_corpus(content: &str) -> Vec { + let lines: Vec<&str> = content.lines().collect(); + let mut i = 0; + let mut cases = Vec::new(); + + while i < lines.len() { + while i < lines.len() && lines[i].trim().is_empty() { + i += 1; + } + if i >= lines.len() { + break; + } + + assert!( + is_header_rule(lines[i]), + "Expected header delimiter at line {}", + i + 1 + ); + i += 1; + + assert!(i < lines.len(), "Missing test name at line {}", i + 1); + let name = lines[i].trim().to_string(); + i += 1; + + assert!( + i < lines.len() && is_header_rule(lines[i]), + "Missing closing header delimiter for case {name}" + ); + i += 1; + + let input_start = i; + while i < lines.len() && lines[i].trim() != "---" { + i += 1; + } + assert!(i < lines.len(), "Missing --- separator for case {name}"); + let input = lines[input_start..i].join("\n").trim_end().to_string(); + i += 1; + + // Raw tree-sitter parse section. New-format files have a second + // `---` separator between the raw tree and the mapped AST. Legacy + // files (with only one separator) have no raw section — in that + // case `raw` stays empty and update mode will populate it. + let raw_start = i; + let mut next_sep = i; + while next_sep < lines.len() && lines[next_sep].trim() != "---" { + if is_header_rule(lines[next_sep]) + && next_sep + 2 < lines.len() + && !lines[next_sep + 1].trim().is_empty() + && is_header_rule(lines[next_sep + 2]) + { + break; + } + next_sep += 1; + } + let raw = if next_sep < lines.len() && lines[next_sep].trim() == "---" { + let raw_text = lines[raw_start..next_sep].join("\n").trim().to_string(); + i = next_sep + 1; + raw_text + } else { + String::new() + }; + + let expected_start = i; + while i < lines.len() { + if is_header_rule(lines[i]) + && i + 2 < lines.len() + && !lines[i + 1].trim().is_empty() + && is_header_rule(lines[i + 2]) + { + break; + } + i += 1; + } + let expected = lines[expected_start..i].join("\n").trim().to_string(); + + cases.push(CorpusCase { + name, + input, + raw, + expected, + }); + } + + cases +} + +fn render_corpus(cases: &[CorpusCase]) -> String { + let mut out = String::new(); + + for (idx, case) in cases.iter().enumerate() { + if idx > 0 { + // Blank line between cases. + out.push('\n'); + } + out.push_str("===\n"); + out.push_str(case.name.trim()); + out.push_str("\n===\n\n"); + out.push_str(case.input.trim()); + out.push_str("\n\n---\n\n"); + out.push_str(case.raw.trim()); + out.push_str("\n\n---\n\n"); + out.push_str(case.expected.trim()); + // Single trailing newline per case; the inter-case blank line is + // added by the prefix above, and the file ends with exactly one `\n`. + out.push('\n'); + } + + out +} + +fn run_desugaring( + lang: &simple::LanguageSpec, + input: &str, +) -> Result { + let runner = match lang.desugar.as_ref() { + Some(config) => Runner::from_config(lang.ts_language.clone(), config) + .map_err(|e| format!("Failed to create yeast runner: {e}"))?, + None => Runner::new(lang.ts_language.clone(), &[]), + }; + + runner + .run(input) + .map_err(|e| format!("Failed to parse input: {e}")) +} + +/// Produce the raw tree-sitter parse tree dump for `input`, with no +/// desugaring rules applied. Uses a `Runner` with an empty phase list and +/// the input grammar's own schema. +fn dump_raw_parse( + lang: &simple::LanguageSpec, + input: &str, +) -> Result { + let runner = Runner::new(lang.ts_language.clone(), &[]); + let ast = runner + .run(input) + .map_err(|e| format!("Failed to parse input: {e}"))?; + Ok(dump_ast(&ast, ast.get_root(), input)) +} + +#[test] +fn test_corpus() { + let update_mode = update_mode_enabled(); + let all_languages = languages::all_language_specs(); + let corpus_dir = Path::new("tests/corpus"); + + for lang in all_languages { + let output_schema = yeast::node_types_yaml::schema_from_yaml_with_language( + languages::OUTPUT_AST_SCHEMA, + &lang.ts_language, + ) + .expect("Failed to parse OUTPUT_AST_SCHEMA YAML"); + + let lang_corpus_dir = corpus_dir.join(&lang.prefix); + if !lang_corpus_dir.exists() { + continue; + } + + let mut corpus_files: Vec<_> = fs::read_dir(&lang_corpus_dir) + .unwrap_or_else(|e| { + panic!( + "Failed to read corpus directory {}: {e}", + lang_corpus_dir.display() + ) + }) + .map(|entry| entry.expect("Failed to read corpus entry").path()) + .filter(|path| path.extension().is_some_and(|ext| ext == "txt")) + .collect(); + corpus_files.sort(); + + for corpus_path in corpus_files { + let content = fs::read_to_string(&corpus_path) + .unwrap_or_else(|e| panic!("Failed to read {}: {e}", corpus_path.display())); + let mut cases = parse_corpus(&content); + let mut failures = Vec::new(); + assert!( + !cases.is_empty(), + "No corpus cases found in {}", + corpus_path.display() + ); + + for case in &mut cases { + match dump_raw_parse(&lang, &case.input) { + Err(e) => { + failures.push(format!( + "Raw parse failed for {} in {}: {}", + case.name, + corpus_path.display(), + e + )); + } + Ok(actual_raw) => { + if update_mode { + case.raw = actual_raw.trim().to_string(); + } else if case.raw.trim() != actual_raw.trim() { + failures.push(format!( + "Raw parse mismatch in {}: \"{}\"\nEXPECTED:\n\n{}\n\nACTUAL:\n\n{}", + corpus_path.display(), + case.name, + case.raw.trim(), + actual_raw.trim() + )); + } + } + } + + match run_desugaring(&lang, &case.input) { + Err(e) => { + failures.push(format!( + "Desugaring failed for {} in {}: {}", + case.name, + corpus_path.display(), + e + )); + } + Ok(actual) => { + let actual_dump = dump_ast_with_type_errors( + &actual, + actual.get_root(), + &case.input, + &output_schema, + ); + if update_mode { + case.expected = actual_dump.trim().to_string(); + } else if case.expected.trim() != actual_dump.trim() { + failures.push(format!( + "Test failed in {}: \"{}\"\nEXPECTED:\n\n{}\n\nACTUAL:\n\n{}", + corpus_path.display(), + case.name, + case.expected.trim(), + actual_dump.trim() + )); + } + } + } + } + + assert!( + failures.is_empty(), + "{}", + failures.join("\n\n") + "\n\n" + ); + + if update_mode { + let updated = render_corpus(&cases); + let write_result = fs::write(&corpus_path, updated); + assert!( + write_result.is_ok(), + "Failed to update corpus file {}: {}", + corpus_path.display(), + write_result.err().map_or_else(String::new, |e| e.to_string()) + ); + } + } + } +} diff --git a/unified/ql/lib/codeql/unified/Ast.qll b/unified/ql/lib/codeql/unified/Ast.qll index 5b9491fdb9fe..d9060c26f0f2 100644 --- a/unified/ql/lib/codeql/unified/Ast.qll +++ b/unified/ql/lib/codeql/unified/Ast.qll @@ -1,5 +1,5 @@ /** - * CodeQL library for Swift + * CodeQL library for Unified * Automatically generated from the tree-sitter grammar; do not edit */ @@ -24,20 +24,20 @@ private predicate discardLocation(@location_default loc) { } overlay[local] -module Swift { +module Unified { /** The base class for all AST nodes */ - class AstNode extends @swift_ast_node { + class AstNode extends @unified_ast_node { /** Gets a string representation of this element. */ string toString() { result = this.getAPrimaryQlClass() } /** Gets the location of this element. */ - final L::Location getLocation() { swift_ast_node_location(this, result) } + final L::Location getLocation() { unified_ast_node_location(this, result) } /** Gets the parent of this element. */ - final AstNode getParent() { swift_ast_node_parent(this, result, _) } + final AstNode getParent() { unified_ast_node_parent(this, result, _) } /** Gets the index of this node among the children of its parent. */ - final int getParentIndex() { swift_ast_node_parent(this, _, result) } + final int getParentIndex() { unified_ast_node_parent(this, _, result) } /** Gets a field or child node of this node. */ AstNode getAFieldOrChild() { none() } @@ -50,9 +50,9 @@ module Swift { } /** A token. */ - class Token extends @swift_token, AstNode { + class Token extends @unified_token, AstNode { /** Gets the value of this token. */ - final string getValue() { swift_tokeninfo(this, _, result) } + final string getValue() { unified_tokeninfo(this, _, result) } /** Gets a string representation of this element. */ final override string toString() { result = this.getValue() } @@ -61,2766 +61,386 @@ module Swift { override string getAPrimaryQlClass() { result = "Token" } } - /** A reserved word. */ - class ReservedWord extends @swift_reserved_word, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ReservedWord" } - } - /** Gets the file containing the given `node`. */ - private @file getNodeFile(@swift_ast_node node) { - exists(@location_default loc | swift_ast_node_location(node, loc) | + private @file getNodeFile(@unified_ast_node node) { + exists(@location_default loc | unified_ast_node_location(node, loc) | locations_default(loc, result, _, _, _, _) ) } /** Holds if `node` is in the `file` and is part of the overlay base database. */ - private predicate discardableAstNode(@file file, @swift_ast_node node) { + private predicate discardableAstNode(@file file, @unified_ast_node node) { not isOverlay() and file = getNodeFile(node) } /** Holds if `node` should be discarded, because it is part of the overlay base and is in a file that was also extracted as part of the overlay database. */ overlay[discard_entity] - private predicate discardAstNode(@swift_ast_node node) { + private predicate discardAstNode(@unified_ast_node node) { exists(@file file, string path | files(file, path) | discardableAstNode(file, node) and overlayChangedFiles(path) ) } - /** A class representing `additive_expression` nodes. */ - class AdditiveExpression extends @swift_additive_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "AdditiveExpression" } - - /** Gets the node corresponding to the field `lhs`. */ - final Expression getLhs() { swift_additive_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `op`. */ - final string getOp() { - exists(int value | swift_additive_expression_def(this, _, value, _) | - result = "+" and value = 0 - or - result = "-" and value = 1 - ) - } - - /** Gets the node corresponding to the field `rhs`. */ - final Expression getRhs() { swift_additive_expression_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_additive_expression_def(this, result, _, _) or - swift_additive_expression_def(this, _, _, result) - } - } - - /** A class representing `array_literal` nodes. */ - class ArrayLiteral extends @swift_array_literal, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ArrayLiteral" } - - /** Gets the node corresponding to the field `element`. */ - final Expression getElement(int i) { swift_array_literal_element(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_array_literal_element(this, _, result) } - } - - /** A class representing `array_type` nodes. */ - class ArrayType extends @swift_array_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ArrayType" } - - /** Gets the node corresponding to the field `element`. */ - final Type getElement() { swift_array_type_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_array_type_def(this, result) } - } - - /** A class representing `as_expression` nodes. */ - class AsExpression extends @swift_as_expression, AstNode { + /** A class representing `apply_pattern` nodes. */ + class ApplyPattern extends @unified_apply_pattern, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "AsExpression" } - - /** Gets the node corresponding to the field `expr`. */ - final Expression getExpr() { swift_as_expression_def(this, result, _, _) } + final override string getAPrimaryQlClass() { result = "ApplyPattern" } - /** Gets the node corresponding to the field `type`. */ - final Type getType() { swift_as_expression_def(this, _, result, _) } + /** Gets the node corresponding to the field `argument`. */ + final Pattern getArgument(int i) { unified_apply_pattern_argument(this, i, result) } - /** Gets the child of this node. */ - final AsOperator getChild() { swift_as_expression_def(this, _, _, result) } + /** Gets the node corresponding to the field `constructor`. */ + final Expr getConstructor() { unified_apply_pattern_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_as_expression_def(this, result, _, _) or - swift_as_expression_def(this, _, result, _) or - swift_as_expression_def(this, _, _, result) + unified_apply_pattern_argument(this, _, result) or unified_apply_pattern_def(this, result) } } - /** A class representing `as_operator` tokens. */ - class AsOperator extends @swift_token_as_operator, Token { + /** A class representing `binary_expr` nodes. */ + class BinaryExpr extends @unified_binary_expr, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "AsOperator" } - } + final override string getAPrimaryQlClass() { result = "BinaryExpr" } - /** A class representing `assignment` nodes. */ - class Assignment extends @swift_assignment, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Assignment" } + /** Gets the node corresponding to the field `left`. */ + final Expr getLeft() { unified_binary_expr_def(this, result, _, _) } /** Gets the node corresponding to the field `operator`. */ - final string getOperator() { - exists(int value | swift_assignment_def(this, value, _, _) | - result = "%=" and value = 0 - or - result = "*=" and value = 1 - or - result = "+=" and value = 2 - or - result = "-=" and value = 3 - or - result = "/=" and value = 4 - or - result = "=" and value = 5 - ) - } - - /** Gets the node corresponding to the field `result`. */ - final Expression getResult() { swift_assignment_def(this, _, result, _) } + final Operator getOperator() { unified_binary_expr_def(this, _, result, _) } - /** Gets the node corresponding to the field `target`. */ - final DirectlyAssignableExpression getTarget() { swift_assignment_def(this, _, _, result) } + /** Gets the node corresponding to the field `right`. */ + final Expr getRight() { unified_binary_expr_def(this, _, _, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_assignment_def(this, _, result, _) or swift_assignment_def(this, _, _, result) + unified_binary_expr_def(this, result, _, _) or + unified_binary_expr_def(this, _, result, _) or + unified_binary_expr_def(this, _, _, result) } } - /** A class representing `associatedtype_declaration` nodes. */ - class AssociatedtypeDeclaration extends @swift_associatedtype_declaration, AstNode { + /** A class representing `block_stmt` nodes. */ + class BlockStmt extends @unified_block_stmt, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "AssociatedtypeDeclaration" } - - /** Gets the node corresponding to the field `default_value`. */ - final Type getDefaultValue() { swift_associatedtype_declaration_default_value(this, result) } - - /** Gets the node corresponding to the field `must_inherit`. */ - final Type getMustInherit() { swift_associatedtype_declaration_must_inherit(this, result) } - - /** Gets the node corresponding to the field `name`. */ - final TypeIdentifier getName() { swift_associatedtype_declaration_def(this, result) } + final override string getAPrimaryQlClass() { result = "BlockStmt" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_associatedtype_declaration_child(this, i, result) } + /** Gets the node corresponding to the field `body`. */ + final Stmt getBody(int i) { unified_block_stmt_body(this, i, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_associatedtype_declaration_default_value(this, result) or - swift_associatedtype_declaration_must_inherit(this, result) or - swift_associatedtype_declaration_def(this, result) or - swift_associatedtype_declaration_child(this, _, result) - } + final override AstNode getAFieldOrChild() { unified_block_stmt_body(this, _, result) } } - /** A class representing `attribute` nodes. */ - class Attribute extends @swift_attribute, AstNode { + /** A class representing `call_expr` nodes. */ + class CallExpr extends @unified_call_expr, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Attribute" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_attribute_child(this, i, result) } + final override string getAPrimaryQlClass() { result = "CallExpr" } - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_attribute_child(this, _, result) } - } - - /** A class representing `availability_condition` nodes. */ - class AvailabilityCondition extends @swift_availability_condition, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "AvailabilityCondition" } + /** Gets the node corresponding to the field `argument`. */ + final Expr getArgument(int i) { unified_call_expr_argument(this, i, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_availability_condition_child(this, i, result) } + /** Gets the node corresponding to the field `function`. */ + final Expr getFunction() { unified_call_expr_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_availability_condition_child(this, _, result) + unified_call_expr_argument(this, _, result) or unified_call_expr_def(this, result) } } - /** A class representing `await_expression` nodes. */ - class AwaitExpression extends @swift_await_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "AwaitExpression" } - - /** Gets the node corresponding to the field `expr`. */ - final Expression getExpr() { swift_await_expression_expr(this, result) } - - /** Gets the child of this node. */ - final Expression getChild() { swift_await_expression_child(this, result) } + class Condition extends @unified_condition, AstNode { } - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_await_expression_expr(this, result) or swift_await_expression_child(this, result) - } - } - - /** A class representing `bang` tokens. */ - class Bang extends @swift_token_bang, Token { + /** A class representing `empty_stmt` tokens. */ + class EmptyStmt extends @unified_token_empty_stmt, Token { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Bang" } + final override string getAPrimaryQlClass() { result = "EmptyStmt" } } - /** A class representing `bin_literal` tokens. */ - class BinLiteral extends @swift_token_bin_literal, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "BinLiteral" } - } + class Expr extends @unified_expr, AstNode { } - /** A class representing `bitwise_operation` nodes. */ - class BitwiseOperation extends @swift_bitwise_operation, AstNode { + /** A class representing `expr_condition` nodes. */ + class ExprCondition extends @unified_expr_condition, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "BitwiseOperation" } - - /** Gets the node corresponding to the field `lhs`. */ - final Expression getLhs() { swift_bitwise_operation_def(this, result, _, _) } - - /** Gets the node corresponding to the field `op`. */ - final string getOp() { - exists(int value | swift_bitwise_operation_def(this, _, value, _) | - result = "&" and value = 0 - or - result = "<<" and value = 1 - or - result = ">>" and value = 2 - or - result = "^" and value = 3 - or - result = "|" and value = 4 - ) - } + final override string getAPrimaryQlClass() { result = "ExprCondition" } - /** Gets the node corresponding to the field `rhs`. */ - final Expression getRhs() { swift_bitwise_operation_def(this, _, _, result) } + /** Gets the node corresponding to the field `expr`. */ + final Expr getExpr() { unified_expr_condition_def(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_bitwise_operation_def(this, result, _, _) or - swift_bitwise_operation_def(this, _, _, result) - } - } - - /** A class representing `boolean_literal` tokens. */ - class BooleanLiteral extends @swift_token_boolean_literal, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "BooleanLiteral" } + final override AstNode getAFieldOrChild() { unified_expr_condition_def(this, result) } } - /** A class representing `call_expression` nodes. */ - class CallExpression extends @swift_call_expression, AstNode { + /** A class representing `expr_stmt` nodes. */ + class ExprStmt extends @unified_expr_stmt, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "CallExpression" } + final override string getAPrimaryQlClass() { result = "ExprStmt" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_call_expression_child(this, i, result) } + /** Gets the node corresponding to the field `expr`. */ + final Expr getExpr() { unified_expr_stmt_def(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_call_expression_child(this, _, result) } + final override AstNode getAFieldOrChild() { unified_expr_stmt_def(this, result) } } - /** A class representing `call_suffix` nodes. */ - class CallSuffix extends @swift_call_suffix, AstNode { + /** A class representing `guard_if_stmt` nodes. */ + class GuardIfStmt extends @unified_guard_if_stmt, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "CallSuffix" } + final override string getAPrimaryQlClass() { result = "GuardIfStmt" } - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName(int i) { swift_call_suffix_name(this, i, result) } + /** Gets the node corresponding to the field `condition`. */ + final Condition getCondition() { unified_guard_if_stmt_def(this, result, _) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_call_suffix_child(this, i, result) } + /** Gets the node corresponding to the field `else`. */ + final Stmt getElse() { unified_guard_if_stmt_def(this, _, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_call_suffix_name(this, _, result) or swift_call_suffix_child(this, _, result) + unified_guard_if_stmt_def(this, result, _) or unified_guard_if_stmt_def(this, _, result) } } - /** A class representing `capture_list` nodes. */ - class CaptureList extends @swift_capture_list, AstNode { + /** A class representing `identifier` tokens. */ + class Identifier extends @unified_token_identifier, Token { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "CaptureList" } - - /** Gets the `i`th child of this node. */ - final CaptureListItem getChild(int i) { swift_capture_list_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_capture_list_child(this, _, result) } + final override string getAPrimaryQlClass() { result = "Identifier" } } - /** A class representing `capture_list_item` nodes. */ - class CaptureListItem extends @swift_capture_list_item, AstNode { + /** A class representing `if_stmt` nodes. */ + class IfStmt extends @unified_if_stmt, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "CaptureListItem" } - - /** Gets the node corresponding to the field `name`. */ - final AstNode getName() { swift_capture_list_item_def(this, result) } - - /** Gets the node corresponding to the field `value`. */ - final Expression getValue() { swift_capture_list_item_value(this, result) } - - /** Gets the child of this node. */ - final OwnershipModifier getChild() { swift_capture_list_item_child(this, result) } + final override string getAPrimaryQlClass() { result = "IfStmt" } - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_capture_list_item_def(this, result) or - swift_capture_list_item_value(this, result) or - swift_capture_list_item_child(this, result) - } - } - - /** A class representing `catch_block` nodes. */ - class CatchBlock extends @swift_catch_block, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "CatchBlock" } + /** Gets the node corresponding to the field `condition`. */ + final Condition getCondition() { unified_if_stmt_def(this, result) } - /** Gets the node corresponding to the field `error`. */ - final Pattern getError() { swift_catch_block_error(this, result) } + /** Gets the node corresponding to the field `else`. */ + final Stmt getElse() { unified_if_stmt_else(this, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_catch_block_child(this, i, result) } + /** Gets the node corresponding to the field `then`. */ + final Stmt getThen() { unified_if_stmt_then(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_catch_block_error(this, result) or swift_catch_block_child(this, _, result) + unified_if_stmt_def(this, result) or + unified_if_stmt_else(this, result) or + unified_if_stmt_then(this, result) } } - /** A class representing `catch_keyword` tokens. */ - class CatchKeyword extends @swift_token_catch_keyword, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "CatchKeyword" } - } - - /** A class representing `check_expression` nodes. */ - class CheckExpression extends @swift_check_expression, AstNode { + /** A class representing `ignore_pattern` tokens. */ + class IgnorePattern extends @unified_token_ignore_pattern, Token { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "CheckExpression" } - - /** Gets the node corresponding to the field `op`. */ - final string getOp() { - exists(int value | swift_check_expression_def(this, value, _, _) | - (result = "is" and value = 0) - ) - } - - /** Gets the node corresponding to the field `target`. */ - final Expression getTarget() { swift_check_expression_def(this, _, result, _) } - - /** Gets the node corresponding to the field `type`. */ - final Type getType() { swift_check_expression_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_check_expression_def(this, _, result, _) or - swift_check_expression_def(this, _, _, result) - } + final override string getAPrimaryQlClass() { result = "IgnorePattern" } } - /** A class representing `class_body` nodes. */ - class ClassBody extends @swift_class_body, AstNode { + /** A class representing `int_literal` tokens. */ + class IntLiteral extends @unified_token_int_literal, Token { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ClassBody" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_class_body_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_class_body_child(this, _, result) } + final override string getAPrimaryQlClass() { result = "IntLiteral" } } - /** A class representing `class_declaration` nodes. */ - class ClassDeclaration extends @swift_class_declaration, AstNode { + /** A class representing `lambda_expr` nodes. */ + class LambdaExpr extends @unified_lambda_expr, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ClassDeclaration" } + final override string getAPrimaryQlClass() { result = "LambdaExpr" } /** Gets the node corresponding to the field `body`. */ - final AstNode getBody() { swift_class_declaration_def(this, result, _, _) } - - /** Gets the node corresponding to the field `declaration_kind`. */ - final string getDeclarationKind() { - exists(int value | swift_class_declaration_def(this, _, value, _) | - result = "actor" and value = 0 - or - result = "class" and value = 1 - or - result = "enum" and value = 2 - or - result = "extension" and value = 3 - or - result = "struct" and value = 4 - ) - } - - /** Gets the node corresponding to the field `name`. */ - final AstNode getName() { swift_class_declaration_def(this, _, _, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_class_declaration_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_class_declaration_def(this, result, _, _) or - swift_class_declaration_def(this, _, _, result) or - swift_class_declaration_child(this, _, result) - } - } - - /** A class representing `comment` tokens. */ - class Comment extends @swift_token_comment, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Comment" } - } - - /** A class representing `comparison_expression` nodes. */ - class ComparisonExpression extends @swift_comparison_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ComparisonExpression" } - - /** Gets the node corresponding to the field `lhs`. */ - final Expression getLhs() { swift_comparison_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `op`. */ - final string getOp() { - exists(int value | swift_comparison_expression_def(this, _, value, _) | - result = "<" and value = 0 - or - result = "<=" and value = 1 - or - result = ">" and value = 2 - or - result = ">=" and value = 3 - ) - } - - /** Gets the node corresponding to the field `rhs`. */ - final Expression getRhs() { swift_comparison_expression_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_comparison_expression_def(this, result, _, _) or - swift_comparison_expression_def(this, _, _, result) - } - } - - /** A class representing `computed_getter` nodes. */ - class ComputedGetter extends @swift_computed_getter, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ComputedGetter" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_computed_getter_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_computed_getter_child(this, _, result) } - } - - /** A class representing `computed_modify` nodes. */ - class ComputedModify extends @swift_computed_modify, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ComputedModify" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_computed_modify_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_computed_modify_child(this, _, result) } - } - - /** A class representing `computed_property` nodes. */ - class ComputedProperty extends @swift_computed_property, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ComputedProperty" } + final AstNode getBody() { unified_lambda_expr_def(this, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_computed_property_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_computed_property_child(this, _, result) } - } - - /** A class representing `computed_setter` nodes. */ - class ComputedSetter extends @swift_computed_setter, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ComputedSetter" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_computed_setter_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_computed_setter_child(this, _, result) } - } - - /** A class representing `conjunction_expression` nodes. */ - class ConjunctionExpression extends @swift_conjunction_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ConjunctionExpression" } - - /** Gets the node corresponding to the field `lhs`. */ - final Expression getLhs() { swift_conjunction_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `op`. */ - final string getOp() { - exists(int value | swift_conjunction_expression_def(this, _, value, _) | - (result = "&&" and value = 0) - ) - } - - /** Gets the node corresponding to the field `rhs`. */ - final Expression getRhs() { swift_conjunction_expression_def(this, _, _, result) } + /** Gets the node corresponding to the field `parameter`. */ + final Parameter getParameter(int i) { unified_lambda_expr_parameter(this, i, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_conjunction_expression_def(this, result, _, _) or - swift_conjunction_expression_def(this, _, _, result) + unified_lambda_expr_def(this, result) or unified_lambda_expr_parameter(this, _, result) } } - /** A class representing `constructor_expression` nodes. */ - class ConstructorExpression extends @swift_constructor_expression, AstNode { + /** A class representing `let_pattern_condition` nodes. */ + class LetPatternCondition extends @unified_let_pattern_condition, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ConstructorExpression" } + final override string getAPrimaryQlClass() { result = "LetPatternCondition" } - /** Gets the node corresponding to the field `constructed_type`. */ - final AstNode getConstructedType() { swift_constructor_expression_def(this, result, _) } + /** Gets the node corresponding to the field `pattern`. */ + final Pattern getPattern() { unified_let_pattern_condition_def(this, result, _) } - /** Gets the child of this node. */ - final ConstructorSuffix getChild() { swift_constructor_expression_def(this, _, result) } + /** Gets the node corresponding to the field `value`. */ + final Expr getValue() { unified_let_pattern_condition_def(this, _, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_constructor_expression_def(this, result, _) or - swift_constructor_expression_def(this, _, result) + unified_let_pattern_condition_def(this, result, _) or + unified_let_pattern_condition_def(this, _, result) } } - /** A class representing `constructor_suffix` nodes. */ - class ConstructorSuffix extends @swift_constructor_suffix, AstNode { + /** A class representing `member_access_expr` nodes. */ + class MemberAccessExpr extends @unified_member_access_expr, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ConstructorSuffix" } + final override string getAPrimaryQlClass() { result = "MemberAccessExpr" } - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName(int i) { swift_constructor_suffix_name(this, i, result) } + /** Gets the node corresponding to the field `member`. */ + final Identifier getMember() { unified_member_access_expr_def(this, result, _) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_constructor_suffix_child(this, i, result) } + /** Gets the node corresponding to the field `target`. */ + final Expr getTarget() { unified_member_access_expr_def(this, _, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_constructor_suffix_name(this, _, result) or - swift_constructor_suffix_child(this, _, result) + unified_member_access_expr_def(this, result, _) or + unified_member_access_expr_def(this, _, result) } } - /** A class representing `control_transfer_statement` nodes. */ - class ControlTransferStatement extends @swift_control_transfer_statement, AstNode { + /** A class representing `name_expr` nodes. */ + class NameExpr extends @unified_name_expr, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ControlTransferStatement" } - - /** Gets the node corresponding to the field `result`. */ - final Expression getResult() { swift_control_transfer_statement_result(this, result) } + final override string getAPrimaryQlClass() { result = "NameExpr" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_control_transfer_statement_child(this, i, result) } + /** Gets the node corresponding to the field `identifier`. */ + final Identifier getIdentifier() { unified_name_expr_def(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_control_transfer_statement_result(this, result) or - swift_control_transfer_statement_child(this, _, result) - } - } - - /** A class representing `custom_operator` tokens. */ - class CustomOperator extends @swift_token_custom_operator, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "CustomOperator" } - } - - /** A class representing `default_keyword` tokens. */ - class DefaultKeyword extends @swift_token_default_keyword, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DefaultKeyword" } + final override AstNode getAFieldOrChild() { unified_name_expr_def(this, result) } } - /** A class representing `deinit_declaration` nodes. */ - class DeinitDeclaration extends @swift_deinit_declaration, AstNode { + /** A class representing `operator` tokens. */ + class Operator extends @unified_token_operator, Token { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DeinitDeclaration" } - - /** Gets the node corresponding to the field `body`. */ - final FunctionBody getBody() { swift_deinit_declaration_def(this, result) } - - /** Gets the child of this node. */ - final Modifiers getChild() { swift_deinit_declaration_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_deinit_declaration_def(this, result) or swift_deinit_declaration_child(this, result) - } + final override string getAPrimaryQlClass() { result = "Operator" } } - /** A class representing `deprecated_operator_declaration_body` nodes. */ - class DeprecatedOperatorDeclarationBody extends @swift_deprecated_operator_declaration_body, - AstNode - { + /** A class representing `parameter` nodes. */ + class Parameter extends @unified_parameter, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DeprecatedOperatorDeclarationBody" } + final override string getAPrimaryQlClass() { result = "Parameter" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { - swift_deprecated_operator_declaration_body_child(this, i, result) - } + /** Gets the node corresponding to the field `pattern`. */ + final Pattern getPattern() { unified_parameter_def(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_deprecated_operator_declaration_body_child(this, _, result) - } + final override AstNode getAFieldOrChild() { unified_parameter_def(this, result) } } - /** A class representing `diagnostic` tokens. */ - class Diagnostic extends @swift_token_diagnostic, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Diagnostic" } - } + class Pattern extends @unified_pattern, AstNode { } - /** A class representing `dictionary_literal` nodes. */ - class DictionaryLiteral extends @swift_dictionary_literal, AstNode { + /** A class representing `sequence_condition` nodes. */ + class SequenceCondition extends @unified_sequence_condition, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DictionaryLiteral" } + final override string getAPrimaryQlClass() { result = "SequenceCondition" } - /** Gets the node corresponding to the field `key`. */ - final Expression getKey(int i) { swift_dictionary_literal_key(this, i, result) } + /** Gets the node corresponding to the field `condition`. */ + final Condition getCondition() { unified_sequence_condition_def(this, result) } - /** Gets the node corresponding to the field `value`. */ - final Expression getValue(int i) { swift_dictionary_literal_value(this, i, result) } + /** Gets the node corresponding to the field `stmt`. */ + final Stmt getStmt(int i) { unified_sequence_condition_stmt(this, i, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_dictionary_literal_key(this, _, result) or - swift_dictionary_literal_value(this, _, result) + unified_sequence_condition_def(this, result) or + unified_sequence_condition_stmt(this, _, result) } } - /** A class representing `dictionary_type` nodes. */ - class DictionaryType extends @swift_dictionary_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DictionaryType" } - - /** Gets the node corresponding to the field `key`. */ - final Type getKey() { swift_dictionary_type_def(this, result, _) } - - /** Gets the node corresponding to the field `value`. */ - final Type getValue() { swift_dictionary_type_def(this, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_dictionary_type_def(this, result, _) or swift_dictionary_type_def(this, _, result) - } - } + class Stmt extends @unified_stmt, AstNode { } - /** A class representing `didset_clause` nodes. */ - class DidsetClause extends @swift_didset_clause, AstNode { + /** A class representing `string_literal` tokens. */ + class StringLiteral extends @unified_token_string_literal, Token { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DidsetClause" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_didset_clause_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_didset_clause_child(this, _, result) } + final override string getAPrimaryQlClass() { result = "StringLiteral" } } - /** A class representing `directive` nodes. */ - class Directive extends @swift_directive, AstNode { + /** A class representing `top_level` nodes. */ + class TopLevel extends @unified_top_level, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Directive" } + final override string getAPrimaryQlClass() { result = "TopLevel" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_directive_child(this, i, result) } + /** Gets the node corresponding to the field `body`. */ + final AstNode getBody(int i) { unified_top_level_body(this, i, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_directive_child(this, _, result) } + final override AstNode getAFieldOrChild() { unified_top_level_body(this, _, result) } } - /** A class representing `directly_assignable_expression` nodes. */ - class DirectlyAssignableExpression extends @swift_directly_assignable_expression, AstNode { + /** A class representing `tuple_pattern` nodes. */ + class TuplePattern extends @unified_tuple_pattern, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DirectlyAssignableExpression" } + final override string getAPrimaryQlClass() { result = "TuplePattern" } - /** Gets the child of this node. */ - final Expression getChild() { swift_directly_assignable_expression_def(this, result) } + /** Gets the node corresponding to the field `element`. */ + final Pattern getElement(int i) { unified_tuple_pattern_element(this, i, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_directly_assignable_expression_def(this, result) - } + final override AstNode getAFieldOrChild() { unified_tuple_pattern_element(this, _, result) } } - /** A class representing `disjunction_expression` nodes. */ - class DisjunctionExpression extends @swift_disjunction_expression, AstNode { + /** A class representing `unary_expr` nodes. */ + class UnaryExpr extends @unified_unary_expr, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DisjunctionExpression" } + final override string getAPrimaryQlClass() { result = "UnaryExpr" } - /** Gets the node corresponding to the field `lhs`. */ - final Expression getLhs() { swift_disjunction_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `op`. */ - final string getOp() { - exists(int value | swift_disjunction_expression_def(this, _, value, _) | - (result = "||" and value = 0) - ) - } + /** Gets the node corresponding to the field `operand`. */ + final Expr getOperand() { unified_unary_expr_def(this, result, _) } - /** Gets the node corresponding to the field `rhs`. */ - final Expression getRhs() { swift_disjunction_expression_def(this, _, _, result) } + /** Gets the node corresponding to the field `operator`. */ + final Operator getOperator() { unified_unary_expr_def(this, _, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_disjunction_expression_def(this, result, _, _) or - swift_disjunction_expression_def(this, _, _, result) + unified_unary_expr_def(this, result, _) or unified_unary_expr_def(this, _, result) } } - /** A class representing `do_statement` nodes. */ - class DoStatement extends @swift_do_statement, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DoStatement" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_do_statement_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_do_statement_child(this, _, result) } - } - - /** A class representing `else` tokens. */ - class Else extends @swift_token_else, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Else" } - } - - /** A class representing `enum_class_body` nodes. */ - class EnumClassBody extends @swift_enum_class_body, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "EnumClassBody" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_enum_class_body_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_enum_class_body_child(this, _, result) } - } - - /** A class representing `enum_entry` nodes. */ - class EnumEntry extends @swift_enum_entry, AstNode { + /** A class representing `unsupported_node` tokens. */ + class UnsupportedNode extends @unified_token_unsupported_node, Token { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "EnumEntry" } - - /** Gets the node corresponding to the field `data_contents`. */ - final EnumTypeParameters getDataContents(int i) { - swift_enum_entry_data_contents(this, i, result) - } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName(int i) { swift_enum_entry_name(this, i, result) } - - /** Gets the node corresponding to the field `raw_value`. */ - final Expression getRawValue(int i) { swift_enum_entry_raw_value(this, i, result) } - - /** Gets the child of this node. */ - final Modifiers getChild() { swift_enum_entry_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_enum_entry_data_contents(this, _, result) or - swift_enum_entry_name(this, _, result) or - swift_enum_entry_raw_value(this, _, result) or - swift_enum_entry_child(this, result) - } + final override string getAPrimaryQlClass() { result = "UnsupportedNode" } } - /** A class representing `enum_type_parameters` nodes. */ - class EnumTypeParameters extends @swift_enum_type_parameters, AstNode { + /** A class representing `var_pattern` nodes. */ + class VarPattern extends @unified_var_pattern, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "EnumTypeParameters" } + final override string getAPrimaryQlClass() { result = "VarPattern" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_enum_type_parameters_child(this, i, result) } + /** Gets the node corresponding to the field `identifier`. */ + final Identifier getIdentifier() { unified_var_pattern_def(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_enum_type_parameters_child(this, _, result) } + final override AstNode getAFieldOrChild() { unified_var_pattern_def(this, result) } } - /** A class representing `equality_constraint` nodes. */ - class EqualityConstraint extends @swift_equality_constraint, AstNode { + /** A class representing `variable_declaration_stmt` nodes. */ + class VariableDeclarationStmt extends @unified_variable_declaration_stmt, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "EqualityConstraint" } - - /** Gets the node corresponding to the field `constrained_type`. */ - final AstNode getConstrainedType() { swift_equality_constraint_def(this, result, _) } - - /** Gets the node corresponding to the field `must_equal`. */ - final Type getMustEqual() { swift_equality_constraint_def(this, _, result) } - - /** Gets the `i`th child of this node. */ - final Attribute getChild(int i) { swift_equality_constraint_child(this, i, result) } + final override string getAPrimaryQlClass() { result = "VariableDeclarationStmt" } - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_equality_constraint_def(this, result, _) or - swift_equality_constraint_def(this, _, result) or - swift_equality_constraint_child(this, _, result) - } - } - - /** A class representing `equality_expression` nodes. */ - class EqualityExpression extends @swift_equality_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "EqualityExpression" } - - /** Gets the node corresponding to the field `lhs`. */ - final Expression getLhs() { swift_equality_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `op`. */ - final string getOp() { - exists(int value | swift_equality_expression_def(this, _, value, _) | - result = "!=" and value = 0 - or - result = "!==" and value = 1 - or - result = "==" and value = 2 - or - result = "===" and value = 3 - ) + /** Gets the node corresponding to the field `variable_declarator`. */ + final VariableDeclarator getVariableDeclarator(int i) { + unified_variable_declaration_stmt_variable_declarator(this, i, result) } - /** Gets the node corresponding to the field `rhs`. */ - final Expression getRhs() { swift_equality_expression_def(this, _, _, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_equality_expression_def(this, result, _, _) or - swift_equality_expression_def(this, _, _, result) + unified_variable_declaration_stmt_variable_declarator(this, _, result) } } - /** A class representing `existential_type` nodes. */ - class ExistentialType extends @swift_existential_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ExistentialType" } - - /** Gets the child of this node. */ - final UnannotatedType getChild() { swift_existential_type_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_existential_type_def(this, result) } - } - - class Expression extends @swift_expression, AstNode { } - - /** A class representing `external_macro_definition` nodes. */ - class ExternalMacroDefinition extends @swift_external_macro_definition, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ExternalMacroDefinition" } - - /** Gets the child of this node. */ - final ValueArguments getChild() { swift_external_macro_definition_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_external_macro_definition_def(this, result) } - } - - /** A class representing `for_statement` nodes. */ - class ForStatement extends @swift_for_statement, AstNode { + /** A class representing `variable_declarator` nodes. */ + class VariableDeclarator extends @unified_variable_declarator, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ForStatement" } + final override string getAPrimaryQlClass() { result = "VariableDeclarator" } - /** Gets the node corresponding to the field `collection`. */ - final Expression getCollection() { swift_for_statement_def(this, result, _) } + /** Gets the node corresponding to the field `pattern`. */ + final Pattern getPattern() { unified_variable_declarator_def(this, result) } - /** Gets the node corresponding to the field `item`. */ - final Pattern getItem() { swift_for_statement_def(this, _, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_for_statement_child(this, i, result) } + /** Gets the node corresponding to the field `value`. */ + final Expr getValue() { unified_variable_declarator_value(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_for_statement_def(this, result, _) or - swift_for_statement_def(this, _, result) or - swift_for_statement_child(this, _, result) - } - } - - /** A class representing `fully_open_range` tokens. */ - class FullyOpenRange extends @swift_token_fully_open_range, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "FullyOpenRange" } - } - - /** A class representing `function_body` nodes. */ - class FunctionBody extends @swift_function_body, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "FunctionBody" } - - /** Gets the child of this node. */ - final Statements getChild() { swift_function_body_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_function_body_child(this, result) } - } - - /** A class representing `function_declaration` nodes. */ - class FunctionDeclaration extends @swift_function_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "FunctionDeclaration" } - - /** Gets the node corresponding to the field `body`. */ - final FunctionBody getBody() { swift_function_declaration_def(this, result, _) } - - /** Gets the node corresponding to the field `default_value`. */ - final Expression getDefaultValue(int i) { - swift_function_declaration_default_value(this, i, result) + unified_variable_declarator_def(this, result) or + unified_variable_declarator_value(this, result) } - - /** Gets the node corresponding to the field `name`. */ - final AstNode getName() { swift_function_declaration_def(this, _, result) } - - /** Gets the node corresponding to the field `return_type`. */ - final AstNode getReturnType() { swift_function_declaration_return_type(this, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_function_declaration_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_function_declaration_def(this, result, _) or - swift_function_declaration_default_value(this, _, result) or - swift_function_declaration_def(this, _, result) or - swift_function_declaration_return_type(this, result) or - swift_function_declaration_child(this, _, result) - } - } - - /** A class representing `function_modifier` tokens. */ - class FunctionModifier extends @swift_token_function_modifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "FunctionModifier" } - } - - /** A class representing `function_type` nodes. */ - class FunctionType extends @swift_function_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "FunctionType" } - - /** Gets the node corresponding to the field `params`. */ - final UnannotatedType getParams() { swift_function_type_def(this, result, _) } - - /** Gets the node corresponding to the field `return_type`. */ - final Type getReturnType() { swift_function_type_def(this, _, result) } - - /** Gets the child of this node. */ - final AstNode getChild() { swift_function_type_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_function_type_def(this, result, _) or - swift_function_type_def(this, _, result) or - swift_function_type_child(this, result) - } - } - - /** A class representing `getter_specifier` nodes. */ - class GetterSpecifier extends @swift_getter_specifier, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "GetterSpecifier" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_getter_specifier_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_getter_specifier_child(this, _, result) } - } - - class GlobalDeclaration extends @swift_global_declaration, AstNode { } - - /** A class representing `guard_statement` nodes. */ - class GuardStatement extends @swift_guard_statement, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "GuardStatement" } - - /** Gets the node corresponding to the field `condition`. */ - final IfCondition getCondition(int i) { swift_guard_statement_condition(this, i, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_guard_statement_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_guard_statement_condition(this, _, result) or - swift_guard_statement_child(this, _, result) - } - } - - /** A class representing `hex_literal` tokens. */ - class HexLiteral extends @swift_token_hex_literal, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "HexLiteral" } - } - - /** A class representing `identifier` nodes. */ - class Identifier extends @swift_identifier, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Identifier" } - - /** Gets the `i`th child of this node. */ - final SimpleIdentifier getChild(int i) { swift_identifier_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_identifier_child(this, _, result) } - } - - /** A class representing `if_condition` nodes. */ - class IfCondition extends @swift_if_condition, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "IfCondition" } - - /** Gets the child of this node. */ - final AstNode getChild() { swift_if_condition_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_if_condition_def(this, result) } - } - - /** A class representing `if_let_binding` nodes. */ - class IfLetBinding extends @swift_if_let_binding, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "IfLetBinding" } - - /** Gets the node corresponding to the field `bound_identifier`. */ - final SimpleIdentifier getBoundIdentifier() { - swift_if_let_binding_bound_identifier(this, result) - } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_if_let_binding_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_if_let_binding_bound_identifier(this, result) or - swift_if_let_binding_child(this, _, result) - } - } - - /** A class representing `if_statement` nodes. */ - class IfStatement extends @swift_if_statement, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "IfStatement" } - - /** Gets the node corresponding to the field `condition`. */ - final IfCondition getCondition(int i) { swift_if_statement_condition(this, i, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_if_statement_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_if_statement_condition(this, _, result) or swift_if_statement_child(this, _, result) - } - } - - /** A class representing `implicitly_unwrapped_type` nodes. */ - class ImplicitlyUnwrappedType extends @swift_implicitly_unwrapped_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ImplicitlyUnwrappedType" } - - /** Gets the child of this node. */ - final Type getChild() { swift_implicitly_unwrapped_type_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_implicitly_unwrapped_type_def(this, result) } - } - - /** A class representing `import_declaration` nodes. */ - class ImportDeclaration extends @swift_import_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ImportDeclaration" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_import_declaration_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_import_declaration_child(this, _, result) } - } - - /** A class representing `infix_expression` nodes. */ - class InfixExpression extends @swift_infix_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "InfixExpression" } - - /** Gets the node corresponding to the field `lhs`. */ - final Expression getLhs() { swift_infix_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `op`. */ - final CustomOperator getOp() { swift_infix_expression_def(this, _, result, _) } - - /** Gets the node corresponding to the field `rhs`. */ - final Expression getRhs() { swift_infix_expression_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_infix_expression_def(this, result, _, _) or - swift_infix_expression_def(this, _, result, _) or - swift_infix_expression_def(this, _, _, result) - } - } - - /** A class representing `inheritance_constraint` nodes. */ - class InheritanceConstraint extends @swift_inheritance_constraint, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "InheritanceConstraint" } - - /** Gets the node corresponding to the field `constrained_type`. */ - final AstNode getConstrainedType() { swift_inheritance_constraint_def(this, result, _) } - - /** Gets the node corresponding to the field `inherits_from`. */ - final AstNode getInheritsFrom() { swift_inheritance_constraint_def(this, _, result) } - - /** Gets the `i`th child of this node. */ - final Attribute getChild(int i) { swift_inheritance_constraint_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_inheritance_constraint_def(this, result, _) or - swift_inheritance_constraint_def(this, _, result) or - swift_inheritance_constraint_child(this, _, result) - } - } - - /** A class representing `inheritance_modifier` tokens. */ - class InheritanceModifier extends @swift_token_inheritance_modifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "InheritanceModifier" } - } - - /** A class representing `inheritance_specifier` nodes. */ - class InheritanceSpecifier extends @swift_inheritance_specifier, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "InheritanceSpecifier" } - - /** Gets the node corresponding to the field `inherits_from`. */ - final AstNode getInheritsFrom() { swift_inheritance_specifier_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_inheritance_specifier_def(this, result) } - } - - /** A class representing `init_declaration` nodes. */ - class InitDeclaration extends @swift_init_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "InitDeclaration" } - - /** Gets the node corresponding to the field `body`. */ - final FunctionBody getBody() { swift_init_declaration_body(this, result) } - - /** Gets the node corresponding to the field `default_value`. */ - final Expression getDefaultValue(int i) { - swift_init_declaration_default_value(this, i, result) - } - - /** Gets the node corresponding to the field `name`. */ - final string getName() { - exists(int value | swift_init_declaration_def(this, value) | (result = "init" and value = 0)) - } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_init_declaration_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_init_declaration_body(this, result) or - swift_init_declaration_default_value(this, _, result) or - swift_init_declaration_child(this, _, result) - } - } - - /** A class representing `integer_literal` tokens. */ - class IntegerLiteral extends @swift_token_integer_literal, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "IntegerLiteral" } - } - - /** A class representing `interpolated_expression` nodes. */ - class InterpolatedExpression extends @swift_interpolated_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "InterpolatedExpression" } - - /** Gets the node corresponding to the field `name`. */ - final ValueArgumentLabel getName() { swift_interpolated_expression_name(this, result) } - - /** Gets the node corresponding to the field `reference_specifier`. */ - final ValueArgumentLabel getReferenceSpecifier(int i) { - swift_interpolated_expression_reference_specifier(this, i, result) - } - - /** Gets the node corresponding to the field `value`. */ - final Expression getValue() { swift_interpolated_expression_value(this, result) } - - /** Gets the child of this node. */ - final TypeModifiers getChild() { swift_interpolated_expression_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_interpolated_expression_name(this, result) or - swift_interpolated_expression_reference_specifier(this, _, result) or - swift_interpolated_expression_value(this, result) or - swift_interpolated_expression_child(this, result) - } - } - - /** A class representing `key_path_expression` nodes. */ - class KeyPathExpression extends @swift_key_path_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "KeyPathExpression" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_key_path_expression_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_key_path_expression_child(this, _, result) } - } - - /** A class representing `key_path_string_expression` nodes. */ - class KeyPathStringExpression extends @swift_key_path_string_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "KeyPathStringExpression" } - - /** Gets the child of this node. */ - final Expression getChild() { swift_key_path_string_expression_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_key_path_string_expression_def(this, result) } - } - - /** A class representing `lambda_function_type` nodes. */ - class LambdaFunctionType extends @swift_lambda_function_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "LambdaFunctionType" } - - /** Gets the node corresponding to the field `return_type`. */ - final AstNode getReturnType() { swift_lambda_function_type_return_type(this, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_lambda_function_type_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_lambda_function_type_return_type(this, result) or - swift_lambda_function_type_child(this, _, result) - } - } - - /** A class representing `lambda_function_type_parameters` nodes. */ - class LambdaFunctionTypeParameters extends @swift_lambda_function_type_parameters, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "LambdaFunctionTypeParameters" } - - /** Gets the `i`th child of this node. */ - final LambdaParameter getChild(int i) { - swift_lambda_function_type_parameters_child(this, i, result) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_lambda_function_type_parameters_child(this, _, result) - } - } - - /** A class representing `lambda_literal` nodes. */ - class LambdaLiteral extends @swift_lambda_literal, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "LambdaLiteral" } - - /** Gets the node corresponding to the field `captures`. */ - final CaptureList getCaptures() { swift_lambda_literal_captures(this, result) } - - /** Gets the node corresponding to the field `type`. */ - final LambdaFunctionType getType() { swift_lambda_literal_type(this, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_lambda_literal_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_lambda_literal_captures(this, result) or - swift_lambda_literal_type(this, result) or - swift_lambda_literal_child(this, _, result) - } - } - - /** A class representing `lambda_parameter` nodes. */ - class LambdaParameter extends @swift_lambda_parameter, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "LambdaParameter" } - - /** Gets the node corresponding to the field `external_name`. */ - final SimpleIdentifier getExternalName() { swift_lambda_parameter_external_name(this, result) } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName() { swift_lambda_parameter_name(this, result) } - - /** Gets the node corresponding to the field `type`. */ - final AstNode getType() { swift_lambda_parameter_type(this, result) } - - /** Gets the child of this node. */ - final AstNode getChild() { swift_lambda_parameter_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_lambda_parameter_external_name(this, result) or - swift_lambda_parameter_name(this, result) or - swift_lambda_parameter_type(this, result) or - swift_lambda_parameter_child(this, result) - } - } - - /** A class representing `line_str_text` tokens. */ - class LineStrText extends @swift_token_line_str_text, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "LineStrText" } - } - - /** A class representing `line_string_literal` nodes. */ - class LineStringLiteral extends @swift_line_string_literal, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "LineStringLiteral" } - - /** Gets the node corresponding to the field `interpolation`. */ - final InterpolatedExpression getInterpolation(int i) { - swift_line_string_literal_interpolation(this, i, result) - } - - /** Gets the node corresponding to the field `text`. */ - final AstNode getText(int i) { swift_line_string_literal_text(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_line_string_literal_interpolation(this, _, result) or - swift_line_string_literal_text(this, _, result) - } - } - - class LocalDeclaration extends @swift_local_declaration, AstNode { } - - /** A class representing `macro_declaration` nodes. */ - class MacroDeclaration extends @swift_macro_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "MacroDeclaration" } - - /** Gets the node corresponding to the field `default_value`. */ - final Expression getDefaultValue(int i) { - swift_macro_declaration_default_value(this, i, result) - } - - /** Gets the node corresponding to the field `definition`. */ - final MacroDefinition getDefinition() { swift_macro_declaration_definition(this, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_macro_declaration_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_macro_declaration_default_value(this, _, result) or - swift_macro_declaration_definition(this, result) or - swift_macro_declaration_child(this, _, result) - } - } - - /** A class representing `macro_definition` nodes. */ - class MacroDefinition extends @swift_macro_definition, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "MacroDefinition" } - - /** Gets the node corresponding to the field `body`. */ - final AstNode getBody() { swift_macro_definition_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_macro_definition_def(this, result) } - } - - /** A class representing `macro_invocation` nodes. */ - class MacroInvocation extends @swift_macro_invocation, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "MacroInvocation" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_macro_invocation_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_macro_invocation_child(this, _, result) } - } - - /** A class representing `member_modifier` tokens. */ - class MemberModifier extends @swift_token_member_modifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "MemberModifier" } - } - - /** A class representing `metatype` nodes. */ - class Metatype extends @swift_metatype, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Metatype" } - - /** Gets the child of this node. */ - final UnannotatedType getChild() { swift_metatype_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_metatype_def(this, result) } - } - - /** A class representing `modifiers` nodes. */ - class Modifiers extends @swift_modifiers, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Modifiers" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_modifiers_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_modifiers_child(this, _, result) } - } - - /** A class representing `modify_specifier` nodes. */ - class ModifySpecifier extends @swift_modify_specifier, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ModifySpecifier" } - - /** Gets the child of this node. */ - final MutationModifier getChild() { swift_modify_specifier_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_modify_specifier_child(this, result) } - } - - /** A class representing `multi_line_str_text` tokens. */ - class MultiLineStrText extends @swift_token_multi_line_str_text, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "MultiLineStrText" } - } - - /** A class representing `multi_line_string_literal` nodes. */ - class MultiLineStringLiteral extends @swift_multi_line_string_literal, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "MultiLineStringLiteral" } - - /** Gets the node corresponding to the field `interpolation`. */ - final InterpolatedExpression getInterpolation(int i) { - swift_multi_line_string_literal_interpolation(this, i, result) - } - - /** Gets the node corresponding to the field `text`. */ - final AstNode getText(int i) { swift_multi_line_string_literal_text(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_multi_line_string_literal_interpolation(this, _, result) or - swift_multi_line_string_literal_text(this, _, result) - } - } - - /** A class representing `multiline_comment` tokens. */ - class MultilineComment extends @swift_token_multiline_comment, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "MultilineComment" } - } - - /** A class representing `multiplicative_expression` nodes. */ - class MultiplicativeExpression extends @swift_multiplicative_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "MultiplicativeExpression" } - - /** Gets the node corresponding to the field `lhs`. */ - final Expression getLhs() { swift_multiplicative_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `op`. */ - final string getOp() { - exists(int value | swift_multiplicative_expression_def(this, _, value, _) | - result = "%" and value = 0 - or - result = "*" and value = 1 - or - result = "/" and value = 2 - ) - } - - /** Gets the node corresponding to the field `rhs`. */ - final Expression getRhs() { swift_multiplicative_expression_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_multiplicative_expression_def(this, result, _, _) or - swift_multiplicative_expression_def(this, _, _, result) - } - } - - /** A class representing `mutation_modifier` tokens. */ - class MutationModifier extends @swift_token_mutation_modifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "MutationModifier" } - } - - /** A class representing `navigation_expression` nodes. */ - class NavigationExpression extends @swift_navigation_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "NavigationExpression" } - - /** Gets the node corresponding to the field `suffix`. */ - final NavigationSuffix getSuffix() { swift_navigation_expression_def(this, result) } - - /** Gets the node corresponding to the field `target`. */ - final AstNode getTarget(int i) { swift_navigation_expression_target(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_navigation_expression_def(this, result) or - swift_navigation_expression_target(this, _, result) - } - } - - /** A class representing `navigation_suffix` nodes. */ - class NavigationSuffix extends @swift_navigation_suffix, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "NavigationSuffix" } - - /** Gets the node corresponding to the field `suffix`. */ - final AstNode getSuffix() { swift_navigation_suffix_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_navigation_suffix_def(this, result) } - } - - /** A class representing `nested_type_identifier` nodes. */ - class NestedTypeIdentifier extends @swift_nested_type_identifier, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "NestedTypeIdentifier" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_nested_type_identifier_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_nested_type_identifier_child(this, _, result) - } - } - - /** A class representing `nil_coalescing_expression` nodes. */ - class NilCoalescingExpression extends @swift_nil_coalescing_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "NilCoalescingExpression" } - - /** Gets the node corresponding to the field `if_nil`. */ - final Expression getIfNil() { swift_nil_coalescing_expression_def(this, result, _) } - - /** Gets the node corresponding to the field `value`. */ - final Expression getValue() { swift_nil_coalescing_expression_def(this, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_nil_coalescing_expression_def(this, result, _) or - swift_nil_coalescing_expression_def(this, _, result) - } - } - - /** A class representing `oct_literal` tokens. */ - class OctLiteral extends @swift_token_oct_literal, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "OctLiteral" } - } - - /** A class representing `opaque_type` nodes. */ - class OpaqueType extends @swift_opaque_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "OpaqueType" } - - /** Gets the child of this node. */ - final UnannotatedType getChild() { swift_opaque_type_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_opaque_type_def(this, result) } - } - - /** A class representing `open_end_range_expression` nodes. */ - class OpenEndRangeExpression extends @swift_open_end_range_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "OpenEndRangeExpression" } - - /** Gets the node corresponding to the field `start`. */ - final Expression getStart() { swift_open_end_range_expression_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_open_end_range_expression_def(this, result) } - } - - /** A class representing `open_start_range_expression` nodes. */ - class OpenStartRangeExpression extends @swift_open_start_range_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "OpenStartRangeExpression" } - - /** Gets the node corresponding to the field `end`. */ - final Expression getEnd() { swift_open_start_range_expression_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_open_start_range_expression_def(this, result) - } - } - - /** A class representing `operator_declaration` nodes. */ - class OperatorDeclaration extends @swift_operator_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "OperatorDeclaration" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_operator_declaration_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_operator_declaration_child(this, _, result) } - } - - /** A class representing `optional_chain_marker` nodes. */ - class OptionalChainMarker extends @swift_optional_chain_marker, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "OptionalChainMarker" } - - /** Gets the child of this node. */ - final Expression getChild() { swift_optional_chain_marker_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_optional_chain_marker_def(this, result) } - } - - /** A class representing `optional_type` nodes. */ - class OptionalType extends @swift_optional_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "OptionalType" } - - /** Gets the node corresponding to the field `wrapped`. */ - final AstNode getWrapped() { swift_optional_type_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_optional_type_def(this, result) } - } - - /** A class representing `ownership_modifier` tokens. */ - class OwnershipModifier extends @swift_token_ownership_modifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "OwnershipModifier" } - } - - /** A class representing `parameter` nodes. */ - class Parameter extends @swift_parameter, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Parameter" } - - /** Gets the node corresponding to the field `external_name`. */ - final SimpleIdentifier getExternalName() { swift_parameter_external_name(this, result) } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName() { swift_parameter_def(this, result, _) } - - /** Gets the node corresponding to the field `type`. */ - final AstNode getType() { swift_parameter_def(this, _, result) } - - /** Gets the child of this node. */ - final ParameterModifiers getChild() { swift_parameter_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_parameter_external_name(this, result) or - swift_parameter_def(this, result, _) or - swift_parameter_def(this, _, result) or - swift_parameter_child(this, result) - } - } - - /** A class representing `parameter_modifier` tokens. */ - class ParameterModifier extends @swift_token_parameter_modifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ParameterModifier" } - } - - /** A class representing `parameter_modifiers` nodes. */ - class ParameterModifiers extends @swift_parameter_modifiers, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ParameterModifiers" } - - /** Gets the `i`th child of this node. */ - final ParameterModifier getChild(int i) { swift_parameter_modifiers_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_parameter_modifiers_child(this, _, result) } - } - - /** A class representing `pattern` nodes. */ - class Pattern extends @swift_pattern, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Pattern" } - - /** Gets the node corresponding to the field `bound_identifier`. */ - final SimpleIdentifier getBoundIdentifier() { swift_pattern_bound_identifier(this, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_pattern_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_pattern_bound_identifier(this, result) or swift_pattern_child(this, _, result) - } - } - - /** A class representing `playground_literal` nodes. */ - class PlaygroundLiteral extends @swift_playground_literal, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PlaygroundLiteral" } - - /** Gets the `i`th child of this node. */ - final Expression getChild(int i) { swift_playground_literal_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_playground_literal_child(this, _, result) } - } - - /** A class representing `postfix_expression` nodes. */ - class PostfixExpression extends @swift_postfix_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PostfixExpression" } - - /** Gets the node corresponding to the field `operation`. */ - final AstNode getOperation() { swift_postfix_expression_def(this, result, _) } - - /** Gets the node corresponding to the field `target`. */ - final Expression getTarget() { swift_postfix_expression_def(this, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_postfix_expression_def(this, result, _) or swift_postfix_expression_def(this, _, result) - } - } - - /** A class representing `precedence_group_attribute` nodes. */ - class PrecedenceGroupAttribute extends @swift_precedence_group_attribute, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PrecedenceGroupAttribute" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_precedence_group_attribute_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_precedence_group_attribute_child(this, _, result) - } - } - - /** A class representing `precedence_group_attributes` nodes. */ - class PrecedenceGroupAttributes extends @swift_precedence_group_attributes, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PrecedenceGroupAttributes" } - - /** Gets the `i`th child of this node. */ - final PrecedenceGroupAttribute getChild(int i) { - swift_precedence_group_attributes_child(this, i, result) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_precedence_group_attributes_child(this, _, result) - } - } - - /** A class representing `precedence_group_declaration` nodes. */ - class PrecedenceGroupDeclaration extends @swift_precedence_group_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PrecedenceGroupDeclaration" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_precedence_group_declaration_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_precedence_group_declaration_child(this, _, result) - } - } - - /** A class representing `prefix_expression` nodes. */ - class PrefixExpression extends @swift_prefix_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PrefixExpression" } - - /** Gets the node corresponding to the field `operation`. */ - final AstNode getOperation() { swift_prefix_expression_def(this, result, _) } - - /** Gets the node corresponding to the field `target`. */ - final Expression getTarget() { swift_prefix_expression_def(this, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_prefix_expression_def(this, result, _) or swift_prefix_expression_def(this, _, result) - } - } - - /** A class representing `property_behavior_modifier` tokens. */ - class PropertyBehaviorModifier extends @swift_token_property_behavior_modifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PropertyBehaviorModifier" } - } - - /** A class representing `property_declaration` nodes. */ - class PropertyDeclaration extends @swift_property_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PropertyDeclaration" } - - /** Gets the node corresponding to the field `computed_value`. */ - final ComputedProperty getComputedValue(int i) { - swift_property_declaration_computed_value(this, i, result) - } - - /** Gets the node corresponding to the field `name`. */ - final Pattern getName(int i) { swift_property_declaration_name(this, i, result) } - - /** Gets the node corresponding to the field `value`. */ - final Expression getValue(int i) { swift_property_declaration_value(this, i, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_property_declaration_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_property_declaration_computed_value(this, _, result) or - swift_property_declaration_name(this, _, result) or - swift_property_declaration_value(this, _, result) or - swift_property_declaration_child(this, _, result) - } - } - - /** A class representing `property_modifier` tokens. */ - class PropertyModifier extends @swift_token_property_modifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PropertyModifier" } - } - - /** A class representing `protocol_body` nodes. */ - class ProtocolBody extends @swift_protocol_body, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ProtocolBody" } - - /** Gets the `i`th child of this node. */ - final ProtocolMemberDeclaration getChild(int i) { swift_protocol_body_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_protocol_body_child(this, _, result) } - } - - /** A class representing `protocol_composition_type` nodes. */ - class ProtocolCompositionType extends @swift_protocol_composition_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ProtocolCompositionType" } - - /** Gets the `i`th child of this node. */ - final UnannotatedType getChild(int i) { swift_protocol_composition_type_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_protocol_composition_type_child(this, _, result) - } - } - - /** A class representing `protocol_declaration` nodes. */ - class ProtocolDeclaration extends @swift_protocol_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ProtocolDeclaration" } - - /** Gets the node corresponding to the field `body`. */ - final ProtocolBody getBody() { swift_protocol_declaration_def(this, result, _, _) } - - /** Gets the node corresponding to the field `declaration_kind`. */ - final string getDeclarationKind() { - exists(int value | swift_protocol_declaration_def(this, _, value, _) | - (result = "protocol" and value = 0) - ) - } - - /** Gets the node corresponding to the field `name`. */ - final TypeIdentifier getName() { swift_protocol_declaration_def(this, _, _, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_protocol_declaration_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_protocol_declaration_def(this, result, _, _) or - swift_protocol_declaration_def(this, _, _, result) or - swift_protocol_declaration_child(this, _, result) - } - } - - /** A class representing `protocol_function_declaration` nodes. */ - class ProtocolFunctionDeclaration extends @swift_protocol_function_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ProtocolFunctionDeclaration" } - - /** Gets the node corresponding to the field `body`. */ - final FunctionBody getBody() { swift_protocol_function_declaration_body(this, result) } - - /** Gets the node corresponding to the field `default_value`. */ - final Expression getDefaultValue(int i) { - swift_protocol_function_declaration_default_value(this, i, result) - } - - /** Gets the node corresponding to the field `name`. */ - final AstNode getName() { swift_protocol_function_declaration_def(this, result) } - - /** Gets the node corresponding to the field `return_type`. */ - final AstNode getReturnType() { swift_protocol_function_declaration_return_type(this, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_protocol_function_declaration_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_protocol_function_declaration_body(this, result) or - swift_protocol_function_declaration_default_value(this, _, result) or - swift_protocol_function_declaration_def(this, result) or - swift_protocol_function_declaration_return_type(this, result) or - swift_protocol_function_declaration_child(this, _, result) - } - } - - class ProtocolMemberDeclaration extends @swift_protocol_member_declaration, AstNode { } - - /** A class representing `protocol_property_declaration` nodes. */ - class ProtocolPropertyDeclaration extends @swift_protocol_property_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ProtocolPropertyDeclaration" } - - /** Gets the node corresponding to the field `name`. */ - final Pattern getName() { swift_protocol_property_declaration_def(this, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_protocol_property_declaration_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_protocol_property_declaration_def(this, result) or - swift_protocol_property_declaration_child(this, _, result) - } - } - - /** A class representing `protocol_property_requirements` nodes. */ - class ProtocolPropertyRequirements extends @swift_protocol_property_requirements, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ProtocolPropertyRequirements" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_protocol_property_requirements_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_protocol_property_requirements_child(this, _, result) - } - } - - /** A class representing `range_expression` nodes. */ - class RangeExpression extends @swift_range_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RangeExpression" } - - /** Gets the node corresponding to the field `end`. */ - final Expression getEnd() { swift_range_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `op`. */ - final string getOp() { - exists(int value | swift_range_expression_def(this, _, value, _) | - result = "..." and value = 0 - or - result = "..<" and value = 1 - ) - } - - /** Gets the node corresponding to the field `start`. */ - final Expression getStart() { swift_range_expression_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_range_expression_def(this, result, _, _) or - swift_range_expression_def(this, _, _, result) - } - } - - /** A class representing `raw_str_continuing_indicator` tokens. */ - class RawStrContinuingIndicator extends @swift_token_raw_str_continuing_indicator, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RawStrContinuingIndicator" } - } - - /** A class representing `raw_str_end_part` tokens. */ - class RawStrEndPart extends @swift_token_raw_str_end_part, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RawStrEndPart" } - } - - /** A class representing `raw_str_interpolation` nodes. */ - class RawStrInterpolation extends @swift_raw_str_interpolation, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RawStrInterpolation" } - - /** Gets the node corresponding to the field `interpolation`. */ - final InterpolatedExpression getInterpolation(int i) { - swift_raw_str_interpolation_interpolation(this, i, result) - } - - /** Gets the child of this node. */ - final RawStrInterpolationStart getChild() { swift_raw_str_interpolation_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_raw_str_interpolation_interpolation(this, _, result) or - swift_raw_str_interpolation_def(this, result) - } - } - - /** A class representing `raw_str_interpolation_start` tokens. */ - class RawStrInterpolationStart extends @swift_token_raw_str_interpolation_start, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RawStrInterpolationStart" } - } - - /** A class representing `raw_str_part` tokens. */ - class RawStrPart extends @swift_token_raw_str_part, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RawStrPart" } - } - - /** A class representing `raw_string_literal` nodes. */ - class RawStringLiteral extends @swift_raw_string_literal, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RawStringLiteral" } - - /** Gets the node corresponding to the field `interpolation`. */ - final RawStrInterpolation getInterpolation(int i) { - swift_raw_string_literal_interpolation(this, i, result) - } - - /** Gets the node corresponding to the field `text`. */ - final AstNode getText(int i) { swift_raw_string_literal_text(this, i, result) } - - /** Gets the `i`th child of this node. */ - final RawStrContinuingIndicator getChild(int i) { - swift_raw_string_literal_child(this, i, result) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_raw_string_literal_interpolation(this, _, result) or - swift_raw_string_literal_text(this, _, result) or - swift_raw_string_literal_child(this, _, result) - } - } - - /** A class representing `real_literal` tokens. */ - class RealLiteral extends @swift_token_real_literal, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RealLiteral" } - } - - /** A class representing `referenceable_operator` nodes. */ - class ReferenceableOperator extends @swift_referenceable_operator, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ReferenceableOperator" } - - /** Gets the child of this node. */ - final AstNode getChild() { swift_referenceable_operator_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_referenceable_operator_child(this, result) } - } - - /** A class representing `regex_literal` tokens. */ - class RegexLiteral extends @swift_token_regex_literal, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RegexLiteral" } - } - - /** A class representing `repeat_while_statement` nodes. */ - class RepeatWhileStatement extends @swift_repeat_while_statement, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RepeatWhileStatement" } - - /** Gets the node corresponding to the field `condition`. */ - final IfCondition getCondition(int i) { - swift_repeat_while_statement_condition(this, i, result) - } - - /** Gets the child of this node. */ - final Statements getChild() { swift_repeat_while_statement_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_repeat_while_statement_condition(this, _, result) or - swift_repeat_while_statement_child(this, result) - } - } - - /** A class representing `selector_expression` nodes. */ - class SelectorExpression extends @swift_selector_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SelectorExpression" } - - /** Gets the child of this node. */ - final Expression getChild() { swift_selector_expression_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_selector_expression_def(this, result) } - } - - /** A class representing `self_expression` tokens. */ - class SelfExpression extends @swift_token_self_expression, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SelfExpression" } - } - - /** A class representing `setter_specifier` nodes. */ - class SetterSpecifier extends @swift_setter_specifier, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SetterSpecifier" } - - /** Gets the child of this node. */ - final MutationModifier getChild() { swift_setter_specifier_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_setter_specifier_child(this, result) } - } - - /** A class representing `shebang_line` tokens. */ - class ShebangLine extends @swift_token_shebang_line, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ShebangLine" } - } - - /** A class representing `simple_identifier` tokens. */ - class SimpleIdentifier extends @swift_token_simple_identifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SimpleIdentifier" } - } - - /** A class representing `source_file` nodes. */ - class SourceFile extends @swift_source_file, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SourceFile" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_source_file_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_source_file_child(this, _, result) } - } - - /** A class representing `special_literal` tokens. */ - class SpecialLiteral extends @swift_token_special_literal, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SpecialLiteral" } - } - - /** A class representing `statement_label` tokens. */ - class StatementLabel extends @swift_token_statement_label, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "StatementLabel" } - } - - /** A class representing `statements` nodes. */ - class Statements extends @swift_statements, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Statements" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_statements_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_statements_child(this, _, result) } - } - - /** A class representing `str_escaped_char` tokens. */ - class StrEscapedChar extends @swift_token_str_escaped_char, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "StrEscapedChar" } - } - - /** A class representing `subscript_declaration` nodes. */ - class SubscriptDeclaration extends @swift_subscript_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SubscriptDeclaration" } - - /** Gets the node corresponding to the field `default_value`. */ - final Expression getDefaultValue(int i) { - swift_subscript_declaration_default_value(this, i, result) - } - - /** Gets the node corresponding to the field `return_type`. */ - final AstNode getReturnType() { swift_subscript_declaration_return_type(this, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_subscript_declaration_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_subscript_declaration_default_value(this, _, result) or - swift_subscript_declaration_return_type(this, result) or - swift_subscript_declaration_child(this, _, result) - } - } - - /** A class representing `super_expression` tokens. */ - class SuperExpression extends @swift_token_super_expression, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SuperExpression" } - } - - /** A class representing `suppressed_constraint` nodes. */ - class SuppressedConstraint extends @swift_suppressed_constraint, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SuppressedConstraint" } - - /** Gets the node corresponding to the field `suppressed`. */ - final TypeIdentifier getSuppressed() { swift_suppressed_constraint_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_suppressed_constraint_def(this, result) } - } - - /** A class representing `switch_entry` nodes. */ - class SwitchEntry extends @swift_switch_entry, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SwitchEntry" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_switch_entry_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_switch_entry_child(this, _, result) } - } - - /** A class representing `switch_pattern` nodes. */ - class SwitchPattern extends @swift_switch_pattern, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SwitchPattern" } - - /** Gets the child of this node. */ - final Pattern getChild() { swift_switch_pattern_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_switch_pattern_def(this, result) } - } - - /** A class representing `switch_statement` nodes. */ - class SwitchStatement extends @swift_switch_statement, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SwitchStatement" } - - /** Gets the node corresponding to the field `expr`. */ - final Expression getExpr() { swift_switch_statement_def(this, result) } - - /** Gets the `i`th child of this node. */ - final SwitchEntry getChild(int i) { swift_switch_statement_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_switch_statement_def(this, result) or swift_switch_statement_child(this, _, result) - } - } - - /** A class representing `ternary_expression` nodes. */ - class TernaryExpression extends @swift_ternary_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TernaryExpression" } - - /** Gets the node corresponding to the field `condition`. */ - final Expression getCondition() { swift_ternary_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `if_false`. */ - final Expression getIfFalse() { swift_ternary_expression_def(this, _, result, _) } - - /** Gets the node corresponding to the field `if_true`. */ - final Expression getIfTrue() { swift_ternary_expression_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_ternary_expression_def(this, result, _, _) or - swift_ternary_expression_def(this, _, result, _) or - swift_ternary_expression_def(this, _, _, result) - } - } - - /** A class representing `throw_keyword` tokens. */ - class ThrowKeyword extends @swift_token_throw_keyword, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ThrowKeyword" } - } - - /** A class representing `throws` tokens. */ - class Throws extends @swift_token_throws, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Throws" } - } - - /** A class representing `throws_clause` nodes. */ - class ThrowsClause extends @swift_throws_clause, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ThrowsClause" } - - /** Gets the node corresponding to the field `type`. */ - final UnannotatedType getType() { swift_throws_clause_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_throws_clause_def(this, result) } - } - - /** A class representing `try_expression` nodes. */ - class TryExpression extends @swift_try_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TryExpression" } - - /** Gets the node corresponding to the field `expr`. */ - final Expression getExpr() { swift_try_expression_def(this, result, _) } - - /** Gets the child of this node. */ - final TryOperator getChild() { swift_try_expression_def(this, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_try_expression_def(this, result, _) or swift_try_expression_def(this, _, result) - } - } - - /** A class representing `try_operator` tokens. */ - class TryOperator extends @swift_token_try_operator, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TryOperator" } - } - - /** A class representing `tuple_expression` nodes. */ - class TupleExpression extends @swift_tuple_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TupleExpression" } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName(int i) { swift_tuple_expression_name(this, i, result) } - - /** Gets the node corresponding to the field `value`. */ - final Expression getValue(int i) { swift_tuple_expression_value(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_tuple_expression_name(this, _, result) or swift_tuple_expression_value(this, _, result) - } - } - - /** A class representing `tuple_type` nodes. */ - class TupleType extends @swift_tuple_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TupleType" } - - /** Gets the node corresponding to the field `element`. */ - final TupleTypeItem getElement(int i) { swift_tuple_type_element(this, i, result) } - - /** Gets the child of this node. */ - final TupleTypeItem getChild() { swift_tuple_type_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_tuple_type_element(this, _, result) or swift_tuple_type_child(this, result) - } - } - - /** A class representing `tuple_type_item` nodes. */ - class TupleTypeItem extends @swift_tuple_type_item, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TupleTypeItem" } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName() { swift_tuple_type_item_name(this, result) } - - /** Gets the node corresponding to the field `type`. */ - final Type getType() { swift_tuple_type_item_type(this, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_tuple_type_item_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_tuple_type_item_name(this, result) or - swift_tuple_type_item_type(this, result) or - swift_tuple_type_item_child(this, _, result) - } - } - - /** A class representing `type` nodes. */ - class Type extends @swift_type__, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Type" } - - /** Gets the node corresponding to the field `modifiers`. */ - final TypeModifiers getModifiers() { swift_type_modifiers(this, result) } - - /** Gets the node corresponding to the field `name`. */ - final UnannotatedType getName() { swift_type_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_type_modifiers(this, result) or swift_type_def(this, result) - } - } - - /** A class representing `type_annotation` nodes. */ - class TypeAnnotation extends @swift_type_annotation, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeAnnotation" } - - /** Gets the node corresponding to the field `type`. */ - final AstNode getType() { swift_type_annotation_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_annotation_def(this, result) } - } - - /** A class representing `type_arguments` nodes. */ - class TypeArguments extends @swift_type_arguments, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeArguments" } - - /** Gets the `i`th child of this node. */ - final Type getChild(int i) { swift_type_arguments_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_arguments_child(this, _, result) } - } - - /** A class representing `type_constraint` nodes. */ - class TypeConstraint extends @swift_type_constraint, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeConstraint" } - - /** Gets the child of this node. */ - final AstNode getChild() { swift_type_constraint_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_constraint_def(this, result) } - } - - /** A class representing `type_constraints` nodes. */ - class TypeConstraints extends @swift_type_constraints, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeConstraints" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_type_constraints_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_constraints_child(this, _, result) } - } - - /** A class representing `type_identifier` tokens. */ - class TypeIdentifier extends @swift_token_type_identifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeIdentifier" } - } - - class TypeLevelDeclaration extends @swift_type_level_declaration, AstNode { } - - /** A class representing `type_modifiers` nodes. */ - class TypeModifiers extends @swift_type_modifiers, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeModifiers" } - - /** Gets the `i`th child of this node. */ - final Attribute getChild(int i) { swift_type_modifiers_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_modifiers_child(this, _, result) } - } - - /** A class representing `type_pack_expansion` nodes. */ - class TypePackExpansion extends @swift_type_pack_expansion, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypePackExpansion" } - - /** Gets the child of this node. */ - final UnannotatedType getChild() { swift_type_pack_expansion_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_pack_expansion_def(this, result) } - } - - /** A class representing `type_parameter` nodes. */ - class TypeParameter extends @swift_type_parameter, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeParameter" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_type_parameter_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_parameter_child(this, _, result) } - } - - /** A class representing `type_parameter_modifiers` nodes. */ - class TypeParameterModifiers extends @swift_type_parameter_modifiers, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeParameterModifiers" } - - /** Gets the `i`th child of this node. */ - final Attribute getChild(int i) { swift_type_parameter_modifiers_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_type_parameter_modifiers_child(this, _, result) - } - } - - /** A class representing `type_parameter_pack` nodes. */ - class TypeParameterPack extends @swift_type_parameter_pack, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeParameterPack" } - - /** Gets the child of this node. */ - final UnannotatedType getChild() { swift_type_parameter_pack_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_parameter_pack_def(this, result) } - } - - /** A class representing `type_parameters` nodes. */ - class TypeParameters extends @swift_type_parameters, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeParameters" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_type_parameters_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_parameters_child(this, _, result) } - } - - /** A class representing `typealias_declaration` nodes. */ - class TypealiasDeclaration extends @swift_typealias_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypealiasDeclaration" } - - /** Gets the node corresponding to the field `name`. */ - final TypeIdentifier getName() { swift_typealias_declaration_def(this, result, _) } - - /** Gets the node corresponding to the field `value`. */ - final Type getValue() { swift_typealias_declaration_def(this, _, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_typealias_declaration_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_typealias_declaration_def(this, result, _) or - swift_typealias_declaration_def(this, _, result) or - swift_typealias_declaration_child(this, _, result) - } - } - - class UnannotatedType extends @swift_unannotated_type, AstNode { } - - /** A class representing `user_type` nodes. */ - class UserType extends @swift_user_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "UserType" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_user_type_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_user_type_child(this, _, result) } - } - - /** A class representing `value_argument` nodes. */ - class ValueArgument extends @swift_value_argument, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ValueArgument" } - - /** Gets the node corresponding to the field `name`. */ - final ValueArgumentLabel getName() { swift_value_argument_name(this, result) } - - /** Gets the node corresponding to the field `reference_specifier`. */ - final ValueArgumentLabel getReferenceSpecifier(int i) { - swift_value_argument_reference_specifier(this, i, result) - } - - /** Gets the node corresponding to the field `value`. */ - final Expression getValue() { swift_value_argument_value(this, result) } - - /** Gets the child of this node. */ - final TypeModifiers getChild() { swift_value_argument_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_value_argument_name(this, result) or - swift_value_argument_reference_specifier(this, _, result) or - swift_value_argument_value(this, result) or - swift_value_argument_child(this, result) - } - } - - /** A class representing `value_argument_label` nodes. */ - class ValueArgumentLabel extends @swift_value_argument_label, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ValueArgumentLabel" } - - /** Gets the child of this node. */ - final SimpleIdentifier getChild() { swift_value_argument_label_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_value_argument_label_def(this, result) } - } - - /** A class representing `value_arguments` nodes. */ - class ValueArguments extends @swift_value_arguments, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ValueArguments" } - - /** Gets the `i`th child of this node. */ - final ValueArgument getChild(int i) { swift_value_arguments_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_value_arguments_child(this, _, result) } - } - - /** A class representing `value_binding_pattern` nodes. */ - class ValueBindingPattern extends @swift_value_binding_pattern, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ValueBindingPattern" } - - /** Gets the node corresponding to the field `mutability`. */ - final string getMutability() { - exists(int value | swift_value_binding_pattern_def(this, value) | - result = "let" and value = 0 - or - result = "var" and value = 1 - ) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { none() } - } - - /** A class representing `value_pack_expansion` nodes. */ - class ValuePackExpansion extends @swift_value_pack_expansion, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ValuePackExpansion" } - - /** Gets the child of this node. */ - final Expression getChild() { swift_value_pack_expansion_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_value_pack_expansion_def(this, result) } - } - - /** A class representing `value_parameter_pack` nodes. */ - class ValueParameterPack extends @swift_value_parameter_pack, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ValueParameterPack" } - - /** Gets the child of this node. */ - final Expression getChild() { swift_value_parameter_pack_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_value_parameter_pack_def(this, result) } - } - - /** A class representing `visibility_modifier` tokens. */ - class VisibilityModifier extends @swift_token_visibility_modifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "VisibilityModifier" } - } - - /** A class representing `where_clause` nodes. */ - class WhereClause extends @swift_where_clause, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "WhereClause" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_where_clause_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_where_clause_child(this, _, result) } - } - - /** A class representing `where_keyword` tokens. */ - class WhereKeyword extends @swift_token_where_keyword, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "WhereKeyword" } - } - - /** A class representing `while_statement` nodes. */ - class WhileStatement extends @swift_while_statement, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "WhileStatement" } - - /** Gets the node corresponding to the field `condition`. */ - final IfCondition getCondition(int i) { swift_while_statement_condition(this, i, result) } - - /** Gets the child of this node. */ - final Statements getChild() { swift_while_statement_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_while_statement_condition(this, _, result) or swift_while_statement_child(this, result) - } - } - - /** A class representing `wildcard_pattern` tokens. */ - class WildcardPattern extends @swift_token_wildcard_pattern, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "WildcardPattern" } - } - - /** A class representing `willset_clause` nodes. */ - class WillsetClause extends @swift_willset_clause, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "WillsetClause" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_willset_clause_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_willset_clause_child(this, _, result) } - } - - /** A class representing `willset_didset_block` nodes. */ - class WillsetDidsetBlock extends @swift_willset_didset_block, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "WillsetDidsetBlock" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_willset_didset_block_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_willset_didset_block_child(this, _, result) } } } diff --git a/unified/ql/lib/unified.dbscheme b/unified/ql/lib/unified.dbscheme index b50bc56eaa2a..28718d794236 100644 --- a/unified/ql/lib/unified.dbscheme +++ b/unified/ql/lib/unified.dbscheme @@ -1,4 +1,4 @@ -// CodeQL database schema for Swift +// CodeQL database schema for Unified // Automatically generated from the tree-sitter grammar; do not edit // To regenerate, run unified/scripts/create-extractor-pack.sh @@ -131,2003 +131,220 @@ overlayChangedFiles( string path: string ref ); -/*- Swift dbscheme -*/ -case @swift_additive_expression.op of - 0 = @swift_additive_expression_plus -| 1 = @swift_additive_expression_minus -; - - -swift_additive_expression_def( - unique int id: @swift_additive_expression, - int lhs: @swift_expression ref, - int op: int ref, - int rhs: @swift_expression ref -); - -#keyset[swift_array_literal, index] -swift_array_literal_element( - int swift_array_literal: @swift_array_literal ref, - int index: int ref, - unique int element: @swift_expression ref -); - -swift_array_literal_def( - unique int id: @swift_array_literal -); - -swift_array_type_def( - unique int id: @swift_array_type, - int element: @swift_type__ ref -); - -swift_as_expression_def( - unique int id: @swift_as_expression, - int expr: @swift_expression ref, - int type__: @swift_type__ ref, - int child: @swift_token_as_operator ref -); - -case @swift_assignment.operator of - 0 = @swift_assignment_percentequal -| 1 = @swift_assignment_starequal -| 2 = @swift_assignment_plusequal -| 3 = @swift_assignment_minusequal -| 4 = @swift_assignment_slashequal -| 5 = @swift_assignment_equal -; - - -swift_assignment_def( - unique int id: @swift_assignment, - int operator: int ref, - int result: @swift_expression ref, - int target: @swift_directly_assignable_expression ref -); - -swift_associatedtype_declaration_default_value( - unique int swift_associatedtype_declaration: @swift_associatedtype_declaration ref, - unique int default_value: @swift_type__ ref -); - -swift_associatedtype_declaration_must_inherit( - unique int swift_associatedtype_declaration: @swift_associatedtype_declaration ref, - unique int must_inherit: @swift_type__ ref -); - -@swift_associatedtype_declaration_child_type = @swift_modifiers | @swift_type_constraints - -#keyset[swift_associatedtype_declaration, index] -swift_associatedtype_declaration_child( - int swift_associatedtype_declaration: @swift_associatedtype_declaration ref, - int index: int ref, - unique int child: @swift_associatedtype_declaration_child_type ref -); - -swift_associatedtype_declaration_def( - unique int id: @swift_associatedtype_declaration, - int name: @swift_token_type_identifier ref -); - -@swift_attribute_child_type = @swift_expression | @swift_user_type - -#keyset[swift_attribute, index] -swift_attribute_child( - int swift_attribute: @swift_attribute ref, - int index: int ref, - unique int child: @swift_attribute_child_type ref -); - -swift_attribute_def( - unique int id: @swift_attribute -); - -@swift_availability_condition_child_type = @swift_identifier | @swift_token_integer_literal - -#keyset[swift_availability_condition, index] -swift_availability_condition_child( - int swift_availability_condition: @swift_availability_condition ref, - int index: int ref, - unique int child: @swift_availability_condition_child_type ref -); - -swift_availability_condition_def( - unique int id: @swift_availability_condition -); - -swift_await_expression_expr( - unique int swift_await_expression: @swift_await_expression ref, - unique int expr: @swift_expression ref -); - -swift_await_expression_child( - unique int swift_await_expression: @swift_await_expression ref, - unique int child: @swift_expression ref -); - -swift_await_expression_def( - unique int id: @swift_await_expression -); - -case @swift_bitwise_operation.op of - 0 = @swift_bitwise_operation_ampersand -| 1 = @swift_bitwise_operation_langlelangle -| 2 = @swift_bitwise_operation_ranglerangle -| 3 = @swift_bitwise_operation_caret -| 4 = @swift_bitwise_operation_pipe -; - - -swift_bitwise_operation_def( - unique int id: @swift_bitwise_operation, - int lhs: @swift_expression ref, - int op: int ref, - int rhs: @swift_expression ref -); - -@swift_call_expression_child_type = @swift_call_suffix | @swift_expression - -#keyset[swift_call_expression, index] -swift_call_expression_child( - int swift_call_expression: @swift_call_expression ref, - int index: int ref, - unique int child: @swift_call_expression_child_type ref -); - -swift_call_expression_def( - unique int id: @swift_call_expression -); - -#keyset[swift_call_suffix, index] -swift_call_suffix_name( - int swift_call_suffix: @swift_call_suffix ref, - int index: int ref, - unique int name: @swift_token_simple_identifier ref -); - -@swift_call_suffix_child_type = @swift_lambda_literal | @swift_value_arguments - -#keyset[swift_call_suffix, index] -swift_call_suffix_child( - int swift_call_suffix: @swift_call_suffix ref, - int index: int ref, - unique int child: @swift_call_suffix_child_type ref -); - -swift_call_suffix_def( - unique int id: @swift_call_suffix -); - -#keyset[swift_capture_list, index] -swift_capture_list_child( - int swift_capture_list: @swift_capture_list ref, - int index: int ref, - unique int child: @swift_capture_list_item ref -); - -swift_capture_list_def( - unique int id: @swift_capture_list -); - -@swift_capture_list_item_name_type = @swift_token_self_expression | @swift_token_simple_identifier - -swift_capture_list_item_value( - unique int swift_capture_list_item: @swift_capture_list_item ref, - unique int value: @swift_expression ref -); - -swift_capture_list_item_child( - unique int swift_capture_list_item: @swift_capture_list_item ref, - unique int child: @swift_token_ownership_modifier ref -); - -swift_capture_list_item_def( - unique int id: @swift_capture_list_item, - int name: @swift_capture_list_item_name_type ref -); - -swift_catch_block_error( - unique int swift_catch_block: @swift_catch_block ref, - unique int error: @swift_pattern ref -); - -@swift_catch_block_child_type = @swift_statements | @swift_token_catch_keyword | @swift_where_clause - -#keyset[swift_catch_block, index] -swift_catch_block_child( - int swift_catch_block: @swift_catch_block ref, - int index: int ref, - unique int child: @swift_catch_block_child_type ref -); - -swift_catch_block_def( - unique int id: @swift_catch_block -); - -case @swift_check_expression.op of - 0 = @swift_check_expression_is -; - - -swift_check_expression_def( - unique int id: @swift_check_expression, - int op: int ref, - int target: @swift_expression ref, - int type__: @swift_type__ ref -); - -@swift_class_body_child_type = @swift_token_multiline_comment | @swift_type_level_declaration - -#keyset[swift_class_body, index] -swift_class_body_child( - int swift_class_body: @swift_class_body ref, - int index: int ref, - unique int child: @swift_class_body_child_type ref -); - -swift_class_body_def( - unique int id: @swift_class_body -); - -@swift_class_declaration_body_type = @swift_class_body | @swift_enum_class_body - -case @swift_class_declaration.declaration_kind of - 0 = @swift_class_declaration_actor -| 1 = @swift_class_declaration_class -| 2 = @swift_class_declaration_enum -| 3 = @swift_class_declaration_extension -| 4 = @swift_class_declaration_struct -; - - -@swift_class_declaration_name_type = @swift_token_type_identifier | @swift_unannotated_type - -@swift_class_declaration_child_type = @swift_attribute | @swift_inheritance_specifier | @swift_modifiers | @swift_token_inheritance_modifier | @swift_token_ownership_modifier | @swift_token_property_behavior_modifier | @swift_type_constraints | @swift_type_parameters - -#keyset[swift_class_declaration, index] -swift_class_declaration_child( - int swift_class_declaration: @swift_class_declaration ref, - int index: int ref, - unique int child: @swift_class_declaration_child_type ref -); - -swift_class_declaration_def( - unique int id: @swift_class_declaration, - int body: @swift_class_declaration_body_type ref, - int declaration_kind: int ref, - int name: @swift_class_declaration_name_type ref -); - -case @swift_comparison_expression.op of - 0 = @swift_comparison_expression_langle -| 1 = @swift_comparison_expression_langleequal -| 2 = @swift_comparison_expression_rangle -| 3 = @swift_comparison_expression_rangleequal -; - - -swift_comparison_expression_def( - unique int id: @swift_comparison_expression, - int lhs: @swift_expression ref, - int op: int ref, - int rhs: @swift_expression ref -); - -@swift_computed_getter_child_type = @swift_attribute | @swift_getter_specifier | @swift_statements - -#keyset[swift_computed_getter, index] -swift_computed_getter_child( - int swift_computed_getter: @swift_computed_getter ref, - int index: int ref, - unique int child: @swift_computed_getter_child_type ref -); - -swift_computed_getter_def( - unique int id: @swift_computed_getter -); - -@swift_computed_modify_child_type = @swift_attribute | @swift_modify_specifier | @swift_statements - -#keyset[swift_computed_modify, index] -swift_computed_modify_child( - int swift_computed_modify: @swift_computed_modify ref, - int index: int ref, - unique int child: @swift_computed_modify_child_type ref -); - -swift_computed_modify_def( - unique int id: @swift_computed_modify -); - -@swift_computed_property_child_type = @swift_computed_getter | @swift_computed_modify | @swift_computed_setter | @swift_statements - -#keyset[swift_computed_property, index] -swift_computed_property_child( - int swift_computed_property: @swift_computed_property ref, - int index: int ref, - unique int child: @swift_computed_property_child_type ref -); - -swift_computed_property_def( - unique int id: @swift_computed_property -); - -@swift_computed_setter_child_type = @swift_attribute | @swift_setter_specifier | @swift_statements | @swift_token_simple_identifier - -#keyset[swift_computed_setter, index] -swift_computed_setter_child( - int swift_computed_setter: @swift_computed_setter ref, - int index: int ref, - unique int child: @swift_computed_setter_child_type ref -); - -swift_computed_setter_def( - unique int id: @swift_computed_setter -); - -case @swift_conjunction_expression.op of - 0 = @swift_conjunction_expression_ampersandampersand -; - - -swift_conjunction_expression_def( - unique int id: @swift_conjunction_expression, - int lhs: @swift_expression ref, - int op: int ref, - int rhs: @swift_expression ref -); - -@swift_constructor_expression_constructed_type_type = @swift_array_type | @swift_dictionary_type | @swift_user_type - -swift_constructor_expression_def( - unique int id: @swift_constructor_expression, - int constructed_type: @swift_constructor_expression_constructed_type_type ref, - int child: @swift_constructor_suffix ref -); - -#keyset[swift_constructor_suffix, index] -swift_constructor_suffix_name( - int swift_constructor_suffix: @swift_constructor_suffix ref, - int index: int ref, - unique int name: @swift_token_simple_identifier ref -); - -@swift_constructor_suffix_child_type = @swift_lambda_literal | @swift_value_arguments - -#keyset[swift_constructor_suffix, index] -swift_constructor_suffix_child( - int swift_constructor_suffix: @swift_constructor_suffix ref, - int index: int ref, - unique int child: @swift_constructor_suffix_child_type ref -); - -swift_constructor_suffix_def( - unique int id: @swift_constructor_suffix -); - -swift_control_transfer_statement_result( - unique int swift_control_transfer_statement: @swift_control_transfer_statement ref, - unique int result: @swift_expression ref -); - -@swift_control_transfer_statement_child_type = @swift_expression | @swift_token_throw_keyword - -#keyset[swift_control_transfer_statement, index] -swift_control_transfer_statement_child( - int swift_control_transfer_statement: @swift_control_transfer_statement ref, - int index: int ref, - unique int child: @swift_control_transfer_statement_child_type ref -); - -swift_control_transfer_statement_def( - unique int id: @swift_control_transfer_statement -); - -swift_deinit_declaration_child( - unique int swift_deinit_declaration: @swift_deinit_declaration ref, - unique int child: @swift_modifiers ref -); - -swift_deinit_declaration_def( - unique int id: @swift_deinit_declaration, - int body: @swift_function_body ref -); - -@swift_deprecated_operator_declaration_body_child_type = @swift_line_string_literal | @swift_multi_line_string_literal | @swift_raw_string_literal | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_hex_literal | @swift_token_integer_literal | @swift_token_oct_literal | @swift_token_real_literal | @swift_token_regex_literal | @swift_token_simple_identifier - -#keyset[swift_deprecated_operator_declaration_body, index] -swift_deprecated_operator_declaration_body_child( - int swift_deprecated_operator_declaration_body: @swift_deprecated_operator_declaration_body ref, - int index: int ref, - unique int child: @swift_deprecated_operator_declaration_body_child_type ref -); - -swift_deprecated_operator_declaration_body_def( - unique int id: @swift_deprecated_operator_declaration_body -); - -#keyset[swift_dictionary_literal, index] -swift_dictionary_literal_key( - int swift_dictionary_literal: @swift_dictionary_literal ref, - int index: int ref, - unique int key__: @swift_expression ref -); - -#keyset[swift_dictionary_literal, index] -swift_dictionary_literal_value( - int swift_dictionary_literal: @swift_dictionary_literal ref, - int index: int ref, - unique int value: @swift_expression ref -); - -swift_dictionary_literal_def( - unique int id: @swift_dictionary_literal -); - -swift_dictionary_type_def( - unique int id: @swift_dictionary_type, - int key__: @swift_type__ ref, - int value: @swift_type__ ref -); - -@swift_didset_clause_child_type = @swift_modifiers | @swift_statements | @swift_token_simple_identifier - -#keyset[swift_didset_clause, index] -swift_didset_clause_child( - int swift_didset_clause: @swift_didset_clause ref, - int index: int ref, - unique int child: @swift_didset_clause_child_type ref -); - -swift_didset_clause_def( - unique int id: @swift_didset_clause -); - -@swift_directive_child_type = @swift_token_boolean_literal | @swift_token_integer_literal | @swift_token_simple_identifier - -#keyset[swift_directive, index] -swift_directive_child( - int swift_directive: @swift_directive ref, - int index: int ref, - unique int child: @swift_directive_child_type ref -); - -swift_directive_def( - unique int id: @swift_directive -); - -swift_directly_assignable_expression_def( - unique int id: @swift_directly_assignable_expression, - int child: @swift_expression ref -); - -case @swift_disjunction_expression.op of - 0 = @swift_disjunction_expression_pipepipe -; - - -swift_disjunction_expression_def( - unique int id: @swift_disjunction_expression, - int lhs: @swift_expression ref, - int op: int ref, - int rhs: @swift_expression ref -); - -@swift_do_statement_child_type = @swift_catch_block | @swift_statements - -#keyset[swift_do_statement, index] -swift_do_statement_child( - int swift_do_statement: @swift_do_statement ref, - int index: int ref, - unique int child: @swift_do_statement_child_type ref -); - -swift_do_statement_def( - unique int id: @swift_do_statement -); - -@swift_enum_class_body_child_type = @swift_enum_entry | @swift_type_level_declaration - -#keyset[swift_enum_class_body, index] -swift_enum_class_body_child( - int swift_enum_class_body: @swift_enum_class_body ref, - int index: int ref, - unique int child: @swift_enum_class_body_child_type ref -); - -swift_enum_class_body_def( - unique int id: @swift_enum_class_body -); - -#keyset[swift_enum_entry, index] -swift_enum_entry_data_contents( - int swift_enum_entry: @swift_enum_entry ref, - int index: int ref, - unique int data_contents: @swift_enum_type_parameters ref -); - -#keyset[swift_enum_entry, index] -swift_enum_entry_name( - int swift_enum_entry: @swift_enum_entry ref, - int index: int ref, - unique int name: @swift_token_simple_identifier ref -); - -#keyset[swift_enum_entry, index] -swift_enum_entry_raw_value( - int swift_enum_entry: @swift_enum_entry ref, - int index: int ref, - unique int raw_value: @swift_expression ref -); - -swift_enum_entry_child( - unique int swift_enum_entry: @swift_enum_entry ref, - unique int child: @swift_modifiers ref -); - -swift_enum_entry_def( - unique int id: @swift_enum_entry -); - -@swift_enum_type_parameters_child_type = @swift_expression | @swift_token_wildcard_pattern | @swift_type__ - -#keyset[swift_enum_type_parameters, index] -swift_enum_type_parameters_child( - int swift_enum_type_parameters: @swift_enum_type_parameters ref, - int index: int ref, - unique int child: @swift_enum_type_parameters_child_type ref -); - -swift_enum_type_parameters_def( - unique int id: @swift_enum_type_parameters -); - -@swift_equality_constraint_constrained_type_type = @swift_identifier | @swift_nested_type_identifier - -#keyset[swift_equality_constraint, index] -swift_equality_constraint_child( - int swift_equality_constraint: @swift_equality_constraint ref, - int index: int ref, - unique int child: @swift_attribute ref -); - -swift_equality_constraint_def( - unique int id: @swift_equality_constraint, - int constrained_type: @swift_equality_constraint_constrained_type_type ref, - int must_equal: @swift_type__ ref -); - -case @swift_equality_expression.op of - 0 = @swift_equality_expression_bangequal -| 1 = @swift_equality_expression_bangequalequal -| 2 = @swift_equality_expression_equalequal -| 3 = @swift_equality_expression_equalequalequal -; - - -swift_equality_expression_def( - unique int id: @swift_equality_expression, - int lhs: @swift_expression ref, - int op: int ref, - int rhs: @swift_expression ref -); - -swift_existential_type_def( - unique int id: @swift_existential_type, - int child: @swift_unannotated_type ref -); - -@swift_expression = @swift_additive_expression | @swift_array_literal | @swift_as_expression | @swift_assignment | @swift_await_expression | @swift_bitwise_operation | @swift_call_expression | @swift_check_expression | @swift_comparison_expression | @swift_conjunction_expression | @swift_constructor_expression | @swift_dictionary_literal | @swift_directive | @swift_disjunction_expression | @swift_equality_expression | @swift_if_statement | @swift_infix_expression | @swift_key_path_expression | @swift_key_path_string_expression | @swift_lambda_literal | @swift_line_string_literal | @swift_macro_invocation | @swift_multi_line_string_literal | @swift_multiplicative_expression | @swift_navigation_expression | @swift_nil_coalescing_expression | @swift_open_end_range_expression | @swift_open_start_range_expression | @swift_optional_chain_marker | @swift_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_referenceable_operator | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_diagnostic | @swift_token_fully_open_range | @swift_token_hex_literal | @swift_token_integer_literal | @swift_token_oct_literal | @swift_token_real_literal | @swift_token_regex_literal | @swift_token_self_expression | @swift_token_simple_identifier | @swift_token_special_literal | @swift_token_super_expression | @swift_try_expression | @swift_tuple_expression | @swift_value_pack_expansion | @swift_value_parameter_pack - -swift_external_macro_definition_def( - unique int id: @swift_external_macro_definition, - int child: @swift_value_arguments ref -); - -@swift_for_statement_child_type = @swift_statements | @swift_token_try_operator | @swift_type_annotation | @swift_where_clause - -#keyset[swift_for_statement, index] -swift_for_statement_child( - int swift_for_statement: @swift_for_statement ref, - int index: int ref, - unique int child: @swift_for_statement_child_type ref -); - -swift_for_statement_def( - unique int id: @swift_for_statement, - int collection: @swift_expression ref, - int item: @swift_pattern ref -); - -swift_function_body_child( - unique int swift_function_body: @swift_function_body ref, - unique int child: @swift_statements ref -); - -swift_function_body_def( - unique int id: @swift_function_body -); - -#keyset[swift_function_declaration, index] -swift_function_declaration_default_value( - int swift_function_declaration: @swift_function_declaration ref, - int index: int ref, - unique int default_value: @swift_expression ref -); - -@swift_function_declaration_name_type = @swift_referenceable_operator | @swift_token_simple_identifier - -@swift_function_declaration_return_type_type = @swift_implicitly_unwrapped_type | @swift_type__ - -swift_function_declaration_return_type( - unique int swift_function_declaration: @swift_function_declaration ref, - unique int return_type: @swift_function_declaration_return_type_type ref -); - -@swift_function_declaration_child_type = @swift_attribute | @swift_modifiers | @swift_parameter | @swift_throws_clause | @swift_token_inheritance_modifier | @swift_token_ownership_modifier | @swift_token_property_behavior_modifier | @swift_token_throws | @swift_type_constraints | @swift_type_parameters - -#keyset[swift_function_declaration, index] -swift_function_declaration_child( - int swift_function_declaration: @swift_function_declaration ref, - int index: int ref, - unique int child: @swift_function_declaration_child_type ref -); - -swift_function_declaration_def( - unique int id: @swift_function_declaration, - int body: @swift_function_body ref, - int name: @swift_function_declaration_name_type ref -); - -@swift_function_type_child_type = @swift_throws_clause | @swift_token_throws - -swift_function_type_child( - unique int swift_function_type: @swift_function_type ref, - unique int child: @swift_function_type_child_type ref -); - -swift_function_type_def( - unique int id: @swift_function_type, - int params: @swift_unannotated_type ref, - int return_type: @swift_type__ ref -); - -@swift_getter_specifier_child_type = @swift_throws_clause | @swift_token_mutation_modifier | @swift_token_throws - -#keyset[swift_getter_specifier, index] -swift_getter_specifier_child( - int swift_getter_specifier: @swift_getter_specifier ref, - int index: int ref, - unique int child: @swift_getter_specifier_child_type ref -); - -swift_getter_specifier_def( - unique int id: @swift_getter_specifier -); - -@swift_global_declaration = @swift_associatedtype_declaration | @swift_class_declaration | @swift_function_declaration | @swift_import_declaration | @swift_init_declaration | @swift_macro_declaration | @swift_operator_declaration | @swift_precedence_group_declaration | @swift_property_declaration | @swift_protocol_declaration | @swift_typealias_declaration - -#keyset[swift_guard_statement, index] -swift_guard_statement_condition( - int swift_guard_statement: @swift_guard_statement ref, - int index: int ref, - unique int condition: @swift_if_condition ref -); - -@swift_guard_statement_child_type = @swift_statements | @swift_token_else - -#keyset[swift_guard_statement, index] -swift_guard_statement_child( - int swift_guard_statement: @swift_guard_statement ref, - int index: int ref, - unique int child: @swift_guard_statement_child_type ref -); - -swift_guard_statement_def( - unique int id: @swift_guard_statement -); - -#keyset[swift_identifier, index] -swift_identifier_child( - int swift_identifier: @swift_identifier ref, - int index: int ref, - unique int child: @swift_token_simple_identifier ref -); - -swift_identifier_def( - unique int id: @swift_identifier -); - -@swift_if_condition_child_type = @swift_availability_condition | @swift_expression | @swift_if_let_binding - -swift_if_condition_def( - unique int id: @swift_if_condition, - int child: @swift_if_condition_child_type ref -); - -swift_if_let_binding_bound_identifier( - unique int swift_if_let_binding: @swift_if_let_binding ref, - unique int bound_identifier: @swift_token_simple_identifier ref -); - -@swift_if_let_binding_child_type = @swift_expression | @swift_pattern | @swift_token_wildcard_pattern | @swift_type__ | @swift_type_annotation | @swift_user_type | @swift_value_binding_pattern | @swift_where_clause - -#keyset[swift_if_let_binding, index] -swift_if_let_binding_child( - int swift_if_let_binding: @swift_if_let_binding ref, - int index: int ref, - unique int child: @swift_if_let_binding_child_type ref -); - -swift_if_let_binding_def( - unique int id: @swift_if_let_binding -); - -#keyset[swift_if_statement, index] -swift_if_statement_condition( - int swift_if_statement: @swift_if_statement ref, - int index: int ref, - unique int condition: @swift_if_condition ref -); - -@swift_if_statement_child_type = @swift_if_statement | @swift_statements | @swift_token_else - -#keyset[swift_if_statement, index] -swift_if_statement_child( - int swift_if_statement: @swift_if_statement ref, - int index: int ref, - unique int child: @swift_if_statement_child_type ref -); - -swift_if_statement_def( - unique int id: @swift_if_statement -); - -swift_implicitly_unwrapped_type_def( - unique int id: @swift_implicitly_unwrapped_type, - int child: @swift_type__ ref -); - -@swift_import_declaration_child_type = @swift_identifier | @swift_modifiers - -#keyset[swift_import_declaration, index] -swift_import_declaration_child( - int swift_import_declaration: @swift_import_declaration ref, - int index: int ref, - unique int child: @swift_import_declaration_child_type ref -); - -swift_import_declaration_def( - unique int id: @swift_import_declaration -); - -swift_infix_expression_def( - unique int id: @swift_infix_expression, - int lhs: @swift_expression ref, - int op: @swift_token_custom_operator ref, - int rhs: @swift_expression ref -); - -@swift_inheritance_constraint_constrained_type_type = @swift_identifier | @swift_nested_type_identifier - -@swift_inheritance_constraint_inherits_from_type = @swift_implicitly_unwrapped_type | @swift_type__ - -#keyset[swift_inheritance_constraint, index] -swift_inheritance_constraint_child( - int swift_inheritance_constraint: @swift_inheritance_constraint ref, - int index: int ref, - unique int child: @swift_attribute ref -); - -swift_inheritance_constraint_def( - unique int id: @swift_inheritance_constraint, - int constrained_type: @swift_inheritance_constraint_constrained_type_type ref, - int inherits_from: @swift_inheritance_constraint_inherits_from_type ref -); - -@swift_inheritance_specifier_inherits_from_type = @swift_function_type | @swift_suppressed_constraint | @swift_user_type - -swift_inheritance_specifier_def( - unique int id: @swift_inheritance_specifier, - int inherits_from: @swift_inheritance_specifier_inherits_from_type ref -); - -swift_init_declaration_body( - unique int swift_init_declaration: @swift_init_declaration ref, - unique int body: @swift_function_body ref -); - -#keyset[swift_init_declaration, index] -swift_init_declaration_default_value( - int swift_init_declaration: @swift_init_declaration ref, - int index: int ref, - unique int default_value: @swift_expression ref -); - -case @swift_init_declaration.name of - 0 = @swift_init_declaration_init -; - - -@swift_init_declaration_child_type = @swift_attribute | @swift_modifiers | @swift_parameter | @swift_throws_clause | @swift_token_bang | @swift_token_throws | @swift_type_constraints | @swift_type_parameters - -#keyset[swift_init_declaration, index] -swift_init_declaration_child( - int swift_init_declaration: @swift_init_declaration ref, - int index: int ref, - unique int child: @swift_init_declaration_child_type ref -); - -swift_init_declaration_def( - unique int id: @swift_init_declaration, - int name: int ref -); - -swift_interpolated_expression_name( - unique int swift_interpolated_expression: @swift_interpolated_expression ref, - unique int name: @swift_value_argument_label ref -); - -#keyset[swift_interpolated_expression, index] -swift_interpolated_expression_reference_specifier( - int swift_interpolated_expression: @swift_interpolated_expression ref, - int index: int ref, - unique int reference_specifier: @swift_value_argument_label ref -); - -swift_interpolated_expression_value( - unique int swift_interpolated_expression: @swift_interpolated_expression ref, - unique int value: @swift_expression ref -); - -swift_interpolated_expression_child( - unique int swift_interpolated_expression: @swift_interpolated_expression ref, - unique int child: @swift_type_modifiers ref -); - -swift_interpolated_expression_def( - unique int id: @swift_interpolated_expression -); - -@swift_key_path_expression_child_type = @swift_array_type | @swift_dictionary_type | @swift_token_bang | @swift_token_simple_identifier | @swift_token_type_identifier | @swift_type_arguments | @swift_value_argument - -#keyset[swift_key_path_expression, index] -swift_key_path_expression_child( - int swift_key_path_expression: @swift_key_path_expression ref, - int index: int ref, - unique int child: @swift_key_path_expression_child_type ref -); - -swift_key_path_expression_def( - unique int id: @swift_key_path_expression -); - -swift_key_path_string_expression_def( - unique int id: @swift_key_path_string_expression, - int child: @swift_expression ref -); - -@swift_lambda_function_type_return_type_type = @swift_implicitly_unwrapped_type | @swift_type__ - -swift_lambda_function_type_return_type( - unique int swift_lambda_function_type: @swift_lambda_function_type ref, - unique int return_type: @swift_lambda_function_type_return_type_type ref -); - -@swift_lambda_function_type_child_type = @swift_lambda_function_type_parameters | @swift_throws_clause | @swift_token_throws - -#keyset[swift_lambda_function_type, index] -swift_lambda_function_type_child( - int swift_lambda_function_type: @swift_lambda_function_type ref, - int index: int ref, - unique int child: @swift_lambda_function_type_child_type ref -); - -swift_lambda_function_type_def( - unique int id: @swift_lambda_function_type -); - -#keyset[swift_lambda_function_type_parameters, index] -swift_lambda_function_type_parameters_child( - int swift_lambda_function_type_parameters: @swift_lambda_function_type_parameters ref, - int index: int ref, - unique int child: @swift_lambda_parameter ref -); - -swift_lambda_function_type_parameters_def( - unique int id: @swift_lambda_function_type_parameters -); - -swift_lambda_literal_captures( - unique int swift_lambda_literal: @swift_lambda_literal ref, - unique int captures: @swift_capture_list ref -); - -swift_lambda_literal_type( - unique int swift_lambda_literal: @swift_lambda_literal ref, - unique int type__: @swift_lambda_function_type ref -); - -@swift_lambda_literal_child_type = @swift_attribute | @swift_statements - -#keyset[swift_lambda_literal, index] -swift_lambda_literal_child( - int swift_lambda_literal: @swift_lambda_literal ref, - int index: int ref, - unique int child: @swift_lambda_literal_child_type ref -); - -swift_lambda_literal_def( - unique int id: @swift_lambda_literal -); - -swift_lambda_parameter_external_name( - unique int swift_lambda_parameter: @swift_lambda_parameter ref, - unique int external_name: @swift_token_simple_identifier ref -); - -swift_lambda_parameter_name( - unique int swift_lambda_parameter: @swift_lambda_parameter ref, - unique int name: @swift_token_simple_identifier ref -); - -@swift_lambda_parameter_type_type = @swift_implicitly_unwrapped_type | @swift_type__ - -swift_lambda_parameter_type( - unique int swift_lambda_parameter: @swift_lambda_parameter ref, - unique int type__: @swift_lambda_parameter_type_type ref -); - -@swift_lambda_parameter_child_type = @swift_parameter_modifiers | @swift_token_self_expression - -swift_lambda_parameter_child( - unique int swift_lambda_parameter: @swift_lambda_parameter ref, - unique int child: @swift_lambda_parameter_child_type ref -); - -swift_lambda_parameter_def( - unique int id: @swift_lambda_parameter -); - -#keyset[swift_line_string_literal, index] -swift_line_string_literal_interpolation( - int swift_line_string_literal: @swift_line_string_literal ref, - int index: int ref, - unique int interpolation: @swift_interpolated_expression ref -); - -@swift_line_string_literal_text_type = @swift_token_line_str_text | @swift_token_str_escaped_char - -#keyset[swift_line_string_literal, index] -swift_line_string_literal_text( - int swift_line_string_literal: @swift_line_string_literal ref, - int index: int ref, - unique int text: @swift_line_string_literal_text_type ref -); - -swift_line_string_literal_def( - unique int id: @swift_line_string_literal -); - -@swift_local_declaration = @swift_class_declaration | @swift_function_declaration | @swift_property_declaration | @swift_typealias_declaration - -#keyset[swift_macro_declaration, index] -swift_macro_declaration_default_value( - int swift_macro_declaration: @swift_macro_declaration ref, - int index: int ref, - unique int default_value: @swift_expression ref -); - -swift_macro_declaration_definition( - unique int swift_macro_declaration: @swift_macro_declaration ref, - unique int definition: @swift_macro_definition ref -); - -@swift_macro_declaration_child_type = @swift_attribute | @swift_modifiers | @swift_parameter | @swift_token_simple_identifier | @swift_type_constraints | @swift_type_parameters | @swift_unannotated_type - -#keyset[swift_macro_declaration, index] -swift_macro_declaration_child( - int swift_macro_declaration: @swift_macro_declaration ref, - int index: int ref, - unique int child: @swift_macro_declaration_child_type ref -); - -swift_macro_declaration_def( - unique int id: @swift_macro_declaration -); - -@swift_macro_definition_body_type = @swift_expression | @swift_external_macro_definition - -swift_macro_definition_def( - unique int id: @swift_macro_definition, - int body: @swift_macro_definition_body_type ref -); - -@swift_macro_invocation_child_type = @swift_call_suffix | @swift_token_simple_identifier | @swift_type_parameters - -#keyset[swift_macro_invocation, index] -swift_macro_invocation_child( - int swift_macro_invocation: @swift_macro_invocation ref, - int index: int ref, - unique int child: @swift_macro_invocation_child_type ref -); - -swift_macro_invocation_def( - unique int id: @swift_macro_invocation -); - -swift_metatype_def( - unique int id: @swift_metatype, - int child: @swift_unannotated_type ref -); - -@swift_modifiers_child_type = @swift_attribute | @swift_token_function_modifier | @swift_token_inheritance_modifier | @swift_token_member_modifier | @swift_token_mutation_modifier | @swift_token_ownership_modifier | @swift_token_parameter_modifier | @swift_token_property_behavior_modifier | @swift_token_property_modifier | @swift_token_visibility_modifier - -#keyset[swift_modifiers, index] -swift_modifiers_child( - int swift_modifiers: @swift_modifiers ref, - int index: int ref, - unique int child: @swift_modifiers_child_type ref -); - -swift_modifiers_def( - unique int id: @swift_modifiers -); - -swift_modify_specifier_child( - unique int swift_modify_specifier: @swift_modify_specifier ref, - unique int child: @swift_token_mutation_modifier ref -); - -swift_modify_specifier_def( - unique int id: @swift_modify_specifier -); - -#keyset[swift_multi_line_string_literal, index] -swift_multi_line_string_literal_interpolation( - int swift_multi_line_string_literal: @swift_multi_line_string_literal ref, - int index: int ref, - unique int interpolation: @swift_interpolated_expression ref -); - -@swift_multi_line_string_literal_text_type = @swift_reserved_word | @swift_token_multi_line_str_text | @swift_token_str_escaped_char - -#keyset[swift_multi_line_string_literal, index] -swift_multi_line_string_literal_text( - int swift_multi_line_string_literal: @swift_multi_line_string_literal ref, - int index: int ref, - unique int text: @swift_multi_line_string_literal_text_type ref -); - -swift_multi_line_string_literal_def( - unique int id: @swift_multi_line_string_literal -); - -case @swift_multiplicative_expression.op of - 0 = @swift_multiplicative_expression_percent -| 1 = @swift_multiplicative_expression_star -| 2 = @swift_multiplicative_expression_slash -; - - -swift_multiplicative_expression_def( - unique int id: @swift_multiplicative_expression, - int lhs: @swift_expression ref, - int op: int ref, - int rhs: @swift_expression ref -); - -@swift_navigation_expression_target_type = @swift_array_type | @swift_dictionary_type | @swift_existential_type | @swift_expression | @swift_opaque_type | @swift_reserved_word | @swift_user_type - -#keyset[swift_navigation_expression, index] -swift_navigation_expression_target( - int swift_navigation_expression: @swift_navigation_expression ref, - int index: int ref, - unique int target: @swift_navigation_expression_target_type ref -); - -swift_navigation_expression_def( - unique int id: @swift_navigation_expression, - int suffix: @swift_navigation_suffix ref -); - -@swift_navigation_suffix_suffix_type = @swift_token_integer_literal | @swift_token_simple_identifier - -swift_navigation_suffix_def( - unique int id: @swift_navigation_suffix, - int suffix: @swift_navigation_suffix_suffix_type ref -); - -@swift_nested_type_identifier_child_type = @swift_token_simple_identifier | @swift_unannotated_type - -#keyset[swift_nested_type_identifier, index] -swift_nested_type_identifier_child( - int swift_nested_type_identifier: @swift_nested_type_identifier ref, - int index: int ref, - unique int child: @swift_nested_type_identifier_child_type ref -); - -swift_nested_type_identifier_def( - unique int id: @swift_nested_type_identifier -); - -swift_nil_coalescing_expression_def( - unique int id: @swift_nil_coalescing_expression, - int if_nil: @swift_expression ref, - int value: @swift_expression ref -); - -swift_opaque_type_def( - unique int id: @swift_opaque_type, - int child: @swift_unannotated_type ref -); - -swift_open_end_range_expression_def( - unique int id: @swift_open_end_range_expression, - int start: @swift_expression ref -); - -swift_open_start_range_expression_def( - unique int id: @swift_open_start_range_expression, - int end: @swift_expression ref -); - -@swift_operator_declaration_child_type = @swift_deprecated_operator_declaration_body | @swift_referenceable_operator | @swift_token_simple_identifier - -#keyset[swift_operator_declaration, index] -swift_operator_declaration_child( - int swift_operator_declaration: @swift_operator_declaration ref, - int index: int ref, - unique int child: @swift_operator_declaration_child_type ref -); - -swift_operator_declaration_def( - unique int id: @swift_operator_declaration -); - -swift_optional_chain_marker_def( - unique int id: @swift_optional_chain_marker, - int child: @swift_expression ref -); - -@swift_optional_type_wrapped_type = @swift_array_type | @swift_dictionary_type | @swift_tuple_type | @swift_user_type - -swift_optional_type_def( - unique int id: @swift_optional_type, - int wrapped: @swift_optional_type_wrapped_type ref -); - -swift_parameter_external_name( - unique int swift_parameter: @swift_parameter ref, - unique int external_name: @swift_token_simple_identifier ref -); - -@swift_parameter_type_type = @swift_implicitly_unwrapped_type | @swift_type__ - -swift_parameter_child( - unique int swift_parameter: @swift_parameter ref, - unique int child: @swift_parameter_modifiers ref -); - -swift_parameter_def( - unique int id: @swift_parameter, - int name: @swift_token_simple_identifier ref, - int type__: @swift_parameter_type_type ref -); - -#keyset[swift_parameter_modifiers, index] -swift_parameter_modifiers_child( - int swift_parameter_modifiers: @swift_parameter_modifiers ref, - int index: int ref, - unique int child: @swift_token_parameter_modifier ref -); - -swift_parameter_modifiers_def( - unique int id: @swift_parameter_modifiers -); - -swift_pattern_bound_identifier( - unique int swift_pattern: @swift_pattern ref, - unique int bound_identifier: @swift_token_simple_identifier ref -); - -@swift_pattern_child_type = @swift_expression | @swift_pattern | @swift_token_wildcard_pattern | @swift_type__ | @swift_user_type | @swift_value_binding_pattern - -#keyset[swift_pattern, index] -swift_pattern_child( - int swift_pattern: @swift_pattern ref, - int index: int ref, - unique int child: @swift_pattern_child_type ref -); - -swift_pattern_def( - unique int id: @swift_pattern -); - -#keyset[swift_playground_literal, index] -swift_playground_literal_child( - int swift_playground_literal: @swift_playground_literal ref, - int index: int ref, - unique int child: @swift_expression ref -); - -swift_playground_literal_def( - unique int id: @swift_playground_literal -); - -@swift_postfix_expression_operation_type = @swift_reserved_word | @swift_token_bang - -swift_postfix_expression_def( - unique int id: @swift_postfix_expression, - int operation: @swift_postfix_expression_operation_type ref, - int target: @swift_expression ref -); - -@swift_precedence_group_attribute_child_type = @swift_token_boolean_literal | @swift_token_simple_identifier - -#keyset[swift_precedence_group_attribute, index] -swift_precedence_group_attribute_child( - int swift_precedence_group_attribute: @swift_precedence_group_attribute ref, - int index: int ref, - unique int child: @swift_precedence_group_attribute_child_type ref -); - -swift_precedence_group_attribute_def( - unique int id: @swift_precedence_group_attribute -); - -#keyset[swift_precedence_group_attributes, index] -swift_precedence_group_attributes_child( - int swift_precedence_group_attributes: @swift_precedence_group_attributes ref, - int index: int ref, - unique int child: @swift_precedence_group_attribute ref -); - -swift_precedence_group_attributes_def( - unique int id: @swift_precedence_group_attributes -); - -@swift_precedence_group_declaration_child_type = @swift_precedence_group_attributes | @swift_token_simple_identifier - -#keyset[swift_precedence_group_declaration, index] -swift_precedence_group_declaration_child( - int swift_precedence_group_declaration: @swift_precedence_group_declaration ref, - int index: int ref, - unique int child: @swift_precedence_group_declaration_child_type ref -); - -swift_precedence_group_declaration_def( - unique int id: @swift_precedence_group_declaration -); - -@swift_prefix_expression_operation_type = @swift_reserved_word | @swift_token_bang | @swift_token_custom_operator - -swift_prefix_expression_def( - unique int id: @swift_prefix_expression, - int operation: @swift_prefix_expression_operation_type ref, - int target: @swift_expression ref -); - -#keyset[swift_property_declaration, index] -swift_property_declaration_computed_value( - int swift_property_declaration: @swift_property_declaration ref, - int index: int ref, - unique int computed_value: @swift_computed_property ref -); - -#keyset[swift_property_declaration, index] -swift_property_declaration_name( - int swift_property_declaration: @swift_property_declaration ref, - int index: int ref, - unique int name: @swift_pattern ref -); - -#keyset[swift_property_declaration, index] -swift_property_declaration_value( - int swift_property_declaration: @swift_property_declaration ref, - int index: int ref, - unique int value: @swift_expression ref -); - -@swift_property_declaration_child_type = @swift_attribute | @swift_modifiers | @swift_token_inheritance_modifier | @swift_token_ownership_modifier | @swift_token_property_behavior_modifier | @swift_type_annotation | @swift_type_constraints | @swift_value_binding_pattern | @swift_willset_didset_block - -#keyset[swift_property_declaration, index] -swift_property_declaration_child( - int swift_property_declaration: @swift_property_declaration ref, - int index: int ref, - unique int child: @swift_property_declaration_child_type ref -); - -swift_property_declaration_def( - unique int id: @swift_property_declaration -); - -#keyset[swift_protocol_body, index] -swift_protocol_body_child( - int swift_protocol_body: @swift_protocol_body ref, - int index: int ref, - unique int child: @swift_protocol_member_declaration ref -); - -swift_protocol_body_def( - unique int id: @swift_protocol_body -); - -#keyset[swift_protocol_composition_type, index] -swift_protocol_composition_type_child( - int swift_protocol_composition_type: @swift_protocol_composition_type ref, - int index: int ref, - unique int child: @swift_unannotated_type ref -); - -swift_protocol_composition_type_def( - unique int id: @swift_protocol_composition_type -); - -case @swift_protocol_declaration.declaration_kind of - 0 = @swift_protocol_declaration_protocol -; - - -@swift_protocol_declaration_child_type = @swift_attribute | @swift_inheritance_specifier | @swift_modifiers | @swift_type_constraints | @swift_type_parameters - -#keyset[swift_protocol_declaration, index] -swift_protocol_declaration_child( - int swift_protocol_declaration: @swift_protocol_declaration ref, - int index: int ref, - unique int child: @swift_protocol_declaration_child_type ref -); - -swift_protocol_declaration_def( - unique int id: @swift_protocol_declaration, - int body: @swift_protocol_body ref, - int declaration_kind: int ref, - int name: @swift_token_type_identifier ref -); - -swift_protocol_function_declaration_body( - unique int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, - unique int body: @swift_function_body ref -); - -#keyset[swift_protocol_function_declaration, index] -swift_protocol_function_declaration_default_value( - int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, - int index: int ref, - unique int default_value: @swift_expression ref -); - -@swift_protocol_function_declaration_name_type = @swift_referenceable_operator | @swift_token_simple_identifier - -@swift_protocol_function_declaration_return_type_type = @swift_implicitly_unwrapped_type | @swift_type__ - -swift_protocol_function_declaration_return_type( - unique int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, - unique int return_type: @swift_protocol_function_declaration_return_type_type ref -); - -@swift_protocol_function_declaration_child_type = @swift_attribute | @swift_modifiers | @swift_parameter | @swift_throws_clause | @swift_token_throws | @swift_type_constraints | @swift_type_parameters - -#keyset[swift_protocol_function_declaration, index] -swift_protocol_function_declaration_child( - int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, - int index: int ref, - unique int child: @swift_protocol_function_declaration_child_type ref -); - -swift_protocol_function_declaration_def( - unique int id: @swift_protocol_function_declaration, - int name: @swift_protocol_function_declaration_name_type ref -); - -@swift_protocol_member_declaration = @swift_associatedtype_declaration | @swift_deinit_declaration | @swift_init_declaration | @swift_protocol_function_declaration | @swift_protocol_property_declaration | @swift_subscript_declaration | @swift_typealias_declaration - -@swift_protocol_property_declaration_child_type = @swift_modifiers | @swift_protocol_property_requirements | @swift_type_annotation | @swift_type_constraints - -#keyset[swift_protocol_property_declaration, index] -swift_protocol_property_declaration_child( - int swift_protocol_property_declaration: @swift_protocol_property_declaration ref, - int index: int ref, - unique int child: @swift_protocol_property_declaration_child_type ref -); - -swift_protocol_property_declaration_def( - unique int id: @swift_protocol_property_declaration, - int name: @swift_pattern ref -); - -@swift_protocol_property_requirements_child_type = @swift_getter_specifier | @swift_setter_specifier - -#keyset[swift_protocol_property_requirements, index] -swift_protocol_property_requirements_child( - int swift_protocol_property_requirements: @swift_protocol_property_requirements ref, - int index: int ref, - unique int child: @swift_protocol_property_requirements_child_type ref -); - -swift_protocol_property_requirements_def( - unique int id: @swift_protocol_property_requirements -); - -case @swift_range_expression.op of - 0 = @swift_range_expression_dotdotdot -| 1 = @swift_range_expression_dotdotlangle -; - - -swift_range_expression_def( - unique int id: @swift_range_expression, - int end: @swift_expression ref, - int op: int ref, - int start: @swift_expression ref -); - -#keyset[swift_raw_str_interpolation, index] -swift_raw_str_interpolation_interpolation( - int swift_raw_str_interpolation: @swift_raw_str_interpolation ref, - int index: int ref, - unique int interpolation: @swift_interpolated_expression ref -); - -swift_raw_str_interpolation_def( - unique int id: @swift_raw_str_interpolation, - int child: @swift_token_raw_str_interpolation_start ref -); - -#keyset[swift_raw_string_literal, index] -swift_raw_string_literal_interpolation( - int swift_raw_string_literal: @swift_raw_string_literal ref, - int index: int ref, - unique int interpolation: @swift_raw_str_interpolation ref -); - -@swift_raw_string_literal_text_type = @swift_token_raw_str_end_part | @swift_token_raw_str_part - -#keyset[swift_raw_string_literal, index] -swift_raw_string_literal_text( - int swift_raw_string_literal: @swift_raw_string_literal ref, - int index: int ref, - unique int text: @swift_raw_string_literal_text_type ref -); - -#keyset[swift_raw_string_literal, index] -swift_raw_string_literal_child( - int swift_raw_string_literal: @swift_raw_string_literal ref, - int index: int ref, - unique int child: @swift_token_raw_str_continuing_indicator ref -); - -swift_raw_string_literal_def( - unique int id: @swift_raw_string_literal -); - -@swift_referenceable_operator_child_type = @swift_token_bang | @swift_token_custom_operator - -swift_referenceable_operator_child( - unique int swift_referenceable_operator: @swift_referenceable_operator ref, - unique int child: @swift_referenceable_operator_child_type ref -); - -swift_referenceable_operator_def( - unique int id: @swift_referenceable_operator -); - -#keyset[swift_repeat_while_statement, index] -swift_repeat_while_statement_condition( - int swift_repeat_while_statement: @swift_repeat_while_statement ref, - int index: int ref, - unique int condition: @swift_if_condition ref -); - -swift_repeat_while_statement_child( - unique int swift_repeat_while_statement: @swift_repeat_while_statement ref, - unique int child: @swift_statements ref -); - -swift_repeat_while_statement_def( - unique int id: @swift_repeat_while_statement -); - -swift_selector_expression_def( - unique int id: @swift_selector_expression, - int child: @swift_expression ref -); - -swift_setter_specifier_child( - unique int swift_setter_specifier: @swift_setter_specifier ref, - unique int child: @swift_token_mutation_modifier ref -); - -swift_setter_specifier_def( - unique int id: @swift_setter_specifier -); - -@swift_source_file_child_type = @swift_do_statement | @swift_expression | @swift_for_statement | @swift_global_declaration | @swift_guard_statement | @swift_repeat_while_statement | @swift_token_shebang_line | @swift_token_statement_label | @swift_token_throw_keyword | @swift_while_statement - -#keyset[swift_source_file, index] -swift_source_file_child( - int swift_source_file: @swift_source_file ref, - int index: int ref, - unique int child: @swift_source_file_child_type ref -); - -swift_source_file_def( - unique int id: @swift_source_file -); - -@swift_statements_child_type = @swift_control_transfer_statement | @swift_do_statement | @swift_expression | @swift_for_statement | @swift_guard_statement | @swift_local_declaration | @swift_repeat_while_statement | @swift_token_statement_label | @swift_while_statement - -#keyset[swift_statements, index] -swift_statements_child( - int swift_statements: @swift_statements ref, - int index: int ref, - unique int child: @swift_statements_child_type ref -); - -swift_statements_def( - unique int id: @swift_statements -); - -#keyset[swift_subscript_declaration, index] -swift_subscript_declaration_default_value( - int swift_subscript_declaration: @swift_subscript_declaration ref, - int index: int ref, - unique int default_value: @swift_expression ref -); - -@swift_subscript_declaration_return_type_type = @swift_implicitly_unwrapped_type | @swift_type__ - -swift_subscript_declaration_return_type( - unique int swift_subscript_declaration: @swift_subscript_declaration ref, - unique int return_type: @swift_subscript_declaration_return_type_type ref -); - -@swift_subscript_declaration_child_type = @swift_attribute | @swift_computed_property | @swift_modifiers | @swift_parameter | @swift_type_constraints | @swift_type_parameters - -#keyset[swift_subscript_declaration, index] -swift_subscript_declaration_child( - int swift_subscript_declaration: @swift_subscript_declaration ref, - int index: int ref, - unique int child: @swift_subscript_declaration_child_type ref -); - -swift_subscript_declaration_def( - unique int id: @swift_subscript_declaration -); - -swift_suppressed_constraint_def( - unique int id: @swift_suppressed_constraint, - int suppressed: @swift_token_type_identifier ref -); - -@swift_switch_entry_child_type = @swift_expression | @swift_modifiers | @swift_statements | @swift_switch_pattern | @swift_token_default_keyword | @swift_token_where_keyword - -#keyset[swift_switch_entry, index] -swift_switch_entry_child( - int swift_switch_entry: @swift_switch_entry ref, - int index: int ref, - unique int child: @swift_switch_entry_child_type ref -); - -swift_switch_entry_def( - unique int id: @swift_switch_entry -); - -swift_switch_pattern_def( - unique int id: @swift_switch_pattern, - int child: @swift_pattern ref -); - -#keyset[swift_switch_statement, index] -swift_switch_statement_child( - int swift_switch_statement: @swift_switch_statement ref, - int index: int ref, - unique int child: @swift_switch_entry ref -); - -swift_switch_statement_def( - unique int id: @swift_switch_statement, - int expr: @swift_expression ref -); - -swift_ternary_expression_def( - unique int id: @swift_ternary_expression, - int condition: @swift_expression ref, - int if_false: @swift_expression ref, - int if_true: @swift_expression ref -); - -swift_throws_clause_def( - unique int id: @swift_throws_clause, - int type__: @swift_unannotated_type ref -); - -swift_try_expression_def( - unique int id: @swift_try_expression, - int expr: @swift_expression ref, - int child: @swift_token_try_operator ref -); - -#keyset[swift_tuple_expression, index] -swift_tuple_expression_name( - int swift_tuple_expression: @swift_tuple_expression ref, - int index: int ref, - unique int name: @swift_token_simple_identifier ref -); - -#keyset[swift_tuple_expression, index] -swift_tuple_expression_value( - int swift_tuple_expression: @swift_tuple_expression ref, - int index: int ref, - unique int value: @swift_expression ref -); - -swift_tuple_expression_def( - unique int id: @swift_tuple_expression -); - -#keyset[swift_tuple_type, index] -swift_tuple_type_element( - int swift_tuple_type: @swift_tuple_type ref, - int index: int ref, - unique int element: @swift_tuple_type_item ref -); - -swift_tuple_type_child( - unique int swift_tuple_type: @swift_tuple_type ref, - unique int child: @swift_tuple_type_item ref -); - -swift_tuple_type_def( - unique int id: @swift_tuple_type -); - -swift_tuple_type_item_name( - unique int swift_tuple_type_item: @swift_tuple_type_item ref, - unique int name: @swift_token_simple_identifier ref -); - -swift_tuple_type_item_type( - unique int swift_tuple_type_item: @swift_tuple_type_item ref, - unique int type__: @swift_type__ ref -); - -@swift_tuple_type_item_child_type = @swift_dictionary_type | @swift_existential_type | @swift_opaque_type | @swift_parameter_modifiers | @swift_token_wildcard_pattern - -#keyset[swift_tuple_type_item, index] -swift_tuple_type_item_child( - int swift_tuple_type_item: @swift_tuple_type_item ref, +/*- Unified dbscheme -*/ +#keyset[unified_apply_pattern, index] +unified_apply_pattern_argument( + int unified_apply_pattern: @unified_apply_pattern ref, int index: int ref, - unique int child: @swift_tuple_type_item_child_type ref -); - -swift_tuple_type_item_def( - unique int id: @swift_tuple_type_item + unique int argument: @unified_pattern ref ); -swift_type_modifiers( - unique int swift_type__: @swift_type__ ref, - unique int modifiers: @swift_type_modifiers ref +unified_apply_pattern_def( + unique int id: @unified_apply_pattern, + int constructor: @unified_expr ref ); -swift_type_def( - unique int id: @swift_type__, - int name: @swift_unannotated_type ref +unified_binary_expr_def( + unique int id: @unified_binary_expr, + int left: @unified_expr ref, + int operator: @unified_token_operator ref, + int right: @unified_expr ref ); -@swift_type_annotation_type_type = @swift_implicitly_unwrapped_type | @swift_type__ - -swift_type_annotation_def( - unique int id: @swift_type_annotation, - int type__: @swift_type_annotation_type_type ref -); - -#keyset[swift_type_arguments, index] -swift_type_arguments_child( - int swift_type_arguments: @swift_type_arguments ref, +#keyset[unified_block_stmt, index] +unified_block_stmt_body( + int unified_block_stmt: @unified_block_stmt ref, int index: int ref, - unique int child: @swift_type__ ref -); - -swift_type_arguments_def( - unique int id: @swift_type_arguments + unique int body: @unified_stmt ref ); -@swift_type_constraint_child_type = @swift_equality_constraint | @swift_inheritance_constraint - -swift_type_constraint_def( - unique int id: @swift_type_constraint, - int child: @swift_type_constraint_child_type ref +unified_block_stmt_def( + unique int id: @unified_block_stmt ); -@swift_type_constraints_child_type = @swift_token_where_keyword | @swift_type_constraint - -#keyset[swift_type_constraints, index] -swift_type_constraints_child( - int swift_type_constraints: @swift_type_constraints ref, +#keyset[unified_call_expr, index] +unified_call_expr_argument( + int unified_call_expr: @unified_call_expr ref, int index: int ref, - unique int child: @swift_type_constraints_child_type ref + unique int argument: @unified_expr ref ); -swift_type_constraints_def( - unique int id: @swift_type_constraints +unified_call_expr_def( + unique int id: @unified_call_expr, + int function: @unified_expr ref ); -@swift_type_level_declaration = @swift_associatedtype_declaration | @swift_class_declaration | @swift_deinit_declaration | @swift_function_declaration | @swift_import_declaration | @swift_init_declaration | @swift_operator_declaration | @swift_precedence_group_declaration | @swift_property_declaration | @swift_protocol_declaration | @swift_subscript_declaration | @swift_typealias_declaration - -#keyset[swift_type_modifiers, index] -swift_type_modifiers_child( - int swift_type_modifiers: @swift_type_modifiers ref, - int index: int ref, - unique int child: @swift_attribute ref -); +@unified_condition = @unified_expr_condition | @unified_let_pattern_condition | @unified_sequence_condition | @unified_token_unsupported_node -swift_type_modifiers_def( - unique int id: @swift_type_modifiers -); +@unified_expr = @unified_binary_expr | @unified_call_expr | @unified_lambda_expr | @unified_member_access_expr | @unified_name_expr | @unified_token_int_literal | @unified_token_string_literal | @unified_token_unsupported_node | @unified_unary_expr -swift_type_pack_expansion_def( - unique int id: @swift_type_pack_expansion, - int child: @swift_unannotated_type ref +unified_expr_condition_def( + unique int id: @unified_expr_condition, + int expr: @unified_expr ref ); -@swift_type_parameter_child_type = @swift_token_type_identifier | @swift_type__ | @swift_type_parameter_modifiers | @swift_type_parameter_pack - -#keyset[swift_type_parameter, index] -swift_type_parameter_child( - int swift_type_parameter: @swift_type_parameter ref, - int index: int ref, - unique int child: @swift_type_parameter_child_type ref +unified_expr_stmt_def( + unique int id: @unified_expr_stmt, + int expr: @unified_expr ref ); -swift_type_parameter_def( - unique int id: @swift_type_parameter +unified_guard_if_stmt_def( + unique int id: @unified_guard_if_stmt, + int condition: @unified_condition ref, + int else: @unified_stmt ref ); -#keyset[swift_type_parameter_modifiers, index] -swift_type_parameter_modifiers_child( - int swift_type_parameter_modifiers: @swift_type_parameter_modifiers ref, - int index: int ref, - unique int child: @swift_attribute ref +unified_if_stmt_else( + unique int unified_if_stmt: @unified_if_stmt ref, + unique int else: @unified_stmt ref ); -swift_type_parameter_modifiers_def( - unique int id: @swift_type_parameter_modifiers +unified_if_stmt_then( + unique int unified_if_stmt: @unified_if_stmt ref, + unique int then: @unified_stmt ref ); -swift_type_parameter_pack_def( - unique int id: @swift_type_parameter_pack, - int child: @swift_unannotated_type ref +unified_if_stmt_def( + unique int id: @unified_if_stmt, + int condition: @unified_condition ref ); -@swift_type_parameters_child_type = @swift_type_constraints | @swift_type_parameter +@unified_lambda_expr_body_type = @unified_expr | @unified_stmt -#keyset[swift_type_parameters, index] -swift_type_parameters_child( - int swift_type_parameters: @swift_type_parameters ref, +#keyset[unified_lambda_expr, index] +unified_lambda_expr_parameter( + int unified_lambda_expr: @unified_lambda_expr ref, int index: int ref, - unique int child: @swift_type_parameters_child_type ref + unique int parameter: @unified_parameter ref ); -swift_type_parameters_def( - unique int id: @swift_type_parameters +unified_lambda_expr_def( + unique int id: @unified_lambda_expr, + int body: @unified_lambda_expr_body_type ref ); -@swift_typealias_declaration_child_type = @swift_attribute | @swift_modifiers | @swift_token_inheritance_modifier | @swift_token_ownership_modifier | @swift_token_property_behavior_modifier | @swift_type_parameters - -#keyset[swift_typealias_declaration, index] -swift_typealias_declaration_child( - int swift_typealias_declaration: @swift_typealias_declaration ref, - int index: int ref, - unique int child: @swift_typealias_declaration_child_type ref +unified_let_pattern_condition_def( + unique int id: @unified_let_pattern_condition, + int pattern: @unified_pattern ref, + int value: @unified_expr ref ); -swift_typealias_declaration_def( - unique int id: @swift_typealias_declaration, - int name: @swift_token_type_identifier ref, - int value: @swift_type__ ref +unified_member_access_expr_def( + unique int id: @unified_member_access_expr, + int member: @unified_token_identifier ref, + int target: @unified_expr ref ); -@swift_unannotated_type = @swift_array_type | @swift_dictionary_type | @swift_existential_type | @swift_function_type | @swift_metatype | @swift_opaque_type | @swift_optional_type | @swift_protocol_composition_type | @swift_suppressed_constraint | @swift_tuple_type | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type - -@swift_user_type_child_type = @swift_token_type_identifier | @swift_type_arguments - -#keyset[swift_user_type, index] -swift_user_type_child( - int swift_user_type: @swift_user_type ref, - int index: int ref, - unique int child: @swift_user_type_child_type ref +unified_name_expr_def( + unique int id: @unified_name_expr, + int identifier: @unified_token_identifier ref ); -swift_user_type_def( - unique int id: @swift_user_type +unified_parameter_def( + unique int id: @unified_parameter, + int pattern: @unified_pattern ref ); -swift_value_argument_name( - unique int swift_value_argument: @swift_value_argument ref, - unique int name: @swift_value_argument_label ref -); +@unified_pattern = @unified_apply_pattern | @unified_token_ignore_pattern | @unified_token_unsupported_node | @unified_tuple_pattern | @unified_var_pattern -#keyset[swift_value_argument, index] -swift_value_argument_reference_specifier( - int swift_value_argument: @swift_value_argument ref, +#keyset[unified_sequence_condition, index] +unified_sequence_condition_stmt( + int unified_sequence_condition: @unified_sequence_condition ref, int index: int ref, - unique int reference_specifier: @swift_value_argument_label ref + unique int stmt: @unified_stmt ref ); -swift_value_argument_value( - unique int swift_value_argument: @swift_value_argument ref, - unique int value: @swift_expression ref +unified_sequence_condition_def( + unique int id: @unified_sequence_condition, + int condition: @unified_condition ref ); -swift_value_argument_child( - unique int swift_value_argument: @swift_value_argument ref, - unique int child: @swift_type_modifiers ref -); - -swift_value_argument_def( - unique int id: @swift_value_argument -); +@unified_stmt = @unified_block_stmt | @unified_expr_stmt | @unified_guard_if_stmt | @unified_if_stmt | @unified_token_empty_stmt | @unified_token_unsupported_node | @unified_variable_declaration_stmt -swift_value_argument_label_def( - unique int id: @swift_value_argument_label, - int child: @swift_token_simple_identifier ref -); +@unified_top_level_body_type = @unified_expr | @unified_stmt -#keyset[swift_value_arguments, index] -swift_value_arguments_child( - int swift_value_arguments: @swift_value_arguments ref, +#keyset[unified_top_level, index] +unified_top_level_body( + int unified_top_level: @unified_top_level ref, int index: int ref, - unique int child: @swift_value_argument ref + unique int body: @unified_top_level_body_type ref ); -swift_value_arguments_def( - unique int id: @swift_value_arguments +unified_top_level_def( + unique int id: @unified_top_level ); -case @swift_value_binding_pattern.mutability of - 0 = @swift_value_binding_pattern_let -| 1 = @swift_value_binding_pattern_var -; - - -swift_value_binding_pattern_def( - unique int id: @swift_value_binding_pattern, - int mutability: int ref -); - -swift_value_pack_expansion_def( - unique int id: @swift_value_pack_expansion, - int child: @swift_expression ref -); - -swift_value_parameter_pack_def( - unique int id: @swift_value_parameter_pack, - int child: @swift_expression ref -); - -@swift_where_clause_child_type = @swift_expression | @swift_token_where_keyword - -#keyset[swift_where_clause, index] -swift_where_clause_child( - int swift_where_clause: @swift_where_clause ref, +#keyset[unified_tuple_pattern, index] +unified_tuple_pattern_element( + int unified_tuple_pattern: @unified_tuple_pattern ref, int index: int ref, - unique int child: @swift_where_clause_child_type ref -); - -swift_where_clause_def( - unique int id: @swift_where_clause + unique int element: @unified_pattern ref ); -#keyset[swift_while_statement, index] -swift_while_statement_condition( - int swift_while_statement: @swift_while_statement ref, - int index: int ref, - unique int condition: @swift_if_condition ref +unified_tuple_pattern_def( + unique int id: @unified_tuple_pattern ); -swift_while_statement_child( - unique int swift_while_statement: @swift_while_statement ref, - unique int child: @swift_statements ref +unified_unary_expr_def( + unique int id: @unified_unary_expr, + int operand: @unified_expr ref, + int operator: @unified_token_operator ref ); -swift_while_statement_def( - unique int id: @swift_while_statement +unified_var_pattern_def( + unique int id: @unified_var_pattern, + int identifier: @unified_token_identifier ref ); -@swift_willset_clause_child_type = @swift_modifiers | @swift_statements | @swift_token_simple_identifier - -#keyset[swift_willset_clause, index] -swift_willset_clause_child( - int swift_willset_clause: @swift_willset_clause ref, +#keyset[unified_variable_declaration_stmt, index] +unified_variable_declaration_stmt_variable_declarator( + int unified_variable_declaration_stmt: @unified_variable_declaration_stmt ref, int index: int ref, - unique int child: @swift_willset_clause_child_type ref + unique int variable_declarator: @unified_variable_declarator ref ); -swift_willset_clause_def( - unique int id: @swift_willset_clause +unified_variable_declaration_stmt_def( + unique int id: @unified_variable_declaration_stmt ); -@swift_willset_didset_block_child_type = @swift_didset_clause | @swift_willset_clause - -#keyset[swift_willset_didset_block, index] -swift_willset_didset_block_child( - int swift_willset_didset_block: @swift_willset_didset_block ref, - int index: int ref, - unique int child: @swift_willset_didset_block_child_type ref +unified_variable_declarator_value( + unique int unified_variable_declarator: @unified_variable_declarator ref, + unique int value: @unified_expr ref ); -swift_willset_didset_block_def( - unique int id: @swift_willset_didset_block +unified_variable_declarator_def( + unique int id: @unified_variable_declarator, + int pattern: @unified_pattern ref ); -swift_tokeninfo( - unique int id: @swift_token, +unified_tokeninfo( + unique int id: @unified_token, int kind: int ref, string value: string ref ); -case @swift_token.kind of - 0 = @swift_reserved_word -| 1 = @swift_token_as_operator -| 2 = @swift_token_bang -| 3 = @swift_token_bin_literal -| 4 = @swift_token_boolean_literal -| 5 = @swift_token_catch_keyword -| 6 = @swift_token_comment -| 7 = @swift_token_custom_operator -| 8 = @swift_token_default_keyword -| 9 = @swift_token_diagnostic -| 10 = @swift_token_else -| 11 = @swift_token_fully_open_range -| 12 = @swift_token_function_modifier -| 13 = @swift_token_hex_literal -| 14 = @swift_token_inheritance_modifier -| 15 = @swift_token_integer_literal -| 16 = @swift_token_line_str_text -| 17 = @swift_token_member_modifier -| 18 = @swift_token_multi_line_str_text -| 19 = @swift_token_multiline_comment -| 20 = @swift_token_mutation_modifier -| 21 = @swift_token_oct_literal -| 22 = @swift_token_ownership_modifier -| 23 = @swift_token_parameter_modifier -| 24 = @swift_token_property_behavior_modifier -| 25 = @swift_token_property_modifier -| 26 = @swift_token_raw_str_continuing_indicator -| 27 = @swift_token_raw_str_end_part -| 28 = @swift_token_raw_str_interpolation_start -| 29 = @swift_token_raw_str_part -| 30 = @swift_token_real_literal -| 31 = @swift_token_regex_literal -| 32 = @swift_token_self_expression -| 33 = @swift_token_shebang_line -| 34 = @swift_token_simple_identifier -| 35 = @swift_token_special_literal -| 36 = @swift_token_statement_label -| 37 = @swift_token_str_escaped_char -| 38 = @swift_token_super_expression -| 39 = @swift_token_throw_keyword -| 40 = @swift_token_throws -| 41 = @swift_token_try_operator -| 42 = @swift_token_type_identifier -| 43 = @swift_token_visibility_modifier -| 44 = @swift_token_where_keyword -| 45 = @swift_token_wildcard_pattern +case @unified_token.kind of + 1 = @unified_token_empty_stmt +| 2 = @unified_token_identifier +| 3 = @unified_token_ignore_pattern +| 4 = @unified_token_int_literal +| 5 = @unified_token_operator +| 6 = @unified_token_string_literal +| 7 = @unified_token_unsupported_node ; -@swift_ast_node = @swift_additive_expression | @swift_array_literal | @swift_array_type | @swift_as_expression | @swift_assignment | @swift_associatedtype_declaration | @swift_attribute | @swift_availability_condition | @swift_await_expression | @swift_bitwise_operation | @swift_call_expression | @swift_call_suffix | @swift_capture_list | @swift_capture_list_item | @swift_catch_block | @swift_check_expression | @swift_class_body | @swift_class_declaration | @swift_comparison_expression | @swift_computed_getter | @swift_computed_modify | @swift_computed_property | @swift_computed_setter | @swift_conjunction_expression | @swift_constructor_expression | @swift_constructor_suffix | @swift_control_transfer_statement | @swift_deinit_declaration | @swift_deprecated_operator_declaration_body | @swift_dictionary_literal | @swift_dictionary_type | @swift_didset_clause | @swift_directive | @swift_directly_assignable_expression | @swift_disjunction_expression | @swift_do_statement | @swift_enum_class_body | @swift_enum_entry | @swift_enum_type_parameters | @swift_equality_constraint | @swift_equality_expression | @swift_existential_type | @swift_external_macro_definition | @swift_for_statement | @swift_function_body | @swift_function_declaration | @swift_function_type | @swift_getter_specifier | @swift_guard_statement | @swift_identifier | @swift_if_condition | @swift_if_let_binding | @swift_if_statement | @swift_implicitly_unwrapped_type | @swift_import_declaration | @swift_infix_expression | @swift_inheritance_constraint | @swift_inheritance_specifier | @swift_init_declaration | @swift_interpolated_expression | @swift_key_path_expression | @swift_key_path_string_expression | @swift_lambda_function_type | @swift_lambda_function_type_parameters | @swift_lambda_literal | @swift_lambda_parameter | @swift_line_string_literal | @swift_macro_declaration | @swift_macro_definition | @swift_macro_invocation | @swift_metatype | @swift_modifiers | @swift_modify_specifier | @swift_multi_line_string_literal | @swift_multiplicative_expression | @swift_navigation_expression | @swift_navigation_suffix | @swift_nested_type_identifier | @swift_nil_coalescing_expression | @swift_opaque_type | @swift_open_end_range_expression | @swift_open_start_range_expression | @swift_operator_declaration | @swift_optional_chain_marker | @swift_optional_type | @swift_parameter | @swift_parameter_modifiers | @swift_pattern | @swift_playground_literal | @swift_postfix_expression | @swift_precedence_group_attribute | @swift_precedence_group_attributes | @swift_precedence_group_declaration | @swift_prefix_expression | @swift_property_declaration | @swift_protocol_body | @swift_protocol_composition_type | @swift_protocol_declaration | @swift_protocol_function_declaration | @swift_protocol_property_declaration | @swift_protocol_property_requirements | @swift_range_expression | @swift_raw_str_interpolation | @swift_raw_string_literal | @swift_referenceable_operator | @swift_repeat_while_statement | @swift_selector_expression | @swift_setter_specifier | @swift_source_file | @swift_statements | @swift_subscript_declaration | @swift_suppressed_constraint | @swift_switch_entry | @swift_switch_pattern | @swift_switch_statement | @swift_ternary_expression | @swift_throws_clause | @swift_token | @swift_try_expression | @swift_tuple_expression | @swift_tuple_type | @swift_tuple_type_item | @swift_type__ | @swift_type_annotation | @swift_type_arguments | @swift_type_constraint | @swift_type_constraints | @swift_type_modifiers | @swift_type_pack_expansion | @swift_type_parameter | @swift_type_parameter_modifiers | @swift_type_parameter_pack | @swift_type_parameters | @swift_typealias_declaration | @swift_user_type | @swift_value_argument | @swift_value_argument_label | @swift_value_arguments | @swift_value_binding_pattern | @swift_value_pack_expansion | @swift_value_parameter_pack | @swift_where_clause | @swift_while_statement | @swift_willset_clause | @swift_willset_didset_block +@unified_ast_node = @unified_apply_pattern | @unified_binary_expr | @unified_block_stmt | @unified_call_expr | @unified_expr_condition | @unified_expr_stmt | @unified_guard_if_stmt | @unified_if_stmt | @unified_lambda_expr | @unified_let_pattern_condition | @unified_member_access_expr | @unified_name_expr | @unified_parameter | @unified_sequence_condition | @unified_token | @unified_top_level | @unified_tuple_pattern | @unified_unary_expr | @unified_var_pattern | @unified_variable_declaration_stmt | @unified_variable_declarator -swift_ast_node_location( - unique int node: @swift_ast_node ref, +unified_ast_node_location( + unique int node: @unified_ast_node ref, int loc: @location_default ref ); #keyset[parent, parent_index] -swift_ast_node_parent( - unique int node: @swift_ast_node ref, - int parent: @swift_ast_node ref, +unified_ast_node_parent( + unique int node: @unified_ast_node ref, + int parent: @unified_ast_node ref, int parent_index: int ref ); diff --git a/unified/ql/test/library-tests/BasicTest/name_expr.swift b/unified/ql/test/library-tests/BasicTest/name_expr.swift new file mode 100644 index 000000000000..613f3a62861a --- /dev/null +++ b/unified/ql/test/library-tests/BasicTest/name_expr.swift @@ -0,0 +1 @@ +var x = y + 2; diff --git a/unified/ql/test/library-tests/BasicTest/test.expected b/unified/ql/test/library-tests/BasicTest/test.expected index 62b8146bf040..1d6bb8def2b5 100644 --- a/unified/ql/test/library-tests/BasicTest/test.expected +++ b/unified/ql/test/library-tests/BasicTest/test.expected @@ -1,101 +1,18 @@ -identifier -| test.swift:1:8:1:17 | Foundation | Foundation | -| test.swift:5:9:5:13 | items | items | -| test.swift:7:19:7:21 | add | add | -| test.swift:7:23:7:23 | _ | _ | -| test.swift:7:25:7:28 | item | item | -| test.swift:8:9:8:13 | items | items | -| test.swift:8:15:8:20 | append | append | -| test.swift:8:22:8:25 | item | item | -| test.swift:11:10:11:17 | contains | contains | -| test.swift:11:19:11:19 | _ | _ | -| test.swift:11:21:11:24 | item | item | -| test.swift:12:16:12:20 | items | items | -| test.swift:12:22:12:29 | contains | contains | -| test.swift:12:31:12:34 | item | item | -| test.swift:19:9:19:13 | count | count | -| test.swift:20:10:20:13 | item | item | -| test.swift:20:15:20:16 | at | at | -| test.swift:20:18:20:22 | index | index | -| test.swift:24:6:24:10 | merge | merge | -| test.swift:24:27:24:27 | _ | _ | -| test.swift:24:29:24:33 | first | first | -| test.swift:24:39:24:39 | _ | _ | -| test.swift:24:41:24:46 | second | second | -| test.swift:24:73:24:73 | T | T | -| test.swift:24:75:24:81 | Element | Element | -| test.swift:25:9:25:14 | result | result | -| test.swift:25:18:25:22 | Array | Array | -| test.swift:25:24:25:28 | first | first | -| test.swift:26:9:26:12 | item | item | -| test.swift:26:17:26:22 | second | second | -| test.swift:27:13:27:18 | result | result | -| test.swift:27:20:27:27 | contains | contains | -| test.swift:27:29:27:32 | item | item | -| test.swift:28:13:28:18 | result | result | -| test.swift:28:20:28:25 | append | append | -| test.swift:28:27:28:30 | item | item | -| test.swift:31:12:31:17 | result | result | -| test.swift:37:17:37:20 | data | data | -| test.swift:39:9:39:13 | count | count | -| test.swift:40:16:40:19 | data | data | -| test.swift:40:21:40:25 | count | count | -| test.swift:43:9:43:15 | isEmpty | isEmpty | -| test.swift:44:9:44:12 | data | data | -| test.swift:44:14:44:20 | isEmpty | isEmpty | -| test.swift:47:10:47:13 | item | item | -| test.swift:47:15:47:16 | at | at | -| test.swift:47:18:47:22 | index | index | -| test.swift:48:15:48:19 | index | index | -| test.swift:48:29:48:33 | index | index | -| test.swift:48:37:48:40 | data | data | -| test.swift:48:42:48:46 | count | count | -| test.swift:49:16:49:19 | data | data | -| test.swift:49:21:49:25 | index | index | -| test.swift:52:10:52:12 | add | add | -| test.swift:52:14:52:14 | _ | _ | -| test.swift:52:16:52:19 | item | item | -| test.swift:53:9:53:12 | data | data | -| test.swift:53:14:53:19 | append | append | -| test.swift:53:21:53:24 | item | item | -| test.swift:59:10:59:16 | success | success | -| test.swift:60:10:60:16 | failure | failure | -| test.swift:62:10:62:12 | map | map | -| test.swift:62:17:62:17 | _ | _ | -| test.swift:62:19:62:27 | transform | transform | -| test.swift:64:15:64:21 | success | success | -| test.swift:64:27:64:31 | value | value | -| test.swift:65:21:65:27 | success | success | -| test.swift:65:29:65:37 | transform | transform | -| test.swift:65:39:65:43 | value | value | -| test.swift:66:15:66:21 | failure | failure | -| test.swift:66:27:66:31 | error | error | -| test.swift:67:21:67:27 | failure | failure | -| test.swift:67:29:67:33 | error | error | -| test.swift:73:23:73:29 | Element | Element | -| test.swift:74:10:74:17 | isSorted | isSorted | -| test.swift:75:13:75:13 | i | i | -| test.swift:75:23:75:31 | blah | blah | -| test.swift:76:21:76:21 | i | i | -| test.swift:76:31:76:35 | blah | blah | -| test.swift:85:6:85:12 | combine | combine | -| test.swift:85:17:85:17 | _ | _ | -| test.swift:85:19:85:24 | values | values | -| test.swift:85:32:85:40 | transform | transform | -| test.swift:86:12:86:17 | values | values | -| test.swift:86:19:86:25 | isEmpty | isEmpty | -| test.swift:87:12:87:17 | values | values | -| test.swift:87:19:87:27 | dropFirst | dropFirst | -| test.swift:87:31:87:36 | reduce | reduce | -| test.swift:87:38:87:43 | values | values | -| test.swift:87:49:87:57 | transform | transform | -func -| test.swift:7:5:9:5 | FunctionDeclaration | -| test.swift:11:5:13:5 | FunctionDeclaration | -| test.swift:24:1:32:1 | FunctionDeclaration | -| test.swift:47:5:50:5 | FunctionDeclaration | -| test.swift:52:5:54:5 | FunctionDeclaration | -| test.swift:62:5:69:5 | FunctionDeclaration | -| test.swift:74:5:81:5 | FunctionDeclaration | -| test.swift:85:1:88:1 | FunctionDeclaration | -add +nameExpr +| name_expr.swift:1:9:1:9 | NameExpr | y | +unsupported +| test.swift:1:1:1:17 | | | +| test.swift:3:1:3:38 | | | +| test.swift:4:1:14:1 | | | +| test.swift:16:1:16:32 | | | +| test.swift:17:1:21:1 | | | +| test.swift:23:1:23:37 | | | +| test.swift:24:1:32:1 | | | +| test.swift:34:1:34:49 | | | +| test.swift:35:1:55:1 | | | +| test.swift:57:1:57:30 | | | +| test.swift:58:1:70:1 | | | +| test.swift:72:1:72:37 | | | +| test.swift:73:1:82:1 | | | +| test.swift:84:1:84:24 | | | +| test.swift:85:1:88:1 | | | diff --git a/unified/ql/test/library-tests/BasicTest/test.ql b/unified/ql/test/library-tests/BasicTest/test.ql index 3a5ee2f1c157..ca422d039781 100644 --- a/unified/ql/test/library-tests/BasicTest/test.ql +++ b/unified/ql/test/library-tests/BasicTest/test.ql @@ -1,9 +1,5 @@ -import codeql.unified.Ast +import codeql.unified.Ast::Unified -query predicate identifier(Swift::SimpleIdentifier node, string name) { name = node.getValue() } +query predicate nameExpr(NameExpr node, string value) { value = node.getIdentifier().getValue() } -query predicate func(Swift::FunctionDeclaration node) { any() } - -query predicate add(Swift::AdditiveExpression node, Swift::AstNode lhs, Swift::AstNode rhs) { - lhs = node.getLhs(0) and rhs = node.getRhs(0) -} +query predicate unsupported(UnsupportedNode node, string value) { value = node.getValue() } diff --git a/unified/scripts/update-corpus.sh b/unified/scripts/update-corpus.sh new file mode 100755 index 000000000000..2f3ebade8cb3 --- /dev/null +++ b/unified/scripts/update-corpus.sh @@ -0,0 +1,8 @@ +#!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +cd "$(dirname "$0")/.." + +cd extractor +UNIFIED_UPDATE_CORPUS=1 cargo test