diff --git a/ql/src/codeql_ruby/AST.qll b/ql/src/codeql_ruby/AST.qll index 28a05877c5f..d64e6d6f1b5 100644 --- a/ql/src/codeql_ruby/AST.qll +++ b/ql/src/codeql_ruby/AST.qll @@ -9,6 +9,7 @@ import ast.Module import ast.Parameter import ast.Operation import ast.Pattern +import ast.Scope import ast.Statement import ast.Variable private import ast.internal.AST diff --git a/ql/src/codeql_ruby/ast/Method.qll b/ql/src/codeql_ruby/ast/Method.qll index 3040df238cc..60a17ac340a 100644 --- a/ql/src/codeql_ruby/ast/Method.qll +++ b/ql/src/codeql_ruby/ast/Method.qll @@ -18,13 +18,18 @@ class Callable extends Expr, CfgScope { } /** A method. */ -class Method extends Callable, BodyStatement, @method { - final override Method::Range range; - - final override string getAPrimaryQlClass() { result = "Method" } +class MethodBase extends Callable, BodyStatement, Scope { + override MethodBase::Range range; /** Gets the name of this method. */ final string getName() { result = range.getName() } +} + +/** A normal method. */ +class Method extends MethodBase, @method { + final override Method::Range range; + + final override string getAPrimaryQlClass() { result = "Method" } /** * Holds if this is a setter method, as in the following example: @@ -40,16 +45,13 @@ class Method extends Callable, BodyStatement, @method { } /** A singleton method. */ -class SingletonMethod extends Callable, BodyStatement, @singleton_method { +class SingletonMethod extends MethodBase, @singleton_method { final override SingletonMethod::Range range; final override string getAPrimaryQlClass() { result = "SingletonMethod" } /** Gets the object of this singleton method. */ final Expr getObject() { result = range.getObject() } - - /** Gets the name of this method. */ - final string getName() { result = range.getName() } } /** @@ -65,7 +67,7 @@ class Lambda extends Callable, BodyStatement, @lambda { } /** A block. */ -class Block extends Callable, StmtSequence { +class Block extends Callable, StmtSequence, Scope { override Block::Range range; } diff --git a/ql/src/codeql_ruby/ast/Module.qll b/ql/src/codeql_ruby/ast/Module.qll index 64238e60213..5f3e150e79a 100644 --- a/ql/src/codeql_ruby/ast/Module.qll +++ b/ql/src/codeql_ruby/ast/Module.qll @@ -5,14 +5,14 @@ private import internal.Module /** * The base class for classes, singleton classes, and modules. */ -class ModuleBase extends BodyStatement { +class ModuleBase extends BodyStatement, Scope { override ModuleBase::Range range; /** Gets a method defined in this module/class. */ - Method getAMethod() { result = this.getAStmt() } + MethodBase getAMethod() { result = this.getAStmt() } /** Gets the method named `name` in this module/class, if any. */ - Method getMethod(string name) { result = this.getAMethod() and result.getName() = name } + MethodBase getMethod(string name) { result = this.getAMethod() and result.getName() = name } /** Gets a class defined in this module/class. */ Class getAClass() { result = this.getAStmt() } diff --git a/ql/src/codeql_ruby/ast/Scope.qll b/ql/src/codeql_ruby/ast/Scope.qll new file mode 100644 index 00000000000..c0484232a3d --- /dev/null +++ b/ql/src/codeql_ruby/ast/Scope.qll @@ -0,0 +1,24 @@ +private import codeql_ruby.AST +private import internal.Scope + +class Scope extends AstNode, Scope::ScopeType { + override Scope::Range range; + + AstNode getADescendant() { result = range.getADescendant() } + + ModuleBase getEnclosingModule() { result = range.getEnclosingModule() } + + MethodBase getEnclosingMethod() { result = range.getEnclosingMethod() } + + /** Gets the scope in which this scope is nested, if any. */ + Scope getOuterScope() { result = range.getOuterScope() } + + /** Gets a variable that is declared in this scope. */ + final Variable getAVariable() { result.getDeclaringScope() = this } + + /** Gets the variable declared in this scope with the given name, if any. */ + final Variable getVariable(string name) { + result = this.getAVariable() and + result.getName() = name + } +} diff --git a/ql/src/codeql_ruby/ast/Statement.qll b/ql/src/codeql_ruby/ast/Statement.qll index 2e6e6c37509..2842ba23661 100644 --- a/ql/src/codeql_ruby/ast/Statement.qll +++ b/ql/src/codeql_ruby/ast/Statement.qll @@ -2,7 +2,6 @@ private import codeql_ruby.AST private import codeql_ruby.CFG private import internal.Expr private import internal.Statement -private import internal.Variable private import codeql_ruby.controlflow.internal.ControlFlowGraphImpl /** @@ -19,9 +18,6 @@ class Stmt extends AstNode { /** Gets the control-flow scope of this statement, if any. */ CfgScope getCfgScope() { result = getCfgScope(this) } - /** Gets the variable scope that this statement belongs to. */ - VariableScope getVariableScope() { result = enclosingScope(this) } - /** Gets the enclosing callable, if any. */ Callable getEnclosingCallable() { result = this.getCfgScope() } } diff --git a/ql/src/codeql_ruby/ast/Variable.qll b/ql/src/codeql_ruby/ast/Variable.qll index d848763b71b..955723399dd 100644 --- a/ql/src/codeql_ruby/ast/Variable.qll +++ b/ql/src/codeql_ruby/ast/Variable.qll @@ -4,34 +4,6 @@ private import codeql_ruby.AST private import codeql.Locations private import internal.Variable -/** A scope in which variables can be declared. */ -class VariableScope extends TScope { - VariableScope::Range range; - - VariableScope() { range = this } - - /** Gets a textual representation of this element. */ - final string toString() { result = range.toString() } - - /** Gets the program element this scope is associated with, if any. */ - final AstNode getScopeElement() { result = range.getScopeElement() } - - /** Gets the location of the program element this scope is associated with. */ - final Location getLocation() { result = getScopeElement().getLocation() } - - /** Gets a variable that is declared in this scope. */ - final Variable getAVariable() { result.getDeclaringScope() = this } - - /** Gets the variable with the given name that is declared in this scope. */ - final Variable getVariable(string name) { - result = this.getAVariable() and - result.getName() = name - } - - /** Gets the scope in which this scope is nested, if any. */ - VariableScope getOuterScope() { result = enclosingScope(this.getScopeElement()) } -} - /** A variable declared in a scope. */ class Variable extends TVariable { Variable::Range range; @@ -48,7 +20,7 @@ class Variable extends TVariable { final Location getLocation() { result = range.getLocation() } /** Gets the scope this variable is declared in. */ - final VariableScope getDeclaringScope() { result = range.getDeclaringScope() } + final Scope getDeclaringScope() { result = range.getDeclaringScope() } /** Gets an access to this variable. */ VariableAccess getAnAccess() { result.getVariable() = this } diff --git a/ql/src/codeql_ruby/ast/internal/Method.qll b/ql/src/codeql_ruby/ast/internal/Method.qll index 49540f9b788..0b31ca2d22d 100644 --- a/ql/src/codeql_ruby/ast/internal/Method.qll +++ b/ql/src/codeql_ruby/ast/internal/Method.qll @@ -2,6 +2,7 @@ private import codeql_ruby.AST private import codeql_ruby.ast.internal.AST private import codeql_ruby.ast.internal.Expr private import codeql_ruby.ast.internal.Parameter +private import codeql_ruby.ast.internal.Scope private import TreeSitter module Callable { @@ -14,13 +15,25 @@ module Callable { } } +module MethodBase { + abstract class Range extends Callable::Range, BodyStatement::Range, Scope::Range { + abstract string getName(); + + override predicate child(string label, AstNode::Range child) { + Callable::Range.super.child(label, child) or BodyStatement::Range.super.child(label, child) + } + + override string toString() { result = BodyStatement::Range.super.toString() } + } +} + module Method { - class Range extends Callable::Range, BodyStatement::Range, @method { + class Range extends MethodBase::Range, @method { final override Generated::Method generated; override Parameter::Range getParameter(int n) { result = generated.getParameters().getChild(n) } - string getName() { + override string getName() { result = generated.getName().(Generated::Token).getValue() or result = generated.getName().(Generated::Setter).getName().getValue() + "=" } @@ -30,20 +43,16 @@ module Method { final override Generated::AstNode getChild(int i) { result = generated.getChild(i) } final override string toString() { result = this.getName() } - - override predicate child(string label, AstNode::Range child) { - Callable::Range.super.child(label, child) or BodyStatement::Range.super.child(label, child) - } } } module SingletonMethod { - class Range extends Callable::Range, BodyStatement::Range, @singleton_method { + class Range extends MethodBase::Range, @singleton_method { final override Generated::SingletonMethod generated; override Parameter::Range getParameter(int n) { result = generated.getParameters().getChild(n) } - string getName() { + override string getName() { result = generated.getName().(Generated::Token).getValue() or result = generated.getName().(SymbolLiteral).getValueText() or result = generated.getName().(Generated::Setter).getName().getValue() + "=" @@ -56,9 +65,7 @@ module SingletonMethod { final override string toString() { result = this.getName() } override predicate child(string label, AstNode::Range child) { - Callable::Range.super.child(label, child) - or - BodyStatement::Range.super.child(label, child) + MethodBase::Range.super.child(label, child) or label = "getObject" and child = getObject() } @@ -89,7 +96,7 @@ module Lambda { } module Block { - abstract class Range extends Callable::Range, StmtSequence::Range { + abstract class Range extends Callable::Range, StmtSequence::Range, Scope::Range { Range() { not generated.getParent() instanceof Generated::Lambda } override predicate child(string label, AstNode::Range child) { @@ -97,6 +104,8 @@ module Block { or StmtSequence::Range.super.child(label, child) } + + override string toString() { result = StmtSequence::Range.super.toString() } } } diff --git a/ql/src/codeql_ruby/ast/internal/Module.qll b/ql/src/codeql_ruby/ast/internal/Module.qll index e5b28b92df2..349e6ced59a 100644 --- a/ql/src/codeql_ruby/ast/internal/Module.qll +++ b/ql/src/codeql_ruby/ast/internal/Module.qll @@ -2,10 +2,13 @@ private import codeql_ruby.AST private import codeql_ruby.ast.internal.AST private import codeql_ruby.ast.internal.Constant private import codeql_ruby.ast.internal.Expr +private import codeql_ruby.ast.internal.Scope private import codeql_ruby.ast.internal.TreeSitter module ModuleBase { - abstract class Range extends BodyStatement::Range { } + abstract class Range extends BodyStatement::Range, Scope::Range { + override string toString() { result = BodyStatement::Range.super.toString() } + } } module Namespace { diff --git a/ql/src/codeql_ruby/ast/internal/Scope.qll b/ql/src/codeql_ruby/ast/internal/Scope.qll new file mode 100644 index 00000000000..ab057c2d921 --- /dev/null +++ b/ql/src/codeql_ruby/ast/internal/Scope.qll @@ -0,0 +1,63 @@ +private import TreeSitter +private import codeql_ruby.ast.internal.AST +private import codeql_ruby.ast.internal.Module +private import codeql_ruby.ast.internal.Method +private import codeql_ruby.ast.internal.Statement + +module Scope { + class ScopeType = MethodLike or ModuleLike or BlockLike; + + class BlockLike = @do_block or @lambda or @block or @end_block; + + class ModuleLike = @program or @module or @class or @singleton_class; + + class MethodLike = @method or @singleton_method; + + class Range extends AstNode::Range, ScopeType { + Range() { not exists(Generated::Lambda l | l.getBody() = this) } + + Generated::AstNode getADescendant() { this = scopeOf(result) } + + ModuleBase::Range getEnclosingModule() { + result = this + or + not this instanceof ModuleBase::Range and result = this.getOuterScope().getEnclosingModule() + } + + MethodBase::Range getEnclosingMethod() { + result = this + or + not this instanceof MethodBase::Range and + not this instanceof ModuleBase::Range and + result = this.getOuterScope().getEnclosingMethod() + } + + Scope::Range getOuterScope() { result = scopeOf(this) } + + override string toString() { none() } + } +} + +/** Gets the enclosing scope of a node */ +private Scope::Range scopeOf(Generated::AstNode n) { + exists(Generated::AstNode p | p = parentOf(n) | + p instanceof Scope::Range and result = p + or + not p instanceof Scope::Range and result = scopeOf(p) + ) +} + +private Generated::AstNode parentOf(Generated::AstNode n) { + exists(Generated::AstNode parent | parent = n.getParent() | + if + n = + [ + parent.(Generated::Module).getName(), parent.(Generated::Class).getName(), + parent.(Generated::Class).getSuperclass(), parent.(Generated::SingletonClass).getValue(), + parent.(Generated::Method).getName(), parent.(Generated::SingletonMethod).getName(), + parent.(Generated::SingletonMethod).getObject() + ] + then result = parent.getParent() + else result = parent + ) +} diff --git a/ql/src/codeql_ruby/ast/internal/Variable.qll b/ql/src/codeql_ruby/ast/internal/Variable.qll index ee2e11a7d91..7a64e957609 100644 --- a/ql/src/codeql_ruby/ast/internal/Variable.qll +++ b/ql/src/codeql_ruby/ast/internal/Variable.qll @@ -7,78 +7,37 @@ private import codeql_ruby.ast.internal.Method private import codeql_ruby.ast.internal.Module private import codeql_ruby.ast.internal.Pattern private import codeql_ruby.ast.internal.Parameter - -Generated::AstNode parentOf(Generated::AstNode n) { - exists(Generated::AstNode parent | parent = n.getParent() | - if - n = - [ - parent.(Generated::Module).getName(), parent.(Generated::Class).getName(), - parent.(Generated::Class).getSuperclass(), parent.(Generated::SingletonClass).getValue(), - parent.(Generated::Method).getName(), parent.(Generated::SingletonMethod).getName(), - parent.(Generated::SingletonMethod).getObject() - ] - then result = parent.getParent() - else result = parent - ) -} - -private Generated::AstNode parentOfNoScope(Generated::AstNode n) { - result = parentOf(n) and - not n = any(VariableScope::Range s).getScopeElement() -} +private import codeql_ruby.ast.internal.Scope private predicate instanceVariableAccess( - Generated::InstanceVariable var, string name, VariableScope scope, boolean instance + Generated::InstanceVariable var, string name, Scope::Range scope, boolean instance ) { name = var.getValue() and scope = enclosingModuleOrClass(var) and if hasEnclosingMethod(var) then instance = true else instance = false } -private predicate classVariableAccess(Generated::ClassVariable var, string name, VariableScope scope) { +private predicate classVariableAccess(Generated::ClassVariable var, string name, Scope::Range scope) { name = var.getValue() and scope = enclosingModuleOrClass(var) } -predicate hasEnclosingMethod(Generated::AstNode node) { - exists(Callable::Range method | - parentCallableScope*(enclosingScope(node)) = TCallableScope(method) - | - method instanceof Method::Range or - method instanceof SingletonMethod::Range - ) +private predicate hasEnclosingMethod(Generated::AstNode node) { + exists(Scope::Range s | node = s.getADescendant() and exists(s.getEnclosingMethod())) } -private TCallableScope parentCallableScope(TCallableScope scope) { - exists(Callable::Range c | - scope = TCallableScope(c) and - not c instanceof Method::Range and - not c instanceof SingletonMethod::Range - | - result = scope.(VariableScope::Range).getOuterScope() - ) +private ModuleBase::Range enclosingModuleOrClass(Generated::AstNode node) { + exists(Scope::Range s | node = s.getADescendant() and result = s.getEnclosingModule()) } -private VariableScope::Range parentScope(VariableScope::Range scope) { - not scope instanceof ModuleOrClassScope and - result = scope.getOuterScope() -} - -private ModuleOrClassScope enclosingModuleOrClass(Generated::AstNode node) { - result = parentScope*(enclosingScope(node)) -} - -private predicate parameterAssignment( - CallableScope::Range scope, string name, Generated::Identifier i -) { - implicitParameterAssignmentNode(i, scope.getScopeElement()) and +private predicate parameterAssignment(Callable::Range scope, string name, Generated::Identifier i) { + implicitParameterAssignmentNode(i, scope) and name = i.getValue() } /** Holds if `scope` defines `name` in its parameter declaration at `i`. */ private predicate scopeDefinesParameterVariable( - CallableScope::Range scope, string name, Generated::Identifier i + Callable::Range scope, string name, Generated::Identifier i ) { // In case of overlapping parameter names (e.g. `_`), only the first // parameter will give rise to a variable @@ -90,7 +49,7 @@ private predicate scopeDefinesParameterVariable( ) or exists(Parameter::Range p | - p = scope.getScopeElement().(Callable::Range).getParameter(_) and + p = scope.(Callable::Range).getParameter(_) and name = p.(NamedParameter::Range).getName() | i = p.(Generated::BlockParameter).getName() or @@ -102,7 +61,7 @@ private predicate scopeDefinesParameterVariable( } /** Holds if `name` is assigned in `scope` at `i`. */ -private predicate scopeAssigns(VariableScope scope, string name, Generated::Identifier i) { +private predicate scopeAssigns(Scope::Range scope, string name, Generated::Identifier i) { (explicitAssignmentNode(i, _) or implicitAssignmentNode(i)) and name = i.getValue() and scope = enclosingScope(i) @@ -137,9 +96,7 @@ cached private module Cached { /** Gets the enclosing scope for `node`. */ cached - VariableScope::Range enclosingScope(Generated::AstNode node) { - result.getScopeElement() = parentOfNoScope*(parentOf(node)) - } + Scope::Range enclosingScope(Generated::AstNode node) { result.getADescendant() = node } cached newtype TScope = @@ -154,7 +111,7 @@ private module Cached { cached newtype TVariable = TGlobalVariable(string name) { name = any(Generated::GlobalVariable var).getValue() } or - TClassVariable(VariableScope scope, string name, Generated::AstNode decl) { + TClassVariable(Scope::Range scope, string name, Generated::AstNode decl) { decl = min(Generated::ClassVariable other | classVariableAccess(other, name, scope) @@ -162,7 +119,7 @@ private module Cached { other order by other.getLocation().getStartLine(), other.getLocation().getStartColumn() ) } or - TInstanceVariable(VariableScope scope, string name, boolean instance, Generated::AstNode decl) { + TInstanceVariable(Scope::Range scope, string name, boolean instance, Generated::AstNode decl) { decl = min(Generated::InstanceVariable other | instanceVariableAccess(other, name, scope, instance) @@ -170,7 +127,7 @@ private module Cached { other order by other.getLocation().getStartLine(), other.getLocation().getStartColumn() ) } or - TLocalVariable(VariableScope::Range scope, string name, Generated::Identifier i) { + TLocalVariable(Scope::Range scope, string name, Generated::Identifier i) { scopeDefinesParameterVariable(scope, name, i) or i = @@ -180,7 +137,7 @@ private module Cached { other order by other.getLocation().getStartLine(), other.getLocation().getStartColumn() ) and not scopeDefinesParameterVariable(scope, name, _) and - not scope.inherits(name, _) + not inherits(scope, name, _) } // Db types that can be vcalls @@ -330,10 +287,12 @@ private module Cached { } cached - predicate access(Generated::Identifier access, Variable variable) { - exists(string name | name = access.getValue() | - variable.getDeclaringScope() = enclosingScope(access) and + predicate access(Generated::Identifier access, Variable::Range variable) { + exists(string name | variable.getName() = name and + name = access.getValue() + | + variable.getDeclaringScope() = enclosingScope(access) and not strictlyBefore(access.getLocation(), variable.getLocation()) and // In case of overlapping parameter names, later parameters should not // be considered accesses to the first parameter @@ -341,9 +300,9 @@ private module Cached { then scopeDefinesParameterVariable(_, _, access) else any() or - exists(VariableScope declScope | - variable = declScope.getVariable(name) and - enclosingScope(access).inherits(name, declScope) + exists(Scope::Range declScope | + variable.getDeclaringScope() = declScope and + inherits(enclosingScope(access), name, declScope) ) ) } @@ -371,7 +330,7 @@ private module Cached { cached predicate instanceVariableAccess(Generated::InstanceVariable var, InstanceVariable v) { - exists(string name, VariableScope scope, boolean instance | + exists(string name, Scope::Range scope, boolean instance | v = TInstanceVariable(scope, name, instance, _) and instanceVariableAccess(var, name, scope, instance) ) @@ -379,7 +338,7 @@ private module Cached { cached predicate classVariableAccess(Generated::ClassVariable var, ClassVariable variable) { - exists(VariableScope scope, string name | + exists(Scope::Range scope, string name | variable = TClassVariable(scope, name, _) and classVariableAccess(var, name, scope) ) @@ -388,125 +347,22 @@ private module Cached { import Cached -module VariableScope { - abstract class Range extends TScope { - abstract string toString(); - - abstract Generated::AstNode getScopeElement(); - - abstract predicate isCapturing(); - - VariableScope::Range getOuterScope() { result = enclosingScope(this.getScopeElement()) } - - /** Holds if this scope inherits `name` from an outer scope `outer`. */ - predicate inherits(string name, VariableScope::Range outer) { - this.isCapturing() and - 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().inherits(name, outer) +/** Holds if this scope inherits `name` from an outer scope `outer`. */ +private predicate inherits(Block::Range scope, string name, Scope::Range outer) { + not scopeDefinesParameterVariable(scope, name, _) and + ( + outer = scope.getOuterScope() and + ( + scopeDefinesParameterVariable(outer, name, _) + or + exists(Generated::Identifier i | + scopeAssigns(outer, name, i) and + strictlyBefore(i.getLocation(), scope.(Generated::AstNode).getLocation()) ) - } - - final Location getLocation() { result = getScopeElement().getLocation() } - } -} - -module GlobalScope { - class Range extends VariableScope::Range, TGlobalScope { - override string toString() { result = "global scope" } - - override Generated::AstNode getScopeElement() { none() } - - override predicate isCapturing() { none() } - } -} - -module TopLevelScope { - class Range extends VariableScope::Range, TTopLevelScope { - Generated::Program program; - - Range() { TTopLevelScope(program) = this } - - override string toString() { - result = "top-level scope for " + program.getLocation().getFile().getBaseName() - } - - override Generated::AstNode getScopeElement() { result = program } - - override predicate isCapturing() { none() } - } -} - -module ModuleScope { - class Range extends VariableScope::Range, TModuleScope { - Generated::Module mdl; - - Range() { TModuleScope(mdl) = this } - - override string toString() { result = "module scope for " + mdl.(Module::Range).getName() } - - override Generated::AstNode getScopeElement() { result = mdl } - - override predicate isCapturing() { none() } - } -} - -module ClassScope { - class Range extends VariableScope::Range, TClassScope { - Generated::AstNode cls; - - Range() { TClassScope(cls) = this } - - override string toString() { - result = "class scope for " + cls.(Class::Range).getName() - or - cls instanceof Generated::SingletonClass and result = "class scope" - } - - override Generated::AstNode getScopeElement() { result = cls } - - override predicate isCapturing() { none() } - } -} - -module CallableScope { - class Range extends VariableScope::Range, TCallableScope { - private Generated::AstNode c; - - Range() { this = TCallableScope(c) } - - override string toString() { - result = "method scope for " + c.(SingletonMethod).getName() - or - result = "method scope for " + c.(Method).getName() - or - c instanceof Lambda and - result = "lambda scope" - or - c instanceof Block and - result = "block scope" - } - - override Generated::AstNode getScopeElement() { TCallableScope(result) = this } - - override predicate isCapturing() { - c instanceof Generated::Lambda - or - c instanceof Generated::Block - or - c instanceof Generated::DoBlock - } - } + ) + or + inherits(scope.getOuterScope(), name, outer) + ) } module Variable { @@ -517,13 +373,13 @@ module Variable { abstract Location getLocation(); - abstract VariableScope getDeclaringScope(); + abstract Scope::Range getDeclaringScope(); } } module LocalVariable { class Range extends Variable::Range, TLocalVariable { - private VariableScope scope; + private Scope::Range scope; private string name; private Generated::Identifier i; @@ -533,7 +389,7 @@ module LocalVariable { final override Location getLocation() { result = i.getLocation() } - final override VariableScope getDeclaringScope() { result = scope } + final override Scope::Range getDeclaringScope() { result = scope } final VariableAccess getDefiningAccess() { result = getNodeForIdentifier(i) } } @@ -549,7 +405,7 @@ module GlobalVariable { final override Location getLocation() { none() } - final override VariableScope getDeclaringScope() { result = TGlobalScope() } + final override Scope::Range getDeclaringScope() { none() } } } @@ -557,7 +413,7 @@ private class ModuleOrClassScope = TClassScope or TModuleScope or TTopLevelScope module InstanceVariable { class Range extends Variable::Range, TInstanceVariable { - private ModuleOrClassScope scope; + private ModuleBase::Range scope; private boolean instance; private string name; private Generated::AstNode decl; @@ -570,13 +426,13 @@ module InstanceVariable { final override Location getLocation() { result = decl.getLocation() } - final override VariableScope getDeclaringScope() { result = scope } + final override Scope::Range getDeclaringScope() { result = scope } } } module ClassVariable { class Range extends Variable::Range, TClassVariable { - private ModuleOrClassScope scope; + private ModuleBase::Range scope; private string name; private Generated::AstNode decl; @@ -586,7 +442,7 @@ module ClassVariable { final override Location getLocation() { result = decl.getLocation() } - final override VariableScope getDeclaringScope() { result = scope } + final override Scope::Range getDeclaringScope() { result = scope } } } diff --git a/ql/src/codeql_ruby/controlflow/internal/ControlFlowGraphImpl.qll b/ql/src/codeql_ruby/controlflow/internal/ControlFlowGraphImpl.qll index 931f7020666..f6d63161d94 100644 --- a/ql/src/codeql_ruby/controlflow/internal/ControlFlowGraphImpl.qll +++ b/ql/src/codeql_ruby/controlflow/internal/ControlFlowGraphImpl.qll @@ -33,6 +33,7 @@ private import codeql_ruby.ast.internal.AST as ASTInternal private import codeql_ruby.ast.internal.Control as Control +private import codeql_ruby.ast.internal.Scope private import codeql_ruby.ast.internal.TreeSitter::Generated private import AstNodes private import codeql_ruby.ast.internal.Variable @@ -148,11 +149,6 @@ module CfgScope { } } -private AstNode parent(AstNode n) { - result = parentOf(n) and - not n instanceof CfgScope -} - abstract private class ControlFlowTree extends AstNode { /** * Holds if `first` is the first element executed within this AST node. @@ -1263,11 +1259,16 @@ module Trees { } } +private Scope::Range parent(Scope::Range n) { + result = n.getOuterScope() and + not n instanceof CfgScope +} + cached private module Cached { /** Gets the CFG scope of node `n`. */ cached - CfgScope getCfgScope(AstNode n) { result = unique(CfgScope scope | scope = parent*(parentOf(n))) } + CfgScope getCfgScope(AstNode n) { result = parent*(any(Scope::Range x | x.getADescendant() = n)) } private predicate isAbnormalExitType(SuccessorType t) { t instanceof RaiseSuccessor or t instanceof ExitSuccessor diff --git a/ql/src/codeql_ruby/dataflow/internal/SsaImpl.qll b/ql/src/codeql_ruby/dataflow/internal/SsaImpl.qll index f8d4671e563..bdc3c813ca0 100644 --- a/ql/src/codeql_ruby/dataflow/internal/SsaImpl.qll +++ b/ql/src/codeql_ruby/dataflow/internal/SsaImpl.qll @@ -6,7 +6,7 @@ private import CfgNodes::ExprNodes /** Holds if `v` is uninitialized at index `i` in entry block `bb`. */ predicate uninitializedWrite(EntryBasicBlock bb, int i, LocalVariable v) { - v.getDeclaringScope().getScopeElement() = bb.getScope() and + v.getDeclaringScope() = bb.getScope() and i = -1 } diff --git a/ql/test/library-tests/variables/varaccess.expected b/ql/test/library-tests/variables/varaccess.expected index 596bd750fea..ddfa887a139 100644 --- a/ql/test/library-tests/variables/varaccess.expected +++ b/ql/test/library-tests/variables/varaccess.expected @@ -1,181 +1,179 @@ variableAccess -| class_variables.rb:1:1:1:3 | @@x | class_variables.rb:1:1:1:3 | @@x | class_variables.rb:1:1:29:4 | top-level scope for class_variables.rb | -| class_variables.rb:3:3:3:5 | @@x | class_variables.rb:1:1:1:3 | @@x | class_variables.rb:1:1:29:4 | top-level scope for class_variables.rb | -| class_variables.rb:6:4:6:6 | @@x | class_variables.rb:1:1:1:3 | @@x | class_variables.rb:1:1:29:4 | top-level scope for class_variables.rb | -| class_variables.rb:11:7:11:9 | @@x | class_variables.rb:11:7:11:9 | @@x | class_variables.rb:9:1:16:3 | class scope for X | -| class_variables.rb:14:6:14:8 | @@x | class_variables.rb:11:7:11:9 | @@x | class_variables.rb:9:1:16:3 | class scope for X | -| class_variables.rb:19:3:19:5 | @@x | class_variables.rb:19:3:19:5 | @@x | class_variables.rb:18:1:20:3 | class scope for Y | -| class_variables.rb:23:3:23:5 | @@x | class_variables.rb:23:3:23:5 | @@x | class_variables.rb:22:1:24:3 | module scope for M | -| class_variables.rb:28:5:28:7 | @@x | class_variables.rb:28:5:28:7 | @@x | class_variables.rb:26:1:29:3 | module scope for N | -| instance_variables.rb:1:1:1:4 | @top | instance_variables.rb:1:1:1:4 | @top | instance_variables.rb:1:1:44:4 | top-level scope for instance_variables.rb | -| instance_variables.rb:4:3:4:6 | @foo | instance_variables.rb:4:3:4:6 | @foo | instance_variables.rb:1:1:44:4 | top-level scope for instance_variables.rb | -| instance_variables.rb:8:8:8:11 | @foo | instance_variables.rb:4:3:4:6 | @foo | instance_variables.rb:1:1:44:4 | top-level scope for instance_variables.rb | -| instance_variables.rb:11:6:11:9 | @top | instance_variables.rb:1:1:1:4 | @top | instance_variables.rb:1:1:44:4 | top-level scope for instance_variables.rb | -| instance_variables.rb:14:3:14:4 | @x | instance_variables.rb:14:3:14:4 | @x | instance_variables.rb:13:1:18:3 | class scope for X | -| instance_variables.rb:16:5:16:6 | @y | instance_variables.rb:16:5:16:6 | @y | instance_variables.rb:13:1:18:3 | class scope for X | -| instance_variables.rb:21:2:21:3 | @m | instance_variables.rb:21:2:21:3 | @m | instance_variables.rb:20:1:25:3 | module scope for M | -| instance_variables.rb:23:4:23:5 | @n | instance_variables.rb:23:4:23:5 | @n | instance_variables.rb:20:1:25:3 | module scope for M | -| instance_variables.rb:28:3:28:4 | @x | instance_variables.rb:28:3:28:4 | @x | instance_variables.rb:1:1:44:4 | top-level scope for instance_variables.rb | -| instance_variables.rb:32:12:32:13 | @x | instance_variables.rb:32:12:32:13 | @x | instance_variables.rb:1:1:44:4 | top-level scope for instance_variables.rb | -| instance_variables.rb:36:3:36:4 | @x | instance_variables.rb:36:3:36:4 | @x | instance_variables.rb:35:1:44:4 | class scope for C | -| instance_variables.rb:39:6:39:7 | @x | instance_variables.rb:39:6:39:7 | @x | instance_variables.rb:35:1:44:4 | class scope for C | -| instance_variables.rb:42:6:42:7 | @x | instance_variables.rb:39:6:39:7 | @x | instance_variables.rb:35:1:44:4 | class scope for C | -| 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 for C | -| 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 for M | -| 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 for N | -| 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 for D | -| 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 for show_a | -| 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 for show_a | -| 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 for show_a | -| 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 for show_a2 | -| 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 for show_a2 | -| 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 for D | -| 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 for N | -| 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 for M | -| 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 for C | -| 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 for nested_scopes.rb | -| 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 for nested_scopes.rb | -| 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 for order_pizza | -| parameters.rb:7:25:7:31 | *pizzas | parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:1:13:3 | method scope for order_pizza | -| parameters.rb:8:6:8:11 | pizzas | parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:1:13:3 | method scope for order_pizza | -| parameters.rb:9:25:9:30 | client | parameters.rb:7:17:7:22 | client | parameters.rb:7:1:13:3 | method scope for order_pizza | -| parameters.rb:11:14:11:19 | pizzas | parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:1:13:3 | method scope for order_pizza | -| parameters.rb:11:41:11:46 | client | parameters.rb:7:17:7:22 | client | parameters.rb:7:1:13:3 | method scope for order_pizza | -| parameters.rb:15:15:15:19 | **map | parameters.rb:15:17:15:19 | map | parameters.rb:15:1:19:3 | method scope for print_map | -| parameters.rb:16:3:16:5 | map | parameters.rb:15:17:15:19 | map | parameters.rb:15:1:19:3 | method scope for print_map | -| 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:16:21:21 | &block | parameters.rb:21:17:21:21 | block | parameters.rb:21:1:23:3 | method scope for call_block | -| parameters.rb:22:3:22:7 | block | parameters.rb:21:17:21:21 | block | parameters.rb:21:1:23:3 | method scope for call_block | -| parameters.rb:25:15:25:18 | name | parameters.rb:25:15:25:18 | name | parameters.rb:25:1:28:3 | method scope for opt_param | -| parameters.rb:25:33:25:36 | size | parameters.rb:25:33:25:36 | size | parameters.rb:25:1:28:3 | method scope for opt_param | -| parameters.rb:25:40:25:43 | name | parameters.rb:25:15:25:18 | name | parameters.rb:25:1:28:3 | method scope for opt_param | -| parameters.rb:26:8:26:11 | name | parameters.rb:25:15:25:18 | name | parameters.rb:25:1:28:3 | method scope for opt_param | -| parameters.rb:27:8:27:11 | size | parameters.rb:25:33:25:36 | size | parameters.rb:25:1:28:3 | method scope for opt_param | -| parameters.rb:30:15:30:19 | first | parameters.rb:30:15:30:19 | first | parameters.rb:30:1:32:3 | method scope for key_param | -| parameters.rb:30:24:30:29 | middle | parameters.rb:30:24:30:29 | middle | parameters.rb:30:1:32:3 | method scope for key_param | -| parameters.rb:30:36:30:39 | last | parameters.rb:30:36:30:39 | last | parameters.rb:30:1:32:3 | method scope for key_param | -| parameters.rb:31:11:31:15 | first | parameters.rb:30:15:30:19 | first | parameters.rb:30:1:32:3 | method scope for key_param | -| parameters.rb:31:20:31:25 | middle | parameters.rb:30:24:30:29 | middle | parameters.rb:30:1:32:3 | method scope for key_param | -| parameters.rb:31:30:31:33 | last | parameters.rb:30:36:30:39 | last | parameters.rb:30:1:32:3 | method scope for key_param | -| parameters.rb:34:1:34:1 | b | parameters.rb:34:1:34:1 | b | parameters.rb:1:1:58:1 | top-level scope for parameters.rb | -| parameters.rb:35:11:35:11 | a | parameters.rb:35:11:35:11 | a | parameters.rb:35:1:38:3 | method scope for multi | -| parameters.rb:35:16:35:16 | b | parameters.rb:35:16:35:16 | b | parameters.rb:35:1:38:3 | method scope for multi | -| parameters.rb:37:11:37:11 | a | parameters.rb:35:11:35:11 | a | parameters.rb:35:1:38:3 | method scope for multi | -| parameters.rb:37:16:37:16 | b | parameters.rb:35:16:35:16 | b | parameters.rb:35:1:38:3 | method scope for multi | -| parameters.rb:40:12:40:12 | d | parameters.rb:40:12:40:12 | d | parameters.rb:40:1:43:3 | method scope for multi2 | -| parameters.rb:40:15:40:15 | e | parameters.rb:40:15:40:15 | e | parameters.rb:40:1:43:3 | method scope for multi2 | -| parameters.rb:42:11:42:11 | d | parameters.rb:40:12:40:12 | d | parameters.rb:40:1:43:3 | method scope for multi2 | -| parameters.rb:42:16:42:16 | e | parameters.rb:40:15:40:15 | e | parameters.rb:40:1:43:3 | method scope for multi2 | -| parameters.rb:45:20:45:20 | _ | parameters.rb:45:20:45:20 | _ | parameters.rb:45:1:47:3 | method scope for dup_underscore | -| parameters.rb:46:8:46:8 | _ | parameters.rb:45:20:45:20 | _ | parameters.rb:45:1:47:3 | method scope for dup_underscore | -| parameters.rb:49:13:49:13 | a | parameters.rb:49:13:49:13 | a | parameters.rb:49:1:51:3 | method scope for tuples | -| parameters.rb:49:15:49:15 | b | parameters.rb:49:15:49:15 | b | parameters.rb:49:1:51:3 | method scope for tuples | -| parameters.rb:50:11:50:11 | a | parameters.rb:49:13:49:13 | a | parameters.rb:49:1:51:3 | method scope for tuples | -| parameters.rb:50:16:50:16 | b | parameters.rb:49:15:49:15 | b | parameters.rb:49:1:51:3 | method scope for tuples | -| parameters.rb:53:1:53:1 | x | parameters.rb:53:1:53:1 | x | parameters.rb:1:1:58:1 | top-level scope for parameters.rb | -| 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 for parameters.rb | -| parameters.rb:55:9:55:9 | x | parameters.rb:53:1:53:1 | x | parameters.rb:1:1:58:1 | top-level scope for parameters.rb | -| 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:40:1 | top-level scope for scopes.rb | -| scopes.rb:8:6:8:6 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:40:1 | top-level scope for scopes.rb | -| scopes.rb:9:14:9:14 | x | scopes.rb:9:14:9:14 | x | scopes.rb:9:9:18:3 | block scope | -| scopes.rb:10:9:10:9 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:40:1 | top-level scope for scopes.rb | -| scopes.rb:11:4:11:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:40:1 | top-level scope for scopes.rb | -| scopes.rb:12:9:12:9 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:40:1 | top-level scope for scopes.rb | -| scopes.rb:13:4:13:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:40:1 | top-level scope for scopes.rb | -| scopes.rb:13:7:13:7 | b | scopes.rb:13:7:13:7 | b | scopes.rb:9:9:18:3 | block scope | -| scopes.rb:13:11:13:11 | c | scopes.rb:13:11:13:11 | c | scopes.rb:9:9:18:3 | block scope | -| scopes.rb:13:14:13:14 | d | scopes.rb:13:14:13:14 | d | scopes.rb:9:9:18:3 | block scope | -| scopes.rb:14:9:14:9 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:40:1 | top-level scope for scopes.rb | -| 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 | -| scopes.rb:21:1:21:7 | $global | file://:0:0:0:0 | $global | file://:0:0:0:0 | global scope | -| scopes.rb:24:1:24:6 | script | scopes.rb:24:1:24:6 | script | scopes.rb:1:1:40:1 | top-level scope for scopes.rb | -| scopes.rb:24:10:24:11 | $0 | file://:0:0:0:0 | $0 | file://:0:0:0:0 | global scope | -| scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | scopes.rb:1:1:40:1 | top-level scope for scopes.rb | -| scopes.rb:28:8:28:8 | x | scopes.rb:27:1:27:1 | x | scopes.rb:1:1:40:1 | top-level scope for scopes.rb | -| scopes.rb:29:3:29:3 | x | scopes.rb:29:3:29:3 | x | scopes.rb:28:1:30:3 | module scope for B | -| scopes.rb:31:10:31:10 | x | scopes.rb:27:1:27:1 | x | scopes.rb:1:1:40:1 | top-level scope for scopes.rb | -| scopes.rb:32:3:32:3 | x | scopes.rb:32:3:32:3 | x | scopes.rb:31:1:33:3 | class scope | -| scopes.rb:34:7:34:7 | x | scopes.rb:27:1:27:1 | x | scopes.rb:1:1:40:1 | top-level scope for scopes.rb | -| scopes.rb:34:14:34:14 | x | scopes.rb:27:1:27:1 | x | scopes.rb:1:1:40:1 | top-level scope for scopes.rb | -| scopes.rb:35:3:35:3 | x | scopes.rb:35:3:35:3 | x | scopes.rb:34:1:36:3 | class scope for C | -| scopes.rb:37:5:37:5 | x | scopes.rb:27:1:27:1 | x | scopes.rb:1:1:40:1 | top-level scope for scopes.rb | -| scopes.rb:38:3:38:3 | x | scopes.rb:38:3:38:3 | x | scopes.rb:37:1:39:3 | method scope for foo | -| ssa.rb:1:7:1:7 | b | ssa.rb:1:7:1:7 | b | ssa.rb:1:1:16:3 | method scope for m | -| ssa.rb:2:3:2:3 | i | ssa.rb:2:3:2:3 | i | ssa.rb:1:1:16:3 | method scope for m | -| ssa.rb:3:8:3:8 | i | ssa.rb:2:3:2:3 | i | ssa.rb:1:1:16:3 | method scope for m | -| ssa.rb:4:8:4:8 | i | ssa.rb:2:3:2:3 | i | ssa.rb:1:1:16:3 | method scope for m | -| ssa.rb:5:6:5:6 | b | ssa.rb:1:7:1:7 | b | ssa.rb:1:1:16:3 | method scope for m | -| ssa.rb:6:5:6:5 | i | ssa.rb:2:3:2:3 | i | ssa.rb:1:1:16:3 | method scope for m | -| ssa.rb:7:10:7:10 | i | ssa.rb:2:3:2:3 | i | ssa.rb:1:1:16:3 | method scope for m | -| ssa.rb:8:10:8:10 | i | ssa.rb:2:3:2:3 | i | ssa.rb:1:1:16:3 | method scope for m | -| ssa.rb:10:5:10:5 | i | ssa.rb:2:3:2:3 | i | ssa.rb:1:1:16:3 | method scope for m | -| ssa.rb:11:10:11:10 | i | ssa.rb:2:3:2:3 | i | ssa.rb:1:1:16:3 | method scope for m | -| ssa.rb:12:10:12:10 | i | ssa.rb:2:3:2:3 | i | ssa.rb:1:1:16:3 | method scope for m | -| ssa.rb:15:8:15:8 | i | ssa.rb:2:3:2:3 | i | ssa.rb:1:1:16:3 | method scope for m | -| ssa.rb:18:8:18:8 | x | ssa.rb:18:8:18:8 | x | ssa.rb:18:1:23:3 | method scope for m1 | -| ssa.rb:19:9:19:9 | x | ssa.rb:18:8:18:8 | x | ssa.rb:18:1:23:3 | method scope for m1 | -| ssa.rb:20:10:20:10 | x | ssa.rb:18:8:18:8 | x | ssa.rb:18:1:23:3 | method scope for m1 | -| ssa.rb:21:5:21:5 | x | ssa.rb:18:8:18:8 | x | ssa.rb:18:1:23:3 | method scope for m1 | -| ssa.rb:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements | ssa.rb:25:1:30:3 | method scope for m2 | -| ssa.rb:26:7:26:10 | elem | ssa.rb:26:7:26:10 | elem | ssa.rb:25:1:30:3 | method scope for m2 | -| ssa.rb:26:15:26:22 | elements | ssa.rb:25:8:25:15 | elements | ssa.rb:25:1:30:3 | method scope for m2 | -| ssa.rb:27:10:27:13 | elem | ssa.rb:26:7:26:10 | elem | ssa.rb:25:1:30:3 | method scope for m2 | -| ssa.rb:29:8:29:11 | elem | ssa.rb:26:7:26:10 | elem | ssa.rb:25:1:30:3 | method scope for m2 | -| ssa.rb:33:20:33:20 | x | ssa.rb:33:20:33:20 | x | ssa.rb:33:16:35:5 | block scope | -| ssa.rb:34:10:34:10 | x | ssa.rb:33:20:33:20 | x | ssa.rb:33:16:35:5 | block scope | -| ssa.rb:40:3:40:4 | m3 | ssa.rb:40:3:40:4 | m3 | ssa.rb:38:1:42:3 | method scope for m4 | -| ssa.rb:41:8:41:9 | m3 | ssa.rb:40:3:40:4 | m3 | ssa.rb:38:1:42:3 | method scope for m4 | -| ssa.rb:44:8:44:8 | b | ssa.rb:44:8:44:8 | b | ssa.rb:44:1:47:3 | method scope for m5 | -| ssa.rb:45:3:45:3 | x | ssa.rb:45:3:45:3 | x | ssa.rb:44:1:47:3 | method scope for m5 | -| ssa.rb:45:12:45:12 | b | ssa.rb:44:8:44:8 | b | ssa.rb:44:1:47:3 | method scope for m5 | -| ssa.rb:46:8:46:8 | x | ssa.rb:45:3:45:3 | x | ssa.rb:44:1:47:3 | method scope for m5 | -| ssa.rb:49:9:49:9 | x | ssa.rb:49:9:49:9 | x | ssa.rb:49:1:51:3 | method scope for m6 | -| ssa.rb:49:14:49:14 | y | ssa.rb:49:14:49:14 | y | ssa.rb:49:1:51:3 | method scope for m6 | -| ssa.rb:50:8:50:8 | y | ssa.rb:49:14:49:14 | y | ssa.rb:49:1:51:3 | method scope for m6 | -| ssa.rb:53:8:53:10 | foo | ssa.rb:53:8:53:10 | foo | ssa.rb:53:1:56:3 | method scope for m7 | -| ssa.rb:54:3:54:3 | x | ssa.rb:54:3:54:3 | x | ssa.rb:53:1:56:3 | method scope for m7 | -| ssa.rb:54:7:54:9 | foo | ssa.rb:53:8:53:10 | foo | ssa.rb:53:1:56:3 | method scope for m7 | -| ssa.rb:55:8:55:8 | x | ssa.rb:54:3:54:3 | x | ssa.rb:53:1:56:3 | method scope for m7 | -| ssa.rb:59:3:59:3 | x | ssa.rb:59:3:59:3 | x | ssa.rb:58:1:62:3 | method scope for m8 | -| ssa.rb:60:3:60:3 | x | ssa.rb:59:3:59:3 | x | ssa.rb:58:1:62:3 | method scope for m8 | -| ssa.rb:61:8:61:8 | x | ssa.rb:59:3:59:3 | x | ssa.rb:58:1:62:3 | method scope for m8 | -| ssa.rb:64:8:64:8 | a | ssa.rb:64:8:64:8 | a | ssa.rb:64:1:72:3 | method scope for m9 | -| ssa.rb:65:3:65:10 | captured | ssa.rb:65:3:65:10 | captured | ssa.rb:64:1:72:3 | method scope for m9 | -| ssa.rb:66:3:66:3 | a | ssa.rb:64:8:64:8 | a | ssa.rb:64:1:72:3 | method scope for m9 | -| ssa.rb:66:15:66:15 | a | ssa.rb:66:15:66:15 | a | ssa.rb:66:11:70:5 | block scope | -| ssa.rb:67:10:67:10 | a | ssa.rb:66:15:66:15 | a | ssa.rb:66:11:70:5 | block scope | -| ssa.rb:68:10:68:17 | captured | ssa.rb:65:3:65:10 | captured | ssa.rb:64:1:72:3 | method scope for m9 | -| ssa.rb:69:5:69:12 | captured | ssa.rb:65:3:65:10 | captured | ssa.rb:64:1:72:3 | method scope for m9 | -| ssa.rb:71:8:71:15 | captured | ssa.rb:65:3:65:10 | captured | ssa.rb:64:1:72:3 | method scope for m9 | -| ssa.rb:75:3:75:10 | captured | ssa.rb:75:3:75:10 | captured | ssa.rb:74:1:79:3 | method scope for m10 | -| ssa.rb:77:15:77:22 | captured | ssa.rb:75:3:75:10 | captured | ssa.rb:74:1:79:3 | method scope for m10 | -| ssa.rb:82:3:82:10 | captured | ssa.rb:82:3:82:10 | captured | ssa.rb:81:1:88:3 | method scope for m11 | -| ssa.rb:85:15:85:22 | captured | ssa.rb:82:3:82:10 | captured | ssa.rb:81:1:88:3 | method scope for m11 | +| class_variables.rb:1:1:1:3 | @@x | class_variables.rb:1:1:1:3 | @@x | class_variables.rb:1:1:29:4 | class_variables.rb | +| class_variables.rb:3:3:3:5 | @@x | class_variables.rb:1:1:1:3 | @@x | class_variables.rb:1:1:29:4 | class_variables.rb | +| class_variables.rb:6:4:6:6 | @@x | class_variables.rb:1:1:1:3 | @@x | class_variables.rb:1:1:29:4 | class_variables.rb | +| class_variables.rb:11:7:11:9 | @@x | class_variables.rb:11:7:11:9 | @@x | class_variables.rb:9:1:16:3 | X | +| class_variables.rb:14:6:14:8 | @@x | class_variables.rb:11:7:11:9 | @@x | class_variables.rb:9:1:16:3 | X | +| class_variables.rb:19:3:19:5 | @@x | class_variables.rb:19:3:19:5 | @@x | class_variables.rb:18:1:20:3 | Y | +| class_variables.rb:23:3:23:5 | @@x | class_variables.rb:23:3:23:5 | @@x | class_variables.rb:22:1:24:3 | M | +| class_variables.rb:28:5:28:7 | @@x | class_variables.rb:28:5:28:7 | @@x | class_variables.rb:26:1:29:3 | N | +| instance_variables.rb:1:1:1:4 | @top | instance_variables.rb:1:1:1:4 | @top | instance_variables.rb:1:1:44:4 | instance_variables.rb | +| instance_variables.rb:4:3:4:6 | @foo | instance_variables.rb:4:3:4:6 | @foo | instance_variables.rb:1:1:44:4 | instance_variables.rb | +| instance_variables.rb:8:8:8:11 | @foo | instance_variables.rb:4:3:4:6 | @foo | instance_variables.rb:1:1:44:4 | instance_variables.rb | +| instance_variables.rb:11:6:11:9 | @top | instance_variables.rb:1:1:1:4 | @top | instance_variables.rb:1:1:44:4 | instance_variables.rb | +| instance_variables.rb:14:3:14:4 | @x | instance_variables.rb:14:3:14:4 | @x | instance_variables.rb:13:1:18:3 | X | +| instance_variables.rb:16:5:16:6 | @y | instance_variables.rb:16:5:16:6 | @y | instance_variables.rb:13:1:18:3 | X | +| instance_variables.rb:21:2:21:3 | @m | instance_variables.rb:21:2:21:3 | @m | instance_variables.rb:20:1:25:3 | M | +| instance_variables.rb:23:4:23:5 | @n | instance_variables.rb:23:4:23:5 | @n | instance_variables.rb:20:1:25:3 | M | +| instance_variables.rb:28:3:28:4 | @x | instance_variables.rb:28:3:28:4 | @x | instance_variables.rb:1:1:44:4 | instance_variables.rb | +| instance_variables.rb:32:12:32:13 | @x | instance_variables.rb:32:12:32:13 | @x | instance_variables.rb:1:1:44:4 | instance_variables.rb | +| instance_variables.rb:36:3:36:4 | @x | instance_variables.rb:36:3:36:4 | @x | instance_variables.rb:35:1:44:4 | C | +| instance_variables.rb:39:6:39:7 | @x | instance_variables.rb:39:6:39:7 | @x | instance_variables.rb:35:1:44:4 | C | +| instance_variables.rb:42:6:42:7 | @x | instance_variables.rb:39:6:39:7 | @x | instance_variables.rb:35:1:44:4 | C | +| nested_scopes.rb:5:3:5:3 | a | nested_scopes.rb:5:3:5:3 | a | nested_scopes.rb:4:1:39:3 | C | +| nested_scopes.rb:7:5:7:5 | a | nested_scopes.rb:7:5:7:5 | a | nested_scopes.rb:6:3:37:5 | M | +| nested_scopes.rb:9:7:9:7 | a | nested_scopes.rb:9:7:9:7 | a | nested_scopes.rb:8:5:35:7 | N | +| nested_scopes.rb:11:9:11:9 | a | nested_scopes.rb:11:9:11:9 | a | nested_scopes.rb:10:7:26:9 | D | +| nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:12:9:21:11 | show_a | +| nested_scopes.rb:14:16:14:16 | a | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:12:9:21:11 | show_a | +| nested_scopes.rb:15:11:15:11 | a | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:12:9:21:11 | show_a | +| nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:15:19:20:13 | do ... end | +| nested_scopes.rb:16:13:16:13 | a | nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:15:19:20:13 | do ... end | +| nested_scopes.rb:16:26:16:26 | x | nested_scopes.rb:16:26:16:26 | x | nested_scopes.rb:16:21:19:15 | do ... end | +| nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:16:21:19:15 | do ... end | +| nested_scopes.rb:17:15:17:15 | a | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:16:21:19:15 | do ... end | +| nested_scopes.rb:18:15:18:15 | a | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:16:21:19:15 | do ... end | +| nested_scopes.rb:18:26:18:26 | x | nested_scopes.rb:18:26:18:26 | x | nested_scopes.rb:18:23:18:36 | { ... } | +| nested_scopes.rb:18:34:18:34 | a | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:16:21:19:15 | do ... end | +| nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:22:9:24:11 | show_a2 | +| nested_scopes.rb:23:16:23:16 | a | nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:22:9:24:11 | show_a2 | +| nested_scopes.rb:25:14:25:14 | a | nested_scopes.rb:11:9:11:9 | a | nested_scopes.rb:10:7:26:9 | D | +| nested_scopes.rb:31:11:31:11 | a | nested_scopes.rb:31:11:31:11 | a | nested_scopes.rb:30:7:33:9 | class << ... | +| nested_scopes.rb:32:16:32:16 | a | nested_scopes.rb:31:11:31:11 | a | nested_scopes.rb:30:7:33:9 | class << ... | +| nested_scopes.rb:34:12:34:12 | a | nested_scopes.rb:9:7:9:7 | a | nested_scopes.rb:8:5:35:7 | N | +| nested_scopes.rb:36:10:36:10 | a | nested_scopes.rb:7:5:7:5 | a | nested_scopes.rb:6:3:37:5 | M | +| nested_scopes.rb:38:8:38:8 | a | nested_scopes.rb:5:3:5:3 | a | nested_scopes.rb:4:1:39:3 | C | +| nested_scopes.rb:40:1:40:1 | d | nested_scopes.rb:40:1:40:1 | d | nested_scopes.rb:1:1:42:1 | nested_scopes.rb | +| nested_scopes.rb:41:1:41:1 | d | nested_scopes.rb:40:1:40:1 | d | nested_scopes.rb:1:1:42:1 | nested_scopes.rb | +| parameters.rb:1:14:1:14 | x | parameters.rb:1:14:1:14 | x | parameters.rb:1:9:5:3 | do ... end | +| parameters.rb:1:18:1:18 | y | parameters.rb:1:18:1:18 | y | parameters.rb:1:9:5:3 | do ... end | +| parameters.rb:2:4:2:4 | y | parameters.rb:1:18:1:18 | y | parameters.rb:1:9:5:3 | do ... end | +| parameters.rb:3:9:3:9 | x | parameters.rb:1:14:1:14 | x | parameters.rb:1:9:5:3 | do ... end | +| parameters.rb:4:9:4:9 | y | parameters.rb:1:18:1:18 | y | parameters.rb:1:9:5:3 | do ... end | +| parameters.rb:7:17:7:22 | client | parameters.rb:7:17:7:22 | client | parameters.rb:7:1:13:3 | order_pizza | +| parameters.rb:7:25:7:31 | *pizzas | parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:1:13:3 | order_pizza | +| parameters.rb:8:6:8:11 | pizzas | parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:1:13:3 | order_pizza | +| parameters.rb:9:25:9:30 | client | parameters.rb:7:17:7:22 | client | parameters.rb:7:1:13:3 | order_pizza | +| parameters.rb:11:14:11:19 | pizzas | parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:1:13:3 | order_pizza | +| parameters.rb:11:41:11:46 | client | parameters.rb:7:17:7:22 | client | parameters.rb:7:1:13:3 | order_pizza | +| parameters.rb:15:15:15:19 | **map | parameters.rb:15:17:15:19 | map | parameters.rb:15:1:19:3 | print_map | +| parameters.rb:16:3:16:5 | map | parameters.rb:15:17:15:19 | map | parameters.rb:15:1:19:3 | print_map | +| parameters.rb:16:16:16:18 | key | parameters.rb:16:16:16:18 | key | parameters.rb:16:12:18:5 | do ... end | +| parameters.rb:16:21:16:25 | value | parameters.rb:16:21:16:25 | value | parameters.rb:16:12:18:5 | do ... end | +| parameters.rb:17:13:17:15 | key | parameters.rb:16:16:16:18 | key | parameters.rb:16:12:18:5 | do ... end | +| parameters.rb:17:22:17:26 | value | parameters.rb:16:21:16:25 | value | parameters.rb:16:12:18:5 | do ... end | +| parameters.rb:21:16:21:21 | &block | parameters.rb:21:17:21:21 | block | parameters.rb:21:1:23:3 | call_block | +| parameters.rb:22:3:22:7 | block | parameters.rb:21:17:21:21 | block | parameters.rb:21:1:23:3 | call_block | +| parameters.rb:25:15:25:18 | name | parameters.rb:25:15:25:18 | name | parameters.rb:25:1:28:3 | opt_param | +| parameters.rb:25:33:25:36 | size | parameters.rb:25:33:25:36 | size | parameters.rb:25:1:28:3 | opt_param | +| parameters.rb:25:40:25:43 | name | parameters.rb:25:15:25:18 | name | parameters.rb:25:1:28:3 | opt_param | +| parameters.rb:26:8:26:11 | name | parameters.rb:25:15:25:18 | name | parameters.rb:25:1:28:3 | opt_param | +| parameters.rb:27:8:27:11 | size | parameters.rb:25:33:25:36 | size | parameters.rb:25:1:28:3 | opt_param | +| parameters.rb:30:15:30:19 | first | parameters.rb:30:15:30:19 | first | parameters.rb:30:1:32:3 | key_param | +| parameters.rb:30:24:30:29 | middle | parameters.rb:30:24:30:29 | middle | parameters.rb:30:1:32:3 | key_param | +| parameters.rb:30:36:30:39 | last | parameters.rb:30:36:30:39 | last | parameters.rb:30:1:32:3 | key_param | +| parameters.rb:31:11:31:15 | first | parameters.rb:30:15:30:19 | first | parameters.rb:30:1:32:3 | key_param | +| parameters.rb:31:20:31:25 | middle | parameters.rb:30:24:30:29 | middle | parameters.rb:30:1:32:3 | key_param | +| parameters.rb:31:30:31:33 | last | parameters.rb:30:36:30:39 | last | parameters.rb:30:1:32:3 | key_param | +| parameters.rb:34:1:34:1 | b | parameters.rb:34:1:34:1 | b | parameters.rb:1:1:58:1 | parameters.rb | +| parameters.rb:35:11:35:11 | a | parameters.rb:35:11:35:11 | a | parameters.rb:35:1:38:3 | multi | +| parameters.rb:35:16:35:16 | b | parameters.rb:35:16:35:16 | b | parameters.rb:35:1:38:3 | multi | +| parameters.rb:37:11:37:11 | a | parameters.rb:35:11:35:11 | a | parameters.rb:35:1:38:3 | multi | +| parameters.rb:37:16:37:16 | b | parameters.rb:35:16:35:16 | b | parameters.rb:35:1:38:3 | multi | +| parameters.rb:40:12:40:12 | d | parameters.rb:40:12:40:12 | d | parameters.rb:40:1:43:3 | multi2 | +| parameters.rb:40:15:40:15 | e | parameters.rb:40:15:40:15 | e | parameters.rb:40:1:43:3 | multi2 | +| parameters.rb:42:11:42:11 | d | parameters.rb:40:12:40:12 | d | parameters.rb:40:1:43:3 | multi2 | +| parameters.rb:42:16:42:16 | e | parameters.rb:40:15:40:15 | e | parameters.rb:40:1:43:3 | multi2 | +| parameters.rb:45:20:45:20 | _ | parameters.rb:45:20:45:20 | _ | parameters.rb:45:1:47:3 | dup_underscore | +| parameters.rb:46:8:46:8 | _ | parameters.rb:45:20:45:20 | _ | parameters.rb:45:1:47:3 | dup_underscore | +| parameters.rb:49:13:49:13 | a | parameters.rb:49:13:49:13 | a | parameters.rb:49:1:51:3 | tuples | +| parameters.rb:49:15:49:15 | b | parameters.rb:49:15:49:15 | b | parameters.rb:49:1:51:3 | tuples | +| parameters.rb:50:11:50:11 | a | parameters.rb:49:13:49:13 | a | parameters.rb:49:1:51:3 | tuples | +| parameters.rb:50:16:50:16 | b | parameters.rb:49:15:49:15 | b | parameters.rb:49:1:51:3 | tuples | +| parameters.rb:53:1:53:1 | x | parameters.rb:53:1:53:1 | x | parameters.rb:1:1:58:1 | parameters.rb | +| parameters.rb:54:14:54:14 | y | parameters.rb:54:14:54:14 | y | parameters.rb:54:9:57:3 | do ... end | +| parameters.rb:54:19:54:19 | x | parameters.rb:53:1:53:1 | x | parameters.rb:1:1:58:1 | parameters.rb | +| parameters.rb:55:9:55:9 | x | parameters.rb:53:1:53:1 | x | parameters.rb:1:1:58:1 | parameters.rb | +| parameters.rb:56:9:56:9 | y | parameters.rb:54:14:54:14 | y | parameters.rb:54:9:57:3 | do ... end | +| scopes.rb:2:14:2:14 | x | scopes.rb:2:14:2:14 | x | scopes.rb:2:9:6:3 | do ... end | +| scopes.rb:4:4:4:4 | a | scopes.rb:4:4:4:4 | a | scopes.rb:2:9:6:3 | do ... end | +| scopes.rb:5:9:5:9 | a | scopes.rb:4:4:4:4 | a | scopes.rb:2:9:6:3 | do ... end | +| scopes.rb:7:1:7:1 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:40:1 | scopes.rb | +| scopes.rb:8:6:8:6 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:40:1 | scopes.rb | +| scopes.rb:9:14:9:14 | x | scopes.rb:9:14:9:14 | x | scopes.rb:9:9:18:3 | do ... end | +| scopes.rb:10:9:10:9 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:40:1 | scopes.rb | +| scopes.rb:11:4:11:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:40:1 | scopes.rb | +| scopes.rb:12:9:12:9 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:40:1 | scopes.rb | +| scopes.rb:13:4:13:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:40:1 | scopes.rb | +| scopes.rb:13:7:13:7 | b | scopes.rb:13:7:13:7 | b | scopes.rb:9:9:18:3 | do ... end | +| scopes.rb:13:11:13:11 | c | scopes.rb:13:11:13:11 | c | scopes.rb:9:9:18:3 | do ... end | +| scopes.rb:13:14:13:14 | d | scopes.rb:13:14:13:14 | d | scopes.rb:9:9:18:3 | do ... end | +| scopes.rb:14:9:14:9 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:40:1 | scopes.rb | +| scopes.rb:15:9:15:9 | b | scopes.rb:13:7:13:7 | b | scopes.rb:9:9:18:3 | do ... end | +| scopes.rb:16:9:16:9 | c | scopes.rb:13:11:13:11 | c | scopes.rb:9:9:18:3 | do ... end | +| scopes.rb:17:9:17:9 | d | scopes.rb:13:14:13:14 | d | scopes.rb:9:9:18:3 | do ... end | +| scopes.rb:24:1:24:6 | script | scopes.rb:24:1:24:6 | script | scopes.rb:1:1:40:1 | scopes.rb | +| scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | scopes.rb:1:1:40:1 | scopes.rb | +| scopes.rb:28:8:28:8 | x | scopes.rb:27:1:27:1 | x | scopes.rb:1:1:40:1 | scopes.rb | +| scopes.rb:29:3:29:3 | x | scopes.rb:29:3:29:3 | x | scopes.rb:28:1:30:3 | B | +| scopes.rb:31:10:31:10 | x | scopes.rb:27:1:27:1 | x | scopes.rb:1:1:40:1 | scopes.rb | +| scopes.rb:32:3:32:3 | x | scopes.rb:32:3:32:3 | x | scopes.rb:31:1:33:3 | class << ... | +| scopes.rb:34:7:34:7 | x | scopes.rb:27:1:27:1 | x | scopes.rb:1:1:40:1 | scopes.rb | +| scopes.rb:34:14:34:14 | x | scopes.rb:27:1:27:1 | x | scopes.rb:1:1:40:1 | scopes.rb | +| scopes.rb:35:3:35:3 | x | scopes.rb:35:3:35:3 | x | scopes.rb:34:1:36:3 | C | +| scopes.rb:37:5:37:5 | x | scopes.rb:27:1:27:1 | x | scopes.rb:1:1:40:1 | scopes.rb | +| scopes.rb:38:3:38:3 | x | scopes.rb:38:3:38:3 | x | scopes.rb:37:1:39:3 | foo | +| ssa.rb:1:7:1:7 | b | ssa.rb:1:7:1:7 | b | ssa.rb:1:1:16:3 | m | +| ssa.rb:2:3:2:3 | i | ssa.rb:2:3:2:3 | i | ssa.rb:1:1:16:3 | m | +| ssa.rb:3:8:3:8 | i | ssa.rb:2:3:2:3 | i | ssa.rb:1:1:16:3 | m | +| ssa.rb:4:8:4:8 | i | ssa.rb:2:3:2:3 | i | ssa.rb:1:1:16:3 | m | +| ssa.rb:5:6:5:6 | b | ssa.rb:1:7:1:7 | b | ssa.rb:1:1:16:3 | m | +| ssa.rb:6:5:6:5 | i | ssa.rb:2:3:2:3 | i | ssa.rb:1:1:16:3 | m | +| ssa.rb:7:10:7:10 | i | ssa.rb:2:3:2:3 | i | ssa.rb:1:1:16:3 | m | +| ssa.rb:8:10:8:10 | i | ssa.rb:2:3:2:3 | i | ssa.rb:1:1:16:3 | m | +| ssa.rb:10:5:10:5 | i | ssa.rb:2:3:2:3 | i | ssa.rb:1:1:16:3 | m | +| ssa.rb:11:10:11:10 | i | ssa.rb:2:3:2:3 | i | ssa.rb:1:1:16:3 | m | +| ssa.rb:12:10:12:10 | i | ssa.rb:2:3:2:3 | i | ssa.rb:1:1:16:3 | m | +| ssa.rb:15:8:15:8 | i | ssa.rb:2:3:2:3 | i | ssa.rb:1:1:16:3 | m | +| ssa.rb:18:8:18:8 | x | ssa.rb:18:8:18:8 | x | ssa.rb:18:1:23:3 | m1 | +| ssa.rb:19:9:19:9 | x | ssa.rb:18:8:18:8 | x | ssa.rb:18:1:23:3 | m1 | +| ssa.rb:20:10:20:10 | x | ssa.rb:18:8:18:8 | x | ssa.rb:18:1:23:3 | m1 | +| ssa.rb:21:5:21:5 | x | ssa.rb:18:8:18:8 | x | ssa.rb:18:1:23:3 | m1 | +| ssa.rb:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements | ssa.rb:25:1:30:3 | m2 | +| ssa.rb:26:7:26:10 | elem | ssa.rb:26:7:26:10 | elem | ssa.rb:25:1:30:3 | m2 | +| ssa.rb:26:15:26:22 | elements | ssa.rb:25:8:25:15 | elements | ssa.rb:25:1:30:3 | m2 | +| ssa.rb:27:10:27:13 | elem | ssa.rb:26:7:26:10 | elem | ssa.rb:25:1:30:3 | m2 | +| ssa.rb:29:8:29:11 | elem | ssa.rb:26:7:26:10 | elem | ssa.rb:25:1:30:3 | m2 | +| ssa.rb:33:20:33:20 | x | ssa.rb:33:20:33:20 | x | ssa.rb:33:16:35:5 | do ... end | +| ssa.rb:34:10:34:10 | x | ssa.rb:33:20:33:20 | x | ssa.rb:33:16:35:5 | do ... end | +| ssa.rb:40:3:40:4 | m3 | ssa.rb:40:3:40:4 | m3 | ssa.rb:38:1:42:3 | m4 | +| ssa.rb:41:8:41:9 | m3 | ssa.rb:40:3:40:4 | m3 | ssa.rb:38:1:42:3 | m4 | +| ssa.rb:44:8:44:8 | b | ssa.rb:44:8:44:8 | b | ssa.rb:44:1:47:3 | m5 | +| ssa.rb:45:3:45:3 | x | ssa.rb:45:3:45:3 | x | ssa.rb:44:1:47:3 | m5 | +| ssa.rb:45:12:45:12 | b | ssa.rb:44:8:44:8 | b | ssa.rb:44:1:47:3 | m5 | +| ssa.rb:46:8:46:8 | x | ssa.rb:45:3:45:3 | x | ssa.rb:44:1:47:3 | m5 | +| ssa.rb:49:9:49:9 | x | ssa.rb:49:9:49:9 | x | ssa.rb:49:1:51:3 | m6 | +| ssa.rb:49:14:49:14 | y | ssa.rb:49:14:49:14 | y | ssa.rb:49:1:51:3 | m6 | +| ssa.rb:50:8:50:8 | y | ssa.rb:49:14:49:14 | y | ssa.rb:49:1:51:3 | m6 | +| ssa.rb:53:8:53:10 | foo | ssa.rb:53:8:53:10 | foo | ssa.rb:53:1:56:3 | m7 | +| ssa.rb:54:3:54:3 | x | ssa.rb:54:3:54:3 | x | ssa.rb:53:1:56:3 | m7 | +| ssa.rb:54:7:54:9 | foo | ssa.rb:53:8:53:10 | foo | ssa.rb:53:1:56:3 | m7 | +| ssa.rb:55:8:55:8 | x | ssa.rb:54:3:54:3 | x | ssa.rb:53:1:56:3 | m7 | +| ssa.rb:59:3:59:3 | x | ssa.rb:59:3:59:3 | x | ssa.rb:58:1:62:3 | m8 | +| ssa.rb:60:3:60:3 | x | ssa.rb:59:3:59:3 | x | ssa.rb:58:1:62:3 | m8 | +| ssa.rb:61:8:61:8 | x | ssa.rb:59:3:59:3 | x | ssa.rb:58:1:62:3 | m8 | +| ssa.rb:64:8:64:8 | a | ssa.rb:64:8:64:8 | a | ssa.rb:64:1:72:3 | m9 | +| ssa.rb:65:3:65:10 | captured | ssa.rb:65:3:65:10 | captured | ssa.rb:64:1:72:3 | m9 | +| ssa.rb:66:3:66:3 | a | ssa.rb:64:8:64:8 | a | ssa.rb:64:1:72:3 | m9 | +| ssa.rb:66:15:66:15 | a | ssa.rb:66:15:66:15 | a | ssa.rb:66:11:70:5 | do ... end | +| ssa.rb:67:10:67:10 | a | ssa.rb:66:15:66:15 | a | ssa.rb:66:11:70:5 | do ... end | +| ssa.rb:68:10:68:17 | captured | ssa.rb:65:3:65:10 | captured | ssa.rb:64:1:72:3 | m9 | +| ssa.rb:69:5:69:12 | captured | ssa.rb:65:3:65:10 | captured | ssa.rb:64:1:72:3 | m9 | +| ssa.rb:71:8:71:15 | captured | ssa.rb:65:3:65:10 | captured | ssa.rb:64:1:72:3 | m9 | +| ssa.rb:75:3:75:10 | captured | ssa.rb:75:3:75:10 | captured | ssa.rb:74:1:79:3 | m10 | +| ssa.rb:77:15:77:22 | captured | ssa.rb:75:3:75:10 | captured | ssa.rb:74:1:79:3 | m10 | +| ssa.rb:82:3:82:10 | captured | ssa.rb:82:3:82:10 | captured | ssa.rb:81:1:88:3 | m11 | +| ssa.rb:85:15:85:22 | captured | ssa.rb:82:3:82:10 | captured | ssa.rb:81:1:88:3 | m11 | explicitWrite | nested_scopes.rb:5:3:5:3 | a | nested_scopes.rb:5:3:5:7 | ... = ... | | nested_scopes.rb:7:5:7:5 | a | nested_scopes.rb:7:5:7:9 | ... = ... | diff --git a/ql/test/library-tests/variables/varaccess.ql b/ql/test/library-tests/variables/varaccess.ql index df7f516efb4..fff11bb421f 100644 --- a/ql/test/library-tests/variables/varaccess.ql +++ b/ql/test/library-tests/variables/varaccess.ql @@ -1,7 +1,7 @@ import codeql_ruby.AST import codeql_ruby.ast.Variable -query predicate variableAccess(VariableAccess access, Variable variable, VariableScope scope) { +query predicate variableAccess(VariableAccess access, Variable variable, Scope scope) { variable = access.getVariable() and scope = variable.getDeclaringScope() } diff --git a/ql/test/library-tests/variables/varscopes.expected b/ql/test/library-tests/variables/varscopes.expected index 401ce5a280d..9639caa4cb0 100644 --- a/ql/test/library-tests/variables/varscopes.expected +++ b/ql/test/library-tests/variables/varscopes.expected @@ -1,75 +1,74 @@ -| class_variables.rb:1:1:29:4 | top-level scope for class_variables.rb | -| class_variables.rb:5:1:7:3 | method scope for print | -| class_variables.rb:9:1:16:3 | class scope for X | -| class_variables.rb:10:3:12:5 | method scope for b | -| class_variables.rb:13:3:15:5 | method scope for s | -| class_variables.rb:18:1:20:3 | class scope for Y | -| class_variables.rb:22:1:24:3 | module scope for M | -| class_variables.rb:26:1:29:3 | module scope for N | -| file://:0:0:0:0 | global scope | -| instance_variables.rb:1:1:44:4 | top-level scope for instance_variables.rb | -| instance_variables.rb:3:1:5:3 | method scope for foo | -| instance_variables.rb:7:1:9:3 | method scope for print_foo | -| instance_variables.rb:13:1:18:3 | class scope for X | -| instance_variables.rb:15:3:17:5 | method scope for m | -| instance_variables.rb:20:1:25:3 | module scope for M | -| instance_variables.rb:22:2:24:4 | method scope for n | -| instance_variables.rb:27:6:29:1 | block scope | -| instance_variables.rb:31:1:33:3 | method scope for bar | -| instance_variables.rb:32:10:32:21 | block scope | -| instance_variables.rb:35:1:44:4 | class scope for C | -| instance_variables.rb:37:3:43:5 | method scope for x | -| instance_variables.rb:38:4:40:6 | method scope for y | -| nested_scopes.rb:1:1:3:3 | method scope for a | -| nested_scopes.rb:1:1:42:1 | top-level scope for nested_scopes.rb | -| nested_scopes.rb:4:1:39:3 | class scope for C | -| nested_scopes.rb:6:3:37:5 | module scope for M | -| nested_scopes.rb:8:5:35:7 | module scope for N | -| nested_scopes.rb:10:7:26:9 | class scope for D | -| nested_scopes.rb:12:9:21:11 | method scope for show_a | -| nested_scopes.rb:15:19:20:13 | block scope | -| nested_scopes.rb:16:21:19:15 | block scope | -| nested_scopes.rb:18:23:18:36 | block scope | -| nested_scopes.rb:22:9:24:11 | method scope for show_a2 | -| nested_scopes.rb:27:7:29:9 | method scope for show | -| nested_scopes.rb:30:7:33:9 | class scope | -| parameters.rb:1:1:58:1 | top-level scope for parameters.rb | -| parameters.rb:1:9:5:3 | block scope | -| parameters.rb:7:1:13:3 | method scope for order_pizza | -| parameters.rb:15:1:19:3 | method scope for print_map | -| parameters.rb:16:12:18:5 | block scope | -| parameters.rb:21:1:23:3 | method scope for call_block | -| parameters.rb:25:1:28:3 | method scope for opt_param | -| parameters.rb:30:1:32:3 | method scope for key_param | -| parameters.rb:35:1:38:3 | method scope for multi | -| parameters.rb:40:1:43:3 | method scope for multi2 | -| parameters.rb:45:1:47:3 | method scope for dup_underscore | -| parameters.rb:49:1:51:3 | method scope for tuples | -| parameters.rb:54:9:57:3 | block scope | -| scopes.rb:1:1:1:15 | method scope for a | -| scopes.rb:1:1:40:1 | top-level scope for scopes.rb | -| scopes.rb:2:9:6:3 | block scope | -| scopes.rb:9:9:18:3 | block scope | -| scopes.rb:26:1:26:12 | class scope for A | -| scopes.rb:28:1:30:3 | module scope for B | -| scopes.rb:31:1:33:3 | class scope | -| scopes.rb:34:1:36:3 | class scope for C | -| scopes.rb:37:1:39:3 | method scope for foo | -| ssa.rb:1:1:16:3 | method scope for m | -| ssa.rb:1:1:88:3 | top-level scope for ssa.rb | -| ssa.rb:18:1:23:3 | method scope for m1 | -| ssa.rb:25:1:30:3 | method scope for m2 | -| ssa.rb:32:1:36:3 | method scope for m3 | -| ssa.rb:33:16:35:5 | block scope | -| ssa.rb:38:1:42:3 | method scope for m4 | -| ssa.rb:44:1:47:3 | method scope for m5 | -| ssa.rb:49:1:51:3 | method scope for m6 | -| ssa.rb:53:1:56:3 | method scope for m7 | -| ssa.rb:58:1:62:3 | method scope for m8 | -| ssa.rb:64:1:72:3 | method scope for m9 | -| ssa.rb:66:11:70:5 | block scope | -| ssa.rb:74:1:79:3 | method scope for m10 | -| ssa.rb:76:7:78:5 | block scope | -| ssa.rb:81:1:88:3 | method scope for m11 | -| ssa.rb:83:7:87:5 | block scope | -| ssa.rb:84:10:86:8 | block scope | +| class_variables.rb:1:1:29:4 | class_variables.rb | +| class_variables.rb:5:1:7:3 | print | +| class_variables.rb:9:1:16:3 | X | +| class_variables.rb:10:3:12:5 | b | +| class_variables.rb:13:3:15:5 | s | +| class_variables.rb:18:1:20:3 | Y | +| class_variables.rb:22:1:24:3 | M | +| class_variables.rb:26:1:29:3 | N | +| instance_variables.rb:1:1:44:4 | instance_variables.rb | +| instance_variables.rb:3:1:5:3 | foo | +| instance_variables.rb:7:1:9:3 | print_foo | +| instance_variables.rb:13:1:18:3 | X | +| instance_variables.rb:15:3:17:5 | m | +| instance_variables.rb:20:1:25:3 | M | +| instance_variables.rb:22:2:24:4 | n | +| instance_variables.rb:27:6:29:1 | { ... } | +| instance_variables.rb:31:1:33:3 | bar | +| instance_variables.rb:32:10:32:21 | { ... } | +| instance_variables.rb:35:1:44:4 | C | +| instance_variables.rb:37:3:43:5 | x | +| instance_variables.rb:38:4:40:6 | y | +| nested_scopes.rb:1:1:3:3 | a | +| nested_scopes.rb:1:1:42:1 | nested_scopes.rb | +| nested_scopes.rb:4:1:39:3 | C | +| nested_scopes.rb:6:3:37:5 | M | +| nested_scopes.rb:8:5:35:7 | N | +| nested_scopes.rb:10:7:26:9 | D | +| nested_scopes.rb:12:9:21:11 | show_a | +| nested_scopes.rb:15:19:20:13 | do ... end | +| nested_scopes.rb:16:21:19:15 | do ... end | +| nested_scopes.rb:18:23:18:36 | { ... } | +| nested_scopes.rb:22:9:24:11 | show_a2 | +| nested_scopes.rb:27:7:29:9 | show | +| nested_scopes.rb:30:7:33:9 | class << ... | +| parameters.rb:1:1:58:1 | parameters.rb | +| parameters.rb:1:9:5:3 | do ... end | +| parameters.rb:7:1:13:3 | order_pizza | +| parameters.rb:15:1:19:3 | print_map | +| parameters.rb:16:12:18:5 | do ... end | +| parameters.rb:21:1:23:3 | call_block | +| parameters.rb:25:1:28:3 | opt_param | +| parameters.rb:30:1:32:3 | key_param | +| parameters.rb:35:1:38:3 | multi | +| parameters.rb:40:1:43:3 | multi2 | +| parameters.rb:45:1:47:3 | dup_underscore | +| parameters.rb:49:1:51:3 | tuples | +| parameters.rb:54:9:57:3 | do ... end | +| scopes.rb:1:1:1:15 | a | +| scopes.rb:1:1:40:1 | scopes.rb | +| scopes.rb:2:9:6:3 | do ... end | +| scopes.rb:9:9:18:3 | do ... end | +| scopes.rb:26:1:26:12 | A | +| scopes.rb:28:1:30:3 | B | +| scopes.rb:31:1:33:3 | class << ... | +| scopes.rb:34:1:36:3 | C | +| scopes.rb:37:1:39:3 | foo | +| ssa.rb:1:1:16:3 | m | +| ssa.rb:1:1:88:3 | ssa.rb | +| ssa.rb:18:1:23:3 | m1 | +| ssa.rb:25:1:30:3 | m2 | +| ssa.rb:32:1:36:3 | m3 | +| ssa.rb:33:16:35:5 | do ... end | +| ssa.rb:38:1:42:3 | m4 | +| ssa.rb:44:1:47:3 | m5 | +| ssa.rb:49:1:51:3 | m6 | +| ssa.rb:53:1:56:3 | m7 | +| ssa.rb:58:1:62:3 | m8 | +| ssa.rb:64:1:72:3 | m9 | +| ssa.rb:66:11:70:5 | do ... end | +| ssa.rb:74:1:79:3 | m10 | +| ssa.rb:76:7:78:5 | do ... end | +| ssa.rb:81:1:88:3 | m11 | +| ssa.rb:83:7:87:5 | do ... end | +| ssa.rb:84:10:86:8 | do ... end | diff --git a/ql/test/library-tests/variables/varscopes.ql b/ql/test/library-tests/variables/varscopes.ql index e0272ce17af..8a8af82355b 100644 --- a/ql/test/library-tests/variables/varscopes.ql +++ b/ql/test/library-tests/variables/varscopes.ql @@ -1,3 +1,3 @@ -import codeql_ruby.ast.Variable +import codeql_ruby.ast.Scope -select any(VariableScope x) +select any(Scope x)