mirror of
https://github.com/github/codeql.git
synced 2026-04-28 02:05:14 +02:00
Merge pull request #238 from github/aibaars/extract-erb
Extract ERB tags
This commit is contained in:
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -47,7 +47,7 @@ jobs:
|
||||
run: cargo build --release
|
||||
- name: Generate dbscheme
|
||||
if: ${{ matrix.os == 'ubuntu-latest' }}
|
||||
run: target/release/ruby-generator
|
||||
run: target/release/ruby-generator --dbscheme ql/src/ruby.dbscheme --library ql/src/codeql_ruby/ast/internal/TreeSitter.qll
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: ${{ matrix.os == 'ubuntu-latest' }}
|
||||
with:
|
||||
|
||||
2
.github/workflows/dataset_measure.yml
vendored
2
.github/workflows/dataset_measure.yml
vendored
@@ -73,7 +73,7 @@ jobs:
|
||||
path: stats
|
||||
- run: |
|
||||
python -m pip install --user lxml
|
||||
find stats -name 'stats.xml' | sort | xargs python scripts/merge_stats.py --output ql/src/ruby.dbscheme.stats --normalise tokeninfo
|
||||
find stats -name 'stats.xml' | sort | xargs python scripts/merge_stats.py --output ql/src/ruby.dbscheme.stats --normalise ruby_tokeninfo
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ruby.dbscheme.stats
|
||||
|
||||
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -396,9 +396,11 @@ dependencies = [
|
||||
name = "ruby-generator"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"node-types",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"tree-sitter-embedded-template",
|
||||
"tree-sitter-ruby",
|
||||
]
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ The generated `ql/src/ruby.dbscheme` and `ql/src/codeql_ruby/ast/internal/TreeSi
|
||||
|
||||
```bash
|
||||
# Run the generator
|
||||
cargo run --release -p ruby-generator
|
||||
cargo run --release -p ruby-generator -- --dbscheme ql/src/ruby.dbscheme --library ql/src/codeql_ruby/ast/internal/TreeSitter.qll
|
||||
# Then auto-format the QL library
|
||||
codeql query format -i ql/src/codeql_ruby/ast/internal/TreeSitter.qll
|
||||
```
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
cargo build --release
|
||||
|
||||
cargo run --release -p ruby-generator
|
||||
cargo run --release -p ruby-generator -- --dbscheme ql/src/ruby.dbscheme --library ql/src/codeql_ruby/ast/internal/TreeSitter.qll
|
||||
codeql query format -i ql\src\codeql_ruby\ast\internal\TreeSitter.qll
|
||||
|
||||
rm -Recurse -Force extractor-pack
|
||||
|
||||
@@ -12,7 +12,7 @@ fi
|
||||
|
||||
cargo build --release
|
||||
|
||||
cargo run --release -p ruby-generator
|
||||
cargo run --release -p ruby-generator -- --dbscheme ql/src/ruby.dbscheme --library ql/src/codeql_ruby/ast/internal/TreeSitter.qll
|
||||
codeql query format -i ql/src/codeql_ruby/ast/internal/TreeSitter.qll
|
||||
|
||||
rm -rf extractor-pack
|
||||
|
||||
@@ -3,11 +3,13 @@ use std::borrow::Cow;
|
||||
use std::collections::BTreeMap as Map;
|
||||
use std::collections::BTreeSet as Set;
|
||||
use std::fmt;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
use tracing::{error, info, span, Level};
|
||||
use tree_sitter::{Language, Node, Parser, Range, Tree};
|
||||
|
||||
struct TrapWriter {
|
||||
pub struct TrapWriter {
|
||||
/// The accumulated trap entries
|
||||
trap_output: Vec<TrapEntry>,
|
||||
/// A counter for generating fresh labels
|
||||
@@ -16,7 +18,7 @@ struct TrapWriter {
|
||||
global_keys: std::collections::HashMap<String, Label>,
|
||||
}
|
||||
|
||||
fn new_trap_writer() -> TrapWriter {
|
||||
pub fn new_trap_writer() -> TrapWriter {
|
||||
TrapWriter {
|
||||
counter: 0,
|
||||
trap_output: Vec::new(),
|
||||
@@ -147,16 +149,22 @@ impl TrapWriter {
|
||||
fn comment(&mut self, text: String) {
|
||||
self.trap_output.push(TrapEntry::Comment(text));
|
||||
}
|
||||
|
||||
pub fn output(self, writer: &mut dyn Write) -> std::io::Result<()> {
|
||||
write!(writer, "{}", Program(self.trap_output))
|
||||
}
|
||||
}
|
||||
|
||||
/// Extracts the source file at `path`, which is assumed to be canonicalized.
|
||||
pub fn extract(
|
||||
language: Language,
|
||||
language_prefix: &str,
|
||||
schema: &NodeTypeMap,
|
||||
trap_writer: &mut TrapWriter,
|
||||
path: &Path,
|
||||
source: &Vec<u8>,
|
||||
ranges: &[Range],
|
||||
) -> std::io::Result<Program> {
|
||||
) -> std::io::Result<()> {
|
||||
let span = span!(
|
||||
Level::TRACE,
|
||||
"extract",
|
||||
@@ -171,8 +179,7 @@ pub fn extract(
|
||||
parser.set_language(language).unwrap();
|
||||
parser.set_included_ranges(&ranges).unwrap();
|
||||
let tree = parser.parse(&source, None).expect("Failed to parse file");
|
||||
let mut trap_writer = new_trap_writer();
|
||||
trap_writer.comment(format!("Auto-generated TRAP file for {}", path.display()));
|
||||
&trap_writer.comment(format!("Auto-generated TRAP file for {}", path.display()));
|
||||
let file_label = &trap_writer.populate_file(path);
|
||||
let mut visitor = Visitor {
|
||||
source: &source,
|
||||
@@ -183,12 +190,13 @@ pub fn extract(
|
||||
token_counter: 0,
|
||||
toplevel_child_counter: 0,
|
||||
stack: Vec::new(),
|
||||
language_prefix,
|
||||
schema,
|
||||
};
|
||||
traverse(&tree, &mut visitor);
|
||||
|
||||
parser.reset();
|
||||
Ok(Program(visitor.trap_writer.trap_output))
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Escapes a string for use in a TRAP key, by replacing special characters with
|
||||
@@ -288,11 +296,13 @@ struct Visitor<'a> {
|
||||
/// The source code as a UTF-8 byte array
|
||||
source: &'a Vec<u8>,
|
||||
/// A TrapWriter to accumulate trap entries
|
||||
trap_writer: TrapWriter,
|
||||
trap_writer: &'a mut TrapWriter,
|
||||
/// A counter for tokens
|
||||
token_counter: usize,
|
||||
/// A counter for top-level child nodes
|
||||
toplevel_child_counter: usize,
|
||||
/// Language prefix
|
||||
language_prefix: &'a str,
|
||||
/// A lookup table from type name to node types
|
||||
schema: &'a NodeTypeMap,
|
||||
/// A stack for gathering information from child nodes. Whenever a node is
|
||||
@@ -400,7 +410,7 @@ impl Visitor<'_> {
|
||||
match &table.kind {
|
||||
EntryKind::Token { kind_id, .. } => {
|
||||
self.trap_writer.add_tuple(
|
||||
"ast_node_parent",
|
||||
&format!("{}_ast_node_parent", self.language_prefix),
|
||||
vec![
|
||||
Arg::Label(id),
|
||||
Arg::Label(parent_id),
|
||||
@@ -408,7 +418,7 @@ impl Visitor<'_> {
|
||||
],
|
||||
);
|
||||
self.trap_writer.add_tuple(
|
||||
"tokeninfo",
|
||||
&format!("{}_tokeninfo", self.language_prefix),
|
||||
vec![
|
||||
Arg::Label(id),
|
||||
Arg::Int(*kind_id),
|
||||
@@ -426,7 +436,7 @@ impl Visitor<'_> {
|
||||
} => {
|
||||
if let Some(args) = self.complex_node(&node, fields, &child_nodes, id) {
|
||||
self.trap_writer.add_tuple(
|
||||
"ast_node_parent",
|
||||
&format!("{}_ast_node_parent", self.language_prefix),
|
||||
vec![
|
||||
Arg::Label(id),
|
||||
Arg::Label(parent_id),
|
||||
|
||||
@@ -6,7 +6,7 @@ use clap;
|
||||
use flate2::write::GzEncoder;
|
||||
use rayon::prelude::*;
|
||||
use std::fs;
|
||||
use std::io::{BufRead, BufWriter, Write};
|
||||
use std::io::{BufRead, BufWriter};
|
||||
use std::path::{Path, PathBuf};
|
||||
use tree_sitter::{Language, Parser, Range};
|
||||
|
||||
@@ -124,7 +124,9 @@ fn main() -> std::io::Result<()> {
|
||||
|
||||
let language = tree_sitter_ruby::language();
|
||||
let erb = tree_sitter_embedded_template::language();
|
||||
let schema = node_types::read_node_types_str(tree_sitter_ruby::NODE_TYPES)?;
|
||||
let schema = node_types::read_node_types_str("ruby", tree_sitter_ruby::NODE_TYPES)?;
|
||||
let erb_schema =
|
||||
node_types::read_node_types_str("erb", tree_sitter_embedded_template::NODE_TYPES)?;
|
||||
let lines: std::io::Result<Vec<String>> = std::io::BufReader::new(file_list).lines().collect();
|
||||
let lines = lines?;
|
||||
lines.par_iter().try_for_each(|line| {
|
||||
@@ -133,8 +135,19 @@ fn main() -> std::io::Result<()> {
|
||||
let src_archive_file = path_for(&src_archive_dir, &path, "");
|
||||
let mut source = std::fs::read(&path)?;
|
||||
let code_ranges;
|
||||
let mut trap_writer = extractor::new_trap_writer();
|
||||
if path.extension().map_or(false, |x| x == "erb") {
|
||||
tracing::info!("scanning: {}", path.display());
|
||||
extractor::extract(
|
||||
erb,
|
||||
"erb",
|
||||
&erb_schema,
|
||||
&mut trap_writer,
|
||||
&path,
|
||||
&source,
|
||||
&[],
|
||||
)?;
|
||||
|
||||
let (ranges, line_breaks) = scan_erb(erb, &source);
|
||||
for i in line_breaks {
|
||||
if i < source.len() {
|
||||
@@ -145,17 +158,25 @@ fn main() -> std::io::Result<()> {
|
||||
} else {
|
||||
code_ranges = vec![];
|
||||
}
|
||||
let trap = extractor::extract(language, &schema, &path, &source, &code_ranges)?;
|
||||
extractor::extract(
|
||||
language,
|
||||
"ruby",
|
||||
&schema,
|
||||
&mut trap_writer,
|
||||
&path,
|
||||
&source,
|
||||
&code_ranges,
|
||||
)?;
|
||||
std::fs::create_dir_all(&src_archive_file.parent().unwrap())?;
|
||||
std::fs::copy(&path, &src_archive_file)?;
|
||||
std::fs::create_dir_all(&trap_file.parent().unwrap())?;
|
||||
let trap_file = std::fs::File::create(&trap_file)?;
|
||||
let mut trap_file = BufWriter::new(trap_file);
|
||||
match trap_compression {
|
||||
TrapCompression::None => write!(trap_file, "{}", trap),
|
||||
TrapCompression::None => trap_writer.output(&mut trap_file),
|
||||
TrapCompression::Gzip => {
|
||||
let mut compressed_writer = GzEncoder::new(trap_file, flate2::Compression::fast());
|
||||
write!(compressed_writer, "{}", trap)
|
||||
trap_writer.output(&mut compressed_writer)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -7,7 +7,9 @@ edition = "2018"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
clap = "2.33"
|
||||
node-types = { path = "../node-types" }
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = { version = "0.2", features = ["env-filter"] }
|
||||
tree-sitter-embedded-template = { git = "https://github.com/tree-sitter/tree-sitter-embedded-template", rev = "d4aac29c08aa7c596633d00b5ec2dd2d247eafe4" }
|
||||
tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "32cd5a04adb4accb0c121f037ab59df3c3488228" }
|
||||
|
||||
@@ -117,17 +117,7 @@ impl<'a> fmt::Display for Union<'a> {
|
||||
}
|
||||
|
||||
/// Generates the dbscheme by writing the given dbscheme `entries` to the `file`.
|
||||
pub fn write<'a>(
|
||||
language_name: &str,
|
||||
file: &mut dyn std::io::Write,
|
||||
entries: &'a [Entry],
|
||||
) -> std::io::Result<()> {
|
||||
write!(file, "// CodeQL database schema for {}\n", language_name)?;
|
||||
write!(
|
||||
file,
|
||||
"// Automatically generated from the tree-sitter grammar; do not edit\n\n"
|
||||
)?;
|
||||
|
||||
pub fn write<'a>(file: &mut dyn std::io::Write, entries: &'a [Entry]) -> std::io::Result<()> {
|
||||
for entry in entries {
|
||||
match entry {
|
||||
Entry::Case(case) => write!(file, "{}\n\n", case)?,
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub struct Language {
|
||||
pub name: String,
|
||||
pub node_types: &'static str,
|
||||
pub dbscheme_path: PathBuf,
|
||||
pub ql_library_path: PathBuf,
|
||||
}
|
||||
|
||||
@@ -3,13 +3,14 @@ mod language;
|
||||
mod ql;
|
||||
mod ql_gen;
|
||||
|
||||
use clap;
|
||||
use language::Language;
|
||||
use std::collections::BTreeMap as Map;
|
||||
use std::collections::BTreeSet as Set;
|
||||
use std::fs::File;
|
||||
use std::io::LineWriter;
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
use tracing::{error, info};
|
||||
|
||||
/// Given the name of the parent node, and its field information, returns a pair,
|
||||
/// the first of which is the field's type. The second is an optional dbscheme
|
||||
@@ -135,18 +136,16 @@ fn add_field_for_column_storage<'a>(
|
||||
}
|
||||
|
||||
/// Converts the given tree-sitter node types into CodeQL dbscheme entries.
|
||||
fn convert_nodes<'a>(nodes: &'a node_types::NodeTypeMap) -> Vec<dbscheme::Entry<'a>> {
|
||||
let mut entries: Vec<dbscheme::Entry> = vec![
|
||||
create_location_union(),
|
||||
create_locations_default_table(),
|
||||
create_sourceline_union(),
|
||||
create_numlines_table(),
|
||||
create_files_table(),
|
||||
create_folders_table(),
|
||||
create_container_union(),
|
||||
create_containerparent_table(),
|
||||
create_source_location_prefix_table(),
|
||||
];
|
||||
/// Returns a tuple containing:
|
||||
///
|
||||
/// 1. A vector of dbscheme entries.
|
||||
/// 2. A set of names of the members of the `<lang>_ast_node` union.
|
||||
/// 3. A map where the keys are the dbscheme names for token kinds, and the
|
||||
/// values are their integer representations.
|
||||
fn convert_nodes<'a>(
|
||||
nodes: &'a node_types::NodeTypeMap,
|
||||
) -> (Vec<dbscheme::Entry<'a>>, Set<&'a str>, Map<&'a str, usize>) {
|
||||
let mut entries: Vec<dbscheme::Entry> = Vec::new();
|
||||
let mut ast_node_members: Set<&str> = Set::new();
|
||||
let token_kinds: Map<&str, usize> = nodes
|
||||
.iter()
|
||||
@@ -157,7 +156,6 @@ fn convert_nodes<'a>(nodes: &'a node_types::NodeTypeMap) -> Vec<dbscheme::Entry<
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
ast_node_members.insert("token");
|
||||
for (_, node) in nodes {
|
||||
match &node.kind {
|
||||
node_types::EntryKind::Union { members: n_members } => {
|
||||
@@ -250,48 +248,30 @@ fn convert_nodes<'a>(nodes: &'a node_types::NodeTypeMap) -> Vec<dbscheme::Entry<
|
||||
}
|
||||
}
|
||||
|
||||
// Add the tokeninfo table
|
||||
let (token_case, token_table) = create_tokeninfo(token_kinds);
|
||||
entries.push(dbscheme::Entry::Table(token_table));
|
||||
entries.push(dbscheme::Entry::Case(token_case));
|
||||
|
||||
// Add the diagnostics table
|
||||
let (diagnostics_case, diagnostics_table) = create_diagnostics();
|
||||
entries.push(dbscheme::Entry::Table(diagnostics_table));
|
||||
entries.push(dbscheme::Entry::Case(diagnostics_case));
|
||||
|
||||
// Create a union of all database types.
|
||||
entries.push(dbscheme::Entry::Union(dbscheme::Union {
|
||||
name: "ast_node",
|
||||
members: ast_node_members,
|
||||
}));
|
||||
|
||||
// Create the ast_node_parent union.
|
||||
entries.push(dbscheme::Entry::Union(dbscheme::Union {
|
||||
name: "ast_node_parent",
|
||||
members: ["ast_node", "file"].iter().cloned().collect(),
|
||||
}));
|
||||
|
||||
entries.push(dbscheme::Entry::Table(create_ast_node_parent_table()));
|
||||
|
||||
entries
|
||||
(entries, ast_node_members, token_kinds)
|
||||
}
|
||||
fn create_ast_node_parent_table<'a>() -> dbscheme::Table<'a> {
|
||||
|
||||
/// Creates a dbscheme table entry representing the parent relation for AST nodes.
|
||||
///
|
||||
/// # Arguments
|
||||
/// - `name` - the name of both the table to create and the node parent type.
|
||||
/// - `ast_node_name` - the name of the node child type.
|
||||
fn create_ast_node_parent_table<'a>(name: &'a str, ast_node_name: &'a str) -> dbscheme::Table<'a> {
|
||||
dbscheme::Table {
|
||||
name: "ast_node_parent",
|
||||
name,
|
||||
columns: vec![
|
||||
dbscheme::Column {
|
||||
db_type: dbscheme::DbColumnType::Int,
|
||||
name: "child",
|
||||
unique: false,
|
||||
ql_type: ql::Type::AtType("ast_node"),
|
||||
ql_type: ql::Type::AtType(ast_node_name),
|
||||
ql_type_is_ref: true,
|
||||
},
|
||||
dbscheme::Column {
|
||||
db_type: dbscheme::DbColumnType::Int,
|
||||
name: "parent",
|
||||
unique: false,
|
||||
ql_type: ql::Type::AtType("ast_node_parent"),
|
||||
ql_type: ql::Type::AtType(name),
|
||||
ql_type_is_ref: true,
|
||||
},
|
||||
dbscheme::Column {
|
||||
@@ -306,18 +286,16 @@ fn create_ast_node_parent_table<'a>() -> dbscheme::Table<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn create_tokeninfo<'a>(
|
||||
token_kinds: Map<&'a str, usize>,
|
||||
) -> (dbscheme::Case<'a>, dbscheme::Table<'a>) {
|
||||
let table = dbscheme::Table {
|
||||
name: "tokeninfo",
|
||||
fn create_tokeninfo<'a>(name: &'a str, type_name: &'a str) -> dbscheme::Table<'a> {
|
||||
dbscheme::Table {
|
||||
name,
|
||||
keysets: None,
|
||||
columns: vec![
|
||||
dbscheme::Column {
|
||||
db_type: dbscheme::DbColumnType::Int,
|
||||
name: "id",
|
||||
unique: true,
|
||||
ql_type: ql::Type::AtType("token"),
|
||||
ql_type: ql::Type::AtType(type_name),
|
||||
ql_type_is_ref: false,
|
||||
},
|
||||
dbscheme::Column {
|
||||
@@ -356,31 +334,19 @@ fn create_tokeninfo<'a>(
|
||||
ql_type_is_ref: true,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn create_token_case<'a>(name: &'a str, token_kinds: Map<&'a str, usize>) -> dbscheme::Case<'a> {
|
||||
let branches: Vec<(usize, &str)> = token_kinds
|
||||
.iter()
|
||||
.map(|(&name, kind_id)| (*kind_id, name))
|
||||
.collect();
|
||||
let case = dbscheme::Case {
|
||||
name: "token",
|
||||
dbscheme::Case {
|
||||
name: name,
|
||||
column: "kind",
|
||||
branches: branches,
|
||||
};
|
||||
(case, table)
|
||||
}
|
||||
|
||||
fn write_dbscheme(language: &Language, entries: &[dbscheme::Entry]) -> std::io::Result<()> {
|
||||
info!(
|
||||
"Writing database schema for {} to '{}'",
|
||||
&language.name,
|
||||
match language.dbscheme_path.to_str() {
|
||||
None => "<undisplayable>",
|
||||
Some(p) => p,
|
||||
}
|
||||
);
|
||||
let file = File::create(&language.dbscheme_path)?;
|
||||
let mut file = LineWriter::new(file);
|
||||
dbscheme::write(&language.name, &mut file, &entries)
|
||||
}
|
||||
}
|
||||
|
||||
fn create_location_union<'a>() -> dbscheme::Entry<'a> {
|
||||
@@ -665,7 +631,7 @@ fn create_diagnostics<'a>() -> (dbscheme::Case<'a>, dbscheme::Table<'a>) {
|
||||
(case, table)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
fn main() -> std::io::Result<()> {
|
||||
tracing_subscriber::fmt()
|
||||
.with_target(false)
|
||||
.without_time()
|
||||
@@ -673,33 +639,122 @@ fn main() {
|
||||
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
|
||||
.init();
|
||||
|
||||
// TODO: figure out proper dbscheme output path and/or take it from the
|
||||
// command line.
|
||||
let ruby = Language {
|
||||
name: "Ruby".to_owned(),
|
||||
node_types: tree_sitter_ruby::NODE_TYPES,
|
||||
dbscheme_path: PathBuf::from("ql/src/ruby.dbscheme"),
|
||||
ql_library_path: PathBuf::from("ql/src/codeql_ruby/ast/internal/TreeSitter.qll"),
|
||||
};
|
||||
match node_types::read_node_types_str(&ruby.node_types) {
|
||||
Err(e) => {
|
||||
error!("Failed to read node-types JSON for {}: {}", ruby.name, e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
Ok(nodes) => {
|
||||
let dbscheme_entries = convert_nodes(&nodes);
|
||||
let matches = clap::App::new("Ruby dbscheme generator")
|
||||
.version("1.0")
|
||||
.author("GitHub")
|
||||
.about("CodeQL Ruby dbscheme generator")
|
||||
.args_from_usage(
|
||||
"--dbscheme=<FILE> 'Path of the generated dbscheme file'
|
||||
--library=<FILE> 'Path of the generated QLL file'",
|
||||
)
|
||||
.get_matches();
|
||||
let dbscheme_path = matches.value_of("dbscheme").expect("missing --dbscheme");
|
||||
let dbscheme_path = PathBuf::from(dbscheme_path);
|
||||
|
||||
if let Err(e) = write_dbscheme(&ruby, &dbscheme_entries) {
|
||||
error!("Failed to write dbscheme: {}", e);
|
||||
std::process::exit(2);
|
||||
}
|
||||
let ql_library_path = matches.value_of("library").expect("missing --library");
|
||||
let ql_library_path = PathBuf::from(ql_library_path);
|
||||
|
||||
let classes = ql_gen::convert_nodes(&nodes);
|
||||
let languages = vec![
|
||||
Language {
|
||||
name: "Ruby".to_owned(),
|
||||
node_types: tree_sitter_ruby::NODE_TYPES,
|
||||
},
|
||||
Language {
|
||||
name: "Erb".to_owned(),
|
||||
node_types: tree_sitter_embedded_template::NODE_TYPES,
|
||||
},
|
||||
];
|
||||
let mut dbscheme_writer = LineWriter::new(File::create(dbscheme_path)?);
|
||||
write!(
|
||||
dbscheme_writer,
|
||||
"// CodeQL database schema for {}\n\
|
||||
// Automatically generated from the tree-sitter grammar; do not edit\n\n",
|
||||
languages[0].name
|
||||
)?;
|
||||
let (diagnostics_case, diagnostics_table) = create_diagnostics();
|
||||
dbscheme::write(
|
||||
&mut dbscheme_writer,
|
||||
&[
|
||||
create_location_union(),
|
||||
create_locations_default_table(),
|
||||
create_sourceline_union(),
|
||||
create_numlines_table(),
|
||||
create_files_table(),
|
||||
create_folders_table(),
|
||||
create_container_union(),
|
||||
create_containerparent_table(),
|
||||
create_source_location_prefix_table(),
|
||||
dbscheme::Entry::Table(diagnostics_table),
|
||||
dbscheme::Entry::Case(diagnostics_case),
|
||||
],
|
||||
)?;
|
||||
|
||||
if let Err(e) = ql_gen::write(&ruby, &classes) {
|
||||
println!("Failed to write QL library: {}", e);
|
||||
std::process::exit(3);
|
||||
}
|
||||
}
|
||||
let mut ql_writer = LineWriter::new(File::create(ql_library_path)?);
|
||||
write!(
|
||||
ql_writer,
|
||||
"/*\n\
|
||||
* CodeQL library for {}
|
||||
* Automatically generated from the tree-sitter grammar; do not edit\n\
|
||||
*/\n\n",
|
||||
languages[0].name
|
||||
)?;
|
||||
ql::write(
|
||||
&mut ql_writer,
|
||||
&[
|
||||
ql::TopLevel::Import("codeql.files.FileSystem"),
|
||||
ql::TopLevel::Import("codeql.Locations"),
|
||||
],
|
||||
)?;
|
||||
|
||||
for language in languages {
|
||||
let prefix = node_types::to_snake_case(&language.name);
|
||||
let ast_node_name = format!("{}_ast_node", &prefix);
|
||||
let ast_node_parent_name = format!("{}_ast_node_parent", &prefix);
|
||||
let token_name = format!("{}_token", &prefix);
|
||||
let tokeninfo_name = format!("{}_tokeninfo", &prefix);
|
||||
let reserved_word_name = format!("{}_reserved_word", &prefix);
|
||||
let nodes = node_types::read_node_types_str(&prefix, &language.node_types)?;
|
||||
let (dbscheme_entries, mut ast_node_members, token_kinds) = convert_nodes(&nodes);
|
||||
ast_node_members.insert(&token_name);
|
||||
dbscheme::write(&mut dbscheme_writer, &dbscheme_entries)?;
|
||||
let token_case = create_token_case(&token_name, token_kinds);
|
||||
dbscheme::write(
|
||||
&mut dbscheme_writer,
|
||||
&[
|
||||
dbscheme::Entry::Table(create_tokeninfo(&tokeninfo_name, &token_name)),
|
||||
dbscheme::Entry::Case(token_case),
|
||||
dbscheme::Entry::Union(dbscheme::Union {
|
||||
name: &ast_node_name,
|
||||
members: ast_node_members,
|
||||
}),
|
||||
dbscheme::Entry::Union(dbscheme::Union {
|
||||
name: &ast_node_parent_name,
|
||||
members: [&ast_node_name, "file"].iter().cloned().collect(),
|
||||
}),
|
||||
dbscheme::Entry::Table(create_ast_node_parent_table(
|
||||
&ast_node_parent_name,
|
||||
&ast_node_name,
|
||||
)),
|
||||
],
|
||||
)?;
|
||||
|
||||
let mut body = vec![
|
||||
ql::TopLevel::Class(ql_gen::create_ast_node_class(
|
||||
&ast_node_name,
|
||||
&ast_node_parent_name,
|
||||
)),
|
||||
ql::TopLevel::Class(ql_gen::create_token_class(&token_name, &tokeninfo_name)),
|
||||
ql::TopLevel::Class(ql_gen::create_reserved_word_class(&reserved_word_name)),
|
||||
];
|
||||
body.append(&mut ql_gen::convert_nodes(&nodes));
|
||||
ql::write(
|
||||
&mut ql_writer,
|
||||
&[ql::TopLevel::Module(ql::Module {
|
||||
qldoc: None,
|
||||
name: &language.name,
|
||||
body,
|
||||
})],
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
use std::collections::BTreeSet;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Eq, PartialEq, Hash)]
|
||||
pub enum TopLevel<'a> {
|
||||
Class(Class<'a>),
|
||||
Import(&'a str),
|
||||
Module(Module<'a>),
|
||||
}
|
||||
|
||||
impl<'a> fmt::Display for TopLevel<'a> {
|
||||
@@ -11,6 +13,7 @@ impl<'a> fmt::Display for TopLevel<'a> {
|
||||
match self {
|
||||
TopLevel::Import(x) => write!(f, "private import {}", x),
|
||||
TopLevel::Class(cls) => write!(f, "{}", cls),
|
||||
TopLevel::Module(m) => write!(f, "{}", m),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,6 +70,26 @@ impl<'a> fmt::Display for Class<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Eq, PartialEq, Hash)]
|
||||
pub struct Module<'a> {
|
||||
pub qldoc: Option<String>,
|
||||
pub name: &'a str,
|
||||
pub body: Vec<TopLevel<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> fmt::Display for Module<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if let Some(qldoc) = &self.qldoc {
|
||||
write!(f, "/** {} */", qldoc)?;
|
||||
}
|
||||
write!(f, "module {} {{ \n", self.name)?;
|
||||
for decl in &self.body {
|
||||
write!(f, " {}\n", decl)?;
|
||||
}
|
||||
write!(f, "}}")?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
// The QL type of a column.
|
||||
#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
|
||||
pub enum Type<'a> {
|
||||
@@ -226,25 +249,10 @@ impl<'a> fmt::Display for FormalParameter<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates a QL library by writing the given `classes` to the `file`.
|
||||
pub fn write<'a>(
|
||||
language_name: &str,
|
||||
file: &mut dyn std::io::Write,
|
||||
elements: &'a [TopLevel],
|
||||
) -> std::io::Result<()> {
|
||||
write!(file, "/*\n")?;
|
||||
write!(file, " * CodeQL library for {}\n", language_name)?;
|
||||
write!(
|
||||
file,
|
||||
" * Automatically generated from the tree-sitter grammar; do not edit\n"
|
||||
)?;
|
||||
write!(file, " */\n\n")?;
|
||||
write!(file, "module Generated {{\n")?;
|
||||
|
||||
/// Generates a QL library by writing the given `elements` to the `file`.
|
||||
pub fn write<'a>(file: &mut dyn std::io::Write, elements: &'a [TopLevel]) -> std::io::Result<()> {
|
||||
for element in elements {
|
||||
write!(file, "{}\n\n", &element)?;
|
||||
}
|
||||
|
||||
write!(file, "}}")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,32 +1,9 @@
|
||||
use crate::language::Language;
|
||||
use crate::ql;
|
||||
use std::collections::BTreeSet;
|
||||
use std::fs::File;
|
||||
use std::io::LineWriter;
|
||||
|
||||
/// Writes the QL AST library for the given library.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// `language` - the language for which we're generating a library
|
||||
/// `classes` - the list of classes to write.
|
||||
pub fn write(language: &Language, classes: &[ql::TopLevel]) -> std::io::Result<()> {
|
||||
println!(
|
||||
"Writing QL library for {} to '{}'",
|
||||
&language.name,
|
||||
match language.ql_library_path.to_str() {
|
||||
None => "<undisplayable>",
|
||||
Some(p) => p,
|
||||
}
|
||||
);
|
||||
let file = File::create(&language.ql_library_path)?;
|
||||
let mut file = LineWriter::new(file);
|
||||
ql::write(&language.name, &mut file, &classes)
|
||||
}
|
||||
|
||||
/// Creates the hard-coded `AstNode` class that acts as a supertype of all
|
||||
/// classes we generate.
|
||||
fn create_ast_node_class<'a>() -> ql::Class<'a> {
|
||||
pub fn create_ast_node_class<'a>(ast_node: &'a str, ast_node_parent: &'a str) -> ql::Class<'a> {
|
||||
// Default implementation of `toString` calls `this.getAPrimaryQlClass()`
|
||||
let to_string = ql::Predicate {
|
||||
qldoc: Some(String::from(
|
||||
@@ -64,7 +41,7 @@ fn create_ast_node_class<'a>() -> ql::Class<'a> {
|
||||
return_type: Some(ql::Type::Normal("AstNode")),
|
||||
formal_parameters: vec![],
|
||||
body: ql::Expression::Pred(
|
||||
"ast_node_parent",
|
||||
ast_node_parent,
|
||||
vec![
|
||||
ql::Expression::Var("this"),
|
||||
ql::Expression::Var("result"),
|
||||
@@ -81,7 +58,7 @@ fn create_ast_node_class<'a>() -> ql::Class<'a> {
|
||||
return_type: Some(ql::Type::Int),
|
||||
formal_parameters: vec![],
|
||||
body: ql::Expression::Pred(
|
||||
"ast_node_parent",
|
||||
ast_node_parent,
|
||||
vec![
|
||||
ql::Expression::Var("this"),
|
||||
ql::Expression::Var("_"),
|
||||
@@ -106,7 +83,7 @@ fn create_ast_node_class<'a>() -> ql::Class<'a> {
|
||||
qldoc: Some(String::from("The base class for all AST nodes")),
|
||||
name: "AstNode",
|
||||
is_abstract: false,
|
||||
supertypes: vec![ql::Type::AtType("ast_node")].into_iter().collect(),
|
||||
supertypes: vec![ql::Type::AtType(ast_node)].into_iter().collect(),
|
||||
characteristic_predicate: None,
|
||||
predicates: vec![
|
||||
to_string,
|
||||
@@ -119,7 +96,7 @@ fn create_ast_node_class<'a>() -> ql::Class<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn create_token_class<'a>() -> ql::Class<'a> {
|
||||
pub fn create_token_class<'a>(token_type: &'a str, tokeninfo: &'a str) -> ql::Class<'a> {
|
||||
let tokeninfo_arity = 6;
|
||||
let get_value = ql::Predicate {
|
||||
qldoc: Some(String::from("Gets the value of this token.")),
|
||||
@@ -127,7 +104,7 @@ fn create_token_class<'a>() -> ql::Class<'a> {
|
||||
overridden: false,
|
||||
return_type: Some(ql::Type::String),
|
||||
formal_parameters: vec![],
|
||||
body: create_get_field_expr_for_column_storage("result", "tokeninfo", 3, tokeninfo_arity),
|
||||
body: create_get_field_expr_for_column_storage("result", tokeninfo, 3, tokeninfo_arity),
|
||||
};
|
||||
let get_location = ql::Predicate {
|
||||
qldoc: Some(String::from("Gets the location of this token.")),
|
||||
@@ -135,7 +112,7 @@ fn create_token_class<'a>() -> ql::Class<'a> {
|
||||
overridden: true,
|
||||
return_type: Some(ql::Type::Normal("Location")),
|
||||
formal_parameters: vec![],
|
||||
body: create_get_field_expr_for_column_storage("result", "tokeninfo", 4, tokeninfo_arity),
|
||||
body: create_get_field_expr_for_column_storage("result", tokeninfo, 4, tokeninfo_arity),
|
||||
};
|
||||
let to_string = ql::Predicate {
|
||||
qldoc: Some(String::from(
|
||||
@@ -154,7 +131,7 @@ fn create_token_class<'a>() -> ql::Class<'a> {
|
||||
qldoc: Some(String::from("A token.")),
|
||||
name: "Token",
|
||||
is_abstract: false,
|
||||
supertypes: vec![ql::Type::AtType("token"), ql::Type::Normal("AstNode")]
|
||||
supertypes: vec![ql::Type::AtType(token_type), ql::Type::Normal("AstNode")]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
characteristic_predicate: None,
|
||||
@@ -168,8 +145,7 @@ fn create_token_class<'a>() -> ql::Class<'a> {
|
||||
}
|
||||
|
||||
// Creates the `ReservedWord` class.
|
||||
fn create_reserved_word_class<'a>() -> ql::Class<'a> {
|
||||
let db_name = "reserved_word";
|
||||
pub fn create_reserved_word_class<'a>(db_name: &'a str) -> ql::Class<'a> {
|
||||
let class_name = "ReservedWord";
|
||||
let get_a_primary_ql_class = create_get_a_primary_ql_class(&class_name);
|
||||
ql::Class {
|
||||
@@ -452,9 +428,7 @@ fn create_field_getters<'a>(
|
||||
}
|
||||
};
|
||||
let qldoc = match &field.name {
|
||||
Some(name) => {
|
||||
format!("Gets the node corresponding to the field `{}`.", name)
|
||||
}
|
||||
Some(name) => format!("Gets the node corresponding to the field `{}`.", name),
|
||||
None => {
|
||||
if formal_parameters.len() == 0 {
|
||||
"Gets the child of this node.".to_owned()
|
||||
@@ -478,13 +452,7 @@ fn create_field_getters<'a>(
|
||||
|
||||
/// Converts the given node types into CodeQL classes wrapping the dbscheme.
|
||||
pub fn convert_nodes<'a>(nodes: &'a node_types::NodeTypeMap) -> Vec<ql::TopLevel<'a>> {
|
||||
let mut classes: Vec<ql::TopLevel> = vec![
|
||||
ql::TopLevel::Import("codeql.files.FileSystem"),
|
||||
ql::TopLevel::Import("codeql.Locations"),
|
||||
ql::TopLevel::Class(create_ast_node_class()),
|
||||
ql::TopLevel::Class(create_token_class()),
|
||||
ql::TopLevel::Class(create_reserved_word_class()),
|
||||
];
|
||||
let mut classes: Vec<ql::TopLevel> = Vec::new();
|
||||
let mut token_kinds = BTreeSet::new();
|
||||
for (type_name, node) in nodes {
|
||||
if let node_types::EntryKind::Token { .. } = &node.kind {
|
||||
|
||||
@@ -81,15 +81,15 @@ pub enum Storage {
|
||||
},
|
||||
}
|
||||
|
||||
pub fn read_node_types(node_types_path: &Path) -> std::io::Result<NodeTypeMap> {
|
||||
pub fn read_node_types(prefix: &str, node_types_path: &Path) -> std::io::Result<NodeTypeMap> {
|
||||
let file = fs::File::open(node_types_path)?;
|
||||
let node_types = serde_json::from_reader(file)?;
|
||||
Ok(convert_nodes(&node_types))
|
||||
Ok(convert_nodes(&prefix, &node_types))
|
||||
}
|
||||
|
||||
pub fn read_node_types_str(node_types_json: &str) -> std::io::Result<NodeTypeMap> {
|
||||
pub fn read_node_types_str(prefix: &str, node_types_json: &str) -> std::io::Result<NodeTypeMap> {
|
||||
let node_types = serde_json::from_str(node_types_json)?;
|
||||
Ok(convert_nodes(&node_types))
|
||||
Ok(convert_nodes(&prefix, &node_types))
|
||||
}
|
||||
|
||||
fn convert_type(node_type: &NodeType) -> TypeName {
|
||||
@@ -104,7 +104,7 @@ fn convert_types(node_types: &Vec<NodeType>) -> Set<TypeName> {
|
||||
std::collections::BTreeSet::from(iter)
|
||||
}
|
||||
|
||||
pub fn convert_nodes(nodes: &Vec<NodeInfo>) -> NodeTypeMap {
|
||||
pub fn convert_nodes(prefix: &str, nodes: &Vec<NodeInfo>) -> NodeTypeMap {
|
||||
let mut entries = NodeTypeMap::new();
|
||||
let mut token_kinds = Set::new();
|
||||
|
||||
@@ -125,6 +125,7 @@ pub fn convert_nodes(nodes: &Vec<NodeInfo>) -> NodeTypeMap {
|
||||
let flattened_name = &node_type_name(&node.kind, node.named);
|
||||
let dbscheme_name = escape_name(&flattened_name);
|
||||
let ql_class_name = dbscheme_name_to_class_name(&dbscheme_name);
|
||||
let dbscheme_name = format!("{}_{}", prefix, &dbscheme_name);
|
||||
if let Some(subtypes) = &node.subtypes {
|
||||
// It's a tree-sitter supertype node, for which we create a union
|
||||
// type.
|
||||
@@ -150,6 +151,8 @@ pub fn convert_nodes(nodes: &Vec<NodeInfo>) -> NodeTypeMap {
|
||||
named: node.named,
|
||||
};
|
||||
let table_name = escape_name(&(format!("{}_def", &flattened_name)));
|
||||
let table_name = format!("{}_{}", prefix, &table_name);
|
||||
|
||||
let mut fields = Vec::new();
|
||||
|
||||
// If the type also has fields or children, then we create either
|
||||
@@ -157,6 +160,7 @@ pub fn convert_nodes(nodes: &Vec<NodeInfo>) -> NodeTypeMap {
|
||||
if let Some(node_fields) = &node.fields {
|
||||
for (field_name, field_info) in node_fields {
|
||||
add_field(
|
||||
&prefix,
|
||||
&type_name,
|
||||
Some(field_name.to_string()),
|
||||
field_info,
|
||||
@@ -167,7 +171,14 @@ pub fn convert_nodes(nodes: &Vec<NodeInfo>) -> NodeTypeMap {
|
||||
}
|
||||
if let Some(children) = &node.children {
|
||||
// Treat children as if they were a field called 'child'.
|
||||
add_field(&type_name, None, children, &mut fields, &token_kinds);
|
||||
add_field(
|
||||
&prefix,
|
||||
&type_name,
|
||||
None,
|
||||
children,
|
||||
&mut fields,
|
||||
&token_kinds,
|
||||
);
|
||||
}
|
||||
entries.insert(
|
||||
type_name,
|
||||
@@ -188,13 +199,13 @@ pub fn convert_nodes(nodes: &Vec<NodeInfo>) -> NodeTypeMap {
|
||||
counter += 1;
|
||||
let unprefixed_name = node_type_name(&type_name.kind, true);
|
||||
Entry {
|
||||
dbscheme_name: escape_name(&format!("token_{}", &unprefixed_name)),
|
||||
dbscheme_name: escape_name(&format!("{}_token_{}", &prefix, &unprefixed_name)),
|
||||
ql_class_name: dbscheme_name_to_class_name(&escape_name(&unprefixed_name)),
|
||||
kind: EntryKind::Token { kind_id: counter },
|
||||
}
|
||||
} else {
|
||||
Entry {
|
||||
dbscheme_name: "reserved_word".to_owned(),
|
||||
dbscheme_name: format!("{}_reserved_word", &prefix),
|
||||
ql_class_name: "ReservedWord".to_owned(),
|
||||
kind: EntryKind::Token { kind_id: 0 },
|
||||
}
|
||||
@@ -205,6 +216,7 @@ pub fn convert_nodes(nodes: &Vec<NodeInfo>) -> NodeTypeMap {
|
||||
}
|
||||
|
||||
fn add_field(
|
||||
prefix: &str,
|
||||
parent_type_name: &TypeName,
|
||||
field_name: Option<String>,
|
||||
field_info: &FieldInfo,
|
||||
@@ -221,7 +233,8 @@ fn add_field(
|
||||
// Put the field in an auxiliary table.
|
||||
let has_index = field_info.multiple;
|
||||
let field_table_name = escape_name(&format!(
|
||||
"{}_{}",
|
||||
"{}_{}_{}",
|
||||
&prefix,
|
||||
parent_flattened_name,
|
||||
&name_for_field_or_child(&field_name)
|
||||
));
|
||||
@@ -244,7 +257,7 @@ fn add_field(
|
||||
let mut field_token_ints: BTreeMap<String, (usize, String)> = BTreeMap::new();
|
||||
for t in converted_types {
|
||||
let dbscheme_variant_name =
|
||||
escape_name(&format!("{}_{}", parent_flattened_name, t.kind));
|
||||
escape_name(&format!("{}_{}_{}", &prefix, parent_flattened_name, t.kind));
|
||||
field_token_ints.insert(t.kind.to_owned(), (counter, dbscheme_variant_name));
|
||||
counter += 1;
|
||||
}
|
||||
@@ -256,7 +269,8 @@ fn add_field(
|
||||
FieldTypeInfo::Multiple {
|
||||
types: converted_types,
|
||||
dbscheme_union: format!(
|
||||
"{}_{}_type",
|
||||
"{}_{}_{}_type",
|
||||
&prefix,
|
||||
&parent_flattened_name,
|
||||
&name_for_field_or_child(&field_name)
|
||||
),
|
||||
@@ -380,6 +394,23 @@ fn escape_name(name: &str) -> String {
|
||||
result
|
||||
}
|
||||
|
||||
pub fn to_snake_case(word: &str) -> String {
|
||||
let mut prev_upper = true;
|
||||
let mut result = String::new();
|
||||
for c in word.chars() {
|
||||
if c.is_uppercase() {
|
||||
if !prev_upper {
|
||||
result.push('_')
|
||||
}
|
||||
prev_upper = true;
|
||||
result.push(c.to_ascii_lowercase());
|
||||
} else {
|
||||
prev_upper = false;
|
||||
result.push(c);
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
/// Given a valid dbscheme name (i.e. in snake case), produces the equivalent QL
|
||||
/// name (i.e. in CamelCase). For example, "foo_bar_baz" becomes "FooBarBaz".
|
||||
fn dbscheme_name_to_class_name(dbscheme_name: &str) -> String {
|
||||
@@ -402,3 +433,10 @@ fn dbscheme_name_to_class_name(dbscheme_name: &str) -> String {
|
||||
.collect::<Vec<String>>()
|
||||
.join("")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn to_snake_case_test() {
|
||||
assert_eq!("ruby", to_snake_case("Ruby"));
|
||||
assert_eq!("erb", to_snake_case("ERB"));
|
||||
assert_eq!("embedded_template", to_snake_case("EmbeddedTemplate"));
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/** Provides classes for working with files and folders. */
|
||||
|
||||
private import codeql_ruby.ast.internal.TreeSitter
|
||||
private import codeql.Locations
|
||||
|
||||
/** A file or folder. */
|
||||
@@ -169,28 +168,6 @@ class File extends Container, @file {
|
||||
/** Gets the URL of this file. */
|
||||
override string getURL() { result = "file://" + this.getAbsolutePath() + ":0:0:0:0" }
|
||||
|
||||
/** Gets a token in this file. */
|
||||
private Generated::Token getAToken() { result.getLocation().getFile() = this }
|
||||
|
||||
/** Holds if `line` contains a token. */
|
||||
private predicate line(int line, boolean comment) {
|
||||
exists(Generated::Token token, Location l |
|
||||
token = this.getAToken() and
|
||||
l = token.getLocation() and
|
||||
line in [l.getStartLine() .. l.getEndLine()] and
|
||||
if token instanceof @token_comment then comment = true else comment = false
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the number of lines in this file. */
|
||||
int getNumberOfLines() { result = max([0, this.getAToken().getLocation().getEndLine()]) }
|
||||
|
||||
/** Gets the number of lines of code in this file. */
|
||||
int getNumberOfLinesOfCode() { result = count(int line | this.line(line, false)) }
|
||||
|
||||
/** Gets the number of lines of comments in this file. */
|
||||
int getNumberOfLinesOfComments() { result = count(int line | this.line(line, true)) }
|
||||
|
||||
/** Holds if this file was extracted from ordinary source code. */
|
||||
predicate fromSource() { files(this, _, _, _, 1) }
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import ast.Variable
|
||||
private import ast.internal.AST
|
||||
private import ast.internal.Scope
|
||||
private import ast.internal.Synthesis
|
||||
private import ast.internal.TreeSitter
|
||||
|
||||
/**
|
||||
* A node in the abstract syntax tree. This class is the base class for all Ruby
|
||||
@@ -104,3 +105,30 @@ class AstNode extends TAstNode {
|
||||
*/
|
||||
final AstNode getDesugared() { result = getSynthChild(this, -1) }
|
||||
}
|
||||
|
||||
/** A Ruby source file */
|
||||
class RubyFile extends File {
|
||||
RubyFile() { ruby_ast_node_parent(_, this, _) }
|
||||
|
||||
/** Gets a token in this file. */
|
||||
private Ruby::Token getAToken() { result.getLocation().getFile() = this }
|
||||
|
||||
/** Holds if `line` contains a token. */
|
||||
private predicate line(int line, boolean comment) {
|
||||
exists(Ruby::Token token, Location l |
|
||||
token = this.getAToken() and
|
||||
l = token.getLocation() and
|
||||
line in [l.getStartLine() .. l.getEndLine()] and
|
||||
if token instanceof @ruby_token_comment then comment = true else comment = false
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the number of lines in this file. */
|
||||
int getNumberOfLines() { result = max([0, this.getAToken().getLocation().getEndLine()]) }
|
||||
|
||||
/** Gets the number of lines of code in this file. */
|
||||
int getNumberOfLinesOfCode() { result = count(int line | this.line(line, false)) }
|
||||
|
||||
/** Gets the number of lines of comments in this file. */
|
||||
int getNumberOfLinesOfComments() { result = count(int line | this.line(line, true)) }
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ class ElementReference extends MethodCall, TElementReference {
|
||||
* ```
|
||||
*/
|
||||
class YieldCall extends Call, TYieldCall {
|
||||
Generated::Yield g;
|
||||
Ruby::Yield g;
|
||||
|
||||
YieldCall() { this = TYieldCall(g) }
|
||||
|
||||
@@ -180,7 +180,7 @@ class SuperCall extends MethodCall, TSuperCall {
|
||||
* ```
|
||||
*/
|
||||
class BlockArgument extends Expr, TBlockArgument {
|
||||
private Generated::BlockArgument g;
|
||||
private Ruby::BlockArgument g;
|
||||
|
||||
BlockArgument() { this = TBlockArgument(g) }
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ class ConstantAccess extends Expr, TConstantAccess {
|
||||
}
|
||||
|
||||
private class TokenConstantAccess extends ConstantAccess, TTokenConstantAccess {
|
||||
private Generated::Constant g;
|
||||
private Ruby::Constant g;
|
||||
|
||||
TokenConstantAccess() { this = TTokenConstantAccess(g) }
|
||||
|
||||
@@ -55,8 +55,8 @@ private class TokenConstantAccess extends ConstantAccess, TTokenConstantAccess {
|
||||
}
|
||||
|
||||
private class ScopeResolutionConstantAccess extends ConstantAccess, TScopeResolutionConstantAccess {
|
||||
private Generated::ScopeResolution g;
|
||||
private Generated::Constant constant;
|
||||
private Ruby::ScopeResolution g;
|
||||
private Ruby::Constant constant;
|
||||
|
||||
ScopeResolutionConstantAccess() { this = TScopeResolutionConstantAccess(g, constant) }
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ class IfExpr extends ConditionalExpr, TIfExpr {
|
||||
}
|
||||
|
||||
private class If extends IfExpr, TIf {
|
||||
private Generated::If g;
|
||||
private Ruby::If g;
|
||||
|
||||
If() { this = TIf(g) }
|
||||
|
||||
@@ -125,7 +125,7 @@ private class If extends IfExpr, TIf {
|
||||
}
|
||||
|
||||
private class Elsif extends IfExpr, TElsif {
|
||||
private Generated::Elsif g;
|
||||
private Ruby::Elsif g;
|
||||
|
||||
Elsif() { this = TElsif(g) }
|
||||
|
||||
@@ -149,7 +149,7 @@ private class Elsif extends IfExpr, TElsif {
|
||||
* ```
|
||||
*/
|
||||
class UnlessExpr extends ConditionalExpr, TUnlessExpr {
|
||||
private Generated::Unless g;
|
||||
private Ruby::Unless g;
|
||||
|
||||
UnlessExpr() { this = TUnlessExpr(g) }
|
||||
|
||||
@@ -207,7 +207,7 @@ class UnlessExpr extends ConditionalExpr, TUnlessExpr {
|
||||
* ```
|
||||
*/
|
||||
class IfModifierExpr extends ConditionalExpr, TIfModifierExpr {
|
||||
private Generated::IfModifier g;
|
||||
private Ruby::IfModifier g;
|
||||
|
||||
IfModifierExpr() { this = TIfModifierExpr(g) }
|
||||
|
||||
@@ -242,7 +242,7 @@ class IfModifierExpr extends ConditionalExpr, TIfModifierExpr {
|
||||
* ```
|
||||
*/
|
||||
class UnlessModifierExpr extends ConditionalExpr, TUnlessModifierExpr {
|
||||
private Generated::UnlessModifier g;
|
||||
private Ruby::UnlessModifier g;
|
||||
|
||||
UnlessModifierExpr() { this = TUnlessModifierExpr(g) }
|
||||
|
||||
@@ -277,7 +277,7 @@ class UnlessModifierExpr extends ConditionalExpr, TUnlessModifierExpr {
|
||||
* ```
|
||||
*/
|
||||
class TernaryIfExpr extends ConditionalExpr, TTernaryIfExpr {
|
||||
private Generated::Conditional g;
|
||||
private Ruby::Conditional g;
|
||||
|
||||
TernaryIfExpr() { this = TTernaryIfExpr(g) }
|
||||
|
||||
@@ -309,7 +309,7 @@ class TernaryIfExpr extends ConditionalExpr, TTernaryIfExpr {
|
||||
}
|
||||
|
||||
class CaseExpr extends ControlExpr, TCaseExpr {
|
||||
private Generated::Case g;
|
||||
private Ruby::Case g;
|
||||
|
||||
CaseExpr() { this = TCaseExpr(g) }
|
||||
|
||||
@@ -379,7 +379,7 @@ class CaseExpr extends ControlExpr, TCaseExpr {
|
||||
* ```
|
||||
*/
|
||||
class WhenExpr extends Expr, TWhenExpr {
|
||||
private Generated::When g;
|
||||
private Ruby::When g;
|
||||
|
||||
WhenExpr() { this = TWhenExpr(g) }
|
||||
|
||||
@@ -465,7 +465,7 @@ class ConditionalLoop extends Loop, TConditionalLoop {
|
||||
* ```
|
||||
*/
|
||||
class WhileExpr extends ConditionalLoop, TWhileExpr {
|
||||
private Generated::While g;
|
||||
private Ruby::While g;
|
||||
|
||||
WhileExpr() { this = TWhileExpr(g) }
|
||||
|
||||
@@ -495,7 +495,7 @@ class WhileExpr extends ConditionalLoop, TWhileExpr {
|
||||
* ```
|
||||
*/
|
||||
class UntilExpr extends ConditionalLoop, TUntilExpr {
|
||||
private Generated::Until g;
|
||||
private Ruby::Until g;
|
||||
|
||||
UntilExpr() { this = TUntilExpr(g) }
|
||||
|
||||
@@ -522,7 +522,7 @@ class UntilExpr extends ConditionalLoop, TUntilExpr {
|
||||
* ```
|
||||
*/
|
||||
class WhileModifierExpr extends ConditionalLoop, TWhileModifierExpr {
|
||||
private Generated::WhileModifier g;
|
||||
private Ruby::WhileModifier g;
|
||||
|
||||
WhileModifierExpr() { this = TWhileModifierExpr(g) }
|
||||
|
||||
@@ -548,7 +548,7 @@ class WhileModifierExpr extends ConditionalLoop, TWhileModifierExpr {
|
||||
* ```
|
||||
*/
|
||||
class UntilModifierExpr extends ConditionalLoop, TUntilModifierExpr {
|
||||
private Generated::UntilModifier g;
|
||||
private Ruby::UntilModifier g;
|
||||
|
||||
UntilModifierExpr() { this = TUntilModifierExpr(g) }
|
||||
|
||||
@@ -576,7 +576,7 @@ class UntilModifierExpr extends ConditionalLoop, TUntilModifierExpr {
|
||||
* ```
|
||||
*/
|
||||
class ForExpr extends Loop, TForExpr {
|
||||
private Generated::For g;
|
||||
private Ruby::For g;
|
||||
|
||||
ForExpr() { this = TForExpr(g) }
|
||||
|
||||
|
||||
@@ -37,14 +37,14 @@ class Self extends Expr, TSelf {
|
||||
* ```
|
||||
*/
|
||||
class ArgumentList extends Expr, TArgumentList {
|
||||
private Generated::AstNode g;
|
||||
private Ruby::AstNode g;
|
||||
|
||||
ArgumentList() { this = TArgumentList(g) }
|
||||
|
||||
/** Gets the `i`th element in this argument list. */
|
||||
Expr getElement(int i) {
|
||||
toGenerated(result) in [
|
||||
g.(Generated::ArgumentList).getChild(i), g.(Generated::RightAssignmentList).getChild(i)
|
||||
g.(Ruby::ArgumentList).getChild(i), g.(Ruby::RightAssignmentList).getChild(i)
|
||||
]
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ private class StmtSequenceSynth extends StmtSequence, TStmtSequenceSynth {
|
||||
}
|
||||
|
||||
private class Then extends StmtSequence, TThen {
|
||||
private Generated::Then g;
|
||||
private Ruby::Then g;
|
||||
|
||||
Then() { this = TThen(g) }
|
||||
|
||||
@@ -102,7 +102,7 @@ private class Then extends StmtSequence, TThen {
|
||||
}
|
||||
|
||||
private class Else extends StmtSequence, TElse {
|
||||
private Generated::Else g;
|
||||
private Ruby::Else g;
|
||||
|
||||
Else() { this = TElse(g) }
|
||||
|
||||
@@ -112,7 +112,7 @@ private class Else extends StmtSequence, TElse {
|
||||
}
|
||||
|
||||
private class Do extends StmtSequence, TDo {
|
||||
private Generated::Do g;
|
||||
private Ruby::Do g;
|
||||
|
||||
Do() { this = TDo(g) }
|
||||
|
||||
@@ -122,7 +122,7 @@ private class Do extends StmtSequence, TDo {
|
||||
}
|
||||
|
||||
private class Ensure extends StmtSequence, TEnsure {
|
||||
private Generated::Ensure g;
|
||||
private Ruby::Ensure g;
|
||||
|
||||
Ensure() { this = TEnsure(g) }
|
||||
|
||||
@@ -138,28 +138,28 @@ private class Ensure extends StmtSequence, TEnsure {
|
||||
*/
|
||||
class BodyStmt extends StmtSequence, TBodyStmt {
|
||||
// Not defined by dispatch, as it should not be exposed
|
||||
private Generated::AstNode getChild(int i) {
|
||||
result = any(Generated::Method g | this = TMethod(g)).getChild(i)
|
||||
private Ruby::AstNode getChild(int i) {
|
||||
result = any(Ruby::Method g | this = TMethod(g)).getChild(i)
|
||||
or
|
||||
result = any(Generated::SingletonMethod g | this = TSingletonMethod(g)).getChild(i)
|
||||
result = any(Ruby::SingletonMethod g | this = TSingletonMethod(g)).getChild(i)
|
||||
or
|
||||
exists(Generated::Lambda g | this = TLambda(g) |
|
||||
result = g.getBody().(Generated::DoBlock).getChild(i) or
|
||||
result = g.getBody().(Generated::Block).getChild(i)
|
||||
exists(Ruby::Lambda g | this = TLambda(g) |
|
||||
result = g.getBody().(Ruby::DoBlock).getChild(i) or
|
||||
result = g.getBody().(Ruby::Block).getChild(i)
|
||||
)
|
||||
or
|
||||
result = any(Generated::DoBlock g | this = TDoBlock(g)).getChild(i)
|
||||
result = any(Ruby::DoBlock g | this = TDoBlock(g)).getChild(i)
|
||||
or
|
||||
result = any(Generated::Program g | this = TToplevel(g)).getChild(i) and
|
||||
not result instanceof Generated::BeginBlock
|
||||
result = any(Ruby::Program g | this = TToplevel(g)).getChild(i) and
|
||||
not result instanceof Ruby::BeginBlock
|
||||
or
|
||||
result = any(Generated::Class g | this = TClassDeclaration(g)).getChild(i)
|
||||
result = any(Ruby::Class g | this = TClassDeclaration(g)).getChild(i)
|
||||
or
|
||||
result = any(Generated::SingletonClass g | this = TSingletonClass(g)).getChild(i)
|
||||
result = any(Ruby::SingletonClass g | this = TSingletonClass(g)).getChild(i)
|
||||
or
|
||||
result = any(Generated::Module g | this = TModuleDeclaration(g)).getChild(i)
|
||||
result = any(Ruby::Module g | this = TModuleDeclaration(g)).getChild(i)
|
||||
or
|
||||
result = any(Generated::Begin g | this = TBeginExpr(g)).getChild(i)
|
||||
result = any(Ruby::Begin g | this = TBeginExpr(g)).getChild(i)
|
||||
}
|
||||
|
||||
final override Stmt getStmt(int n) {
|
||||
@@ -218,7 +218,7 @@ class BodyStmt extends StmtSequence, TBodyStmt {
|
||||
* ```
|
||||
*/
|
||||
class ParenthesizedExpr extends StmtSequence, TParenthesizedExpr {
|
||||
private Generated::ParenthesizedStatements g;
|
||||
private Ruby::ParenthesizedStatements g;
|
||||
|
||||
ParenthesizedExpr() { this = TParenthesizedExpr(g) }
|
||||
|
||||
@@ -240,7 +240,7 @@ class ParenthesizedExpr extends StmtSequence, TParenthesizedExpr {
|
||||
* ```
|
||||
*/
|
||||
class Pair extends Expr, TPair {
|
||||
private Generated::Pair g;
|
||||
private Ruby::Pair g;
|
||||
|
||||
Pair() { this = TPair(g) }
|
||||
|
||||
@@ -289,7 +289,7 @@ class Pair extends Expr, TPair {
|
||||
* end
|
||||
*/
|
||||
class RescueClause extends Expr, TRescueClause {
|
||||
private Generated::Rescue g;
|
||||
private Ruby::Rescue g;
|
||||
|
||||
RescueClause() { this = TRescueClause(g) }
|
||||
|
||||
@@ -357,7 +357,7 @@ class RescueClause extends Expr, TRescueClause {
|
||||
* ```
|
||||
*/
|
||||
class RescueModifierExpr extends Expr, TRescueModifierExpr {
|
||||
private Generated::RescueModifier g;
|
||||
private Ruby::RescueModifier g;
|
||||
|
||||
RescueModifierExpr() { this = TRescueModifierExpr(g) }
|
||||
|
||||
@@ -398,7 +398,7 @@ class RescueModifierExpr extends Expr, TRescueModifierExpr {
|
||||
* ```
|
||||
*/
|
||||
class StringConcatenation extends Expr, TStringConcatenation {
|
||||
private Generated::ChainedString g;
|
||||
private Ruby::ChainedString g;
|
||||
|
||||
StringConcatenation() { this = TStringConcatenation(g) }
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ class IntegerLiteral extends NumericLiteral, TIntegerLiteral {
|
||||
}
|
||||
|
||||
private class IntegerLiteralReal extends IntegerLiteral, TIntegerLiteralReal {
|
||||
private Generated::Integer g;
|
||||
private Ruby::Integer g;
|
||||
|
||||
IntegerLiteralReal() { this = TIntegerLiteralReal(g) }
|
||||
|
||||
@@ -113,7 +113,7 @@ private class IntegerLiteralSynth extends IntegerLiteral, TIntegerLiteralSynth {
|
||||
* ```
|
||||
*/
|
||||
class FloatLiteral extends NumericLiteral, TFloatLiteral {
|
||||
private Generated::Float g;
|
||||
private Ruby::Float g;
|
||||
|
||||
FloatLiteral() { this = TFloatLiteral(g) }
|
||||
|
||||
@@ -132,11 +132,11 @@ class FloatLiteral extends NumericLiteral, TFloatLiteral {
|
||||
* ```
|
||||
*/
|
||||
class RationalLiteral extends NumericLiteral, TRationalLiteral {
|
||||
private Generated::Rational g;
|
||||
private Ruby::Rational g;
|
||||
|
||||
RationalLiteral() { this = TRationalLiteral(g) }
|
||||
|
||||
final override string getValueText() { result = g.getChild().(Generated::Token).getValue() + "r" }
|
||||
final override string getValueText() { result = g.getChild().(Ruby::Token).getValue() + "r" }
|
||||
|
||||
final override string toString() { result = this.getValueText() }
|
||||
|
||||
@@ -151,7 +151,7 @@ class RationalLiteral extends NumericLiteral, TRationalLiteral {
|
||||
* ```
|
||||
*/
|
||||
class ComplexLiteral extends NumericLiteral, TComplexLiteral {
|
||||
private Generated::Complex g;
|
||||
private Ruby::Complex g;
|
||||
|
||||
ComplexLiteral() { this = TComplexLiteral(g) }
|
||||
|
||||
@@ -164,7 +164,7 @@ class ComplexLiteral extends NumericLiteral, TComplexLiteral {
|
||||
|
||||
/** A `nil` literal. */
|
||||
class NilLiteral extends Literal, TNilLiteral {
|
||||
private Generated::Nil g;
|
||||
private Ruby::Nil g;
|
||||
|
||||
NilLiteral() { this = TNilLiteral(g) }
|
||||
|
||||
@@ -197,7 +197,7 @@ class BooleanLiteral extends Literal, TBooleanLiteral {
|
||||
}
|
||||
|
||||
private class TrueLiteral extends BooleanLiteral, TTrueLiteral {
|
||||
private Generated::True g;
|
||||
private Ruby::True g;
|
||||
|
||||
TrueLiteral() { this = TTrueLiteral(g) }
|
||||
|
||||
@@ -207,7 +207,7 @@ private class TrueLiteral extends BooleanLiteral, TTrueLiteral {
|
||||
}
|
||||
|
||||
private class FalseLiteral extends BooleanLiteral, TFalseLiteral {
|
||||
private Generated::False g;
|
||||
private Ruby::False g;
|
||||
|
||||
FalseLiteral() { this = TFalseLiteral(g) }
|
||||
|
||||
@@ -241,7 +241,7 @@ class StringComponent extends AstNode, TStringComponent {
|
||||
* ```
|
||||
*/
|
||||
class StringTextComponent extends StringComponent, TStringTextComponent {
|
||||
private Generated::Token g;
|
||||
private Ruby::Token g;
|
||||
|
||||
StringTextComponent() { this = TStringTextComponent(g) }
|
||||
|
||||
@@ -256,7 +256,7 @@ class StringTextComponent extends StringComponent, TStringTextComponent {
|
||||
* An escape sequence component of a string or string-like literal.
|
||||
*/
|
||||
class StringEscapeSequenceComponent extends StringComponent, TStringEscapeSequenceComponent {
|
||||
private Generated::EscapeSequence g;
|
||||
private Ruby::EscapeSequence g;
|
||||
|
||||
StringEscapeSequenceComponent() { this = TStringEscapeSequenceComponent(g) }
|
||||
|
||||
@@ -272,7 +272,7 @@ class StringEscapeSequenceComponent extends StringComponent, TStringEscapeSequen
|
||||
*/
|
||||
class StringInterpolationComponent extends StringComponent, StmtSequence,
|
||||
TStringInterpolationComponent {
|
||||
private Generated::Interpolation g;
|
||||
private Ruby::Interpolation g;
|
||||
|
||||
StringInterpolationComponent() { this = TStringInterpolationComponent(g) }
|
||||
|
||||
@@ -386,9 +386,9 @@ class StringlikeLiteral extends Literal, TStringlikeLiteral {
|
||||
concat(StringComponent c, int i, string s |
|
||||
c = this.getComponent(i) and
|
||||
(
|
||||
s = toGenerated(c).(Generated::Token).getValue()
|
||||
s = toGenerated(c).(Ruby::Token).getValue()
|
||||
or
|
||||
not toGenerated(c) instanceof Generated::Token and
|
||||
not toGenerated(c) instanceof Ruby::Token and
|
||||
s = "#{...}"
|
||||
)
|
||||
|
|
||||
@@ -424,7 +424,7 @@ class StringLiteral extends StringlikeLiteral, TStringLiteral {
|
||||
}
|
||||
|
||||
private class RegularStringLiteral extends StringLiteral, TRegularStringLiteral {
|
||||
private Generated::String g;
|
||||
private Ruby::String g;
|
||||
|
||||
RegularStringLiteral() { this = TRegularStringLiteral(g) }
|
||||
|
||||
@@ -432,7 +432,7 @@ private class RegularStringLiteral extends StringLiteral, TRegularStringLiteral
|
||||
}
|
||||
|
||||
private class BareStringLiteral extends StringLiteral, TBareStringLiteral {
|
||||
private Generated::BareString g;
|
||||
private Ruby::BareString g;
|
||||
|
||||
BareStringLiteral() { this = TBareStringLiteral(g) }
|
||||
|
||||
@@ -447,7 +447,7 @@ private class BareStringLiteral extends StringLiteral, TBareStringLiteral {
|
||||
* ```
|
||||
*/
|
||||
class RegExpLiteral extends StringlikeLiteral, TRegExpLiteral {
|
||||
private Generated::Regex g;
|
||||
private Ruby::Regex g;
|
||||
|
||||
RegExpLiteral() { this = TRegExpLiteral(g) }
|
||||
|
||||
@@ -467,11 +467,7 @@ class RegExpLiteral extends StringlikeLiteral, TRegExpLiteral {
|
||||
// For `/foo/i`, there should be an `/i` token in the database with `this`
|
||||
// as its parents. Strip the delimiter, which can vary.
|
||||
result =
|
||||
max(Generated::Token t |
|
||||
t.getParent() = g
|
||||
|
|
||||
t.getValue().suffix(1) order by t.getParentIndex()
|
||||
)
|
||||
max(Ruby::Token t | t.getParent() = g | t.getValue().suffix(1) order by t.getParentIndex())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -528,7 +524,7 @@ class SymbolLiteral extends StringlikeLiteral, TSymbolLiteral {
|
||||
}
|
||||
|
||||
private class SimpleSymbolLiteral extends SymbolLiteral, TSimpleSymbolLiteral {
|
||||
private Generated::SimpleSymbol g;
|
||||
private Ruby::SimpleSymbol g;
|
||||
|
||||
SimpleSymbolLiteral() { this = TSimpleSymbolLiteral(g) }
|
||||
|
||||
@@ -541,7 +537,7 @@ private class SimpleSymbolLiteral extends SymbolLiteral, TSimpleSymbolLiteral {
|
||||
private class ComplexSymbolLiteral extends SymbolLiteral, TComplexSymbolLiteral { }
|
||||
|
||||
private class DelimitedSymbolLiteral extends ComplexSymbolLiteral, TDelimitedSymbolLiteral {
|
||||
private Generated::DelimitedSymbol g;
|
||||
private Ruby::DelimitedSymbol g;
|
||||
|
||||
DelimitedSymbolLiteral() { this = TDelimitedSymbolLiteral(g) }
|
||||
|
||||
@@ -549,7 +545,7 @@ private class DelimitedSymbolLiteral extends ComplexSymbolLiteral, TDelimitedSym
|
||||
}
|
||||
|
||||
private class BareSymbolLiteral extends ComplexSymbolLiteral, TBareSymbolLiteral {
|
||||
private Generated::BareSymbol g;
|
||||
private Ruby::BareSymbol g;
|
||||
|
||||
BareSymbolLiteral() { this = TBareSymbolLiteral(g) }
|
||||
|
||||
@@ -557,7 +553,7 @@ private class BareSymbolLiteral extends ComplexSymbolLiteral, TBareSymbolLiteral
|
||||
}
|
||||
|
||||
private class HashKeySymbolLiteral extends SymbolLiteral, THashKeySymbolLiteral {
|
||||
private Generated::HashKeySymbol g;
|
||||
private Ruby::HashKeySymbol g;
|
||||
|
||||
HashKeySymbolLiteral() { this = THashKeySymbolLiteral(g) }
|
||||
|
||||
@@ -575,7 +571,7 @@ private class HashKeySymbolLiteral extends SymbolLiteral, THashKeySymbolLiteral
|
||||
* ```
|
||||
*/
|
||||
class SubshellLiteral extends StringlikeLiteral, TSubshellLiteral {
|
||||
private Generated::Subshell g;
|
||||
private Ruby::Subshell g;
|
||||
|
||||
SubshellLiteral() { this = TSubshellLiteral(g) }
|
||||
|
||||
@@ -593,7 +589,7 @@ class SubshellLiteral extends StringlikeLiteral, TSubshellLiteral {
|
||||
* ```
|
||||
*/
|
||||
class CharacterLiteral extends Literal, TCharacterLiteral {
|
||||
private Generated::Character g;
|
||||
private Ruby::Character g;
|
||||
|
||||
CharacterLiteral() { this = TCharacterLiteral(g) }
|
||||
|
||||
@@ -614,7 +610,7 @@ class CharacterLiteral extends Literal, TCharacterLiteral {
|
||||
* ```
|
||||
*/
|
||||
class HereDoc extends StringlikeLiteral, THereDoc {
|
||||
private Generated::HeredocBeginning g;
|
||||
private Ruby::HeredocBeginning g;
|
||||
|
||||
HereDoc() { this = THereDoc(g) }
|
||||
|
||||
@@ -698,7 +694,7 @@ class ArrayLiteral extends Literal, TArrayLiteral {
|
||||
}
|
||||
|
||||
private class RegularArrayLiteral extends ArrayLiteral, TRegularArrayLiteral {
|
||||
private Generated::Array g;
|
||||
private Ruby::Array g;
|
||||
|
||||
RegularArrayLiteral() { this = TRegularArrayLiteral(g) }
|
||||
|
||||
@@ -708,7 +704,7 @@ private class RegularArrayLiteral extends ArrayLiteral, TRegularArrayLiteral {
|
||||
}
|
||||
|
||||
private class StringArrayLiteral extends ArrayLiteral, TStringArrayLiteral {
|
||||
private Generated::StringArray g;
|
||||
private Ruby::StringArray g;
|
||||
|
||||
StringArrayLiteral() { this = TStringArrayLiteral(g) }
|
||||
|
||||
@@ -718,7 +714,7 @@ private class StringArrayLiteral extends ArrayLiteral, TStringArrayLiteral {
|
||||
}
|
||||
|
||||
private class SymbolArrayLiteral extends ArrayLiteral, TSymbolArrayLiteral {
|
||||
private Generated::SymbolArray g;
|
||||
private Ruby::SymbolArray g;
|
||||
|
||||
SymbolArrayLiteral() { this = TSymbolArrayLiteral(g) }
|
||||
|
||||
@@ -735,7 +731,7 @@ private class SymbolArrayLiteral extends ArrayLiteral, TSymbolArrayLiteral {
|
||||
* ```
|
||||
*/
|
||||
class HashLiteral extends Literal, THashLiteral {
|
||||
private Generated::Hash g;
|
||||
private Ruby::Hash g;
|
||||
|
||||
HashLiteral() { this = THashLiteral(g) }
|
||||
|
||||
@@ -820,7 +816,7 @@ class RangeLiteral extends Literal, TRangeLiteral {
|
||||
}
|
||||
|
||||
private class RangeLiteralReal extends RangeLiteral, TRangeLiteralReal {
|
||||
private Generated::Range g;
|
||||
private Ruby::Range g;
|
||||
|
||||
RangeLiteralReal() { this = TRangeLiteralReal(g) }
|
||||
|
||||
@@ -828,9 +824,9 @@ private class RangeLiteralReal extends RangeLiteral, TRangeLiteralReal {
|
||||
|
||||
final override Expr getEnd() { toGenerated(result) = g.getEnd() }
|
||||
|
||||
final override predicate isInclusive() { g instanceof @range_dotdot }
|
||||
final override predicate isInclusive() { g instanceof @ruby_range_dotdot }
|
||||
|
||||
final override predicate isExclusive() { g instanceof @range_dotdotdot }
|
||||
final override predicate isExclusive() { g instanceof @ruby_range_dotdotdot }
|
||||
}
|
||||
|
||||
private class RangeLiteralSynth extends RangeLiteral, TRangeLiteralSynth {
|
||||
@@ -868,9 +864,9 @@ private class TokenMethodName extends MethodName, TTokenMethodName {
|
||||
TokenMethodName() { this = TTokenMethodName(g) }
|
||||
|
||||
final override string getValueText() {
|
||||
result = g.(Generated::Token).getValue()
|
||||
result = g.(Ruby::Token).getValue()
|
||||
or
|
||||
result = g.(Generated::Setter).getName().getValue() + "="
|
||||
result = g.(Ruby::Setter).getName().getValue() + "="
|
||||
}
|
||||
|
||||
final override string toString() { result = this.getValueText() }
|
||||
|
||||
@@ -40,15 +40,15 @@ private class Private extends MethodCall {
|
||||
|
||||
/** A normal method. */
|
||||
class Method extends MethodBase, TMethod {
|
||||
private Generated::Method g;
|
||||
private Ruby::Method g;
|
||||
|
||||
Method() { this = TMethod(g) }
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "Method" }
|
||||
|
||||
final override string getName() {
|
||||
result = g.getName().(Generated::Token).getValue() or
|
||||
result = g.getName().(Generated::Setter).getName().getValue() + "="
|
||||
result = g.getName().(Ruby::Token).getValue() or
|
||||
result = g.getName().(Ruby::Setter).getName().getValue() + "="
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,7 +61,7 @@ class Method extends MethodBase, TMethod {
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
final predicate isSetter() { g.getName() instanceof Generated::Setter }
|
||||
final predicate isSetter() { g.getName() instanceof Ruby::Setter }
|
||||
|
||||
/**
|
||||
* Holds if this method is private. All methods with the name prefix
|
||||
@@ -118,7 +118,7 @@ class Method extends MethodBase, TMethod {
|
||||
|
||||
/** A singleton method. */
|
||||
class SingletonMethod extends MethodBase, TSingletonMethod {
|
||||
private Generated::SingletonMethod g;
|
||||
private Ruby::SingletonMethod g;
|
||||
|
||||
SingletonMethod() { this = TSingletonMethod(g) }
|
||||
|
||||
@@ -128,9 +128,9 @@ class SingletonMethod extends MethodBase, TSingletonMethod {
|
||||
final Expr getObject() { toGenerated(result) = g.getObject() }
|
||||
|
||||
final override string getName() {
|
||||
result = g.getName().(Generated::Token).getValue()
|
||||
result = g.getName().(Ruby::Token).getValue()
|
||||
or
|
||||
result = g.getName().(Generated::Setter).getName().getValue() + "="
|
||||
result = g.getName().(Ruby::Setter).getName().getValue() + "="
|
||||
}
|
||||
|
||||
final override Parameter getParameter(int n) {
|
||||
@@ -153,7 +153,7 @@ class SingletonMethod extends MethodBase, TSingletonMethod {
|
||||
* ```
|
||||
*/
|
||||
class Lambda extends Callable, BodyStmt, TLambda {
|
||||
private Generated::Lambda g;
|
||||
private Ruby::Lambda g;
|
||||
|
||||
Lambda() { this = TLambda(g) }
|
||||
|
||||
@@ -183,7 +183,7 @@ class Block extends Callable, StmtSequence, Scope, TBlock {
|
||||
|
||||
/** A block enclosed within `do` and `end`. */
|
||||
class DoBlock extends Block, BodyStmt, TDoBlock {
|
||||
private Generated::DoBlock g;
|
||||
private Ruby::DoBlock g;
|
||||
|
||||
DoBlock() { this = TDoBlock(g) }
|
||||
|
||||
@@ -209,7 +209,7 @@ class DoBlock extends Block, BodyStmt, TDoBlock {
|
||||
* ```
|
||||
*/
|
||||
class BraceBlock extends Block, TBraceBlock {
|
||||
private Generated::Block g;
|
||||
private Ruby::Block g;
|
||||
|
||||
BraceBlock() { this = TBraceBlock(g) }
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ class ModuleBase extends BodyStmt, Scope, TModuleBase {
|
||||
* ```
|
||||
*/
|
||||
class Toplevel extends ModuleBase, TToplevel {
|
||||
private Generated::Program g;
|
||||
private Ruby::Program g;
|
||||
|
||||
Toplevel() { this = TToplevel(g) }
|
||||
|
||||
@@ -119,8 +119,7 @@ class Toplevel extends ModuleBase, TToplevel {
|
||||
* Gets the `n`th `BEGIN` block.
|
||||
*/
|
||||
final BeginBlock getBeginBlock(int n) {
|
||||
toGenerated(result) =
|
||||
rank[n + 1](int i, Generated::BeginBlock b | b = g.getChild(i) | b order by i)
|
||||
toGenerated(result) = rank[n + 1](int i, Ruby::BeginBlock b | b = g.getChild(i) | b order by i)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -231,7 +230,7 @@ class Namespace extends ModuleBase, ConstantWriteAccess, TNamespace {
|
||||
* ```
|
||||
*/
|
||||
class ClassDeclaration extends Namespace, TClassDeclaration {
|
||||
private Generated::Class g;
|
||||
private Ruby::Class g;
|
||||
|
||||
ClassDeclaration() { this = TClassDeclaration(g) }
|
||||
|
||||
@@ -256,16 +255,16 @@ class ClassDeclaration extends Namespace, TClassDeclaration {
|
||||
final Expr getSuperclassExpr() { toGenerated(result) = g.getSuperclass().getChild() }
|
||||
|
||||
final override string getName() {
|
||||
result = g.getName().(Generated::Token).getValue() or
|
||||
result = g.getName().(Generated::ScopeResolution).getName().(Generated::Token).getValue()
|
||||
result = g.getName().(Ruby::Token).getValue() or
|
||||
result = g.getName().(Ruby::ScopeResolution).getName().(Ruby::Token).getValue()
|
||||
}
|
||||
|
||||
final override Expr getScopeExpr() {
|
||||
toGenerated(result) = g.getName().(Generated::ScopeResolution).getScope()
|
||||
toGenerated(result) = g.getName().(Ruby::ScopeResolution).getScope()
|
||||
}
|
||||
|
||||
final override predicate hasGlobalScope() {
|
||||
exists(Generated::ScopeResolution sr |
|
||||
exists(Ruby::ScopeResolution sr |
|
||||
sr = g.getName() and
|
||||
not exists(sr.getScope())
|
||||
)
|
||||
@@ -290,7 +289,7 @@ class ClassDeclaration extends Namespace, TClassDeclaration {
|
||||
* ```
|
||||
*/
|
||||
class SingletonClass extends ModuleBase, TSingletonClass {
|
||||
private Generated::SingletonClass g;
|
||||
private Ruby::SingletonClass g;
|
||||
|
||||
SingletonClass() { this = TSingletonClass(g) }
|
||||
|
||||
@@ -342,23 +341,23 @@ class SingletonClass extends ModuleBase, TSingletonClass {
|
||||
* ```
|
||||
*/
|
||||
class ModuleDeclaration extends Namespace, TModuleDeclaration {
|
||||
private Generated::Module g;
|
||||
private Ruby::Module g;
|
||||
|
||||
ModuleDeclaration() { this = TModuleDeclaration(g) }
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "ModuleDeclaration" }
|
||||
|
||||
final override string getName() {
|
||||
result = g.getName().(Generated::Token).getValue() or
|
||||
result = g.getName().(Generated::ScopeResolution).getName().(Generated::Token).getValue()
|
||||
result = g.getName().(Ruby::Token).getValue() or
|
||||
result = g.getName().(Ruby::ScopeResolution).getName().(Ruby::Token).getValue()
|
||||
}
|
||||
|
||||
final override Expr getScopeExpr() {
|
||||
toGenerated(result) = g.getName().(Generated::ScopeResolution).getScope()
|
||||
toGenerated(result) = g.getName().(Ruby::ScopeResolution).getScope()
|
||||
}
|
||||
|
||||
final override predicate hasGlobalScope() {
|
||||
exists(Generated::ScopeResolution sr |
|
||||
exists(Ruby::ScopeResolution sr |
|
||||
sr = g.getName() and
|
||||
not exists(sr.getScope())
|
||||
)
|
||||
|
||||
@@ -39,7 +39,7 @@ class UnaryOperation extends Operation, TUnaryOperation {
|
||||
}
|
||||
|
||||
private class UnaryOperationGenerated extends UnaryOperation, TUnaryOperation {
|
||||
private Generated::Unary g;
|
||||
private Ruby::Unary g;
|
||||
|
||||
UnaryOperationGenerated() { g = toGenerated(this) }
|
||||
|
||||
@@ -106,7 +106,7 @@ class SplatExpr extends UnaryOperation, TSplatExpr {
|
||||
* ```
|
||||
*/
|
||||
class HashSplatExpr extends UnaryOperation, THashSplatExpr {
|
||||
private Generated::HashSplatArgument g;
|
||||
private Ruby::HashSplatArgument g;
|
||||
|
||||
HashSplatExpr() { this = THashSplatExpr(g) }
|
||||
|
||||
@@ -164,7 +164,7 @@ class BinaryOperation extends Operation, TBinaryOperation {
|
||||
}
|
||||
|
||||
private class BinaryOperationReal extends BinaryOperation {
|
||||
private Generated::Binary g;
|
||||
private Ruby::Binary g;
|
||||
|
||||
BinaryOperationReal() { g = toGenerated(this) }
|
||||
|
||||
@@ -569,7 +569,7 @@ class AssignExpr extends Assignment, TAssignExpr {
|
||||
* A binary assignment operation other than `=`.
|
||||
*/
|
||||
class AssignOperation extends Assignment, TAssignOperation {
|
||||
Generated::OperatorAssignment g;
|
||||
Ruby::OperatorAssignment g;
|
||||
|
||||
AssignOperation() { g = toGenerated(this) }
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ class NamedParameter extends Parameter, TNamedParameter {
|
||||
|
||||
/** A simple (normal) parameter. */
|
||||
class SimpleParameter extends NamedParameter, PatternParameter, VariablePattern, TSimpleParameter {
|
||||
private Generated::Identifier g;
|
||||
private Ruby::Identifier g;
|
||||
|
||||
SimpleParameter() { this = TSimpleParameter(g) }
|
||||
|
||||
@@ -90,7 +90,7 @@ class SimpleParameter extends NamedParameter, PatternParameter, VariablePattern,
|
||||
* ```
|
||||
*/
|
||||
class BlockParameter extends NamedParameter, TBlockParameter {
|
||||
private Generated::BlockParameter g;
|
||||
private Ruby::BlockParameter g;
|
||||
|
||||
BlockParameter() { this = TBlockParameter(g) }
|
||||
|
||||
@@ -113,7 +113,7 @@ class BlockParameter extends NamedParameter, TBlockParameter {
|
||||
* ```
|
||||
*/
|
||||
class HashSplatParameter extends NamedParameter, THashSplatParameter {
|
||||
private Generated::HashSplatParameter g;
|
||||
private Ruby::HashSplatParameter g;
|
||||
|
||||
HashSplatParameter() { this = THashSplatParameter(g) }
|
||||
|
||||
@@ -138,7 +138,7 @@ class HashSplatParameter extends NamedParameter, THashSplatParameter {
|
||||
* ```
|
||||
*/
|
||||
class KeywordParameter extends NamedParameter, TKeywordParameter {
|
||||
private Generated::KeywordParameter g;
|
||||
private Ruby::KeywordParameter g;
|
||||
|
||||
KeywordParameter() { this = TKeywordParameter(g) }
|
||||
|
||||
@@ -182,7 +182,7 @@ class KeywordParameter extends NamedParameter, TKeywordParameter {
|
||||
* ```
|
||||
*/
|
||||
class OptionalParameter extends NamedParameter, TOptionalParameter {
|
||||
private Generated::OptionalParameter g;
|
||||
private Ruby::OptionalParameter g;
|
||||
|
||||
OptionalParameter() { this = TOptionalParameter(g) }
|
||||
|
||||
@@ -218,7 +218,7 @@ class OptionalParameter extends NamedParameter, TOptionalParameter {
|
||||
* ```
|
||||
*/
|
||||
class SplatParameter extends NamedParameter, TSplatParameter {
|
||||
private Generated::SplatParameter g;
|
||||
private Ruby::SplatParameter g;
|
||||
|
||||
SplatParameter() { this = TSplatParameter(g) }
|
||||
|
||||
|
||||
@@ -65,12 +65,12 @@ class TuplePattern extends Pattern, TTuplePattern {
|
||||
|
||||
private TuplePatternImpl getImpl() { result = toGenerated(this) }
|
||||
|
||||
private Generated::AstNode getChild(int i) { result = this.getImpl().getChildNode(i) }
|
||||
private Ruby::AstNode getChild(int i) { result = this.getImpl().getChildNode(i) }
|
||||
|
||||
/** Gets the `i`th pattern in this tuple pattern. */
|
||||
final Pattern getElement(int i) {
|
||||
exists(Generated::AstNode c | c = this.getChild(i) |
|
||||
toGenerated(result) = c.(Generated::RestAssignment).getChild()
|
||||
exists(Ruby::AstNode c | c = this.getChild(i) |
|
||||
toGenerated(result) = c.(Ruby::RestAssignment).getChild()
|
||||
or
|
||||
toGenerated(result) = c
|
||||
)
|
||||
|
||||
@@ -51,7 +51,7 @@ class BeginExpr extends BodyStmt, TBeginExpr {
|
||||
* ```
|
||||
*/
|
||||
class BeginBlock extends StmtSequence, TBeginBlock {
|
||||
private Generated::BeginBlock g;
|
||||
private Ruby::BeginBlock g;
|
||||
|
||||
BeginBlock() { this = TBeginBlock(g) }
|
||||
|
||||
@@ -69,7 +69,7 @@ class BeginBlock extends StmtSequence, TBeginBlock {
|
||||
* ```
|
||||
*/
|
||||
class EndBlock extends StmtSequence, TEndBlock {
|
||||
private Generated::EndBlock g;
|
||||
private Ruby::EndBlock g;
|
||||
|
||||
EndBlock() { this = TEndBlock(g) }
|
||||
|
||||
@@ -89,7 +89,7 @@ class EndBlock extends StmtSequence, TEndBlock {
|
||||
* ```
|
||||
*/
|
||||
class UndefStmt extends Stmt, TUndefStmt {
|
||||
private Generated::Undef g;
|
||||
private Ruby::Undef g;
|
||||
|
||||
UndefStmt() { this = TUndefStmt(g) }
|
||||
|
||||
@@ -119,7 +119,7 @@ class UndefStmt extends Stmt, TUndefStmt {
|
||||
* ```
|
||||
*/
|
||||
class AliasStmt extends Stmt, TAliasStmt {
|
||||
private Generated::Alias g;
|
||||
private Ruby::Alias g;
|
||||
|
||||
AliasStmt() { this = TAliasStmt(g) }
|
||||
|
||||
@@ -155,19 +155,19 @@ class AliasStmt extends Stmt, TAliasStmt {
|
||||
* ```
|
||||
*/
|
||||
class ReturningStmt extends Stmt, TReturningStmt {
|
||||
private Generated::ArgumentList getArgumentList() {
|
||||
result = any(Generated::Return g | this = TReturnStmt(g)).getChild()
|
||||
private Ruby::ArgumentList getArgumentList() {
|
||||
result = any(Ruby::Return g | this = TReturnStmt(g)).getChild()
|
||||
or
|
||||
result = any(Generated::Break g | this = TBreakStmt(g)).getChild()
|
||||
result = any(Ruby::Break g | this = TBreakStmt(g)).getChild()
|
||||
or
|
||||
result = any(Generated::Next g | this = TNextStmt(g)).getChild()
|
||||
result = any(Ruby::Next g | this = TNextStmt(g)).getChild()
|
||||
}
|
||||
|
||||
/** Gets the returned value, if any. */
|
||||
final Expr getValue() {
|
||||
toGenerated(result) =
|
||||
any(Generated::AstNode res |
|
||||
exists(Generated::ArgumentList a, int c |
|
||||
any(Ruby::AstNode res |
|
||||
exists(Ruby::ArgumentList a, int c |
|
||||
a = this.getArgumentList() and c = count(a.getChild(_))
|
||||
|
|
||||
res = a.getChild(0) and c = 1
|
||||
|
||||
@@ -7,15 +7,16 @@ private import codeql_ruby.AST as AST
|
||||
private import Synthesis
|
||||
|
||||
module MethodName {
|
||||
predicate range(Generated::UnderscoreMethodName g) {
|
||||
exists(Generated::Undef u | u.getChild(_) = g)
|
||||
predicate range(Ruby::UnderscoreMethodName g) {
|
||||
exists(Ruby::Undef u | u.getChild(_) = g)
|
||||
or
|
||||
exists(Generated::Alias a | a.getName() = g or a.getAlias() = g)
|
||||
exists(Ruby::Alias a | a.getName() = g or a.getAlias() = g)
|
||||
}
|
||||
|
||||
class Token =
|
||||
@setter or @token_class_variable or @token_constant or @token_global_variable or
|
||||
@token_identifier or @token_instance_variable or @token_operator;
|
||||
@ruby_setter or @ruby_token_class_variable or @ruby_token_constant or
|
||||
@ruby_token_global_variable or @ruby_token_identifier or @ruby_token_instance_variable or
|
||||
@ruby_token_operator;
|
||||
}
|
||||
|
||||
private predicate mkSynthChild(SynthKind kind, AST::AstNode parent, int i) {
|
||||
@@ -26,142 +27,142 @@ cached
|
||||
private module Cached {
|
||||
cached
|
||||
newtype TAstNode =
|
||||
TAddExprReal(Generated::Binary g) { g instanceof @binary_plus } or
|
||||
TAddExprReal(Ruby::Binary g) { g instanceof @ruby_binary_plus } or
|
||||
TAddExprSynth(AST::AstNode parent, int i) { mkSynthChild(AddExprKind(), parent, i) } or
|
||||
TAliasStmt(Generated::Alias g) or
|
||||
TArgumentList(Generated::AstNode g) {
|
||||
TAliasStmt(Ruby::Alias g) or
|
||||
TArgumentList(Ruby::AstNode g) {
|
||||
(
|
||||
g.getParent() instanceof Generated::Break or
|
||||
g.getParent() instanceof Generated::Return or
|
||||
g.getParent() instanceof Generated::Next or
|
||||
g.getParent() instanceof Generated::Assignment or
|
||||
g.getParent() instanceof Generated::OperatorAssignment
|
||||
g.getParent() instanceof Ruby::Break or
|
||||
g.getParent() instanceof Ruby::Return or
|
||||
g.getParent() instanceof Ruby::Next or
|
||||
g.getParent() instanceof Ruby::Assignment or
|
||||
g.getParent() instanceof Ruby::OperatorAssignment
|
||||
) and
|
||||
(
|
||||
strictcount(g.(Generated::ArgumentList).getChild(_)) > 1
|
||||
strictcount(g.(Ruby::ArgumentList).getChild(_)) > 1
|
||||
or
|
||||
g instanceof Generated::RightAssignmentList
|
||||
g instanceof Ruby::RightAssignmentList
|
||||
)
|
||||
} or
|
||||
TAssignAddExpr(Generated::OperatorAssignment g) { g instanceof @operator_assignment_plusequal } or
|
||||
TAssignBitwiseAndExpr(Generated::OperatorAssignment g) {
|
||||
g instanceof @operator_assignment_ampersandequal
|
||||
TAssignAddExpr(Ruby::OperatorAssignment g) { g instanceof @ruby_operator_assignment_plusequal } or
|
||||
TAssignBitwiseAndExpr(Ruby::OperatorAssignment g) {
|
||||
g instanceof @ruby_operator_assignment_ampersandequal
|
||||
} or
|
||||
TAssignBitwiseOrExpr(Generated::OperatorAssignment g) {
|
||||
g instanceof @operator_assignment_pipeequal
|
||||
TAssignBitwiseOrExpr(Ruby::OperatorAssignment g) {
|
||||
g instanceof @ruby_operator_assignment_pipeequal
|
||||
} or
|
||||
TAssignBitwiseXorExpr(Generated::OperatorAssignment g) {
|
||||
g instanceof @operator_assignment_caretequal
|
||||
TAssignBitwiseXorExpr(Ruby::OperatorAssignment g) {
|
||||
g instanceof @ruby_operator_assignment_caretequal
|
||||
} or
|
||||
TAssignDivExpr(Generated::OperatorAssignment g) { g instanceof @operator_assignment_slashequal } or
|
||||
TAssignExponentExpr(Generated::OperatorAssignment g) {
|
||||
g instanceof @operator_assignment_starstarequal
|
||||
TAssignDivExpr(Ruby::OperatorAssignment g) { g instanceof @ruby_operator_assignment_slashequal } or
|
||||
TAssignExponentExpr(Ruby::OperatorAssignment g) {
|
||||
g instanceof @ruby_operator_assignment_starstarequal
|
||||
} or
|
||||
TAssignExprReal(Generated::Assignment g) or
|
||||
TAssignExprReal(Ruby::Assignment g) or
|
||||
TAssignExprSynth(AST::AstNode parent, int i) { mkSynthChild(AssignExprKind(), parent, i) } or
|
||||
TAssignLShiftExpr(Generated::OperatorAssignment g) {
|
||||
g instanceof @operator_assignment_langlelangleequal
|
||||
TAssignLShiftExpr(Ruby::OperatorAssignment g) {
|
||||
g instanceof @ruby_operator_assignment_langlelangleequal
|
||||
} or
|
||||
TAssignLogicalAndExpr(Generated::OperatorAssignment g) {
|
||||
g instanceof @operator_assignment_ampersandampersandequal
|
||||
TAssignLogicalAndExpr(Ruby::OperatorAssignment g) {
|
||||
g instanceof @ruby_operator_assignment_ampersandampersandequal
|
||||
} or
|
||||
TAssignLogicalOrExpr(Generated::OperatorAssignment g) {
|
||||
g instanceof @operator_assignment_pipepipeequal
|
||||
TAssignLogicalOrExpr(Ruby::OperatorAssignment g) {
|
||||
g instanceof @ruby_operator_assignment_pipepipeequal
|
||||
} or
|
||||
TAssignModuloExpr(Generated::OperatorAssignment g) {
|
||||
g instanceof @operator_assignment_percentequal
|
||||
TAssignModuloExpr(Ruby::OperatorAssignment g) {
|
||||
g instanceof @ruby_operator_assignment_percentequal
|
||||
} or
|
||||
TAssignMulExpr(Generated::OperatorAssignment g) { g instanceof @operator_assignment_starequal } or
|
||||
TAssignRShiftExpr(Generated::OperatorAssignment g) {
|
||||
g instanceof @operator_assignment_ranglerangleequal
|
||||
TAssignMulExpr(Ruby::OperatorAssignment g) { g instanceof @ruby_operator_assignment_starequal } or
|
||||
TAssignRShiftExpr(Ruby::OperatorAssignment g) {
|
||||
g instanceof @ruby_operator_assignment_ranglerangleequal
|
||||
} or
|
||||
TAssignSubExpr(Generated::OperatorAssignment g) { g instanceof @operator_assignment_minusequal } or
|
||||
TBareStringLiteral(Generated::BareString g) or
|
||||
TBareSymbolLiteral(Generated::BareSymbol g) or
|
||||
TBeginBlock(Generated::BeginBlock g) or
|
||||
TBeginExpr(Generated::Begin g) or
|
||||
TBitwiseAndExprReal(Generated::Binary g) { g instanceof @binary_ampersand } or
|
||||
TAssignSubExpr(Ruby::OperatorAssignment g) { g instanceof @ruby_operator_assignment_minusequal } or
|
||||
TBareStringLiteral(Ruby::BareString g) or
|
||||
TBareSymbolLiteral(Ruby::BareSymbol g) or
|
||||
TBeginBlock(Ruby::BeginBlock g) or
|
||||
TBeginExpr(Ruby::Begin g) or
|
||||
TBitwiseAndExprReal(Ruby::Binary g) { g instanceof @ruby_binary_ampersand } or
|
||||
TBitwiseAndExprSynth(AST::AstNode parent, int i) {
|
||||
mkSynthChild(BitwiseAndExprKind(), parent, i)
|
||||
} or
|
||||
TBitwiseOrExprReal(Generated::Binary g) { g instanceof @binary_pipe } or
|
||||
TBitwiseOrExprReal(Ruby::Binary g) { g instanceof @ruby_binary_pipe } or
|
||||
TBitwiseOrExprSynth(AST::AstNode parent, int i) { mkSynthChild(BitwiseOrExprKind(), parent, i) } or
|
||||
TBitwiseXorExprReal(Generated::Binary g) { g instanceof @binary_caret } or
|
||||
TBitwiseXorExprReal(Ruby::Binary g) { g instanceof @ruby_binary_caret } or
|
||||
TBitwiseXorExprSynth(AST::AstNode parent, int i) {
|
||||
mkSynthChild(BitwiseXorExprKind(), parent, i)
|
||||
} or
|
||||
TBlockArgument(Generated::BlockArgument g) or
|
||||
TBlockParameter(Generated::BlockParameter g) or
|
||||
TBraceBlock(Generated::Block g) { not g.getParent() instanceof Generated::Lambda } or
|
||||
TBreakStmt(Generated::Break g) or
|
||||
TCaseEqExpr(Generated::Binary g) { g instanceof @binary_equalequalequal } or
|
||||
TCaseExpr(Generated::Case g) or
|
||||
TCharacterLiteral(Generated::Character g) or
|
||||
TClassDeclaration(Generated::Class g) or
|
||||
TClassVariableAccessReal(Generated::ClassVariable g, AST::ClassVariable v) {
|
||||
TBlockArgument(Ruby::BlockArgument g) or
|
||||
TBlockParameter(Ruby::BlockParameter g) or
|
||||
TBraceBlock(Ruby::Block g) { not g.getParent() instanceof Ruby::Lambda } or
|
||||
TBreakStmt(Ruby::Break g) or
|
||||
TCaseEqExpr(Ruby::Binary g) { g instanceof @ruby_binary_equalequalequal } or
|
||||
TCaseExpr(Ruby::Case g) or
|
||||
TCharacterLiteral(Ruby::Character g) or
|
||||
TClassDeclaration(Ruby::Class g) or
|
||||
TClassVariableAccessReal(Ruby::ClassVariable g, AST::ClassVariable v) {
|
||||
ClassVariableAccess::range(g, v)
|
||||
} or
|
||||
TClassVariableAccessSynth(AST::AstNode parent, int i, AST::ClassVariable v) {
|
||||
mkSynthChild(ClassVariableAccessKind(v), parent, i)
|
||||
} or
|
||||
TComplementExpr(Generated::Unary g) { g instanceof @unary_tilde } or
|
||||
TComplexLiteral(Generated::Complex g) or
|
||||
TDefinedExpr(Generated::Unary g) { g instanceof @unary_definedquestion } or
|
||||
TDelimitedSymbolLiteral(Generated::DelimitedSymbol g) or
|
||||
TDestructuredLeftAssignment(Generated::DestructuredLeftAssignment g) {
|
||||
not strictcount(int i | exists(g.getParent().(Generated::LeftAssignmentList).getChild(i))) = 1
|
||||
TComplementExpr(Ruby::Unary g) { g instanceof @ruby_unary_tilde } or
|
||||
TComplexLiteral(Ruby::Complex g) or
|
||||
TDefinedExpr(Ruby::Unary g) { g instanceof @ruby_unary_definedquestion } or
|
||||
TDelimitedSymbolLiteral(Ruby::DelimitedSymbol g) or
|
||||
TDestructuredLeftAssignment(Ruby::DestructuredLeftAssignment g) {
|
||||
not strictcount(int i | exists(g.getParent().(Ruby::LeftAssignmentList).getChild(i))) = 1
|
||||
} or
|
||||
TDivExprReal(Generated::Binary g) { g instanceof @binary_slash } or
|
||||
TDivExprReal(Ruby::Binary g) { g instanceof @ruby_binary_slash } or
|
||||
TDivExprSynth(AST::AstNode parent, int i) { mkSynthChild(DivExprKind(), parent, i) } or
|
||||
TDo(Generated::Do g) or
|
||||
TDoBlock(Generated::DoBlock g) { not g.getParent() instanceof Generated::Lambda } or
|
||||
TElementReference(Generated::ElementReference g) or
|
||||
TElse(Generated::Else g) or
|
||||
TElsif(Generated::Elsif g) or
|
||||
TEmptyStmt(Generated::EmptyStatement g) or
|
||||
TEndBlock(Generated::EndBlock g) or
|
||||
TEnsure(Generated::Ensure g) or
|
||||
TEqExpr(Generated::Binary g) { g instanceof @binary_equalequal } or
|
||||
TExponentExprReal(Generated::Binary g) { g instanceof @binary_starstar } or
|
||||
TDo(Ruby::Do g) or
|
||||
TDoBlock(Ruby::DoBlock g) { not g.getParent() instanceof Ruby::Lambda } or
|
||||
TElementReference(Ruby::ElementReference g) or
|
||||
TElse(Ruby::Else g) or
|
||||
TElsif(Ruby::Elsif g) or
|
||||
TEmptyStmt(Ruby::EmptyStatement g) or
|
||||
TEndBlock(Ruby::EndBlock g) or
|
||||
TEnsure(Ruby::Ensure g) or
|
||||
TEqExpr(Ruby::Binary g) { g instanceof @ruby_binary_equalequal } or
|
||||
TExponentExprReal(Ruby::Binary g) { g instanceof @ruby_binary_starstar } or
|
||||
TExponentExprSynth(AST::AstNode parent, int i) { mkSynthChild(ExponentExprKind(), parent, i) } or
|
||||
TFalseLiteral(Generated::False g) or
|
||||
TFloatLiteral(Generated::Float g) { not any(Generated::Rational r).getChild() = g } or
|
||||
TForExpr(Generated::For g) or
|
||||
TForIn(Generated::In g) or // TODO REMOVE
|
||||
TGEExpr(Generated::Binary g) { g instanceof @binary_rangleequal } or
|
||||
TGTExpr(Generated::Binary g) { g instanceof @binary_rangle } or
|
||||
TGlobalVariableAccessReal(Generated::GlobalVariable g, AST::GlobalVariable v) {
|
||||
TFalseLiteral(Ruby::False g) or
|
||||
TFloatLiteral(Ruby::Float g) { not any(Ruby::Rational r).getChild() = g } or
|
||||
TForExpr(Ruby::For g) or
|
||||
TForIn(Ruby::In g) or // TODO REMOVE
|
||||
TGEExpr(Ruby::Binary g) { g instanceof @ruby_binary_rangleequal } or
|
||||
TGTExpr(Ruby::Binary g) { g instanceof @ruby_binary_rangle } or
|
||||
TGlobalVariableAccessReal(Ruby::GlobalVariable g, AST::GlobalVariable v) {
|
||||
GlobalVariableAccess::range(g, v)
|
||||
} or
|
||||
TGlobalVariableAccessSynth(AST::AstNode parent, int i, AST::GlobalVariable v) {
|
||||
mkSynthChild(GlobalVariableAccessKind(v), parent, i)
|
||||
} or
|
||||
THashKeySymbolLiteral(Generated::HashKeySymbol g) or
|
||||
THashLiteral(Generated::Hash g) or
|
||||
THashSplatExpr(Generated::HashSplatArgument g) or
|
||||
THashSplatParameter(Generated::HashSplatParameter g) or
|
||||
THereDoc(Generated::HeredocBeginning g) or
|
||||
TIdentifierMethodCall(Generated::Identifier g) { isIdentifierMethodCall(g) } or
|
||||
TIf(Generated::If g) or
|
||||
TIfModifierExpr(Generated::IfModifier g) or
|
||||
TInstanceVariableAccessReal(Generated::InstanceVariable g, AST::InstanceVariable v) {
|
||||
THashKeySymbolLiteral(Ruby::HashKeySymbol g) or
|
||||
THashLiteral(Ruby::Hash g) or
|
||||
THashSplatExpr(Ruby::HashSplatArgument g) or
|
||||
THashSplatParameter(Ruby::HashSplatParameter g) or
|
||||
THereDoc(Ruby::HeredocBeginning g) or
|
||||
TIdentifierMethodCall(Ruby::Identifier g) { isIdentifierMethodCall(g) } or
|
||||
TIf(Ruby::If g) or
|
||||
TIfModifierExpr(Ruby::IfModifier g) or
|
||||
TInstanceVariableAccessReal(Ruby::InstanceVariable g, AST::InstanceVariable v) {
|
||||
InstanceVariableAccess::range(g, v)
|
||||
} or
|
||||
TInstanceVariableAccessSynth(AST::AstNode parent, int i, AST::InstanceVariable v) {
|
||||
mkSynthChild(InstanceVariableAccessKind(v), parent, i)
|
||||
} or
|
||||
TIntegerLiteralReal(Generated::Integer g) { not any(Generated::Rational r).getChild() = g } or
|
||||
TIntegerLiteralReal(Ruby::Integer g) { not any(Ruby::Rational r).getChild() = g } or
|
||||
TIntegerLiteralSynth(AST::AstNode parent, int i, int value) {
|
||||
mkSynthChild(IntegerLiteralKind(value), parent, i)
|
||||
} or
|
||||
TKeywordParameter(Generated::KeywordParameter g) or
|
||||
TLEExpr(Generated::Binary g) { g instanceof @binary_langleequal } or
|
||||
TLShiftExprReal(Generated::Binary g) { g instanceof @binary_langlelangle } or
|
||||
TKeywordParameter(Ruby::KeywordParameter g) or
|
||||
TLEExpr(Ruby::Binary g) { g instanceof @ruby_binary_langleequal } or
|
||||
TLShiftExprReal(Ruby::Binary g) { g instanceof @ruby_binary_langlelangle } or
|
||||
TLShiftExprSynth(AST::AstNode parent, int i) { mkSynthChild(LShiftExprKind(), parent, i) } or
|
||||
TLTExpr(Generated::Binary g) { g instanceof @binary_langle } or
|
||||
TLambda(Generated::Lambda g) or
|
||||
TLeftAssignmentList(Generated::LeftAssignmentList g) or
|
||||
TLocalVariableAccessReal(Generated::Identifier g, AST::LocalVariable v) {
|
||||
TLTExpr(Ruby::Binary g) { g instanceof @ruby_binary_langle } or
|
||||
TLambda(Ruby::Lambda g) or
|
||||
TLeftAssignmentList(Ruby::LeftAssignmentList g) or
|
||||
TLocalVariableAccessReal(Ruby::Identifier g, AST::LocalVariable v) {
|
||||
LocalVariableAccess::range(g, v)
|
||||
} or
|
||||
TLocalVariableAccessSynth(AST::AstNode parent, int i, AST::LocalVariable v) {
|
||||
@@ -169,52 +170,52 @@ private module Cached {
|
||||
or
|
||||
mkSynthChild(LocalVariableAccessSynthKind(v), parent, i)
|
||||
} or
|
||||
TLogicalAndExprReal(Generated::Binary g) {
|
||||
g instanceof @binary_and or g instanceof @binary_ampersandampersand
|
||||
TLogicalAndExprReal(Ruby::Binary g) {
|
||||
g instanceof @ruby_binary_and or g instanceof @ruby_binary_ampersandampersand
|
||||
} or
|
||||
TLogicalAndExprSynth(AST::AstNode parent, int i) {
|
||||
mkSynthChild(LogicalAndExprKind(), parent, i)
|
||||
} or
|
||||
TLogicalOrExprReal(Generated::Binary g) {
|
||||
g instanceof @binary_or or g instanceof @binary_pipepipe
|
||||
TLogicalOrExprReal(Ruby::Binary g) {
|
||||
g instanceof @ruby_binary_or or g instanceof @ruby_binary_pipepipe
|
||||
} or
|
||||
TLogicalOrExprSynth(AST::AstNode parent, int i) { mkSynthChild(LogicalOrExprKind(), parent, i) } or
|
||||
TMethod(Generated::Method g) or
|
||||
TMethod(Ruby::Method g) or
|
||||
TMethodCallSynth(AST::AstNode parent, int i, string name, boolean setter, int arity) {
|
||||
mkSynthChild(MethodCallKind(name, setter, arity), parent, i)
|
||||
} or
|
||||
TModuleDeclaration(Generated::Module g) or
|
||||
TModuloExprReal(Generated::Binary g) { g instanceof @binary_percent } or
|
||||
TModuleDeclaration(Ruby::Module g) or
|
||||
TModuloExprReal(Ruby::Binary g) { g instanceof @ruby_binary_percent } or
|
||||
TModuloExprSynth(AST::AstNode parent, int i) { mkSynthChild(ModuloExprKind(), parent, i) } or
|
||||
TMulExprReal(Generated::Binary g) { g instanceof @binary_star } or
|
||||
TMulExprReal(Ruby::Binary g) { g instanceof @ruby_binary_star } or
|
||||
TMulExprSynth(AST::AstNode parent, int i) { mkSynthChild(MulExprKind(), parent, i) } or
|
||||
TNEExpr(Generated::Binary g) { g instanceof @binary_bangequal } or
|
||||
TNextStmt(Generated::Next g) or
|
||||
TNilLiteral(Generated::Nil g) or
|
||||
TNoRegExpMatchExpr(Generated::Binary g) { g instanceof @binary_bangtilde } or
|
||||
TNotExpr(Generated::Unary g) { g instanceof @unary_bang or g instanceof @unary_not } or
|
||||
TOptionalParameter(Generated::OptionalParameter g) or
|
||||
TPair(Generated::Pair g) or
|
||||
TParenthesizedExpr(Generated::ParenthesizedStatements g) or
|
||||
TRShiftExprReal(Generated::Binary g) { g instanceof @binary_ranglerangle } or
|
||||
TNEExpr(Ruby::Binary g) { g instanceof @ruby_binary_bangequal } or
|
||||
TNextStmt(Ruby::Next g) or
|
||||
TNilLiteral(Ruby::Nil g) or
|
||||
TNoRegExpMatchExpr(Ruby::Binary g) { g instanceof @ruby_binary_bangtilde } or
|
||||
TNotExpr(Ruby::Unary g) { g instanceof @ruby_unary_bang or g instanceof @ruby_unary_not } or
|
||||
TOptionalParameter(Ruby::OptionalParameter g) or
|
||||
TPair(Ruby::Pair g) or
|
||||
TParenthesizedExpr(Ruby::ParenthesizedStatements g) or
|
||||
TRShiftExprReal(Ruby::Binary g) { g instanceof @ruby_binary_ranglerangle } or
|
||||
TRShiftExprSynth(AST::AstNode parent, int i) { mkSynthChild(RShiftExprKind(), parent, i) } or
|
||||
TRangeLiteralReal(Generated::Range g) or
|
||||
TRangeLiteralReal(Ruby::Range g) or
|
||||
TRangeLiteralSynth(AST::AstNode parent, int i, boolean inclusive) {
|
||||
mkSynthChild(RangeLiteralKind(inclusive), parent, i)
|
||||
} or
|
||||
TRationalLiteral(Generated::Rational g) or
|
||||
TRedoStmt(Generated::Redo g) or
|
||||
TRegExpLiteral(Generated::Regex g) or
|
||||
TRegExpMatchExpr(Generated::Binary g) { g instanceof @binary_equaltilde } or
|
||||
TRegularArrayLiteral(Generated::Array g) or
|
||||
TRegularMethodCall(Generated::Call g) { isRegularMethodCall(g) } or
|
||||
TRegularStringLiteral(Generated::String g) or
|
||||
TRegularSuperCall(Generated::Call g) { g.getMethod() instanceof Generated::Super } or
|
||||
TRescueClause(Generated::Rescue g) or
|
||||
TRescueModifierExpr(Generated::RescueModifier g) or
|
||||
TRetryStmt(Generated::Retry g) or
|
||||
TReturnStmt(Generated::Return g) or
|
||||
TScopeResolutionConstantAccess(Generated::ScopeResolution g, Generated::Constant constant) {
|
||||
TRationalLiteral(Ruby::Rational g) or
|
||||
TRedoStmt(Ruby::Redo g) or
|
||||
TRegExpLiteral(Ruby::Regex g) or
|
||||
TRegExpMatchExpr(Ruby::Binary g) { g instanceof @ruby_binary_equaltilde } or
|
||||
TRegularArrayLiteral(Ruby::Array g) or
|
||||
TRegularMethodCall(Ruby::Call g) { isRegularMethodCall(g) } or
|
||||
TRegularStringLiteral(Ruby::String g) or
|
||||
TRegularSuperCall(Ruby::Call g) { g.getMethod() instanceof Ruby::Super } or
|
||||
TRescueClause(Ruby::Rescue g) or
|
||||
TRescueModifierExpr(Ruby::RescueModifier g) or
|
||||
TRetryStmt(Ruby::Retry g) or
|
||||
TReturnStmt(Ruby::Return g) or
|
||||
TScopeResolutionConstantAccess(Ruby::ScopeResolution g, Ruby::Constant constant) {
|
||||
constant = g.getName() and
|
||||
(
|
||||
// A tree-sitter `scope_resolution` node with a `constant` name field is a
|
||||
@@ -225,34 +226,34 @@ private module Cached {
|
||||
explicitAssignmentNode(g, _)
|
||||
)
|
||||
} or
|
||||
TScopeResolutionMethodCall(Generated::ScopeResolution g, Generated::Identifier i) {
|
||||
TScopeResolutionMethodCall(Ruby::ScopeResolution g, Ruby::Identifier i) {
|
||||
isScopeResolutionMethodCall(g, i)
|
||||
} or
|
||||
TSelfReal(Generated::Self g) or
|
||||
TSelfReal(Ruby::Self g) or
|
||||
TSelfSynth(AST::AstNode parent, int i) { mkSynthChild(SelfKind(), parent, i) } or
|
||||
TSimpleParameter(Generated::Identifier g) { g instanceof Parameter::Range } or
|
||||
TSimpleSymbolLiteral(Generated::SimpleSymbol g) or
|
||||
TSingletonClass(Generated::SingletonClass g) or
|
||||
TSingletonMethod(Generated::SingletonMethod g) or
|
||||
TSpaceshipExpr(Generated::Binary g) { g instanceof @binary_langleequalrangle } or
|
||||
TSplatExprReal(Generated::SplatArgument g) or
|
||||
TSimpleParameter(Ruby::Identifier g) { g instanceof Parameter::Range } or
|
||||
TSimpleSymbolLiteral(Ruby::SimpleSymbol g) or
|
||||
TSingletonClass(Ruby::SingletonClass g) or
|
||||
TSingletonMethod(Ruby::SingletonMethod g) or
|
||||
TSpaceshipExpr(Ruby::Binary g) { g instanceof @ruby_binary_langleequalrangle } or
|
||||
TSplatExprReal(Ruby::SplatArgument g) or
|
||||
TSplatExprSynth(AST::AstNode parent, int i) { mkSynthChild(SplatExprKind(), parent, i) } or
|
||||
TSplatParameter(Generated::SplatParameter g) or
|
||||
TSplatParameter(Ruby::SplatParameter g) or
|
||||
TStmtSequenceSynth(AST::AstNode parent, int i) { mkSynthChild(StmtSequenceKind(), parent, i) } or
|
||||
TStringArrayLiteral(Generated::StringArray g) or
|
||||
TStringConcatenation(Generated::ChainedString g) or
|
||||
TStringEscapeSequenceComponent(Generated::EscapeSequence g) or
|
||||
TStringInterpolationComponent(Generated::Interpolation g) or
|
||||
TStringTextComponent(Generated::Token g) {
|
||||
g instanceof Generated::StringContent or g instanceof Generated::HeredocContent
|
||||
TStringArrayLiteral(Ruby::StringArray g) or
|
||||
TStringConcatenation(Ruby::ChainedString g) or
|
||||
TStringEscapeSequenceComponent(Ruby::EscapeSequence g) or
|
||||
TStringInterpolationComponent(Ruby::Interpolation g) or
|
||||
TStringTextComponent(Ruby::Token g) {
|
||||
g instanceof Ruby::StringContent or g instanceof Ruby::HeredocContent
|
||||
} or
|
||||
TSubExprReal(Generated::Binary g) { g instanceof @binary_minus } or
|
||||
TSubExprReal(Ruby::Binary g) { g instanceof @ruby_binary_minus } or
|
||||
TSubExprSynth(AST::AstNode parent, int i) { mkSynthChild(SubExprKind(), parent, i) } or
|
||||
TSubshellLiteral(Generated::Subshell g) or
|
||||
TSymbolArrayLiteral(Generated::SymbolArray g) or
|
||||
TTernaryIfExpr(Generated::Conditional g) or
|
||||
TThen(Generated::Then g) or
|
||||
TTokenConstantAccess(Generated::Constant g) {
|
||||
TSubshellLiteral(Ruby::Subshell g) or
|
||||
TSymbolArrayLiteral(Ruby::SymbolArray g) or
|
||||
TTernaryIfExpr(Ruby::Conditional g) or
|
||||
TThen(Ruby::Then g) or
|
||||
TTokenConstantAccess(Ruby::Constant g) {
|
||||
// A tree-sitter `constant` token is a read of that constant in any context
|
||||
// where an identifier would be a vcall.
|
||||
vcall(g)
|
||||
@@ -260,21 +261,21 @@ private module Cached {
|
||||
explicitAssignmentNode(g, _)
|
||||
} or
|
||||
TTokenMethodName(MethodName::Token g) { MethodName::range(g) } or
|
||||
TTokenSuperCall(Generated::Super g) { vcall(g) } or
|
||||
TToplevel(Generated::Program g) { g.getLocation().getFile().getExtension() != "erb" } or
|
||||
TTrueLiteral(Generated::True g) or
|
||||
TTuplePatternParameter(Generated::DestructuredParameter g) or
|
||||
TUnaryMinusExpr(Generated::Unary g) { g instanceof @unary_minus } or
|
||||
TUnaryPlusExpr(Generated::Unary g) { g instanceof @unary_plus } or
|
||||
TUndefStmt(Generated::Undef g) or
|
||||
TUnlessExpr(Generated::Unless g) or
|
||||
TUnlessModifierExpr(Generated::UnlessModifier g) or
|
||||
TUntilExpr(Generated::Until g) or
|
||||
TUntilModifierExpr(Generated::UntilModifier g) or
|
||||
TWhenExpr(Generated::When g) or
|
||||
TWhileExpr(Generated::While g) or
|
||||
TWhileModifierExpr(Generated::WhileModifier g) or
|
||||
TYieldCall(Generated::Yield g)
|
||||
TTokenSuperCall(Ruby::Super g) { vcall(g) } or
|
||||
TToplevel(Ruby::Program g) { g.getLocation().getFile().getExtension() != "erb" } or
|
||||
TTrueLiteral(Ruby::True g) or
|
||||
TTuplePatternParameter(Ruby::DestructuredParameter g) or
|
||||
TUnaryMinusExpr(Ruby::Unary g) { g instanceof @ruby_unary_minus } or
|
||||
TUnaryPlusExpr(Ruby::Unary g) { g instanceof @ruby_unary_plus } or
|
||||
TUndefStmt(Ruby::Undef g) or
|
||||
TUnlessExpr(Ruby::Unless g) or
|
||||
TUnlessModifierExpr(Ruby::UnlessModifier g) or
|
||||
TUntilExpr(Ruby::Until g) or
|
||||
TUntilModifierExpr(Ruby::UntilModifier g) or
|
||||
TWhenExpr(Ruby::When g) or
|
||||
TWhileExpr(Ruby::While g) or
|
||||
TWhileModifierExpr(Ruby::WhileModifier g) or
|
||||
TYieldCall(Ruby::Yield g)
|
||||
|
||||
/**
|
||||
* Gets the underlying TreeSitter entity for a given AST node. This does not
|
||||
@@ -282,7 +283,7 @@ private module Cached {
|
||||
* for any given generated node.
|
||||
*/
|
||||
cached
|
||||
Generated::AstNode toGenerated(AST::AstNode n) {
|
||||
Ruby::AstNode toGenerated(AST::AstNode n) {
|
||||
n = TAddExprReal(result) or
|
||||
n = TAliasStmt(result) or
|
||||
n = TArgumentList(result) or
|
||||
@@ -491,7 +492,7 @@ private module Cached {
|
||||
* nodes.
|
||||
*/
|
||||
cached
|
||||
Generated::AstNode toGeneratedInclSynth(AST::AstNode n) {
|
||||
Ruby::AstNode toGeneratedInclSynth(AST::AstNode n) {
|
||||
result = toGenerated(n)
|
||||
or
|
||||
not exists(toGenerated(n)) and
|
||||
@@ -515,7 +516,7 @@ private module Cached {
|
||||
|
||||
import Cached
|
||||
|
||||
TAstNode fromGenerated(Generated::AstNode n) { n = toGenerated(result) }
|
||||
TAstNode fromGenerated(Ruby::AstNode n) { n = toGenerated(result) }
|
||||
|
||||
class TCall = TMethodCall or TYieldCall;
|
||||
|
||||
|
||||
@@ -3,13 +3,13 @@ private import Variable
|
||||
private import codeql_ruby.AST
|
||||
private import codeql_ruby.ast.internal.AST
|
||||
|
||||
predicate isIdentifierMethodCall(Generated::Identifier g) { vcall(g) and not access(g, _) }
|
||||
predicate isIdentifierMethodCall(Ruby::Identifier g) { vcall(g) and not access(g, _) }
|
||||
|
||||
predicate isRegularMethodCall(Generated::Call g) { not g.getMethod() instanceof Generated::Super }
|
||||
predicate isRegularMethodCall(Ruby::Call g) { not g.getMethod() instanceof Ruby::Super }
|
||||
|
||||
predicate isScopeResolutionMethodCall(Generated::ScopeResolution g, Generated::Identifier i) {
|
||||
predicate isScopeResolutionMethodCall(Ruby::ScopeResolution g, Ruby::Identifier i) {
|
||||
i = g.getName() and
|
||||
not exists(Generated::Call c | c.getMethod() = g)
|
||||
not exists(Ruby::Call c | c.getMethod() = g)
|
||||
}
|
||||
|
||||
abstract class CallImpl extends Call {
|
||||
@@ -50,7 +50,7 @@ class MethodCallSynth extends MethodCallImpl, TMethodCallSynth {
|
||||
}
|
||||
|
||||
class IdentifierMethodCall extends MethodCallImpl, TIdentifierMethodCall {
|
||||
private Generated::Identifier g;
|
||||
private Ruby::Identifier g;
|
||||
|
||||
IdentifierMethodCall() { this = TIdentifierMethodCall(g) }
|
||||
|
||||
@@ -64,8 +64,8 @@ class IdentifierMethodCall extends MethodCallImpl, TIdentifierMethodCall {
|
||||
}
|
||||
|
||||
class ScopeResolutionMethodCall extends MethodCallImpl, TScopeResolutionMethodCall {
|
||||
private Generated::ScopeResolution g;
|
||||
private Generated::Identifier i;
|
||||
private Ruby::ScopeResolution g;
|
||||
private Ruby::Identifier i;
|
||||
|
||||
ScopeResolutionMethodCall() { this = TScopeResolutionMethodCall(g, i) }
|
||||
|
||||
@@ -79,7 +79,7 @@ class ScopeResolutionMethodCall extends MethodCallImpl, TScopeResolutionMethodCa
|
||||
}
|
||||
|
||||
class RegularMethodCall extends MethodCallImpl, TRegularMethodCall {
|
||||
private Generated::Call g;
|
||||
private Ruby::Call g;
|
||||
|
||||
RegularMethodCall() { this = TRegularMethodCall(g) }
|
||||
|
||||
@@ -87,7 +87,7 @@ class RegularMethodCall extends MethodCallImpl, TRegularMethodCall {
|
||||
toGenerated(result) = g.getReceiver()
|
||||
or
|
||||
not exists(g.getReceiver()) and
|
||||
toGenerated(result) = g.getMethod().(Generated::ScopeResolution).getScope()
|
||||
toGenerated(result) = g.getMethod().(Ruby::ScopeResolution).getScope()
|
||||
or
|
||||
result = TSelfSynth(this, 0)
|
||||
}
|
||||
@@ -95,31 +95,30 @@ class RegularMethodCall extends MethodCallImpl, TRegularMethodCall {
|
||||
final override string getMethodNameImpl() {
|
||||
isRegularMethodCall(g) and
|
||||
(
|
||||
result = "call" and g.getMethod() instanceof Generated::ArgumentList
|
||||
result = "call" and g.getMethod() instanceof Ruby::ArgumentList
|
||||
or
|
||||
result = g.getMethod().(Generated::Token).getValue()
|
||||
result = g.getMethod().(Ruby::Token).getValue()
|
||||
or
|
||||
result = g.getMethod().(Generated::ScopeResolution).getName().(Generated::Token).getValue()
|
||||
result = g.getMethod().(Ruby::ScopeResolution).getName().(Ruby::Token).getValue()
|
||||
)
|
||||
}
|
||||
|
||||
final override Expr getArgumentImpl(int n) {
|
||||
toGenerated(result) = g.getArguments().getChild(n)
|
||||
or
|
||||
toGenerated(result) = g.getMethod().(Generated::ArgumentList).getChild(n)
|
||||
toGenerated(result) = g.getMethod().(Ruby::ArgumentList).getChild(n)
|
||||
}
|
||||
|
||||
final override int getNumberOfArgumentsImpl() {
|
||||
result =
|
||||
count(g.getArguments().getChild(_)) +
|
||||
count(g.getMethod().(Generated::ArgumentList).getChild(_))
|
||||
count(g.getArguments().getChild(_)) + count(g.getMethod().(Ruby::ArgumentList).getChild(_))
|
||||
}
|
||||
|
||||
final override Block getBlock() { toGenerated(result) = g.getBlock() }
|
||||
}
|
||||
|
||||
class ElementReferenceImpl extends MethodCallImpl, TElementReference {
|
||||
private Generated::ElementReference g;
|
||||
private Ruby::ElementReference g;
|
||||
|
||||
ElementReferenceImpl() { this = TElementReference(g) }
|
||||
|
||||
@@ -133,7 +132,7 @@ class ElementReferenceImpl extends MethodCallImpl, TElementReference {
|
||||
}
|
||||
|
||||
class TokenSuperCall extends SuperCall, MethodCallImpl, TTokenSuperCall {
|
||||
private Generated::Super g;
|
||||
private Ruby::Super g;
|
||||
|
||||
TokenSuperCall() { this = TTokenSuperCall(g) }
|
||||
|
||||
@@ -147,11 +146,11 @@ class TokenSuperCall extends SuperCall, MethodCallImpl, TTokenSuperCall {
|
||||
}
|
||||
|
||||
class RegularSuperCall extends SuperCall, MethodCallImpl, TRegularSuperCall {
|
||||
private Generated::Call g;
|
||||
private Ruby::Call g;
|
||||
|
||||
RegularSuperCall() { this = TRegularSuperCall(g) }
|
||||
|
||||
final override string getMethodNameImpl() { result = g.getMethod().(Generated::Super).getValue() }
|
||||
final override string getMethodNameImpl() { result = g.getMethod().(Ruby::Super).getValue() }
|
||||
|
||||
final override Expr getReceiverImpl() { none() }
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ class AssignmentImpl extends Operation, TAssignment {
|
||||
}
|
||||
|
||||
class AssignExprReal extends AssignmentImpl, AssignExpr, TAssignExprReal {
|
||||
private Generated::Assignment g;
|
||||
private Ruby::Assignment g;
|
||||
|
||||
AssignExprReal() { this = TAssignExprReal(g) }
|
||||
|
||||
@@ -35,7 +35,7 @@ abstract class SplatExprImpl extends SplatExpr {
|
||||
}
|
||||
|
||||
class SplatExprReal extends SplatExprImpl, TSplatExprReal {
|
||||
private Generated::SplatArgument g;
|
||||
private Ruby::SplatArgument g;
|
||||
|
||||
SplatExprReal() { this = TSplatExprReal(g) }
|
||||
|
||||
|
||||
@@ -3,15 +3,15 @@ private import AST
|
||||
private import TreeSitter
|
||||
|
||||
module Parameter {
|
||||
class Range extends Generated::AstNode {
|
||||
class Range extends Ruby::AstNode {
|
||||
private int pos;
|
||||
|
||||
Range() {
|
||||
this = any(Generated::BlockParameters bp).getChild(pos)
|
||||
this = any(Ruby::BlockParameters bp).getChild(pos)
|
||||
or
|
||||
this = any(Generated::MethodParameters mp).getChild(pos)
|
||||
this = any(Ruby::MethodParameters mp).getChild(pos)
|
||||
or
|
||||
this = any(Generated::LambdaParameters lp).getChild(pos)
|
||||
this = any(Ruby::LambdaParameters lp).getChild(pos)
|
||||
}
|
||||
|
||||
int getPosition() { result = pos }
|
||||
|
||||
@@ -2,30 +2,30 @@ private import codeql_ruby.AST
|
||||
private import AST
|
||||
private import TreeSitter
|
||||
|
||||
abstract class TuplePatternImpl extends Generated::AstNode {
|
||||
abstract Generated::AstNode getChildNode(int i);
|
||||
abstract class TuplePatternImpl extends Ruby::AstNode {
|
||||
abstract Ruby::AstNode getChildNode(int i);
|
||||
|
||||
final int getRestIndex() {
|
||||
result = unique(int i | this.getChildNode(i) instanceof Generated::RestAssignment)
|
||||
result = unique(int i | this.getChildNode(i) instanceof Ruby::RestAssignment)
|
||||
}
|
||||
}
|
||||
|
||||
class TuplePatternParameterImpl extends TuplePatternImpl, Generated::DestructuredParameter {
|
||||
override Generated::AstNode getChildNode(int i) { result = this.getChild(i) }
|
||||
class TuplePatternParameterImpl extends TuplePatternImpl, Ruby::DestructuredParameter {
|
||||
override Ruby::AstNode getChildNode(int i) { result = this.getChild(i) }
|
||||
}
|
||||
|
||||
class DestructuredLeftAssignmentImpl extends TuplePatternImpl, Generated::DestructuredLeftAssignment {
|
||||
override Generated::AstNode getChildNode(int i) { result = this.getChild(i) }
|
||||
class DestructuredLeftAssignmentImpl extends TuplePatternImpl, Ruby::DestructuredLeftAssignment {
|
||||
override Ruby::AstNode getChildNode(int i) { result = this.getChild(i) }
|
||||
}
|
||||
|
||||
class LeftAssignmentListImpl extends TuplePatternImpl, Generated::LeftAssignmentList {
|
||||
override Generated::AstNode getChildNode(int i) {
|
||||
class LeftAssignmentListImpl extends TuplePatternImpl, Ruby::LeftAssignmentList {
|
||||
override Ruby::AstNode getChildNode(int i) {
|
||||
this =
|
||||
any(Generated::LeftAssignmentList lal |
|
||||
any(Ruby::LeftAssignmentList lal |
|
||||
if
|
||||
strictcount(int j | exists(lal.getChild(j))) = 1 and
|
||||
lal.getChild(0) instanceof Generated::DestructuredLeftAssignment
|
||||
then result = lal.getChild(0).(Generated::DestructuredLeftAssignment).getChild(i)
|
||||
lal.getChild(0) instanceof Ruby::DestructuredLeftAssignment
|
||||
then result = lal.getChild(0).(Ruby::DestructuredLeftAssignment).getChild(i)
|
||||
else result = lal.getChild(i)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -10,10 +10,10 @@ private class TBlockLike = TDoBlock or TLambda or TBlock or TEndBlock;
|
||||
private class TModuleLike = TToplevel or TModuleDeclaration or TClassDeclaration or TSingletonClass;
|
||||
|
||||
module Scope {
|
||||
class TypeRange = Callable::TypeRange or ModuleBase::TypeRange or @end_block;
|
||||
class TypeRange = Callable::TypeRange or ModuleBase::TypeRange or @ruby_end_block;
|
||||
|
||||
class Range extends Generated::AstNode, TypeRange {
|
||||
Range() { not this = any(Generated::Lambda l).getBody() }
|
||||
class Range extends Ruby::AstNode, TypeRange {
|
||||
Range() { not this = any(Ruby::Lambda l).getBody() }
|
||||
|
||||
ModuleBase::Range getEnclosingModule() {
|
||||
result = this
|
||||
@@ -34,45 +34,45 @@ module Scope {
|
||||
}
|
||||
|
||||
module MethodBase {
|
||||
class TypeRange = @method or @singleton_method;
|
||||
class TypeRange = @ruby_method or @ruby_singleton_method;
|
||||
|
||||
class Range extends Scope::Range, TypeRange { }
|
||||
}
|
||||
|
||||
module Callable {
|
||||
class TypeRange = MethodBase::TypeRange or @do_block or @lambda or @block;
|
||||
class TypeRange = MethodBase::TypeRange or @ruby_do_block or @ruby_lambda or @ruby_block;
|
||||
|
||||
class Range extends Scope::Range, TypeRange {
|
||||
Parameter::Range getParameter(int i) {
|
||||
result = this.(Generated::Method).getParameters().getChild(i) or
|
||||
result = this.(Generated::SingletonMethod).getParameters().getChild(i) or
|
||||
result = this.(Generated::DoBlock).getParameters().getChild(i) or
|
||||
result = this.(Generated::Lambda).getParameters().getChild(i) or
|
||||
result = this.(Generated::Block).getParameters().getChild(i)
|
||||
result = this.(Ruby::Method).getParameters().getChild(i) or
|
||||
result = this.(Ruby::SingletonMethod).getParameters().getChild(i) or
|
||||
result = this.(Ruby::DoBlock).getParameters().getChild(i) or
|
||||
result = this.(Ruby::Lambda).getParameters().getChild(i) or
|
||||
result = this.(Ruby::Block).getParameters().getChild(i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module ModuleBase {
|
||||
class TypeRange = @program or @module or @class or @singleton_class;
|
||||
class TypeRange = @ruby_program or @ruby_module or @ruby_class or @ruby_singleton_class;
|
||||
|
||||
class Range extends Scope::Range, TypeRange { }
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate rankHeredocBody(File f, Generated::HeredocBody b, int i) {
|
||||
private predicate rankHeredocBody(File f, Ruby::HeredocBody b, int i) {
|
||||
b =
|
||||
rank[i](Generated::HeredocBody b0 |
|
||||
rank[i](Ruby::HeredocBody b0 |
|
||||
f = b0.getLocation().getFile()
|
||||
|
|
||||
b0 order by b0.getLocation().getStartLine(), b0.getLocation().getStartColumn()
|
||||
)
|
||||
}
|
||||
|
||||
Generated::HeredocBody getHereDocBody(Generated::HeredocBeginning g) {
|
||||
Ruby::HeredocBody getHereDocBody(Ruby::HeredocBeginning g) {
|
||||
exists(int i, File f |
|
||||
g =
|
||||
rank[i](Generated::HeredocBeginning b |
|
||||
rank[i](Ruby::HeredocBeginning b |
|
||||
f = b.getLocation().getFile()
|
||||
|
|
||||
b order by b.getLocation().getStartLine(), b.getLocation().getStartColumn()
|
||||
@@ -81,17 +81,17 @@ Generated::HeredocBody getHereDocBody(Generated::HeredocBeginning g) {
|
||||
)
|
||||
}
|
||||
|
||||
private Generated::AstNode parentOf(Generated::AstNode n) {
|
||||
private Ruby::AstNode parentOf(Ruby::AstNode n) {
|
||||
n = getHereDocBody(result)
|
||||
or
|
||||
exists(Generated::AstNode parent | parent = n.getParent() |
|
||||
exists(Ruby::AstNode parent | parent = n.getParent() |
|
||||
if
|
||||
n =
|
||||
[
|
||||
parent.(Generated::Module).getName(), parent.(Generated::Class).getName(),
|
||||
parent.(Generated::Class).getSuperclass(), parent.(Generated::SingletonClass).getValue(),
|
||||
parent.(Generated::Method).getName(), parent.(Generated::SingletonMethod).getName(),
|
||||
parent.(Generated::SingletonMethod).getObject()
|
||||
parent.(Ruby::Module).getName(), parent.(Ruby::Class).getName(),
|
||||
parent.(Ruby::Class).getSuperclass(), parent.(Ruby::SingletonClass).getValue(),
|
||||
parent.(Ruby::Method).getName(), parent.(Ruby::SingletonMethod).getName(),
|
||||
parent.(Ruby::SingletonMethod).getObject()
|
||||
]
|
||||
then result = parent.getParent()
|
||||
else result = parent
|
||||
@@ -100,8 +100,8 @@ private Generated::AstNode parentOf(Generated::AstNode n) {
|
||||
|
||||
/** Gets the enclosing scope of a node */
|
||||
cached
|
||||
Scope::Range scopeOf(Generated::AstNode n) {
|
||||
exists(Generated::AstNode p | p = parentOf(n) |
|
||||
Scope::Range scopeOf(Ruby::AstNode n) {
|
||||
exists(Ruby::AstNode p | p = parentOf(n) |
|
||||
p = result
|
||||
or
|
||||
not p instanceof Scope::Range and result = scopeOf(p)
|
||||
|
||||
@@ -149,13 +149,13 @@ private module ImplicitSelfSynthesis {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate regularMethodCallSelfSynthesis(TRegularMethodCall mc, int i, Child child) {
|
||||
exists(Generated::AstNode g |
|
||||
exists(Ruby::AstNode g |
|
||||
mc = TRegularMethodCall(g) and
|
||||
// If there's no explicit receiver (or scope resolution that acts like a
|
||||
// receiver), then the receiver is implicitly `self`. N.B. `::Foo()` is
|
||||
// not valid Ruby.
|
||||
not exists(g.(Generated::Call).getReceiver()) and
|
||||
not exists(g.(Generated::Call).getMethod().(Generated::ScopeResolution).getScope())
|
||||
not exists(g.(Ruby::Call).getReceiver()) and
|
||||
not exists(g.(Ruby::Call).getMethod().(Ruby::ScopeResolution).getScope())
|
||||
) and
|
||||
child = SynthChild(SelfKind()) and
|
||||
i = 0
|
||||
@@ -316,7 +316,7 @@ private module AssignOperationDesugar {
|
||||
}
|
||||
|
||||
private Location getAssignOperationLocation(AssignOperation ao) {
|
||||
exists(Generated::OperatorAssignment g, Generated::Token op |
|
||||
exists(Ruby::OperatorAssignment g, Ruby::Token op |
|
||||
g = toGenerated(ao) and
|
||||
op.getParent() = g and
|
||||
op.getParentIndex() = 1 and
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,73 +9,73 @@ private import codeql_ruby.ast.internal.Synthesis
|
||||
/**
|
||||
* Holds if `n` is in the left-hand-side of an explicit assignment `assignment`.
|
||||
*/
|
||||
predicate explicitAssignmentNode(Generated::AstNode n, Generated::AstNode assignment) {
|
||||
n = assignment.(Generated::Assignment).getLeft()
|
||||
predicate explicitAssignmentNode(Ruby::AstNode n, Ruby::AstNode assignment) {
|
||||
n = assignment.(Ruby::Assignment).getLeft()
|
||||
or
|
||||
n = assignment.(Generated::OperatorAssignment).getLeft()
|
||||
n = assignment.(Ruby::OperatorAssignment).getLeft()
|
||||
or
|
||||
exists(Generated::AstNode parent |
|
||||
exists(Ruby::AstNode parent |
|
||||
parent = n.getParent() and
|
||||
explicitAssignmentNode(parent, assignment)
|
||||
|
|
||||
parent instanceof Generated::DestructuredLeftAssignment
|
||||
parent instanceof Ruby::DestructuredLeftAssignment
|
||||
or
|
||||
parent instanceof Generated::LeftAssignmentList
|
||||
parent instanceof Ruby::LeftAssignmentList
|
||||
or
|
||||
parent instanceof Generated::RestAssignment
|
||||
parent instanceof Ruby::RestAssignment
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `n` is inside an implicit assignment. */
|
||||
predicate implicitAssignmentNode(Generated::AstNode n) {
|
||||
n = any(Generated::ExceptionVariable ev).getChild()
|
||||
predicate implicitAssignmentNode(Ruby::AstNode n) {
|
||||
n = any(Ruby::ExceptionVariable ev).getChild()
|
||||
or
|
||||
n = any(Generated::For for).getPattern()
|
||||
n = any(Ruby::For for).getPattern()
|
||||
or
|
||||
implicitAssignmentNode(n.getParent())
|
||||
}
|
||||
|
||||
/** Holds if `n` is inside a parameter. */
|
||||
predicate implicitParameterAssignmentNode(Generated::AstNode n, Callable::Range c) {
|
||||
predicate implicitParameterAssignmentNode(Ruby::AstNode n, Callable::Range c) {
|
||||
n = c.getParameter(_)
|
||||
or
|
||||
implicitParameterAssignmentNode(n.getParent().(Generated::DestructuredParameter), c)
|
||||
implicitParameterAssignmentNode(n.getParent().(Ruby::DestructuredParameter), c)
|
||||
}
|
||||
|
||||
private predicate instanceVariableAccess(
|
||||
Generated::InstanceVariable var, string name, Scope::Range scope, boolean instance
|
||||
Ruby::InstanceVariable var, string name, Scope::Range scope, boolean instance
|
||||
) {
|
||||
name = var.getValue() and
|
||||
scope = enclosingModuleOrClass(var) and
|
||||
if hasEnclosingMethod(var) then instance = true else instance = false
|
||||
}
|
||||
|
||||
private predicate classVariableAccess(Generated::ClassVariable var, string name, Scope::Range scope) {
|
||||
private predicate classVariableAccess(Ruby::ClassVariable var, string name, Scope::Range scope) {
|
||||
name = var.getValue() and
|
||||
scope = enclosingModuleOrClass(var)
|
||||
}
|
||||
|
||||
private predicate hasEnclosingMethod(Generated::AstNode node) {
|
||||
private predicate hasEnclosingMethod(Ruby::AstNode node) {
|
||||
exists(Scope::Range s | scopeOf(node) = s and exists(s.getEnclosingMethod()))
|
||||
}
|
||||
|
||||
private ModuleBase::Range enclosingModuleOrClass(Generated::AstNode node) {
|
||||
private ModuleBase::Range enclosingModuleOrClass(Ruby::AstNode node) {
|
||||
exists(Scope::Range s | scopeOf(node) = s and result = s.getEnclosingModule())
|
||||
}
|
||||
|
||||
private predicate parameterAssignment(Callable::Range scope, string name, Generated::Identifier i) {
|
||||
private predicate parameterAssignment(Callable::Range scope, string name, Ruby::Identifier i) {
|
||||
implicitParameterAssignmentNode(i, scope) and
|
||||
name = i.getValue()
|
||||
}
|
||||
|
||||
/** Holds if `scope` defines `name` in its parameter declaration at `i`. */
|
||||
private predicate scopeDefinesParameterVariable(
|
||||
Callable::Range scope, string name, Generated::Identifier i
|
||||
Callable::Range scope, string name, Ruby::Identifier i
|
||||
) {
|
||||
// In case of overlapping parameter names (e.g. `_`), only the first
|
||||
// parameter will give rise to a variable
|
||||
i =
|
||||
min(Generated::Identifier other |
|
||||
min(Ruby::Identifier other |
|
||||
parameterAssignment(scope, name, other)
|
||||
|
|
||||
other order by other.getLocation().getStartLine(), other.getLocation().getStartColumn()
|
||||
@@ -85,16 +85,16 @@ private predicate scopeDefinesParameterVariable(
|
||||
p = scope.getParameter(_) and
|
||||
name = i.getValue()
|
||||
|
|
||||
i = p.(Generated::BlockParameter).getName() or
|
||||
i = p.(Generated::HashSplatParameter).getName() or
|
||||
i = p.(Generated::KeywordParameter).getName() or
|
||||
i = p.(Generated::OptionalParameter).getName() or
|
||||
i = p.(Generated::SplatParameter).getName()
|
||||
i = p.(Ruby::BlockParameter).getName() or
|
||||
i = p.(Ruby::HashSplatParameter).getName() or
|
||||
i = p.(Ruby::KeywordParameter).getName() or
|
||||
i = p.(Ruby::OptionalParameter).getName() or
|
||||
i = p.(Ruby::SplatParameter).getName()
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `name` is assigned in `scope` at `i`. */
|
||||
private predicate scopeAssigns(Scope::Range scope, string name, Generated::Identifier i) {
|
||||
private predicate scopeAssigns(Scope::Range scope, string name, Ruby::Identifier i) {
|
||||
(explicitAssignmentNode(i, _) or implicitAssignmentNode(i)) and
|
||||
name = i.getValue() and
|
||||
scope = scopeOf(i)
|
||||
@@ -112,28 +112,28 @@ cached
|
||||
private module Cached {
|
||||
cached
|
||||
newtype TVariable =
|
||||
TGlobalVariable(string name) { name = any(Generated::GlobalVariable var).getValue() } or
|
||||
TClassVariable(Scope::Range scope, string name, Generated::AstNode decl) {
|
||||
TGlobalVariable(string name) { name = any(Ruby::GlobalVariable var).getValue() } or
|
||||
TClassVariable(Scope::Range scope, string name, Ruby::AstNode decl) {
|
||||
decl =
|
||||
min(Generated::ClassVariable other |
|
||||
min(Ruby::ClassVariable other |
|
||||
classVariableAccess(other, name, scope)
|
||||
|
|
||||
other order by other.getLocation().getStartLine(), other.getLocation().getStartColumn()
|
||||
)
|
||||
} or
|
||||
TInstanceVariable(Scope::Range scope, string name, boolean instance, Generated::AstNode decl) {
|
||||
TInstanceVariable(Scope::Range scope, string name, boolean instance, Ruby::AstNode decl) {
|
||||
decl =
|
||||
min(Generated::InstanceVariable other |
|
||||
min(Ruby::InstanceVariable other |
|
||||
instanceVariableAccess(other, name, scope, instance)
|
||||
|
|
||||
other order by other.getLocation().getStartLine(), other.getLocation().getStartColumn()
|
||||
)
|
||||
} or
|
||||
TLocalVariableReal(Scope::Range scope, string name, Generated::Identifier i) {
|
||||
TLocalVariableReal(Scope::Range scope, string name, Ruby::Identifier i) {
|
||||
scopeDefinesParameterVariable(scope, name, i)
|
||||
or
|
||||
i =
|
||||
min(Generated::Identifier other |
|
||||
min(Ruby::Identifier other |
|
||||
scopeAssigns(scope, name, other)
|
||||
|
|
||||
other order by other.getLocation().getStartLine(), other.getLocation().getStartColumn()
|
||||
@@ -145,7 +145,7 @@ private module Cached {
|
||||
|
||||
// Db types that can be vcalls
|
||||
private class VcallToken =
|
||||
@scope_resolution or @token_constant or @token_identifier or @token_super;
|
||||
@ruby_scope_resolution or @ruby_token_constant or @ruby_token_identifier or @ruby_token_super;
|
||||
|
||||
/**
|
||||
* Holds if `i` is an `identifier` node occurring in the context where it
|
||||
@@ -162,135 +162,135 @@ private module Cached {
|
||||
*/
|
||||
cached
|
||||
predicate vcall(VcallToken i) {
|
||||
i = any(Generated::ArgumentList x).getChild(_)
|
||||
i = any(Ruby::ArgumentList x).getChild(_)
|
||||
or
|
||||
i = any(Generated::Array x).getChild(_)
|
||||
i = any(Ruby::Array x).getChild(_)
|
||||
or
|
||||
i = any(Generated::Assignment x).getRight()
|
||||
i = any(Ruby::Assignment x).getRight()
|
||||
or
|
||||
i = any(Generated::Begin x).getChild(_)
|
||||
i = any(Ruby::Begin x).getChild(_)
|
||||
or
|
||||
i = any(Generated::BeginBlock x).getChild(_)
|
||||
i = any(Ruby::BeginBlock x).getChild(_)
|
||||
or
|
||||
i = any(Generated::Binary x).getLeft()
|
||||
i = any(Ruby::Binary x).getLeft()
|
||||
or
|
||||
i = any(Generated::Binary x).getRight()
|
||||
i = any(Ruby::Binary x).getRight()
|
||||
or
|
||||
i = any(Generated::Block x).getChild(_)
|
||||
i = any(Ruby::Block x).getChild(_)
|
||||
or
|
||||
i = any(Generated::BlockArgument x).getChild()
|
||||
i = any(Ruby::BlockArgument x).getChild()
|
||||
or
|
||||
i = any(Generated::Call x).getReceiver()
|
||||
i = any(Ruby::Call x).getReceiver()
|
||||
or
|
||||
i = any(Generated::Case x).getValue()
|
||||
i = any(Ruby::Case x).getValue()
|
||||
or
|
||||
i = any(Generated::Class x).getChild(_)
|
||||
i = any(Ruby::Class x).getChild(_)
|
||||
or
|
||||
i = any(Generated::Conditional x).getCondition()
|
||||
i = any(Ruby::Conditional x).getCondition()
|
||||
or
|
||||
i = any(Generated::Conditional x).getConsequence()
|
||||
i = any(Ruby::Conditional x).getConsequence()
|
||||
or
|
||||
i = any(Generated::Conditional x).getAlternative()
|
||||
i = any(Ruby::Conditional x).getAlternative()
|
||||
or
|
||||
i = any(Generated::Do x).getChild(_)
|
||||
i = any(Ruby::Do x).getChild(_)
|
||||
or
|
||||
i = any(Generated::DoBlock x).getChild(_)
|
||||
i = any(Ruby::DoBlock x).getChild(_)
|
||||
or
|
||||
i = any(Generated::ElementReference x).getChild(_)
|
||||
i = any(Ruby::ElementReference x).getChild(_)
|
||||
or
|
||||
i = any(Generated::ElementReference x).getObject()
|
||||
i = any(Ruby::ElementReference x).getObject()
|
||||
or
|
||||
i = any(Generated::Else x).getChild(_)
|
||||
i = any(Ruby::Else x).getChild(_)
|
||||
or
|
||||
i = any(Generated::Elsif x).getCondition()
|
||||
i = any(Ruby::Elsif x).getCondition()
|
||||
or
|
||||
i = any(Generated::EndBlock x).getChild(_)
|
||||
i = any(Ruby::EndBlock x).getChild(_)
|
||||
or
|
||||
i = any(Generated::Ensure x).getChild(_)
|
||||
i = any(Ruby::Ensure x).getChild(_)
|
||||
or
|
||||
i = any(Generated::Exceptions x).getChild(_)
|
||||
i = any(Ruby::Exceptions x).getChild(_)
|
||||
or
|
||||
i = any(Generated::HashSplatArgument x).getChild()
|
||||
i = any(Ruby::HashSplatArgument x).getChild()
|
||||
or
|
||||
i = any(Generated::If x).getCondition()
|
||||
i = any(Ruby::If x).getCondition()
|
||||
or
|
||||
i = any(Generated::IfModifier x).getCondition()
|
||||
i = any(Ruby::IfModifier x).getCondition()
|
||||
or
|
||||
i = any(Generated::IfModifier x).getBody()
|
||||
i = any(Ruby::IfModifier x).getBody()
|
||||
or
|
||||
i = any(Generated::In x).getChild()
|
||||
i = any(Ruby::In x).getChild()
|
||||
or
|
||||
i = any(Generated::Interpolation x).getChild(_)
|
||||
i = any(Ruby::Interpolation x).getChild(_)
|
||||
or
|
||||
i = any(Generated::KeywordParameter x).getValue()
|
||||
i = any(Ruby::KeywordParameter x).getValue()
|
||||
or
|
||||
i = any(Generated::Method x).getChild(_)
|
||||
i = any(Ruby::Method x).getChild(_)
|
||||
or
|
||||
i = any(Generated::Module x).getChild(_)
|
||||
i = any(Ruby::Module x).getChild(_)
|
||||
or
|
||||
i = any(Generated::OperatorAssignment x).getRight()
|
||||
i = any(Ruby::OperatorAssignment x).getRight()
|
||||
or
|
||||
i = any(Generated::OptionalParameter x).getValue()
|
||||
i = any(Ruby::OptionalParameter x).getValue()
|
||||
or
|
||||
i = any(Generated::Pair x).getKey()
|
||||
i = any(Ruby::Pair x).getKey()
|
||||
or
|
||||
i = any(Generated::Pair x).getValue()
|
||||
i = any(Ruby::Pair x).getValue()
|
||||
or
|
||||
i = any(Generated::ParenthesizedStatements x).getChild(_)
|
||||
i = any(Ruby::ParenthesizedStatements x).getChild(_)
|
||||
or
|
||||
i = any(Generated::Pattern x).getChild()
|
||||
i = any(Ruby::Pattern x).getChild()
|
||||
or
|
||||
i = any(Generated::Program x).getChild(_)
|
||||
i = any(Ruby::Program x).getChild(_)
|
||||
or
|
||||
i = any(Generated::Range x).getBegin()
|
||||
i = any(Ruby::Range x).getBegin()
|
||||
or
|
||||
i = any(Generated::Range x).getEnd()
|
||||
i = any(Ruby::Range x).getEnd()
|
||||
or
|
||||
i = any(Generated::RescueModifier x).getBody()
|
||||
i = any(Ruby::RescueModifier x).getBody()
|
||||
or
|
||||
i = any(Generated::RescueModifier x).getHandler()
|
||||
i = any(Ruby::RescueModifier x).getHandler()
|
||||
or
|
||||
i = any(Generated::RightAssignmentList x).getChild(_)
|
||||
i = any(Ruby::RightAssignmentList x).getChild(_)
|
||||
or
|
||||
i = any(Generated::ScopeResolution x).getScope()
|
||||
i = any(Ruby::ScopeResolution x).getScope()
|
||||
or
|
||||
i = any(Generated::SingletonClass x).getValue()
|
||||
i = any(Ruby::SingletonClass x).getValue()
|
||||
or
|
||||
i = any(Generated::SingletonClass x).getChild(_)
|
||||
i = any(Ruby::SingletonClass x).getChild(_)
|
||||
or
|
||||
i = any(Generated::SingletonMethod x).getChild(_)
|
||||
i = any(Ruby::SingletonMethod x).getChild(_)
|
||||
or
|
||||
i = any(Generated::SingletonMethod x).getObject()
|
||||
i = any(Ruby::SingletonMethod x).getObject()
|
||||
or
|
||||
i = any(Generated::SplatArgument x).getChild()
|
||||
i = any(Ruby::SplatArgument x).getChild()
|
||||
or
|
||||
i = any(Generated::Superclass x).getChild()
|
||||
i = any(Ruby::Superclass x).getChild()
|
||||
or
|
||||
i = any(Generated::Then x).getChild(_)
|
||||
i = any(Ruby::Then x).getChild(_)
|
||||
or
|
||||
i = any(Generated::Unary x).getOperand()
|
||||
i = any(Ruby::Unary x).getOperand()
|
||||
or
|
||||
i = any(Generated::Unless x).getCondition()
|
||||
i = any(Ruby::Unless x).getCondition()
|
||||
or
|
||||
i = any(Generated::UnlessModifier x).getCondition()
|
||||
i = any(Ruby::UnlessModifier x).getCondition()
|
||||
or
|
||||
i = any(Generated::UnlessModifier x).getBody()
|
||||
i = any(Ruby::UnlessModifier x).getBody()
|
||||
or
|
||||
i = any(Generated::Until x).getCondition()
|
||||
i = any(Ruby::Until x).getCondition()
|
||||
or
|
||||
i = any(Generated::UntilModifier x).getCondition()
|
||||
i = any(Ruby::UntilModifier x).getCondition()
|
||||
or
|
||||
i = any(Generated::UntilModifier x).getBody()
|
||||
i = any(Ruby::UntilModifier x).getBody()
|
||||
or
|
||||
i = any(Generated::While x).getCondition()
|
||||
i = any(Ruby::While x).getCondition()
|
||||
or
|
||||
i = any(Generated::WhileModifier x).getCondition()
|
||||
i = any(Ruby::WhileModifier x).getCondition()
|
||||
or
|
||||
i = any(Generated::WhileModifier x).getBody()
|
||||
i = any(Ruby::WhileModifier x).getBody()
|
||||
}
|
||||
|
||||
cached
|
||||
predicate access(Generated::Identifier access, VariableReal::Range variable) {
|
||||
predicate access(Ruby::Identifier access, VariableReal::Range variable) {
|
||||
exists(string name |
|
||||
variable.getName() = name and
|
||||
name = access.getValue()
|
||||
@@ -310,17 +310,17 @@ private module Cached {
|
||||
)
|
||||
}
|
||||
|
||||
private class Access extends Generated::Token {
|
||||
private class Access extends Ruby::Token {
|
||||
Access() {
|
||||
access(this, _) or
|
||||
this instanceof Generated::GlobalVariable or
|
||||
this instanceof Generated::InstanceVariable or
|
||||
this instanceof Generated::ClassVariable
|
||||
this instanceof Ruby::GlobalVariable or
|
||||
this instanceof Ruby::InstanceVariable or
|
||||
this instanceof Ruby::ClassVariable
|
||||
}
|
||||
}
|
||||
|
||||
cached
|
||||
predicate explicitWriteAccess(Access access, Generated::AstNode assignment) {
|
||||
predicate explicitWriteAccess(Access access, Ruby::AstNode assignment) {
|
||||
explicitAssignmentNode(access, assignment)
|
||||
}
|
||||
|
||||
@@ -337,7 +337,7 @@ private module Cached {
|
||||
}
|
||||
|
||||
cached
|
||||
predicate instanceVariableAccess(Generated::InstanceVariable var, InstanceVariable v) {
|
||||
predicate instanceVariableAccess(Ruby::InstanceVariable var, InstanceVariable v) {
|
||||
exists(string name, Scope::Range scope, boolean instance |
|
||||
v = TInstanceVariable(scope, name, instance, _) and
|
||||
instanceVariableAccess(var, name, scope, instance)
|
||||
@@ -345,7 +345,7 @@ private module Cached {
|
||||
}
|
||||
|
||||
cached
|
||||
predicate classVariableAccess(Generated::ClassVariable var, ClassVariable variable) {
|
||||
predicate classVariableAccess(Ruby::ClassVariable var, ClassVariable variable) {
|
||||
exists(Scope::Range scope, string name |
|
||||
variable = TClassVariable(scope, name, _) and
|
||||
classVariableAccess(var, name, scope)
|
||||
@@ -357,14 +357,14 @@ import Cached
|
||||
|
||||
/** Holds if this scope inherits `name` from an outer scope `outer`. */
|
||||
private predicate inherits(Scope::Range scope, string name, Scope::Range outer) {
|
||||
(scope instanceof Generated::Block or scope instanceof Generated::DoBlock) and
|
||||
(scope instanceof Ruby::Block or scope instanceof Ruby::DoBlock) and
|
||||
not scopeDefinesParameterVariable(scope, name, _) and
|
||||
(
|
||||
outer = scope.getOuterScope() and
|
||||
(
|
||||
scopeDefinesParameterVariable(outer, name, _)
|
||||
or
|
||||
exists(Generated::Identifier i |
|
||||
exists(Ruby::Identifier i |
|
||||
scopeAssigns(outer, name, i) and
|
||||
strictlyBefore(i.getLocation(), scope.getLocation())
|
||||
)
|
||||
@@ -394,7 +394,7 @@ module LocalVariable {
|
||||
class Range extends VariableReal::Range, TLocalVariableReal {
|
||||
private Scope::Range scope;
|
||||
private string name;
|
||||
private Generated::Identifier i;
|
||||
private Ruby::Identifier i;
|
||||
|
||||
Range() { this = TLocalVariableReal(scope, name, i) }
|
||||
|
||||
@@ -464,7 +464,7 @@ module InstanceVariable {
|
||||
private ModuleBase::Range scope;
|
||||
private boolean instance;
|
||||
private string name;
|
||||
private Generated::AstNode decl;
|
||||
private Ruby::AstNode decl;
|
||||
|
||||
Range() { this = TInstanceVariable(scope, name, instance, decl) }
|
||||
|
||||
@@ -482,7 +482,7 @@ module ClassVariable {
|
||||
class Range extends VariableReal::Range, TClassVariable {
|
||||
private ModuleBase::Range scope;
|
||||
private string name;
|
||||
private Generated::AstNode decl;
|
||||
private Ruby::AstNode decl;
|
||||
|
||||
Range() { this = TClassVariable(scope, name, decl) }
|
||||
|
||||
@@ -499,7 +499,7 @@ abstract class VariableAccessImpl extends VariableAccess {
|
||||
}
|
||||
|
||||
module LocalVariableAccess {
|
||||
predicate range(Generated::Identifier id, LocalVariable v) {
|
||||
predicate range(Ruby::Identifier id, LocalVariable v) {
|
||||
access(id, v) and
|
||||
(
|
||||
explicitWriteAccess(id, _)
|
||||
@@ -517,7 +517,7 @@ class TVariableAccessReal =
|
||||
|
||||
private class LocalVariableAccessReal extends VariableAccessImpl, LocalVariableAccess,
|
||||
TLocalVariableAccessReal {
|
||||
private Generated::Identifier g;
|
||||
private Ruby::Identifier g;
|
||||
private LocalVariable v;
|
||||
|
||||
LocalVariableAccessReal() { this = TLocalVariableAccessReal(g, v) }
|
||||
@@ -539,12 +539,12 @@ private class LocalVariableAccessSynth extends VariableAccessImpl, LocalVariable
|
||||
}
|
||||
|
||||
module GlobalVariableAccess {
|
||||
predicate range(Generated::GlobalVariable n, GlobalVariable v) { n.getValue() = v.getName() }
|
||||
predicate range(Ruby::GlobalVariable n, GlobalVariable v) { n.getValue() = v.getName() }
|
||||
}
|
||||
|
||||
private class GlobalVariableAccessReal extends GlobalVariableAccess, VariableAccessImpl,
|
||||
TGlobalVariableAccessReal {
|
||||
private Generated::GlobalVariable g;
|
||||
private Ruby::GlobalVariable g;
|
||||
private GlobalVariable v;
|
||||
|
||||
GlobalVariableAccessReal() { this = TGlobalVariableAccessReal(g, v) }
|
||||
@@ -566,14 +566,12 @@ private class GlobalVariableAccessSynth extends GlobalVariableAccess, VariableAc
|
||||
}
|
||||
|
||||
module InstanceVariableAccess {
|
||||
predicate range(Generated::InstanceVariable n, InstanceVariable v) {
|
||||
instanceVariableAccess(n, v)
|
||||
}
|
||||
predicate range(Ruby::InstanceVariable n, InstanceVariable v) { instanceVariableAccess(n, v) }
|
||||
}
|
||||
|
||||
private class InstanceVariableAccessReal extends InstanceVariableAccess, VariableAccessImpl,
|
||||
TInstanceVariableAccessReal {
|
||||
private Generated::InstanceVariable g;
|
||||
private Ruby::InstanceVariable g;
|
||||
private InstanceVariable v;
|
||||
|
||||
InstanceVariableAccessReal() { this = TInstanceVariableAccessReal(g, v) }
|
||||
@@ -595,12 +593,12 @@ private class InstanceVariableAccessSynth extends InstanceVariableAccess, Variab
|
||||
}
|
||||
|
||||
module ClassVariableAccess {
|
||||
predicate range(Generated::ClassVariable n, ClassVariable v) { classVariableAccess(n, v) }
|
||||
predicate range(Ruby::ClassVariable n, ClassVariable v) { classVariableAccess(n, v) }
|
||||
}
|
||||
|
||||
private class ClassVariableAccessReal extends ClassVariableAccess, VariableAccessImpl,
|
||||
TClassVariableAccessReal {
|
||||
private Generated::ClassVariable g;
|
||||
private Ruby::ClassVariable g;
|
||||
private ClassVariable v;
|
||||
|
||||
ClassVariableAccessReal() { this = TClassVariableAccessReal(g, v) }
|
||||
|
||||
@@ -353,9 +353,9 @@ class ExitBasicBlock extends BasicBlock {
|
||||
}
|
||||
|
||||
private module JoinBlockPredecessors {
|
||||
private predicate id(Generated::AstNode x, Generated::AstNode y) { x = y }
|
||||
private predicate id(Ruby::AstNode x, Ruby::AstNode y) { x = y }
|
||||
|
||||
private predicate idOf(Generated::AstNode x, int y) = equivalenceRelation(id/2)(x, y)
|
||||
private predicate idOf(Ruby::AstNode x, int y) = equivalenceRelation(id/2)(x, y)
|
||||
|
||||
int getId(JoinBlockPredecessor jbp) {
|
||||
idOf(toGeneratedInclSynth(jbp.getFirstNode().(AstCfgNode).getNode()), result)
|
||||
|
||||
@@ -202,7 +202,7 @@ private class ForRange extends ForExpr {
|
||||
}
|
||||
|
||||
ForIn getIn() {
|
||||
result = ASTInternal::TForIn(ASTInternal::toGenerated(this).(Generated::For).getValue())
|
||||
result = ASTInternal::TForIn(ASTInternal::toGenerated(this).(Ruby::For).getValue())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
|
||||
import ruby
|
||||
|
||||
from File f, int n
|
||||
from RubyFile f, int n
|
||||
where n = f.getNumberOfLines()
|
||||
select f, n order by n desc
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
|
||||
import ruby
|
||||
|
||||
from File f, int n
|
||||
from RubyFile f, int n
|
||||
where n = f.getNumberOfLinesOfCode()
|
||||
select f, n order by n desc
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
|
||||
import ruby
|
||||
|
||||
from File f, int n
|
||||
from RubyFile f, int n
|
||||
where n = f.getNumberOfLinesOfComments()
|
||||
select f, n order by n desc
|
||||
|
||||
@@ -12,4 +12,4 @@
|
||||
|
||||
import ruby
|
||||
|
||||
select sum(File f | exists(f.getRelativePath()) | f.getNumberOfLinesOfCode())
|
||||
select sum(RubyFile f | exists(f.getRelativePath()) | f.getNumberOfLinesOfCode())
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
import ruby
|
||||
|
||||
select sum(File f |
|
||||
select sum(RubyFile f |
|
||||
f.fromSource() and
|
||||
exists(f.getRelativePath()) and
|
||||
not f.getAbsolutePath().matches("%/vendor/%")
|
||||
|
||||
2458
ql/src/ruby.dbscheme
2458
ql/src/ruby.dbscheme
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,165 @@
|
||||
description: Add ERB tables and rename Ruby tables
|
||||
compatibility: backwards
|
||||
ruby_alias_def.rel: reorder alias_def.rel ( int id, int alias, int name, int loc ) id alias name loc
|
||||
ruby_argument_list_child.rel: reorder argument_list_child.rel ( int ruby_argument_list, int index, int child ) ruby_argument_list index child
|
||||
ruby_argument_list_def.rel: reorder argument_list_def.rel ( int id, int loc ) id loc
|
||||
ruby_array_child.rel: reorder array_child.rel ( int ruby_array, int index, int child ) ruby_array index child
|
||||
ruby_array_def.rel: reorder array_def.rel ( int id, int loc ) id loc
|
||||
ruby_assignment_def.rel: reorder assignment_def.rel ( int id, int left, int right, int loc ) id left right loc
|
||||
ruby_bare_string_child.rel: reorder bare_string_child.rel ( int ruby_bare_string, int index, int child ) ruby_bare_string index child
|
||||
ruby_bare_string_def.rel: reorder bare_string_def.rel ( int id, int loc ) id loc
|
||||
ruby_bare_symbol_child.rel: reorder bare_symbol_child.rel ( int ruby_bare_symbol, int index, int child ) ruby_bare_symbol index child
|
||||
ruby_bare_symbol_def.rel: reorder bare_symbol_def.rel ( int id, int loc ) id loc
|
||||
ruby_begin_child.rel: reorder begin_child.rel ( int ruby_begin, int index, int child ) ruby_begin index child
|
||||
ruby_begin_def.rel: reorder begin_def.rel ( int id, int loc ) id loc
|
||||
ruby_begin_block_child.rel: reorder begin_block_child.rel ( int ruby_begin_block, int index, int child ) ruby_begin_block index child
|
||||
ruby_begin_block_def.rel: reorder begin_block_def.rel ( int id, int loc ) id loc
|
||||
ruby_binary_def.rel: reorder binary_def.rel ( int id, int left, int operator, int right, int loc ) id left operator right loc
|
||||
ruby_block_parameters.rel: reorder block_parameters.rel ( int ruby_block, int parameters ) ruby_block parameters
|
||||
ruby_block_child.rel: reorder block_child.rel ( int ruby_block, int index, int child ) ruby_block index child
|
||||
ruby_block_def.rel: reorder block_def.rel ( int id, int loc ) id loc
|
||||
ruby_block_argument_def.rel: reorder block_argument_def.rel ( int id, int child, int loc ) id child loc
|
||||
ruby_block_parameter_def.rel: reorder block_parameter_def.rel ( int id, int name, int loc ) id name loc
|
||||
ruby_block_parameters_child.rel: reorder block_parameters_child.rel ( int ruby_block_parameters, int index, int child ) ruby_block_parameters index child
|
||||
ruby_block_parameters_def.rel: reorder block_parameters_def.rel ( int id, int loc ) id loc
|
||||
ruby_break_child.rel: reorder break_child.rel ( int ruby_break, int child ) ruby_break child
|
||||
ruby_break_def.rel: reorder break_def.rel ( int id, int loc ) id loc
|
||||
ruby_call_arguments.rel: reorder call_arguments.rel ( int ruby_call, int arguments ) ruby_call arguments
|
||||
ruby_call_block.rel: reorder call_block.rel ( int ruby_call, int block ) ruby_call block
|
||||
ruby_call_receiver.rel: reorder call_receiver.rel ( int ruby_call, int receiver ) ruby_call receiver
|
||||
ruby_call_def.rel: reorder call_def.rel ( int id, int method, int loc ) id method loc
|
||||
ruby_case_value.rel: reorder case_value.rel ( int ruby_case__, int value ) ruby_case__ value
|
||||
ruby_case_child.rel: reorder case_child.rel ( int ruby_case__, int index, int child ) ruby_case__ index child
|
||||
ruby_case_def.rel: reorder case_def.rel ( int id, int loc ) id loc
|
||||
ruby_chained_string_child.rel: reorder chained_string_child.rel ( int ruby_chained_string, int index, int child ) ruby_chained_string index child
|
||||
ruby_chained_string_def.rel: reorder chained_string_def.rel ( int id, int loc ) id loc
|
||||
ruby_class_superclass.rel: reorder class_superclass.rel ( int ruby_class, int superclass ) ruby_class superclass
|
||||
ruby_class_child.rel: reorder class_child.rel ( int ruby_class, int index, int child ) ruby_class index child
|
||||
ruby_class_def.rel: reorder class_def.rel ( int id, int name, int loc ) id name loc
|
||||
ruby_conditional_def.rel: reorder conditional_def.rel ( int id, int alternative, int condition, int consequence, int loc ) id alternative condition consequence loc
|
||||
ruby_delimited_symbol_child.rel: reorder delimited_symbol_child.rel ( int ruby_delimited_symbol, int index, int child ) ruby_delimited_symbol index child
|
||||
ruby_delimited_symbol_def.rel: reorder delimited_symbol_def.rel ( int id, int loc ) id loc
|
||||
ruby_destructured_left_assignment_child.rel: reorder destructured_left_assignment_child.rel ( int ruby_destructured_left_assignment, int index, int child ) ruby_destructured_left_assignment index child
|
||||
ruby_destructured_left_assignment_def.rel: reorder destructured_left_assignment_def.rel ( int id, int loc ) id loc
|
||||
ruby_destructured_parameter_child.rel: reorder destructured_parameter_child.rel ( int ruby_destructured_parameter, int index, int child ) ruby_destructured_parameter index child
|
||||
ruby_destructured_parameter_def.rel: reorder destructured_parameter_def.rel ( int id, int loc ) id loc
|
||||
ruby_do_child.rel: reorder do_child.rel ( int ruby_do, int index, int child ) ruby_do index child
|
||||
ruby_do_def.rel: reorder do_def.rel ( int id, int loc ) id loc
|
||||
ruby_do_block_parameters.rel: reorder do_block_parameters.rel ( int ruby_do_block, int parameters ) ruby_do_block parameters
|
||||
ruby_do_block_child.rel: reorder do_block_child.rel ( int ruby_do_block, int index, int child ) ruby_do_block index child
|
||||
ruby_do_block_def.rel: reorder do_block_def.rel ( int id, int loc ) id loc
|
||||
ruby_element_reference_child.rel: reorder element_reference_child.rel ( int ruby_element_reference, int index, int child ) ruby_element_reference index child
|
||||
ruby_element_reference_def.rel: reorder element_reference_def.rel ( int id, int object, int loc ) id object loc
|
||||
ruby_else_child.rel: reorder else_child.rel ( int ruby_else, int index, int child ) ruby_else index child
|
||||
ruby_else_def.rel: reorder else_def.rel ( int id, int loc ) id loc
|
||||
ruby_elsif_alternative.rel: reorder elsif_alternative.rel ( int ruby_elsif, int alternative ) ruby_elsif alternative
|
||||
ruby_elsif_consequence.rel: reorder elsif_consequence.rel ( int ruby_elsif, int consequence ) ruby_elsif consequence
|
||||
ruby_elsif_def.rel: reorder elsif_def.rel ( int id, int condition, int loc ) id condition loc
|
||||
ruby_end_block_child.rel: reorder end_block_child.rel ( int ruby_end_block, int index, int child ) ruby_end_block index child
|
||||
ruby_end_block_def.rel: reorder end_block_def.rel ( int id, int loc ) id loc
|
||||
ruby_ensure_child.rel: reorder ensure_child.rel ( int ruby_ensure, int index, int child ) ruby_ensure index child
|
||||
ruby_ensure_def.rel: reorder ensure_def.rel ( int id, int loc ) id loc
|
||||
ruby_exception_variable_def.rel: reorder exception_variable_def.rel ( int id, int child, int loc ) id child loc
|
||||
ruby_exceptions_child.rel: reorder exceptions_child.rel ( int ruby_exceptions, int index, int child ) ruby_exceptions index child
|
||||
ruby_exceptions_def.rel: reorder exceptions_def.rel ( int id, int loc ) id loc
|
||||
ruby_for_def.rel: reorder for_def.rel ( int id, int body, int pattern, int value, int loc ) id body pattern value loc
|
||||
ruby_hash_child.rel: reorder hash_child.rel ( int ruby_hash, int index, int child ) ruby_hash index child
|
||||
ruby_hash_def.rel: reorder hash_def.rel ( int id, int loc ) id loc
|
||||
ruby_hash_splat_argument_def.rel: reorder hash_splat_argument_def.rel ( int id, int child, int loc ) id child loc
|
||||
ruby_hash_splat_parameter_name.rel: reorder hash_splat_parameter_name.rel ( int ruby_hash_splat_parameter, int name ) ruby_hash_splat_parameter name
|
||||
ruby_hash_splat_parameter_def.rel: reorder hash_splat_parameter_def.rel ( int id, int loc ) id loc
|
||||
ruby_heredoc_body_child.rel: reorder heredoc_body_child.rel ( int ruby_heredoc_body, int index, int child ) ruby_heredoc_body index child
|
||||
ruby_heredoc_body_def.rel: reorder heredoc_body_def.rel ( int id, int loc ) id loc
|
||||
ruby_if_alternative.rel: reorder if_alternative.rel ( int ruby_if, int alternative ) ruby_if alternative
|
||||
ruby_if_consequence.rel: reorder if_consequence.rel ( int ruby_if, int consequence ) ruby_if consequence
|
||||
ruby_if_def.rel: reorder if_def.rel ( int id, int condition, int loc ) id condition loc
|
||||
ruby_if_modifier_def.rel: reorder if_modifier_def.rel ( int id, int body, int condition, int loc ) id body condition loc
|
||||
ruby_in_def.rel: reorder in_def.rel ( int id, int child, int loc ) id child loc
|
||||
ruby_interpolation_child.rel: reorder interpolation_child.rel ( int ruby_interpolation, int index, int child ) ruby_interpolation index child
|
||||
ruby_interpolation_def.rel: reorder interpolation_def.rel ( int id, int loc ) id loc
|
||||
ruby_keyword_parameter_value.rel: reorder keyword_parameter_value.rel ( int ruby_keyword_parameter, int value ) ruby_keyword_parameter value
|
||||
ruby_keyword_parameter_def.rel: reorder keyword_parameter_def.rel ( int id, int name, int loc ) id name loc
|
||||
ruby_lambda_parameters.rel: reorder lambda_parameters.rel ( int ruby_lambda, int parameters ) ruby_lambda parameters
|
||||
ruby_lambda_def.rel: reorder lambda_def.rel ( int id, int body, int loc ) id body loc
|
||||
ruby_lambda_parameters_child.rel: reorder lambda_parameters_child.rel ( int ruby_lambda_parameters, int index, int child ) ruby_lambda_parameters index child
|
||||
ruby_lambda_parameters_def.rel: reorder lambda_parameters_def.rel ( int id, int loc ) id loc
|
||||
ruby_left_assignment_list_child.rel: reorder left_assignment_list_child.rel ( int ruby_left_assignment_list, int index, int child ) ruby_left_assignment_list index child
|
||||
ruby_left_assignment_list_def.rel: reorder left_assignment_list_def.rel ( int id, int loc ) id loc
|
||||
ruby_method_parameters.rel: reorder method_parameters.rel ( int ruby_method, int parameters ) ruby_method parameters
|
||||
ruby_method_child.rel: reorder method_child.rel ( int ruby_method, int index, int child ) ruby_method index child
|
||||
ruby_method_def.rel: reorder method_def.rel ( int id, int name, int loc ) id name loc
|
||||
ruby_method_parameters_child.rel: reorder method_parameters_child.rel ( int ruby_method_parameters, int index, int child ) ruby_method_parameters index child
|
||||
ruby_method_parameters_def.rel: reorder method_parameters_def.rel ( int id, int loc ) id loc
|
||||
ruby_module_child.rel: reorder module_child.rel ( int ruby_module, int index, int child ) ruby_module index child
|
||||
ruby_module_def.rel: reorder module_def.rel ( int id, int name, int loc ) id name loc
|
||||
ruby_next_child.rel: reorder next_child.rel ( int ruby_next, int child ) ruby_next child
|
||||
ruby_next_def.rel: reorder next_def.rel ( int id, int loc ) id loc
|
||||
ruby_operator_assignment_def.rel: reorder operator_assignment_def.rel ( int id, int left, int operator, int right, int loc ) id left operator right loc
|
||||
ruby_optional_parameter_def.rel: reorder optional_parameter_def.rel ( int id, int name, int value, int loc ) id name value loc
|
||||
ruby_pair_def.rel: reorder pair_def.rel ( int id, int key__, int value, int loc ) id key__ value loc
|
||||
ruby_parenthesized_statements_child.rel: reorder parenthesized_statements_child.rel ( int ruby_parenthesized_statements, int index, int child ) ruby_parenthesized_statements index child
|
||||
ruby_parenthesized_statements_def.rel: reorder parenthesized_statements_def.rel ( int id, int loc ) id loc
|
||||
ruby_pattern_def.rel: reorder pattern_def.rel ( int id, int child, int loc ) id child loc
|
||||
ruby_program_child.rel: reorder program_child.rel ( int ruby_program, int index, int child ) ruby_program index child
|
||||
ruby_program_def.rel: reorder program_def.rel ( int id, int loc ) id loc
|
||||
ruby_range_begin.rel: reorder range_begin.rel ( int ruby_range, int begin ) ruby_range begin
|
||||
ruby_range_end.rel: reorder range_end.rel ( int ruby_range, int end ) ruby_range end
|
||||
ruby_range_def.rel: reorder range_def.rel ( int id, int operator, int loc ) id operator loc
|
||||
ruby_rational_def.rel: reorder rational_def.rel ( int id, int child, int loc ) id child loc
|
||||
ruby_redo_child.rel: reorder redo_child.rel ( int ruby_redo, int child ) ruby_redo child
|
||||
ruby_redo_def.rel: reorder redo_def.rel ( int id, int loc ) id loc
|
||||
ruby_regex_child.rel: reorder regex_child.rel ( int ruby_regex, int index, int child ) ruby_regex index child
|
||||
ruby_regex_def.rel: reorder regex_def.rel ( int id, int loc ) id loc
|
||||
ruby_rescue_body.rel: reorder rescue_body.rel ( int ruby_rescue, int body ) ruby_rescue body
|
||||
ruby_rescue_exceptions.rel: reorder rescue_exceptions.rel ( int ruby_rescue, int exceptions ) ruby_rescue exceptions
|
||||
ruby_rescue_variable.rel: reorder rescue_variable.rel ( int ruby_rescue, int variable ) ruby_rescue variable
|
||||
ruby_rescue_def.rel: reorder rescue_def.rel ( int id, int loc ) id loc
|
||||
ruby_rescue_modifier_def.rel: reorder rescue_modifier_def.rel ( int id, int body, int handler, int loc ) id body handler loc
|
||||
ruby_rest_assignment_child.rel: reorder rest_assignment_child.rel ( int ruby_rest_assignment, int child ) ruby_rest_assignment child
|
||||
ruby_rest_assignment_def.rel: reorder rest_assignment_def.rel ( int id, int loc ) id loc
|
||||
ruby_retry_child.rel: reorder retry_child.rel ( int ruby_retry, int child ) ruby_retry child
|
||||
ruby_retry_def.rel: reorder retry_def.rel ( int id, int loc ) id loc
|
||||
ruby_return_child.rel: reorder return_child.rel ( int ruby_return, int child ) ruby_return child
|
||||
ruby_return_def.rel: reorder return_def.rel ( int id, int loc ) id loc
|
||||
ruby_right_assignment_list_child.rel: reorder right_assignment_list_child.rel ( int ruby_right_assignment_list, int index, int child ) ruby_right_assignment_list index child
|
||||
ruby_right_assignment_list_def.rel: reorder right_assignment_list_def.rel ( int id, int loc ) id loc
|
||||
ruby_scope_resolution_scope.rel: reorder scope_resolution_scope.rel ( int ruby_scope_resolution, int scope ) ruby_scope_resolution scope
|
||||
ruby_scope_resolution_def.rel: reorder scope_resolution_def.rel ( int id, int name, int loc ) id name loc
|
||||
ruby_setter_def.rel: reorder setter_def.rel ( int id, int name, int loc ) id name loc
|
||||
ruby_singleton_class_child.rel: reorder singleton_class_child.rel ( int ruby_singleton_class, int index, int child ) ruby_singleton_class index child
|
||||
ruby_singleton_class_def.rel: reorder singleton_class_def.rel ( int id, int value, int loc ) id value loc
|
||||
ruby_singleton_method_parameters.rel: reorder singleton_method_parameters.rel ( int ruby_singleton_method, int parameters ) ruby_singleton_method parameters
|
||||
ruby_singleton_method_child.rel: reorder singleton_method_child.rel ( int ruby_singleton_method, int index, int child ) ruby_singleton_method index child
|
||||
ruby_singleton_method_def.rel: reorder singleton_method_def.rel ( int id, int name, int object, int loc ) id name object loc
|
||||
ruby_splat_argument_def.rel: reorder splat_argument_def.rel ( int id, int child, int loc ) id child loc
|
||||
ruby_splat_parameter_name.rel: reorder splat_parameter_name.rel ( int ruby_splat_parameter, int name ) ruby_splat_parameter name
|
||||
ruby_splat_parameter_def.rel: reorder splat_parameter_def.rel ( int id, int loc ) id loc
|
||||
ruby_string_child.rel: reorder string_child.rel ( int ruby_string__, int index, int child ) ruby_string__ index child
|
||||
ruby_string_def.rel: reorder string_def.rel ( int id, int loc ) id loc
|
||||
ruby_string_array_child.rel: reorder string_array_child.rel ( int ruby_string_array, int index, int child ) ruby_string_array index child
|
||||
ruby_string_array_def.rel: reorder string_array_def.rel ( int id, int loc ) id loc
|
||||
ruby_subshell_child.rel: reorder subshell_child.rel ( int ruby_subshell, int index, int child ) ruby_subshell index child
|
||||
ruby_subshell_def.rel: reorder subshell_def.rel ( int id, int loc ) id loc
|
||||
ruby_superclass_def.rel: reorder superclass_def.rel ( int id, int child, int loc ) id child loc
|
||||
ruby_symbol_array_child.rel: reorder symbol_array_child.rel ( int ruby_symbol_array, int index, int child ) ruby_symbol_array index child
|
||||
ruby_symbol_array_def.rel: reorder symbol_array_def.rel ( int id, int loc ) id loc
|
||||
ruby_then_child.rel: reorder then_child.rel ( int ruby_then, int index, int child ) ruby_then index child
|
||||
ruby_then_def.rel: reorder then_def.rel ( int id, int loc ) id loc
|
||||
ruby_unary_def.rel: reorder unary_def.rel ( int id, int operand, int operator, int loc ) id operand operator loc
|
||||
ruby_undef_child.rel: reorder undef_child.rel ( int ruby_undef, int index, int child ) ruby_undef index child
|
||||
ruby_undef_def.rel: reorder undef_def.rel ( int id, int loc ) id loc
|
||||
ruby_unless_alternative.rel: reorder unless_alternative.rel ( int ruby_unless, int alternative ) ruby_unless alternative
|
||||
ruby_unless_consequence.rel: reorder unless_consequence.rel ( int ruby_unless, int consequence ) ruby_unless consequence
|
||||
ruby_unless_def.rel: reorder unless_def.rel ( int id, int condition, int loc ) id condition loc
|
||||
ruby_unless_modifier_def.rel: reorder unless_modifier_def.rel ( int id, int body, int condition, int loc ) id body condition loc
|
||||
ruby_until_def.rel: reorder until_def.rel ( int id, int body, int condition, int loc ) id body condition loc
|
||||
ruby_until_modifier_def.rel: reorder until_modifier_def.rel ( int id, int body, int condition, int loc ) id body condition loc
|
||||
ruby_when_body.rel: reorder when_body.rel ( int ruby_when, int body ) ruby_when body
|
||||
ruby_when_pattern.rel: reorder when_pattern.rel ( int ruby_when, int index, int pattern ) ruby_when index pattern
|
||||
ruby_when_def.rel: reorder when_def.rel ( int id, int loc ) id loc
|
||||
ruby_while_def.rel: reorder while_def.rel ( int id, int body, int condition, int loc ) id body condition loc
|
||||
ruby_while_modifier_def.rel: reorder while_modifier_def.rel ( int id, int body, int condition, int loc ) id body condition loc
|
||||
ruby_yield_child.rel: reorder yield_child.rel ( int ruby_yield, int child ) ruby_yield child
|
||||
ruby_yield_def.rel: reorder yield_def.rel ( int id, int loc ) id loc
|
||||
ruby_tokeninfo.rel: reorder tokeninfo.rel ( int id, int kind, int file, int idx, string value, int loc ) id kind file idx value loc
|
||||
ruby_ast_node_parent.rel: reorder ast_node_parent.rel ( int child, int parent, int parent_index) child parent parent_index
|
||||
@@ -4,6 +4,6 @@ import codeql_ruby.ast.internal.TreeSitter
|
||||
/**
|
||||
* A class representing line comments in Ruby.
|
||||
*/
|
||||
class LineComment extends Generated::Comment {
|
||||
class LineComment extends Ruby::Comment {
|
||||
string getContents() { result = this.getValue().suffix(1) }
|
||||
}
|
||||
|
||||
@@ -1476,6 +1476,11 @@ control/loops.rb:
|
||||
# 66| getAnOperand/getLeftOperand/getLesserOperand: [LocalVariableAccess] x
|
||||
# 66| getAnOperand/getGreaterOperand/getRightOperand: [LocalVariableAccess] y
|
||||
# 66| getBody: [StmtSequence] do ...
|
||||
misc/misc.erb:
|
||||
# 2| [MethodCall] call to require_asset
|
||||
# 2| getReceiver: [Self] self
|
||||
# 2| getArgument: [StringLiteral] "main_include_admin.js"
|
||||
# 2| getComponent: [StringTextComponent] main_include_admin.js
|
||||
misc/misc.rb:
|
||||
# 1| [Toplevel] misc.rb
|
||||
# 1| getStmt: [AssignExpr] ... = ...
|
||||
|
||||
3
ql/test/library-tests/ast/misc/misc.erb
Normal file
3
ql/test/library-tests/ast/misc/misc.erb
Normal file
@@ -0,0 +1,3 @@
|
||||
<%
|
||||
require_asset("main_include_admin.js")
|
||||
%>
|
||||
Reference in New Issue
Block a user