Ruby: generate overlay discard predicates

This commit is contained in:
Nick Rolfe
2025-06-06 18:06:13 +01:00
parent 1bbba2f664
commit a9ddf0026b
5 changed files with 287 additions and 3 deletions

View File

@@ -2,7 +2,6 @@ use clap::Args;
use codeql_extractor::file_paths::PathTransformer;
use lazy_static::lazy_static;
use rayon::prelude::*;
use serde_json;
use std::borrow::Cow;
use std::collections::HashSet;
use std::fs;

View File

@@ -5,6 +5,10 @@
import codeql.Locations as L
/** Holds if the database is an overlay. */
overlay[local]
private predicate isOverlay() { databaseMetadata("isOverlay", "true") }
module Ruby {
/** The base class for all AST nodes */
class AstNode extends @ruby_ast_node {
@@ -48,6 +52,30 @@ module Ruby {
final override string getAPrimaryQlClass() { result = "ReservedWord" }
}
/** Gets the file containing the given `node`. */
overlay[local]
private @file getNodeFile(@ruby_ast_node node) {
exists(@location_default loc | ruby_ast_node_location(node, loc) |
locations_default(loc, result, _, _, _, _)
)
}
/** Holds if `file` was extracted as part of the overlay database. */
overlay[local]
private predicate discardFile(@file file) { isOverlay() and file = getNodeFile(_) }
/** Holds if `node` is in the `file` and is part of the overlay base database. */
overlay[local]
private predicate discardableAstNode(@file file, @ruby_ast_node node) {
not isOverlay() and file = getNodeFile(node)
}
/** Holds if `node` should be discarded, because it is part of the overlay base and is in a file that was also extracted as part of the overlay database. */
overlay[discard_entity]
private predicate discardAstNode(@ruby_ast_node node) {
exists(@file file | discardableAstNode(file, node) and discardFile(file))
}
class UnderscoreArg extends @ruby_underscore_arg, AstNode { }
class UnderscoreCallOperator extends @ruby_underscore_call_operator, AstNode { }
@@ -1970,6 +1998,30 @@ module Erb {
final override string getAPrimaryQlClass() { result = "ReservedWord" }
}
/** Gets the file containing the given `node`. */
overlay[local]
private @file getNodeFile(@erb_ast_node node) {
exists(@location_default loc | erb_ast_node_location(node, loc) |
locations_default(loc, result, _, _, _, _)
)
}
/** Holds if `file` was extracted as part of the overlay database. */
overlay[local]
private predicate discardFile(@file file) { isOverlay() and file = getNodeFile(_) }
/** Holds if `node` is in the `file` and is part of the overlay base database. */
overlay[local]
private predicate discardableAstNode(@file file, @erb_ast_node node) {
not isOverlay() and file = getNodeFile(node)
}
/** Holds if `node` should be discarded, because it is part of the overlay base and is in a file that was also extracted as part of the overlay database. */
overlay[discard_entity]
private predicate discardAstNode(@erb_ast_node node) {
exists(@file file | discardableAstNode(file, node) and discardFile(file))
}
/** A class representing `code` tokens. */
class Code extends @erb_token_code, Token {
/** Gets the name of the primary QL class for this element. */