mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Merge pull request #19989 from github/nickrolfe/ruby-annotations
Ruby: add overlay annotations to AST/CFG/SSA layers
This commit is contained in:
@@ -1,4 +1,6 @@
|
|||||||
/** Provides classes for working with locations. */
|
/** Provides classes for working with locations. */
|
||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
import files.FileSystem
|
import files.FileSystem
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
/** Provides classes for working with files and folders. */
|
/** Provides classes for working with files and folders. */
|
||||||
|
overlay[local?]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql_ql.ast.internal.TreeSitter
|
private import codeql_ql.ast.internal.TreeSitter
|
||||||
private import codeql.Locations
|
private import codeql.Locations
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import ql
|
private import ql
|
||||||
private import codeql_ql.ast.internal.TreeSitter
|
private import codeql_ql.ast.internal.TreeSitter
|
||||||
private import experimental.RA
|
private import experimental.RA
|
||||||
@@ -23,6 +26,7 @@ private float stringToTimestamp(string str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bindingset[s]
|
bindingset[s]
|
||||||
|
overlay[global]
|
||||||
private Predicate getPredicateFromPosition(string s) {
|
private Predicate getPredicateFromPosition(string s) {
|
||||||
exists(string r, string filepath, int startline | r = "(.*):(\\d+),(\\d+)-(\\d+),(\\d+)" |
|
exists(string r, string filepath, int startline | r = "(.*):(\\d+),(\\d+)-(\\d+),(\\d+)" |
|
||||||
filepath = s.regexpCapture(r, 1) and
|
filepath = s.regexpCapture(r, 1) and
|
||||||
@@ -397,6 +401,7 @@ module KindPredicatesLog {
|
|||||||
|
|
||||||
string getPosition() { result = this.getString("position") }
|
string getPosition() { result = this.getString("position") }
|
||||||
|
|
||||||
|
overlay[global]
|
||||||
Predicate getPredicate() { result = getPredicateFromPosition(this.getPosition()) }
|
Predicate getPredicate() { result = getPredicateFromPosition(this.getPosition()) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ private predicate discardLocation(@location_default loc) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlay[local]
|
||||||
module QL {
|
module QL {
|
||||||
/** The base class for all AST nodes */
|
/** The base class for all AST nodes */
|
||||||
class AstNode extends @ql_ast_node {
|
class AstNode extends @ql_ast_node {
|
||||||
@@ -67,7 +68,6 @@ module QL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the file containing the given `node`. */
|
/** Gets the file containing the given `node`. */
|
||||||
overlay[local]
|
|
||||||
private @file getNodeFile(@ql_ast_node node) {
|
private @file getNodeFile(@ql_ast_node node) {
|
||||||
exists(@location_default loc | ql_ast_node_location(node, loc) |
|
exists(@location_default loc | ql_ast_node_location(node, loc) |
|
||||||
locations_default(loc, result, _, _, _, _)
|
locations_default(loc, result, _, _, _, _)
|
||||||
@@ -75,7 +75,6 @@ module QL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Holds if `node` is in the `file` and is part of the overlay base database. */
|
/** Holds if `node` is in the `file` and is part of the overlay base database. */
|
||||||
overlay[local]
|
|
||||||
private predicate discardableAstNode(@file file, @ql_ast_node node) {
|
private predicate discardableAstNode(@file file, @ql_ast_node node) {
|
||||||
not isOverlay() and file = getNodeFile(node)
|
not isOverlay() and file = getNodeFile(node)
|
||||||
}
|
}
|
||||||
@@ -1315,6 +1314,7 @@ module QL {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlay[local]
|
||||||
module Dbscheme {
|
module Dbscheme {
|
||||||
/** The base class for all AST nodes */
|
/** The base class for all AST nodes */
|
||||||
class AstNode extends @dbscheme_ast_node {
|
class AstNode extends @dbscheme_ast_node {
|
||||||
@@ -1359,7 +1359,6 @@ module Dbscheme {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the file containing the given `node`. */
|
/** Gets the file containing the given `node`. */
|
||||||
overlay[local]
|
|
||||||
private @file getNodeFile(@dbscheme_ast_node node) {
|
private @file getNodeFile(@dbscheme_ast_node node) {
|
||||||
exists(@location_default loc | dbscheme_ast_node_location(node, loc) |
|
exists(@location_default loc | dbscheme_ast_node_location(node, loc) |
|
||||||
locations_default(loc, result, _, _, _, _)
|
locations_default(loc, result, _, _, _, _)
|
||||||
@@ -1367,7 +1366,6 @@ module Dbscheme {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Holds if `node` is in the `file` and is part of the overlay base database. */
|
/** Holds if `node` is in the `file` and is part of the overlay base database. */
|
||||||
overlay[local]
|
|
||||||
private predicate discardableAstNode(@file file, @dbscheme_ast_node node) {
|
private predicate discardableAstNode(@file file, @dbscheme_ast_node node) {
|
||||||
not isOverlay() and file = getNodeFile(node)
|
not isOverlay() and file = getNodeFile(node)
|
||||||
}
|
}
|
||||||
@@ -1673,6 +1671,7 @@ module Dbscheme {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlay[local]
|
||||||
module Blame {
|
module Blame {
|
||||||
/** The base class for all AST nodes */
|
/** The base class for all AST nodes */
|
||||||
class AstNode extends @blame_ast_node {
|
class AstNode extends @blame_ast_node {
|
||||||
@@ -1717,7 +1716,6 @@ module Blame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the file containing the given `node`. */
|
/** Gets the file containing the given `node`. */
|
||||||
overlay[local]
|
|
||||||
private @file getNodeFile(@blame_ast_node node) {
|
private @file getNodeFile(@blame_ast_node node) {
|
||||||
exists(@location_default loc | blame_ast_node_location(node, loc) |
|
exists(@location_default loc | blame_ast_node_location(node, loc) |
|
||||||
locations_default(loc, result, _, _, _, _)
|
locations_default(loc, result, _, _, _, _)
|
||||||
@@ -1725,7 +1723,6 @@ module Blame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Holds if `node` is in the `file` and is part of the overlay base database. */
|
/** Holds if `node` is in the `file` and is part of the overlay base database. */
|
||||||
overlay[local]
|
|
||||||
private predicate discardableAstNode(@file file, @blame_ast_node node) {
|
private predicate discardableAstNode(@file file, @blame_ast_node node) {
|
||||||
not isOverlay() and file = getNodeFile(node)
|
not isOverlay() and file = getNodeFile(node)
|
||||||
}
|
}
|
||||||
@@ -1808,6 +1805,7 @@ module Blame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlay[local]
|
||||||
module JSON {
|
module JSON {
|
||||||
/** The base class for all AST nodes */
|
/** The base class for all AST nodes */
|
||||||
class AstNode extends @json_ast_node {
|
class AstNode extends @json_ast_node {
|
||||||
@@ -1852,7 +1850,6 @@ module JSON {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the file containing the given `node`. */
|
/** Gets the file containing the given `node`. */
|
||||||
overlay[local]
|
|
||||||
private @file getNodeFile(@json_ast_node node) {
|
private @file getNodeFile(@json_ast_node node) {
|
||||||
exists(@location_default loc | json_ast_node_location(node, loc) |
|
exists(@location_default loc | json_ast_node_location(node, loc) |
|
||||||
locations_default(loc, result, _, _, _, _)
|
locations_default(loc, result, _, _, _, _)
|
||||||
@@ -1860,7 +1857,6 @@ module JSON {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Holds if `node` is in the `file` and is part of the overlay base database. */
|
/** Holds if `node` is in the `file` and is part of the overlay base database. */
|
||||||
overlay[local]
|
|
||||||
private predicate discardableAstNode(@file file, @json_ast_node node) {
|
private predicate discardableAstNode(@file file, @json_ast_node node) {
|
||||||
not isOverlay() and file = getNodeFile(node)
|
not isOverlay() and file = getNodeFile(node)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
/**
|
overlay[local]
|
||||||
* Parses RA expressions.
|
module;
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A predicate that contains RA.
|
* A predicate that contains RA.
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import ql
|
|||||||
import codeql_ql.StructuredLogs
|
import codeql_ql.StructuredLogs
|
||||||
import KindPredicatesLog
|
import KindPredicatesLog
|
||||||
|
|
||||||
|
overlay[local]
|
||||||
module SumCounts implements Fold<int> {
|
module SumCounts implements Fold<int> {
|
||||||
int base(PipeLineRun run) { result = sum(int i | | run.getCount(i)) }
|
int base(PipeLineRun run) { result = sum(int i | | run.getCount(i)) }
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import experimental.RA
|
import experimental.RA
|
||||||
|
|
||||||
|
overlay[local]
|
||||||
class TestPredicate extends string {
|
class TestPredicate extends string {
|
||||||
TestPredicate() { this = "p1" }
|
TestPredicate() { this = "p1" }
|
||||||
|
|
||||||
|
|||||||
4
ruby/ql/lib/change-notes/2025-07-09-overlay-local.md
Normal file
4
ruby/ql/lib/change-notes/2025-07-09-overlay-local.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: breaking
|
||||||
|
---
|
||||||
|
* Most classes and predicates in the AST, SSA, and control-flow-graph libraries are now annotated with `overlay[local]`, in preparation for incremental analysis. This could result in compiler errors for custom queries if they extend these classes. To mitigate such errors, look for ways to restructure custom QL code so it doesn't depend on changing the behavior of standard-library classes.
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
/** Provides classes for working with locations. */
|
/** Provides classes for working with locations. */
|
||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
import files.FileSystem
|
import files.FileSystem
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
/** Provides classes for working with files and folders. */
|
/** Provides classes for working with files and folders. */
|
||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.Locations
|
private import codeql.Locations
|
||||||
private import codeql.util.FileSystem
|
private import codeql.util.FileSystem
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
import codeql.Locations
|
import codeql.Locations
|
||||||
import ast.Call
|
import ast.Call
|
||||||
import ast.Control
|
import ast.Control
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
/** Provides classes relating to extraction diagnostics. */
|
/** Provides classes relating to extraction diagnostics. */
|
||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.Locations
|
private import codeql.Locations
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import internal.AST
|
private import internal.AST
|
||||||
private import internal.Call
|
private import internal.Call
|
||||||
|
private import internal.Literal
|
||||||
private import internal.TreeSitter
|
private import internal.TreeSitter
|
||||||
private import codeql.ruby.dataflow.internal.DataFlowDispatch
|
private import codeql.ruby.dataflow.internal.DataFlowDispatch
|
||||||
private import codeql.ruby.dataflow.internal.DataFlowImplCommon
|
private import codeql.ruby.dataflow.internal.DataFlowImplCommon
|
||||||
@@ -41,7 +45,7 @@ class Call extends Expr instanceof CallImpl {
|
|||||||
final Expr getKeywordArgument(string keyword) {
|
final Expr getKeywordArgument(string keyword) {
|
||||||
exists(Pair p |
|
exists(Pair p |
|
||||||
p = this.getAnArgument() and
|
p = this.getAnArgument() and
|
||||||
p.getKey().getConstantValue().isSymbol(keyword) and
|
keyword = p.getKey().(SymbolLiteral).(StringlikeLiteralImpl).getStringValue() and
|
||||||
result = p.getValue()
|
result = p.getValue()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -52,6 +56,7 @@ class Call extends Expr instanceof CallImpl {
|
|||||||
final int getNumberOfArguments() { result = super.getNumberOfArgumentsImpl() }
|
final int getNumberOfArguments() { result = super.getNumberOfArgumentsImpl() }
|
||||||
|
|
||||||
/** Gets a potential target of this call, if any. */
|
/** Gets a potential target of this call, if any. */
|
||||||
|
overlay[global]
|
||||||
final Callable getATarget() {
|
final Callable getATarget() {
|
||||||
exists(DataFlowCall c |
|
exists(DataFlowCall c |
|
||||||
this = c.asCall().getExpr() and
|
this = c.asCall().getExpr() and
|
||||||
@@ -153,6 +158,7 @@ class MethodCall extends Call instanceof MethodCallImpl {
|
|||||||
* TODO: When API Graphs is able to resolve calls to methods like `Kernel.send`
|
* TODO: When API Graphs is able to resolve calls to methods like `Kernel.send`
|
||||||
* this class is no longer necessary and should be removed.
|
* this class is no longer necessary and should be removed.
|
||||||
*/
|
*/
|
||||||
|
overlay[global]
|
||||||
class UnknownMethodCall extends MethodCall {
|
class UnknownMethodCall extends MethodCall {
|
||||||
UnknownMethodCall() { not exists(this.(Call).getATarget()) }
|
UnknownMethodCall() { not exists(this.(Call).getATarget()) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import internal.AST
|
private import internal.AST
|
||||||
private import internal.Constant
|
private import internal.Constant
|
||||||
@@ -6,6 +9,7 @@ private import internal.Variable
|
|||||||
private import internal.TreeSitter
|
private import internal.TreeSitter
|
||||||
|
|
||||||
/** A constant value. */
|
/** A constant value. */
|
||||||
|
overlay[global]
|
||||||
class ConstantValue extends TConstantValue {
|
class ConstantValue extends TConstantValue {
|
||||||
/** Gets a textual representation of this constant value. */
|
/** Gets a textual representation of this constant value. */
|
||||||
final string toString() { this.hasValueWithType(result, _) }
|
final string toString() { this.hasValueWithType(result, _) }
|
||||||
@@ -134,6 +138,7 @@ class ConstantValue extends TConstantValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Provides different sub classes of `ConstantValue`. */
|
/** Provides different sub classes of `ConstantValue`. */
|
||||||
|
overlay[global]
|
||||||
module ConstantValue {
|
module ConstantValue {
|
||||||
/** A constant integer value. */
|
/** A constant integer value. */
|
||||||
class ConstantIntegerValue extends ConstantValue, TInt { }
|
class ConstantIntegerValue extends ConstantValue, TInt { }
|
||||||
@@ -268,15 +273,18 @@ class ConstantReadAccess extends ConstantAccess {
|
|||||||
*
|
*
|
||||||
* the value being read at `M::CONST` is `"const"`.
|
* the value being read at `M::CONST` is `"const"`.
|
||||||
*/
|
*/
|
||||||
|
overlay[global]
|
||||||
Expr getValue() { result = getConstantReadAccessValue(this) }
|
Expr getValue() { result = getConstantReadAccessValue(this) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a fully qualified name for this constant read, based on the context in
|
* Gets a fully qualified name for this constant read, based on the context in
|
||||||
* which it occurs.
|
* which it occurs.
|
||||||
*/
|
*/
|
||||||
|
overlay[global]
|
||||||
string getAQualifiedName() { result = resolveConstant(this) }
|
string getAQualifiedName() { result = resolveConstant(this) }
|
||||||
|
|
||||||
/** Gets the module that this read access resolves to, if any. */
|
/** Gets the module that this read access resolves to, if any. */
|
||||||
|
overlay[global]
|
||||||
Module getModule() { result = resolveConstantReadAccess(this) }
|
Module getModule() { result = resolveConstantReadAccess(this) }
|
||||||
|
|
||||||
final override string getAPrimaryQlClass() { result = "ConstantReadAccess" }
|
final override string getAPrimaryQlClass() { result = "ConstantReadAccess" }
|
||||||
@@ -342,6 +350,7 @@ class ConstantWriteAccess extends ConstantAccess {
|
|||||||
* constants up the namespace chain, the fully qualified name of a nested
|
* constants up the namespace chain, the fully qualified name of a nested
|
||||||
* constant can be ambiguous from just statically looking at the AST.
|
* constant can be ambiguous from just statically looking at the AST.
|
||||||
*/
|
*/
|
||||||
|
overlay[global]
|
||||||
string getAQualifiedName() { result = resolveConstantWrite(this) }
|
string getAQualifiedName() { result = resolveConstantWrite(this) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import internal.AST
|
private import internal.AST
|
||||||
private import internal.Control
|
private import internal.Control
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import internal.Erb
|
private import internal.Erb
|
||||||
private import internal.TreeSitter
|
private import internal.TreeSitter
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import codeql.ruby.CFG
|
private import codeql.ruby.CFG
|
||||||
private import internal.AST
|
private import internal.AST
|
||||||
@@ -12,6 +15,7 @@ private import internal.TreeSitter
|
|||||||
*/
|
*/
|
||||||
class Expr extends Stmt, TExpr {
|
class Expr extends Stmt, TExpr {
|
||||||
/** Gets the constant value of this expression, if any. */
|
/** Gets the constant value of this expression, if any. */
|
||||||
|
overlay[global]
|
||||||
ConstantValue getConstantValue() { result = getConstantValueExpr(this) }
|
ConstantValue getConstantValue() { result = getConstantValueExpr(this) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -425,6 +429,7 @@ class StringConcatenation extends Expr, TStringConcatenation {
|
|||||||
* "foo" "bar#{ n }"
|
* "foo" "bar#{ n }"
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
|
overlay[global]
|
||||||
final string getConcatenatedValueText() {
|
final string getConcatenatedValueText() {
|
||||||
forall(StringLiteral c | c = this.getString(_) |
|
forall(StringLiteral c | c = this.getString(_) |
|
||||||
exists(c.getConstantValue().getStringlikeValue())
|
exists(c.getConstantValue().getStringlikeValue())
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import codeql.ruby.Regexp as RE
|
private import codeql.ruby.Regexp as RE
|
||||||
private import internal.AST
|
private import internal.AST
|
||||||
@@ -41,6 +44,7 @@ class IntegerLiteral extends NumericLiteral instanceof IntegerLiteralImpl {
|
|||||||
/** Gets the numerical value of this integer literal. */
|
/** Gets the numerical value of this integer literal. */
|
||||||
final int getValue() { result = super.getValue() }
|
final int getValue() { result = super.getValue() }
|
||||||
|
|
||||||
|
overlay[global]
|
||||||
final override ConstantValue::ConstantIntegerValue getConstantValue() {
|
final override ConstantValue::ConstantIntegerValue getConstantValue() {
|
||||||
result = NumericLiteral.super.getConstantValue()
|
result = NumericLiteral.super.getConstantValue()
|
||||||
}
|
}
|
||||||
@@ -57,6 +61,7 @@ class IntegerLiteral extends NumericLiteral instanceof IntegerLiteralImpl {
|
|||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
class FloatLiteral extends NumericLiteral instanceof FloatLiteralImpl {
|
class FloatLiteral extends NumericLiteral instanceof FloatLiteralImpl {
|
||||||
|
overlay[global]
|
||||||
final override ConstantValue::ConstantFloatValue getConstantValue() {
|
final override ConstantValue::ConstantFloatValue getConstantValue() {
|
||||||
result = NumericLiteral.super.getConstantValue()
|
result = NumericLiteral.super.getConstantValue()
|
||||||
}
|
}
|
||||||
@@ -72,6 +77,7 @@ class FloatLiteral extends NumericLiteral instanceof FloatLiteralImpl {
|
|||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
class RationalLiteral extends NumericLiteral instanceof RationalLiteralImpl {
|
class RationalLiteral extends NumericLiteral instanceof RationalLiteralImpl {
|
||||||
|
overlay[global]
|
||||||
final override ConstantValue::ConstantRationalValue getConstantValue() {
|
final override ConstantValue::ConstantRationalValue getConstantValue() {
|
||||||
result = NumericLiteral.super.getConstantValue()
|
result = NumericLiteral.super.getConstantValue()
|
||||||
}
|
}
|
||||||
@@ -87,6 +93,7 @@ class RationalLiteral extends NumericLiteral instanceof RationalLiteralImpl {
|
|||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
class ComplexLiteral extends NumericLiteral instanceof ComplexLiteralImpl {
|
class ComplexLiteral extends NumericLiteral instanceof ComplexLiteralImpl {
|
||||||
|
overlay[global]
|
||||||
final override ConstantValue::ConstantComplexValue getConstantValue() {
|
final override ConstantValue::ConstantComplexValue getConstantValue() {
|
||||||
result = NumericLiteral.super.getConstantValue()
|
result = NumericLiteral.super.getConstantValue()
|
||||||
}
|
}
|
||||||
@@ -96,6 +103,7 @@ class ComplexLiteral extends NumericLiteral instanceof ComplexLiteralImpl {
|
|||||||
|
|
||||||
/** A `nil` literal. */
|
/** A `nil` literal. */
|
||||||
class NilLiteral extends Literal instanceof NilLiteralImpl {
|
class NilLiteral extends Literal instanceof NilLiteralImpl {
|
||||||
|
overlay[global]
|
||||||
final override ConstantValue::ConstantNilValue getConstantValue() { result = TNil() }
|
final override ConstantValue::ConstantNilValue getConstantValue() { result = TNil() }
|
||||||
|
|
||||||
final override string getAPrimaryQlClass() { result = "NilLiteral" }
|
final override string getAPrimaryQlClass() { result = "NilLiteral" }
|
||||||
@@ -122,6 +130,7 @@ class BooleanLiteral extends Literal instanceof BooleanLiteralImpl {
|
|||||||
/** Gets the value of this Boolean literal. */
|
/** Gets the value of this Boolean literal. */
|
||||||
boolean getValue() { result = super.getValue() }
|
boolean getValue() { result = super.getValue() }
|
||||||
|
|
||||||
|
overlay[global]
|
||||||
final override ConstantValue::ConstantBooleanValue getConstantValue() {
|
final override ConstantValue::ConstantBooleanValue getConstantValue() {
|
||||||
result = Literal.super.getConstantValue()
|
result = Literal.super.getConstantValue()
|
||||||
}
|
}
|
||||||
@@ -133,6 +142,7 @@ class BooleanLiteral extends Literal instanceof BooleanLiteralImpl {
|
|||||||
class EncodingLiteral extends Literal instanceof EncodingLiteralImpl {
|
class EncodingLiteral extends Literal instanceof EncodingLiteralImpl {
|
||||||
final override string getAPrimaryQlClass() { result = "EncodingLiteral" }
|
final override string getAPrimaryQlClass() { result = "EncodingLiteral" }
|
||||||
|
|
||||||
|
overlay[global]
|
||||||
final override ConstantValue::ConstantStringValue getConstantValue() {
|
final override ConstantValue::ConstantStringValue getConstantValue() {
|
||||||
result = Literal.super.getConstantValue()
|
result = Literal.super.getConstantValue()
|
||||||
}
|
}
|
||||||
@@ -144,6 +154,7 @@ class EncodingLiteral extends Literal instanceof EncodingLiteralImpl {
|
|||||||
class LineLiteral extends Literal instanceof LineLiteralImpl {
|
class LineLiteral extends Literal instanceof LineLiteralImpl {
|
||||||
final override string getAPrimaryQlClass() { result = "LineLiteral" }
|
final override string getAPrimaryQlClass() { result = "LineLiteral" }
|
||||||
|
|
||||||
|
overlay[global]
|
||||||
final override ConstantValue::ConstantIntegerValue getConstantValue() {
|
final override ConstantValue::ConstantIntegerValue getConstantValue() {
|
||||||
result = Literal.super.getConstantValue()
|
result = Literal.super.getConstantValue()
|
||||||
}
|
}
|
||||||
@@ -155,6 +166,7 @@ class LineLiteral extends Literal instanceof LineLiteralImpl {
|
|||||||
class FileLiteral extends Literal instanceof FileLiteralImpl {
|
class FileLiteral extends Literal instanceof FileLiteralImpl {
|
||||||
final override string getAPrimaryQlClass() { result = "FileLiteral" }
|
final override string getAPrimaryQlClass() { result = "FileLiteral" }
|
||||||
|
|
||||||
|
overlay[global]
|
||||||
final override ConstantValue::ConstantStringValue getConstantValue() {
|
final override ConstantValue::ConstantStringValue getConstantValue() {
|
||||||
result = Literal.super.getConstantValue()
|
result = Literal.super.getConstantValue()
|
||||||
}
|
}
|
||||||
@@ -166,6 +178,7 @@ class FileLiteral extends Literal instanceof FileLiteralImpl {
|
|||||||
*/
|
*/
|
||||||
class StringComponent extends AstNode instanceof StringComponentImpl {
|
class StringComponent extends AstNode instanceof StringComponentImpl {
|
||||||
/** Gets the constant value of this string component, if any. */
|
/** Gets the constant value of this string component, if any. */
|
||||||
|
overlay[global]
|
||||||
ConstantValue::ConstantStringValue getConstantValue() { result = TString(super.getValue()) }
|
ConstantValue::ConstantStringValue getConstantValue() { result = TString(super.getValue()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,6 +223,7 @@ class StringInterpolationComponent extends StringComponent, StmtSequence instanc
|
|||||||
|
|
||||||
final override Stmt getStmt(int n) { toGenerated(result) = g.getChild(n) }
|
final override Stmt getStmt(int n) { toGenerated(result) = g.getChild(n) }
|
||||||
|
|
||||||
|
overlay[global]
|
||||||
final override ConstantValue::ConstantStringValue getConstantValue() {
|
final override ConstantValue::ConstantStringValue getConstantValue() {
|
||||||
result = StmtSequence.super.getConstantValue()
|
result = StmtSequence.super.getConstantValue()
|
||||||
}
|
}
|
||||||
@@ -257,6 +271,7 @@ class RegExpInterpolationComponent extends RegExpComponent, StmtSequence instanc
|
|||||||
|
|
||||||
final override Stmt getStmt(int n) { toGenerated(result) = g.getChild(n) }
|
final override Stmt getStmt(int n) { toGenerated(result) = g.getChild(n) }
|
||||||
|
|
||||||
|
overlay[global]
|
||||||
final override ConstantValue::ConstantStringValue getConstantValue() {
|
final override ConstantValue::ConstantStringValue getConstantValue() {
|
||||||
result = StmtSequence.super.getConstantValue()
|
result = StmtSequence.super.getConstantValue()
|
||||||
}
|
}
|
||||||
@@ -387,6 +402,7 @@ class RegExpLiteral extends StringlikeLiteral instanceof RegExpLiteralImpl {
|
|||||||
final predicate hasFreeSpacingFlag() { this.getFlagString().charAt(_) = "x" }
|
final predicate hasFreeSpacingFlag() { this.getFlagString().charAt(_) = "x" }
|
||||||
|
|
||||||
/** Returns the root node of the parse tree of this regular expression. */
|
/** Returns the root node of the parse tree of this regular expression. */
|
||||||
|
overlay[global]
|
||||||
final RE::RegExpTerm getParsed() { result = RE::getParsedRegExp(this) }
|
final RE::RegExpTerm getParsed() { result = RE::getParsedRegExp(this) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -404,6 +420,7 @@ class SymbolLiteral extends StringlikeLiteral instanceof SymbolLiteralImpl {
|
|||||||
not this instanceof MethodName and result = "SymbolLiteral"
|
not this instanceof MethodName and result = "SymbolLiteral"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlay[global]
|
||||||
final override ConstantValue::ConstantSymbolValue getConstantValue() {
|
final override ConstantValue::ConstantSymbolValue getConstantValue() {
|
||||||
result = StringlikeLiteral.super.getConstantValue()
|
result = StringlikeLiteral.super.getConstantValue()
|
||||||
}
|
}
|
||||||
@@ -436,6 +453,7 @@ class SubshellLiteral extends StringlikeLiteral instanceof SubshellLiteralImpl {
|
|||||||
class CharacterLiteral extends Literal instanceof CharacterLiteralImpl {
|
class CharacterLiteral extends Literal instanceof CharacterLiteralImpl {
|
||||||
final override string getAPrimaryQlClass() { result = "CharacterLiteral" }
|
final override string getAPrimaryQlClass() { result = "CharacterLiteral" }
|
||||||
|
|
||||||
|
overlay[global]
|
||||||
final override ConstantValue::ConstantStringValue getConstantValue() {
|
final override ConstantValue::ConstantStringValue getConstantValue() {
|
||||||
result = Literal.super.getConstantValue()
|
result = Literal.super.getConstantValue()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import codeql.ruby.controlflow.ControlFlowGraph
|
private import codeql.ruby.controlflow.ControlFlowGraph
|
||||||
private import internal.AST
|
private import internal.AST
|
||||||
@@ -40,18 +43,22 @@ class MethodBase extends Callable, BodyStmt, Scope, TMethodBase {
|
|||||||
* Holds if this method is public.
|
* Holds if this method is public.
|
||||||
* Methods are public by default.
|
* Methods are public by default.
|
||||||
*/
|
*/
|
||||||
|
overlay[global]
|
||||||
predicate isPublic() { this.getVisibility() = "public" }
|
predicate isPublic() { this.getVisibility() = "public" }
|
||||||
|
|
||||||
/** Holds if this method is private. */
|
/** Holds if this method is private. */
|
||||||
|
overlay[global]
|
||||||
predicate isPrivate() { this.getVisibility() = "private" }
|
predicate isPrivate() { this.getVisibility() = "private" }
|
||||||
|
|
||||||
/** Holds if this method is protected. */
|
/** Holds if this method is protected. */
|
||||||
|
overlay[global]
|
||||||
predicate isProtected() { this.getVisibility() = "protected" }
|
predicate isProtected() { this.getVisibility() = "protected" }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a string describing the visibility of this method.
|
* Gets a string describing the visibility of this method.
|
||||||
* This is either 'public', 'private' or 'protected'.
|
* This is either 'public', 'private' or 'protected'.
|
||||||
*/
|
*/
|
||||||
|
overlay[global]
|
||||||
string getVisibility() {
|
string getVisibility() {
|
||||||
result = getVisibilityModifier(this).getVisibility()
|
result = getVisibilityModifier(this).getVisibility()
|
||||||
or
|
or
|
||||||
@@ -73,6 +80,7 @@ class MethodBase extends Callable, BodyStmt, Scope, TMethodBase {
|
|||||||
* end
|
* end
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
|
overlay[global]
|
||||||
private VisibilityModifier getExplicitVisibilityModifier(Method m) {
|
private VisibilityModifier getExplicitVisibilityModifier(Method m) {
|
||||||
result.getMethodArgument() = m
|
result.getMethodArgument() = m
|
||||||
or
|
or
|
||||||
@@ -86,6 +94,7 @@ private VisibilityModifier getExplicitVisibilityModifier(Method m) {
|
|||||||
* Gets the visibility modifier that defines the visibility of method `m`, if
|
* Gets the visibility modifier that defines the visibility of method `m`, if
|
||||||
* any.
|
* any.
|
||||||
*/
|
*/
|
||||||
|
overlay[global]
|
||||||
private VisibilityModifier getVisibilityModifier(MethodBase mb) {
|
private VisibilityModifier getVisibilityModifier(MethodBase mb) {
|
||||||
mb =
|
mb =
|
||||||
any(Method m |
|
any(Method m |
|
||||||
@@ -202,6 +211,7 @@ class Method extends MethodBase, TMethod {
|
|||||||
* end
|
* end
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
|
overlay[global]
|
||||||
override predicate isPrivate() { super.isPrivate() }
|
override predicate isPrivate() { super.isPrivate() }
|
||||||
|
|
||||||
final override Parameter getParameter(int n) {
|
final override Parameter getParameter(int n) {
|
||||||
@@ -210,6 +220,7 @@ class Method extends MethodBase, TMethod {
|
|||||||
|
|
||||||
final override string toString() { result = this.getName() }
|
final override string toString() { result = this.getName() }
|
||||||
|
|
||||||
|
overlay[global]
|
||||||
override string getVisibility() {
|
override string getVisibility() {
|
||||||
result = getVisibilityModifier(this).getVisibility()
|
result = getVisibilityModifier(this).getVisibility()
|
||||||
or
|
or
|
||||||
@@ -223,6 +234,7 @@ class Method extends MethodBase, TMethod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlay[global]
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate modifiesIn(VisibilityModifier vm, ModuleBase n, string name) {
|
private predicate modifiesIn(VisibilityModifier vm, ModuleBase n, string name) {
|
||||||
n = vm.getEnclosingModule() and
|
n = vm.getEnclosingModule() and
|
||||||
@@ -299,6 +311,7 @@ class SingletonMethod extends MethodBase, TSingletonMethod {
|
|||||||
* end
|
* end
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
|
overlay[global]
|
||||||
override predicate isPrivate() { super.isPrivate() }
|
override predicate isPrivate() { super.isPrivate() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import codeql.ruby.CFG
|
private import codeql.ruby.CFG
|
||||||
private import internal.AST
|
private import internal.AST
|
||||||
@@ -8,6 +11,7 @@ private import internal.Scope
|
|||||||
/**
|
/**
|
||||||
* A representation of a run-time `module` or `class` value.
|
* A representation of a run-time `module` or `class` value.
|
||||||
*/
|
*/
|
||||||
|
overlay[global]
|
||||||
class Module extends TModule {
|
class Module extends TModule {
|
||||||
/** Gets a declaration of this module, if any. */
|
/** Gets a declaration of this module, if any. */
|
||||||
ModuleBase getADeclaration() { result.getModule() = this }
|
ModuleBase getADeclaration() { result.getModule() = this }
|
||||||
@@ -255,6 +259,7 @@ class ModuleBase extends BodyStmt, Scope, TModuleBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the representation of the run-time value of this module or class. */
|
/** Gets the representation of the run-time value of this module or class. */
|
||||||
|
overlay[global]
|
||||||
Module getModule() { none() }
|
Module getModule() { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -333,6 +338,7 @@ class Toplevel extends ModuleBase, TToplevel {
|
|||||||
pred = "getBeginBlock" and result = this.getBeginBlock(_)
|
pred = "getBeginBlock" and result = this.getBeginBlock(_)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlay[global]
|
||||||
final override Module getModule() { result = TResolved("Object") }
|
final override Module getModule() { result = TResolved("Object") }
|
||||||
|
|
||||||
final override string toString() { result = g.getLocation().getFile().getBaseName() }
|
final override string toString() { result = g.getLocation().getFile().getBaseName() }
|
||||||
@@ -405,6 +411,7 @@ class Namespace extends ModuleBase, ConstantWriteAccess, TNamespace {
|
|||||||
*/
|
*/
|
||||||
override predicate hasGlobalScope() { none() }
|
override predicate hasGlobalScope() { none() }
|
||||||
|
|
||||||
|
overlay[global]
|
||||||
final override Module getModule() {
|
final override Module getModule() {
|
||||||
result = any(string qName | qName = namespaceDeclaration(this) | TResolved(qName))
|
result = any(string qName | qName = namespaceDeclaration(this) | TResolved(qName))
|
||||||
or
|
or
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import internal.AST
|
private import internal.AST
|
||||||
private import internal.TreeSitter
|
private import internal.TreeSitter
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import internal.AST
|
private import internal.AST
|
||||||
private import internal.Variable
|
private import internal.Variable
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import internal.AST
|
private import internal.AST
|
||||||
private import internal.Pattern
|
private import internal.Pattern
|
||||||
@@ -203,6 +206,7 @@ class HashPattern extends CasePattern, THashPattern {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the value for a given key name. */
|
/** Gets the value for a given key name. */
|
||||||
|
overlay[global]
|
||||||
CasePattern getValueByKey(string key) {
|
CasePattern getValueByKey(string key) {
|
||||||
exists(int i |
|
exists(int i |
|
||||||
this.getKey(i).getConstantValue().isStringlikeValue(key) and result = this.getValue(i)
|
this.getKey(i).getConstantValue().isStringlikeValue(key) and result = this.getValue(i)
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import internal.AST
|
private import internal.AST
|
||||||
private import internal.Scope
|
private import internal.Scope
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import codeql.ruby.CFG
|
private import codeql.ruby.CFG
|
||||||
private import internal.AST
|
private import internal.AST
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
/** Provides classes for modeling program variables. */
|
/** Provides classes for modeling program variables. */
|
||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import internal.AST
|
private import internal.AST
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
import codeql.Locations
|
import codeql.Locations
|
||||||
private import TreeSitter
|
private import TreeSitter
|
||||||
private import codeql.ruby.ast.internal.Call
|
private import codeql.ruby.ast.internal.Call
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import TreeSitter
|
private import TreeSitter
|
||||||
private import Variable
|
private import Variable
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ private import ExprNodes
|
|||||||
* constant value in some cases.
|
* constant value in some cases.
|
||||||
*/
|
*/
|
||||||
private module Propagation {
|
private module Propagation {
|
||||||
|
overlay[local]
|
||||||
ExprCfgNode getSource(VariableReadAccessCfgNode read) {
|
ExprCfgNode getSource(VariableReadAccessCfgNode read) {
|
||||||
exists(Ssa::WriteDefinition def |
|
exists(Ssa::WriteDefinition def |
|
||||||
def.assigns(result) and
|
def.assigns(result) and
|
||||||
@@ -199,6 +200,7 @@ private module Propagation {
|
|||||||
forex(ExprCfgNode n | n = e.getAControlFlowNode() | isComplex(n, real, imaginary))
|
forex(ExprCfgNode n | n = e.getAControlFlowNode() | isComplex(n, real, imaginary))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlay[local]
|
||||||
private class StringlikeLiteralWithInterpolationCfgNode extends StringlikeLiteralCfgNode {
|
private class StringlikeLiteralWithInterpolationCfgNode extends StringlikeLiteralCfgNode {
|
||||||
StringlikeLiteralWithInterpolationCfgNode() {
|
StringlikeLiteralWithInterpolationCfgNode() {
|
||||||
this.getAComponent() =
|
this.getAComponent() =
|
||||||
@@ -208,6 +210,7 @@ private module Propagation {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlay[global]
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private string getComponentValue(int i) {
|
private string getComponentValue(int i) {
|
||||||
this.getComponent(i) =
|
this.getComponent(i) =
|
||||||
@@ -219,17 +222,20 @@ private module Propagation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
language[monotonicAggregates]
|
language[monotonicAggregates]
|
||||||
|
overlay[global]
|
||||||
private string getValue() {
|
private string getValue() {
|
||||||
result =
|
result =
|
||||||
strictconcat(int i | exists(this.getComponent(i)) | this.getComponentValue(i) order by i)
|
strictconcat(int i | exists(this.getComponent(i)) | this.getComponentValue(i) order by i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlay[global]
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
string getSymbolValue() {
|
string getSymbolValue() {
|
||||||
result = this.getValue() and
|
result = this.getValue() and
|
||||||
this.getExpr() instanceof SymbolLiteral
|
this.getExpr() instanceof SymbolLiteral
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlay[global]
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
string getStringValue() {
|
string getStringValue() {
|
||||||
result = this.getValue() and
|
result = this.getValue() and
|
||||||
@@ -237,6 +243,7 @@ private module Propagation {
|
|||||||
not this.getExpr() instanceof RegExpLiteral
|
not this.getExpr() instanceof RegExpLiteral
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlay[global]
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
string getRegExpValue(string flags) {
|
string getRegExpValue(string flags) {
|
||||||
result = this.getValue() and
|
result = this.getValue() and
|
||||||
@@ -566,6 +573,7 @@ private predicate isArrayExpr(Expr e, ArrayLiteralCfgNode arr) {
|
|||||||
isArrayExpr(e.(MethodCall).getReceiver(), arr)
|
isArrayExpr(e.(MethodCall).getReceiver(), arr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlay[local]
|
||||||
private class TokenConstantAccess extends ConstantAccess, TTokenConstantAccess {
|
private class TokenConstantAccess extends ConstantAccess, TTokenConstantAccess {
|
||||||
private Ruby::Constant g;
|
private Ruby::Constant g;
|
||||||
|
|
||||||
@@ -577,6 +585,7 @@ private class TokenConstantAccess extends ConstantAccess, TTokenConstantAccess {
|
|||||||
/**
|
/**
|
||||||
* A constant access that has a scope resolution qualifier.
|
* A constant access that has a scope resolution qualifier.
|
||||||
*/
|
*/
|
||||||
|
overlay[local]
|
||||||
class ScopeResolutionConstantAccess extends ConstantAccess, TScopeResolutionConstantAccess {
|
class ScopeResolutionConstantAccess extends ConstantAccess, TScopeResolutionConstantAccess {
|
||||||
private Ruby::ScopeResolution g;
|
private Ruby::ScopeResolution g;
|
||||||
private Ruby::Constant constant;
|
private Ruby::Constant constant;
|
||||||
@@ -595,6 +604,7 @@ class ScopeResolutionConstantAccess extends ConstantAccess, TScopeResolutionCons
|
|||||||
final override predicate hasGlobalScope() { not exists(g.getScope()) }
|
final override predicate hasGlobalScope() { not exists(g.getScope()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlay[local]
|
||||||
private class ConstantReadAccessSynth extends ConstantAccess, TConstantReadAccessSynth {
|
private class ConstantReadAccessSynth extends ConstantAccess, TConstantReadAccessSynth {
|
||||||
private string value;
|
private string value;
|
||||||
|
|
||||||
@@ -609,6 +619,7 @@ private class ConstantReadAccessSynth extends ConstantAccess, TConstantReadAcces
|
|||||||
final override predicate hasGlobalScope() { value.matches("::%") }
|
final override predicate hasGlobalScope() { value.matches("::%") }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlay[local]
|
||||||
private class ConstantWriteAccessSynth extends ConstantAccess, TConstantWriteAccessSynth {
|
private class ConstantWriteAccessSynth extends ConstantAccess, TConstantWriteAccessSynth {
|
||||||
private string value;
|
private string value;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import TreeSitter
|
private import TreeSitter
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import codeql.ruby.ast.internal.AST
|
private import codeql.ruby.ast.internal.AST
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
import codeql.Locations
|
import codeql.Locations
|
||||||
private import TreeSitter
|
private import TreeSitter
|
||||||
private import codeql.ruby.ast.Erb
|
private import codeql.ruby.ast.Erb
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import codeql.ruby.CFG
|
private import codeql.ruby.CFG
|
||||||
private import AST
|
private import AST
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import AST
|
private import AST
|
||||||
private import Constant
|
private import Constant
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import AST
|
private import AST
|
||||||
private import TreeSitter
|
private import TreeSitter
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import Scope as Scope
|
private import Scope as Scope
|
||||||
|
|
||||||
@@ -11,6 +14,7 @@ private string builtin() {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlay[global]
|
||||||
cached
|
cached
|
||||||
private module Cached {
|
private module Cached {
|
||||||
cached
|
cached
|
||||||
@@ -215,6 +219,7 @@ private string scopeAppend(string qualifier, string name) {
|
|||||||
* both as a performance optimization (minimize non-linear recursion), and as a way
|
* both as a performance optimization (minimize non-linear recursion), and as a way
|
||||||
* to prevent infinite recursion.
|
* to prevent infinite recursion.
|
||||||
*/
|
*/
|
||||||
|
overlay[global]
|
||||||
private module ResolveImpl {
|
private module ResolveImpl {
|
||||||
private ModuleBase enclosing(ModuleBase m, int level) {
|
private ModuleBase enclosing(ModuleBase m, int level) {
|
||||||
result = m and level = 0
|
result = m and level = 0
|
||||||
@@ -583,6 +588,7 @@ private ModuleBase enclosingModuleNoBlock(Stmt node) {
|
|||||||
result = enclosingScopesNoBlock(Scope::scopeOfInclSynth(node))
|
result = enclosingScopesNoBlock(Scope::scopeOfInclSynth(node))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlay[global]
|
||||||
private Module getAncestors(Module m) {
|
private Module getAncestors(Module m) {
|
||||||
result = m or
|
result = m or
|
||||||
result = getAncestors(m.getAnIncludedModule()) or
|
result = getAncestors(m.getAnIncludedModule()) or
|
||||||
@@ -593,6 +599,7 @@ private newtype TMethodOrExpr =
|
|||||||
TMethod(Method m) or
|
TMethod(Method m) or
|
||||||
TExpr(Expr e)
|
TExpr(Expr e)
|
||||||
|
|
||||||
|
overlay[global]
|
||||||
private TMethodOrExpr getMethodOrConst(TModule owner, string name) {
|
private TMethodOrExpr getMethodOrConst(TModule owner, string name) {
|
||||||
exists(ModuleBase m | m.getModule() = owner |
|
exists(ModuleBase m | m.getModule() = owner |
|
||||||
result = TMethod(m.getMethod(name))
|
result = TMethod(m.getMethod(name))
|
||||||
@@ -601,12 +608,14 @@ private TMethodOrExpr getMethodOrConst(TModule owner, string name) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlay[global]
|
||||||
module ExposedForTestingOnly {
|
module ExposedForTestingOnly {
|
||||||
Method getMethod(TModule owner, string name) { TMethod(result) = getMethodOrConst(owner, name) }
|
Method getMethod(TModule owner, string name) { TMethod(result) = getMethodOrConst(owner, name) }
|
||||||
|
|
||||||
Expr getConst(TModule owner, string name) { TExpr(result) = getMethodOrConst(owner, name) }
|
Expr getConst(TModule owner, string name) { TExpr(result) = getMethodOrConst(owner, name) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlay[global]
|
||||||
private TMethodOrExpr lookupMethodOrConst0(Module m, string name) {
|
private TMethodOrExpr lookupMethodOrConst0(Module m, string name) {
|
||||||
result = lookupMethodOrConst0(m.getAPrependedModule(), name)
|
result = lookupMethodOrConst0(m.getAPrependedModule(), name)
|
||||||
or
|
or
|
||||||
@@ -621,6 +630,7 @@ private TMethodOrExpr lookupMethodOrConst0(Module m, string name) {
|
|||||||
|
|
||||||
private AstNode getNode(TMethodOrExpr e) { e = TMethod(result) or e = TExpr(result) }
|
private AstNode getNode(TMethodOrExpr e) { e = TMethod(result) or e = TExpr(result) }
|
||||||
|
|
||||||
|
overlay[global]
|
||||||
private TMethodOrExpr lookupMethodOrConst(Module m, string name) {
|
private TMethodOrExpr lookupMethodOrConst(Module m, string name) {
|
||||||
result = lookupMethodOrConst0(m, name)
|
result = lookupMethodOrConst0(m, name)
|
||||||
or
|
or
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import AST
|
private import AST
|
||||||
private import TreeSitter
|
private import TreeSitter
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import AST
|
private import AST
|
||||||
private import TreeSitter
|
private import TreeSitter
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import codeql.ruby.ast.internal.Expr
|
private import codeql.ruby.ast.internal.Expr
|
||||||
private import codeql.ruby.ast.internal.Parameter
|
private import codeql.ruby.ast.internal.Parameter
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import TreeSitter
|
private import TreeSitter
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import codeql.ruby.ast.internal.AST
|
private import codeql.ruby.ast.internal.AST
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
/** Provides predicates for synthesizing AST nodes. */
|
/** Provides predicates for synthesizing AST nodes. */
|
||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import AST
|
private import AST
|
||||||
private import TreeSitter
|
private import TreeSitter
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ private predicate discardLocation(@location_default loc) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlay[local]
|
||||||
module Ruby {
|
module Ruby {
|
||||||
/** The base class for all AST nodes */
|
/** The base class for all AST nodes */
|
||||||
class AstNode extends @ruby_ast_node {
|
class AstNode extends @ruby_ast_node {
|
||||||
@@ -67,7 +68,6 @@ module Ruby {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the file containing the given `node`. */
|
/** Gets the file containing the given `node`. */
|
||||||
overlay[local]
|
|
||||||
private @file getNodeFile(@ruby_ast_node node) {
|
private @file getNodeFile(@ruby_ast_node node) {
|
||||||
exists(@location_default loc | ruby_ast_node_location(node, loc) |
|
exists(@location_default loc | ruby_ast_node_location(node, loc) |
|
||||||
locations_default(loc, result, _, _, _, _)
|
locations_default(loc, result, _, _, _, _)
|
||||||
@@ -75,7 +75,6 @@ module Ruby {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Holds if `node` is in the `file` and is part of the overlay base database. */
|
/** 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) {
|
private predicate discardableAstNode(@file file, @ruby_ast_node node) {
|
||||||
not isOverlay() and file = getNodeFile(node)
|
not isOverlay() and file = getNodeFile(node)
|
||||||
}
|
}
|
||||||
@@ -1967,6 +1966,7 @@ module Ruby {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlay[local]
|
||||||
module Erb {
|
module Erb {
|
||||||
/** The base class for all AST nodes */
|
/** The base class for all AST nodes */
|
||||||
class AstNode extends @erb_ast_node {
|
class AstNode extends @erb_ast_node {
|
||||||
@@ -2011,7 +2011,6 @@ module Erb {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the file containing the given `node`. */
|
/** Gets the file containing the given `node`. */
|
||||||
overlay[local]
|
|
||||||
private @file getNodeFile(@erb_ast_node node) {
|
private @file getNodeFile(@erb_ast_node node) {
|
||||||
exists(@location_default loc | erb_ast_node_location(node, loc) |
|
exists(@location_default loc | erb_ast_node_location(node, loc) |
|
||||||
locations_default(loc, result, _, _, _, _)
|
locations_default(loc, result, _, _, _, _)
|
||||||
@@ -2019,7 +2018,6 @@ module Erb {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Holds if `node` is in the `file` and is part of the overlay base database. */
|
/** 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) {
|
private predicate discardableAstNode(@file file, @erb_ast_node node) {
|
||||||
not isOverlay() and file = getNodeFile(node)
|
not isOverlay() and file = getNodeFile(node)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import TreeSitter
|
private import TreeSitter
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import codeql.ruby.CFG
|
private import codeql.ruby.CFG
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
/** Provides classes representing basic blocks. */
|
/** Provides classes representing basic blocks. */
|
||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import codeql.ruby.ast.internal.AST
|
private import codeql.ruby.ast.internal.AST
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
/** Provides classes representing nodes in a control flow graph. */
|
/** Provides classes representing nodes in a control flow graph. */
|
||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import codeql.ruby.controlflow.BasicBlocks
|
private import codeql.ruby.controlflow.BasicBlocks
|
||||||
private import codeql.ruby.dataflow.SSA
|
private import codeql.ruby.dataflow.SSA
|
||||||
private import codeql.ruby.ast.internal.Constant
|
private import codeql.ruby.ast.internal.Constant
|
||||||
private import codeql.ruby.ast.internal.Literal
|
|
||||||
private import ControlFlowGraph
|
private import ControlFlowGraph
|
||||||
private import internal.ControlFlowGraphImpl as CfgImpl
|
private import internal.ControlFlowGraphImpl as CfgImpl
|
||||||
|
|
||||||
@@ -36,11 +37,13 @@ class ExitNode extends CfgNode, CfgImpl::ExitNode {
|
|||||||
*/
|
*/
|
||||||
class AstCfgNode extends CfgNode, CfgImpl::AstCfgNode {
|
class AstCfgNode extends CfgNode, CfgImpl::AstCfgNode {
|
||||||
/** Gets the name of the primary QL class for this node. */
|
/** Gets the name of the primary QL class for this node. */
|
||||||
|
overlay[global]
|
||||||
override string getAPrimaryQlClass() { result = "AstCfgNode" }
|
override string getAPrimaryQlClass() { result = "AstCfgNode" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A control-flow node that wraps an AST expression. */
|
/** A control-flow node that wraps an AST expression. */
|
||||||
class ExprCfgNode extends AstCfgNode {
|
class ExprCfgNode extends AstCfgNode {
|
||||||
|
overlay[global]
|
||||||
override string getAPrimaryQlClass() { result = "ExprCfgNode" }
|
override string getAPrimaryQlClass() { result = "ExprCfgNode" }
|
||||||
|
|
||||||
Expr e;
|
Expr e;
|
||||||
@@ -51,6 +54,7 @@ class ExprCfgNode extends AstCfgNode {
|
|||||||
Expr getExpr() { result = e }
|
Expr getExpr() { result = e }
|
||||||
|
|
||||||
/** Gets the constant value of this expression, if any. */
|
/** Gets the constant value of this expression, if any. */
|
||||||
|
overlay[global]
|
||||||
ConstantValue getConstantValue() { result = getConstantValue(this) }
|
ConstantValue getConstantValue() { result = getConstantValue(this) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,6 +80,7 @@ class StringComponentCfgNode extends AstCfgNode {
|
|||||||
StringComponentCfgNode() { this.getAstNode() instanceof StringComponent }
|
StringComponentCfgNode() { this.getAstNode() instanceof StringComponent }
|
||||||
|
|
||||||
/** Gets the constant value of this string component. */
|
/** Gets the constant value of this string component. */
|
||||||
|
overlay[global]
|
||||||
ConstantValue getConstantValue() {
|
ConstantValue getConstantValue() {
|
||||||
result = this.getAstNode().(StringComponent).getConstantValue()
|
result = this.getAstNode().(StringComponent).getConstantValue()
|
||||||
}
|
}
|
||||||
@@ -297,6 +302,7 @@ module ExprNodes {
|
|||||||
|
|
||||||
/** A control-flow node that wraps a `Call` AST expression. */
|
/** A control-flow node that wraps a `Call` AST expression. */
|
||||||
class CallCfgNode extends ExprCfgNode {
|
class CallCfgNode extends ExprCfgNode {
|
||||||
|
overlay[global]
|
||||||
override string getAPrimaryQlClass() { result = "CallCfgNode" }
|
override string getAPrimaryQlClass() { result = "CallCfgNode" }
|
||||||
|
|
||||||
override CallExprChildMapping e;
|
override CallExprChildMapping e;
|
||||||
@@ -310,6 +316,7 @@ module ExprNodes {
|
|||||||
final ExprCfgNode getAnArgument() { result = this.getArgument(_) }
|
final ExprCfgNode getAnArgument() { result = this.getArgument(_) }
|
||||||
|
|
||||||
/** Gets the keyword argument whose key is `keyword` of this call. */
|
/** Gets the keyword argument whose key is `keyword` of this call. */
|
||||||
|
overlay[global]
|
||||||
final ExprCfgNode getKeywordArgument(string keyword) {
|
final ExprCfgNode getKeywordArgument(string keyword) {
|
||||||
exists(PairCfgNode n |
|
exists(PairCfgNode n |
|
||||||
e.hasCfgChild(e.getAnArgument(), this, n) and
|
e.hasCfgChild(e.getAnArgument(), this, n) and
|
||||||
@@ -338,6 +345,7 @@ module ExprNodes {
|
|||||||
|
|
||||||
/** A control-flow node that wraps a `MethodCall` AST expression. */
|
/** A control-flow node that wraps a `MethodCall` AST expression. */
|
||||||
class MethodCallCfgNode extends CallCfgNode {
|
class MethodCallCfgNode extends CallCfgNode {
|
||||||
|
overlay[global]
|
||||||
override string getAPrimaryQlClass() { result = "MethodCallCfgNode" }
|
override string getAPrimaryQlClass() { result = "MethodCallCfgNode" }
|
||||||
|
|
||||||
MethodCallCfgNode() { super.getExpr() instanceof MethodCall }
|
MethodCallCfgNode() { super.getExpr() instanceof MethodCall }
|
||||||
@@ -842,6 +850,7 @@ module ExprNodes {
|
|||||||
this.getAstNode() instanceof StringInterpolationComponent
|
this.getAstNode() instanceof StringInterpolationComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlay[global]
|
||||||
final override ConstantValue getConstantValue() {
|
final override ConstantValue getConstantValue() {
|
||||||
result = StmtSequenceCfgNode.super.getConstantValue()
|
result = StmtSequenceCfgNode.super.getConstantValue()
|
||||||
}
|
}
|
||||||
@@ -855,6 +864,7 @@ module ExprNodes {
|
|||||||
this.getAstNode() instanceof RegExpInterpolationComponent
|
this.getAstNode() instanceof RegExpInterpolationComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlay[global]
|
||||||
final override ConstantValue getConstantValue() {
|
final override ConstantValue getConstantValue() {
|
||||||
result = StmtSequenceCfgNode.super.getConstantValue()
|
result = StmtSequenceCfgNode.super.getConstantValue()
|
||||||
}
|
}
|
||||||
@@ -946,6 +956,7 @@ module ExprNodes {
|
|||||||
* into calls to `Array.[]`, so this includes both desugared calls as well as
|
* into calls to `Array.[]`, so this includes both desugared calls as well as
|
||||||
* explicit calls.
|
* explicit calls.
|
||||||
*/
|
*/
|
||||||
|
overlay[global]
|
||||||
class ArrayLiteralCfgNode extends MethodCallCfgNode {
|
class ArrayLiteralCfgNode extends MethodCallCfgNode {
|
||||||
override string getAPrimaryQlClass() { result = "ArrayLiteralCfgNode" }
|
override string getAPrimaryQlClass() { result = "ArrayLiteralCfgNode" }
|
||||||
|
|
||||||
@@ -963,6 +974,7 @@ module ExprNodes {
|
|||||||
* into calls to `Hash.[]`, so this includes both desugared calls as well as
|
* into calls to `Hash.[]`, so this includes both desugared calls as well as
|
||||||
* explicit calls.
|
* explicit calls.
|
||||||
*/
|
*/
|
||||||
|
overlay[global]
|
||||||
class HashLiteralCfgNode extends MethodCallCfgNode {
|
class HashLiteralCfgNode extends MethodCallCfgNode {
|
||||||
override string getAPrimaryQlClass() { result = "HashLiteralCfgNode" }
|
override string getAPrimaryQlClass() { result = "HashLiteralCfgNode" }
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
/** Provides classes representing the control flow graph. */
|
/** Provides classes representing the control flow graph. */
|
||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import codeql.ruby.controlflow.BasicBlocks
|
private import codeql.ruby.controlflow.BasicBlocks
|
||||||
@@ -35,6 +37,7 @@ class CfgScope extends Scope instanceof CfgImpl::CfgScopeImpl {
|
|||||||
*/
|
*/
|
||||||
class CfgNode extends CfgImpl::Node {
|
class CfgNode extends CfgImpl::Node {
|
||||||
/** Gets the name of the primary QL class for this node. */
|
/** Gets the name of the primary QL class for this node. */
|
||||||
|
overlay[global]
|
||||||
string getAPrimaryQlClass() { none() }
|
string getAPrimaryQlClass() { none() }
|
||||||
|
|
||||||
/** Gets the file of this control flow node. */
|
/** Gets the file of this control flow node. */
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
*
|
*
|
||||||
* A completion represents how a statement or expression terminates.
|
* A completion represents how a statement or expression terminates.
|
||||||
*/
|
*/
|
||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import codeql.ruby.ast.internal.AST
|
private import codeql.ruby.ast.internal.AST
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
* Provides an implementation for constructing control-flow graphs (CFGs) from
|
* Provides an implementation for constructing control-flow graphs (CFGs) from
|
||||||
* abstract syntax trees (ASTs), using the shared library from `codeql.controlflow.Cfg`.
|
* abstract syntax trees (ASTs), using the shared library from `codeql.controlflow.Cfg`.
|
||||||
*/
|
*/
|
||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.controlflow.Cfg as CfgShared
|
private import codeql.controlflow.Cfg as CfgShared
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.CFG
|
private import codeql.ruby.CFG
|
||||||
|
|
||||||
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
|
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
/** Provides a simple analysis for identifying calls that will not return. */
|
/** Provides a simple analysis for identifying calls that will not return. */
|
||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import Completion
|
private import Completion
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
/**
|
/**
|
||||||
* Provides classes and predicates relevant for splitting the control flow graph.
|
* Provides classes and predicates relevant for splitting the control flow graph.
|
||||||
*/
|
*/
|
||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ruby.AST as Ast
|
private import codeql.ruby.AST as Ast
|
||||||
private import Completion as Comp
|
private import Completion as Comp
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
/**
|
/**
|
||||||
* Provides the module `Ssa` for working with static single assignment (SSA) form.
|
* Provides the module `Ssa` for working with static single assignment (SSA) form.
|
||||||
*/
|
*/
|
||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides classes for working with static single assignment (SSA) form.
|
* Provides classes for working with static single assignment (SSA) form.
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
overlay[local]
|
||||||
|
module;
|
||||||
|
|
||||||
private import codeql.ssa.Ssa as SsaImplCommon
|
private import codeql.ssa.Ssa as SsaImplCommon
|
||||||
private import codeql.ruby.AST
|
private import codeql.ruby.AST
|
||||||
private import codeql.ruby.CFG as Cfg
|
private import codeql.ruby.CFG as Cfg
|
||||||
@@ -393,6 +396,7 @@ private module Cached {
|
|||||||
|
|
||||||
signature predicate guardChecksSig(Cfg::CfgNodes::AstCfgNode g, Cfg::CfgNode e, boolean branch);
|
signature predicate guardChecksSig(Cfg::CfgNodes::AstCfgNode g, Cfg::CfgNode e, boolean branch);
|
||||||
|
|
||||||
|
overlay[global]
|
||||||
cached // nothing is actually cached
|
cached // nothing is actually cached
|
||||||
module BarrierGuard<guardChecksSig/3 guardChecks> {
|
module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||||
private predicate guardChecksAdjTypes(
|
private predicate guardChecksAdjTypes(
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ pub fn generate(
|
|||||||
qldoc: None,
|
qldoc: None,
|
||||||
name: &language.name,
|
name: &language.name,
|
||||||
body,
|
body,
|
||||||
|
overlay: Some(ql::OverlayAnnotation::Local),
|
||||||
})],
|
})],
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ pub struct Module<'a> {
|
|||||||
pub qldoc: Option<String>,
|
pub qldoc: Option<String>,
|
||||||
pub name: &'a str,
|
pub name: &'a str,
|
||||||
pub body: Vec<TopLevel<'a>>,
|
pub body: Vec<TopLevel<'a>>,
|
||||||
|
pub overlay: Option<OverlayAnnotation>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Module<'_> {
|
impl fmt::Display for Module<'_> {
|
||||||
@@ -102,6 +103,14 @@ impl fmt::Display for Module<'_> {
|
|||||||
if let Some(qldoc) = &self.qldoc {
|
if let Some(qldoc) = &self.qldoc {
|
||||||
write!(f, "/** {} */", qldoc)?;
|
write!(f, "/** {} */", qldoc)?;
|
||||||
}
|
}
|
||||||
|
if let Some(overlay_annotation) = &self.overlay {
|
||||||
|
write!(f, "overlay[")?;
|
||||||
|
match overlay_annotation {
|
||||||
|
OverlayAnnotation::Local => write!(f, "local")?,
|
||||||
|
OverlayAnnotation::DiscardEntity => write!(f, "discard_entity")?,
|
||||||
|
}
|
||||||
|
write!(f, "] ")?;
|
||||||
|
}
|
||||||
writeln!(f, "module {} {{ ", self.name)?;
|
writeln!(f, "module {} {{ ", self.name)?;
|
||||||
for decl in &self.body {
|
for decl in &self.body {
|
||||||
writeln!(f, " {}", decl)?;
|
writeln!(f, " {}", decl)?;
|
||||||
|
|||||||
@@ -286,7 +286,7 @@ pub fn create_get_node_file_predicate<'a>(
|
|||||||
overridden: false,
|
overridden: false,
|
||||||
is_private: true,
|
is_private: true,
|
||||||
is_final: false,
|
is_final: false,
|
||||||
overlay: Some(ql::OverlayAnnotation::Local),
|
overlay: None,
|
||||||
return_type: Some(ql::Type::At("file")),
|
return_type: Some(ql::Type::At("file")),
|
||||||
formal_parameters: vec![ql::FormalParameter {
|
formal_parameters: vec![ql::FormalParameter {
|
||||||
name: "node",
|
name: "node",
|
||||||
@@ -327,7 +327,7 @@ pub fn create_discardable_ast_node_predicate(ast_node_name: &str) -> ql::Predica
|
|||||||
overridden: false,
|
overridden: false,
|
||||||
is_private: true,
|
is_private: true,
|
||||||
is_final: false,
|
is_final: false,
|
||||||
overlay: Some(ql::OverlayAnnotation::Local),
|
overlay: None,
|
||||||
return_type: None,
|
return_type: None,
|
||||||
formal_parameters: vec![
|
formal_parameters: vec![
|
||||||
ql::FormalParameter {
|
ql::FormalParameter {
|
||||||
|
|||||||
Reference in New Issue
Block a user