From 809bd22e4c2d7d0a846b4cd3d1091cd0fce0e0ba Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Thu, 29 May 2025 16:49:27 +0100 Subject: [PATCH 1/3] Ruby: add support for extracting overlays --- Cargo.lock | 1 + .../tree_sitter_extractors_deps/defs.bzl | 1 + ruby/codeql-extractor.yml | 1 + ruby/extractor/Cargo.toml | 1 + ruby/extractor/src/extractor.rs | 52 +++++++++++++++++++ 5 files changed, 56 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 934cae590c1a..6a4ab106539e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -405,6 +405,7 @@ dependencies = [ "lazy_static", "rayon", "regex", + "serde_json", "tracing", "tracing-subscriber", "tree-sitter", diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl b/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl index 0247ee36d9f5..2f95fab79e17 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl @@ -301,6 +301,7 @@ _NORMAL_DEPENDENCIES = { "lazy_static": Label("@vendor_ts__lazy_static-1.5.0//:lazy_static"), "rayon": Label("@vendor_ts__rayon-1.10.0//:rayon"), "regex": Label("@vendor_ts__regex-1.11.1//:regex"), + "serde_json": Label("@vendor_ts__serde_json-1.0.140//:serde_json"), "tracing": Label("@vendor_ts__tracing-0.1.41//:tracing"), "tracing-subscriber": Label("@vendor_ts__tracing-subscriber-0.3.19//:tracing_subscriber"), "tree-sitter": Label("@vendor_ts__tree-sitter-0.24.6//:tree_sitter"), diff --git a/ruby/codeql-extractor.yml b/ruby/codeql-extractor.yml index abb50db2a295..a832b0c10654 100644 --- a/ruby/codeql-extractor.yml +++ b/ruby/codeql-extractor.yml @@ -3,6 +3,7 @@ display_name: "Ruby" version: 0.1.0 column_kind: "utf8" legacy_qltest_extraction: true +overlay_support_version: 20250108 build_modes: - none github_api_languages: diff --git a/ruby/extractor/Cargo.toml b/ruby/extractor/Cargo.toml index 8d3a94113fa2..16cdcca246c2 100644 --- a/ruby/extractor/Cargo.toml +++ b/ruby/extractor/Cargo.toml @@ -17,5 +17,6 @@ rayon = "1.10.0" regex = "1.11.1" encoding = "0.2" lazy_static = "1.5.0" +serde_json = "1.0.140" codeql-extractor = { path = "../../shared/tree-sitter-extractor" } diff --git a/ruby/extractor/src/extractor.rs b/ruby/extractor/src/extractor.rs index d42713122263..92bcf748a087 100644 --- a/ruby/extractor/src/extractor.rs +++ b/ruby/extractor/src/extractor.rs @@ -1,7 +1,9 @@ use clap::Args; use lazy_static::lazy_static; use rayon::prelude::*; +use serde_json; use std::borrow::Cow; +use std::collections::HashSet; use std::fs; use std::io::BufRead; use std::path::{Path, PathBuf}; @@ -78,6 +80,8 @@ pub fn run(options: Options) -> std::io::Result<()> { let file_list = fs::File::open(file_paths::path_from_string(&options.file_list))?; + let overlay_changed_files: Option> = get_overlay_changed_files(); + let language: Language = tree_sitter_ruby::LANGUAGE.into(); let erb: Language = tree_sitter_embedded_template::LANGUAGE.into(); // Look up tree-sitter kind ids now, to avoid string comparisons when scanning ERB files. @@ -94,6 +98,13 @@ pub fn run(options: Options) -> std::io::Result<()> { .try_for_each(|line| { let mut diagnostics_writer = diagnostics.logger(); let path = PathBuf::from(line).canonicalize()?; + match &overlay_changed_files { + Some(changed_files) if !changed_files.contains(&path) => { + // We are extracting an overlay and this file is not in the list of changes files, so we should skip it. + return Result::Ok(()); + } + _ => {}, + } let src_archive_file = file_paths::path_for(&src_archive_dir, &path, ""); let mut source = std::fs::read(&path)?; let mut needs_conversion = false; @@ -212,6 +223,12 @@ pub fn run(options: Options) -> std::io::Result<()> { let mut trap_writer = trap::Writer::new(); extractor::populate_empty_location(&mut trap_writer); let res = write_trap(&trap_dir, path, &trap_writer, trap_compression); + if let Ok(output_path) = std::env::var("CODEQL_EXTRACTOR_RUBY_OVERLAY_BASE_METADATA_OUT") { + // We're extracting an overlay base. For now, we don't have any metadata we need to store + // that would get read when extracting the overlay, but the CLI expects us to write + // *something*. An empty file will do. + std::fs::write(output_path, b"")?; + } tracing::info!("Extraction complete"); res } @@ -302,6 +319,41 @@ fn skip_space(content: &[u8], index: usize) -> usize { } index } + +/** +* If the relevant environment variable has been set by the CLI, indicating that we are extracting +* an overlay, this function reads the JSON file at the path given by its value, and returns a set +* of canonicalized paths of source files that have changed and should therefore be extracted. +* +* If the environment variable is not set (i.e. we're not extracting an overlay), or if the file +* cannot be read, this function returns `None`. In that case, all files should be extracted. +*/ +fn get_overlay_changed_files() -> Option> { + let path = std::env::var("CODEQL_EXTRACTOR_RUBY_OVERLAY_CHANGES").ok()?; + let file_content = fs::read_to_string(path).ok()?; + let json_value: serde_json::Value = serde_json::from_str(&file_content).ok()?; + + // The JSON file is expected to have the following structure: + // { + // "changes": [ + // "relative/path/to/changed/file1.rb", + // "relative/path/to/changed/file2.rb", + // ... + // ] + // } + json_value + .get("changes")? + .as_array()? + .iter() + .map(|change| { + change + .as_str() + .map(|s| PathBuf::from(s).canonicalize().ok()) + .flatten() + }) + .collect() +} + fn scan_coding_comment(content: &[u8]) -> std::option::Option> { let mut index = 0; // skip UTF-8 BOM marker if there is one From e8ff07dc0b8a484e3cd28431f03cc30c1c5e058b Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Thu, 29 May 2025 18:22:36 +0100 Subject: [PATCH 2/3] Ruby: add databaseMetadata relation to dbscheme This is required for overlay support. --- config/dbscheme-fragments.json | 3 +- ql/extractor/src/generator.rs | 2 +- .../old.dbscheme | 1532 +++++++++++++++++ .../ruby.dbscheme | 1526 ++++++++++++++++ .../upgrade.properties | 3 + ruby/extractor/src/generator.rs | 2 +- ruby/ql/lib/ruby.dbscheme | 6 + ruby/ql/lib/ruby.dbscheme.stats | 36 + .../old.dbscheme | 1526 ++++++++++++++++ .../ruby.dbscheme | 1532 +++++++++++++++++ .../upgrade.properties | 2 + .../src/generator/mod.rs | 34 + 12 files changed, 6201 insertions(+), 3 deletions(-) create mode 100644 ruby/downgrades/dc51d416301df12df5b70fbc4338de6cc1f82bfd/old.dbscheme create mode 100644 ruby/downgrades/dc51d416301df12df5b70fbc4338de6cc1f82bfd/ruby.dbscheme create mode 100644 ruby/downgrades/dc51d416301df12df5b70fbc4338de6cc1f82bfd/upgrade.properties create mode 100644 ruby/ql/lib/upgrades/40a6b0a5e81115bd870b3a12a1fe954b06362bb7/old.dbscheme create mode 100644 ruby/ql/lib/upgrades/40a6b0a5e81115bd870b3a12a1fe954b06362bb7/ruby.dbscheme create mode 100644 ruby/ql/lib/upgrades/40a6b0a5e81115bd870b3a12a1fe954b06362bb7/upgrade.properties diff --git a/config/dbscheme-fragments.json b/config/dbscheme-fragments.json index c56289ff1716..b8c79fc8f3ab 100644 --- a/config/dbscheme-fragments.json +++ b/config/dbscheme-fragments.json @@ -11,6 +11,7 @@ "/*- Diagnostic messages -*/", "/*- Diagnostic messages: severity -*/", "/*- Source location prefix -*/", + "/*- Database metadata -*/", "/*- Lines of code -*/", "/*- Configuration files with key value pairs -*/", "/*- YAML -*/", @@ -31,4 +32,4 @@ "/*- Python dbscheme -*/", "/*- Empty location -*/" ] -} \ No newline at end of file +} diff --git a/ql/extractor/src/generator.rs b/ql/extractor/src/generator.rs index 1dca6969f348..ea663896e640 100644 --- a/ql/extractor/src/generator.rs +++ b/ql/extractor/src/generator.rs @@ -36,5 +36,5 @@ pub fn run(options: Options) -> std::io::Result<()> { }, ]; - generate(languages, options.dbscheme, options.library) + generate(languages, options.dbscheme, options.library, false) } diff --git a/ruby/downgrades/dc51d416301df12df5b70fbc4338de6cc1f82bfd/old.dbscheme b/ruby/downgrades/dc51d416301df12df5b70fbc4338de6cc1f82bfd/old.dbscheme new file mode 100644 index 000000000000..dc51d416301d --- /dev/null +++ b/ruby/downgrades/dc51d416301df12df5b70fbc4338de6cc1f82bfd/old.dbscheme @@ -0,0 +1,1532 @@ +// CodeQL database schema for Ruby +// Automatically generated from the tree-sitter grammar; do not edit + +/*- Files and folders -*/ + +/** + * The location of an element. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @file | @folder + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/*- Empty location -*/ + +empty_location( + int location: @location_default ref +); + +/*- Source location prefix -*/ + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/*- Diagnostic messages -*/ + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/*- Diagnostic messages: severity -*/ + +case @diagnostic.severity of + 10 = @diagnostic_debug +| 20 = @diagnostic_info +| 30 = @diagnostic_warning +| 40 = @diagnostic_error +; + +/*- YAML -*/ + +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + string tag: string ref, + string tostring: string ref); + +case @yaml_node.kind of + 0 = @yaml_scalar_node +| 1 = @yaml_mapping_node +| 2 = @yaml_sequence_node +| 3 = @yaml_alias_node +; + +@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node; + +@yaml_node_parent = @yaml_collection_node | @file; + +yaml_anchors (unique int node: @yaml_node ref, + string anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + string target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + string value: string ref); + +yaml_errors (unique int id: @yaml_error, + string message: string ref); + +yaml_locations(unique int locatable: @yaml_locatable ref, + int location: @location_default ref); + +@yaml_locatable = @yaml_node | @yaml_error; + +/*- Database metadata -*/ +databaseMetadata( + string metadataKey: string ref, + string value: string ref +); + +/*- Ruby dbscheme -*/ +@ruby_underscore_arg = @ruby_assignment | @ruby_binary | @ruby_conditional | @ruby_operator_assignment | @ruby_range | @ruby_unary | @ruby_underscore_primary + +@ruby_underscore_call_operator = @ruby_reserved_word + +@ruby_underscore_expression = @ruby_assignment | @ruby_binary | @ruby_break | @ruby_call | @ruby_match_pattern | @ruby_next | @ruby_operator_assignment | @ruby_return | @ruby_test_pattern | @ruby_unary | @ruby_underscore_arg | @ruby_yield + +@ruby_underscore_lhs = @ruby_call | @ruby_element_reference | @ruby_scope_resolution | @ruby_token_false | @ruby_token_nil | @ruby_token_true | @ruby_underscore_variable + +@ruby_underscore_method_name = @ruby_delimited_symbol | @ruby_setter | @ruby_token_constant | @ruby_token_identifier | @ruby_token_operator | @ruby_token_simple_symbol | @ruby_underscore_nonlocal_variable + +@ruby_underscore_nonlocal_variable = @ruby_token_class_variable | @ruby_token_global_variable | @ruby_token_instance_variable + +@ruby_underscore_pattern_constant = @ruby_scope_resolution | @ruby_token_constant + +@ruby_underscore_pattern_expr = @ruby_alternative_pattern | @ruby_as_pattern | @ruby_underscore_pattern_expr_basic + +@ruby_underscore_pattern_expr_basic = @ruby_array_pattern | @ruby_expression_reference_pattern | @ruby_find_pattern | @ruby_hash_pattern | @ruby_parenthesized_pattern | @ruby_range | @ruby_token_identifier | @ruby_underscore_pattern_constant | @ruby_underscore_pattern_primitive | @ruby_variable_reference_pattern + +@ruby_underscore_pattern_primitive = @ruby_delimited_symbol | @ruby_lambda | @ruby_regex | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_symbol_array | @ruby_token_encoding | @ruby_token_false | @ruby_token_file | @ruby_token_heredoc_beginning | @ruby_token_line | @ruby_token_nil | @ruby_token_self | @ruby_token_simple_symbol | @ruby_token_true | @ruby_unary | @ruby_underscore_simple_numeric + +@ruby_underscore_pattern_top_expr_body = @ruby_array_pattern | @ruby_find_pattern | @ruby_hash_pattern | @ruby_underscore_pattern_expr + +@ruby_underscore_primary = @ruby_array | @ruby_begin | @ruby_break | @ruby_call | @ruby_case__ | @ruby_case_match | @ruby_chained_string | @ruby_class | @ruby_delimited_symbol | @ruby_for | @ruby_hash | @ruby_if | @ruby_lambda | @ruby_method | @ruby_module | @ruby_next | @ruby_parenthesized_statements | @ruby_redo | @ruby_regex | @ruby_retry | @ruby_return | @ruby_singleton_class | @ruby_singleton_method | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_symbol_array | @ruby_token_character | @ruby_token_heredoc_beginning | @ruby_token_simple_symbol | @ruby_unary | @ruby_underscore_lhs | @ruby_underscore_simple_numeric | @ruby_unless | @ruby_until | @ruby_while | @ruby_yield + +@ruby_underscore_simple_numeric = @ruby_complex | @ruby_rational | @ruby_token_float | @ruby_token_integer + +@ruby_underscore_statement = @ruby_alias | @ruby_begin_block | @ruby_end_block | @ruby_if_modifier | @ruby_rescue_modifier | @ruby_undef | @ruby_underscore_expression | @ruby_unless_modifier | @ruby_until_modifier | @ruby_while_modifier + +@ruby_underscore_variable = @ruby_token_constant | @ruby_token_identifier | @ruby_token_self | @ruby_token_super | @ruby_underscore_nonlocal_variable + +ruby_alias_def( + unique int id: @ruby_alias, + int alias: @ruby_underscore_method_name ref, + int name: @ruby_underscore_method_name ref +); + +#keyset[ruby_alternative_pattern, index] +ruby_alternative_pattern_alternatives( + int ruby_alternative_pattern: @ruby_alternative_pattern ref, + int index: int ref, + unique int alternatives: @ruby_underscore_pattern_expr_basic ref +); + +ruby_alternative_pattern_def( + unique int id: @ruby_alternative_pattern +); + +@ruby_argument_list_child_type = @ruby_block_argument | @ruby_hash_splat_argument | @ruby_pair | @ruby_splat_argument | @ruby_token_forward_argument | @ruby_underscore_expression + +#keyset[ruby_argument_list, index] +ruby_argument_list_child( + int ruby_argument_list: @ruby_argument_list ref, + int index: int ref, + unique int child: @ruby_argument_list_child_type ref +); + +ruby_argument_list_def( + unique int id: @ruby_argument_list +); + +@ruby_array_child_type = @ruby_block_argument | @ruby_hash_splat_argument | @ruby_pair | @ruby_splat_argument | @ruby_token_forward_argument | @ruby_underscore_expression + +#keyset[ruby_array, index] +ruby_array_child( + int ruby_array: @ruby_array ref, + int index: int ref, + unique int child: @ruby_array_child_type ref +); + +ruby_array_def( + unique int id: @ruby_array +); + +ruby_array_pattern_class( + unique int ruby_array_pattern: @ruby_array_pattern ref, + unique int class: @ruby_underscore_pattern_constant ref +); + +@ruby_array_pattern_child_type = @ruby_splat_parameter | @ruby_underscore_pattern_expr + +#keyset[ruby_array_pattern, index] +ruby_array_pattern_child( + int ruby_array_pattern: @ruby_array_pattern ref, + int index: int ref, + unique int child: @ruby_array_pattern_child_type ref +); + +ruby_array_pattern_def( + unique int id: @ruby_array_pattern +); + +ruby_as_pattern_def( + unique int id: @ruby_as_pattern, + int name: @ruby_token_identifier ref, + int value: @ruby_underscore_pattern_expr ref +); + +@ruby_assignment_left_type = @ruby_left_assignment_list | @ruby_underscore_lhs + +@ruby_assignment_right_type = @ruby_rescue_modifier | @ruby_right_assignment_list | @ruby_splat_argument | @ruby_underscore_expression + +ruby_assignment_def( + unique int id: @ruby_assignment, + int left: @ruby_assignment_left_type ref, + int right: @ruby_assignment_right_type ref +); + +@ruby_bare_string_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_bare_string, index] +ruby_bare_string_child( + int ruby_bare_string: @ruby_bare_string ref, + int index: int ref, + unique int child: @ruby_bare_string_child_type ref +); + +ruby_bare_string_def( + unique int id: @ruby_bare_string +); + +@ruby_bare_symbol_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_bare_symbol, index] +ruby_bare_symbol_child( + int ruby_bare_symbol: @ruby_bare_symbol ref, + int index: int ref, + unique int child: @ruby_bare_symbol_child_type ref +); + +ruby_bare_symbol_def( + unique int id: @ruby_bare_symbol +); + +@ruby_begin_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_begin, index] +ruby_begin_child( + int ruby_begin: @ruby_begin ref, + int index: int ref, + unique int child: @ruby_begin_child_type ref +); + +ruby_begin_def( + unique int id: @ruby_begin +); + +@ruby_begin_block_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_begin_block, index] +ruby_begin_block_child( + int ruby_begin_block: @ruby_begin_block ref, + int index: int ref, + unique int child: @ruby_begin_block_child_type ref +); + +ruby_begin_block_def( + unique int id: @ruby_begin_block +); + +@ruby_binary_left_type = @ruby_underscore_expression | @ruby_underscore_simple_numeric + +case @ruby_binary.operator of + 0 = @ruby_binary_bangequal +| 1 = @ruby_binary_bangtilde +| 2 = @ruby_binary_percent +| 3 = @ruby_binary_ampersand +| 4 = @ruby_binary_ampersandampersand +| 5 = @ruby_binary_star +| 6 = @ruby_binary_starstar +| 7 = @ruby_binary_plus +| 8 = @ruby_binary_minus +| 9 = @ruby_binary_slash +| 10 = @ruby_binary_langle +| 11 = @ruby_binary_langlelangle +| 12 = @ruby_binary_langleequal +| 13 = @ruby_binary_langleequalrangle +| 14 = @ruby_binary_equalequal +| 15 = @ruby_binary_equalequalequal +| 16 = @ruby_binary_equaltilde +| 17 = @ruby_binary_rangle +| 18 = @ruby_binary_rangleequal +| 19 = @ruby_binary_ranglerangle +| 20 = @ruby_binary_caret +| 21 = @ruby_binary_and +| 22 = @ruby_binary_or +| 23 = @ruby_binary_pipe +| 24 = @ruby_binary_pipepipe +; + + +ruby_binary_def( + unique int id: @ruby_binary, + int left: @ruby_binary_left_type ref, + int operator: int ref, + int right: @ruby_underscore_expression ref +); + +ruby_block_body( + unique int ruby_block: @ruby_block ref, + unique int body: @ruby_block_body ref +); + +ruby_block_parameters( + unique int ruby_block: @ruby_block ref, + unique int parameters: @ruby_block_parameters ref +); + +ruby_block_def( + unique int id: @ruby_block +); + +ruby_block_argument_child( + unique int ruby_block_argument: @ruby_block_argument ref, + unique int child: @ruby_underscore_arg ref +); + +ruby_block_argument_def( + unique int id: @ruby_block_argument +); + +@ruby_block_body_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_block_body, index] +ruby_block_body_child( + int ruby_block_body: @ruby_block_body ref, + int index: int ref, + unique int child: @ruby_block_body_child_type ref +); + +ruby_block_body_def( + unique int id: @ruby_block_body +); + +ruby_block_parameter_name( + unique int ruby_block_parameter: @ruby_block_parameter ref, + unique int name: @ruby_token_identifier ref +); + +ruby_block_parameter_def( + unique int id: @ruby_block_parameter +); + +#keyset[ruby_block_parameters, index] +ruby_block_parameters_locals( + int ruby_block_parameters: @ruby_block_parameters ref, + int index: int ref, + unique int locals: @ruby_token_identifier ref +); + +@ruby_block_parameters_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_block_parameters, index] +ruby_block_parameters_child( + int ruby_block_parameters: @ruby_block_parameters ref, + int index: int ref, + unique int child: @ruby_block_parameters_child_type ref +); + +ruby_block_parameters_def( + unique int id: @ruby_block_parameters +); + +@ruby_body_statement_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_body_statement, index] +ruby_body_statement_child( + int ruby_body_statement: @ruby_body_statement ref, + int index: int ref, + unique int child: @ruby_body_statement_child_type ref +); + +ruby_body_statement_def( + unique int id: @ruby_body_statement +); + +ruby_break_child( + unique int ruby_break: @ruby_break ref, + unique int child: @ruby_argument_list ref +); + +ruby_break_def( + unique int id: @ruby_break +); + +ruby_call_arguments( + unique int ruby_call: @ruby_call ref, + unique int arguments: @ruby_argument_list ref +); + +@ruby_call_block_type = @ruby_block | @ruby_do_block + +ruby_call_block( + unique int ruby_call: @ruby_call ref, + unique int block: @ruby_call_block_type ref +); + +@ruby_call_method_type = @ruby_token_operator | @ruby_underscore_variable + +ruby_call_method( + unique int ruby_call: @ruby_call ref, + unique int method: @ruby_call_method_type ref +); + +ruby_call_operator( + unique int ruby_call: @ruby_call ref, + unique int operator: @ruby_underscore_call_operator ref +); + +ruby_call_receiver( + unique int ruby_call: @ruby_call ref, + unique int receiver: @ruby_underscore_primary ref +); + +ruby_call_def( + unique int id: @ruby_call +); + +ruby_case_value( + unique int ruby_case__: @ruby_case__ ref, + unique int value: @ruby_underscore_statement ref +); + +@ruby_case_child_type = @ruby_else | @ruby_when + +#keyset[ruby_case__, index] +ruby_case_child( + int ruby_case__: @ruby_case__ ref, + int index: int ref, + unique int child: @ruby_case_child_type ref +); + +ruby_case_def( + unique int id: @ruby_case__ +); + +#keyset[ruby_case_match, index] +ruby_case_match_clauses( + int ruby_case_match: @ruby_case_match ref, + int index: int ref, + unique int clauses: @ruby_in_clause ref +); + +ruby_case_match_else( + unique int ruby_case_match: @ruby_case_match ref, + unique int else: @ruby_else ref +); + +ruby_case_match_def( + unique int id: @ruby_case_match, + int value: @ruby_underscore_statement ref +); + +#keyset[ruby_chained_string, index] +ruby_chained_string_child( + int ruby_chained_string: @ruby_chained_string ref, + int index: int ref, + unique int child: @ruby_string__ ref +); + +ruby_chained_string_def( + unique int id: @ruby_chained_string +); + +ruby_class_body( + unique int ruby_class: @ruby_class ref, + unique int body: @ruby_body_statement ref +); + +@ruby_class_name_type = @ruby_scope_resolution | @ruby_token_constant + +ruby_class_superclass( + unique int ruby_class: @ruby_class ref, + unique int superclass: @ruby_superclass ref +); + +ruby_class_def( + unique int id: @ruby_class, + int name: @ruby_class_name_type ref +); + +@ruby_complex_child_type = @ruby_rational | @ruby_token_float | @ruby_token_integer + +ruby_complex_def( + unique int id: @ruby_complex, + int child: @ruby_complex_child_type ref +); + +ruby_conditional_def( + unique int id: @ruby_conditional, + int alternative: @ruby_underscore_arg ref, + int condition: @ruby_underscore_arg ref, + int consequence: @ruby_underscore_arg ref +); + +@ruby_delimited_symbol_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_delimited_symbol, index] +ruby_delimited_symbol_child( + int ruby_delimited_symbol: @ruby_delimited_symbol ref, + int index: int ref, + unique int child: @ruby_delimited_symbol_child_type ref +); + +ruby_delimited_symbol_def( + unique int id: @ruby_delimited_symbol +); + +@ruby_destructured_left_assignment_child_type = @ruby_destructured_left_assignment | @ruby_rest_assignment | @ruby_underscore_lhs + +#keyset[ruby_destructured_left_assignment, index] +ruby_destructured_left_assignment_child( + int ruby_destructured_left_assignment: @ruby_destructured_left_assignment ref, + int index: int ref, + unique int child: @ruby_destructured_left_assignment_child_type ref +); + +ruby_destructured_left_assignment_def( + unique int id: @ruby_destructured_left_assignment +); + +@ruby_destructured_parameter_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_destructured_parameter, index] +ruby_destructured_parameter_child( + int ruby_destructured_parameter: @ruby_destructured_parameter ref, + int index: int ref, + unique int child: @ruby_destructured_parameter_child_type ref +); + +ruby_destructured_parameter_def( + unique int id: @ruby_destructured_parameter +); + +@ruby_do_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_do, index] +ruby_do_child( + int ruby_do: @ruby_do ref, + int index: int ref, + unique int child: @ruby_do_child_type ref +); + +ruby_do_def( + unique int id: @ruby_do +); + +ruby_do_block_body( + unique int ruby_do_block: @ruby_do_block ref, + unique int body: @ruby_body_statement ref +); + +ruby_do_block_parameters( + unique int ruby_do_block: @ruby_do_block ref, + unique int parameters: @ruby_block_parameters ref +); + +ruby_do_block_def( + unique int id: @ruby_do_block +); + +@ruby_element_reference_block_type = @ruby_block | @ruby_do_block + +ruby_element_reference_block( + unique int ruby_element_reference: @ruby_element_reference ref, + unique int block: @ruby_element_reference_block_type ref +); + +@ruby_element_reference_child_type = @ruby_block_argument | @ruby_hash_splat_argument | @ruby_pair | @ruby_splat_argument | @ruby_token_forward_argument | @ruby_underscore_expression + +#keyset[ruby_element_reference, index] +ruby_element_reference_child( + int ruby_element_reference: @ruby_element_reference ref, + int index: int ref, + unique int child: @ruby_element_reference_child_type ref +); + +ruby_element_reference_def( + unique int id: @ruby_element_reference, + int object: @ruby_underscore_primary ref +); + +@ruby_else_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_else, index] +ruby_else_child( + int ruby_else: @ruby_else ref, + int index: int ref, + unique int child: @ruby_else_child_type ref +); + +ruby_else_def( + unique int id: @ruby_else +); + +@ruby_elsif_alternative_type = @ruby_else | @ruby_elsif + +ruby_elsif_alternative( + unique int ruby_elsif: @ruby_elsif ref, + unique int alternative: @ruby_elsif_alternative_type ref +); + +ruby_elsif_consequence( + unique int ruby_elsif: @ruby_elsif ref, + unique int consequence: @ruby_then ref +); + +ruby_elsif_def( + unique int id: @ruby_elsif, + int condition: @ruby_underscore_statement ref +); + +@ruby_end_block_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_end_block, index] +ruby_end_block_child( + int ruby_end_block: @ruby_end_block ref, + int index: int ref, + unique int child: @ruby_end_block_child_type ref +); + +ruby_end_block_def( + unique int id: @ruby_end_block +); + +@ruby_ensure_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_ensure, index] +ruby_ensure_child( + int ruby_ensure: @ruby_ensure ref, + int index: int ref, + unique int child: @ruby_ensure_child_type ref +); + +ruby_ensure_def( + unique int id: @ruby_ensure +); + +ruby_exception_variable_def( + unique int id: @ruby_exception_variable, + int child: @ruby_underscore_lhs ref +); + +@ruby_exceptions_child_type = @ruby_splat_argument | @ruby_underscore_arg + +#keyset[ruby_exceptions, index] +ruby_exceptions_child( + int ruby_exceptions: @ruby_exceptions ref, + int index: int ref, + unique int child: @ruby_exceptions_child_type ref +); + +ruby_exceptions_def( + unique int id: @ruby_exceptions +); + +ruby_expression_reference_pattern_def( + unique int id: @ruby_expression_reference_pattern, + int value: @ruby_underscore_expression ref +); + +ruby_find_pattern_class( + unique int ruby_find_pattern: @ruby_find_pattern ref, + unique int class: @ruby_underscore_pattern_constant ref +); + +@ruby_find_pattern_child_type = @ruby_splat_parameter | @ruby_underscore_pattern_expr + +#keyset[ruby_find_pattern, index] +ruby_find_pattern_child( + int ruby_find_pattern: @ruby_find_pattern ref, + int index: int ref, + unique int child: @ruby_find_pattern_child_type ref +); + +ruby_find_pattern_def( + unique int id: @ruby_find_pattern +); + +@ruby_for_pattern_type = @ruby_left_assignment_list | @ruby_underscore_lhs + +ruby_for_def( + unique int id: @ruby_for, + int body: @ruby_do ref, + int pattern: @ruby_for_pattern_type ref, + int value: @ruby_in ref +); + +@ruby_hash_child_type = @ruby_hash_splat_argument | @ruby_pair + +#keyset[ruby_hash, index] +ruby_hash_child( + int ruby_hash: @ruby_hash ref, + int index: int ref, + unique int child: @ruby_hash_child_type ref +); + +ruby_hash_def( + unique int id: @ruby_hash +); + +ruby_hash_pattern_class( + unique int ruby_hash_pattern: @ruby_hash_pattern ref, + unique int class: @ruby_underscore_pattern_constant ref +); + +@ruby_hash_pattern_child_type = @ruby_hash_splat_parameter | @ruby_keyword_pattern | @ruby_token_hash_splat_nil + +#keyset[ruby_hash_pattern, index] +ruby_hash_pattern_child( + int ruby_hash_pattern: @ruby_hash_pattern ref, + int index: int ref, + unique int child: @ruby_hash_pattern_child_type ref +); + +ruby_hash_pattern_def( + unique int id: @ruby_hash_pattern +); + +ruby_hash_splat_argument_child( + unique int ruby_hash_splat_argument: @ruby_hash_splat_argument ref, + unique int child: @ruby_underscore_arg ref +); + +ruby_hash_splat_argument_def( + unique int id: @ruby_hash_splat_argument +); + +ruby_hash_splat_parameter_name( + unique int ruby_hash_splat_parameter: @ruby_hash_splat_parameter ref, + unique int name: @ruby_token_identifier ref +); + +ruby_hash_splat_parameter_def( + unique int id: @ruby_hash_splat_parameter +); + +@ruby_heredoc_body_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_heredoc_content | @ruby_token_heredoc_end + +#keyset[ruby_heredoc_body, index] +ruby_heredoc_body_child( + int ruby_heredoc_body: @ruby_heredoc_body ref, + int index: int ref, + unique int child: @ruby_heredoc_body_child_type ref +); + +ruby_heredoc_body_def( + unique int id: @ruby_heredoc_body +); + +@ruby_if_alternative_type = @ruby_else | @ruby_elsif + +ruby_if_alternative( + unique int ruby_if: @ruby_if ref, + unique int alternative: @ruby_if_alternative_type ref +); + +ruby_if_consequence( + unique int ruby_if: @ruby_if ref, + unique int consequence: @ruby_then ref +); + +ruby_if_def( + unique int id: @ruby_if, + int condition: @ruby_underscore_statement ref +); + +ruby_if_guard_def( + unique int id: @ruby_if_guard, + int condition: @ruby_underscore_expression ref +); + +ruby_if_modifier_def( + unique int id: @ruby_if_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +ruby_in_def( + unique int id: @ruby_in, + int child: @ruby_underscore_arg ref +); + +ruby_in_clause_body( + unique int ruby_in_clause: @ruby_in_clause ref, + unique int body: @ruby_then ref +); + +@ruby_in_clause_guard_type = @ruby_if_guard | @ruby_unless_guard + +ruby_in_clause_guard( + unique int ruby_in_clause: @ruby_in_clause ref, + unique int guard: @ruby_in_clause_guard_type ref +); + +ruby_in_clause_def( + unique int id: @ruby_in_clause, + int pattern: @ruby_underscore_pattern_top_expr_body ref +); + +@ruby_interpolation_child_type = @ruby_token_empty_statement | @ruby_underscore_nonlocal_variable | @ruby_underscore_statement + +#keyset[ruby_interpolation, index] +ruby_interpolation_child( + int ruby_interpolation: @ruby_interpolation ref, + int index: int ref, + unique int child: @ruby_interpolation_child_type ref +); + +ruby_interpolation_def( + unique int id: @ruby_interpolation +); + +ruby_keyword_parameter_value( + unique int ruby_keyword_parameter: @ruby_keyword_parameter ref, + unique int value: @ruby_underscore_arg ref +); + +ruby_keyword_parameter_def( + unique int id: @ruby_keyword_parameter, + int name: @ruby_token_identifier ref +); + +@ruby_keyword_pattern_key_type = @ruby_string__ | @ruby_token_hash_key_symbol + +ruby_keyword_pattern_value( + unique int ruby_keyword_pattern: @ruby_keyword_pattern ref, + unique int value: @ruby_underscore_pattern_expr ref +); + +ruby_keyword_pattern_def( + unique int id: @ruby_keyword_pattern, + int key__: @ruby_keyword_pattern_key_type ref +); + +@ruby_lambda_body_type = @ruby_block | @ruby_do_block + +ruby_lambda_parameters( + unique int ruby_lambda: @ruby_lambda ref, + unique int parameters: @ruby_lambda_parameters ref +); + +ruby_lambda_def( + unique int id: @ruby_lambda, + int body: @ruby_lambda_body_type ref +); + +@ruby_lambda_parameters_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_lambda_parameters, index] +ruby_lambda_parameters_child( + int ruby_lambda_parameters: @ruby_lambda_parameters ref, + int index: int ref, + unique int child: @ruby_lambda_parameters_child_type ref +); + +ruby_lambda_parameters_def( + unique int id: @ruby_lambda_parameters +); + +@ruby_left_assignment_list_child_type = @ruby_destructured_left_assignment | @ruby_rest_assignment | @ruby_underscore_lhs + +#keyset[ruby_left_assignment_list, index] +ruby_left_assignment_list_child( + int ruby_left_assignment_list: @ruby_left_assignment_list ref, + int index: int ref, + unique int child: @ruby_left_assignment_list_child_type ref +); + +ruby_left_assignment_list_def( + unique int id: @ruby_left_assignment_list +); + +ruby_match_pattern_def( + unique int id: @ruby_match_pattern, + int pattern: @ruby_underscore_pattern_top_expr_body ref, + int value: @ruby_underscore_arg ref +); + +@ruby_method_body_type = @ruby_body_statement | @ruby_rescue_modifier | @ruby_underscore_arg + +ruby_method_body( + unique int ruby_method: @ruby_method ref, + unique int body: @ruby_method_body_type ref +); + +ruby_method_parameters( + unique int ruby_method: @ruby_method ref, + unique int parameters: @ruby_method_parameters ref +); + +ruby_method_def( + unique int id: @ruby_method, + int name: @ruby_underscore_method_name ref +); + +@ruby_method_parameters_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_method_parameters, index] +ruby_method_parameters_child( + int ruby_method_parameters: @ruby_method_parameters ref, + int index: int ref, + unique int child: @ruby_method_parameters_child_type ref +); + +ruby_method_parameters_def( + unique int id: @ruby_method_parameters +); + +ruby_module_body( + unique int ruby_module: @ruby_module ref, + unique int body: @ruby_body_statement ref +); + +@ruby_module_name_type = @ruby_scope_resolution | @ruby_token_constant + +ruby_module_def( + unique int id: @ruby_module, + int name: @ruby_module_name_type ref +); + +ruby_next_child( + unique int ruby_next: @ruby_next ref, + unique int child: @ruby_argument_list ref +); + +ruby_next_def( + unique int id: @ruby_next +); + +case @ruby_operator_assignment.operator of + 0 = @ruby_operator_assignment_percentequal +| 1 = @ruby_operator_assignment_ampersandampersandequal +| 2 = @ruby_operator_assignment_ampersandequal +| 3 = @ruby_operator_assignment_starstarequal +| 4 = @ruby_operator_assignment_starequal +| 5 = @ruby_operator_assignment_plusequal +| 6 = @ruby_operator_assignment_minusequal +| 7 = @ruby_operator_assignment_slashequal +| 8 = @ruby_operator_assignment_langlelangleequal +| 9 = @ruby_operator_assignment_ranglerangleequal +| 10 = @ruby_operator_assignment_caretequal +| 11 = @ruby_operator_assignment_pipeequal +| 12 = @ruby_operator_assignment_pipepipeequal +; + + +@ruby_operator_assignment_right_type = @ruby_rescue_modifier | @ruby_underscore_expression + +ruby_operator_assignment_def( + unique int id: @ruby_operator_assignment, + int left: @ruby_underscore_lhs ref, + int operator: int ref, + int right: @ruby_operator_assignment_right_type ref +); + +ruby_optional_parameter_def( + unique int id: @ruby_optional_parameter, + int name: @ruby_token_identifier ref, + int value: @ruby_underscore_arg ref +); + +@ruby_pair_key_type = @ruby_string__ | @ruby_token_hash_key_symbol | @ruby_underscore_arg + +ruby_pair_value( + unique int ruby_pair: @ruby_pair ref, + unique int value: @ruby_underscore_arg ref +); + +ruby_pair_def( + unique int id: @ruby_pair, + int key__: @ruby_pair_key_type ref +); + +ruby_parenthesized_pattern_def( + unique int id: @ruby_parenthesized_pattern, + int child: @ruby_underscore_pattern_expr ref +); + +@ruby_parenthesized_statements_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_parenthesized_statements, index] +ruby_parenthesized_statements_child( + int ruby_parenthesized_statements: @ruby_parenthesized_statements ref, + int index: int ref, + unique int child: @ruby_parenthesized_statements_child_type ref +); + +ruby_parenthesized_statements_def( + unique int id: @ruby_parenthesized_statements +); + +@ruby_pattern_child_type = @ruby_splat_argument | @ruby_underscore_arg + +ruby_pattern_def( + unique int id: @ruby_pattern, + int child: @ruby_pattern_child_type ref +); + +@ruby_program_child_type = @ruby_token_empty_statement | @ruby_token_uninterpreted | @ruby_underscore_statement + +#keyset[ruby_program, index] +ruby_program_child( + int ruby_program: @ruby_program ref, + int index: int ref, + unique int child: @ruby_program_child_type ref +); + +ruby_program_def( + unique int id: @ruby_program +); + +@ruby_range_begin_type = @ruby_underscore_arg | @ruby_underscore_pattern_primitive + +ruby_range_begin( + unique int ruby_range: @ruby_range ref, + unique int begin: @ruby_range_begin_type ref +); + +@ruby_range_end_type = @ruby_underscore_arg | @ruby_underscore_pattern_primitive + +ruby_range_end( + unique int ruby_range: @ruby_range ref, + unique int end: @ruby_range_end_type ref +); + +case @ruby_range.operator of + 0 = @ruby_range_dotdot +| 1 = @ruby_range_dotdotdot +; + + +ruby_range_def( + unique int id: @ruby_range, + int operator: int ref +); + +@ruby_rational_child_type = @ruby_token_float | @ruby_token_integer + +ruby_rational_def( + unique int id: @ruby_rational, + int child: @ruby_rational_child_type ref +); + +ruby_redo_child( + unique int ruby_redo: @ruby_redo ref, + unique int child: @ruby_argument_list ref +); + +ruby_redo_def( + unique int id: @ruby_redo +); + +@ruby_regex_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_regex, index] +ruby_regex_child( + int ruby_regex: @ruby_regex ref, + int index: int ref, + unique int child: @ruby_regex_child_type ref +); + +ruby_regex_def( + unique int id: @ruby_regex +); + +ruby_rescue_body( + unique int ruby_rescue: @ruby_rescue ref, + unique int body: @ruby_then ref +); + +ruby_rescue_exceptions( + unique int ruby_rescue: @ruby_rescue ref, + unique int exceptions: @ruby_exceptions ref +); + +ruby_rescue_variable( + unique int ruby_rescue: @ruby_rescue ref, + unique int variable: @ruby_exception_variable ref +); + +ruby_rescue_def( + unique int id: @ruby_rescue +); + +@ruby_rescue_modifier_body_type = @ruby_underscore_arg | @ruby_underscore_statement + +ruby_rescue_modifier_def( + unique int id: @ruby_rescue_modifier, + int body: @ruby_rescue_modifier_body_type ref, + int handler: @ruby_underscore_expression ref +); + +ruby_rest_assignment_child( + unique int ruby_rest_assignment: @ruby_rest_assignment ref, + unique int child: @ruby_underscore_lhs ref +); + +ruby_rest_assignment_def( + unique int id: @ruby_rest_assignment +); + +ruby_retry_child( + unique int ruby_retry: @ruby_retry ref, + unique int child: @ruby_argument_list ref +); + +ruby_retry_def( + unique int id: @ruby_retry +); + +ruby_return_child( + unique int ruby_return: @ruby_return ref, + unique int child: @ruby_argument_list ref +); + +ruby_return_def( + unique int id: @ruby_return +); + +@ruby_right_assignment_list_child_type = @ruby_splat_argument | @ruby_underscore_arg + +#keyset[ruby_right_assignment_list, index] +ruby_right_assignment_list_child( + int ruby_right_assignment_list: @ruby_right_assignment_list ref, + int index: int ref, + unique int child: @ruby_right_assignment_list_child_type ref +); + +ruby_right_assignment_list_def( + unique int id: @ruby_right_assignment_list +); + +@ruby_scope_resolution_scope_type = @ruby_underscore_pattern_constant | @ruby_underscore_primary + +ruby_scope_resolution_scope( + unique int ruby_scope_resolution: @ruby_scope_resolution ref, + unique int scope: @ruby_scope_resolution_scope_type ref +); + +ruby_scope_resolution_def( + unique int id: @ruby_scope_resolution, + int name: @ruby_token_constant ref +); + +ruby_setter_def( + unique int id: @ruby_setter, + int name: @ruby_token_identifier ref +); + +ruby_singleton_class_body( + unique int ruby_singleton_class: @ruby_singleton_class ref, + unique int body: @ruby_body_statement ref +); + +ruby_singleton_class_def( + unique int id: @ruby_singleton_class, + int value: @ruby_underscore_arg ref +); + +@ruby_singleton_method_body_type = @ruby_body_statement | @ruby_rescue_modifier | @ruby_underscore_arg + +ruby_singleton_method_body( + unique int ruby_singleton_method: @ruby_singleton_method ref, + unique int body: @ruby_singleton_method_body_type ref +); + +@ruby_singleton_method_object_type = @ruby_underscore_arg | @ruby_underscore_variable + +ruby_singleton_method_parameters( + unique int ruby_singleton_method: @ruby_singleton_method ref, + unique int parameters: @ruby_method_parameters ref +); + +ruby_singleton_method_def( + unique int id: @ruby_singleton_method, + int name: @ruby_underscore_method_name ref, + int object: @ruby_singleton_method_object_type ref +); + +ruby_splat_argument_child( + unique int ruby_splat_argument: @ruby_splat_argument ref, + unique int child: @ruby_underscore_arg ref +); + +ruby_splat_argument_def( + unique int id: @ruby_splat_argument +); + +ruby_splat_parameter_name( + unique int ruby_splat_parameter: @ruby_splat_parameter ref, + unique int name: @ruby_token_identifier ref +); + +ruby_splat_parameter_def( + unique int id: @ruby_splat_parameter +); + +@ruby_string_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_string__, index] +ruby_string_child( + int ruby_string__: @ruby_string__ ref, + int index: int ref, + unique int child: @ruby_string_child_type ref +); + +ruby_string_def( + unique int id: @ruby_string__ +); + +#keyset[ruby_string_array, index] +ruby_string_array_child( + int ruby_string_array: @ruby_string_array ref, + int index: int ref, + unique int child: @ruby_bare_string ref +); + +ruby_string_array_def( + unique int id: @ruby_string_array +); + +@ruby_subshell_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_subshell, index] +ruby_subshell_child( + int ruby_subshell: @ruby_subshell ref, + int index: int ref, + unique int child: @ruby_subshell_child_type ref +); + +ruby_subshell_def( + unique int id: @ruby_subshell +); + +ruby_superclass_def( + unique int id: @ruby_superclass, + int child: @ruby_underscore_expression ref +); + +#keyset[ruby_symbol_array, index] +ruby_symbol_array_child( + int ruby_symbol_array: @ruby_symbol_array ref, + int index: int ref, + unique int child: @ruby_bare_symbol ref +); + +ruby_symbol_array_def( + unique int id: @ruby_symbol_array +); + +ruby_test_pattern_def( + unique int id: @ruby_test_pattern, + int pattern: @ruby_underscore_pattern_top_expr_body ref, + int value: @ruby_underscore_arg ref +); + +@ruby_then_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_then, index] +ruby_then_child( + int ruby_then: @ruby_then ref, + int index: int ref, + unique int child: @ruby_then_child_type ref +); + +ruby_then_def( + unique int id: @ruby_then +); + +@ruby_unary_operand_type = @ruby_parenthesized_statements | @ruby_underscore_expression | @ruby_underscore_simple_numeric + +case @ruby_unary.operator of + 0 = @ruby_unary_bang +| 1 = @ruby_unary_plus +| 2 = @ruby_unary_minus +| 3 = @ruby_unary_definedquestion +| 4 = @ruby_unary_not +| 5 = @ruby_unary_tilde +; + + +ruby_unary_def( + unique int id: @ruby_unary, + int operand: @ruby_unary_operand_type ref, + int operator: int ref +); + +#keyset[ruby_undef, index] +ruby_undef_child( + int ruby_undef: @ruby_undef ref, + int index: int ref, + unique int child: @ruby_underscore_method_name ref +); + +ruby_undef_def( + unique int id: @ruby_undef +); + +@ruby_unless_alternative_type = @ruby_else | @ruby_elsif + +ruby_unless_alternative( + unique int ruby_unless: @ruby_unless ref, + unique int alternative: @ruby_unless_alternative_type ref +); + +ruby_unless_consequence( + unique int ruby_unless: @ruby_unless ref, + unique int consequence: @ruby_then ref +); + +ruby_unless_def( + unique int id: @ruby_unless, + int condition: @ruby_underscore_statement ref +); + +ruby_unless_guard_def( + unique int id: @ruby_unless_guard, + int condition: @ruby_underscore_expression ref +); + +ruby_unless_modifier_def( + unique int id: @ruby_unless_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +ruby_until_def( + unique int id: @ruby_until, + int body: @ruby_do ref, + int condition: @ruby_underscore_statement ref +); + +ruby_until_modifier_def( + unique int id: @ruby_until_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +@ruby_variable_reference_pattern_name_type = @ruby_token_identifier | @ruby_underscore_nonlocal_variable + +ruby_variable_reference_pattern_def( + unique int id: @ruby_variable_reference_pattern, + int name: @ruby_variable_reference_pattern_name_type ref +); + +ruby_when_body( + unique int ruby_when: @ruby_when ref, + unique int body: @ruby_then ref +); + +#keyset[ruby_when, index] +ruby_when_pattern( + int ruby_when: @ruby_when ref, + int index: int ref, + unique int pattern: @ruby_pattern ref +); + +ruby_when_def( + unique int id: @ruby_when +); + +ruby_while_def( + unique int id: @ruby_while, + int body: @ruby_do ref, + int condition: @ruby_underscore_statement ref +); + +ruby_while_modifier_def( + unique int id: @ruby_while_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +ruby_yield_child( + unique int ruby_yield: @ruby_yield ref, + unique int child: @ruby_argument_list ref +); + +ruby_yield_def( + unique int id: @ruby_yield +); + +ruby_tokeninfo( + unique int id: @ruby_token, + int kind: int ref, + string value: string ref +); + +case @ruby_token.kind of + 0 = @ruby_reserved_word +| 1 = @ruby_token_character +| 2 = @ruby_token_class_variable +| 3 = @ruby_token_comment +| 4 = @ruby_token_constant +| 5 = @ruby_token_empty_statement +| 6 = @ruby_token_encoding +| 7 = @ruby_token_escape_sequence +| 8 = @ruby_token_false +| 9 = @ruby_token_file +| 10 = @ruby_token_float +| 11 = @ruby_token_forward_argument +| 12 = @ruby_token_forward_parameter +| 13 = @ruby_token_global_variable +| 14 = @ruby_token_hash_key_symbol +| 15 = @ruby_token_hash_splat_nil +| 16 = @ruby_token_heredoc_beginning +| 17 = @ruby_token_heredoc_content +| 18 = @ruby_token_heredoc_end +| 19 = @ruby_token_identifier +| 20 = @ruby_token_instance_variable +| 21 = @ruby_token_integer +| 22 = @ruby_token_line +| 23 = @ruby_token_nil +| 24 = @ruby_token_operator +| 25 = @ruby_token_self +| 26 = @ruby_token_simple_symbol +| 27 = @ruby_token_string_content +| 28 = @ruby_token_super +| 29 = @ruby_token_true +| 30 = @ruby_token_uninterpreted +; + + +@ruby_ast_node = @ruby_alias | @ruby_alternative_pattern | @ruby_argument_list | @ruby_array | @ruby_array_pattern | @ruby_as_pattern | @ruby_assignment | @ruby_bare_string | @ruby_bare_symbol | @ruby_begin | @ruby_begin_block | @ruby_binary | @ruby_block | @ruby_block_argument | @ruby_block_body | @ruby_block_parameter | @ruby_block_parameters | @ruby_body_statement | @ruby_break | @ruby_call | @ruby_case__ | @ruby_case_match | @ruby_chained_string | @ruby_class | @ruby_complex | @ruby_conditional | @ruby_delimited_symbol | @ruby_destructured_left_assignment | @ruby_destructured_parameter | @ruby_do | @ruby_do_block | @ruby_element_reference | @ruby_else | @ruby_elsif | @ruby_end_block | @ruby_ensure | @ruby_exception_variable | @ruby_exceptions | @ruby_expression_reference_pattern | @ruby_find_pattern | @ruby_for | @ruby_hash | @ruby_hash_pattern | @ruby_hash_splat_argument | @ruby_hash_splat_parameter | @ruby_heredoc_body | @ruby_if | @ruby_if_guard | @ruby_if_modifier | @ruby_in | @ruby_in_clause | @ruby_interpolation | @ruby_keyword_parameter | @ruby_keyword_pattern | @ruby_lambda | @ruby_lambda_parameters | @ruby_left_assignment_list | @ruby_match_pattern | @ruby_method | @ruby_method_parameters | @ruby_module | @ruby_next | @ruby_operator_assignment | @ruby_optional_parameter | @ruby_pair | @ruby_parenthesized_pattern | @ruby_parenthesized_statements | @ruby_pattern | @ruby_program | @ruby_range | @ruby_rational | @ruby_redo | @ruby_regex | @ruby_rescue | @ruby_rescue_modifier | @ruby_rest_assignment | @ruby_retry | @ruby_return | @ruby_right_assignment_list | @ruby_scope_resolution | @ruby_setter | @ruby_singleton_class | @ruby_singleton_method | @ruby_splat_argument | @ruby_splat_parameter | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_superclass | @ruby_symbol_array | @ruby_test_pattern | @ruby_then | @ruby_token | @ruby_unary | @ruby_undef | @ruby_unless | @ruby_unless_guard | @ruby_unless_modifier | @ruby_until | @ruby_until_modifier | @ruby_variable_reference_pattern | @ruby_when | @ruby_while | @ruby_while_modifier | @ruby_yield + +ruby_ast_node_location( + unique int node: @ruby_ast_node ref, + int loc: @location_default ref +); + +#keyset[parent, parent_index] +ruby_ast_node_parent( + unique int node: @ruby_ast_node ref, + int parent: @ruby_ast_node ref, + int parent_index: int ref +); + +/*- Erb dbscheme -*/ +erb_comment_directive_child( + unique int erb_comment_directive: @erb_comment_directive ref, + unique int child: @erb_token_comment ref +); + +erb_comment_directive_def( + unique int id: @erb_comment_directive +); + +erb_directive_child( + unique int erb_directive: @erb_directive ref, + unique int child: @erb_token_code ref +); + +erb_directive_def( + unique int id: @erb_directive +); + +erb_graphql_directive_child( + unique int erb_graphql_directive: @erb_graphql_directive ref, + unique int child: @erb_token_code ref +); + +erb_graphql_directive_def( + unique int id: @erb_graphql_directive +); + +erb_output_directive_child( + unique int erb_output_directive: @erb_output_directive ref, + unique int child: @erb_token_code ref +); + +erb_output_directive_def( + unique int id: @erb_output_directive +); + +@erb_template_child_type = @erb_comment_directive | @erb_directive | @erb_graphql_directive | @erb_output_directive | @erb_token_content + +#keyset[erb_template, index] +erb_template_child( + int erb_template: @erb_template ref, + int index: int ref, + unique int child: @erb_template_child_type ref +); + +erb_template_def( + unique int id: @erb_template +); + +erb_tokeninfo( + unique int id: @erb_token, + int kind: int ref, + string value: string ref +); + +case @erb_token.kind of + 0 = @erb_reserved_word +| 1 = @erb_token_code +| 2 = @erb_token_comment +| 3 = @erb_token_content +; + + +@erb_ast_node = @erb_comment_directive | @erb_directive | @erb_graphql_directive | @erb_output_directive | @erb_template | @erb_token + +erb_ast_node_location( + unique int node: @erb_ast_node ref, + int loc: @location_default ref +); + +#keyset[parent, parent_index] +erb_ast_node_parent( + unique int node: @erb_ast_node ref, + int parent: @erb_ast_node ref, + int parent_index: int ref +); + diff --git a/ruby/downgrades/dc51d416301df12df5b70fbc4338de6cc1f82bfd/ruby.dbscheme b/ruby/downgrades/dc51d416301df12df5b70fbc4338de6cc1f82bfd/ruby.dbscheme new file mode 100644 index 000000000000..40a6b0a5e811 --- /dev/null +++ b/ruby/downgrades/dc51d416301df12df5b70fbc4338de6cc1f82bfd/ruby.dbscheme @@ -0,0 +1,1526 @@ +// CodeQL database schema for Ruby +// Automatically generated from the tree-sitter grammar; do not edit + +/*- Files and folders -*/ + +/** + * The location of an element. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @file | @folder + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/*- Empty location -*/ + +empty_location( + int location: @location_default ref +); + +/*- Source location prefix -*/ + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/*- Diagnostic messages -*/ + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/*- Diagnostic messages: severity -*/ + +case @diagnostic.severity of + 10 = @diagnostic_debug +| 20 = @diagnostic_info +| 30 = @diagnostic_warning +| 40 = @diagnostic_error +; + +/*- YAML -*/ + +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + string tag: string ref, + string tostring: string ref); + +case @yaml_node.kind of + 0 = @yaml_scalar_node +| 1 = @yaml_mapping_node +| 2 = @yaml_sequence_node +| 3 = @yaml_alias_node +; + +@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node; + +@yaml_node_parent = @yaml_collection_node | @file; + +yaml_anchors (unique int node: @yaml_node ref, + string anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + string target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + string value: string ref); + +yaml_errors (unique int id: @yaml_error, + string message: string ref); + +yaml_locations(unique int locatable: @yaml_locatable ref, + int location: @location_default ref); + +@yaml_locatable = @yaml_node | @yaml_error; + +/*- Ruby dbscheme -*/ +@ruby_underscore_arg = @ruby_assignment | @ruby_binary | @ruby_conditional | @ruby_operator_assignment | @ruby_range | @ruby_unary | @ruby_underscore_primary + +@ruby_underscore_call_operator = @ruby_reserved_word + +@ruby_underscore_expression = @ruby_assignment | @ruby_binary | @ruby_break | @ruby_call | @ruby_match_pattern | @ruby_next | @ruby_operator_assignment | @ruby_return | @ruby_test_pattern | @ruby_unary | @ruby_underscore_arg | @ruby_yield + +@ruby_underscore_lhs = @ruby_call | @ruby_element_reference | @ruby_scope_resolution | @ruby_token_false | @ruby_token_nil | @ruby_token_true | @ruby_underscore_variable + +@ruby_underscore_method_name = @ruby_delimited_symbol | @ruby_setter | @ruby_token_constant | @ruby_token_identifier | @ruby_token_operator | @ruby_token_simple_symbol | @ruby_underscore_nonlocal_variable + +@ruby_underscore_nonlocal_variable = @ruby_token_class_variable | @ruby_token_global_variable | @ruby_token_instance_variable + +@ruby_underscore_pattern_constant = @ruby_scope_resolution | @ruby_token_constant + +@ruby_underscore_pattern_expr = @ruby_alternative_pattern | @ruby_as_pattern | @ruby_underscore_pattern_expr_basic + +@ruby_underscore_pattern_expr_basic = @ruby_array_pattern | @ruby_expression_reference_pattern | @ruby_find_pattern | @ruby_hash_pattern | @ruby_parenthesized_pattern | @ruby_range | @ruby_token_identifier | @ruby_underscore_pattern_constant | @ruby_underscore_pattern_primitive | @ruby_variable_reference_pattern + +@ruby_underscore_pattern_primitive = @ruby_delimited_symbol | @ruby_lambda | @ruby_regex | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_symbol_array | @ruby_token_encoding | @ruby_token_false | @ruby_token_file | @ruby_token_heredoc_beginning | @ruby_token_line | @ruby_token_nil | @ruby_token_self | @ruby_token_simple_symbol | @ruby_token_true | @ruby_unary | @ruby_underscore_simple_numeric + +@ruby_underscore_pattern_top_expr_body = @ruby_array_pattern | @ruby_find_pattern | @ruby_hash_pattern | @ruby_underscore_pattern_expr + +@ruby_underscore_primary = @ruby_array | @ruby_begin | @ruby_break | @ruby_call | @ruby_case__ | @ruby_case_match | @ruby_chained_string | @ruby_class | @ruby_delimited_symbol | @ruby_for | @ruby_hash | @ruby_if | @ruby_lambda | @ruby_method | @ruby_module | @ruby_next | @ruby_parenthesized_statements | @ruby_redo | @ruby_regex | @ruby_retry | @ruby_return | @ruby_singleton_class | @ruby_singleton_method | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_symbol_array | @ruby_token_character | @ruby_token_heredoc_beginning | @ruby_token_simple_symbol | @ruby_unary | @ruby_underscore_lhs | @ruby_underscore_simple_numeric | @ruby_unless | @ruby_until | @ruby_while | @ruby_yield + +@ruby_underscore_simple_numeric = @ruby_complex | @ruby_rational | @ruby_token_float | @ruby_token_integer + +@ruby_underscore_statement = @ruby_alias | @ruby_begin_block | @ruby_end_block | @ruby_if_modifier | @ruby_rescue_modifier | @ruby_undef | @ruby_underscore_expression | @ruby_unless_modifier | @ruby_until_modifier | @ruby_while_modifier + +@ruby_underscore_variable = @ruby_token_constant | @ruby_token_identifier | @ruby_token_self | @ruby_token_super | @ruby_underscore_nonlocal_variable + +ruby_alias_def( + unique int id: @ruby_alias, + int alias: @ruby_underscore_method_name ref, + int name: @ruby_underscore_method_name ref +); + +#keyset[ruby_alternative_pattern, index] +ruby_alternative_pattern_alternatives( + int ruby_alternative_pattern: @ruby_alternative_pattern ref, + int index: int ref, + unique int alternatives: @ruby_underscore_pattern_expr_basic ref +); + +ruby_alternative_pattern_def( + unique int id: @ruby_alternative_pattern +); + +@ruby_argument_list_child_type = @ruby_block_argument | @ruby_hash_splat_argument | @ruby_pair | @ruby_splat_argument | @ruby_token_forward_argument | @ruby_underscore_expression + +#keyset[ruby_argument_list, index] +ruby_argument_list_child( + int ruby_argument_list: @ruby_argument_list ref, + int index: int ref, + unique int child: @ruby_argument_list_child_type ref +); + +ruby_argument_list_def( + unique int id: @ruby_argument_list +); + +@ruby_array_child_type = @ruby_block_argument | @ruby_hash_splat_argument | @ruby_pair | @ruby_splat_argument | @ruby_token_forward_argument | @ruby_underscore_expression + +#keyset[ruby_array, index] +ruby_array_child( + int ruby_array: @ruby_array ref, + int index: int ref, + unique int child: @ruby_array_child_type ref +); + +ruby_array_def( + unique int id: @ruby_array +); + +ruby_array_pattern_class( + unique int ruby_array_pattern: @ruby_array_pattern ref, + unique int class: @ruby_underscore_pattern_constant ref +); + +@ruby_array_pattern_child_type = @ruby_splat_parameter | @ruby_underscore_pattern_expr + +#keyset[ruby_array_pattern, index] +ruby_array_pattern_child( + int ruby_array_pattern: @ruby_array_pattern ref, + int index: int ref, + unique int child: @ruby_array_pattern_child_type ref +); + +ruby_array_pattern_def( + unique int id: @ruby_array_pattern +); + +ruby_as_pattern_def( + unique int id: @ruby_as_pattern, + int name: @ruby_token_identifier ref, + int value: @ruby_underscore_pattern_expr ref +); + +@ruby_assignment_left_type = @ruby_left_assignment_list | @ruby_underscore_lhs + +@ruby_assignment_right_type = @ruby_rescue_modifier | @ruby_right_assignment_list | @ruby_splat_argument | @ruby_underscore_expression + +ruby_assignment_def( + unique int id: @ruby_assignment, + int left: @ruby_assignment_left_type ref, + int right: @ruby_assignment_right_type ref +); + +@ruby_bare_string_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_bare_string, index] +ruby_bare_string_child( + int ruby_bare_string: @ruby_bare_string ref, + int index: int ref, + unique int child: @ruby_bare_string_child_type ref +); + +ruby_bare_string_def( + unique int id: @ruby_bare_string +); + +@ruby_bare_symbol_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_bare_symbol, index] +ruby_bare_symbol_child( + int ruby_bare_symbol: @ruby_bare_symbol ref, + int index: int ref, + unique int child: @ruby_bare_symbol_child_type ref +); + +ruby_bare_symbol_def( + unique int id: @ruby_bare_symbol +); + +@ruby_begin_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_begin, index] +ruby_begin_child( + int ruby_begin: @ruby_begin ref, + int index: int ref, + unique int child: @ruby_begin_child_type ref +); + +ruby_begin_def( + unique int id: @ruby_begin +); + +@ruby_begin_block_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_begin_block, index] +ruby_begin_block_child( + int ruby_begin_block: @ruby_begin_block ref, + int index: int ref, + unique int child: @ruby_begin_block_child_type ref +); + +ruby_begin_block_def( + unique int id: @ruby_begin_block +); + +@ruby_binary_left_type = @ruby_underscore_expression | @ruby_underscore_simple_numeric + +case @ruby_binary.operator of + 0 = @ruby_binary_bangequal +| 1 = @ruby_binary_bangtilde +| 2 = @ruby_binary_percent +| 3 = @ruby_binary_ampersand +| 4 = @ruby_binary_ampersandampersand +| 5 = @ruby_binary_star +| 6 = @ruby_binary_starstar +| 7 = @ruby_binary_plus +| 8 = @ruby_binary_minus +| 9 = @ruby_binary_slash +| 10 = @ruby_binary_langle +| 11 = @ruby_binary_langlelangle +| 12 = @ruby_binary_langleequal +| 13 = @ruby_binary_langleequalrangle +| 14 = @ruby_binary_equalequal +| 15 = @ruby_binary_equalequalequal +| 16 = @ruby_binary_equaltilde +| 17 = @ruby_binary_rangle +| 18 = @ruby_binary_rangleequal +| 19 = @ruby_binary_ranglerangle +| 20 = @ruby_binary_caret +| 21 = @ruby_binary_and +| 22 = @ruby_binary_or +| 23 = @ruby_binary_pipe +| 24 = @ruby_binary_pipepipe +; + + +ruby_binary_def( + unique int id: @ruby_binary, + int left: @ruby_binary_left_type ref, + int operator: int ref, + int right: @ruby_underscore_expression ref +); + +ruby_block_body( + unique int ruby_block: @ruby_block ref, + unique int body: @ruby_block_body ref +); + +ruby_block_parameters( + unique int ruby_block: @ruby_block ref, + unique int parameters: @ruby_block_parameters ref +); + +ruby_block_def( + unique int id: @ruby_block +); + +ruby_block_argument_child( + unique int ruby_block_argument: @ruby_block_argument ref, + unique int child: @ruby_underscore_arg ref +); + +ruby_block_argument_def( + unique int id: @ruby_block_argument +); + +@ruby_block_body_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_block_body, index] +ruby_block_body_child( + int ruby_block_body: @ruby_block_body ref, + int index: int ref, + unique int child: @ruby_block_body_child_type ref +); + +ruby_block_body_def( + unique int id: @ruby_block_body +); + +ruby_block_parameter_name( + unique int ruby_block_parameter: @ruby_block_parameter ref, + unique int name: @ruby_token_identifier ref +); + +ruby_block_parameter_def( + unique int id: @ruby_block_parameter +); + +#keyset[ruby_block_parameters, index] +ruby_block_parameters_locals( + int ruby_block_parameters: @ruby_block_parameters ref, + int index: int ref, + unique int locals: @ruby_token_identifier ref +); + +@ruby_block_parameters_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_block_parameters, index] +ruby_block_parameters_child( + int ruby_block_parameters: @ruby_block_parameters ref, + int index: int ref, + unique int child: @ruby_block_parameters_child_type ref +); + +ruby_block_parameters_def( + unique int id: @ruby_block_parameters +); + +@ruby_body_statement_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_body_statement, index] +ruby_body_statement_child( + int ruby_body_statement: @ruby_body_statement ref, + int index: int ref, + unique int child: @ruby_body_statement_child_type ref +); + +ruby_body_statement_def( + unique int id: @ruby_body_statement +); + +ruby_break_child( + unique int ruby_break: @ruby_break ref, + unique int child: @ruby_argument_list ref +); + +ruby_break_def( + unique int id: @ruby_break +); + +ruby_call_arguments( + unique int ruby_call: @ruby_call ref, + unique int arguments: @ruby_argument_list ref +); + +@ruby_call_block_type = @ruby_block | @ruby_do_block + +ruby_call_block( + unique int ruby_call: @ruby_call ref, + unique int block: @ruby_call_block_type ref +); + +@ruby_call_method_type = @ruby_token_operator | @ruby_underscore_variable + +ruby_call_method( + unique int ruby_call: @ruby_call ref, + unique int method: @ruby_call_method_type ref +); + +ruby_call_operator( + unique int ruby_call: @ruby_call ref, + unique int operator: @ruby_underscore_call_operator ref +); + +ruby_call_receiver( + unique int ruby_call: @ruby_call ref, + unique int receiver: @ruby_underscore_primary ref +); + +ruby_call_def( + unique int id: @ruby_call +); + +ruby_case_value( + unique int ruby_case__: @ruby_case__ ref, + unique int value: @ruby_underscore_statement ref +); + +@ruby_case_child_type = @ruby_else | @ruby_when + +#keyset[ruby_case__, index] +ruby_case_child( + int ruby_case__: @ruby_case__ ref, + int index: int ref, + unique int child: @ruby_case_child_type ref +); + +ruby_case_def( + unique int id: @ruby_case__ +); + +#keyset[ruby_case_match, index] +ruby_case_match_clauses( + int ruby_case_match: @ruby_case_match ref, + int index: int ref, + unique int clauses: @ruby_in_clause ref +); + +ruby_case_match_else( + unique int ruby_case_match: @ruby_case_match ref, + unique int else: @ruby_else ref +); + +ruby_case_match_def( + unique int id: @ruby_case_match, + int value: @ruby_underscore_statement ref +); + +#keyset[ruby_chained_string, index] +ruby_chained_string_child( + int ruby_chained_string: @ruby_chained_string ref, + int index: int ref, + unique int child: @ruby_string__ ref +); + +ruby_chained_string_def( + unique int id: @ruby_chained_string +); + +ruby_class_body( + unique int ruby_class: @ruby_class ref, + unique int body: @ruby_body_statement ref +); + +@ruby_class_name_type = @ruby_scope_resolution | @ruby_token_constant + +ruby_class_superclass( + unique int ruby_class: @ruby_class ref, + unique int superclass: @ruby_superclass ref +); + +ruby_class_def( + unique int id: @ruby_class, + int name: @ruby_class_name_type ref +); + +@ruby_complex_child_type = @ruby_rational | @ruby_token_float | @ruby_token_integer + +ruby_complex_def( + unique int id: @ruby_complex, + int child: @ruby_complex_child_type ref +); + +ruby_conditional_def( + unique int id: @ruby_conditional, + int alternative: @ruby_underscore_arg ref, + int condition: @ruby_underscore_arg ref, + int consequence: @ruby_underscore_arg ref +); + +@ruby_delimited_symbol_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_delimited_symbol, index] +ruby_delimited_symbol_child( + int ruby_delimited_symbol: @ruby_delimited_symbol ref, + int index: int ref, + unique int child: @ruby_delimited_symbol_child_type ref +); + +ruby_delimited_symbol_def( + unique int id: @ruby_delimited_symbol +); + +@ruby_destructured_left_assignment_child_type = @ruby_destructured_left_assignment | @ruby_rest_assignment | @ruby_underscore_lhs + +#keyset[ruby_destructured_left_assignment, index] +ruby_destructured_left_assignment_child( + int ruby_destructured_left_assignment: @ruby_destructured_left_assignment ref, + int index: int ref, + unique int child: @ruby_destructured_left_assignment_child_type ref +); + +ruby_destructured_left_assignment_def( + unique int id: @ruby_destructured_left_assignment +); + +@ruby_destructured_parameter_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_destructured_parameter, index] +ruby_destructured_parameter_child( + int ruby_destructured_parameter: @ruby_destructured_parameter ref, + int index: int ref, + unique int child: @ruby_destructured_parameter_child_type ref +); + +ruby_destructured_parameter_def( + unique int id: @ruby_destructured_parameter +); + +@ruby_do_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_do, index] +ruby_do_child( + int ruby_do: @ruby_do ref, + int index: int ref, + unique int child: @ruby_do_child_type ref +); + +ruby_do_def( + unique int id: @ruby_do +); + +ruby_do_block_body( + unique int ruby_do_block: @ruby_do_block ref, + unique int body: @ruby_body_statement ref +); + +ruby_do_block_parameters( + unique int ruby_do_block: @ruby_do_block ref, + unique int parameters: @ruby_block_parameters ref +); + +ruby_do_block_def( + unique int id: @ruby_do_block +); + +@ruby_element_reference_block_type = @ruby_block | @ruby_do_block + +ruby_element_reference_block( + unique int ruby_element_reference: @ruby_element_reference ref, + unique int block: @ruby_element_reference_block_type ref +); + +@ruby_element_reference_child_type = @ruby_block_argument | @ruby_hash_splat_argument | @ruby_pair | @ruby_splat_argument | @ruby_token_forward_argument | @ruby_underscore_expression + +#keyset[ruby_element_reference, index] +ruby_element_reference_child( + int ruby_element_reference: @ruby_element_reference ref, + int index: int ref, + unique int child: @ruby_element_reference_child_type ref +); + +ruby_element_reference_def( + unique int id: @ruby_element_reference, + int object: @ruby_underscore_primary ref +); + +@ruby_else_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_else, index] +ruby_else_child( + int ruby_else: @ruby_else ref, + int index: int ref, + unique int child: @ruby_else_child_type ref +); + +ruby_else_def( + unique int id: @ruby_else +); + +@ruby_elsif_alternative_type = @ruby_else | @ruby_elsif + +ruby_elsif_alternative( + unique int ruby_elsif: @ruby_elsif ref, + unique int alternative: @ruby_elsif_alternative_type ref +); + +ruby_elsif_consequence( + unique int ruby_elsif: @ruby_elsif ref, + unique int consequence: @ruby_then ref +); + +ruby_elsif_def( + unique int id: @ruby_elsif, + int condition: @ruby_underscore_statement ref +); + +@ruby_end_block_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_end_block, index] +ruby_end_block_child( + int ruby_end_block: @ruby_end_block ref, + int index: int ref, + unique int child: @ruby_end_block_child_type ref +); + +ruby_end_block_def( + unique int id: @ruby_end_block +); + +@ruby_ensure_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_ensure, index] +ruby_ensure_child( + int ruby_ensure: @ruby_ensure ref, + int index: int ref, + unique int child: @ruby_ensure_child_type ref +); + +ruby_ensure_def( + unique int id: @ruby_ensure +); + +ruby_exception_variable_def( + unique int id: @ruby_exception_variable, + int child: @ruby_underscore_lhs ref +); + +@ruby_exceptions_child_type = @ruby_splat_argument | @ruby_underscore_arg + +#keyset[ruby_exceptions, index] +ruby_exceptions_child( + int ruby_exceptions: @ruby_exceptions ref, + int index: int ref, + unique int child: @ruby_exceptions_child_type ref +); + +ruby_exceptions_def( + unique int id: @ruby_exceptions +); + +ruby_expression_reference_pattern_def( + unique int id: @ruby_expression_reference_pattern, + int value: @ruby_underscore_expression ref +); + +ruby_find_pattern_class( + unique int ruby_find_pattern: @ruby_find_pattern ref, + unique int class: @ruby_underscore_pattern_constant ref +); + +@ruby_find_pattern_child_type = @ruby_splat_parameter | @ruby_underscore_pattern_expr + +#keyset[ruby_find_pattern, index] +ruby_find_pattern_child( + int ruby_find_pattern: @ruby_find_pattern ref, + int index: int ref, + unique int child: @ruby_find_pattern_child_type ref +); + +ruby_find_pattern_def( + unique int id: @ruby_find_pattern +); + +@ruby_for_pattern_type = @ruby_left_assignment_list | @ruby_underscore_lhs + +ruby_for_def( + unique int id: @ruby_for, + int body: @ruby_do ref, + int pattern: @ruby_for_pattern_type ref, + int value: @ruby_in ref +); + +@ruby_hash_child_type = @ruby_hash_splat_argument | @ruby_pair + +#keyset[ruby_hash, index] +ruby_hash_child( + int ruby_hash: @ruby_hash ref, + int index: int ref, + unique int child: @ruby_hash_child_type ref +); + +ruby_hash_def( + unique int id: @ruby_hash +); + +ruby_hash_pattern_class( + unique int ruby_hash_pattern: @ruby_hash_pattern ref, + unique int class: @ruby_underscore_pattern_constant ref +); + +@ruby_hash_pattern_child_type = @ruby_hash_splat_parameter | @ruby_keyword_pattern | @ruby_token_hash_splat_nil + +#keyset[ruby_hash_pattern, index] +ruby_hash_pattern_child( + int ruby_hash_pattern: @ruby_hash_pattern ref, + int index: int ref, + unique int child: @ruby_hash_pattern_child_type ref +); + +ruby_hash_pattern_def( + unique int id: @ruby_hash_pattern +); + +ruby_hash_splat_argument_child( + unique int ruby_hash_splat_argument: @ruby_hash_splat_argument ref, + unique int child: @ruby_underscore_arg ref +); + +ruby_hash_splat_argument_def( + unique int id: @ruby_hash_splat_argument +); + +ruby_hash_splat_parameter_name( + unique int ruby_hash_splat_parameter: @ruby_hash_splat_parameter ref, + unique int name: @ruby_token_identifier ref +); + +ruby_hash_splat_parameter_def( + unique int id: @ruby_hash_splat_parameter +); + +@ruby_heredoc_body_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_heredoc_content | @ruby_token_heredoc_end + +#keyset[ruby_heredoc_body, index] +ruby_heredoc_body_child( + int ruby_heredoc_body: @ruby_heredoc_body ref, + int index: int ref, + unique int child: @ruby_heredoc_body_child_type ref +); + +ruby_heredoc_body_def( + unique int id: @ruby_heredoc_body +); + +@ruby_if_alternative_type = @ruby_else | @ruby_elsif + +ruby_if_alternative( + unique int ruby_if: @ruby_if ref, + unique int alternative: @ruby_if_alternative_type ref +); + +ruby_if_consequence( + unique int ruby_if: @ruby_if ref, + unique int consequence: @ruby_then ref +); + +ruby_if_def( + unique int id: @ruby_if, + int condition: @ruby_underscore_statement ref +); + +ruby_if_guard_def( + unique int id: @ruby_if_guard, + int condition: @ruby_underscore_expression ref +); + +ruby_if_modifier_def( + unique int id: @ruby_if_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +ruby_in_def( + unique int id: @ruby_in, + int child: @ruby_underscore_arg ref +); + +ruby_in_clause_body( + unique int ruby_in_clause: @ruby_in_clause ref, + unique int body: @ruby_then ref +); + +@ruby_in_clause_guard_type = @ruby_if_guard | @ruby_unless_guard + +ruby_in_clause_guard( + unique int ruby_in_clause: @ruby_in_clause ref, + unique int guard: @ruby_in_clause_guard_type ref +); + +ruby_in_clause_def( + unique int id: @ruby_in_clause, + int pattern: @ruby_underscore_pattern_top_expr_body ref +); + +@ruby_interpolation_child_type = @ruby_token_empty_statement | @ruby_underscore_nonlocal_variable | @ruby_underscore_statement + +#keyset[ruby_interpolation, index] +ruby_interpolation_child( + int ruby_interpolation: @ruby_interpolation ref, + int index: int ref, + unique int child: @ruby_interpolation_child_type ref +); + +ruby_interpolation_def( + unique int id: @ruby_interpolation +); + +ruby_keyword_parameter_value( + unique int ruby_keyword_parameter: @ruby_keyword_parameter ref, + unique int value: @ruby_underscore_arg ref +); + +ruby_keyword_parameter_def( + unique int id: @ruby_keyword_parameter, + int name: @ruby_token_identifier ref +); + +@ruby_keyword_pattern_key_type = @ruby_string__ | @ruby_token_hash_key_symbol + +ruby_keyword_pattern_value( + unique int ruby_keyword_pattern: @ruby_keyword_pattern ref, + unique int value: @ruby_underscore_pattern_expr ref +); + +ruby_keyword_pattern_def( + unique int id: @ruby_keyword_pattern, + int key__: @ruby_keyword_pattern_key_type ref +); + +@ruby_lambda_body_type = @ruby_block | @ruby_do_block + +ruby_lambda_parameters( + unique int ruby_lambda: @ruby_lambda ref, + unique int parameters: @ruby_lambda_parameters ref +); + +ruby_lambda_def( + unique int id: @ruby_lambda, + int body: @ruby_lambda_body_type ref +); + +@ruby_lambda_parameters_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_lambda_parameters, index] +ruby_lambda_parameters_child( + int ruby_lambda_parameters: @ruby_lambda_parameters ref, + int index: int ref, + unique int child: @ruby_lambda_parameters_child_type ref +); + +ruby_lambda_parameters_def( + unique int id: @ruby_lambda_parameters +); + +@ruby_left_assignment_list_child_type = @ruby_destructured_left_assignment | @ruby_rest_assignment | @ruby_underscore_lhs + +#keyset[ruby_left_assignment_list, index] +ruby_left_assignment_list_child( + int ruby_left_assignment_list: @ruby_left_assignment_list ref, + int index: int ref, + unique int child: @ruby_left_assignment_list_child_type ref +); + +ruby_left_assignment_list_def( + unique int id: @ruby_left_assignment_list +); + +ruby_match_pattern_def( + unique int id: @ruby_match_pattern, + int pattern: @ruby_underscore_pattern_top_expr_body ref, + int value: @ruby_underscore_arg ref +); + +@ruby_method_body_type = @ruby_body_statement | @ruby_rescue_modifier | @ruby_underscore_arg + +ruby_method_body( + unique int ruby_method: @ruby_method ref, + unique int body: @ruby_method_body_type ref +); + +ruby_method_parameters( + unique int ruby_method: @ruby_method ref, + unique int parameters: @ruby_method_parameters ref +); + +ruby_method_def( + unique int id: @ruby_method, + int name: @ruby_underscore_method_name ref +); + +@ruby_method_parameters_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_method_parameters, index] +ruby_method_parameters_child( + int ruby_method_parameters: @ruby_method_parameters ref, + int index: int ref, + unique int child: @ruby_method_parameters_child_type ref +); + +ruby_method_parameters_def( + unique int id: @ruby_method_parameters +); + +ruby_module_body( + unique int ruby_module: @ruby_module ref, + unique int body: @ruby_body_statement ref +); + +@ruby_module_name_type = @ruby_scope_resolution | @ruby_token_constant + +ruby_module_def( + unique int id: @ruby_module, + int name: @ruby_module_name_type ref +); + +ruby_next_child( + unique int ruby_next: @ruby_next ref, + unique int child: @ruby_argument_list ref +); + +ruby_next_def( + unique int id: @ruby_next +); + +case @ruby_operator_assignment.operator of + 0 = @ruby_operator_assignment_percentequal +| 1 = @ruby_operator_assignment_ampersandampersandequal +| 2 = @ruby_operator_assignment_ampersandequal +| 3 = @ruby_operator_assignment_starstarequal +| 4 = @ruby_operator_assignment_starequal +| 5 = @ruby_operator_assignment_plusequal +| 6 = @ruby_operator_assignment_minusequal +| 7 = @ruby_operator_assignment_slashequal +| 8 = @ruby_operator_assignment_langlelangleequal +| 9 = @ruby_operator_assignment_ranglerangleequal +| 10 = @ruby_operator_assignment_caretequal +| 11 = @ruby_operator_assignment_pipeequal +| 12 = @ruby_operator_assignment_pipepipeequal +; + + +@ruby_operator_assignment_right_type = @ruby_rescue_modifier | @ruby_underscore_expression + +ruby_operator_assignment_def( + unique int id: @ruby_operator_assignment, + int left: @ruby_underscore_lhs ref, + int operator: int ref, + int right: @ruby_operator_assignment_right_type ref +); + +ruby_optional_parameter_def( + unique int id: @ruby_optional_parameter, + int name: @ruby_token_identifier ref, + int value: @ruby_underscore_arg ref +); + +@ruby_pair_key_type = @ruby_string__ | @ruby_token_hash_key_symbol | @ruby_underscore_arg + +ruby_pair_value( + unique int ruby_pair: @ruby_pair ref, + unique int value: @ruby_underscore_arg ref +); + +ruby_pair_def( + unique int id: @ruby_pair, + int key__: @ruby_pair_key_type ref +); + +ruby_parenthesized_pattern_def( + unique int id: @ruby_parenthesized_pattern, + int child: @ruby_underscore_pattern_expr ref +); + +@ruby_parenthesized_statements_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_parenthesized_statements, index] +ruby_parenthesized_statements_child( + int ruby_parenthesized_statements: @ruby_parenthesized_statements ref, + int index: int ref, + unique int child: @ruby_parenthesized_statements_child_type ref +); + +ruby_parenthesized_statements_def( + unique int id: @ruby_parenthesized_statements +); + +@ruby_pattern_child_type = @ruby_splat_argument | @ruby_underscore_arg + +ruby_pattern_def( + unique int id: @ruby_pattern, + int child: @ruby_pattern_child_type ref +); + +@ruby_program_child_type = @ruby_token_empty_statement | @ruby_token_uninterpreted | @ruby_underscore_statement + +#keyset[ruby_program, index] +ruby_program_child( + int ruby_program: @ruby_program ref, + int index: int ref, + unique int child: @ruby_program_child_type ref +); + +ruby_program_def( + unique int id: @ruby_program +); + +@ruby_range_begin_type = @ruby_underscore_arg | @ruby_underscore_pattern_primitive + +ruby_range_begin( + unique int ruby_range: @ruby_range ref, + unique int begin: @ruby_range_begin_type ref +); + +@ruby_range_end_type = @ruby_underscore_arg | @ruby_underscore_pattern_primitive + +ruby_range_end( + unique int ruby_range: @ruby_range ref, + unique int end: @ruby_range_end_type ref +); + +case @ruby_range.operator of + 0 = @ruby_range_dotdot +| 1 = @ruby_range_dotdotdot +; + + +ruby_range_def( + unique int id: @ruby_range, + int operator: int ref +); + +@ruby_rational_child_type = @ruby_token_float | @ruby_token_integer + +ruby_rational_def( + unique int id: @ruby_rational, + int child: @ruby_rational_child_type ref +); + +ruby_redo_child( + unique int ruby_redo: @ruby_redo ref, + unique int child: @ruby_argument_list ref +); + +ruby_redo_def( + unique int id: @ruby_redo +); + +@ruby_regex_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_regex, index] +ruby_regex_child( + int ruby_regex: @ruby_regex ref, + int index: int ref, + unique int child: @ruby_regex_child_type ref +); + +ruby_regex_def( + unique int id: @ruby_regex +); + +ruby_rescue_body( + unique int ruby_rescue: @ruby_rescue ref, + unique int body: @ruby_then ref +); + +ruby_rescue_exceptions( + unique int ruby_rescue: @ruby_rescue ref, + unique int exceptions: @ruby_exceptions ref +); + +ruby_rescue_variable( + unique int ruby_rescue: @ruby_rescue ref, + unique int variable: @ruby_exception_variable ref +); + +ruby_rescue_def( + unique int id: @ruby_rescue +); + +@ruby_rescue_modifier_body_type = @ruby_underscore_arg | @ruby_underscore_statement + +ruby_rescue_modifier_def( + unique int id: @ruby_rescue_modifier, + int body: @ruby_rescue_modifier_body_type ref, + int handler: @ruby_underscore_expression ref +); + +ruby_rest_assignment_child( + unique int ruby_rest_assignment: @ruby_rest_assignment ref, + unique int child: @ruby_underscore_lhs ref +); + +ruby_rest_assignment_def( + unique int id: @ruby_rest_assignment +); + +ruby_retry_child( + unique int ruby_retry: @ruby_retry ref, + unique int child: @ruby_argument_list ref +); + +ruby_retry_def( + unique int id: @ruby_retry +); + +ruby_return_child( + unique int ruby_return: @ruby_return ref, + unique int child: @ruby_argument_list ref +); + +ruby_return_def( + unique int id: @ruby_return +); + +@ruby_right_assignment_list_child_type = @ruby_splat_argument | @ruby_underscore_arg + +#keyset[ruby_right_assignment_list, index] +ruby_right_assignment_list_child( + int ruby_right_assignment_list: @ruby_right_assignment_list ref, + int index: int ref, + unique int child: @ruby_right_assignment_list_child_type ref +); + +ruby_right_assignment_list_def( + unique int id: @ruby_right_assignment_list +); + +@ruby_scope_resolution_scope_type = @ruby_underscore_pattern_constant | @ruby_underscore_primary + +ruby_scope_resolution_scope( + unique int ruby_scope_resolution: @ruby_scope_resolution ref, + unique int scope: @ruby_scope_resolution_scope_type ref +); + +ruby_scope_resolution_def( + unique int id: @ruby_scope_resolution, + int name: @ruby_token_constant ref +); + +ruby_setter_def( + unique int id: @ruby_setter, + int name: @ruby_token_identifier ref +); + +ruby_singleton_class_body( + unique int ruby_singleton_class: @ruby_singleton_class ref, + unique int body: @ruby_body_statement ref +); + +ruby_singleton_class_def( + unique int id: @ruby_singleton_class, + int value: @ruby_underscore_arg ref +); + +@ruby_singleton_method_body_type = @ruby_body_statement | @ruby_rescue_modifier | @ruby_underscore_arg + +ruby_singleton_method_body( + unique int ruby_singleton_method: @ruby_singleton_method ref, + unique int body: @ruby_singleton_method_body_type ref +); + +@ruby_singleton_method_object_type = @ruby_underscore_arg | @ruby_underscore_variable + +ruby_singleton_method_parameters( + unique int ruby_singleton_method: @ruby_singleton_method ref, + unique int parameters: @ruby_method_parameters ref +); + +ruby_singleton_method_def( + unique int id: @ruby_singleton_method, + int name: @ruby_underscore_method_name ref, + int object: @ruby_singleton_method_object_type ref +); + +ruby_splat_argument_child( + unique int ruby_splat_argument: @ruby_splat_argument ref, + unique int child: @ruby_underscore_arg ref +); + +ruby_splat_argument_def( + unique int id: @ruby_splat_argument +); + +ruby_splat_parameter_name( + unique int ruby_splat_parameter: @ruby_splat_parameter ref, + unique int name: @ruby_token_identifier ref +); + +ruby_splat_parameter_def( + unique int id: @ruby_splat_parameter +); + +@ruby_string_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_string__, index] +ruby_string_child( + int ruby_string__: @ruby_string__ ref, + int index: int ref, + unique int child: @ruby_string_child_type ref +); + +ruby_string_def( + unique int id: @ruby_string__ +); + +#keyset[ruby_string_array, index] +ruby_string_array_child( + int ruby_string_array: @ruby_string_array ref, + int index: int ref, + unique int child: @ruby_bare_string ref +); + +ruby_string_array_def( + unique int id: @ruby_string_array +); + +@ruby_subshell_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_subshell, index] +ruby_subshell_child( + int ruby_subshell: @ruby_subshell ref, + int index: int ref, + unique int child: @ruby_subshell_child_type ref +); + +ruby_subshell_def( + unique int id: @ruby_subshell +); + +ruby_superclass_def( + unique int id: @ruby_superclass, + int child: @ruby_underscore_expression ref +); + +#keyset[ruby_symbol_array, index] +ruby_symbol_array_child( + int ruby_symbol_array: @ruby_symbol_array ref, + int index: int ref, + unique int child: @ruby_bare_symbol ref +); + +ruby_symbol_array_def( + unique int id: @ruby_symbol_array +); + +ruby_test_pattern_def( + unique int id: @ruby_test_pattern, + int pattern: @ruby_underscore_pattern_top_expr_body ref, + int value: @ruby_underscore_arg ref +); + +@ruby_then_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_then, index] +ruby_then_child( + int ruby_then: @ruby_then ref, + int index: int ref, + unique int child: @ruby_then_child_type ref +); + +ruby_then_def( + unique int id: @ruby_then +); + +@ruby_unary_operand_type = @ruby_parenthesized_statements | @ruby_underscore_expression | @ruby_underscore_simple_numeric + +case @ruby_unary.operator of + 0 = @ruby_unary_bang +| 1 = @ruby_unary_plus +| 2 = @ruby_unary_minus +| 3 = @ruby_unary_definedquestion +| 4 = @ruby_unary_not +| 5 = @ruby_unary_tilde +; + + +ruby_unary_def( + unique int id: @ruby_unary, + int operand: @ruby_unary_operand_type ref, + int operator: int ref +); + +#keyset[ruby_undef, index] +ruby_undef_child( + int ruby_undef: @ruby_undef ref, + int index: int ref, + unique int child: @ruby_underscore_method_name ref +); + +ruby_undef_def( + unique int id: @ruby_undef +); + +@ruby_unless_alternative_type = @ruby_else | @ruby_elsif + +ruby_unless_alternative( + unique int ruby_unless: @ruby_unless ref, + unique int alternative: @ruby_unless_alternative_type ref +); + +ruby_unless_consequence( + unique int ruby_unless: @ruby_unless ref, + unique int consequence: @ruby_then ref +); + +ruby_unless_def( + unique int id: @ruby_unless, + int condition: @ruby_underscore_statement ref +); + +ruby_unless_guard_def( + unique int id: @ruby_unless_guard, + int condition: @ruby_underscore_expression ref +); + +ruby_unless_modifier_def( + unique int id: @ruby_unless_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +ruby_until_def( + unique int id: @ruby_until, + int body: @ruby_do ref, + int condition: @ruby_underscore_statement ref +); + +ruby_until_modifier_def( + unique int id: @ruby_until_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +@ruby_variable_reference_pattern_name_type = @ruby_token_identifier | @ruby_underscore_nonlocal_variable + +ruby_variable_reference_pattern_def( + unique int id: @ruby_variable_reference_pattern, + int name: @ruby_variable_reference_pattern_name_type ref +); + +ruby_when_body( + unique int ruby_when: @ruby_when ref, + unique int body: @ruby_then ref +); + +#keyset[ruby_when, index] +ruby_when_pattern( + int ruby_when: @ruby_when ref, + int index: int ref, + unique int pattern: @ruby_pattern ref +); + +ruby_when_def( + unique int id: @ruby_when +); + +ruby_while_def( + unique int id: @ruby_while, + int body: @ruby_do ref, + int condition: @ruby_underscore_statement ref +); + +ruby_while_modifier_def( + unique int id: @ruby_while_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +ruby_yield_child( + unique int ruby_yield: @ruby_yield ref, + unique int child: @ruby_argument_list ref +); + +ruby_yield_def( + unique int id: @ruby_yield +); + +ruby_tokeninfo( + unique int id: @ruby_token, + int kind: int ref, + string value: string ref +); + +case @ruby_token.kind of + 0 = @ruby_reserved_word +| 1 = @ruby_token_character +| 2 = @ruby_token_class_variable +| 3 = @ruby_token_comment +| 4 = @ruby_token_constant +| 5 = @ruby_token_empty_statement +| 6 = @ruby_token_encoding +| 7 = @ruby_token_escape_sequence +| 8 = @ruby_token_false +| 9 = @ruby_token_file +| 10 = @ruby_token_float +| 11 = @ruby_token_forward_argument +| 12 = @ruby_token_forward_parameter +| 13 = @ruby_token_global_variable +| 14 = @ruby_token_hash_key_symbol +| 15 = @ruby_token_hash_splat_nil +| 16 = @ruby_token_heredoc_beginning +| 17 = @ruby_token_heredoc_content +| 18 = @ruby_token_heredoc_end +| 19 = @ruby_token_identifier +| 20 = @ruby_token_instance_variable +| 21 = @ruby_token_integer +| 22 = @ruby_token_line +| 23 = @ruby_token_nil +| 24 = @ruby_token_operator +| 25 = @ruby_token_self +| 26 = @ruby_token_simple_symbol +| 27 = @ruby_token_string_content +| 28 = @ruby_token_super +| 29 = @ruby_token_true +| 30 = @ruby_token_uninterpreted +; + + +@ruby_ast_node = @ruby_alias | @ruby_alternative_pattern | @ruby_argument_list | @ruby_array | @ruby_array_pattern | @ruby_as_pattern | @ruby_assignment | @ruby_bare_string | @ruby_bare_symbol | @ruby_begin | @ruby_begin_block | @ruby_binary | @ruby_block | @ruby_block_argument | @ruby_block_body | @ruby_block_parameter | @ruby_block_parameters | @ruby_body_statement | @ruby_break | @ruby_call | @ruby_case__ | @ruby_case_match | @ruby_chained_string | @ruby_class | @ruby_complex | @ruby_conditional | @ruby_delimited_symbol | @ruby_destructured_left_assignment | @ruby_destructured_parameter | @ruby_do | @ruby_do_block | @ruby_element_reference | @ruby_else | @ruby_elsif | @ruby_end_block | @ruby_ensure | @ruby_exception_variable | @ruby_exceptions | @ruby_expression_reference_pattern | @ruby_find_pattern | @ruby_for | @ruby_hash | @ruby_hash_pattern | @ruby_hash_splat_argument | @ruby_hash_splat_parameter | @ruby_heredoc_body | @ruby_if | @ruby_if_guard | @ruby_if_modifier | @ruby_in | @ruby_in_clause | @ruby_interpolation | @ruby_keyword_parameter | @ruby_keyword_pattern | @ruby_lambda | @ruby_lambda_parameters | @ruby_left_assignment_list | @ruby_match_pattern | @ruby_method | @ruby_method_parameters | @ruby_module | @ruby_next | @ruby_operator_assignment | @ruby_optional_parameter | @ruby_pair | @ruby_parenthesized_pattern | @ruby_parenthesized_statements | @ruby_pattern | @ruby_program | @ruby_range | @ruby_rational | @ruby_redo | @ruby_regex | @ruby_rescue | @ruby_rescue_modifier | @ruby_rest_assignment | @ruby_retry | @ruby_return | @ruby_right_assignment_list | @ruby_scope_resolution | @ruby_setter | @ruby_singleton_class | @ruby_singleton_method | @ruby_splat_argument | @ruby_splat_parameter | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_superclass | @ruby_symbol_array | @ruby_test_pattern | @ruby_then | @ruby_token | @ruby_unary | @ruby_undef | @ruby_unless | @ruby_unless_guard | @ruby_unless_modifier | @ruby_until | @ruby_until_modifier | @ruby_variable_reference_pattern | @ruby_when | @ruby_while | @ruby_while_modifier | @ruby_yield + +ruby_ast_node_location( + unique int node: @ruby_ast_node ref, + int loc: @location_default ref +); + +#keyset[parent, parent_index] +ruby_ast_node_parent( + unique int node: @ruby_ast_node ref, + int parent: @ruby_ast_node ref, + int parent_index: int ref +); + +/*- Erb dbscheme -*/ +erb_comment_directive_child( + unique int erb_comment_directive: @erb_comment_directive ref, + unique int child: @erb_token_comment ref +); + +erb_comment_directive_def( + unique int id: @erb_comment_directive +); + +erb_directive_child( + unique int erb_directive: @erb_directive ref, + unique int child: @erb_token_code ref +); + +erb_directive_def( + unique int id: @erb_directive +); + +erb_graphql_directive_child( + unique int erb_graphql_directive: @erb_graphql_directive ref, + unique int child: @erb_token_code ref +); + +erb_graphql_directive_def( + unique int id: @erb_graphql_directive +); + +erb_output_directive_child( + unique int erb_output_directive: @erb_output_directive ref, + unique int child: @erb_token_code ref +); + +erb_output_directive_def( + unique int id: @erb_output_directive +); + +@erb_template_child_type = @erb_comment_directive | @erb_directive | @erb_graphql_directive | @erb_output_directive | @erb_token_content + +#keyset[erb_template, index] +erb_template_child( + int erb_template: @erb_template ref, + int index: int ref, + unique int child: @erb_template_child_type ref +); + +erb_template_def( + unique int id: @erb_template +); + +erb_tokeninfo( + unique int id: @erb_token, + int kind: int ref, + string value: string ref +); + +case @erb_token.kind of + 0 = @erb_reserved_word +| 1 = @erb_token_code +| 2 = @erb_token_comment +| 3 = @erb_token_content +; + + +@erb_ast_node = @erb_comment_directive | @erb_directive | @erb_graphql_directive | @erb_output_directive | @erb_template | @erb_token + +erb_ast_node_location( + unique int node: @erb_ast_node ref, + int loc: @location_default ref +); + +#keyset[parent, parent_index] +erb_ast_node_parent( + unique int node: @erb_ast_node ref, + int parent: @erb_ast_node ref, + int parent_index: int ref +); + diff --git a/ruby/downgrades/dc51d416301df12df5b70fbc4338de6cc1f82bfd/upgrade.properties b/ruby/downgrades/dc51d416301df12df5b70fbc4338de6cc1f82bfd/upgrade.properties new file mode 100644 index 000000000000..1d437ec8ac6b --- /dev/null +++ b/ruby/downgrades/dc51d416301df12df5b70fbc4338de6cc1f82bfd/upgrade.properties @@ -0,0 +1,3 @@ +description: Add databaseMetadata relation +compatibility: full +databaseMetadata.rel: delete diff --git a/ruby/extractor/src/generator.rs b/ruby/extractor/src/generator.rs index 00d878243aee..1601d2edda68 100644 --- a/ruby/extractor/src/generator.rs +++ b/ruby/extractor/src/generator.rs @@ -28,5 +28,5 @@ pub fn run(options: Options) -> std::io::Result<()> { }, ]; - generate(languages, options.dbscheme, options.library) + generate(languages, options.dbscheme, options.library, true) } diff --git a/ruby/ql/lib/ruby.dbscheme b/ruby/ql/lib/ruby.dbscheme index 40a6b0a5e811..dc51d416301d 100644 --- a/ruby/ql/lib/ruby.dbscheme +++ b/ruby/ql/lib/ruby.dbscheme @@ -108,6 +108,12 @@ yaml_locations(unique int locatable: @yaml_locatable ref, @yaml_locatable = @yaml_node | @yaml_error; +/*- Database metadata -*/ +databaseMetadata( + string metadataKey: string ref, + string value: string ref +); + /*- Ruby dbscheme -*/ @ruby_underscore_arg = @ruby_assignment | @ruby_binary | @ruby_conditional | @ruby_operator_assignment | @ruby_range | @ruby_unary | @ruby_underscore_primary diff --git a/ruby/ql/lib/ruby.dbscheme.stats b/ruby/ql/lib/ruby.dbscheme.stats index fd8850293b49..74a9e97f4bd4 100644 --- a/ruby/ql/lib/ruby.dbscheme.stats +++ b/ruby/ql/lib/ruby.dbscheme.stats @@ -21521,6 +21521,42 @@ + + databaseMetadata + 1 + + + metadataKey + 1 + + + value + 1 + + + + + metadataKey + value + + + 12 + + + + + + value + metadataKey + + + 12 + + + + + + yaml_aliases 0 diff --git a/ruby/ql/lib/upgrades/40a6b0a5e81115bd870b3a12a1fe954b06362bb7/old.dbscheme b/ruby/ql/lib/upgrades/40a6b0a5e81115bd870b3a12a1fe954b06362bb7/old.dbscheme new file mode 100644 index 000000000000..40a6b0a5e811 --- /dev/null +++ b/ruby/ql/lib/upgrades/40a6b0a5e81115bd870b3a12a1fe954b06362bb7/old.dbscheme @@ -0,0 +1,1526 @@ +// CodeQL database schema for Ruby +// Automatically generated from the tree-sitter grammar; do not edit + +/*- Files and folders -*/ + +/** + * The location of an element. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @file | @folder + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/*- Empty location -*/ + +empty_location( + int location: @location_default ref +); + +/*- Source location prefix -*/ + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/*- Diagnostic messages -*/ + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/*- Diagnostic messages: severity -*/ + +case @diagnostic.severity of + 10 = @diagnostic_debug +| 20 = @diagnostic_info +| 30 = @diagnostic_warning +| 40 = @diagnostic_error +; + +/*- YAML -*/ + +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + string tag: string ref, + string tostring: string ref); + +case @yaml_node.kind of + 0 = @yaml_scalar_node +| 1 = @yaml_mapping_node +| 2 = @yaml_sequence_node +| 3 = @yaml_alias_node +; + +@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node; + +@yaml_node_parent = @yaml_collection_node | @file; + +yaml_anchors (unique int node: @yaml_node ref, + string anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + string target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + string value: string ref); + +yaml_errors (unique int id: @yaml_error, + string message: string ref); + +yaml_locations(unique int locatable: @yaml_locatable ref, + int location: @location_default ref); + +@yaml_locatable = @yaml_node | @yaml_error; + +/*- Ruby dbscheme -*/ +@ruby_underscore_arg = @ruby_assignment | @ruby_binary | @ruby_conditional | @ruby_operator_assignment | @ruby_range | @ruby_unary | @ruby_underscore_primary + +@ruby_underscore_call_operator = @ruby_reserved_word + +@ruby_underscore_expression = @ruby_assignment | @ruby_binary | @ruby_break | @ruby_call | @ruby_match_pattern | @ruby_next | @ruby_operator_assignment | @ruby_return | @ruby_test_pattern | @ruby_unary | @ruby_underscore_arg | @ruby_yield + +@ruby_underscore_lhs = @ruby_call | @ruby_element_reference | @ruby_scope_resolution | @ruby_token_false | @ruby_token_nil | @ruby_token_true | @ruby_underscore_variable + +@ruby_underscore_method_name = @ruby_delimited_symbol | @ruby_setter | @ruby_token_constant | @ruby_token_identifier | @ruby_token_operator | @ruby_token_simple_symbol | @ruby_underscore_nonlocal_variable + +@ruby_underscore_nonlocal_variable = @ruby_token_class_variable | @ruby_token_global_variable | @ruby_token_instance_variable + +@ruby_underscore_pattern_constant = @ruby_scope_resolution | @ruby_token_constant + +@ruby_underscore_pattern_expr = @ruby_alternative_pattern | @ruby_as_pattern | @ruby_underscore_pattern_expr_basic + +@ruby_underscore_pattern_expr_basic = @ruby_array_pattern | @ruby_expression_reference_pattern | @ruby_find_pattern | @ruby_hash_pattern | @ruby_parenthesized_pattern | @ruby_range | @ruby_token_identifier | @ruby_underscore_pattern_constant | @ruby_underscore_pattern_primitive | @ruby_variable_reference_pattern + +@ruby_underscore_pattern_primitive = @ruby_delimited_symbol | @ruby_lambda | @ruby_regex | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_symbol_array | @ruby_token_encoding | @ruby_token_false | @ruby_token_file | @ruby_token_heredoc_beginning | @ruby_token_line | @ruby_token_nil | @ruby_token_self | @ruby_token_simple_symbol | @ruby_token_true | @ruby_unary | @ruby_underscore_simple_numeric + +@ruby_underscore_pattern_top_expr_body = @ruby_array_pattern | @ruby_find_pattern | @ruby_hash_pattern | @ruby_underscore_pattern_expr + +@ruby_underscore_primary = @ruby_array | @ruby_begin | @ruby_break | @ruby_call | @ruby_case__ | @ruby_case_match | @ruby_chained_string | @ruby_class | @ruby_delimited_symbol | @ruby_for | @ruby_hash | @ruby_if | @ruby_lambda | @ruby_method | @ruby_module | @ruby_next | @ruby_parenthesized_statements | @ruby_redo | @ruby_regex | @ruby_retry | @ruby_return | @ruby_singleton_class | @ruby_singleton_method | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_symbol_array | @ruby_token_character | @ruby_token_heredoc_beginning | @ruby_token_simple_symbol | @ruby_unary | @ruby_underscore_lhs | @ruby_underscore_simple_numeric | @ruby_unless | @ruby_until | @ruby_while | @ruby_yield + +@ruby_underscore_simple_numeric = @ruby_complex | @ruby_rational | @ruby_token_float | @ruby_token_integer + +@ruby_underscore_statement = @ruby_alias | @ruby_begin_block | @ruby_end_block | @ruby_if_modifier | @ruby_rescue_modifier | @ruby_undef | @ruby_underscore_expression | @ruby_unless_modifier | @ruby_until_modifier | @ruby_while_modifier + +@ruby_underscore_variable = @ruby_token_constant | @ruby_token_identifier | @ruby_token_self | @ruby_token_super | @ruby_underscore_nonlocal_variable + +ruby_alias_def( + unique int id: @ruby_alias, + int alias: @ruby_underscore_method_name ref, + int name: @ruby_underscore_method_name ref +); + +#keyset[ruby_alternative_pattern, index] +ruby_alternative_pattern_alternatives( + int ruby_alternative_pattern: @ruby_alternative_pattern ref, + int index: int ref, + unique int alternatives: @ruby_underscore_pattern_expr_basic ref +); + +ruby_alternative_pattern_def( + unique int id: @ruby_alternative_pattern +); + +@ruby_argument_list_child_type = @ruby_block_argument | @ruby_hash_splat_argument | @ruby_pair | @ruby_splat_argument | @ruby_token_forward_argument | @ruby_underscore_expression + +#keyset[ruby_argument_list, index] +ruby_argument_list_child( + int ruby_argument_list: @ruby_argument_list ref, + int index: int ref, + unique int child: @ruby_argument_list_child_type ref +); + +ruby_argument_list_def( + unique int id: @ruby_argument_list +); + +@ruby_array_child_type = @ruby_block_argument | @ruby_hash_splat_argument | @ruby_pair | @ruby_splat_argument | @ruby_token_forward_argument | @ruby_underscore_expression + +#keyset[ruby_array, index] +ruby_array_child( + int ruby_array: @ruby_array ref, + int index: int ref, + unique int child: @ruby_array_child_type ref +); + +ruby_array_def( + unique int id: @ruby_array +); + +ruby_array_pattern_class( + unique int ruby_array_pattern: @ruby_array_pattern ref, + unique int class: @ruby_underscore_pattern_constant ref +); + +@ruby_array_pattern_child_type = @ruby_splat_parameter | @ruby_underscore_pattern_expr + +#keyset[ruby_array_pattern, index] +ruby_array_pattern_child( + int ruby_array_pattern: @ruby_array_pattern ref, + int index: int ref, + unique int child: @ruby_array_pattern_child_type ref +); + +ruby_array_pattern_def( + unique int id: @ruby_array_pattern +); + +ruby_as_pattern_def( + unique int id: @ruby_as_pattern, + int name: @ruby_token_identifier ref, + int value: @ruby_underscore_pattern_expr ref +); + +@ruby_assignment_left_type = @ruby_left_assignment_list | @ruby_underscore_lhs + +@ruby_assignment_right_type = @ruby_rescue_modifier | @ruby_right_assignment_list | @ruby_splat_argument | @ruby_underscore_expression + +ruby_assignment_def( + unique int id: @ruby_assignment, + int left: @ruby_assignment_left_type ref, + int right: @ruby_assignment_right_type ref +); + +@ruby_bare_string_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_bare_string, index] +ruby_bare_string_child( + int ruby_bare_string: @ruby_bare_string ref, + int index: int ref, + unique int child: @ruby_bare_string_child_type ref +); + +ruby_bare_string_def( + unique int id: @ruby_bare_string +); + +@ruby_bare_symbol_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_bare_symbol, index] +ruby_bare_symbol_child( + int ruby_bare_symbol: @ruby_bare_symbol ref, + int index: int ref, + unique int child: @ruby_bare_symbol_child_type ref +); + +ruby_bare_symbol_def( + unique int id: @ruby_bare_symbol +); + +@ruby_begin_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_begin, index] +ruby_begin_child( + int ruby_begin: @ruby_begin ref, + int index: int ref, + unique int child: @ruby_begin_child_type ref +); + +ruby_begin_def( + unique int id: @ruby_begin +); + +@ruby_begin_block_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_begin_block, index] +ruby_begin_block_child( + int ruby_begin_block: @ruby_begin_block ref, + int index: int ref, + unique int child: @ruby_begin_block_child_type ref +); + +ruby_begin_block_def( + unique int id: @ruby_begin_block +); + +@ruby_binary_left_type = @ruby_underscore_expression | @ruby_underscore_simple_numeric + +case @ruby_binary.operator of + 0 = @ruby_binary_bangequal +| 1 = @ruby_binary_bangtilde +| 2 = @ruby_binary_percent +| 3 = @ruby_binary_ampersand +| 4 = @ruby_binary_ampersandampersand +| 5 = @ruby_binary_star +| 6 = @ruby_binary_starstar +| 7 = @ruby_binary_plus +| 8 = @ruby_binary_minus +| 9 = @ruby_binary_slash +| 10 = @ruby_binary_langle +| 11 = @ruby_binary_langlelangle +| 12 = @ruby_binary_langleequal +| 13 = @ruby_binary_langleequalrangle +| 14 = @ruby_binary_equalequal +| 15 = @ruby_binary_equalequalequal +| 16 = @ruby_binary_equaltilde +| 17 = @ruby_binary_rangle +| 18 = @ruby_binary_rangleequal +| 19 = @ruby_binary_ranglerangle +| 20 = @ruby_binary_caret +| 21 = @ruby_binary_and +| 22 = @ruby_binary_or +| 23 = @ruby_binary_pipe +| 24 = @ruby_binary_pipepipe +; + + +ruby_binary_def( + unique int id: @ruby_binary, + int left: @ruby_binary_left_type ref, + int operator: int ref, + int right: @ruby_underscore_expression ref +); + +ruby_block_body( + unique int ruby_block: @ruby_block ref, + unique int body: @ruby_block_body ref +); + +ruby_block_parameters( + unique int ruby_block: @ruby_block ref, + unique int parameters: @ruby_block_parameters ref +); + +ruby_block_def( + unique int id: @ruby_block +); + +ruby_block_argument_child( + unique int ruby_block_argument: @ruby_block_argument ref, + unique int child: @ruby_underscore_arg ref +); + +ruby_block_argument_def( + unique int id: @ruby_block_argument +); + +@ruby_block_body_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_block_body, index] +ruby_block_body_child( + int ruby_block_body: @ruby_block_body ref, + int index: int ref, + unique int child: @ruby_block_body_child_type ref +); + +ruby_block_body_def( + unique int id: @ruby_block_body +); + +ruby_block_parameter_name( + unique int ruby_block_parameter: @ruby_block_parameter ref, + unique int name: @ruby_token_identifier ref +); + +ruby_block_parameter_def( + unique int id: @ruby_block_parameter +); + +#keyset[ruby_block_parameters, index] +ruby_block_parameters_locals( + int ruby_block_parameters: @ruby_block_parameters ref, + int index: int ref, + unique int locals: @ruby_token_identifier ref +); + +@ruby_block_parameters_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_block_parameters, index] +ruby_block_parameters_child( + int ruby_block_parameters: @ruby_block_parameters ref, + int index: int ref, + unique int child: @ruby_block_parameters_child_type ref +); + +ruby_block_parameters_def( + unique int id: @ruby_block_parameters +); + +@ruby_body_statement_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_body_statement, index] +ruby_body_statement_child( + int ruby_body_statement: @ruby_body_statement ref, + int index: int ref, + unique int child: @ruby_body_statement_child_type ref +); + +ruby_body_statement_def( + unique int id: @ruby_body_statement +); + +ruby_break_child( + unique int ruby_break: @ruby_break ref, + unique int child: @ruby_argument_list ref +); + +ruby_break_def( + unique int id: @ruby_break +); + +ruby_call_arguments( + unique int ruby_call: @ruby_call ref, + unique int arguments: @ruby_argument_list ref +); + +@ruby_call_block_type = @ruby_block | @ruby_do_block + +ruby_call_block( + unique int ruby_call: @ruby_call ref, + unique int block: @ruby_call_block_type ref +); + +@ruby_call_method_type = @ruby_token_operator | @ruby_underscore_variable + +ruby_call_method( + unique int ruby_call: @ruby_call ref, + unique int method: @ruby_call_method_type ref +); + +ruby_call_operator( + unique int ruby_call: @ruby_call ref, + unique int operator: @ruby_underscore_call_operator ref +); + +ruby_call_receiver( + unique int ruby_call: @ruby_call ref, + unique int receiver: @ruby_underscore_primary ref +); + +ruby_call_def( + unique int id: @ruby_call +); + +ruby_case_value( + unique int ruby_case__: @ruby_case__ ref, + unique int value: @ruby_underscore_statement ref +); + +@ruby_case_child_type = @ruby_else | @ruby_when + +#keyset[ruby_case__, index] +ruby_case_child( + int ruby_case__: @ruby_case__ ref, + int index: int ref, + unique int child: @ruby_case_child_type ref +); + +ruby_case_def( + unique int id: @ruby_case__ +); + +#keyset[ruby_case_match, index] +ruby_case_match_clauses( + int ruby_case_match: @ruby_case_match ref, + int index: int ref, + unique int clauses: @ruby_in_clause ref +); + +ruby_case_match_else( + unique int ruby_case_match: @ruby_case_match ref, + unique int else: @ruby_else ref +); + +ruby_case_match_def( + unique int id: @ruby_case_match, + int value: @ruby_underscore_statement ref +); + +#keyset[ruby_chained_string, index] +ruby_chained_string_child( + int ruby_chained_string: @ruby_chained_string ref, + int index: int ref, + unique int child: @ruby_string__ ref +); + +ruby_chained_string_def( + unique int id: @ruby_chained_string +); + +ruby_class_body( + unique int ruby_class: @ruby_class ref, + unique int body: @ruby_body_statement ref +); + +@ruby_class_name_type = @ruby_scope_resolution | @ruby_token_constant + +ruby_class_superclass( + unique int ruby_class: @ruby_class ref, + unique int superclass: @ruby_superclass ref +); + +ruby_class_def( + unique int id: @ruby_class, + int name: @ruby_class_name_type ref +); + +@ruby_complex_child_type = @ruby_rational | @ruby_token_float | @ruby_token_integer + +ruby_complex_def( + unique int id: @ruby_complex, + int child: @ruby_complex_child_type ref +); + +ruby_conditional_def( + unique int id: @ruby_conditional, + int alternative: @ruby_underscore_arg ref, + int condition: @ruby_underscore_arg ref, + int consequence: @ruby_underscore_arg ref +); + +@ruby_delimited_symbol_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_delimited_symbol, index] +ruby_delimited_symbol_child( + int ruby_delimited_symbol: @ruby_delimited_symbol ref, + int index: int ref, + unique int child: @ruby_delimited_symbol_child_type ref +); + +ruby_delimited_symbol_def( + unique int id: @ruby_delimited_symbol +); + +@ruby_destructured_left_assignment_child_type = @ruby_destructured_left_assignment | @ruby_rest_assignment | @ruby_underscore_lhs + +#keyset[ruby_destructured_left_assignment, index] +ruby_destructured_left_assignment_child( + int ruby_destructured_left_assignment: @ruby_destructured_left_assignment ref, + int index: int ref, + unique int child: @ruby_destructured_left_assignment_child_type ref +); + +ruby_destructured_left_assignment_def( + unique int id: @ruby_destructured_left_assignment +); + +@ruby_destructured_parameter_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_destructured_parameter, index] +ruby_destructured_parameter_child( + int ruby_destructured_parameter: @ruby_destructured_parameter ref, + int index: int ref, + unique int child: @ruby_destructured_parameter_child_type ref +); + +ruby_destructured_parameter_def( + unique int id: @ruby_destructured_parameter +); + +@ruby_do_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_do, index] +ruby_do_child( + int ruby_do: @ruby_do ref, + int index: int ref, + unique int child: @ruby_do_child_type ref +); + +ruby_do_def( + unique int id: @ruby_do +); + +ruby_do_block_body( + unique int ruby_do_block: @ruby_do_block ref, + unique int body: @ruby_body_statement ref +); + +ruby_do_block_parameters( + unique int ruby_do_block: @ruby_do_block ref, + unique int parameters: @ruby_block_parameters ref +); + +ruby_do_block_def( + unique int id: @ruby_do_block +); + +@ruby_element_reference_block_type = @ruby_block | @ruby_do_block + +ruby_element_reference_block( + unique int ruby_element_reference: @ruby_element_reference ref, + unique int block: @ruby_element_reference_block_type ref +); + +@ruby_element_reference_child_type = @ruby_block_argument | @ruby_hash_splat_argument | @ruby_pair | @ruby_splat_argument | @ruby_token_forward_argument | @ruby_underscore_expression + +#keyset[ruby_element_reference, index] +ruby_element_reference_child( + int ruby_element_reference: @ruby_element_reference ref, + int index: int ref, + unique int child: @ruby_element_reference_child_type ref +); + +ruby_element_reference_def( + unique int id: @ruby_element_reference, + int object: @ruby_underscore_primary ref +); + +@ruby_else_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_else, index] +ruby_else_child( + int ruby_else: @ruby_else ref, + int index: int ref, + unique int child: @ruby_else_child_type ref +); + +ruby_else_def( + unique int id: @ruby_else +); + +@ruby_elsif_alternative_type = @ruby_else | @ruby_elsif + +ruby_elsif_alternative( + unique int ruby_elsif: @ruby_elsif ref, + unique int alternative: @ruby_elsif_alternative_type ref +); + +ruby_elsif_consequence( + unique int ruby_elsif: @ruby_elsif ref, + unique int consequence: @ruby_then ref +); + +ruby_elsif_def( + unique int id: @ruby_elsif, + int condition: @ruby_underscore_statement ref +); + +@ruby_end_block_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_end_block, index] +ruby_end_block_child( + int ruby_end_block: @ruby_end_block ref, + int index: int ref, + unique int child: @ruby_end_block_child_type ref +); + +ruby_end_block_def( + unique int id: @ruby_end_block +); + +@ruby_ensure_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_ensure, index] +ruby_ensure_child( + int ruby_ensure: @ruby_ensure ref, + int index: int ref, + unique int child: @ruby_ensure_child_type ref +); + +ruby_ensure_def( + unique int id: @ruby_ensure +); + +ruby_exception_variable_def( + unique int id: @ruby_exception_variable, + int child: @ruby_underscore_lhs ref +); + +@ruby_exceptions_child_type = @ruby_splat_argument | @ruby_underscore_arg + +#keyset[ruby_exceptions, index] +ruby_exceptions_child( + int ruby_exceptions: @ruby_exceptions ref, + int index: int ref, + unique int child: @ruby_exceptions_child_type ref +); + +ruby_exceptions_def( + unique int id: @ruby_exceptions +); + +ruby_expression_reference_pattern_def( + unique int id: @ruby_expression_reference_pattern, + int value: @ruby_underscore_expression ref +); + +ruby_find_pattern_class( + unique int ruby_find_pattern: @ruby_find_pattern ref, + unique int class: @ruby_underscore_pattern_constant ref +); + +@ruby_find_pattern_child_type = @ruby_splat_parameter | @ruby_underscore_pattern_expr + +#keyset[ruby_find_pattern, index] +ruby_find_pattern_child( + int ruby_find_pattern: @ruby_find_pattern ref, + int index: int ref, + unique int child: @ruby_find_pattern_child_type ref +); + +ruby_find_pattern_def( + unique int id: @ruby_find_pattern +); + +@ruby_for_pattern_type = @ruby_left_assignment_list | @ruby_underscore_lhs + +ruby_for_def( + unique int id: @ruby_for, + int body: @ruby_do ref, + int pattern: @ruby_for_pattern_type ref, + int value: @ruby_in ref +); + +@ruby_hash_child_type = @ruby_hash_splat_argument | @ruby_pair + +#keyset[ruby_hash, index] +ruby_hash_child( + int ruby_hash: @ruby_hash ref, + int index: int ref, + unique int child: @ruby_hash_child_type ref +); + +ruby_hash_def( + unique int id: @ruby_hash +); + +ruby_hash_pattern_class( + unique int ruby_hash_pattern: @ruby_hash_pattern ref, + unique int class: @ruby_underscore_pattern_constant ref +); + +@ruby_hash_pattern_child_type = @ruby_hash_splat_parameter | @ruby_keyword_pattern | @ruby_token_hash_splat_nil + +#keyset[ruby_hash_pattern, index] +ruby_hash_pattern_child( + int ruby_hash_pattern: @ruby_hash_pattern ref, + int index: int ref, + unique int child: @ruby_hash_pattern_child_type ref +); + +ruby_hash_pattern_def( + unique int id: @ruby_hash_pattern +); + +ruby_hash_splat_argument_child( + unique int ruby_hash_splat_argument: @ruby_hash_splat_argument ref, + unique int child: @ruby_underscore_arg ref +); + +ruby_hash_splat_argument_def( + unique int id: @ruby_hash_splat_argument +); + +ruby_hash_splat_parameter_name( + unique int ruby_hash_splat_parameter: @ruby_hash_splat_parameter ref, + unique int name: @ruby_token_identifier ref +); + +ruby_hash_splat_parameter_def( + unique int id: @ruby_hash_splat_parameter +); + +@ruby_heredoc_body_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_heredoc_content | @ruby_token_heredoc_end + +#keyset[ruby_heredoc_body, index] +ruby_heredoc_body_child( + int ruby_heredoc_body: @ruby_heredoc_body ref, + int index: int ref, + unique int child: @ruby_heredoc_body_child_type ref +); + +ruby_heredoc_body_def( + unique int id: @ruby_heredoc_body +); + +@ruby_if_alternative_type = @ruby_else | @ruby_elsif + +ruby_if_alternative( + unique int ruby_if: @ruby_if ref, + unique int alternative: @ruby_if_alternative_type ref +); + +ruby_if_consequence( + unique int ruby_if: @ruby_if ref, + unique int consequence: @ruby_then ref +); + +ruby_if_def( + unique int id: @ruby_if, + int condition: @ruby_underscore_statement ref +); + +ruby_if_guard_def( + unique int id: @ruby_if_guard, + int condition: @ruby_underscore_expression ref +); + +ruby_if_modifier_def( + unique int id: @ruby_if_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +ruby_in_def( + unique int id: @ruby_in, + int child: @ruby_underscore_arg ref +); + +ruby_in_clause_body( + unique int ruby_in_clause: @ruby_in_clause ref, + unique int body: @ruby_then ref +); + +@ruby_in_clause_guard_type = @ruby_if_guard | @ruby_unless_guard + +ruby_in_clause_guard( + unique int ruby_in_clause: @ruby_in_clause ref, + unique int guard: @ruby_in_clause_guard_type ref +); + +ruby_in_clause_def( + unique int id: @ruby_in_clause, + int pattern: @ruby_underscore_pattern_top_expr_body ref +); + +@ruby_interpolation_child_type = @ruby_token_empty_statement | @ruby_underscore_nonlocal_variable | @ruby_underscore_statement + +#keyset[ruby_interpolation, index] +ruby_interpolation_child( + int ruby_interpolation: @ruby_interpolation ref, + int index: int ref, + unique int child: @ruby_interpolation_child_type ref +); + +ruby_interpolation_def( + unique int id: @ruby_interpolation +); + +ruby_keyword_parameter_value( + unique int ruby_keyword_parameter: @ruby_keyword_parameter ref, + unique int value: @ruby_underscore_arg ref +); + +ruby_keyword_parameter_def( + unique int id: @ruby_keyword_parameter, + int name: @ruby_token_identifier ref +); + +@ruby_keyword_pattern_key_type = @ruby_string__ | @ruby_token_hash_key_symbol + +ruby_keyword_pattern_value( + unique int ruby_keyword_pattern: @ruby_keyword_pattern ref, + unique int value: @ruby_underscore_pattern_expr ref +); + +ruby_keyword_pattern_def( + unique int id: @ruby_keyword_pattern, + int key__: @ruby_keyword_pattern_key_type ref +); + +@ruby_lambda_body_type = @ruby_block | @ruby_do_block + +ruby_lambda_parameters( + unique int ruby_lambda: @ruby_lambda ref, + unique int parameters: @ruby_lambda_parameters ref +); + +ruby_lambda_def( + unique int id: @ruby_lambda, + int body: @ruby_lambda_body_type ref +); + +@ruby_lambda_parameters_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_lambda_parameters, index] +ruby_lambda_parameters_child( + int ruby_lambda_parameters: @ruby_lambda_parameters ref, + int index: int ref, + unique int child: @ruby_lambda_parameters_child_type ref +); + +ruby_lambda_parameters_def( + unique int id: @ruby_lambda_parameters +); + +@ruby_left_assignment_list_child_type = @ruby_destructured_left_assignment | @ruby_rest_assignment | @ruby_underscore_lhs + +#keyset[ruby_left_assignment_list, index] +ruby_left_assignment_list_child( + int ruby_left_assignment_list: @ruby_left_assignment_list ref, + int index: int ref, + unique int child: @ruby_left_assignment_list_child_type ref +); + +ruby_left_assignment_list_def( + unique int id: @ruby_left_assignment_list +); + +ruby_match_pattern_def( + unique int id: @ruby_match_pattern, + int pattern: @ruby_underscore_pattern_top_expr_body ref, + int value: @ruby_underscore_arg ref +); + +@ruby_method_body_type = @ruby_body_statement | @ruby_rescue_modifier | @ruby_underscore_arg + +ruby_method_body( + unique int ruby_method: @ruby_method ref, + unique int body: @ruby_method_body_type ref +); + +ruby_method_parameters( + unique int ruby_method: @ruby_method ref, + unique int parameters: @ruby_method_parameters ref +); + +ruby_method_def( + unique int id: @ruby_method, + int name: @ruby_underscore_method_name ref +); + +@ruby_method_parameters_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_method_parameters, index] +ruby_method_parameters_child( + int ruby_method_parameters: @ruby_method_parameters ref, + int index: int ref, + unique int child: @ruby_method_parameters_child_type ref +); + +ruby_method_parameters_def( + unique int id: @ruby_method_parameters +); + +ruby_module_body( + unique int ruby_module: @ruby_module ref, + unique int body: @ruby_body_statement ref +); + +@ruby_module_name_type = @ruby_scope_resolution | @ruby_token_constant + +ruby_module_def( + unique int id: @ruby_module, + int name: @ruby_module_name_type ref +); + +ruby_next_child( + unique int ruby_next: @ruby_next ref, + unique int child: @ruby_argument_list ref +); + +ruby_next_def( + unique int id: @ruby_next +); + +case @ruby_operator_assignment.operator of + 0 = @ruby_operator_assignment_percentequal +| 1 = @ruby_operator_assignment_ampersandampersandequal +| 2 = @ruby_operator_assignment_ampersandequal +| 3 = @ruby_operator_assignment_starstarequal +| 4 = @ruby_operator_assignment_starequal +| 5 = @ruby_operator_assignment_plusequal +| 6 = @ruby_operator_assignment_minusequal +| 7 = @ruby_operator_assignment_slashequal +| 8 = @ruby_operator_assignment_langlelangleequal +| 9 = @ruby_operator_assignment_ranglerangleequal +| 10 = @ruby_operator_assignment_caretequal +| 11 = @ruby_operator_assignment_pipeequal +| 12 = @ruby_operator_assignment_pipepipeequal +; + + +@ruby_operator_assignment_right_type = @ruby_rescue_modifier | @ruby_underscore_expression + +ruby_operator_assignment_def( + unique int id: @ruby_operator_assignment, + int left: @ruby_underscore_lhs ref, + int operator: int ref, + int right: @ruby_operator_assignment_right_type ref +); + +ruby_optional_parameter_def( + unique int id: @ruby_optional_parameter, + int name: @ruby_token_identifier ref, + int value: @ruby_underscore_arg ref +); + +@ruby_pair_key_type = @ruby_string__ | @ruby_token_hash_key_symbol | @ruby_underscore_arg + +ruby_pair_value( + unique int ruby_pair: @ruby_pair ref, + unique int value: @ruby_underscore_arg ref +); + +ruby_pair_def( + unique int id: @ruby_pair, + int key__: @ruby_pair_key_type ref +); + +ruby_parenthesized_pattern_def( + unique int id: @ruby_parenthesized_pattern, + int child: @ruby_underscore_pattern_expr ref +); + +@ruby_parenthesized_statements_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_parenthesized_statements, index] +ruby_parenthesized_statements_child( + int ruby_parenthesized_statements: @ruby_parenthesized_statements ref, + int index: int ref, + unique int child: @ruby_parenthesized_statements_child_type ref +); + +ruby_parenthesized_statements_def( + unique int id: @ruby_parenthesized_statements +); + +@ruby_pattern_child_type = @ruby_splat_argument | @ruby_underscore_arg + +ruby_pattern_def( + unique int id: @ruby_pattern, + int child: @ruby_pattern_child_type ref +); + +@ruby_program_child_type = @ruby_token_empty_statement | @ruby_token_uninterpreted | @ruby_underscore_statement + +#keyset[ruby_program, index] +ruby_program_child( + int ruby_program: @ruby_program ref, + int index: int ref, + unique int child: @ruby_program_child_type ref +); + +ruby_program_def( + unique int id: @ruby_program +); + +@ruby_range_begin_type = @ruby_underscore_arg | @ruby_underscore_pattern_primitive + +ruby_range_begin( + unique int ruby_range: @ruby_range ref, + unique int begin: @ruby_range_begin_type ref +); + +@ruby_range_end_type = @ruby_underscore_arg | @ruby_underscore_pattern_primitive + +ruby_range_end( + unique int ruby_range: @ruby_range ref, + unique int end: @ruby_range_end_type ref +); + +case @ruby_range.operator of + 0 = @ruby_range_dotdot +| 1 = @ruby_range_dotdotdot +; + + +ruby_range_def( + unique int id: @ruby_range, + int operator: int ref +); + +@ruby_rational_child_type = @ruby_token_float | @ruby_token_integer + +ruby_rational_def( + unique int id: @ruby_rational, + int child: @ruby_rational_child_type ref +); + +ruby_redo_child( + unique int ruby_redo: @ruby_redo ref, + unique int child: @ruby_argument_list ref +); + +ruby_redo_def( + unique int id: @ruby_redo +); + +@ruby_regex_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_regex, index] +ruby_regex_child( + int ruby_regex: @ruby_regex ref, + int index: int ref, + unique int child: @ruby_regex_child_type ref +); + +ruby_regex_def( + unique int id: @ruby_regex +); + +ruby_rescue_body( + unique int ruby_rescue: @ruby_rescue ref, + unique int body: @ruby_then ref +); + +ruby_rescue_exceptions( + unique int ruby_rescue: @ruby_rescue ref, + unique int exceptions: @ruby_exceptions ref +); + +ruby_rescue_variable( + unique int ruby_rescue: @ruby_rescue ref, + unique int variable: @ruby_exception_variable ref +); + +ruby_rescue_def( + unique int id: @ruby_rescue +); + +@ruby_rescue_modifier_body_type = @ruby_underscore_arg | @ruby_underscore_statement + +ruby_rescue_modifier_def( + unique int id: @ruby_rescue_modifier, + int body: @ruby_rescue_modifier_body_type ref, + int handler: @ruby_underscore_expression ref +); + +ruby_rest_assignment_child( + unique int ruby_rest_assignment: @ruby_rest_assignment ref, + unique int child: @ruby_underscore_lhs ref +); + +ruby_rest_assignment_def( + unique int id: @ruby_rest_assignment +); + +ruby_retry_child( + unique int ruby_retry: @ruby_retry ref, + unique int child: @ruby_argument_list ref +); + +ruby_retry_def( + unique int id: @ruby_retry +); + +ruby_return_child( + unique int ruby_return: @ruby_return ref, + unique int child: @ruby_argument_list ref +); + +ruby_return_def( + unique int id: @ruby_return +); + +@ruby_right_assignment_list_child_type = @ruby_splat_argument | @ruby_underscore_arg + +#keyset[ruby_right_assignment_list, index] +ruby_right_assignment_list_child( + int ruby_right_assignment_list: @ruby_right_assignment_list ref, + int index: int ref, + unique int child: @ruby_right_assignment_list_child_type ref +); + +ruby_right_assignment_list_def( + unique int id: @ruby_right_assignment_list +); + +@ruby_scope_resolution_scope_type = @ruby_underscore_pattern_constant | @ruby_underscore_primary + +ruby_scope_resolution_scope( + unique int ruby_scope_resolution: @ruby_scope_resolution ref, + unique int scope: @ruby_scope_resolution_scope_type ref +); + +ruby_scope_resolution_def( + unique int id: @ruby_scope_resolution, + int name: @ruby_token_constant ref +); + +ruby_setter_def( + unique int id: @ruby_setter, + int name: @ruby_token_identifier ref +); + +ruby_singleton_class_body( + unique int ruby_singleton_class: @ruby_singleton_class ref, + unique int body: @ruby_body_statement ref +); + +ruby_singleton_class_def( + unique int id: @ruby_singleton_class, + int value: @ruby_underscore_arg ref +); + +@ruby_singleton_method_body_type = @ruby_body_statement | @ruby_rescue_modifier | @ruby_underscore_arg + +ruby_singleton_method_body( + unique int ruby_singleton_method: @ruby_singleton_method ref, + unique int body: @ruby_singleton_method_body_type ref +); + +@ruby_singleton_method_object_type = @ruby_underscore_arg | @ruby_underscore_variable + +ruby_singleton_method_parameters( + unique int ruby_singleton_method: @ruby_singleton_method ref, + unique int parameters: @ruby_method_parameters ref +); + +ruby_singleton_method_def( + unique int id: @ruby_singleton_method, + int name: @ruby_underscore_method_name ref, + int object: @ruby_singleton_method_object_type ref +); + +ruby_splat_argument_child( + unique int ruby_splat_argument: @ruby_splat_argument ref, + unique int child: @ruby_underscore_arg ref +); + +ruby_splat_argument_def( + unique int id: @ruby_splat_argument +); + +ruby_splat_parameter_name( + unique int ruby_splat_parameter: @ruby_splat_parameter ref, + unique int name: @ruby_token_identifier ref +); + +ruby_splat_parameter_def( + unique int id: @ruby_splat_parameter +); + +@ruby_string_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_string__, index] +ruby_string_child( + int ruby_string__: @ruby_string__ ref, + int index: int ref, + unique int child: @ruby_string_child_type ref +); + +ruby_string_def( + unique int id: @ruby_string__ +); + +#keyset[ruby_string_array, index] +ruby_string_array_child( + int ruby_string_array: @ruby_string_array ref, + int index: int ref, + unique int child: @ruby_bare_string ref +); + +ruby_string_array_def( + unique int id: @ruby_string_array +); + +@ruby_subshell_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_subshell, index] +ruby_subshell_child( + int ruby_subshell: @ruby_subshell ref, + int index: int ref, + unique int child: @ruby_subshell_child_type ref +); + +ruby_subshell_def( + unique int id: @ruby_subshell +); + +ruby_superclass_def( + unique int id: @ruby_superclass, + int child: @ruby_underscore_expression ref +); + +#keyset[ruby_symbol_array, index] +ruby_symbol_array_child( + int ruby_symbol_array: @ruby_symbol_array ref, + int index: int ref, + unique int child: @ruby_bare_symbol ref +); + +ruby_symbol_array_def( + unique int id: @ruby_symbol_array +); + +ruby_test_pattern_def( + unique int id: @ruby_test_pattern, + int pattern: @ruby_underscore_pattern_top_expr_body ref, + int value: @ruby_underscore_arg ref +); + +@ruby_then_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_then, index] +ruby_then_child( + int ruby_then: @ruby_then ref, + int index: int ref, + unique int child: @ruby_then_child_type ref +); + +ruby_then_def( + unique int id: @ruby_then +); + +@ruby_unary_operand_type = @ruby_parenthesized_statements | @ruby_underscore_expression | @ruby_underscore_simple_numeric + +case @ruby_unary.operator of + 0 = @ruby_unary_bang +| 1 = @ruby_unary_plus +| 2 = @ruby_unary_minus +| 3 = @ruby_unary_definedquestion +| 4 = @ruby_unary_not +| 5 = @ruby_unary_tilde +; + + +ruby_unary_def( + unique int id: @ruby_unary, + int operand: @ruby_unary_operand_type ref, + int operator: int ref +); + +#keyset[ruby_undef, index] +ruby_undef_child( + int ruby_undef: @ruby_undef ref, + int index: int ref, + unique int child: @ruby_underscore_method_name ref +); + +ruby_undef_def( + unique int id: @ruby_undef +); + +@ruby_unless_alternative_type = @ruby_else | @ruby_elsif + +ruby_unless_alternative( + unique int ruby_unless: @ruby_unless ref, + unique int alternative: @ruby_unless_alternative_type ref +); + +ruby_unless_consequence( + unique int ruby_unless: @ruby_unless ref, + unique int consequence: @ruby_then ref +); + +ruby_unless_def( + unique int id: @ruby_unless, + int condition: @ruby_underscore_statement ref +); + +ruby_unless_guard_def( + unique int id: @ruby_unless_guard, + int condition: @ruby_underscore_expression ref +); + +ruby_unless_modifier_def( + unique int id: @ruby_unless_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +ruby_until_def( + unique int id: @ruby_until, + int body: @ruby_do ref, + int condition: @ruby_underscore_statement ref +); + +ruby_until_modifier_def( + unique int id: @ruby_until_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +@ruby_variable_reference_pattern_name_type = @ruby_token_identifier | @ruby_underscore_nonlocal_variable + +ruby_variable_reference_pattern_def( + unique int id: @ruby_variable_reference_pattern, + int name: @ruby_variable_reference_pattern_name_type ref +); + +ruby_when_body( + unique int ruby_when: @ruby_when ref, + unique int body: @ruby_then ref +); + +#keyset[ruby_when, index] +ruby_when_pattern( + int ruby_when: @ruby_when ref, + int index: int ref, + unique int pattern: @ruby_pattern ref +); + +ruby_when_def( + unique int id: @ruby_when +); + +ruby_while_def( + unique int id: @ruby_while, + int body: @ruby_do ref, + int condition: @ruby_underscore_statement ref +); + +ruby_while_modifier_def( + unique int id: @ruby_while_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +ruby_yield_child( + unique int ruby_yield: @ruby_yield ref, + unique int child: @ruby_argument_list ref +); + +ruby_yield_def( + unique int id: @ruby_yield +); + +ruby_tokeninfo( + unique int id: @ruby_token, + int kind: int ref, + string value: string ref +); + +case @ruby_token.kind of + 0 = @ruby_reserved_word +| 1 = @ruby_token_character +| 2 = @ruby_token_class_variable +| 3 = @ruby_token_comment +| 4 = @ruby_token_constant +| 5 = @ruby_token_empty_statement +| 6 = @ruby_token_encoding +| 7 = @ruby_token_escape_sequence +| 8 = @ruby_token_false +| 9 = @ruby_token_file +| 10 = @ruby_token_float +| 11 = @ruby_token_forward_argument +| 12 = @ruby_token_forward_parameter +| 13 = @ruby_token_global_variable +| 14 = @ruby_token_hash_key_symbol +| 15 = @ruby_token_hash_splat_nil +| 16 = @ruby_token_heredoc_beginning +| 17 = @ruby_token_heredoc_content +| 18 = @ruby_token_heredoc_end +| 19 = @ruby_token_identifier +| 20 = @ruby_token_instance_variable +| 21 = @ruby_token_integer +| 22 = @ruby_token_line +| 23 = @ruby_token_nil +| 24 = @ruby_token_operator +| 25 = @ruby_token_self +| 26 = @ruby_token_simple_symbol +| 27 = @ruby_token_string_content +| 28 = @ruby_token_super +| 29 = @ruby_token_true +| 30 = @ruby_token_uninterpreted +; + + +@ruby_ast_node = @ruby_alias | @ruby_alternative_pattern | @ruby_argument_list | @ruby_array | @ruby_array_pattern | @ruby_as_pattern | @ruby_assignment | @ruby_bare_string | @ruby_bare_symbol | @ruby_begin | @ruby_begin_block | @ruby_binary | @ruby_block | @ruby_block_argument | @ruby_block_body | @ruby_block_parameter | @ruby_block_parameters | @ruby_body_statement | @ruby_break | @ruby_call | @ruby_case__ | @ruby_case_match | @ruby_chained_string | @ruby_class | @ruby_complex | @ruby_conditional | @ruby_delimited_symbol | @ruby_destructured_left_assignment | @ruby_destructured_parameter | @ruby_do | @ruby_do_block | @ruby_element_reference | @ruby_else | @ruby_elsif | @ruby_end_block | @ruby_ensure | @ruby_exception_variable | @ruby_exceptions | @ruby_expression_reference_pattern | @ruby_find_pattern | @ruby_for | @ruby_hash | @ruby_hash_pattern | @ruby_hash_splat_argument | @ruby_hash_splat_parameter | @ruby_heredoc_body | @ruby_if | @ruby_if_guard | @ruby_if_modifier | @ruby_in | @ruby_in_clause | @ruby_interpolation | @ruby_keyword_parameter | @ruby_keyword_pattern | @ruby_lambda | @ruby_lambda_parameters | @ruby_left_assignment_list | @ruby_match_pattern | @ruby_method | @ruby_method_parameters | @ruby_module | @ruby_next | @ruby_operator_assignment | @ruby_optional_parameter | @ruby_pair | @ruby_parenthesized_pattern | @ruby_parenthesized_statements | @ruby_pattern | @ruby_program | @ruby_range | @ruby_rational | @ruby_redo | @ruby_regex | @ruby_rescue | @ruby_rescue_modifier | @ruby_rest_assignment | @ruby_retry | @ruby_return | @ruby_right_assignment_list | @ruby_scope_resolution | @ruby_setter | @ruby_singleton_class | @ruby_singleton_method | @ruby_splat_argument | @ruby_splat_parameter | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_superclass | @ruby_symbol_array | @ruby_test_pattern | @ruby_then | @ruby_token | @ruby_unary | @ruby_undef | @ruby_unless | @ruby_unless_guard | @ruby_unless_modifier | @ruby_until | @ruby_until_modifier | @ruby_variable_reference_pattern | @ruby_when | @ruby_while | @ruby_while_modifier | @ruby_yield + +ruby_ast_node_location( + unique int node: @ruby_ast_node ref, + int loc: @location_default ref +); + +#keyset[parent, parent_index] +ruby_ast_node_parent( + unique int node: @ruby_ast_node ref, + int parent: @ruby_ast_node ref, + int parent_index: int ref +); + +/*- Erb dbscheme -*/ +erb_comment_directive_child( + unique int erb_comment_directive: @erb_comment_directive ref, + unique int child: @erb_token_comment ref +); + +erb_comment_directive_def( + unique int id: @erb_comment_directive +); + +erb_directive_child( + unique int erb_directive: @erb_directive ref, + unique int child: @erb_token_code ref +); + +erb_directive_def( + unique int id: @erb_directive +); + +erb_graphql_directive_child( + unique int erb_graphql_directive: @erb_graphql_directive ref, + unique int child: @erb_token_code ref +); + +erb_graphql_directive_def( + unique int id: @erb_graphql_directive +); + +erb_output_directive_child( + unique int erb_output_directive: @erb_output_directive ref, + unique int child: @erb_token_code ref +); + +erb_output_directive_def( + unique int id: @erb_output_directive +); + +@erb_template_child_type = @erb_comment_directive | @erb_directive | @erb_graphql_directive | @erb_output_directive | @erb_token_content + +#keyset[erb_template, index] +erb_template_child( + int erb_template: @erb_template ref, + int index: int ref, + unique int child: @erb_template_child_type ref +); + +erb_template_def( + unique int id: @erb_template +); + +erb_tokeninfo( + unique int id: @erb_token, + int kind: int ref, + string value: string ref +); + +case @erb_token.kind of + 0 = @erb_reserved_word +| 1 = @erb_token_code +| 2 = @erb_token_comment +| 3 = @erb_token_content +; + + +@erb_ast_node = @erb_comment_directive | @erb_directive | @erb_graphql_directive | @erb_output_directive | @erb_template | @erb_token + +erb_ast_node_location( + unique int node: @erb_ast_node ref, + int loc: @location_default ref +); + +#keyset[parent, parent_index] +erb_ast_node_parent( + unique int node: @erb_ast_node ref, + int parent: @erb_ast_node ref, + int parent_index: int ref +); + diff --git a/ruby/ql/lib/upgrades/40a6b0a5e81115bd870b3a12a1fe954b06362bb7/ruby.dbscheme b/ruby/ql/lib/upgrades/40a6b0a5e81115bd870b3a12a1fe954b06362bb7/ruby.dbscheme new file mode 100644 index 000000000000..dc51d416301d --- /dev/null +++ b/ruby/ql/lib/upgrades/40a6b0a5e81115bd870b3a12a1fe954b06362bb7/ruby.dbscheme @@ -0,0 +1,1532 @@ +// CodeQL database schema for Ruby +// Automatically generated from the tree-sitter grammar; do not edit + +/*- Files and folders -*/ + +/** + * The location of an element. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @file | @folder + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/*- Empty location -*/ + +empty_location( + int location: @location_default ref +); + +/*- Source location prefix -*/ + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/*- Diagnostic messages -*/ + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/*- Diagnostic messages: severity -*/ + +case @diagnostic.severity of + 10 = @diagnostic_debug +| 20 = @diagnostic_info +| 30 = @diagnostic_warning +| 40 = @diagnostic_error +; + +/*- YAML -*/ + +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + string tag: string ref, + string tostring: string ref); + +case @yaml_node.kind of + 0 = @yaml_scalar_node +| 1 = @yaml_mapping_node +| 2 = @yaml_sequence_node +| 3 = @yaml_alias_node +; + +@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node; + +@yaml_node_parent = @yaml_collection_node | @file; + +yaml_anchors (unique int node: @yaml_node ref, + string anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + string target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + string value: string ref); + +yaml_errors (unique int id: @yaml_error, + string message: string ref); + +yaml_locations(unique int locatable: @yaml_locatable ref, + int location: @location_default ref); + +@yaml_locatable = @yaml_node | @yaml_error; + +/*- Database metadata -*/ +databaseMetadata( + string metadataKey: string ref, + string value: string ref +); + +/*- Ruby dbscheme -*/ +@ruby_underscore_arg = @ruby_assignment | @ruby_binary | @ruby_conditional | @ruby_operator_assignment | @ruby_range | @ruby_unary | @ruby_underscore_primary + +@ruby_underscore_call_operator = @ruby_reserved_word + +@ruby_underscore_expression = @ruby_assignment | @ruby_binary | @ruby_break | @ruby_call | @ruby_match_pattern | @ruby_next | @ruby_operator_assignment | @ruby_return | @ruby_test_pattern | @ruby_unary | @ruby_underscore_arg | @ruby_yield + +@ruby_underscore_lhs = @ruby_call | @ruby_element_reference | @ruby_scope_resolution | @ruby_token_false | @ruby_token_nil | @ruby_token_true | @ruby_underscore_variable + +@ruby_underscore_method_name = @ruby_delimited_symbol | @ruby_setter | @ruby_token_constant | @ruby_token_identifier | @ruby_token_operator | @ruby_token_simple_symbol | @ruby_underscore_nonlocal_variable + +@ruby_underscore_nonlocal_variable = @ruby_token_class_variable | @ruby_token_global_variable | @ruby_token_instance_variable + +@ruby_underscore_pattern_constant = @ruby_scope_resolution | @ruby_token_constant + +@ruby_underscore_pattern_expr = @ruby_alternative_pattern | @ruby_as_pattern | @ruby_underscore_pattern_expr_basic + +@ruby_underscore_pattern_expr_basic = @ruby_array_pattern | @ruby_expression_reference_pattern | @ruby_find_pattern | @ruby_hash_pattern | @ruby_parenthesized_pattern | @ruby_range | @ruby_token_identifier | @ruby_underscore_pattern_constant | @ruby_underscore_pattern_primitive | @ruby_variable_reference_pattern + +@ruby_underscore_pattern_primitive = @ruby_delimited_symbol | @ruby_lambda | @ruby_regex | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_symbol_array | @ruby_token_encoding | @ruby_token_false | @ruby_token_file | @ruby_token_heredoc_beginning | @ruby_token_line | @ruby_token_nil | @ruby_token_self | @ruby_token_simple_symbol | @ruby_token_true | @ruby_unary | @ruby_underscore_simple_numeric + +@ruby_underscore_pattern_top_expr_body = @ruby_array_pattern | @ruby_find_pattern | @ruby_hash_pattern | @ruby_underscore_pattern_expr + +@ruby_underscore_primary = @ruby_array | @ruby_begin | @ruby_break | @ruby_call | @ruby_case__ | @ruby_case_match | @ruby_chained_string | @ruby_class | @ruby_delimited_symbol | @ruby_for | @ruby_hash | @ruby_if | @ruby_lambda | @ruby_method | @ruby_module | @ruby_next | @ruby_parenthesized_statements | @ruby_redo | @ruby_regex | @ruby_retry | @ruby_return | @ruby_singleton_class | @ruby_singleton_method | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_symbol_array | @ruby_token_character | @ruby_token_heredoc_beginning | @ruby_token_simple_symbol | @ruby_unary | @ruby_underscore_lhs | @ruby_underscore_simple_numeric | @ruby_unless | @ruby_until | @ruby_while | @ruby_yield + +@ruby_underscore_simple_numeric = @ruby_complex | @ruby_rational | @ruby_token_float | @ruby_token_integer + +@ruby_underscore_statement = @ruby_alias | @ruby_begin_block | @ruby_end_block | @ruby_if_modifier | @ruby_rescue_modifier | @ruby_undef | @ruby_underscore_expression | @ruby_unless_modifier | @ruby_until_modifier | @ruby_while_modifier + +@ruby_underscore_variable = @ruby_token_constant | @ruby_token_identifier | @ruby_token_self | @ruby_token_super | @ruby_underscore_nonlocal_variable + +ruby_alias_def( + unique int id: @ruby_alias, + int alias: @ruby_underscore_method_name ref, + int name: @ruby_underscore_method_name ref +); + +#keyset[ruby_alternative_pattern, index] +ruby_alternative_pattern_alternatives( + int ruby_alternative_pattern: @ruby_alternative_pattern ref, + int index: int ref, + unique int alternatives: @ruby_underscore_pattern_expr_basic ref +); + +ruby_alternative_pattern_def( + unique int id: @ruby_alternative_pattern +); + +@ruby_argument_list_child_type = @ruby_block_argument | @ruby_hash_splat_argument | @ruby_pair | @ruby_splat_argument | @ruby_token_forward_argument | @ruby_underscore_expression + +#keyset[ruby_argument_list, index] +ruby_argument_list_child( + int ruby_argument_list: @ruby_argument_list ref, + int index: int ref, + unique int child: @ruby_argument_list_child_type ref +); + +ruby_argument_list_def( + unique int id: @ruby_argument_list +); + +@ruby_array_child_type = @ruby_block_argument | @ruby_hash_splat_argument | @ruby_pair | @ruby_splat_argument | @ruby_token_forward_argument | @ruby_underscore_expression + +#keyset[ruby_array, index] +ruby_array_child( + int ruby_array: @ruby_array ref, + int index: int ref, + unique int child: @ruby_array_child_type ref +); + +ruby_array_def( + unique int id: @ruby_array +); + +ruby_array_pattern_class( + unique int ruby_array_pattern: @ruby_array_pattern ref, + unique int class: @ruby_underscore_pattern_constant ref +); + +@ruby_array_pattern_child_type = @ruby_splat_parameter | @ruby_underscore_pattern_expr + +#keyset[ruby_array_pattern, index] +ruby_array_pattern_child( + int ruby_array_pattern: @ruby_array_pattern ref, + int index: int ref, + unique int child: @ruby_array_pattern_child_type ref +); + +ruby_array_pattern_def( + unique int id: @ruby_array_pattern +); + +ruby_as_pattern_def( + unique int id: @ruby_as_pattern, + int name: @ruby_token_identifier ref, + int value: @ruby_underscore_pattern_expr ref +); + +@ruby_assignment_left_type = @ruby_left_assignment_list | @ruby_underscore_lhs + +@ruby_assignment_right_type = @ruby_rescue_modifier | @ruby_right_assignment_list | @ruby_splat_argument | @ruby_underscore_expression + +ruby_assignment_def( + unique int id: @ruby_assignment, + int left: @ruby_assignment_left_type ref, + int right: @ruby_assignment_right_type ref +); + +@ruby_bare_string_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_bare_string, index] +ruby_bare_string_child( + int ruby_bare_string: @ruby_bare_string ref, + int index: int ref, + unique int child: @ruby_bare_string_child_type ref +); + +ruby_bare_string_def( + unique int id: @ruby_bare_string +); + +@ruby_bare_symbol_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_bare_symbol, index] +ruby_bare_symbol_child( + int ruby_bare_symbol: @ruby_bare_symbol ref, + int index: int ref, + unique int child: @ruby_bare_symbol_child_type ref +); + +ruby_bare_symbol_def( + unique int id: @ruby_bare_symbol +); + +@ruby_begin_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_begin, index] +ruby_begin_child( + int ruby_begin: @ruby_begin ref, + int index: int ref, + unique int child: @ruby_begin_child_type ref +); + +ruby_begin_def( + unique int id: @ruby_begin +); + +@ruby_begin_block_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_begin_block, index] +ruby_begin_block_child( + int ruby_begin_block: @ruby_begin_block ref, + int index: int ref, + unique int child: @ruby_begin_block_child_type ref +); + +ruby_begin_block_def( + unique int id: @ruby_begin_block +); + +@ruby_binary_left_type = @ruby_underscore_expression | @ruby_underscore_simple_numeric + +case @ruby_binary.operator of + 0 = @ruby_binary_bangequal +| 1 = @ruby_binary_bangtilde +| 2 = @ruby_binary_percent +| 3 = @ruby_binary_ampersand +| 4 = @ruby_binary_ampersandampersand +| 5 = @ruby_binary_star +| 6 = @ruby_binary_starstar +| 7 = @ruby_binary_plus +| 8 = @ruby_binary_minus +| 9 = @ruby_binary_slash +| 10 = @ruby_binary_langle +| 11 = @ruby_binary_langlelangle +| 12 = @ruby_binary_langleequal +| 13 = @ruby_binary_langleequalrangle +| 14 = @ruby_binary_equalequal +| 15 = @ruby_binary_equalequalequal +| 16 = @ruby_binary_equaltilde +| 17 = @ruby_binary_rangle +| 18 = @ruby_binary_rangleequal +| 19 = @ruby_binary_ranglerangle +| 20 = @ruby_binary_caret +| 21 = @ruby_binary_and +| 22 = @ruby_binary_or +| 23 = @ruby_binary_pipe +| 24 = @ruby_binary_pipepipe +; + + +ruby_binary_def( + unique int id: @ruby_binary, + int left: @ruby_binary_left_type ref, + int operator: int ref, + int right: @ruby_underscore_expression ref +); + +ruby_block_body( + unique int ruby_block: @ruby_block ref, + unique int body: @ruby_block_body ref +); + +ruby_block_parameters( + unique int ruby_block: @ruby_block ref, + unique int parameters: @ruby_block_parameters ref +); + +ruby_block_def( + unique int id: @ruby_block +); + +ruby_block_argument_child( + unique int ruby_block_argument: @ruby_block_argument ref, + unique int child: @ruby_underscore_arg ref +); + +ruby_block_argument_def( + unique int id: @ruby_block_argument +); + +@ruby_block_body_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_block_body, index] +ruby_block_body_child( + int ruby_block_body: @ruby_block_body ref, + int index: int ref, + unique int child: @ruby_block_body_child_type ref +); + +ruby_block_body_def( + unique int id: @ruby_block_body +); + +ruby_block_parameter_name( + unique int ruby_block_parameter: @ruby_block_parameter ref, + unique int name: @ruby_token_identifier ref +); + +ruby_block_parameter_def( + unique int id: @ruby_block_parameter +); + +#keyset[ruby_block_parameters, index] +ruby_block_parameters_locals( + int ruby_block_parameters: @ruby_block_parameters ref, + int index: int ref, + unique int locals: @ruby_token_identifier ref +); + +@ruby_block_parameters_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_block_parameters, index] +ruby_block_parameters_child( + int ruby_block_parameters: @ruby_block_parameters ref, + int index: int ref, + unique int child: @ruby_block_parameters_child_type ref +); + +ruby_block_parameters_def( + unique int id: @ruby_block_parameters +); + +@ruby_body_statement_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_body_statement, index] +ruby_body_statement_child( + int ruby_body_statement: @ruby_body_statement ref, + int index: int ref, + unique int child: @ruby_body_statement_child_type ref +); + +ruby_body_statement_def( + unique int id: @ruby_body_statement +); + +ruby_break_child( + unique int ruby_break: @ruby_break ref, + unique int child: @ruby_argument_list ref +); + +ruby_break_def( + unique int id: @ruby_break +); + +ruby_call_arguments( + unique int ruby_call: @ruby_call ref, + unique int arguments: @ruby_argument_list ref +); + +@ruby_call_block_type = @ruby_block | @ruby_do_block + +ruby_call_block( + unique int ruby_call: @ruby_call ref, + unique int block: @ruby_call_block_type ref +); + +@ruby_call_method_type = @ruby_token_operator | @ruby_underscore_variable + +ruby_call_method( + unique int ruby_call: @ruby_call ref, + unique int method: @ruby_call_method_type ref +); + +ruby_call_operator( + unique int ruby_call: @ruby_call ref, + unique int operator: @ruby_underscore_call_operator ref +); + +ruby_call_receiver( + unique int ruby_call: @ruby_call ref, + unique int receiver: @ruby_underscore_primary ref +); + +ruby_call_def( + unique int id: @ruby_call +); + +ruby_case_value( + unique int ruby_case__: @ruby_case__ ref, + unique int value: @ruby_underscore_statement ref +); + +@ruby_case_child_type = @ruby_else | @ruby_when + +#keyset[ruby_case__, index] +ruby_case_child( + int ruby_case__: @ruby_case__ ref, + int index: int ref, + unique int child: @ruby_case_child_type ref +); + +ruby_case_def( + unique int id: @ruby_case__ +); + +#keyset[ruby_case_match, index] +ruby_case_match_clauses( + int ruby_case_match: @ruby_case_match ref, + int index: int ref, + unique int clauses: @ruby_in_clause ref +); + +ruby_case_match_else( + unique int ruby_case_match: @ruby_case_match ref, + unique int else: @ruby_else ref +); + +ruby_case_match_def( + unique int id: @ruby_case_match, + int value: @ruby_underscore_statement ref +); + +#keyset[ruby_chained_string, index] +ruby_chained_string_child( + int ruby_chained_string: @ruby_chained_string ref, + int index: int ref, + unique int child: @ruby_string__ ref +); + +ruby_chained_string_def( + unique int id: @ruby_chained_string +); + +ruby_class_body( + unique int ruby_class: @ruby_class ref, + unique int body: @ruby_body_statement ref +); + +@ruby_class_name_type = @ruby_scope_resolution | @ruby_token_constant + +ruby_class_superclass( + unique int ruby_class: @ruby_class ref, + unique int superclass: @ruby_superclass ref +); + +ruby_class_def( + unique int id: @ruby_class, + int name: @ruby_class_name_type ref +); + +@ruby_complex_child_type = @ruby_rational | @ruby_token_float | @ruby_token_integer + +ruby_complex_def( + unique int id: @ruby_complex, + int child: @ruby_complex_child_type ref +); + +ruby_conditional_def( + unique int id: @ruby_conditional, + int alternative: @ruby_underscore_arg ref, + int condition: @ruby_underscore_arg ref, + int consequence: @ruby_underscore_arg ref +); + +@ruby_delimited_symbol_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_delimited_symbol, index] +ruby_delimited_symbol_child( + int ruby_delimited_symbol: @ruby_delimited_symbol ref, + int index: int ref, + unique int child: @ruby_delimited_symbol_child_type ref +); + +ruby_delimited_symbol_def( + unique int id: @ruby_delimited_symbol +); + +@ruby_destructured_left_assignment_child_type = @ruby_destructured_left_assignment | @ruby_rest_assignment | @ruby_underscore_lhs + +#keyset[ruby_destructured_left_assignment, index] +ruby_destructured_left_assignment_child( + int ruby_destructured_left_assignment: @ruby_destructured_left_assignment ref, + int index: int ref, + unique int child: @ruby_destructured_left_assignment_child_type ref +); + +ruby_destructured_left_assignment_def( + unique int id: @ruby_destructured_left_assignment +); + +@ruby_destructured_parameter_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_destructured_parameter, index] +ruby_destructured_parameter_child( + int ruby_destructured_parameter: @ruby_destructured_parameter ref, + int index: int ref, + unique int child: @ruby_destructured_parameter_child_type ref +); + +ruby_destructured_parameter_def( + unique int id: @ruby_destructured_parameter +); + +@ruby_do_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_do, index] +ruby_do_child( + int ruby_do: @ruby_do ref, + int index: int ref, + unique int child: @ruby_do_child_type ref +); + +ruby_do_def( + unique int id: @ruby_do +); + +ruby_do_block_body( + unique int ruby_do_block: @ruby_do_block ref, + unique int body: @ruby_body_statement ref +); + +ruby_do_block_parameters( + unique int ruby_do_block: @ruby_do_block ref, + unique int parameters: @ruby_block_parameters ref +); + +ruby_do_block_def( + unique int id: @ruby_do_block +); + +@ruby_element_reference_block_type = @ruby_block | @ruby_do_block + +ruby_element_reference_block( + unique int ruby_element_reference: @ruby_element_reference ref, + unique int block: @ruby_element_reference_block_type ref +); + +@ruby_element_reference_child_type = @ruby_block_argument | @ruby_hash_splat_argument | @ruby_pair | @ruby_splat_argument | @ruby_token_forward_argument | @ruby_underscore_expression + +#keyset[ruby_element_reference, index] +ruby_element_reference_child( + int ruby_element_reference: @ruby_element_reference ref, + int index: int ref, + unique int child: @ruby_element_reference_child_type ref +); + +ruby_element_reference_def( + unique int id: @ruby_element_reference, + int object: @ruby_underscore_primary ref +); + +@ruby_else_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_else, index] +ruby_else_child( + int ruby_else: @ruby_else ref, + int index: int ref, + unique int child: @ruby_else_child_type ref +); + +ruby_else_def( + unique int id: @ruby_else +); + +@ruby_elsif_alternative_type = @ruby_else | @ruby_elsif + +ruby_elsif_alternative( + unique int ruby_elsif: @ruby_elsif ref, + unique int alternative: @ruby_elsif_alternative_type ref +); + +ruby_elsif_consequence( + unique int ruby_elsif: @ruby_elsif ref, + unique int consequence: @ruby_then ref +); + +ruby_elsif_def( + unique int id: @ruby_elsif, + int condition: @ruby_underscore_statement ref +); + +@ruby_end_block_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_end_block, index] +ruby_end_block_child( + int ruby_end_block: @ruby_end_block ref, + int index: int ref, + unique int child: @ruby_end_block_child_type ref +); + +ruby_end_block_def( + unique int id: @ruby_end_block +); + +@ruby_ensure_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_ensure, index] +ruby_ensure_child( + int ruby_ensure: @ruby_ensure ref, + int index: int ref, + unique int child: @ruby_ensure_child_type ref +); + +ruby_ensure_def( + unique int id: @ruby_ensure +); + +ruby_exception_variable_def( + unique int id: @ruby_exception_variable, + int child: @ruby_underscore_lhs ref +); + +@ruby_exceptions_child_type = @ruby_splat_argument | @ruby_underscore_arg + +#keyset[ruby_exceptions, index] +ruby_exceptions_child( + int ruby_exceptions: @ruby_exceptions ref, + int index: int ref, + unique int child: @ruby_exceptions_child_type ref +); + +ruby_exceptions_def( + unique int id: @ruby_exceptions +); + +ruby_expression_reference_pattern_def( + unique int id: @ruby_expression_reference_pattern, + int value: @ruby_underscore_expression ref +); + +ruby_find_pattern_class( + unique int ruby_find_pattern: @ruby_find_pattern ref, + unique int class: @ruby_underscore_pattern_constant ref +); + +@ruby_find_pattern_child_type = @ruby_splat_parameter | @ruby_underscore_pattern_expr + +#keyset[ruby_find_pattern, index] +ruby_find_pattern_child( + int ruby_find_pattern: @ruby_find_pattern ref, + int index: int ref, + unique int child: @ruby_find_pattern_child_type ref +); + +ruby_find_pattern_def( + unique int id: @ruby_find_pattern +); + +@ruby_for_pattern_type = @ruby_left_assignment_list | @ruby_underscore_lhs + +ruby_for_def( + unique int id: @ruby_for, + int body: @ruby_do ref, + int pattern: @ruby_for_pattern_type ref, + int value: @ruby_in ref +); + +@ruby_hash_child_type = @ruby_hash_splat_argument | @ruby_pair + +#keyset[ruby_hash, index] +ruby_hash_child( + int ruby_hash: @ruby_hash ref, + int index: int ref, + unique int child: @ruby_hash_child_type ref +); + +ruby_hash_def( + unique int id: @ruby_hash +); + +ruby_hash_pattern_class( + unique int ruby_hash_pattern: @ruby_hash_pattern ref, + unique int class: @ruby_underscore_pattern_constant ref +); + +@ruby_hash_pattern_child_type = @ruby_hash_splat_parameter | @ruby_keyword_pattern | @ruby_token_hash_splat_nil + +#keyset[ruby_hash_pattern, index] +ruby_hash_pattern_child( + int ruby_hash_pattern: @ruby_hash_pattern ref, + int index: int ref, + unique int child: @ruby_hash_pattern_child_type ref +); + +ruby_hash_pattern_def( + unique int id: @ruby_hash_pattern +); + +ruby_hash_splat_argument_child( + unique int ruby_hash_splat_argument: @ruby_hash_splat_argument ref, + unique int child: @ruby_underscore_arg ref +); + +ruby_hash_splat_argument_def( + unique int id: @ruby_hash_splat_argument +); + +ruby_hash_splat_parameter_name( + unique int ruby_hash_splat_parameter: @ruby_hash_splat_parameter ref, + unique int name: @ruby_token_identifier ref +); + +ruby_hash_splat_parameter_def( + unique int id: @ruby_hash_splat_parameter +); + +@ruby_heredoc_body_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_heredoc_content | @ruby_token_heredoc_end + +#keyset[ruby_heredoc_body, index] +ruby_heredoc_body_child( + int ruby_heredoc_body: @ruby_heredoc_body ref, + int index: int ref, + unique int child: @ruby_heredoc_body_child_type ref +); + +ruby_heredoc_body_def( + unique int id: @ruby_heredoc_body +); + +@ruby_if_alternative_type = @ruby_else | @ruby_elsif + +ruby_if_alternative( + unique int ruby_if: @ruby_if ref, + unique int alternative: @ruby_if_alternative_type ref +); + +ruby_if_consequence( + unique int ruby_if: @ruby_if ref, + unique int consequence: @ruby_then ref +); + +ruby_if_def( + unique int id: @ruby_if, + int condition: @ruby_underscore_statement ref +); + +ruby_if_guard_def( + unique int id: @ruby_if_guard, + int condition: @ruby_underscore_expression ref +); + +ruby_if_modifier_def( + unique int id: @ruby_if_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +ruby_in_def( + unique int id: @ruby_in, + int child: @ruby_underscore_arg ref +); + +ruby_in_clause_body( + unique int ruby_in_clause: @ruby_in_clause ref, + unique int body: @ruby_then ref +); + +@ruby_in_clause_guard_type = @ruby_if_guard | @ruby_unless_guard + +ruby_in_clause_guard( + unique int ruby_in_clause: @ruby_in_clause ref, + unique int guard: @ruby_in_clause_guard_type ref +); + +ruby_in_clause_def( + unique int id: @ruby_in_clause, + int pattern: @ruby_underscore_pattern_top_expr_body ref +); + +@ruby_interpolation_child_type = @ruby_token_empty_statement | @ruby_underscore_nonlocal_variable | @ruby_underscore_statement + +#keyset[ruby_interpolation, index] +ruby_interpolation_child( + int ruby_interpolation: @ruby_interpolation ref, + int index: int ref, + unique int child: @ruby_interpolation_child_type ref +); + +ruby_interpolation_def( + unique int id: @ruby_interpolation +); + +ruby_keyword_parameter_value( + unique int ruby_keyword_parameter: @ruby_keyword_parameter ref, + unique int value: @ruby_underscore_arg ref +); + +ruby_keyword_parameter_def( + unique int id: @ruby_keyword_parameter, + int name: @ruby_token_identifier ref +); + +@ruby_keyword_pattern_key_type = @ruby_string__ | @ruby_token_hash_key_symbol + +ruby_keyword_pattern_value( + unique int ruby_keyword_pattern: @ruby_keyword_pattern ref, + unique int value: @ruby_underscore_pattern_expr ref +); + +ruby_keyword_pattern_def( + unique int id: @ruby_keyword_pattern, + int key__: @ruby_keyword_pattern_key_type ref +); + +@ruby_lambda_body_type = @ruby_block | @ruby_do_block + +ruby_lambda_parameters( + unique int ruby_lambda: @ruby_lambda ref, + unique int parameters: @ruby_lambda_parameters ref +); + +ruby_lambda_def( + unique int id: @ruby_lambda, + int body: @ruby_lambda_body_type ref +); + +@ruby_lambda_parameters_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_lambda_parameters, index] +ruby_lambda_parameters_child( + int ruby_lambda_parameters: @ruby_lambda_parameters ref, + int index: int ref, + unique int child: @ruby_lambda_parameters_child_type ref +); + +ruby_lambda_parameters_def( + unique int id: @ruby_lambda_parameters +); + +@ruby_left_assignment_list_child_type = @ruby_destructured_left_assignment | @ruby_rest_assignment | @ruby_underscore_lhs + +#keyset[ruby_left_assignment_list, index] +ruby_left_assignment_list_child( + int ruby_left_assignment_list: @ruby_left_assignment_list ref, + int index: int ref, + unique int child: @ruby_left_assignment_list_child_type ref +); + +ruby_left_assignment_list_def( + unique int id: @ruby_left_assignment_list +); + +ruby_match_pattern_def( + unique int id: @ruby_match_pattern, + int pattern: @ruby_underscore_pattern_top_expr_body ref, + int value: @ruby_underscore_arg ref +); + +@ruby_method_body_type = @ruby_body_statement | @ruby_rescue_modifier | @ruby_underscore_arg + +ruby_method_body( + unique int ruby_method: @ruby_method ref, + unique int body: @ruby_method_body_type ref +); + +ruby_method_parameters( + unique int ruby_method: @ruby_method ref, + unique int parameters: @ruby_method_parameters ref +); + +ruby_method_def( + unique int id: @ruby_method, + int name: @ruby_underscore_method_name ref +); + +@ruby_method_parameters_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_method_parameters, index] +ruby_method_parameters_child( + int ruby_method_parameters: @ruby_method_parameters ref, + int index: int ref, + unique int child: @ruby_method_parameters_child_type ref +); + +ruby_method_parameters_def( + unique int id: @ruby_method_parameters +); + +ruby_module_body( + unique int ruby_module: @ruby_module ref, + unique int body: @ruby_body_statement ref +); + +@ruby_module_name_type = @ruby_scope_resolution | @ruby_token_constant + +ruby_module_def( + unique int id: @ruby_module, + int name: @ruby_module_name_type ref +); + +ruby_next_child( + unique int ruby_next: @ruby_next ref, + unique int child: @ruby_argument_list ref +); + +ruby_next_def( + unique int id: @ruby_next +); + +case @ruby_operator_assignment.operator of + 0 = @ruby_operator_assignment_percentequal +| 1 = @ruby_operator_assignment_ampersandampersandequal +| 2 = @ruby_operator_assignment_ampersandequal +| 3 = @ruby_operator_assignment_starstarequal +| 4 = @ruby_operator_assignment_starequal +| 5 = @ruby_operator_assignment_plusequal +| 6 = @ruby_operator_assignment_minusequal +| 7 = @ruby_operator_assignment_slashequal +| 8 = @ruby_operator_assignment_langlelangleequal +| 9 = @ruby_operator_assignment_ranglerangleequal +| 10 = @ruby_operator_assignment_caretequal +| 11 = @ruby_operator_assignment_pipeequal +| 12 = @ruby_operator_assignment_pipepipeequal +; + + +@ruby_operator_assignment_right_type = @ruby_rescue_modifier | @ruby_underscore_expression + +ruby_operator_assignment_def( + unique int id: @ruby_operator_assignment, + int left: @ruby_underscore_lhs ref, + int operator: int ref, + int right: @ruby_operator_assignment_right_type ref +); + +ruby_optional_parameter_def( + unique int id: @ruby_optional_parameter, + int name: @ruby_token_identifier ref, + int value: @ruby_underscore_arg ref +); + +@ruby_pair_key_type = @ruby_string__ | @ruby_token_hash_key_symbol | @ruby_underscore_arg + +ruby_pair_value( + unique int ruby_pair: @ruby_pair ref, + unique int value: @ruby_underscore_arg ref +); + +ruby_pair_def( + unique int id: @ruby_pair, + int key__: @ruby_pair_key_type ref +); + +ruby_parenthesized_pattern_def( + unique int id: @ruby_parenthesized_pattern, + int child: @ruby_underscore_pattern_expr ref +); + +@ruby_parenthesized_statements_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_parenthesized_statements, index] +ruby_parenthesized_statements_child( + int ruby_parenthesized_statements: @ruby_parenthesized_statements ref, + int index: int ref, + unique int child: @ruby_parenthesized_statements_child_type ref +); + +ruby_parenthesized_statements_def( + unique int id: @ruby_parenthesized_statements +); + +@ruby_pattern_child_type = @ruby_splat_argument | @ruby_underscore_arg + +ruby_pattern_def( + unique int id: @ruby_pattern, + int child: @ruby_pattern_child_type ref +); + +@ruby_program_child_type = @ruby_token_empty_statement | @ruby_token_uninterpreted | @ruby_underscore_statement + +#keyset[ruby_program, index] +ruby_program_child( + int ruby_program: @ruby_program ref, + int index: int ref, + unique int child: @ruby_program_child_type ref +); + +ruby_program_def( + unique int id: @ruby_program +); + +@ruby_range_begin_type = @ruby_underscore_arg | @ruby_underscore_pattern_primitive + +ruby_range_begin( + unique int ruby_range: @ruby_range ref, + unique int begin: @ruby_range_begin_type ref +); + +@ruby_range_end_type = @ruby_underscore_arg | @ruby_underscore_pattern_primitive + +ruby_range_end( + unique int ruby_range: @ruby_range ref, + unique int end: @ruby_range_end_type ref +); + +case @ruby_range.operator of + 0 = @ruby_range_dotdot +| 1 = @ruby_range_dotdotdot +; + + +ruby_range_def( + unique int id: @ruby_range, + int operator: int ref +); + +@ruby_rational_child_type = @ruby_token_float | @ruby_token_integer + +ruby_rational_def( + unique int id: @ruby_rational, + int child: @ruby_rational_child_type ref +); + +ruby_redo_child( + unique int ruby_redo: @ruby_redo ref, + unique int child: @ruby_argument_list ref +); + +ruby_redo_def( + unique int id: @ruby_redo +); + +@ruby_regex_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_regex, index] +ruby_regex_child( + int ruby_regex: @ruby_regex ref, + int index: int ref, + unique int child: @ruby_regex_child_type ref +); + +ruby_regex_def( + unique int id: @ruby_regex +); + +ruby_rescue_body( + unique int ruby_rescue: @ruby_rescue ref, + unique int body: @ruby_then ref +); + +ruby_rescue_exceptions( + unique int ruby_rescue: @ruby_rescue ref, + unique int exceptions: @ruby_exceptions ref +); + +ruby_rescue_variable( + unique int ruby_rescue: @ruby_rescue ref, + unique int variable: @ruby_exception_variable ref +); + +ruby_rescue_def( + unique int id: @ruby_rescue +); + +@ruby_rescue_modifier_body_type = @ruby_underscore_arg | @ruby_underscore_statement + +ruby_rescue_modifier_def( + unique int id: @ruby_rescue_modifier, + int body: @ruby_rescue_modifier_body_type ref, + int handler: @ruby_underscore_expression ref +); + +ruby_rest_assignment_child( + unique int ruby_rest_assignment: @ruby_rest_assignment ref, + unique int child: @ruby_underscore_lhs ref +); + +ruby_rest_assignment_def( + unique int id: @ruby_rest_assignment +); + +ruby_retry_child( + unique int ruby_retry: @ruby_retry ref, + unique int child: @ruby_argument_list ref +); + +ruby_retry_def( + unique int id: @ruby_retry +); + +ruby_return_child( + unique int ruby_return: @ruby_return ref, + unique int child: @ruby_argument_list ref +); + +ruby_return_def( + unique int id: @ruby_return +); + +@ruby_right_assignment_list_child_type = @ruby_splat_argument | @ruby_underscore_arg + +#keyset[ruby_right_assignment_list, index] +ruby_right_assignment_list_child( + int ruby_right_assignment_list: @ruby_right_assignment_list ref, + int index: int ref, + unique int child: @ruby_right_assignment_list_child_type ref +); + +ruby_right_assignment_list_def( + unique int id: @ruby_right_assignment_list +); + +@ruby_scope_resolution_scope_type = @ruby_underscore_pattern_constant | @ruby_underscore_primary + +ruby_scope_resolution_scope( + unique int ruby_scope_resolution: @ruby_scope_resolution ref, + unique int scope: @ruby_scope_resolution_scope_type ref +); + +ruby_scope_resolution_def( + unique int id: @ruby_scope_resolution, + int name: @ruby_token_constant ref +); + +ruby_setter_def( + unique int id: @ruby_setter, + int name: @ruby_token_identifier ref +); + +ruby_singleton_class_body( + unique int ruby_singleton_class: @ruby_singleton_class ref, + unique int body: @ruby_body_statement ref +); + +ruby_singleton_class_def( + unique int id: @ruby_singleton_class, + int value: @ruby_underscore_arg ref +); + +@ruby_singleton_method_body_type = @ruby_body_statement | @ruby_rescue_modifier | @ruby_underscore_arg + +ruby_singleton_method_body( + unique int ruby_singleton_method: @ruby_singleton_method ref, + unique int body: @ruby_singleton_method_body_type ref +); + +@ruby_singleton_method_object_type = @ruby_underscore_arg | @ruby_underscore_variable + +ruby_singleton_method_parameters( + unique int ruby_singleton_method: @ruby_singleton_method ref, + unique int parameters: @ruby_method_parameters ref +); + +ruby_singleton_method_def( + unique int id: @ruby_singleton_method, + int name: @ruby_underscore_method_name ref, + int object: @ruby_singleton_method_object_type ref +); + +ruby_splat_argument_child( + unique int ruby_splat_argument: @ruby_splat_argument ref, + unique int child: @ruby_underscore_arg ref +); + +ruby_splat_argument_def( + unique int id: @ruby_splat_argument +); + +ruby_splat_parameter_name( + unique int ruby_splat_parameter: @ruby_splat_parameter ref, + unique int name: @ruby_token_identifier ref +); + +ruby_splat_parameter_def( + unique int id: @ruby_splat_parameter +); + +@ruby_string_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_string__, index] +ruby_string_child( + int ruby_string__: @ruby_string__ ref, + int index: int ref, + unique int child: @ruby_string_child_type ref +); + +ruby_string_def( + unique int id: @ruby_string__ +); + +#keyset[ruby_string_array, index] +ruby_string_array_child( + int ruby_string_array: @ruby_string_array ref, + int index: int ref, + unique int child: @ruby_bare_string ref +); + +ruby_string_array_def( + unique int id: @ruby_string_array +); + +@ruby_subshell_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_subshell, index] +ruby_subshell_child( + int ruby_subshell: @ruby_subshell ref, + int index: int ref, + unique int child: @ruby_subshell_child_type ref +); + +ruby_subshell_def( + unique int id: @ruby_subshell +); + +ruby_superclass_def( + unique int id: @ruby_superclass, + int child: @ruby_underscore_expression ref +); + +#keyset[ruby_symbol_array, index] +ruby_symbol_array_child( + int ruby_symbol_array: @ruby_symbol_array ref, + int index: int ref, + unique int child: @ruby_bare_symbol ref +); + +ruby_symbol_array_def( + unique int id: @ruby_symbol_array +); + +ruby_test_pattern_def( + unique int id: @ruby_test_pattern, + int pattern: @ruby_underscore_pattern_top_expr_body ref, + int value: @ruby_underscore_arg ref +); + +@ruby_then_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_then, index] +ruby_then_child( + int ruby_then: @ruby_then ref, + int index: int ref, + unique int child: @ruby_then_child_type ref +); + +ruby_then_def( + unique int id: @ruby_then +); + +@ruby_unary_operand_type = @ruby_parenthesized_statements | @ruby_underscore_expression | @ruby_underscore_simple_numeric + +case @ruby_unary.operator of + 0 = @ruby_unary_bang +| 1 = @ruby_unary_plus +| 2 = @ruby_unary_minus +| 3 = @ruby_unary_definedquestion +| 4 = @ruby_unary_not +| 5 = @ruby_unary_tilde +; + + +ruby_unary_def( + unique int id: @ruby_unary, + int operand: @ruby_unary_operand_type ref, + int operator: int ref +); + +#keyset[ruby_undef, index] +ruby_undef_child( + int ruby_undef: @ruby_undef ref, + int index: int ref, + unique int child: @ruby_underscore_method_name ref +); + +ruby_undef_def( + unique int id: @ruby_undef +); + +@ruby_unless_alternative_type = @ruby_else | @ruby_elsif + +ruby_unless_alternative( + unique int ruby_unless: @ruby_unless ref, + unique int alternative: @ruby_unless_alternative_type ref +); + +ruby_unless_consequence( + unique int ruby_unless: @ruby_unless ref, + unique int consequence: @ruby_then ref +); + +ruby_unless_def( + unique int id: @ruby_unless, + int condition: @ruby_underscore_statement ref +); + +ruby_unless_guard_def( + unique int id: @ruby_unless_guard, + int condition: @ruby_underscore_expression ref +); + +ruby_unless_modifier_def( + unique int id: @ruby_unless_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +ruby_until_def( + unique int id: @ruby_until, + int body: @ruby_do ref, + int condition: @ruby_underscore_statement ref +); + +ruby_until_modifier_def( + unique int id: @ruby_until_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +@ruby_variable_reference_pattern_name_type = @ruby_token_identifier | @ruby_underscore_nonlocal_variable + +ruby_variable_reference_pattern_def( + unique int id: @ruby_variable_reference_pattern, + int name: @ruby_variable_reference_pattern_name_type ref +); + +ruby_when_body( + unique int ruby_when: @ruby_when ref, + unique int body: @ruby_then ref +); + +#keyset[ruby_when, index] +ruby_when_pattern( + int ruby_when: @ruby_when ref, + int index: int ref, + unique int pattern: @ruby_pattern ref +); + +ruby_when_def( + unique int id: @ruby_when +); + +ruby_while_def( + unique int id: @ruby_while, + int body: @ruby_do ref, + int condition: @ruby_underscore_statement ref +); + +ruby_while_modifier_def( + unique int id: @ruby_while_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +ruby_yield_child( + unique int ruby_yield: @ruby_yield ref, + unique int child: @ruby_argument_list ref +); + +ruby_yield_def( + unique int id: @ruby_yield +); + +ruby_tokeninfo( + unique int id: @ruby_token, + int kind: int ref, + string value: string ref +); + +case @ruby_token.kind of + 0 = @ruby_reserved_word +| 1 = @ruby_token_character +| 2 = @ruby_token_class_variable +| 3 = @ruby_token_comment +| 4 = @ruby_token_constant +| 5 = @ruby_token_empty_statement +| 6 = @ruby_token_encoding +| 7 = @ruby_token_escape_sequence +| 8 = @ruby_token_false +| 9 = @ruby_token_file +| 10 = @ruby_token_float +| 11 = @ruby_token_forward_argument +| 12 = @ruby_token_forward_parameter +| 13 = @ruby_token_global_variable +| 14 = @ruby_token_hash_key_symbol +| 15 = @ruby_token_hash_splat_nil +| 16 = @ruby_token_heredoc_beginning +| 17 = @ruby_token_heredoc_content +| 18 = @ruby_token_heredoc_end +| 19 = @ruby_token_identifier +| 20 = @ruby_token_instance_variable +| 21 = @ruby_token_integer +| 22 = @ruby_token_line +| 23 = @ruby_token_nil +| 24 = @ruby_token_operator +| 25 = @ruby_token_self +| 26 = @ruby_token_simple_symbol +| 27 = @ruby_token_string_content +| 28 = @ruby_token_super +| 29 = @ruby_token_true +| 30 = @ruby_token_uninterpreted +; + + +@ruby_ast_node = @ruby_alias | @ruby_alternative_pattern | @ruby_argument_list | @ruby_array | @ruby_array_pattern | @ruby_as_pattern | @ruby_assignment | @ruby_bare_string | @ruby_bare_symbol | @ruby_begin | @ruby_begin_block | @ruby_binary | @ruby_block | @ruby_block_argument | @ruby_block_body | @ruby_block_parameter | @ruby_block_parameters | @ruby_body_statement | @ruby_break | @ruby_call | @ruby_case__ | @ruby_case_match | @ruby_chained_string | @ruby_class | @ruby_complex | @ruby_conditional | @ruby_delimited_symbol | @ruby_destructured_left_assignment | @ruby_destructured_parameter | @ruby_do | @ruby_do_block | @ruby_element_reference | @ruby_else | @ruby_elsif | @ruby_end_block | @ruby_ensure | @ruby_exception_variable | @ruby_exceptions | @ruby_expression_reference_pattern | @ruby_find_pattern | @ruby_for | @ruby_hash | @ruby_hash_pattern | @ruby_hash_splat_argument | @ruby_hash_splat_parameter | @ruby_heredoc_body | @ruby_if | @ruby_if_guard | @ruby_if_modifier | @ruby_in | @ruby_in_clause | @ruby_interpolation | @ruby_keyword_parameter | @ruby_keyword_pattern | @ruby_lambda | @ruby_lambda_parameters | @ruby_left_assignment_list | @ruby_match_pattern | @ruby_method | @ruby_method_parameters | @ruby_module | @ruby_next | @ruby_operator_assignment | @ruby_optional_parameter | @ruby_pair | @ruby_parenthesized_pattern | @ruby_parenthesized_statements | @ruby_pattern | @ruby_program | @ruby_range | @ruby_rational | @ruby_redo | @ruby_regex | @ruby_rescue | @ruby_rescue_modifier | @ruby_rest_assignment | @ruby_retry | @ruby_return | @ruby_right_assignment_list | @ruby_scope_resolution | @ruby_setter | @ruby_singleton_class | @ruby_singleton_method | @ruby_splat_argument | @ruby_splat_parameter | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_superclass | @ruby_symbol_array | @ruby_test_pattern | @ruby_then | @ruby_token | @ruby_unary | @ruby_undef | @ruby_unless | @ruby_unless_guard | @ruby_unless_modifier | @ruby_until | @ruby_until_modifier | @ruby_variable_reference_pattern | @ruby_when | @ruby_while | @ruby_while_modifier | @ruby_yield + +ruby_ast_node_location( + unique int node: @ruby_ast_node ref, + int loc: @location_default ref +); + +#keyset[parent, parent_index] +ruby_ast_node_parent( + unique int node: @ruby_ast_node ref, + int parent: @ruby_ast_node ref, + int parent_index: int ref +); + +/*- Erb dbscheme -*/ +erb_comment_directive_child( + unique int erb_comment_directive: @erb_comment_directive ref, + unique int child: @erb_token_comment ref +); + +erb_comment_directive_def( + unique int id: @erb_comment_directive +); + +erb_directive_child( + unique int erb_directive: @erb_directive ref, + unique int child: @erb_token_code ref +); + +erb_directive_def( + unique int id: @erb_directive +); + +erb_graphql_directive_child( + unique int erb_graphql_directive: @erb_graphql_directive ref, + unique int child: @erb_token_code ref +); + +erb_graphql_directive_def( + unique int id: @erb_graphql_directive +); + +erb_output_directive_child( + unique int erb_output_directive: @erb_output_directive ref, + unique int child: @erb_token_code ref +); + +erb_output_directive_def( + unique int id: @erb_output_directive +); + +@erb_template_child_type = @erb_comment_directive | @erb_directive | @erb_graphql_directive | @erb_output_directive | @erb_token_content + +#keyset[erb_template, index] +erb_template_child( + int erb_template: @erb_template ref, + int index: int ref, + unique int child: @erb_template_child_type ref +); + +erb_template_def( + unique int id: @erb_template +); + +erb_tokeninfo( + unique int id: @erb_token, + int kind: int ref, + string value: string ref +); + +case @erb_token.kind of + 0 = @erb_reserved_word +| 1 = @erb_token_code +| 2 = @erb_token_comment +| 3 = @erb_token_content +; + + +@erb_ast_node = @erb_comment_directive | @erb_directive | @erb_graphql_directive | @erb_output_directive | @erb_template | @erb_token + +erb_ast_node_location( + unique int node: @erb_ast_node ref, + int loc: @location_default ref +); + +#keyset[parent, parent_index] +erb_ast_node_parent( + unique int node: @erb_ast_node ref, + int parent: @erb_ast_node ref, + int parent_index: int ref +); + diff --git a/ruby/ql/lib/upgrades/40a6b0a5e81115bd870b3a12a1fe954b06362bb7/upgrade.properties b/ruby/ql/lib/upgrades/40a6b0a5e81115bd870b3a12a1fe954b06362bb7/upgrade.properties new file mode 100644 index 000000000000..9b83871fb9b6 --- /dev/null +++ b/ruby/ql/lib/upgrades/40a6b0a5e81115bd870b3a12a1fe954b06362bb7/upgrade.properties @@ -0,0 +1,2 @@ +description: Add databaseMetadata relation +compatibility: full diff --git a/shared/tree-sitter-extractor/src/generator/mod.rs b/shared/tree-sitter-extractor/src/generator/mod.rs index d972e9fb128d..cb35f7ab7682 100644 --- a/shared/tree-sitter-extractor/src/generator/mod.rs +++ b/shared/tree-sitter-extractor/src/generator/mod.rs @@ -17,6 +17,7 @@ pub fn generate( languages: Vec, dbscheme_path: PathBuf, ql_library_path: PathBuf, + add_metadata_relation: bool, ) -> std::io::Result<()> { let dbscheme_file = File::create(dbscheme_path).map_err(|e| { tracing::error!("Failed to create dbscheme file: {}", e); @@ -32,6 +33,16 @@ pub fn generate( writeln!(dbscheme_writer, include_str!("prefix.dbscheme"))?; + // Eventually all languages will have the metadata relation (for overlay support), at which + // point this could be moved to prefix.dbscheme. + if add_metadata_relation { + writeln!(dbscheme_writer, "/*- Database metadata -*/",)?; + dbscheme::write( + &mut dbscheme_writer, + &[dbscheme::Entry::Table(create_database_metadata())], + )?; + } + let mut ql_writer = LineWriter::new(File::create(ql_library_path)?); writeln!( ql_writer, @@ -442,3 +453,26 @@ fn create_token_case<'a>(name: &'a str, token_kinds: Map<&'a str, usize>) -> dbs branches, } } + +fn create_database_metadata() -> dbscheme::Table<'static> { + dbscheme::Table { + name: "databaseMetadata", + keysets: None, + columns: vec![ + dbscheme::Column { + db_type: dbscheme::DbColumnType::String, + name: "metadataKey", + unique: false, + ql_type: ql::Type::String, + ql_type_is_ref: true, + }, + dbscheme::Column { + db_type: dbscheme::DbColumnType::String, + name: "value", + unique: false, + ql_type: ql::Type::String, + ql_type_is_ref: true, + }, + ], + } +} From fb89f221444df181530169fb901f90e325dedc03 Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Fri, 6 Jun 2025 11:36:27 +0100 Subject: [PATCH 3/3] Ruby: add minimal path transformer support Supports only a minimal subset of the project layout specification; enough to work with the transformers produced by the CLI when building an overlay database. --- ruby/extractor/src/extractor.rs | 28 ++++-- rust/extractor/src/archive.rs | 2 +- rust/extractor/src/trap.rs | 3 +- .../src/extractor/mod.rs | 34 ++++--- .../src/extractor/simple.rs | 5 +- .../tree-sitter-extractor/src/file_paths.rs | 94 ++++++++++++++++++- 6 files changed, 137 insertions(+), 29 deletions(-) diff --git a/ruby/extractor/src/extractor.rs b/ruby/extractor/src/extractor.rs index 92bcf748a087..983a918fee67 100644 --- a/ruby/extractor/src/extractor.rs +++ b/ruby/extractor/src/extractor.rs @@ -1,4 +1,5 @@ use clap::Args; +use codeql_extractor::file_paths::PathTransformer; use lazy_static::lazy_static; use rayon::prelude::*; use serde_json; @@ -81,6 +82,7 @@ pub fn run(options: Options) -> std::io::Result<()> { let file_list = fs::File::open(file_paths::path_from_string(&options.file_list))?; let overlay_changed_files: Option> = get_overlay_changed_files(); + let path_transformer = file_paths::load_path_transformer()?; let language: Language = tree_sitter_ruby::LANGUAGE.into(); let erb: Language = tree_sitter_embedded_template::LANGUAGE.into(); @@ -105,7 +107,7 @@ pub fn run(options: Options) -> std::io::Result<()> { } _ => {}, } - let src_archive_file = file_paths::path_for(&src_archive_dir, &path, ""); + let src_archive_file = file_paths::path_for(&src_archive_dir, &path, "", path_transformer.as_ref()); let mut source = std::fs::read(&path)?; let mut needs_conversion = false; let code_ranges; @@ -118,6 +120,7 @@ pub fn run(options: Options) -> std::io::Result<()> { &erb_schema, &mut diagnostics_writer, &mut trap_writer, + path_transformer.as_ref(), &path, &source, &[], @@ -162,7 +165,7 @@ pub fn run(options: Options) -> std::io::Result<()> { "character-decoding-error", "Character decoding error", ) - .file(&file_paths::normalize_path(&path)) + .file(&file_paths::normalize_and_transform_path(&path, path_transformer.as_ref())) .message( "Could not decode the file contents as {}: {}. The contents of the file must match the character encoding specified in the {} {}.", &[ @@ -182,7 +185,7 @@ pub fn run(options: Options) -> std::io::Result<()> { diagnostics_writer.write( diagnostics_writer .new_entry("unknown-character-encoding", "Could not process some files due to an unknown character encoding") - .file(&file_paths::normalize_path(&path)) + .file(&file_paths::normalize_and_transform_path(&path, path_transformer.as_ref())) .message( "Unknown character encoding {} in {} {}.", &[ @@ -205,6 +208,7 @@ pub fn run(options: Options) -> std::io::Result<()> { &schema, &mut diagnostics_writer, &mut trap_writer, + path_transformer.as_ref(), &path, &source, &code_ranges, @@ -215,14 +219,20 @@ pub fn run(options: Options) -> std::io::Result<()> { } else { std::fs::copy(&path, &src_archive_file)?; } - write_trap(&trap_dir, path, &trap_writer, trap_compression) + write_trap(&trap_dir, path, &trap_writer, trap_compression, path_transformer.as_ref()) }) .expect("failed to extract files"); let path = PathBuf::from("extras"); let mut trap_writer = trap::Writer::new(); extractor::populate_empty_location(&mut trap_writer); - let res = write_trap(&trap_dir, path, &trap_writer, trap_compression); + let res = write_trap( + &trap_dir, + path, + &trap_writer, + trap_compression, + path_transformer.as_ref(), + ); if let Ok(output_path) = std::env::var("CODEQL_EXTRACTOR_RUBY_OVERLAY_BASE_METADATA_OUT") { // We're extracting an overlay base. For now, we don't have any metadata we need to store // that would get read when extracting the overlay, but the CLI expects us to write @@ -254,8 +264,14 @@ fn write_trap( path: PathBuf, trap_writer: &trap::Writer, trap_compression: trap::Compression, + path_transformer: Option<&PathTransformer>, ) -> std::io::Result<()> { - let trap_file = file_paths::path_for(trap_dir, &path, trap_compression.extension()); + let trap_file = file_paths::path_for( + trap_dir, + &path, + trap_compression.extension(), + path_transformer, + ); std::fs::create_dir_all(trap_file.parent().unwrap())?; trap_writer.write_to_file(&trap_file, trap_compression) } diff --git a/rust/extractor/src/archive.rs b/rust/extractor/src/archive.rs index ad27c483942c..2cc3be227016 100644 --- a/rust/extractor/src/archive.rs +++ b/rust/extractor/src/archive.rs @@ -15,7 +15,7 @@ impl Archiver { } fn try_archive(&self, source: &Path) -> std::io::Result<()> { - let dest = file_paths::path_for(&self.root, source, ""); + let dest = file_paths::path_for(&self.root, source, "", None); if fs::metadata(&dest).is_ok() { return Ok(()); } diff --git a/rust/extractor/src/trap.rs b/rust/extractor/src/trap.rs index 2206c4c067b2..a7cb43a64327 100644 --- a/rust/extractor/src/trap.rs +++ b/rust/extractor/src/trap.rs @@ -212,7 +212,7 @@ impl TrapFile { ); } pub fn emit_file(&mut self, absolute_path: &Path) -> Label { - let untyped = extractor::populate_file(&mut self.writer, absolute_path); + let untyped = extractor::populate_file(&mut self.writer, absolute_path, None); // SAFETY: populate_file emits `@file` typed labels unsafe { Label::from_untyped(untyped) } } @@ -268,6 +268,7 @@ impl TrapFileProvider { &self.trap_dir.join(category), key.as_ref(), self.compression.extension(), + None, ); debug!("creating trap file {}", path.display()); let mut writer = trap::Writer::new(); diff --git a/shared/tree-sitter-extractor/src/extractor/mod.rs b/shared/tree-sitter-extractor/src/extractor/mod.rs index 18a0cfc94520..0bc489cd5591 100644 --- a/shared/tree-sitter-extractor/src/extractor/mod.rs +++ b/shared/tree-sitter-extractor/src/extractor/mod.rs @@ -67,19 +67,26 @@ pub fn default_subscriber_with_level( ), ) } -pub fn populate_file(writer: &mut trap::Writer, absolute_path: &Path) -> trap::Label { +pub fn populate_file( + writer: &mut trap::Writer, + absolute_path: &Path, + transformer: Option<&file_paths::PathTransformer>, +) -> trap::Label { let (file_label, fresh) = writer.global_id(&trap::full_id_for_file( - &file_paths::normalize_path(absolute_path), + &file_paths::normalize_and_transform_path(absolute_path, transformer), )); if fresh { writer.add_tuple( "files", vec![ trap::Arg::Label(file_label), - trap::Arg::String(file_paths::normalize_path(absolute_path)), + trap::Arg::String(file_paths::normalize_and_transform_path( + absolute_path, + transformer, + )), ], ); - populate_parent_folders(writer, file_label, absolute_path.parent()); + populate_parent_folders(writer, file_label, absolute_path.parent(), transformer); } file_label } @@ -117,6 +124,7 @@ pub fn populate_parent_folders( writer: &mut trap::Writer, child_label: trap::Label, path: Option<&Path>, + transformer: Option<&file_paths::PathTransformer>, ) { let mut path = path; let mut child_label = child_label; @@ -124,9 +132,9 @@ pub fn populate_parent_folders( match path { None => break, Some(folder) => { - let (folder_label, fresh) = writer.global_id(&trap::full_id_for_folder( - &file_paths::normalize_path(folder), - )); + let parent = folder.parent(); + let folder = file_paths::normalize_and_transform_path(folder, transformer); + let (folder_label, fresh) = writer.global_id(&trap::full_id_for_folder(&folder)); writer.add_tuple( "containerparent", vec![ @@ -137,12 +145,9 @@ pub fn populate_parent_folders( if fresh { writer.add_tuple( "folders", - vec![ - trap::Arg::Label(folder_label), - trap::Arg::String(file_paths::normalize_path(folder)), - ], + vec![trap::Arg::Label(folder_label), trap::Arg::String(folder)], ); - path = folder.parent(); + path = parent; child_label = folder_label; } else { break; @@ -205,11 +210,12 @@ pub fn extract( schema: &NodeTypeMap, diagnostics_writer: &mut diagnostics::LogWriter, trap_writer: &mut trap::Writer, + transformer: Option<&file_paths::PathTransformer>, path: &Path, source: &[u8], ranges: &[Range], ) { - let path_str = file_paths::normalize_path(path); + let path_str = file_paths::normalize_and_transform_path(path, transformer); let span = tracing::span!( tracing::Level::TRACE, "extract", @@ -225,7 +231,7 @@ pub fn extract( parser.set_included_ranges(ranges).unwrap(); let tree = parser.parse(source, None).expect("Failed to parse file"); trap_writer.comment(format!("Auto-generated TRAP file for {}", path_str)); - let file_label = populate_file(trap_writer, path); + let file_label = populate_file(trap_writer, path, transformer); let mut visitor = Visitor::new( source, diagnostics_writer, diff --git a/shared/tree-sitter-extractor/src/extractor/simple.rs b/shared/tree-sitter-extractor/src/extractor/simple.rs index eb1232a8ef2e..762ce59fa541 100644 --- a/shared/tree-sitter-extractor/src/extractor/simple.rs +++ b/shared/tree-sitter-extractor/src/extractor/simple.rs @@ -123,7 +123,7 @@ impl Extractor { let mut diagnostics_writer = diagnostics.logger(); let path = PathBuf::from(line).canonicalize()?; let src_archive_file = - crate::file_paths::path_for(&self.source_archive_dir, &path, ""); + crate::file_paths::path_for(&self.source_archive_dir, &path, "", None); let source = std::fs::read(&path)?; let mut trap_writer = trap::Writer::new(); @@ -152,6 +152,7 @@ impl Extractor { &schemas[i], &mut diagnostics_writer, &mut trap_writer, + None, &path, &source, &[], @@ -183,7 +184,7 @@ fn write_trap( trap_writer: &trap::Writer, trap_compression: trap::Compression, ) -> std::io::Result<()> { - let trap_file = crate::file_paths::path_for(trap_dir, path, trap_compression.extension()); + let trap_file = crate::file_paths::path_for(trap_dir, path, trap_compression.extension(), None); std::fs::create_dir_all(trap_file.parent().unwrap())?; trap_writer.write_to_file(&trap_file, trap_compression) } diff --git a/shared/tree-sitter-extractor/src/file_paths.rs b/shared/tree-sitter-extractor/src/file_paths.rs index 917a2fb63227..7f799f1164af 100644 --- a/shared/tree-sitter-extractor/src/file_paths.rs +++ b/shared/tree-sitter-extractor/src/file_paths.rs @@ -1,8 +1,81 @@ -use std::path::{Path, PathBuf}; +use std::{ + fs, + path::{Path, PathBuf}, +}; -/// Normalizes the path according the common CodeQL specification. Assumes that -/// `path` has already been canonicalized using `std::fs::canonicalize`. -pub fn normalize_path(path: &Path) -> String { +/// This represents the minimum supported path transofmration that is needed to support extracting +/// overlay databases. Specifically, it represents a transformer where one path prefix is replaced +/// with a different prefix. +pub struct PathTransformer { + pub original: String, + pub replacement: String, +} + +/// Normalizes the path according to the common CodeQL specification, and, applies the given path +/// transformer, if any. Assumes that `path` has already been canonicalized using +/// `std::fs::canonicalize`. +pub fn normalize_and_transform_path(path: &Path, transformer: Option<&PathTransformer>) -> String { + let path = normalize_path(path); + match transformer { + Some(transformer) => match path.strip_prefix(&transformer.original) { + Some(suffix) => format!("{}{}", transformer.replacement, suffix), + None => path, + }, + None => path, + } +} + +/** + * Attempts to load a path transformer. + * + * If the `CODEQL_PATH_TRANSFORMER` environment variable is not set, no transformer has been + * specified and the function returns `Ok(None)`. + * + * If the environment variable is set, the function attempts to load the transformer from the file + * at the * specified path. If this is successful, it returns `Ok(Some(PathTransformer))`. + * + * If the file cannot be read, or if it does not match the minimal subset of the path-transformer + * syntax supported by this extractor, the function returns an error. + */ +pub fn load_path_transformer() -> std::io::Result> { + let path = match std::env::var("CODEQL_PATH_TRANSFORMER") { + Ok(p) => p, + Err(_) => return Ok(None), + }; + let file_content = fs::read_to_string(path)?; + let lines = file_content + .lines() + .map(|line| line.trim().to_owned()) + .filter(|line| !line.is_empty()) + .collect::>(); + + if lines.len() != 2 { + return Err(unsupported_transformer_error()); + } + let replacement = lines[0] + .strip_prefix('#') + .ok_or(unsupported_transformer_error())?; + let original = lines[1] + .strip_suffix("//") + .ok_or(unsupported_transformer_error())?; + + Ok(Some(PathTransformer { + original: original.to_owned(), + replacement: replacement.to_owned(), + })) +} + +fn unsupported_transformer_error() -> std::io::Error { + std::io::Error::new( + std::io::ErrorKind::InvalidData, + "This extractor only supports path transformers specifying a single path-prefix rewrite, \ + with the first line starting with a # and the second line ending with //.", + ) +} + +/// Normalizes the path according to the common CodeQL specification. Assumes that `path` has +/// already been canonicalized using `std::fs::canonicalize`. +fn normalize_path(path: &Path) -> String { if cfg!(windows) { // The way Rust canonicalizes paths doesn't match the CodeQL spec, so we // have to do a bit of work removing certain prefixes and replacing @@ -93,7 +166,18 @@ pub fn path_from_string(path: &str) -> PathBuf { result } -pub fn path_for(dir: &Path, path: &Path, ext: &str) -> PathBuf { +pub fn path_for( + dir: &Path, + path: &Path, + ext: &str, + transformer: Option<&PathTransformer>, +) -> PathBuf { + let path = if transformer.is_some() { + let transformed = normalize_and_transform_path(path, transformer); + PathBuf::from(transformed) + } else { + path.to_path_buf() + }; let mut result = PathBuf::from(dir); for component in path.components() { match component {