Various changes to user-facing library

- Remove `abstract` classes from public API.
- Align `Variable.qll` with rest of library.
- Introduce `Callable` class.
- Make `Pattern` class cover everything that can be on the LHS of an assignment
  and in a pattern (except special parameters such as `**param`).
This commit is contained in:
Tom Hvitved
2020-11-27 15:12:29 +01:00
parent 59d45de118
commit 58baa33a3f
18 changed files with 572 additions and 627 deletions

View File

@@ -1,6 +1,8 @@
import codeql.Locations
import codeql_ruby.ast.Method
import codeql_ruby.ast.Parameter
import codeql_ruby.ast.Pattern
import codeql_ruby.ast.Variable
private import codeql_ruby.Generated
/**
@@ -26,29 +28,4 @@ class AstNode extends @ast_node {
/** Gets the location if this node. */
Location getLocation() { result = generated.getLocation() }
/**
* Gets the parent of this node in the abstract syntax tree, if it has one.
*/
AstNode getParent() { result = generated.getParent() }
/**
* Gets the index (position) of this node in the parent node's list of
* children.
*/
int getParentIndex() { result = generated.getParentIndex() }
}
/**
* Models program elements for destructured patterns.
*/
abstract class Pattern extends AstNode {
/** Gets the number of elements in this pattern. */
abstract int getNumberOfElements();
/** Gets the nth element in this pattern. */
abstract AstNode getElement(int n);
/** Gets an element in this pattern. */
AstNode getAnElement() { result = this.getElement(_) }
}

View File

@@ -1,17 +1,30 @@
import codeql_ruby.AST
private import codeql_ruby.Generated
private import internal.Method
/** A Ruby method. */
class Method extends @method, AstNode {
Generated::Method generated;
/** A callable. */
class Callable extends AstNode {
Callable() { this instanceof CallableRange }
Method() { generated = this }
/** Gets the number of parameters of this callable. */
final int getNumberOfParameters() { result = count(this.getAParameter()) }
/** Gets a parameter of this callable. */
final Parameter getAParameter() { result = this.getParameter(_) }
/** Gets the nth parameter of this callable. */
final Parameter getParameter(int n) { result = this.(CallableRange).getParameter(n) }
}
/** A method. */
class Method extends Callable, @method {
final override Generated::Method generated;
override string describeQlClass() { result = "Method" }
override string toString() { result = this.getName() }
/** Gets the name of the method. */
/** Gets the name of this method. */
string getName() {
result = generated.getName().(Generated::Token).getValue() or
// TODO: use hand-written Symbol class
@@ -21,7 +34,7 @@ class Method extends @method, AstNode {
/**
* Holds if this is a setter method, as in the following example:
* ```
* ```rb
* class Person
* def name=(n)
* @name = n
@@ -30,90 +43,63 @@ class Method extends @method, AstNode {
* ```
*/
predicate isSetter() { generated.getName() instanceof Generated::Setter }
}
/** Gets the number of parameters of this method. */
int getNumberOfParameters() { result = count(this.getAParameter()) }
/** A singleton method. */
class SingletonMethod extends Callable, @singleton_method {
final override Generated::SingletonMethod generated;
/** Gets a parameter of this method. */
Parameter getAParameter() { result = this.getParameter(_) }
override string describeQlClass() { result = "SingletonMethod" }
/** Gets the nth parameter of this method. */
Parameter getParameter(int n) { result = generated.getParameters().getChild(n) }
override string toString() { result = this.getName() }
/** Gets the name of this method. */
string getName() {
result = generated.getName().(Generated::Token).getValue() or
// TODO: use hand-written Symbol class
result = generated.getName().(Generated::Symbol).toString() or
result = generated.getName().(Generated::Setter).getName().getValue() + "="
}
}
/**
* A Ruby lambda (anonymous method). For example:
* ```
* A lambda (anonymous method). For example:
* ```rb
* -> (x) { x + 1 }
* ```
*/
class Lambda extends @lambda, AstNode {
Generated::Lambda generated;
Lambda() { generated = this }
class Lambda extends Callable, @lambda {
final override Generated::Lambda generated;
override string describeQlClass() { result = "Lambda" }
override string toString() { result = "-> { ... }" }
/** Gets the number of parameters of this lambda. */
int getNumberOfParameters() { result = count(this.getAParameter()) }
/** Gets a parameter of this lambda. */
Parameter getAParameter() { result = this.getParameter(_) }
/** Gets the nth parameter of this lambda. */
Parameter getParameter(int n) { result = generated.getParameters().getChild(n) }
}
/** A Ruby block. */
abstract class Block extends AstNode {
/** Gets the number of parameters of this block. */
abstract int getNumberOfParameters();
/** Gets the nth parameter of this block. */
abstract Parameter getParameter(int n);
/** Gets a parameter of this block. */
Parameter getAParameter() { result = this.getParameter(_) }
// TODO: body/statements
/** A block. */
class Block extends AstNode, Callable {
Block() { this instanceof BlockRange }
}
/** A Ruby block enclosed within `do` and `end`. */
class DoBlock extends @do_block, Block {
Generated::DoBlock generated;
DoBlock() { generated = this }
/** A block enclosed within `do` and `end`. */
class DoBlock extends Block, @do_block {
final override Generated::DoBlock generated;
override string describeQlClass() { result = "DoBlock" }
override string toString() { result = "| ... |" }
/** Gets the number of parameters of this block. */
override int getNumberOfParameters() { result = count(this.getAParameter()) }
/** Gets the nth parameter of this block. */
override Parameter getParameter(int n) { result = generated.getParameters().getChild(n) }
}
/**
* A Ruby block defined using curly braces, e.g. in the following code:
* ```
* A block defined using curly braces, e.g. in the following code:
* ```rb
* names.each { |name| puts name }
* ```
*/
class BraceBlock extends @block, Block {
Generated::Block generated;
BraceBlock() { generated = this }
class BraceBlock extends Block, @block {
final override Generated::Block generated;
override string describeQlClass() { result = "BraceBlock" }
override string toString() { result = "{ ... }" }
/** Gets the number of parameters of this block. */
override int getNumberOfParameters() { result = count(this.getAParameter()) }
/** Gets the nth parameter of this block. */
override Parameter getParameter(int n) { result = generated.getParameters().getChild(n) }
}

View File

@@ -1,105 +1,123 @@
import codeql_ruby.AST
private import codeql_ruby.Generated
private import Variable
private import Pattern
private import internal.Variable
/** A parameter. */
class Parameter extends AstNode {
private int pos;
Parameter() {
this = any(Generated::BlockParameters bp).getChild(pos)
or
this = any(Generated::MethodParameters mp).getChild(pos)
or
this = any(Generated::LambdaParameters lp).getChild(pos)
}
/** Gets the callable that this parameter belongs to. */
Callable getCallable() { result.getAParameter() = this }
/** Gets the zero-based position of this parameter. */
int getPosition() { result = pos }
}
/**
* A parameter to a block, lambda, or method.
* A parameter defined using a pattern.
*
* This includes both simple parameters and tuple parameters.
*/
abstract class Parameter extends AstNode {
/**
* Gets the position of this parameter in the parent block, lambda, or
* method's parameter list.
*/
int getPosition() {
exists(Method m | m.getParameter(result) = this) or
exists(Block b | b.getParameter(result) = this) or
exists(Lambda l | l.getParameter(result) = this)
}
class PatternParameter extends Parameter, Pattern {
override string toString() { result = Pattern.super.toString() }
override Location getLocation() { result = Pattern.super.getLocation() }
}
/** A parameter defined using a tuple pattern. */
class TuplePatternParameter extends PatternParameter, TuplePattern {
override string toString() { result = TuplePattern.super.toString() }
override string describeQlClass() { result = "TuplePatternParameter" }
}
/** A named parameter. */
class NamedParameter extends Parameter {
NamedParameter() { not this instanceof TuplePattern }
/** Gets the name of this parameter. */
string getName() { none() }
/** Gets the variable introduced by this parameter. */
Variable getVariable() { none() }
/** Gets an access to this parameter. */
final VariableAccess getAnAccess() { result = this.getVariable().getAnAccess() }
}
/** A simple (normal) parameter. */
class SimpleParameter extends NamedParameter, PatternParameter, VariablePattern {
override string getName() { result = VariablePattern.super.getName() }
final override Variable getVariable() { result = TLocalVariable(_, _, this) }
override string describeQlClass() { result = "SimpleParameter" }
override string toString() { result = this.getName() }
}
/**
* A parameter that is a block. For example, `&bar` in the following code:
* ```
* ```rb
* def foo(&bar)
* bar.call if block_given?
* end
* ```
*/
class BlockParameter extends @block_parameter, Parameter {
Generated::BlockParameter generated;
class BlockParameter extends @block_parameter, NamedParameter {
override Generated::BlockParameter generated;
BlockParameter() { generated = this }
final override Variable getVariable() { result = TLocalVariable(_, _, generated.getName()) }
override string describeQlClass() { result = "BlockParameter" }
override string toString() { result = "&" + this.getName() }
/** Gets the name of the parameter. */
string getName() { result = generated.getName().getValue() }
}
/**
* A parameter that is destructured. For example, the parameter `(a, b)` in the
* following code:
* ```
* pairs.each do |(a, b)|
* puts a + b
* end
* ```
*/
class PatternParameter extends @destructured_parameter, Parameter, Pattern {
Generated::DestructuredParameter generated;
PatternParameter() { generated = this }
override string describeQlClass() { result = "PatternParameter" }
override string toString() { result = "(..., ...)" }
/**
* Gets the number of parameters of this destructuring.
*/
override int getNumberOfElements() { result = count(this.getElement(_)) }
/**
* Gets the nth parameter of this pattern.
*/
override AstNode getElement(int n) { result = generated.getChild(n) }
override string getName() { result = generated.getName().getValue() }
}
/**
* A hash-splat (or double-splat) parameter. For example, `**options` in the
* following code:
* ```
* ```rb
* def foo(bar, **options)
* ...
* end
* ```
*/
class HashSplatParameter extends @hash_splat_parameter, Parameter {
Generated::HashSplatParameter generated;
class HashSplatParameter extends @hash_splat_parameter, NamedParameter {
override Generated::HashSplatParameter generated;
HashSplatParameter() { generated = this }
final override Variable getVariable() { result = TLocalVariable(_, _, generated.getName()) }
override string describeQlClass() { result = "HashSplatParameter" }
override string toString() { result = "**" + this.getName() }
/** Gets the name of the parameter. */
string getName() { result = generated.getName().getValue() }
override string getName() { result = generated.getName().getValue() }
}
/**
* TODO
*/
class KeywordParameter extends @keyword_parameter, Parameter {
Generated::KeywordParameter generated;
class KeywordParameter extends @keyword_parameter, NamedParameter {
override Generated::KeywordParameter generated;
KeywordParameter() { generated = this }
final override Variable getVariable() { result = TLocalVariable(_, _, generated.getName()) }
override string describeQlClass() { result = "KeywordParameter" }
/** Gets the name of the parameter. */
string getName() { result = generated.getName().getValue() }
override string getName() { result = generated.getName().getValue() }
/**
* Gets the default value, i.e. the value assigned to the parameter when one
@@ -115,23 +133,22 @@ class KeywordParameter extends @keyword_parameter, Parameter {
/**
* An optional parameter. For example, the parameter `name` in the following
* code:
* ```
* ```rb
* def say_hello(name = 'Anon')
* puts "hello #{name}"
* end
* ```
*/
class OptionalParameter extends @optional_parameter, Parameter {
Generated::OptionalParameter generated;
class OptionalParameter extends @optional_parameter, NamedParameter {
override Generated::OptionalParameter generated;
OptionalParameter() { generated = this }
final override Variable getVariable() { result = TLocalVariable(_, _, generated.getName()) }
override string describeQlClass() { result = "OptionalParameter" }
override string toString() { result = this.getName() }
/** Gets the name of the parameter. */
string getName() { result = generated.getName().getValue() }
override string getName() { result = generated.getName().getValue() }
/**
* Gets the default value, i.e. the value assigned to the parameter when one
@@ -143,40 +160,20 @@ class OptionalParameter extends @optional_parameter, Parameter {
/**
* A splat parameter. For example, `*values` in the following code:
* ```
* ```rb
* def foo(bar, *values)
* ...
* end
* ```
*/
class SplatParameter extends @splat_parameter, Parameter {
Generated::SplatParameter generated;
class SplatParameter extends @splat_parameter, NamedParameter {
override Generated::SplatParameter generated;
SplatParameter() { generated = this }
final override Variable getVariable() { result = TLocalVariable(_, _, generated.getName()) }
override string describeQlClass() { result = "SplatParameter" }
override string toString() { result = this.getName() }
/** Gets the name of the parameter. */
string getName() { result = generated.getName().getValue() }
}
/**
* An identifier that is a parameter in a block, lambda, or method.
*/
class IdentifierParameter extends @token_identifier, Parameter {
IdentifierParameter() {
block_parameters_child(_, _, this) or
destructured_parameter_child(_, _, this) or
lambda_parameters_child(_, _, this) or
method_parameters_child(_, _, this)
}
override string describeQlClass() { result = "IdentifierParameter" }
override string toString() { result = this.getName() }
/** Gets the name of the parameter. */
string getName() { result = this.(Generated::Identifier).getValue() }
override string getName() { result = generated.getName().getValue() }
}

View File

@@ -0,0 +1,40 @@
import codeql_ruby.AST
private import codeql_ruby.Generated
private import codeql.Locations
private import internal.Pattern
private import Variable
/** A pattern. */
class Pattern extends AstNode {
Pattern() { this instanceof PatternRange }
}
/** A simple variable pattern. */
class VariablePattern extends Pattern {
override Generated::Identifier generated;
/** Gets the name of the variable used in this pattern. */
string getName() { result = generated.getValue() }
/** Gets the variable used in this pattern. */
Variable getVariable() { this = result.getAnAccess() }
override string toString() { result = this.getName() }
}
/**
* A tuple pattern.
*
* This includes both tuple patterns in parameters and assignments.
*/
class TuplePattern extends Pattern {
TuplePattern() { this instanceof TuplePatternRange }
/** Gets the `i`th pattern in this tuple pattern. */
final Pattern getElement(int i) { result = this.(TuplePatternRange).getElement(i) }
/** Gets a sub pattern in this tuple pattern. */
final Pattern getAnElement() { result = this.getElement(_) }
override string toString() { result = "(..., ...)" }
}

View File

@@ -1,140 +1,9 @@
/** Provides classes for modeling program variables. */
private import codeql_ruby.Generated::Generated
import codeql_ruby.AST
private import codeql_ruby.Generated
private import codeql.Locations
private AstNode parent(AstNode n) {
result = n.getParent() and
not n = any(VariableScope s).getScopeElement()
}
/** Gets the enclosing scope for `node`. */
private VariableScope enclosingScope(AstNode node) {
result.getScopeElement() = parent*(node.getParent())
}
/** A parameter. */
class Parameter extends AstNode {
private int position;
private VariableScope scope;
Parameter() {
this =
scope.(BlockScope).getScopeElement().getAFieldOrChild().(BlockParameters).getChild(position)
or
this =
scope.(MethodScope).getScopeElement().getAFieldOrChild().(MethodParameters).getChild(position)
}
/** Gets the (zero-based) position of this parameter. */
final int getPosition() { result = position }
/** Gets the scope this parameter is declared in. */
final VariableScope getDeclaringScope() { result = scope }
/** Gets an access to this parameter. */
final ParameterAccess getAnAccess() { result.getParameter() = this }
}
private Identifier parameterIdentifier(Parameter p) {
result = p or
result = p.(SplatParameter).getName() or
result = p.(HashSplatParameter).getName() or
result = p.(BlockParameter).getName() or
result = p.(OptionalParameter).getName() or
result = p.(KeywordParameter).getName() or
result = destructuredIdentifier(p.(DestructuredParameter))
}
private Identifier destructuredIdentifier(AstNode node) {
result = node or
result = destructuredIdentifier(node.(DestructuredParameter).getAFieldOrChild())
}
/** Holds if `scope` defines `name` in its parameter declaration. */
private predicate scopeDefinesParameter(VariableScope scope, string name, Location location) {
location =
min(Parameter p, Identifier i |
scope = p.getDeclaringScope() and
i = parameterIdentifier(p) and
name = i.getValue()
|
i.getLocation() as loc order by loc.getStartLine(), loc.getStartColumn()
)
}
/** Holds if `var` is assigned in `scope`. */
private predicate scopeAssigns(VariableScope scope, Identifier var) {
var in [any(Assignment assign).getLeft(), any(OperatorAssignment assign).getLeft()] and
scope = enclosingScope(var)
}
/** Holds if location `one` starts strictly before location `two` */
pragma[inline]
predicate strictlyBefore(Location one, Location two) {
one.getStartLine() < two.getStartLine()
or
one.getStartLine() = two.getStartLine() and one.getStartColumn() < two.getStartColumn()
}
/** Holds if block scope `scope` inherits `var` from an outer scope `outer`. */
private predicate blockScopeInherits(BlockScope scope, string var, VariableScope outer) {
not scopeDefinesParameter(scope, var, _) and
(
outer = scope.getOuterScope() and
(
scopeDefinesParameter(outer, var, _)
or
exists(Identifier i | i.getValue() = var |
scopeAssigns(outer, i) and
strictlyBefore(i.getLocation(), scope.getLocation())
)
)
or
blockScopeInherits(scope.getOuterScope(), var, outer)
)
}
cached
private module Cached {
cached
newtype TScope =
TTopLevelScope(Program node) or
TModuleScope(Module node) or
TClassScope(AstNode cls) { cls instanceof Class or cls instanceof SingletonClass } or
TMethodScope(AstNode method) { method instanceof Method or method instanceof SingletonMethod } or
TBlockScope(AstNode block) { block instanceof Block or block instanceof DoBlock }
cached
newtype TVariable =
TLocalVariable(VariableScope scope, string name, Location location) {
scopeDefinesParameter(scope, name, location)
or
not scopeDefinesParameter(scope, name, _) and
not blockScopeInherits(scope, name, _) and
location =
min(Location loc, Identifier other |
loc = other.getLocation() and name = other.getValue() and scopeAssigns(scope, other)
|
loc order by loc.getStartLine(), loc.getStartColumn()
)
}
cached
predicate access(Identifier access, Variable variable) {
exists(string name | name = access.getValue() |
variable = enclosingScope(access).getVariable(name) and
not strictlyBefore(access.getLocation(), variable.getLocation())
or
exists(VariableScope declScope |
variable = declScope.getVariable(name) and
blockScopeInherits(enclosingScope(access), name, declScope)
)
)
}
}
private import Cached
private import internal.Variable
/** A scope in which variables can be declared. */
class VariableScope extends TScope {
@@ -157,6 +26,47 @@ class VariableScope extends TScope {
}
}
/** A top-level scope. */
class TopLevelScope extends VariableScope, TTopLevelScope {
final override string toString() { result = "top-level scope" }
final override AstNode getScopeElement() { TTopLevelScope(result) = this }
}
/** A module scope. */
class ModuleScope extends VariableScope, TModuleScope {
final override string toString() { result = "module scope" }
final override AstNode getScopeElement() { TModuleScope(result) = this }
}
/** A class scope. */
class ClassScope extends VariableScope, TClassScope {
final override string toString() { result = "class scope" }
final override AstNode getScopeElement() { TClassScope(result) = this }
}
/** A callable scope. */
class CallableScope extends VariableScope, TCallableScope {
private Callable c;
CallableScope() { this = TCallableScope(c) }
final override string toString() {
(c instanceof Method or c instanceof SingletonMethod) and
result = "method scope"
or
c instanceof Lambda and
result = "lambda scope"
or
c instanceof Block and
result = "block scope"
}
final override Callable getScopeElement() { TCallableScope(result) = this }
}
/** A variable declared in a scope. */
class Variable extends TVariable {
/** Gets the name of this variable. */
@@ -179,78 +89,37 @@ class Variable extends TVariable {
class LocalVariable extends Variable {
private VariableScope scope;
private string name;
private Location location;
private Generated::Identifier i;
LocalVariable() { this = TLocalVariable(scope, name, location) }
LocalVariable() { this = TLocalVariable(scope, name, i) }
final override string getName() { result = name }
final override Location getLocation() { result = location }
final override Location getLocation() { result = i.getLocation() }
final override VariableScope getDeclaringScope() { result = scope }
final override LocalVariableAccess getAnAccess() { result.getVariable() = this }
}
/** An identifier that refers to a variable. */
class VariableAccess extends Identifier {
/** An access to a variable. */
class VariableAccess extends AstNode, @token_identifier {
override Generated::Identifier generated;
Variable variable;
VariableAccess() { access(this, variable) }
/**
* Gets the variable this identifier refers to.
*/
/** Gets the variable this identifier refers to. */
Variable getVariable() { result = variable }
override string toString() { result = variable.getName() }
}
/** An identifier that refers to a parameter. */
class ParameterAccess extends VariableAccess {
Parameter parameter;
/** An access to a local variable. */
class LocalVariableAccess extends VariableAccess {
override LocalVariable variable;
ParameterAccess() {
exists(Identifier i |
i = parameterIdentifier(parameter) and
variable.getDeclaringScope() = parameter.getDeclaringScope() and
variable.getLocation() = i.getLocation()
)
}
override LocalVariable getVariable() { result = variable }
final Parameter getParameter() { result = parameter }
}
/** A top-level scope. */
class TopLevelScope extends VariableScope, TTopLevelScope {
final override string toString() { result = "top-level scope" }
final override AstNode getScopeElement() { TTopLevelScope(result) = this }
}
/** A module scope. */
class ModuleScope extends VariableScope, TModuleScope {
final override string toString() { result = "module scope" }
final override Module getScopeElement() { TModuleScope(result) = this }
}
/** A class scope. */
class ClassScope extends VariableScope, TClassScope {
final override string toString() { result = "class scope" }
final override AstNode getScopeElement() { TClassScope(result) = this }
}
/** A method scope. */
class MethodScope extends VariableScope, TMethodScope {
final override string toString() { result = "method scope" }
final override AstNode getScopeElement() { TMethodScope(result) = this }
}
/** A block scope. */
class BlockScope extends VariableScope, TBlockScope {
final override string toString() { result = "block scope" }
final override AstNode getScopeElement() { TBlockScope(result) = this }
/** Gets the scope in which this scope is nested, if any. */
final VariableScope getOuterScope() { result = enclosingScope(this.getScopeElement()) }
override string toString() { result = variable.getName() }
}

View File

@@ -0,0 +1,42 @@
import codeql_ruby.AST
private import codeql_ruby.Generated
abstract class CallableRange extends AstNode {
abstract Parameter getParameter(int n);
}
private class MethodRange extends CallableRange, @method {
final override Generated::Method generated;
override Parameter getParameter(int n) { result = generated.getParameters().getChild(n) }
}
private class SingletonMethodRange extends CallableRange, @singleton_method {
final override Generated::SingletonMethod generated;
override Parameter getParameter(int n) { result = generated.getParameters().getChild(n) }
}
private class LambdaRange extends CallableRange, @lambda {
final override Generated::Lambda generated;
final override Parameter getParameter(int n) { result = generated.getParameters().getChild(n) }
}
abstract class BlockRange extends CallableRange {
Generated::BlockParameters params;
final override Parameter getParameter(int n) { result = params.getChild(n) }
}
private class DoBlockRange extends BlockRange, @do_block {
final override Generated::DoBlock generated;
DoBlockRange() { params = generated.getParameters() }
}
private class BraceBlockRange extends BlockRange, @block {
final override Generated::Block generated;
BraceBlockRange() { params = generated.getParameters() }
}

View File

@@ -0,0 +1,65 @@
import codeql_ruby.AST
private import codeql_ruby.Generated
private import codeql.Locations
private predicate tuplePatternNode(Generated::AstNode n, boolean parameter) {
n instanceof Generated::DestructuredParameter and
parameter = true
or
n instanceof Generated::DestructuredLeftAssignment and
parameter = false
or
n instanceof Generated::LeftAssignmentList and
parameter = false
or
tuplePatternNode(n.getParent(), parameter)
}
private predicate patternNode(Generated::AstNode n, boolean parameter) {
tuplePatternNode(n, parameter)
or
parameter = true and
n = any(Callable c).getAParameter()
or
parameter = false and
n in [
any(Generated::Assignment assign).getLeft(),
any(Generated::OperatorAssignment assign).getLeft()
]
}
/**
* Holds if a variable is assigned at `i`. `parameter` indicates whether it is
* an implicit parameter assignment.
*/
predicate assignment(Generated::Identifier i, boolean parameter) { patternNode(i, parameter) }
abstract class PatternRange extends AstNode {
PatternRange() { patternNode(this, _) }
}
private class VariablePatternRange extends PatternRange {
override Generated::Identifier generated;
}
abstract class TuplePatternRange extends PatternRange {
abstract Pattern getElement(int i);
}
private class ParameterTuplePatternRange extends TuplePatternRange {
override Generated::DestructuredParameter generated;
override Pattern getElement(int i) { result = generated.getChild(i) }
}
private class AssignmentTuplePatternRange extends TuplePatternRange {
override Generated::DestructuredLeftAssignment generated;
override Pattern getElement(int i) { result = generated.getChild(i) }
}
private class AssignmentListPatternRange extends TuplePatternRange {
override Generated::LeftAssignmentList generated;
override Pattern getElement(int i) { result = generated.getChild(i) }
}

View File

@@ -0,0 +1,130 @@
import codeql_ruby.AST
private import codeql_ruby.Generated
private import codeql.Locations
private import Pattern
private Generated::AstNode parent(Generated::AstNode n) {
result = n.getParent() and
not n = any(VariableScope s).getScopeElement()
}
/** Gets the enclosing scope for `node`. */
private VariableScope enclosingScope(Generated::AstNode node) {
result.getScopeElement() = parent*(node.getParent())
}
/** Holds if `scope` defines `name` in its parameter declaration at `i`. */
private predicate scopeDefinesParameterVariable(
CallableScope scope, string name, Generated::Identifier i
) {
assignment(i, true) and
scope = enclosingScope(i) and
name = i.getValue()
or
exists(Parameter p |
p = scope.getScopeElement().getAParameter() and
name = p.(NamedParameter).getName()
|
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()
)
}
/** Holds if `name` is assigned in `scope` at `i`. */
private predicate scopeAssigns(VariableScope scope, string name, Generated::Identifier i) {
assignment(i, false) and
name = i.getValue() and
scope = enclosingScope(i)
}
/** Holds if location `one` starts strictly before location `two` */
pragma[inline]
private predicate strictlyBefore(Location one, Location two) {
one.getStartLine() < two.getStartLine()
or
one.getStartLine() = two.getStartLine() and one.getStartColumn() < two.getStartColumn()
}
/** A scope that may capture outer local variables. */
private class CapturingScope extends CallableScope {
CapturingScope() {
exists(Callable c | c = this.getScopeElement() |
c instanceof Block
or
c instanceof DoBlock
or
c instanceof Lambda // TODO: Check if this is actually the case
)
}
/** Gets the scope in which this scope is nested, if any. */
private VariableScope getOuterScope() { result = enclosingScope(this.getScopeElement()) }
/** Holds if this scope inherits `name` from an outer scope `outer`. */
predicate inherits(string name, VariableScope outer) {
not scopeDefinesParameterVariable(this, name, _) and
(
outer = this.getOuterScope() and
(
scopeDefinesParameterVariable(outer, name, _)
or
exists(Generated::Identifier i |
scopeAssigns(outer, name, i) and
strictlyBefore(i.getLocation(), this.getLocation())
)
)
or
this.getOuterScope().(CapturingScope).inherits(name, outer)
)
}
}
cached
private module Cached {
cached
newtype TScope =
TTopLevelScope(Generated::Program node) or
TModuleScope(Generated::Module node) or
TClassScope(AstNode cls) {
cls instanceof Generated::Class or cls instanceof Generated::SingletonClass
} or
TCallableScope(Callable c)
cached
newtype TVariable =
TLocalVariable(VariableScope scope, string name, Generated::Identifier i) {
scopeDefinesParameterVariable(scope, name, i)
or
scopeAssigns(scope, name, i) and
i =
min(Generated::Identifier other |
scopeAssigns(scope, name, other)
|
other order by other.getLocation().getStartLine(), other.getLocation().getStartColumn()
) and
not scopeDefinesParameterVariable(scope, name, _) and
not scope.(CapturingScope).inherits(name, _)
}
cached
predicate access(Generated::Identifier access, Variable variable) {
exists(string name |
name = access.getValue() and
// Do not generate an access at the defining location
not variable = TLocalVariable(_, name, access)
|
variable = enclosingScope(access).getVariable(name) and
not strictlyBefore(access.getLocation(), variable.getLocation())
or
exists(VariableScope declScope |
variable = declScope.getVariable(name) and
enclosingScope(access).(CapturingScope).inherits(name, declScope)
)
)
}
}
import Cached

View File

@@ -6,23 +6,33 @@ idParams
| params.rb:9:20:9:24 | value | value |
| params.rb:14:11:14:13 | foo | foo |
| params.rb:14:16:14:18 | bar | bar |
| params.rb:17:32:17:32 | a | a |
| params.rb:17:35:17:35 | b | b |
| params.rb:17:38:17:38 | c | c |
| params.rb:22:16:22:16 | a | a |
| params.rb:22:19:22:19 | b | b |
| params.rb:25:24:25:28 | first | first |
| params.rb:25:31:25:36 | second | second |
| params.rb:25:41:25:45 | third | third |
| params.rb:25:48:25:53 | fourth | fourth |
| params.rb:30:23:30:28 | wibble | wibble |
| params.rb:30:31:30:36 | splat | splat |
| params.rb:30:39:30:52 | **double_splat | double_splat |
| params.rb:34:16:34:18 | val | val |
| params.rb:34:21:34:26 | splat | splat |
| params.rb:34:29:34:42 | **double_splat | double_splat |
| params.rb:38:26:38:26 | x | x |
| params.rb:38:29:38:33 | blah | blah |
| params.rb:38:36:38:43 | **wibble | wibble |
| params.rb:41:32:41:32 | x | x |
| params.rb:41:35:41:38 | foo | foo |
| params.rb:41:41:41:46 | bar | bar |
| params.rb:46:28:46:33 | &block | block |
| params.rb:49:28:49:30 | xx | xx |
| params.rb:49:33:49:39 | yy | yy |
| params.rb:53:34:53:34 | x | x |
| params.rb:53:37:53:38 | y | y |
| params.rb:53:41:53:44 | z | z |
| params.rb:58:33:58:36 | val1 | val1 |
| params.rb:58:39:58:46 | val2 | val2 |
| params.rb:58:49:58:58 | val3 | val3 |
| params.rb:62:29:62:34 | &block | block |
| params.rb:65:29:65:32 | name | name |
| params.rb:65:35:65:42 | age | age |
| params.rb:70:35:70:35 | a | a |
| params.rb:70:38:70:45 | b | b |
| params.rb:70:48:70:53 | c | c |
blockParams
| params.rb:46:28:46:33 | &block | block |
| params.rb:62:29:62:34 | &block | block |
@@ -58,82 +68,82 @@ optionalParams
| params.rb:70:38:70:45 | b | b | params.rb:70:42:70:45 | AstNode |
| params.rb:70:48:70:53 | c | c | params.rb:70:52:70:53 | AstNode |
paramsInMethods
| params.rb:4:1:5:3 | identifier_method_params | 0 | params.rb:4:30:4:32 | foo | IdentifierParameter |
| params.rb:4:1:5:3 | identifier_method_params | 1 | params.rb:4:35:4:37 | bar | IdentifierParameter |
| params.rb:4:1:5:3 | identifier_method_params | 2 | params.rb:4:40:4:42 | baz | IdentifierParameter |
| params.rb:17:1:18:3 | destructured_method_param | 0 | params.rb:17:31:17:39 | (..., ...) | PatternParameter |
| params.rb:30:1:31:3 | method_with_splat | 0 | params.rb:30:23:30:28 | wibble | IdentifierParameter |
| params.rb:4:1:5:3 | identifier_method_params | 0 | params.rb:4:30:4:32 | foo | SimpleParameter |
| params.rb:4:1:5:3 | identifier_method_params | 1 | params.rb:4:35:4:37 | bar | SimpleParameter |
| params.rb:4:1:5:3 | identifier_method_params | 2 | params.rb:4:40:4:42 | baz | SimpleParameter |
| params.rb:17:1:18:3 | destructured_method_param | 0 | params.rb:17:31:17:39 | (..., ...) | TuplePatternParameter |
| params.rb:30:1:31:3 | method_with_splat | 0 | params.rb:30:23:30:28 | wibble | SimpleParameter |
| params.rb:30:1:31:3 | method_with_splat | 1 | params.rb:30:31:30:36 | splat | SplatParameter |
| params.rb:30:1:31:3 | method_with_splat | 2 | params.rb:30:39:30:52 | **double_splat | HashSplatParameter |
| params.rb:41:1:43:3 | method_with_keyword_params | 0 | params.rb:41:32:41:32 | x | IdentifierParameter |
| params.rb:41:1:43:3 | method_with_keyword_params | 0 | params.rb:41:32:41:32 | x | SimpleParameter |
| params.rb:41:1:43:3 | method_with_keyword_params | 1 | params.rb:41:35:41:38 | foo | KeywordParameter |
| params.rb:41:1:43:3 | method_with_keyword_params | 2 | params.rb:41:41:41:46 | bar | KeywordParameter |
| params.rb:46:1:48:3 | use_block_with_keyword | 0 | params.rb:46:28:46:33 | &block | BlockParameter |
| params.rb:58:1:59:3 | method_with_optional_params | 0 | params.rb:58:33:58:36 | val1 | IdentifierParameter |
| params.rb:58:1:59:3 | method_with_optional_params | 0 | params.rb:58:33:58:36 | val1 | SimpleParameter |
| params.rb:58:1:59:3 | method_with_optional_params | 1 | params.rb:58:39:58:46 | val2 | OptionalParameter |
| params.rb:58:1:59:3 | method_with_optional_params | 2 | params.rb:58:49:58:58 | val3 | OptionalParameter |
| params.rb:62:1:64:3 | use_block_with_optional | 0 | params.rb:62:29:62:34 | &block | BlockParameter |
paramsInBlocks
| params.rb:9:11:11:3 | \| ... \| | 0 | params.rb:9:15:9:17 | key | IdentifierParameter |
| params.rb:9:11:11:3 | \| ... \| | 1 | params.rb:9:20:9:24 | value | IdentifierParameter |
| params.rb:22:12:22:32 | { ... } | 0 | params.rb:22:15:22:20 | (..., ...) | PatternParameter |
| params.rb:34:12:35:3 | \| ... \| | 0 | params.rb:34:16:34:18 | val | IdentifierParameter |
| params.rb:9:11:11:3 | \| ... \| | 0 | params.rb:9:15:9:17 | key | SimpleParameter |
| params.rb:9:11:11:3 | \| ... \| | 1 | params.rb:9:20:9:24 | value | SimpleParameter |
| params.rb:22:12:22:32 | { ... } | 0 | params.rb:22:15:22:20 | (..., ...) | TuplePatternParameter |
| params.rb:34:12:35:3 | \| ... \| | 0 | params.rb:34:16:34:18 | val | SimpleParameter |
| params.rb:34:12:35:3 | \| ... \| | 1 | params.rb:34:21:34:26 | splat | SplatParameter |
| params.rb:34:12:35:3 | \| ... \| | 2 | params.rb:34:29:34:42 | **double_splat | HashSplatParameter |
| params.rb:49:24:51:3 | \| ... \| | 0 | params.rb:49:28:49:30 | xx | KeywordParameter |
| params.rb:49:24:51:3 | \| ... \| | 1 | params.rb:49:33:49:39 | yy | KeywordParameter |
| params.rb:65:25:67:3 | \| ... \| | 0 | params.rb:65:29:65:32 | name | IdentifierParameter |
| params.rb:65:25:67:3 | \| ... \| | 0 | params.rb:65:29:65:32 | name | SimpleParameter |
| params.rb:65:25:67:3 | \| ... \| | 1 | params.rb:65:35:65:42 | age | OptionalParameter |
paramsInLambdas
| params.rb:14:7:14:33 | -> { ... } | 0 | params.rb:14:11:14:13 | foo | IdentifierParameter |
| params.rb:14:7:14:33 | -> { ... } | 1 | params.rb:14:16:14:18 | bar | IdentifierParameter |
| params.rb:25:19:27:1 | -> { ... } | 0 | params.rb:25:23:25:37 | (..., ...) | PatternParameter |
| params.rb:25:19:27:1 | -> { ... } | 1 | params.rb:25:40:25:54 | (..., ...) | PatternParameter |
| params.rb:38:22:38:47 | -> { ... } | 0 | params.rb:38:26:38:26 | x | IdentifierParameter |
| params.rb:14:7:14:33 | -> { ... } | 0 | params.rb:14:11:14:13 | foo | SimpleParameter |
| params.rb:14:7:14:33 | -> { ... } | 1 | params.rb:14:16:14:18 | bar | SimpleParameter |
| params.rb:25:19:27:1 | -> { ... } | 0 | params.rb:25:23:25:37 | (..., ...) | TuplePatternParameter |
| params.rb:25:19:27:1 | -> { ... } | 1 | params.rb:25:40:25:54 | (..., ...) | TuplePatternParameter |
| params.rb:38:22:38:47 | -> { ... } | 0 | params.rb:38:26:38:26 | x | SimpleParameter |
| params.rb:38:22:38:47 | -> { ... } | 1 | params.rb:38:29:38:33 | blah | SplatParameter |
| params.rb:38:22:38:47 | -> { ... } | 2 | params.rb:38:36:38:43 | **wibble | HashSplatParameter |
| params.rb:53:30:55:1 | -> { ... } | 0 | params.rb:53:34:53:34 | x | IdentifierParameter |
| params.rb:53:30:55:1 | -> { ... } | 0 | params.rb:53:34:53:34 | x | SimpleParameter |
| params.rb:53:30:55:1 | -> { ... } | 1 | params.rb:53:37:53:38 | y | KeywordParameter |
| params.rb:53:30:55:1 | -> { ... } | 2 | params.rb:53:41:53:44 | z | KeywordParameter |
| params.rb:70:31:70:64 | -> { ... } | 0 | params.rb:70:35:70:35 | a | IdentifierParameter |
| params.rb:70:31:70:64 | -> { ... } | 0 | params.rb:70:35:70:35 | a | SimpleParameter |
| params.rb:70:31:70:64 | -> { ... } | 1 | params.rb:70:38:70:45 | b | OptionalParameter |
| params.rb:70:31:70:64 | -> { ... } | 2 | params.rb:70:48:70:53 | c | OptionalParameter |
#select
| params.rb:4:30:4:32 | foo | 0 | IdentifierParameter |
| params.rb:4:35:4:37 | bar | 1 | IdentifierParameter |
| params.rb:4:40:4:42 | baz | 2 | IdentifierParameter |
| params.rb:9:15:9:17 | key | 0 | IdentifierParameter |
| params.rb:9:20:9:24 | value | 1 | IdentifierParameter |
| params.rb:14:11:14:13 | foo | 0 | IdentifierParameter |
| params.rb:14:16:14:18 | bar | 1 | IdentifierParameter |
| params.rb:17:31:17:39 | (..., ...) | 0 | PatternParameter |
| params.rb:22:15:22:20 | (..., ...) | 0 | PatternParameter |
| params.rb:25:23:25:37 | (..., ...) | 0 | PatternParameter |
| params.rb:25:40:25:54 | (..., ...) | 1 | PatternParameter |
| params.rb:30:23:30:28 | wibble | 0 | IdentifierParameter |
| params.rb:4:30:4:32 | foo | 0 | SimpleParameter |
| params.rb:4:35:4:37 | bar | 1 | SimpleParameter |
| params.rb:4:40:4:42 | baz | 2 | SimpleParameter |
| params.rb:9:15:9:17 | key | 0 | SimpleParameter |
| params.rb:9:20:9:24 | value | 1 | SimpleParameter |
| params.rb:14:11:14:13 | foo | 0 | SimpleParameter |
| params.rb:14:16:14:18 | bar | 1 | SimpleParameter |
| params.rb:17:31:17:39 | (..., ...) | 0 | TuplePatternParameter |
| params.rb:22:15:22:20 | (..., ...) | 0 | TuplePatternParameter |
| params.rb:25:23:25:37 | (..., ...) | 0 | TuplePatternParameter |
| params.rb:25:40:25:54 | (..., ...) | 1 | TuplePatternParameter |
| params.rb:30:23:30:28 | wibble | 0 | SimpleParameter |
| params.rb:30:31:30:36 | splat | 1 | SplatParameter |
| params.rb:30:39:30:52 | **double_splat | 2 | HashSplatParameter |
| params.rb:34:16:34:18 | val | 0 | IdentifierParameter |
| params.rb:34:16:34:18 | val | 0 | SimpleParameter |
| params.rb:34:21:34:26 | splat | 1 | SplatParameter |
| params.rb:34:29:34:42 | **double_splat | 2 | HashSplatParameter |
| params.rb:38:26:38:26 | x | 0 | IdentifierParameter |
| params.rb:38:26:38:26 | x | 0 | SimpleParameter |
| params.rb:38:29:38:33 | blah | 1 | SplatParameter |
| params.rb:38:36:38:43 | **wibble | 2 | HashSplatParameter |
| params.rb:41:32:41:32 | x | 0 | IdentifierParameter |
| params.rb:41:32:41:32 | x | 0 | SimpleParameter |
| params.rb:41:35:41:38 | foo | 1 | KeywordParameter |
| params.rb:41:41:41:46 | bar | 2 | KeywordParameter |
| params.rb:46:28:46:33 | &block | 0 | BlockParameter |
| params.rb:49:28:49:30 | xx | 0 | KeywordParameter |
| params.rb:49:33:49:39 | yy | 1 | KeywordParameter |
| params.rb:53:34:53:34 | x | 0 | IdentifierParameter |
| params.rb:53:34:53:34 | x | 0 | SimpleParameter |
| params.rb:53:37:53:38 | y | 1 | KeywordParameter |
| params.rb:53:41:53:44 | z | 2 | KeywordParameter |
| params.rb:58:33:58:36 | val1 | 0 | IdentifierParameter |
| params.rb:58:33:58:36 | val1 | 0 | SimpleParameter |
| params.rb:58:39:58:46 | val2 | 1 | OptionalParameter |
| params.rb:58:49:58:58 | val3 | 2 | OptionalParameter |
| params.rb:62:29:62:34 | &block | 0 | BlockParameter |
| params.rb:65:29:65:32 | name | 0 | IdentifierParameter |
| params.rb:65:29:65:32 | name | 0 | SimpleParameter |
| params.rb:65:35:65:42 | age | 1 | OptionalParameter |
| params.rb:70:35:70:35 | a | 0 | IdentifierParameter |
| params.rb:70:35:70:35 | a | 0 | SimpleParameter |
| params.rb:70:38:70:45 | b | 1 | OptionalParameter |
| params.rb:70:48:70:53 | c | 2 | OptionalParameter |

View File

@@ -2,12 +2,12 @@ import ruby
////////////////////////////////////////////////////////////////////////////////
// Query predicates for various types of parameter
query predicate idParams(IdentifierParameter ip, string name) { name = ip.getName() }
query predicate idParams(NamedParameter np, string name) { name = np.getName() }
query predicate blockParams(BlockParameter bp, string name) { name = bp.getName() }
query predicate patternParams(PatternParameter pp, Parameter child, int childIndex) {
pp.getElement(childIndex) = child
query predicate patternParams(TuplePatternParameter tpp, Pattern child, int childIndex) {
tpp.getElement(childIndex) = child
}
query predicate splatParams(SplatParameter sp, string name) { name = sp.getName() }

View File

@@ -1,29 +1,29 @@
parameter
| nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:15:23:15:23 | a |
| nested_scopes.rb:16:26:16:26 | x | nested_scopes.rb:16:26:16:26 | x |
| nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:16:29:16:29 | a |
| nested_scopes.rb:18:26:18:26 | x | nested_scopes.rb:18:26:18:26 | x |
| nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:22:21:22:21 | a |
| parameters.rb:1:14:1:14 | x | parameters.rb:1:14:1:14 | x |
| parameters.rb:1:18:1:18 | y | parameters.rb:1:18:1:18 | y |
| parameters.rb:7:17:7:22 | client | parameters.rb:7:17:7:22 | client |
| parameters.rb:7:25:7:31 | SplatParameter | parameters.rb:7:26:7:31 | pizzas |
| parameters.rb:15:15:15:19 | HashSplatParameter | parameters.rb:15:17:15:19 | map |
| parameters.rb:7:25:7:31 | pizzas | parameters.rb:7:26:7:31 | pizzas |
| parameters.rb:15:15:15:19 | **map | parameters.rb:15:17:15:19 | map |
| parameters.rb:16:16:16:18 | key | parameters.rb:16:16:16:18 | key |
| parameters.rb:16:21:16:25 | value | parameters.rb:16:21:16:25 | value |
| parameters.rb:21:16:21:21 | BlockParameter | parameters.rb:21:17:21:21 | block |
| parameters.rb:25:15:25:30 | OptionalParameter | parameters.rb:25:15:25:18 | name |
| parameters.rb:25:33:25:50 | OptionalParameter | parameters.rb:25:33:25:36 | size |
| parameters.rb:30:15:30:20 | KeywordParameter | parameters.rb:30:15:30:19 | first |
| parameters.rb:30:24:30:33 | KeywordParameter | parameters.rb:30:24:30:29 | middle |
| parameters.rb:30:36:30:40 | KeywordParameter | parameters.rb:30:36:30:39 | last |
| parameters.rb:35:11:35:21 | OptionalParameter | parameters.rb:35:11:35:11 | a |
| parameters.rb:40:12:40:19 | KeywordParameter | parameters.rb:40:12:40:12 | d |
| parameters.rb:21:16:21:21 | &block | parameters.rb:21:17:21:21 | block |
| parameters.rb:25:15:25:30 | name | parameters.rb:25:15:25:18 | name |
| parameters.rb:25:33:25:50 | size | parameters.rb:25:33:25:36 | size |
| parameters.rb:30:15:30:20 | first | parameters.rb:30:15:30:19 | first |
| parameters.rb:30:24:30:33 | middle | parameters.rb:30:24:30:29 | middle |
| parameters.rb:30:36:30:40 | last | parameters.rb:30:36:30:39 | last |
| parameters.rb:35:11:35:21 | a | parameters.rb:35:11:35:11 | a |
| parameters.rb:40:12:40:19 | d | parameters.rb:40:12:40:12 | d |
| parameters.rb:45:20:45:20 | _ | parameters.rb:45:20:45:20 | _ |
| parameters.rb:49:12:49:16 | DestructuredParameter | parameters.rb:49:13:49:13 | a |
| parameters.rb:49:12:49:16 | DestructuredParameter | parameters.rb:49:15:49:15 | b |
| parameters.rb:54:14:54:24 | OptionalParameter | parameters.rb:54:14:54:14 | y |
| scopes.rb:2:14:2:14 | x | scopes.rb:2:14:2:14 | x |
| scopes.rb:9:14:9:14 | x | scopes.rb:9:14:9:14 | x |
| parameters.rb:45:20:45:20 | _ | parameters.rb:45:22:45:22 | _ |
| parameters.rb:45:22:45:22 | _ | parameters.rb:45:20:45:20 | _ |
| parameters.rb:45:22:45:22 | _ | parameters.rb:45:22:45:22 | _ |
| parameters.rb:54:14:54:24 | y | parameters.rb:54:14:54:14 | y |
parameterNoAcess
| parameters.rb:45:22:45:22 | _ |
| nested_scopes.rb:16:26:16:26 | x |
| nested_scopes.rb:18:26:18:26 | x |
| scopes.rb:2:14:2:14 | x |
| scopes.rb:9:14:9:14 | x |

View File

@@ -1,5 +1,5 @@
import codeql_ruby.ast.Variable
query predicate parameter(Parameter p, Variable v) { p.getAnAccess().getVariable() = v }
query predicate parameter(NamedParameter p, Variable v) { p.getAnAccess().getVariable() = v }
query predicate parameterNoAcess(Parameter p) { not exists(p.getAnAccess()) }
query predicate parameterNoAcess(NamedParameter p) { not exists(p.getAnAccess()) }

View File

@@ -10,4 +10,9 @@ puts a
puts a # local variable from top-level
a = 3
puts a # local variable from top-level
a, b, (c, d) = [4, 5, [6, 7]]
puts a # local variable from top-level
puts b # new local variable
puts c # new local variable
puts d # new local variable
end

View File

@@ -1,173 +1,52 @@
variableAccess
| nested_scopes.rb:5:3:5:3 | a | nested_scopes.rb:5:3:5:3 | a | nested_scopes.rb:4:1:39:3 | class scope |
| nested_scopes.rb:7:5:7:5 | a | nested_scopes.rb:7:5:7:5 | a | nested_scopes.rb:6:3:37:5 | module scope |
| nested_scopes.rb:9:7:9:7 | a | nested_scopes.rb:9:7:9:7 | a | nested_scopes.rb:8:5:35:7 | module scope |
| nested_scopes.rb:11:9:11:9 | a | nested_scopes.rb:11:9:11:9 | a | nested_scopes.rb:10:7:26:9 | class scope |
| nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:12:9:21:11 | method scope |
| nested_scopes.rb:14:16:14:16 | a | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:12:9:21:11 | method scope |
| nested_scopes.rb:15:11:15:11 | a | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:12:9:21:11 | method scope |
| nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:15:19:20:13 | block scope |
| nested_scopes.rb:16:13:16:13 | a | nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:15:19:20:13 | block scope |
| nested_scopes.rb:16:26:16:26 | x | nested_scopes.rb:16:26:16:26 | x | nested_scopes.rb:16:21:19:15 | block scope |
| nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:16:21:19:15 | block scope |
| nested_scopes.rb:17:15:17:15 | a | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:16:21:19:15 | block scope |
| nested_scopes.rb:18:15:18:15 | a | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:16:21:19:15 | block scope |
| nested_scopes.rb:18:26:18:26 | x | nested_scopes.rb:18:26:18:26 | x | nested_scopes.rb:18:23:18:36 | block scope |
| nested_scopes.rb:18:34:18:34 | a | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:16:21:19:15 | block scope |
| nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:22:9:24:11 | method scope |
| nested_scopes.rb:23:16:23:16 | a | nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:22:9:24:11 | method scope |
| nested_scopes.rb:25:14:25:14 | a | nested_scopes.rb:11:9:11:9 | a | nested_scopes.rb:10:7:26:9 | class scope |
| nested_scopes.rb:31:11:31:11 | a | nested_scopes.rb:31:11:31:11 | a | nested_scopes.rb:30:7:33:9 | class scope |
| nested_scopes.rb:32:16:32:16 | a | nested_scopes.rb:31:11:31:11 | a | nested_scopes.rb:30:7:33:9 | class scope |
| nested_scopes.rb:34:12:34:12 | a | nested_scopes.rb:9:7:9:7 | a | nested_scopes.rb:8:5:35:7 | module scope |
| nested_scopes.rb:36:10:36:10 | a | nested_scopes.rb:7:5:7:5 | a | nested_scopes.rb:6:3:37:5 | module scope |
| nested_scopes.rb:38:8:38:8 | a | nested_scopes.rb:5:3:5:3 | a | nested_scopes.rb:4:1:39:3 | class scope |
| nested_scopes.rb:40:1:40:1 | d | nested_scopes.rb:40:1:40:1 | d | nested_scopes.rb:1:1:42:1 | top-level scope |
| nested_scopes.rb:41:1:41:1 | d | nested_scopes.rb:40:1:40:1 | d | nested_scopes.rb:1:1:42:1 | top-level scope |
| parameters.rb:1:14:1:14 | x | parameters.rb:1:14:1:14 | x | parameters.rb:1:9:5:3 | block scope |
| parameters.rb:1:18:1:18 | y | parameters.rb:1:18:1:18 | y | parameters.rb:1:9:5:3 | block scope |
| parameters.rb:2:4:2:4 | y | parameters.rb:1:18:1:18 | y | parameters.rb:1:9:5:3 | block scope |
| parameters.rb:3:9:3:9 | x | parameters.rb:1:14:1:14 | x | parameters.rb:1:9:5:3 | block scope |
| parameters.rb:4:9:4:9 | y | parameters.rb:1:18:1:18 | y | parameters.rb:1:9:5:3 | block scope |
| parameters.rb:7:17:7:22 | client | parameters.rb:7:17:7:22 | client | parameters.rb:7:1:13:3 | method scope |
| parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:1:13:3 | method scope |
| parameters.rb:8:6:8:11 | pizzas | parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:1:13:3 | method scope |
| parameters.rb:9:25:9:30 | client | parameters.rb:7:17:7:22 | client | parameters.rb:7:1:13:3 | method scope |
| parameters.rb:11:14:11:19 | pizzas | parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:1:13:3 | method scope |
| parameters.rb:11:41:11:46 | client | parameters.rb:7:17:7:22 | client | parameters.rb:7:1:13:3 | method scope |
| parameters.rb:15:17:15:19 | map | parameters.rb:15:17:15:19 | map | parameters.rb:15:1:19:3 | method scope |
| parameters.rb:16:3:16:5 | map | parameters.rb:15:17:15:19 | map | parameters.rb:15:1:19:3 | method scope |
| parameters.rb:16:16:16:18 | key | parameters.rb:16:16:16:18 | key | parameters.rb:16:12:18:5 | block scope |
| parameters.rb:16:21:16:25 | value | parameters.rb:16:21:16:25 | value | parameters.rb:16:12:18:5 | block scope |
| parameters.rb:17:13:17:15 | key | parameters.rb:16:16:16:18 | key | parameters.rb:16:12:18:5 | block scope |
| parameters.rb:17:22:17:26 | value | parameters.rb:16:21:16:25 | value | parameters.rb:16:12:18:5 | block scope |
| parameters.rb:21:17:21:21 | block | parameters.rb:21:17:21:21 | block | parameters.rb:21:1:23:3 | method scope |
| parameters.rb:22:3:22:7 | block | parameters.rb:21:17:21:21 | block | parameters.rb:21:1:23:3 | method scope |
| parameters.rb:25:15:25:18 | name | parameters.rb:25:15:25:18 | name | parameters.rb:25:1:28:3 | method scope |
| parameters.rb:25:33:25:36 | size | parameters.rb:25:33:25:36 | size | parameters.rb:25:1:28:3 | method scope |
| parameters.rb:25:40:25:43 | name | parameters.rb:25:15:25:18 | name | parameters.rb:25:1:28:3 | method scope |
| parameters.rb:26:8:26:11 | name | parameters.rb:25:15:25:18 | name | parameters.rb:25:1:28:3 | method scope |
| parameters.rb:27:8:27:11 | size | parameters.rb:25:33:25:36 | size | parameters.rb:25:1:28:3 | method scope |
| parameters.rb:30:15:30:19 | first | parameters.rb:30:15:30:19 | first | parameters.rb:30:1:32:3 | method scope |
| parameters.rb:30:24:30:29 | middle | parameters.rb:30:24:30:29 | middle | parameters.rb:30:1:32:3 | method scope |
| parameters.rb:30:36:30:39 | last | parameters.rb:30:36:30:39 | last | parameters.rb:30:1:32:3 | method scope |
| parameters.rb:31:11:31:15 | first | parameters.rb:30:15:30:19 | first | parameters.rb:30:1:32:3 | method scope |
| parameters.rb:31:20:31:25 | middle | parameters.rb:30:24:30:29 | middle | parameters.rb:30:1:32:3 | method scope |
| parameters.rb:31:30:31:33 | last | parameters.rb:30:36:30:39 | last | parameters.rb:30:1:32:3 | method scope |
| parameters.rb:34:1:34:1 | b | parameters.rb:34:1:34:1 | b | parameters.rb:1:1:58:1 | top-level scope |
| parameters.rb:35:11:35:11 | a | parameters.rb:35:11:35:11 | a | parameters.rb:35:1:38:3 | method scope |
| parameters.rb:35:16:35:16 | b | parameters.rb:35:16:35:16 | b | parameters.rb:35:1:38:3 | method scope |
| parameters.rb:37:11:37:11 | a | parameters.rb:35:11:35:11 | a | parameters.rb:35:1:38:3 | method scope |
| parameters.rb:37:16:37:16 | b | parameters.rb:35:16:35:16 | b | parameters.rb:35:1:38:3 | method scope |
| parameters.rb:40:12:40:12 | d | parameters.rb:40:12:40:12 | d | parameters.rb:40:1:43:3 | method scope |
| parameters.rb:40:15:40:15 | e | parameters.rb:40:15:40:15 | e | parameters.rb:40:1:43:3 | method scope |
| parameters.rb:42:11:42:11 | d | parameters.rb:40:12:40:12 | d | parameters.rb:40:1:43:3 | method scope |
| parameters.rb:42:16:42:16 | e | parameters.rb:40:15:40:15 | e | parameters.rb:40:1:43:3 | method scope |
| parameters.rb:45:20:45:20 | _ | parameters.rb:45:20:45:20 | _ | parameters.rb:45:1:47:3 | method scope |
| parameters.rb:45:22:45:22 | _ | parameters.rb:45:20:45:20 | _ | parameters.rb:45:1:47:3 | method scope |
| parameters.rb:46:8:46:8 | _ | parameters.rb:45:20:45:20 | _ | parameters.rb:45:1:47:3 | method scope |
| parameters.rb:49:13:49:13 | a | parameters.rb:49:13:49:13 | a | parameters.rb:49:1:51:3 | method scope |
| parameters.rb:49:15:49:15 | b | parameters.rb:49:15:49:15 | b | parameters.rb:49:1:51:3 | method scope |
| parameters.rb:46:8:46:8 | _ | parameters.rb:45:22:45:22 | _ | parameters.rb:45:1:47:3 | method scope |
| parameters.rb:50:11:50:11 | a | parameters.rb:49:13:49:13 | a | parameters.rb:49:1:51:3 | method scope |
| parameters.rb:50:16:50:16 | b | parameters.rb:49:15:49:15 | b | parameters.rb:49:1:51:3 | method scope |
| parameters.rb:53:1:53:1 | x | parameters.rb:53:1:53:1 | x | parameters.rb:1:1:58:1 | top-level scope |
| parameters.rb:54:14:54:14 | y | parameters.rb:54:14:54:14 | y | parameters.rb:54:9:57:3 | block scope |
| parameters.rb:54:19:54:19 | x | parameters.rb:53:1:53:1 | x | parameters.rb:1:1:58:1 | top-level scope |
| parameters.rb:55:9:55:9 | x | parameters.rb:53:1:53:1 | x | parameters.rb:1:1:58:1 | top-level scope |
| parameters.rb:56:9:56:9 | y | parameters.rb:54:14:54:14 | y | parameters.rb:54:9:57:3 | block scope |
| scopes.rb:2:14:2:14 | x | scopes.rb:2:14:2:14 | x | scopes.rb:2:9:6:3 | block scope |
| scopes.rb:4:4:4:4 | a | scopes.rb:4:4:4:4 | a | scopes.rb:2:9:6:3 | block scope |
| scopes.rb:5:9:5:9 | a | scopes.rb:4:4:4:4 | a | scopes.rb:2:9:6:3 | block scope |
| scopes.rb:7:1:7:1 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:13:3 | top-level scope |
| scopes.rb:8:6:8:6 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:13:3 | top-level scope |
| scopes.rb:9:14:9:14 | x | scopes.rb:9:14:9:14 | x | scopes.rb:9:9:13:3 | block scope |
| scopes.rb:10:9:10:9 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:13:3 | top-level scope |
| scopes.rb:11:4:11:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:13:3 | top-level scope |
| scopes.rb:12:9:12:9 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:13:3 | top-level scope |
parameterAccess
| nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:15:19:20:13 | block scope |
| nested_scopes.rb:16:13:16:13 | a | nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:15:19:20:13 | block scope |
| nested_scopes.rb:16:26:16:26 | x | nested_scopes.rb:16:26:16:26 | x | nested_scopes.rb:16:21:19:15 | block scope |
| nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:16:21:19:15 | block scope |
| nested_scopes.rb:17:15:17:15 | a | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:16:21:19:15 | block scope |
| nested_scopes.rb:18:15:18:15 | a | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:16:21:19:15 | block scope |
| nested_scopes.rb:18:26:18:26 | x | nested_scopes.rb:18:26:18:26 | x | nested_scopes.rb:18:23:18:36 | block scope |
| nested_scopes.rb:18:34:18:34 | a | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:16:21:19:15 | block scope |
| nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:22:9:24:11 | method scope |
| nested_scopes.rb:23:16:23:16 | a | nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:22:9:24:11 | method scope |
| parameters.rb:1:14:1:14 | x | parameters.rb:1:14:1:14 | x | parameters.rb:1:9:5:3 | block scope |
| parameters.rb:1:18:1:18 | y | parameters.rb:1:18:1:18 | y | parameters.rb:1:9:5:3 | block scope |
| parameters.rb:2:4:2:4 | y | parameters.rb:1:18:1:18 | y | parameters.rb:1:9:5:3 | block scope |
| parameters.rb:3:9:3:9 | x | parameters.rb:1:14:1:14 | x | parameters.rb:1:9:5:3 | block scope |
| parameters.rb:4:9:4:9 | y | parameters.rb:1:18:1:18 | y | parameters.rb:1:9:5:3 | block scope |
| parameters.rb:7:17:7:22 | client | parameters.rb:7:17:7:22 | client | parameters.rb:7:1:13:3 | method scope |
| parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:1:13:3 | method scope |
| parameters.rb:8:6:8:11 | pizzas | parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:1:13:3 | method scope |
| parameters.rb:9:25:9:30 | client | parameters.rb:7:17:7:22 | client | parameters.rb:7:1:13:3 | method scope |
| parameters.rb:11:14:11:19 | pizzas | parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:1:13:3 | method scope |
| parameters.rb:11:41:11:46 | client | parameters.rb:7:17:7:22 | client | parameters.rb:7:1:13:3 | method scope |
| parameters.rb:15:17:15:19 | map | parameters.rb:15:17:15:19 | map | parameters.rb:15:1:19:3 | method scope |
| parameters.rb:16:3:16:5 | map | parameters.rb:15:17:15:19 | map | parameters.rb:15:1:19:3 | method scope |
| parameters.rb:16:16:16:18 | key | parameters.rb:16:16:16:18 | key | parameters.rb:16:12:18:5 | block scope |
| parameters.rb:16:21:16:25 | value | parameters.rb:16:21:16:25 | value | parameters.rb:16:12:18:5 | block scope |
| parameters.rb:17:13:17:15 | key | parameters.rb:16:16:16:18 | key | parameters.rb:16:12:18:5 | block scope |
| parameters.rb:17:22:17:26 | value | parameters.rb:16:21:16:25 | value | parameters.rb:16:12:18:5 | block scope |
| parameters.rb:21:17:21:21 | block | parameters.rb:21:17:21:21 | block | parameters.rb:21:1:23:3 | method scope |
| parameters.rb:22:3:22:7 | block | parameters.rb:21:17:21:21 | block | parameters.rb:21:1:23:3 | method scope |
| parameters.rb:25:15:25:18 | name | parameters.rb:25:15:25:18 | name | parameters.rb:25:1:28:3 | method scope |
| parameters.rb:25:33:25:36 | size | parameters.rb:25:33:25:36 | size | parameters.rb:25:1:28:3 | method scope |
| parameters.rb:25:40:25:43 | name | parameters.rb:25:15:25:18 | name | parameters.rb:25:1:28:3 | method scope |
| parameters.rb:26:8:26:11 | name | parameters.rb:25:15:25:18 | name | parameters.rb:25:1:28:3 | method scope |
| parameters.rb:27:8:27:11 | size | parameters.rb:25:33:25:36 | size | parameters.rb:25:1:28:3 | method scope |
| parameters.rb:30:15:30:19 | first | parameters.rb:30:15:30:19 | first | parameters.rb:30:1:32:3 | method scope |
| parameters.rb:30:24:30:29 | middle | parameters.rb:30:24:30:29 | middle | parameters.rb:30:1:32:3 | method scope |
| parameters.rb:30:36:30:39 | last | parameters.rb:30:36:30:39 | last | parameters.rb:30:1:32:3 | method scope |
| parameters.rb:31:11:31:15 | first | parameters.rb:30:15:30:19 | first | parameters.rb:30:1:32:3 | method scope |
| parameters.rb:31:20:31:25 | middle | parameters.rb:30:24:30:29 | middle | parameters.rb:30:1:32:3 | method scope |
| parameters.rb:31:30:31:33 | last | parameters.rb:30:36:30:39 | last | parameters.rb:30:1:32:3 | method scope |
| parameters.rb:35:11:35:11 | a | parameters.rb:35:11:35:11 | a | parameters.rb:35:1:38:3 | method scope |
| parameters.rb:37:11:37:11 | a | parameters.rb:35:11:35:11 | a | parameters.rb:35:1:38:3 | method scope |
| parameters.rb:40:12:40:12 | d | parameters.rb:40:12:40:12 | d | parameters.rb:40:1:43:3 | method scope |
| parameters.rb:42:11:42:11 | d | parameters.rb:40:12:40:12 | d | parameters.rb:40:1:43:3 | method scope |
| parameters.rb:45:20:45:20 | _ | parameters.rb:45:20:45:20 | _ | parameters.rb:45:1:47:3 | method scope |
| parameters.rb:45:22:45:22 | _ | parameters.rb:45:20:45:20 | _ | parameters.rb:45:1:47:3 | method scope |
| parameters.rb:46:8:46:8 | _ | parameters.rb:45:20:45:20 | _ | parameters.rb:45:1:47:3 | method scope |
| parameters.rb:49:13:49:13 | a | parameters.rb:49:13:49:13 | a | parameters.rb:49:1:51:3 | method scope |
| parameters.rb:49:15:49:15 | b | parameters.rb:49:15:49:15 | b | parameters.rb:49:1:51:3 | method scope |
| parameters.rb:50:11:50:11 | a | parameters.rb:49:13:49:13 | a | parameters.rb:49:1:51:3 | method scope |
| parameters.rb:50:16:50:16 | b | parameters.rb:49:15:49:15 | b | parameters.rb:49:1:51:3 | method scope |
| parameters.rb:54:14:54:14 | y | parameters.rb:54:14:54:14 | y | parameters.rb:54:9:57:3 | block scope |
| parameters.rb:56:9:56:9 | y | parameters.rb:54:14:54:14 | y | parameters.rb:54:9:57:3 | block scope |
| scopes.rb:2:14:2:14 | x | scopes.rb:2:14:2:14 | x | scopes.rb:2:9:6:3 | block scope |
| scopes.rb:9:14:9:14 | x | scopes.rb:9:14:9:14 | x | scopes.rb:9:9:13:3 | block scope |
localVariableAccess
| nested_scopes.rb:5:3:5:3 | a | nested_scopes.rb:5:3:5:3 | a | nested_scopes.rb:4:1:39:3 | class scope |
| nested_scopes.rb:7:5:7:5 | a | nested_scopes.rb:7:5:7:5 | a | nested_scopes.rb:6:3:37:5 | module scope |
| nested_scopes.rb:9:7:9:7 | a | nested_scopes.rb:9:7:9:7 | a | nested_scopes.rb:8:5:35:7 | module scope |
| nested_scopes.rb:11:9:11:9 | a | nested_scopes.rb:11:9:11:9 | a | nested_scopes.rb:10:7:26:9 | class scope |
| nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:12:9:21:11 | method scope |
| nested_scopes.rb:14:16:14:16 | a | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:12:9:21:11 | method scope |
| nested_scopes.rb:15:11:15:11 | a | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:12:9:21:11 | method scope |
| nested_scopes.rb:25:14:25:14 | a | nested_scopes.rb:11:9:11:9 | a | nested_scopes.rb:10:7:26:9 | class scope |
| nested_scopes.rb:31:11:31:11 | a | nested_scopes.rb:31:11:31:11 | a | nested_scopes.rb:30:7:33:9 | class scope |
| nested_scopes.rb:32:16:32:16 | a | nested_scopes.rb:31:11:31:11 | a | nested_scopes.rb:30:7:33:9 | class scope |
| nested_scopes.rb:34:12:34:12 | a | nested_scopes.rb:9:7:9:7 | a | nested_scopes.rb:8:5:35:7 | module scope |
| nested_scopes.rb:36:10:36:10 | a | nested_scopes.rb:7:5:7:5 | a | nested_scopes.rb:6:3:37:5 | module scope |
| nested_scopes.rb:38:8:38:8 | a | nested_scopes.rb:5:3:5:3 | a | nested_scopes.rb:4:1:39:3 | class scope |
| nested_scopes.rb:40:1:40:1 | d | nested_scopes.rb:40:1:40:1 | d | nested_scopes.rb:1:1:42:1 | top-level scope |
| nested_scopes.rb:41:1:41:1 | d | nested_scopes.rb:40:1:40:1 | d | nested_scopes.rb:1:1:42:1 | top-level scope |
| parameters.rb:34:1:34:1 | b | parameters.rb:34:1:34:1 | b | parameters.rb:1:1:58:1 | top-level scope |
| parameters.rb:35:16:35:16 | b | parameters.rb:35:16:35:16 | b | parameters.rb:35:1:38:3 | method scope |
| parameters.rb:37:16:37:16 | b | parameters.rb:35:16:35:16 | b | parameters.rb:35:1:38:3 | method scope |
| parameters.rb:40:15:40:15 | e | parameters.rb:40:15:40:15 | e | parameters.rb:40:1:43:3 | method scope |
| parameters.rb:42:16:42:16 | e | parameters.rb:40:15:40:15 | e | parameters.rb:40:1:43:3 | method scope |
| parameters.rb:53:1:53:1 | x | parameters.rb:53:1:53:1 | x | parameters.rb:1:1:58:1 | top-level scope |
| parameters.rb:54:19:54:19 | x | parameters.rb:53:1:53:1 | x | parameters.rb:1:1:58:1 | top-level scope |
| parameters.rb:55:9:55:9 | x | parameters.rb:53:1:53:1 | x | parameters.rb:1:1:58:1 | top-level scope |
| scopes.rb:4:4:4:4 | a | scopes.rb:4:4:4:4 | a | scopes.rb:2:9:6:3 | block scope |
| scopes.rb:5:9:5:9 | a | scopes.rb:4:4:4:4 | a | scopes.rb:2:9:6:3 | block scope |
| scopes.rb:7:1:7:1 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:13:3 | top-level scope |
| scopes.rb:8:6:8:6 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:13:3 | top-level scope |
| scopes.rb:10:9:10:9 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:13:3 | top-level scope |
| scopes.rb:11:4:11:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:13:3 | top-level scope |
| scopes.rb:12:9:12:9 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:13:3 | top-level scope |
| scopes.rb:8:6:8:6 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:18:3 | top-level scope |
| scopes.rb:10:9:10:9 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:18:3 | top-level scope |
| scopes.rb:11:4:11:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:18:3 | top-level scope |
| scopes.rb:12:9:12:9 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:18:3 | top-level scope |
| scopes.rb:13:4:13:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:18:3 | top-level scope |
| scopes.rb:14:9:14:9 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:18:3 | top-level scope |
| scopes.rb:15:9:15:9 | b | scopes.rb:13:7:13:7 | b | scopes.rb:9:9:18:3 | block scope |
| scopes.rb:16:9:16:9 | c | scopes.rb:13:11:13:11 | c | scopes.rb:9:9:18:3 | block scope |
| scopes.rb:17:9:17:9 | d | scopes.rb:13:14:13:14 | d | scopes.rb:9:9:18:3 | block scope |

View File

@@ -4,16 +4,3 @@ query predicate variableAccess(VariableAccess access, Variable variable, Variabl
variable = access.getVariable() and
scope = variable.getDeclaringScope()
}
query predicate parameterAccess(ParameterAccess access, LocalVariable variable, VariableScope scope) {
variable = access.getVariable() and
scope = variable.getDeclaringScope()
}
query predicate localVariableAccess(
VariableAccess access, LocalVariable variable, VariableScope scope
) {
not access instanceof ParameterAccess and
variable = access.getVariable() and
scope = variable.getDeclaringScope()
}

View File

@@ -1,4 +1,3 @@
variable
| nested_scopes.rb:5:3:5:3 | a |
| nested_scopes.rb:7:5:7:5 | a |
| nested_scopes.rb:9:7:9:7 | a |
@@ -30,6 +29,7 @@ variable
| parameters.rb:40:12:40:12 | d |
| parameters.rb:40:15:40:15 | e |
| parameters.rb:45:20:45:20 | _ |
| parameters.rb:45:22:45:22 | _ |
| parameters.rb:49:13:49:13 | a |
| parameters.rb:49:15:49:15 | b |
| parameters.rb:53:1:53:1 | x |
@@ -38,44 +38,6 @@ variable
| scopes.rb:4:4:4:4 | a |
| scopes.rb:7:1:7:1 | a |
| scopes.rb:9:14:9:14 | x |
parameter
| nested_scopes.rb:15:23:15:23 | a |
| nested_scopes.rb:16:26:16:26 | x |
| nested_scopes.rb:16:29:16:29 | a |
| nested_scopes.rb:18:26:18:26 | x |
| nested_scopes.rb:22:21:22:21 | a |
| parameters.rb:1:14:1:14 | x |
| parameters.rb:1:18:1:18 | y |
| parameters.rb:7:17:7:22 | client |
| parameters.rb:7:26:7:31 | pizzas |
| parameters.rb:15:17:15:19 | map |
| parameters.rb:16:16:16:18 | key |
| parameters.rb:16:21:16:25 | value |
| parameters.rb:21:17:21:21 | block |
| parameters.rb:25:15:25:18 | name |
| parameters.rb:25:33:25:36 | size |
| parameters.rb:30:15:30:19 | first |
| parameters.rb:30:24:30:29 | middle |
| parameters.rb:30:36:30:39 | last |
| parameters.rb:35:11:35:11 | a |
| parameters.rb:40:12:40:12 | d |
| parameters.rb:45:20:45:20 | _ |
| parameters.rb:49:13:49:13 | a |
| parameters.rb:49:15:49:15 | b |
| parameters.rb:54:14:54:14 | y |
| scopes.rb:2:14:2:14 | x |
| scopes.rb:9:14:9:14 | x |
localVariable
| nested_scopes.rb:5:3:5:3 | a |
| nested_scopes.rb:7:5:7:5 | a |
| nested_scopes.rb:9:7:9:7 | a |
| nested_scopes.rb:11:9:11:9 | a |
| nested_scopes.rb:13:11:13:11 | a |
| nested_scopes.rb:31:11:31:11 | a |
| nested_scopes.rb:40:1:40:1 | d |
| parameters.rb:34:1:34:1 | b |
| parameters.rb:35:16:35:16 | b |
| parameters.rb:40:15:40:15 | e |
| parameters.rb:53:1:53:1 | x |
| scopes.rb:4:4:4:4 | a |
| scopes.rb:7:1:7:1 | a |
| scopes.rb:13:7:13:7 | b |
| scopes.rb:13:11:13:11 | c |
| scopes.rb:13:14:13:14 | d |

View File

@@ -1,7 +1,3 @@
import codeql_ruby.ast.Variable
query predicate variable(Variable v) { any() }
query predicate parameter(LocalVariable v) { v.getAnAccess() instanceof ParameterAccess }
query predicate localVariable(LocalVariable v) { not v.getAnAccess() instanceof ParameterAccess }

View File

@@ -25,6 +25,6 @@
| parameters.rb:49:1:51:3 | method scope |
| parameters.rb:54:9:57:3 | block scope |
| scopes.rb:1:1:1:15 | method scope |
| scopes.rb:1:1:13:3 | top-level scope |
| scopes.rb:1:1:18:3 | top-level scope |
| scopes.rb:2:9:6:3 | block scope |
| scopes.rb:9:9:13:3 | block scope |
| scopes.rb:9:9:18:3 | block scope |