Merge pull request #9206 from aibaars/instance-variable-flow

Ruby: flow through instance variables
This commit is contained in:
Arthur Baars
2022-05-24 14:02:33 +02:00
committed by GitHub
17 changed files with 388 additions and 15 deletions

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
Support for data flow through instance variables has been added.

View File

@@ -181,6 +181,17 @@ class GlobalVariableReadAccess extends GlobalVariableAccess, VariableReadAccess
/** An access to an instance variable. */
class InstanceVariableAccess extends VariableAccess instanceof InstanceVariableAccessImpl {
final override string getAPrimaryQlClass() { result = "InstanceVariableAccess" }
/**
* Gets the synthetic receiver (`self`) of this instance variable access.
*/
final SelfVariableAccess getReceiver() { synthChild(this, 0, result) }
final override AstNode getAChild(string pred) {
result = VariableAccess.super.getAChild(pred)
or
pred = "getReceiver" and result = this.getReceiver()
}
}
/** An access to an instance variable where the value is updated. */

View File

@@ -210,6 +210,38 @@ private module ImplicitSelfSynthesis {
regularMethodCallSelfSynthesis(parent, i, child)
}
}
pragma[nomagic]
private AstNode instanceVarAccessSynthParentStar(InstanceVariableAccess var) {
result = var
or
instanceVarAccessSynthParentStar(var) = getSynthChild(result, _)
}
/**
* Gets the `SelfKind` for instance variable access `var`. This is based on the
* "owner" of `var`; for real nodes this is the node itself, for synthetic nodes
* this is the closest parent that is a real node.
*/
pragma[nomagic]
private SelfKind getSelfKind(InstanceVariableAccess var) {
exists(Ruby::AstNode owner |
owner = toGenerated(instanceVarAccessSynthParentStar(var)) and
result = SelfKind(TSelfVariable(scopeOf(owner).getEnclosingSelfScope()))
)
}
pragma[nomagic]
private predicate instanceVariableSelfSynthesis(InstanceVariableAccess var, int i, Child child) {
child = SynthChild(getSelfKind(var)) and
i = 0
}
private class InstanceVariableSelfSynthesis extends Synthesis {
final override predicate child(AstNode parent, int i, Child child) {
instanceVariableSelfSynthesis(parent, i, child)
}
}
}
private module SetterDesugar {

View File

@@ -682,6 +682,24 @@ module ExprNodes {
final override VariableReadAccess getExpr() { result = ExprCfgNode.super.getExpr() }
}
private class InstanceVariableAccessMapping extends ExprChildMapping, InstanceVariableAccess {
override predicate relevantChild(AstNode n) { n = this.getReceiver() }
}
/** A control-flow node that wraps an `InstanceVariableAccess` AST expression. */
class InstanceVariableAccessCfgNode extends ExprCfgNode {
override string getAPrimaryQlClass() { result = "InstanceVariableAccessCfgNode" }
override InstanceVariableAccessMapping e;
override InstanceVariableAccess getExpr() { result = ExprCfgNode.super.getExpr() }
/**
* Gets the synthetic receiver (`self`) of this instance variable access.
*/
final CfgNode getReceiver() { e.hasCfgChild(e.getReceiver(), this, result) }
}
/** A control-flow node that wraps a `VariableWriteAccess` AST expression. */
class VariableWriteAccessCfgNode extends ExprCfgNode {
override string getAPrimaryQlClass() { result = "VariableWriteAccessCfgNode" }
@@ -709,13 +727,26 @@ module ExprNodes {
final override ConstantWriteAccess getExpr() { result = ExprCfgNode.super.getExpr() }
}
/** A control-flow node that wraps a `InstanceVariableWriteAccess` AST expression. */
class InstanceVariableWriteAccessCfgNode extends ExprCfgNode {
/** A control-flow node that wraps an `InstanceVariableReadAccess` AST expression. */
class InstanceVariableReadAccessCfgNode extends InstanceVariableAccessCfgNode {
InstanceVariableReadAccessCfgNode() { this.getNode() instanceof InstanceVariableReadAccess }
override string getAPrimaryQlClass() { result = "InstanceVariableReadAccessCfgNode" }
final override InstanceVariableReadAccess getExpr() {
result = InstanceVariableAccessCfgNode.super.getExpr()
}
}
/** A control-flow node that wraps an `InstanceVariableWriteAccess` AST expression. */
class InstanceVariableWriteAccessCfgNode extends InstanceVariableAccessCfgNode {
InstanceVariableWriteAccessCfgNode() { this.getNode() instanceof InstanceVariableWriteAccess }
override string getAPrimaryQlClass() { result = "InstanceVariableWriteAccessCfgNode" }
override InstanceVariableWriteAccess e;
final override InstanceVariableWriteAccess getExpr() { result = ExprCfgNode.super.getExpr() }
final override InstanceVariableWriteAccess getExpr() {
result = InstanceVariableAccessCfgNode.super.getExpr()
}
}
/** A control-flow node that wraps a `StringInterpolationComponent` AST expression. */

View File

@@ -1006,7 +1006,9 @@ module Trees {
final override ControlFlowTree getChildElement(int i) { result = this.getComponent(i) }
}
private class InstanceVariableTree extends LeafTree, InstanceVariableAccess { }
private class InstanceVariableTree extends StandardPostOrderTree, InstanceVariableAccess {
final override ControlFlowTree getChildElement(int i) { result = this.getReceiver() and i = 0 }
}
private class KeywordParameterTree extends DefaultValueParameterTree, KeywordParameter {
final override Expr getDefaultValueExpr() { result = this.getDefaultValue() }

View File

@@ -219,7 +219,10 @@ private module Cached {
} or
TSelfParameterNode(MethodBase m) or
TBlockParameterNode(MethodBase m) or
TExprPostUpdateNode(CfgNodes::ExprCfgNode n) { n instanceof Argument } or
TExprPostUpdateNode(CfgNodes::ExprCfgNode n) {
n instanceof Argument or
n = any(CfgNodes::ExprNodes::InstanceVariableAccessCfgNode v).getReceiver()
} or
TSummaryNode(
FlowSummaryImpl::Public::SummarizedCallable c,
FlowSummaryImpl::Private::SummaryNodeState state
@@ -339,6 +342,7 @@ private module Cached {
not cv.isInt(_) or
cv.getInt() in [0 .. 10]
} or
TFieldContent(string name) { name = any(InstanceVariable v).getName() } or
TUnknownElementContent()
/**
@@ -795,11 +799,40 @@ predicate jumpStep(Node pred, Node succ) {
succ.asExpr().getExpr().(ConstantReadAccess).getValue() = pred.asExpr().getExpr()
}
/**
* Holds if data can flow from `node1` to `node2` via an assignment to
* content `c`.
*/
predicate storeStep(Node node1, ContentSet c, Node node2) {
// Instance variable assignment, `@var = src`
node2.(PostUpdateNode).getPreUpdateNode().asExpr() =
any(CfgNodes::ExprNodes::InstanceVariableWriteAccessCfgNode var |
exists(CfgNodes::ExprNodes::AssignExprCfgNode assign |
var = assign.getLhs() and
node1.asExpr() = assign.getRhs()
|
c.isSingleton(any(Content::FieldContent ct |
ct.getName() = var.getExpr().getVariable().getName()
))
)
).getReceiver()
or
FlowSummaryImpl::Private::Steps::summaryStoreStep(node1, c, node2)
}
/**
* Holds if there is a read step of content `c` from `node1` to `node2`.
*/
predicate readStep(Node node1, ContentSet c, Node node2) {
// Instance variable read access, `@var`
node2.asExpr() =
any(CfgNodes::ExprNodes::InstanceVariableReadAccessCfgNode var |
node1.asExpr() = var.getReceiver() and
c.isSingleton(any(Content::FieldContent ct |
ct.getName() = var.getExpr().getVariable().getName()
))
)
or
FlowSummaryImpl::Private::Steps::summaryReadStep(node1, c, node2)
}

View File

@@ -223,6 +223,18 @@ module Content {
override string toString() { result = "element" }
}
/** A field of an object, for example an instance variable. */
class FieldContent extends Content, TFieldContent {
private string name;
FieldContent() { this = TFieldContent(name) }
/** Gets the name of the field. */
string getName() { result = name }
override string toString() { result = name }
}
/** Gets the element content corresponding to constant value `cv`. */
ElementContent getElementContent(ConstantValue cv) {
result = TKnownElementContent(cv)

View File

@@ -1234,6 +1234,7 @@ control/cases.rb:
# 150| getBranch: [InClause] in ... then ...
# 150| getPattern: [ReferencePattern] ^...
# 150| getExpr: [InstanceVariableAccess] @foo
# 150| getReceiver: [SelfVariableAccess] self
# 151| getBranch: [InClause] in ... then ...
# 151| getPattern: [ReferencePattern] ^...
# 151| getExpr: [ClassVariableAccess] @@foo
@@ -1246,6 +1247,7 @@ control/cases.rb:
# 156| getBranch: [InClause] in ... then ...
# 156| getPattern: [ReferencePattern] ^...
# 156| getExpr: [InstanceVariableAccess] @foo
# 156| getReceiver: [SelfVariableAccess] self
# 157| getBranch: [InClause] in ... then ...
# 157| getPattern: [ReferencePattern] ^...
# 157| getExpr: [AddExpr] ... + ...
@@ -2771,9 +2773,11 @@ operations/operations.rb:
# 87| getStmt: [ClassDeclaration] X
# 88| getStmt: [AssignExpr] ... = ...
# 88| getAnOperand/getLeftOperand: [InstanceVariableAccess] @x
# 88| getReceiver: [SelfVariableAccess] self
# 88| getAnOperand/getRightOperand: [IntegerLiteral] 1
# 89| getStmt: [AssignAddExpr] ... += ...
# 89| getAnOperand/getLeftOperand: [InstanceVariableAccess] @x
# 89| getReceiver: [SelfVariableAccess] self
# 89| getAnOperand/getRightOperand: [IntegerLiteral] 2
# 91| getStmt: [AssignExpr] ... = ...
# 91| getAnOperand/getLeftOperand: [ClassVariableAccess] @@y

View File

@@ -836,8 +836,10 @@ operations/operations.rb:
# 89| [AssignAddExpr] ... += ...
# 89| getDesugared: [AssignExpr] ... = ...
# 89| getAnOperand/getLeftOperand: [InstanceVariableAccess] @x
# 89| getReceiver: [SelfVariableAccess] self
# 89| getAnOperand/getRightOperand: [AddExpr] ... + ...
# 89| getAnOperand/getLeftOperand/getReceiver: [InstanceVariableAccess] @x
# 89| getReceiver: [SelfVariableAccess] self
# 89| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 2
# 92| [AssignDivExpr] ... /= ...
# 92| getDesugared: [AssignExpr] ... = ...

View File

@@ -1423,9 +1423,12 @@ cfg.html.erb:
# 5| @title
#-----| -> self
# 5| enter cfg.html.erb
# 5| self
#-----| -> @title
# 5| enter cfg.html.erb
#-----| -> self
# 5| exit cfg.html.erb
# 5| exit cfg.html.erb (normal)
@@ -2690,11 +2693,14 @@ cfg.rb:
#-----| -> ... > ...
# 115| C
#-----| -> @field
#-----| -> self
# 116| @field
#-----| -> 42
# 116| self
#-----| -> @field
# 116| ... = ...
#-----| -> @@static_field
@@ -4194,23 +4200,32 @@ desugar.rb:
#-----| -> call to []
# 29| X
#-----| -> @x
#-----| -> self
# 30| @x
#-----| -> 1
# 30| ... = ...
# 30| self
#-----| -> @x
# 30| ... = ...
#-----| -> self
# 30| 1
#-----| -> ... = ...
# 31| @x
#-----| -> @x
#-----| -> self
# 31| @x
#-----| -> 2
# 31| self
#-----| -> @x
# 31| self
#-----| -> @x
# 31| ... = ...
#-----| -> @@y

View File

@@ -0,0 +1,84 @@
failures
edges
| instance_variables.rb:2:19:2:19 | x : | instance_variables.rb:3:18:3:18 | x : |
| instance_variables.rb:2:19:2:19 | x : | instance_variables.rb:3:18:3:18 | x : |
| instance_variables.rb:3:18:3:18 | x : | instance_variables.rb:3:9:3:14 | [post] self [@field] : |
| instance_variables.rb:3:18:3:18 | x : | instance_variables.rb:3:9:3:14 | [post] self [@field] : |
| instance_variables.rb:5:5:7:7 | self in get_field [@field] : | instance_variables.rb:6:16:6:21 | self [@field] : |
| instance_variables.rb:5:5:7:7 | self in get_field [@field] : | instance_variables.rb:6:16:6:21 | self [@field] : |
| instance_variables.rb:6:16:6:21 | @field : | instance_variables.rb:6:9:6:21 | return : |
| instance_variables.rb:6:16:6:21 | @field : | instance_variables.rb:6:9:6:21 | return : |
| instance_variables.rb:6:16:6:21 | self [@field] : | instance_variables.rb:6:16:6:21 | @field : |
| instance_variables.rb:6:16:6:21 | self [@field] : | instance_variables.rb:6:16:6:21 | @field : |
| instance_variables.rb:8:5:10:7 | self in inc_field [@field] : | instance_variables.rb:9:9:9:14 | [post] self [@field] : |
| instance_variables.rb:9:9:9:14 | [post] self [@field] : | instance_variables.rb:9:9:9:14 | [post] self [@field] : |
| instance_variables.rb:11:5:11:8 | [post] self [@foo] : | instance_variables.rb:12:10:12:13 | self [@foo] : |
| instance_variables.rb:11:5:11:8 | [post] self [@foo] : | instance_variables.rb:12:10:12:13 | self [@foo] : |
| instance_variables.rb:11:12:11:22 | call to source : | instance_variables.rb:11:5:11:8 | [post] self [@foo] : |
| instance_variables.rb:11:12:11:22 | call to source : | instance_variables.rb:11:5:11:8 | [post] self [@foo] : |
| instance_variables.rb:12:10:12:13 | self [@foo] : | instance_variables.rb:12:10:12:13 | @foo |
| instance_variables.rb:12:10:12:13 | self [@foo] : | instance_variables.rb:12:10:12:13 | @foo |
| instance_variables.rb:16:1:16:3 | [post] foo [@field] : | instance_variables.rb:17:6:17:8 | foo [@field] : |
| instance_variables.rb:16:1:16:3 | [post] foo [@field] : | instance_variables.rb:17:6:17:8 | foo [@field] : |
| instance_variables.rb:16:15:16:24 | call to source : | instance_variables.rb:2:19:2:19 | x : |
| instance_variables.rb:16:15:16:24 | call to source : | instance_variables.rb:2:19:2:19 | x : |
| instance_variables.rb:16:15:16:24 | call to source : | instance_variables.rb:16:1:16:3 | [post] foo [@field] : |
| instance_variables.rb:16:15:16:24 | call to source : | instance_variables.rb:16:1:16:3 | [post] foo [@field] : |
| instance_variables.rb:17:6:17:8 | foo [@field] : | instance_variables.rb:5:5:7:7 | self in get_field [@field] : |
| instance_variables.rb:17:6:17:8 | foo [@field] : | instance_variables.rb:5:5:7:7 | self in get_field [@field] : |
| instance_variables.rb:17:6:17:8 | foo [@field] : | instance_variables.rb:17:6:17:18 | call to get_field |
| instance_variables.rb:17:6:17:8 | foo [@field] : | instance_variables.rb:17:6:17:18 | call to get_field |
| instance_variables.rb:20:1:20:3 | [post] bar [@field] : | instance_variables.rb:21:6:21:8 | bar [@field] : |
| instance_variables.rb:20:15:20:23 | call to source : | instance_variables.rb:2:19:2:19 | x : |
| instance_variables.rb:20:15:20:23 | call to source : | instance_variables.rb:20:1:20:3 | [post] bar [@field] : |
| instance_variables.rb:21:6:21:8 | bar [@field] : | instance_variables.rb:8:5:10:7 | self in inc_field [@field] : |
| instance_variables.rb:21:6:21:8 | bar [@field] : | instance_variables.rb:21:6:21:18 | call to inc_field |
nodes
| instance_variables.rb:2:19:2:19 | x : | semmle.label | x : |
| instance_variables.rb:2:19:2:19 | x : | semmle.label | x : |
| instance_variables.rb:3:9:3:14 | [post] self [@field] : | semmle.label | [post] self [@field] : |
| instance_variables.rb:3:9:3:14 | [post] self [@field] : | semmle.label | [post] self [@field] : |
| instance_variables.rb:3:18:3:18 | x : | semmle.label | x : |
| instance_variables.rb:3:18:3:18 | x : | semmle.label | x : |
| instance_variables.rb:5:5:7:7 | self in get_field [@field] : | semmle.label | self in get_field [@field] : |
| instance_variables.rb:5:5:7:7 | self in get_field [@field] : | semmle.label | self in get_field [@field] : |
| instance_variables.rb:6:9:6:21 | return : | semmle.label | return : |
| instance_variables.rb:6:9:6:21 | return : | semmle.label | return : |
| instance_variables.rb:6:16:6:21 | @field : | semmle.label | @field : |
| instance_variables.rb:6:16:6:21 | @field : | semmle.label | @field : |
| instance_variables.rb:6:16:6:21 | self [@field] : | semmle.label | self [@field] : |
| instance_variables.rb:6:16:6:21 | self [@field] : | semmle.label | self [@field] : |
| instance_variables.rb:8:5:10:7 | self in inc_field [@field] : | semmle.label | self in inc_field [@field] : |
| instance_variables.rb:9:9:9:14 | [post] self [@field] : | semmle.label | [post] self [@field] : |
| instance_variables.rb:11:5:11:8 | [post] self [@foo] : | semmle.label | [post] self [@foo] : |
| instance_variables.rb:11:5:11:8 | [post] self [@foo] : | semmle.label | [post] self [@foo] : |
| instance_variables.rb:11:12:11:22 | call to source : | semmle.label | call to source : |
| instance_variables.rb:11:12:11:22 | call to source : | semmle.label | call to source : |
| instance_variables.rb:12:10:12:13 | @foo | semmle.label | @foo |
| instance_variables.rb:12:10:12:13 | @foo | semmle.label | @foo |
| instance_variables.rb:12:10:12:13 | self [@foo] : | semmle.label | self [@foo] : |
| instance_variables.rb:12:10:12:13 | self [@foo] : | semmle.label | self [@foo] : |
| instance_variables.rb:16:1:16:3 | [post] foo [@field] : | semmle.label | [post] foo [@field] : |
| instance_variables.rb:16:1:16:3 | [post] foo [@field] : | semmle.label | [post] foo [@field] : |
| instance_variables.rb:16:15:16:24 | call to source : | semmle.label | call to source : |
| instance_variables.rb:16:15:16:24 | call to source : | semmle.label | call to source : |
| instance_variables.rb:17:6:17:8 | foo [@field] : | semmle.label | foo [@field] : |
| instance_variables.rb:17:6:17:8 | foo [@field] : | semmle.label | foo [@field] : |
| instance_variables.rb:17:6:17:18 | call to get_field | semmle.label | call to get_field |
| instance_variables.rb:17:6:17:18 | call to get_field | semmle.label | call to get_field |
| instance_variables.rb:20:1:20:3 | [post] bar [@field] : | semmle.label | [post] bar [@field] : |
| instance_variables.rb:20:15:20:23 | call to source : | semmle.label | call to source : |
| instance_variables.rb:21:6:21:8 | bar [@field] : | semmle.label | bar [@field] : |
| instance_variables.rb:21:6:21:18 | call to inc_field | semmle.label | call to inc_field |
subpaths
| instance_variables.rb:16:15:16:24 | call to source : | instance_variables.rb:2:19:2:19 | x : | instance_variables.rb:3:9:3:14 | [post] self [@field] : | instance_variables.rb:16:1:16:3 | [post] foo [@field] : |
| instance_variables.rb:16:15:16:24 | call to source : | instance_variables.rb:2:19:2:19 | x : | instance_variables.rb:3:9:3:14 | [post] self [@field] : | instance_variables.rb:16:1:16:3 | [post] foo [@field] : |
| instance_variables.rb:17:6:17:8 | foo [@field] : | instance_variables.rb:5:5:7:7 | self in get_field [@field] : | instance_variables.rb:6:9:6:21 | return : | instance_variables.rb:17:6:17:18 | call to get_field |
| instance_variables.rb:17:6:17:8 | foo [@field] : | instance_variables.rb:5:5:7:7 | self in get_field [@field] : | instance_variables.rb:6:9:6:21 | return : | instance_variables.rb:17:6:17:18 | call to get_field |
| instance_variables.rb:20:15:20:23 | call to source : | instance_variables.rb:2:19:2:19 | x : | instance_variables.rb:3:9:3:14 | [post] self [@field] : | instance_variables.rb:20:1:20:3 | [post] bar [@field] : |
| instance_variables.rb:21:6:21:8 | bar [@field] : | instance_variables.rb:8:5:10:7 | self in inc_field [@field] : | instance_variables.rb:8:5:10:7 | self in inc_field [@field] : | instance_variables.rb:21:6:21:18 | call to inc_field |
| instance_variables.rb:21:6:21:8 | bar [@field] : | instance_variables.rb:8:5:10:7 | self in inc_field [@field] : | instance_variables.rb:9:9:9:14 | [post] self [@field] : | instance_variables.rb:21:6:21:18 | call to inc_field |
#select
| instance_variables.rb:12:10:12:13 | @foo | instance_variables.rb:11:12:11:22 | call to source : | instance_variables.rb:12:10:12:13 | @foo | $@ | instance_variables.rb:11:12:11:22 | call to source : | call to source : |
| instance_variables.rb:17:6:17:18 | call to get_field | instance_variables.rb:16:15:16:24 | call to source : | instance_variables.rb:17:6:17:18 | call to get_field | $@ | instance_variables.rb:16:15:16:24 | call to source : | call to source : |
| instance_variables.rb:21:6:21:18 | call to inc_field | instance_variables.rb:20:15:20:23 | call to source : | instance_variables.rb:21:6:21:18 | call to inc_field | $@ | instance_variables.rb:20:15:20:23 | call to source : | call to source : |

View File

@@ -0,0 +1,12 @@
/**
* @kind path-problem
*/
import ruby
import codeql.ruby.DataFlow
private import TestUtilities.InlineFlowTest
import DataFlow::PathGraph
from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultTaintFlowConf conf
where conf.hasFlowPath(source, sink)
select sink, source, sink, "$@", source, source.toString()

View File

@@ -0,0 +1,21 @@
class Foo
def set_field x
@field = x
end
def get_field
return @field
end
def inc_field
@field += 1
end
@foo = source("7")
sink(@foo) # $ hasValueFlow=7
end
foo = Foo.new
foo.set_field(source(42))
sink(foo.get_field) # $ hasValueFlow=42
bar = Foo.new
bar.set_field(source(5))
sink(bar.inc_field) # $ hasTaintFlow=5

View File

@@ -8,9 +8,11 @@ track
| type_tracker.rb:2:5:5:7 | field= | type tracker without call steps | type_tracker.rb:2:5:5:7 | field= |
| type_tracker.rb:2:5:5:7 | return return in field= | type tracker without call steps | type_tracker.rb:2:5:5:7 | return return in field= |
| type_tracker.rb:2:5:5:7 | return return in field= | type tracker without call steps | type_tracker.rb:14:5:14:13 | call to field= |
| type_tracker.rb:2:5:5:7 | self (field=) | type tracker with call steps | type_tracker.rb:7:5:9:7 | self (field) |
| type_tracker.rb:2:5:5:7 | self (field=) | type tracker with call steps | type_tracker.rb:7:5:9:7 | self in field |
| type_tracker.rb:2:5:5:7 | self (field=) | type tracker without call steps | type_tracker.rb:2:5:5:7 | self (field=) |
| type_tracker.rb:2:5:5:7 | self in field= | type tracker with call steps | type_tracker.rb:2:5:5:7 | self (field=) |
| type_tracker.rb:2:5:5:7 | self in field= | type tracker with call steps | type_tracker.rb:7:5:9:7 | self (field) |
| type_tracker.rb:2:5:5:7 | self in field= | type tracker with call steps | type_tracker.rb:7:5:9:7 | self in field |
| type_tracker.rb:2:5:5:7 | self in field= | type tracker without call steps | type_tracker.rb:2:5:5:7 | self in field= |
| type_tracker.rb:2:16:2:18 | val | type tracker with call steps | type_tracker.rb:2:16:2:18 | val |
@@ -19,6 +21,7 @@ track
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:2:16:2:18 | val |
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:2:16:2:18 | val |
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:14:5:14:13 | call to field= |
| type_tracker.rb:3:9:3:23 | [post] self | type tracker with call steps | type_tracker.rb:7:5:9:7 | self (field) |
| type_tracker.rb:3:9:3:23 | [post] self | type tracker with call steps | type_tracker.rb:7:5:9:7 | self in field |
| type_tracker.rb:3:9:3:23 | [post] self | type tracker without call steps | type_tracker.rb:3:9:3:23 | [post] self |
| type_tracker.rb:3:9:3:23 | call to puts | type tracker without call steps | type_tracker.rb:3:9:3:23 | call to puts |
@@ -26,16 +29,20 @@ track
| type_tracker.rb:3:14:3:23 | [post] call to field | type tracker without call steps | type_tracker.rb:3:14:3:23 | [post] call to field |
| type_tracker.rb:3:14:3:23 | call to field | type tracker without call steps | type_tracker.rb:3:14:3:23 | call to field |
| type_tracker.rb:4:9:4:14 | @field | type tracker without call steps | type_tracker.rb:4:9:4:14 | @field |
| type_tracker.rb:4:9:4:14 | [post] self | type tracker without call steps | type_tracker.rb:4:9:4:14 | [post] self |
| type_tracker.rb:7:5:9:7 | &block | type tracker without call steps | type_tracker.rb:7:5:9:7 | &block |
| type_tracker.rb:7:5:9:7 | field | type tracker without call steps | type_tracker.rb:7:5:9:7 | field |
| type_tracker.rb:7:5:9:7 | return return in field | type tracker without call steps | type_tracker.rb:3:14:3:23 | call to field |
| type_tracker.rb:7:5:9:7 | return return in field | type tracker without call steps | type_tracker.rb:7:5:9:7 | return return in field |
| type_tracker.rb:7:5:9:7 | return return in field | type tracker without call steps | type_tracker.rb:15:10:15:18 | call to field |
| type_tracker.rb:7:5:9:7 | self (field) | type tracker without call steps | type_tracker.rb:7:5:9:7 | self (field) |
| type_tracker.rb:7:5:9:7 | self in field | type tracker with call steps | type_tracker.rb:7:5:9:7 | self (field) |
| type_tracker.rb:7:5:9:7 | self in field | type tracker without call steps | type_tracker.rb:7:5:9:7 | self in field |
| type_tracker.rb:8:9:8:14 | @field | type tracker without call steps | type_tracker.rb:3:14:3:23 | call to field |
| type_tracker.rb:8:9:8:14 | @field | type tracker without call steps | type_tracker.rb:7:5:9:7 | return return in field |
| type_tracker.rb:8:9:8:14 | @field | type tracker without call steps | type_tracker.rb:8:9:8:14 | @field |
| type_tracker.rb:8:9:8:14 | @field | type tracker without call steps | type_tracker.rb:15:10:15:18 | call to field |
| type_tracker.rb:8:9:8:14 | [post] self | type tracker without call steps | type_tracker.rb:8:9:8:14 | [post] self |
| type_tracker.rb:12:1:16:3 | &block | type tracker without call steps | type_tracker.rb:12:1:16:3 | &block |
| type_tracker.rb:12:1:16:3 | m | type tracker without call steps | type_tracker.rb:12:1:16:3 | m |
| type_tracker.rb:12:1:16:3 | return return in m | type tracker without call steps | type_tracker.rb:12:1:16:3 | return return in m |
@@ -47,13 +54,16 @@ track
| type_tracker.rb:13:11:13:19 | [post] Container | type tracker without call steps | type_tracker.rb:13:11:13:19 | [post] Container |
| type_tracker.rb:13:11:13:23 | call to new | type tracker with call steps | type_tracker.rb:2:5:5:7 | self (field=) |
| type_tracker.rb:13:11:13:23 | call to new | type tracker with call steps | type_tracker.rb:2:5:5:7 | self in field= |
| type_tracker.rb:13:11:13:23 | call to new | type tracker with call steps | type_tracker.rb:7:5:9:7 | self (field) |
| type_tracker.rb:13:11:13:23 | call to new | type tracker with call steps | type_tracker.rb:7:5:9:7 | self in field |
| type_tracker.rb:13:11:13:23 | call to new | type tracker without call steps | type_tracker.rb:13:11:13:23 | call to new |
| type_tracker.rb:14:5:14:7 | [post] var | type tracker with call steps | type_tracker.rb:7:5:9:7 | self (field) |
| type_tracker.rb:14:5:14:7 | [post] var | type tracker with call steps | type_tracker.rb:7:5:9:7 | self in field |
| type_tracker.rb:14:5:14:7 | [post] var | type tracker without call steps | type_tracker.rb:14:5:14:7 | [post] var |
| type_tracker.rb:14:5:14:13 | call to field= | type tracker without call steps | type_tracker.rb:14:5:14:13 | call to field= |
| type_tracker.rb:14:17:14:23 | "hello" | type tracker with call steps | type_tracker.rb:2:16:2:18 | val |
| type_tracker.rb:14:17:14:23 | "hello" | type tracker with call steps | type_tracker.rb:2:16:2:18 | val |
| type_tracker.rb:14:17:14:23 | "hello" | type tracker with call steps with content field | type_tracker.rb:7:5:9:7 | self (field) |
| type_tracker.rb:14:17:14:23 | "hello" | type tracker with call steps with content field | type_tracker.rb:7:5:9:7 | self in field |
| type_tracker.rb:14:17:14:23 | "hello" | type tracker without call steps | type_tracker.rb:14:5:14:13 | call to field= |
| type_tracker.rb:14:17:14:23 | "hello" | type tracker without call steps | type_tracker.rb:14:17:14:23 | "hello" |
@@ -196,12 +206,18 @@ trackEnd
| type_tracker.rb:2:5:5:7 | self (field=) | type_tracker.rb:2:5:5:7 | self (field=) |
| type_tracker.rb:2:5:5:7 | self (field=) | type_tracker.rb:3:9:3:23 | self |
| type_tracker.rb:2:5:5:7 | self (field=) | type_tracker.rb:3:14:3:17 | self |
| type_tracker.rb:2:5:5:7 | self (field=) | type_tracker.rb:4:9:4:14 | self |
| type_tracker.rb:2:5:5:7 | self (field=) | type_tracker.rb:7:5:9:7 | self (field) |
| type_tracker.rb:2:5:5:7 | self (field=) | type_tracker.rb:7:5:9:7 | self in field |
| type_tracker.rb:2:5:5:7 | self (field=) | type_tracker.rb:8:9:8:14 | self |
| type_tracker.rb:2:5:5:7 | self in field= | type_tracker.rb:2:5:5:7 | self (field=) |
| type_tracker.rb:2:5:5:7 | self in field= | type_tracker.rb:2:5:5:7 | self in field= |
| type_tracker.rb:2:5:5:7 | self in field= | type_tracker.rb:3:9:3:23 | self |
| type_tracker.rb:2:5:5:7 | self in field= | type_tracker.rb:3:14:3:17 | self |
| type_tracker.rb:2:5:5:7 | self in field= | type_tracker.rb:4:9:4:14 | self |
| type_tracker.rb:2:5:5:7 | self in field= | type_tracker.rb:7:5:9:7 | self (field) |
| type_tracker.rb:2:5:5:7 | self in field= | type_tracker.rb:7:5:9:7 | self in field |
| type_tracker.rb:2:5:5:7 | self in field= | type_tracker.rb:8:9:8:14 | self |
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:2:5:5:7 | return return in field= |
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:2:16:2:18 | val |
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:2:16:2:18 | val |
@@ -214,23 +230,33 @@ trackEnd
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:14:5:14:13 | call to field= |
| type_tracker.rb:3:9:3:23 | [post] self | type_tracker.rb:3:9:3:23 | [post] self |
| type_tracker.rb:3:9:3:23 | [post] self | type_tracker.rb:3:14:3:17 | self |
| type_tracker.rb:3:9:3:23 | [post] self | type_tracker.rb:4:9:4:14 | self |
| type_tracker.rb:3:9:3:23 | [post] self | type_tracker.rb:7:5:9:7 | self (field) |
| type_tracker.rb:3:9:3:23 | [post] self | type_tracker.rb:7:5:9:7 | self in field |
| type_tracker.rb:3:9:3:23 | [post] self | type_tracker.rb:8:9:8:14 | self |
| type_tracker.rb:3:9:3:23 | call to puts | type_tracker.rb:3:9:3:23 | call to puts |
| type_tracker.rb:3:14:3:17 | [post] self | type_tracker.rb:3:14:3:17 | [post] self |
| type_tracker.rb:3:14:3:17 | [post] self | type_tracker.rb:4:9:4:14 | self |
| type_tracker.rb:3:14:3:23 | [post] call to field | type_tracker.rb:3:14:3:23 | [post] call to field |
| type_tracker.rb:3:14:3:23 | call to field | type_tracker.rb:3:14:3:23 | call to field |
| type_tracker.rb:4:9:4:14 | @field | type_tracker.rb:4:9:4:14 | @field |
| type_tracker.rb:4:9:4:14 | [post] self | type_tracker.rb:4:9:4:14 | [post] self |
| type_tracker.rb:7:5:9:7 | &block | type_tracker.rb:7:5:9:7 | &block |
| type_tracker.rb:7:5:9:7 | field | type_tracker.rb:1:1:10:3 | Container |
| type_tracker.rb:7:5:9:7 | field | type_tracker.rb:7:5:9:7 | field |
| type_tracker.rb:7:5:9:7 | return return in field | type_tracker.rb:3:14:3:23 | call to field |
| type_tracker.rb:7:5:9:7 | return return in field | type_tracker.rb:7:5:9:7 | return return in field |
| type_tracker.rb:7:5:9:7 | return return in field | type_tracker.rb:15:10:15:18 | call to field |
| type_tracker.rb:7:5:9:7 | self (field) | type_tracker.rb:7:5:9:7 | self (field) |
| type_tracker.rb:7:5:9:7 | self (field) | type_tracker.rb:8:9:8:14 | self |
| type_tracker.rb:7:5:9:7 | self in field | type_tracker.rb:7:5:9:7 | self (field) |
| type_tracker.rb:7:5:9:7 | self in field | type_tracker.rb:7:5:9:7 | self in field |
| type_tracker.rb:7:5:9:7 | self in field | type_tracker.rb:8:9:8:14 | self |
| type_tracker.rb:8:9:8:14 | @field | type_tracker.rb:3:14:3:23 | call to field |
| type_tracker.rb:8:9:8:14 | @field | type_tracker.rb:7:5:9:7 | return return in field |
| type_tracker.rb:8:9:8:14 | @field | type_tracker.rb:8:9:8:14 | @field |
| type_tracker.rb:8:9:8:14 | @field | type_tracker.rb:15:10:15:18 | call to field |
| type_tracker.rb:8:9:8:14 | [post] self | type_tracker.rb:8:9:8:14 | [post] self |
| type_tracker.rb:12:1:16:3 | &block | type_tracker.rb:12:1:16:3 | &block |
| type_tracker.rb:12:1:16:3 | m | type_tracker.rb:12:1:16:3 | m |
| type_tracker.rb:12:1:16:3 | return return in m | type_tracker.rb:12:1:16:3 | return return in m |
@@ -246,13 +272,18 @@ trackEnd
| type_tracker.rb:13:11:13:23 | call to new | type_tracker.rb:2:5:5:7 | self in field= |
| type_tracker.rb:13:11:13:23 | call to new | type_tracker.rb:3:9:3:23 | self |
| type_tracker.rb:13:11:13:23 | call to new | type_tracker.rb:3:14:3:17 | self |
| type_tracker.rb:13:11:13:23 | call to new | type_tracker.rb:4:9:4:14 | self |
| type_tracker.rb:13:11:13:23 | call to new | type_tracker.rb:7:5:9:7 | self (field) |
| type_tracker.rb:13:11:13:23 | call to new | type_tracker.rb:7:5:9:7 | self in field |
| type_tracker.rb:13:11:13:23 | call to new | type_tracker.rb:8:9:8:14 | self |
| type_tracker.rb:13:11:13:23 | call to new | type_tracker.rb:13:5:13:23 | ... = ... |
| type_tracker.rb:13:11:13:23 | call to new | type_tracker.rb:13:5:13:23 | ... = ... |
| type_tracker.rb:13:11:13:23 | call to new | type_tracker.rb:13:11:13:23 | call to new |
| type_tracker.rb:13:11:13:23 | call to new | type_tracker.rb:14:5:14:7 | var |
| type_tracker.rb:13:11:13:23 | call to new | type_tracker.rb:15:10:15:12 | var |
| type_tracker.rb:14:5:14:7 | [post] var | type_tracker.rb:7:5:9:7 | self (field) |
| type_tracker.rb:14:5:14:7 | [post] var | type_tracker.rb:7:5:9:7 | self in field |
| type_tracker.rb:14:5:14:7 | [post] var | type_tracker.rb:8:9:8:14 | self |
| type_tracker.rb:14:5:14:7 | [post] var | type_tracker.rb:14:5:14:7 | [post] var |
| type_tracker.rb:14:5:14:7 | [post] var | type_tracker.rb:15:10:15:12 | var |
| type_tracker.rb:14:5:14:13 | call to field= | type_tracker.rb:14:5:14:13 | call to field= |

View File

@@ -6,8 +6,19 @@ definition
| class_variables.rb:13:3:15:5 | self (s) | class_variables.rb:13:3:15:5 | self |
| class_variables.rb:26:1:29:3 | self (N) | class_variables.rb:26:1:29:3 | self |
| instance_variables.rb:1:1:1:4 | self (instance_variables.rb) | instance_variables.rb:1:1:44:4 | self |
| instance_variables.rb:1:1:44:4 | self (instance_variables.rb) | instance_variables.rb:1:1:44:4 | self |
| instance_variables.rb:3:1:5:3 | self (foo) | instance_variables.rb:3:1:5:3 | self |
| instance_variables.rb:7:1:9:3 | self (print_foo) | instance_variables.rb:7:1:9:3 | self |
| instance_variables.rb:13:1:18:3 | self (X) | instance_variables.rb:13:1:18:3 | self |
| instance_variables.rb:15:3:17:5 | self (m) | instance_variables.rb:15:3:17:5 | self |
| instance_variables.rb:20:1:25:3 | self (M) | instance_variables.rb:20:1:25:3 | self |
| instance_variables.rb:22:2:24:4 | self (n) | instance_variables.rb:22:2:24:4 | self |
| instance_variables.rb:27:6:29:1 | <captured> | instance_variables.rb:1:1:44:4 | self |
| instance_variables.rb:31:1:33:3 | self (bar) | instance_variables.rb:31:1:33:3 | self |
| instance_variables.rb:32:10:32:21 | <captured> | instance_variables.rb:31:1:33:3 | self |
| instance_variables.rb:35:1:44:4 | self (C) | instance_variables.rb:35:1:44:4 | self |
| instance_variables.rb:37:3:43:5 | self (x) | instance_variables.rb:37:3:43:5 | self |
| instance_variables.rb:38:4:40:6 | self (y) | instance_variables.rb:38:4:40:6 | self |
| nested_scopes.rb:1:1:3:3 | self (a) | nested_scopes.rb:1:1:3:3 | self |
| nested_scopes.rb:4:1:39:3 | self (C) | nested_scopes.rb:4:1:39:3 | self |
| nested_scopes.rb:5:3:5:7 | ... = ... | nested_scopes.rb:5:3:5:3 | a |
@@ -158,10 +169,23 @@ read
| class_variables.rb:26:1:29:3 | self (N) | class_variables.rb:26:1:29:3 | self | class_variables.rb:27:3:27:11 | self |
| class_variables.rb:26:1:29:3 | self (N) | class_variables.rb:26:1:29:3 | self | class_variables.rb:28:3:28:7 | self |
| instance_variables.rb:1:1:1:4 | self (instance_variables.rb) | instance_variables.rb:1:1:44:4 | self | instance_variables.rb:11:1:11:9 | self |
| instance_variables.rb:1:1:1:4 | self (instance_variables.rb) | instance_variables.rb:1:1:44:4 | self | instance_variables.rb:11:6:11:9 | self |
| instance_variables.rb:1:1:1:4 | self (instance_variables.rb) | instance_variables.rb:1:1:44:4 | self | instance_variables.rb:27:1:29:1 | self |
| instance_variables.rb:1:1:44:4 | self (instance_variables.rb) | instance_variables.rb:1:1:44:4 | self | instance_variables.rb:1:1:1:4 | self |
| instance_variables.rb:3:1:5:3 | self (foo) | instance_variables.rb:3:1:5:3 | self | instance_variables.rb:4:3:4:6 | self |
| instance_variables.rb:7:1:9:3 | self (print_foo) | instance_variables.rb:7:1:9:3 | self | instance_variables.rb:8:3:8:11 | self |
| instance_variables.rb:7:1:9:3 | self (print_foo) | instance_variables.rb:7:1:9:3 | self | instance_variables.rb:8:8:8:11 | self |
| instance_variables.rb:13:1:18:3 | self (X) | instance_variables.rb:13:1:18:3 | self | instance_variables.rb:14:3:14:4 | self |
| instance_variables.rb:15:3:17:5 | self (m) | instance_variables.rb:15:3:17:5 | self | instance_variables.rb:16:5:16:6 | self |
| instance_variables.rb:20:1:25:3 | self (M) | instance_variables.rb:20:1:25:3 | self | instance_variables.rb:21:2:21:3 | self |
| instance_variables.rb:22:2:24:4 | self (n) | instance_variables.rb:22:2:24:4 | self | instance_variables.rb:23:4:23:5 | self |
| instance_variables.rb:27:6:29:1 | <captured> | instance_variables.rb:1:1:44:4 | self | instance_variables.rb:28:3:28:4 | self |
| instance_variables.rb:32:10:32:21 | <captured> | instance_variables.rb:31:1:33:3 | self | instance_variables.rb:32:12:32:13 | self |
| instance_variables.rb:35:1:44:4 | self (C) | instance_variables.rb:35:1:44:4 | self | instance_variables.rb:36:3:36:4 | self |
| instance_variables.rb:37:3:43:5 | self (x) | instance_variables.rb:37:3:43:5 | self | instance_variables.rb:41:4:41:4 | self |
| instance_variables.rb:37:3:43:5 | self (x) | instance_variables.rb:37:3:43:5 | self | instance_variables.rb:42:4:42:7 | self |
| instance_variables.rb:37:3:43:5 | self (x) | instance_variables.rb:37:3:43:5 | self | instance_variables.rb:42:6:42:7 | self |
| instance_variables.rb:38:4:40:6 | self (y) | instance_variables.rb:38:4:40:6 | self | instance_variables.rb:39:6:39:7 | self |
| nested_scopes.rb:1:1:3:3 | self (a) | nested_scopes.rb:1:1:3:3 | self | nested_scopes.rb:2:3:2:17 | self |
| nested_scopes.rb:4:1:39:3 | self (C) | nested_scopes.rb:4:1:39:3 | self | nested_scopes.rb:38:3:38:8 | self |
| nested_scopes.rb:5:3:5:7 | ... = ... | nested_scopes.rb:5:3:5:3 | a | nested_scopes.rb:38:8:38:8 | a |
@@ -327,8 +351,18 @@ firstRead
| class_variables.rb:13:3:15:5 | self (s) | class_variables.rb:13:3:15:5 | self | class_variables.rb:14:4:14:8 | self |
| class_variables.rb:26:1:29:3 | self (N) | class_variables.rb:26:1:29:3 | self | class_variables.rb:27:3:27:11 | self |
| instance_variables.rb:1:1:1:4 | self (instance_variables.rb) | instance_variables.rb:1:1:44:4 | self | instance_variables.rb:11:1:11:9 | self |
| instance_variables.rb:1:1:44:4 | self (instance_variables.rb) | instance_variables.rb:1:1:44:4 | self | instance_variables.rb:1:1:1:4 | self |
| instance_variables.rb:3:1:5:3 | self (foo) | instance_variables.rb:3:1:5:3 | self | instance_variables.rb:4:3:4:6 | self |
| instance_variables.rb:7:1:9:3 | self (print_foo) | instance_variables.rb:7:1:9:3 | self | instance_variables.rb:8:3:8:11 | self |
| instance_variables.rb:13:1:18:3 | self (X) | instance_variables.rb:13:1:18:3 | self | instance_variables.rb:14:3:14:4 | self |
| instance_variables.rb:15:3:17:5 | self (m) | instance_variables.rb:15:3:17:5 | self | instance_variables.rb:16:5:16:6 | self |
| instance_variables.rb:20:1:25:3 | self (M) | instance_variables.rb:20:1:25:3 | self | instance_variables.rb:21:2:21:3 | self |
| instance_variables.rb:22:2:24:4 | self (n) | instance_variables.rb:22:2:24:4 | self | instance_variables.rb:23:4:23:5 | self |
| instance_variables.rb:27:6:29:1 | <captured> | instance_variables.rb:1:1:44:4 | self | instance_variables.rb:28:3:28:4 | self |
| instance_variables.rb:32:10:32:21 | <captured> | instance_variables.rb:31:1:33:3 | self | instance_variables.rb:32:12:32:13 | self |
| instance_variables.rb:35:1:44:4 | self (C) | instance_variables.rb:35:1:44:4 | self | instance_variables.rb:36:3:36:4 | self |
| instance_variables.rb:37:3:43:5 | self (x) | instance_variables.rb:37:3:43:5 | self | instance_variables.rb:41:4:41:4 | self |
| instance_variables.rb:38:4:40:6 | self (y) | instance_variables.rb:38:4:40:6 | self | instance_variables.rb:39:6:39:7 | self |
| nested_scopes.rb:1:1:3:3 | self (a) | nested_scopes.rb:1:1:3:3 | self | nested_scopes.rb:2:3:2:17 | self |
| nested_scopes.rb:4:1:39:3 | self (C) | nested_scopes.rb:4:1:39:3 | self | nested_scopes.rb:38:3:38:8 | self |
| nested_scopes.rb:5:3:5:7 | ... = ... | nested_scopes.rb:5:3:5:3 | a | nested_scopes.rb:38:8:38:8 | a |
@@ -455,9 +489,20 @@ lastRead
| class_variables.rb:10:3:12:5 | self (b) | class_variables.rb:10:3:12:5 | self | class_variables.rb:11:5:11:9 | self |
| class_variables.rb:13:3:15:5 | self (s) | class_variables.rb:13:3:15:5 | self | class_variables.rb:14:4:14:8 | self |
| class_variables.rb:26:1:29:3 | self (N) | class_variables.rb:26:1:29:3 | self | class_variables.rb:28:3:28:7 | self |
| instance_variables.rb:1:1:1:4 | self (instance_variables.rb) | instance_variables.rb:1:1:44:4 | self | instance_variables.rb:1:1:1:4 | self |
| instance_variables.rb:1:1:1:4 | self (instance_variables.rb) | instance_variables.rb:1:1:44:4 | self | instance_variables.rb:27:1:29:1 | self |
| instance_variables.rb:7:1:9:3 | self (print_foo) | instance_variables.rb:7:1:9:3 | self | instance_variables.rb:8:3:8:11 | self |
| instance_variables.rb:37:3:43:5 | self (x) | instance_variables.rb:37:3:43:5 | self | instance_variables.rb:42:4:42:7 | self |
| instance_variables.rb:1:1:44:4 | self (instance_variables.rb) | instance_variables.rb:1:1:44:4 | self | instance_variables.rb:1:1:1:4 | self |
| instance_variables.rb:3:1:5:3 | self (foo) | instance_variables.rb:3:1:5:3 | self | instance_variables.rb:4:3:4:6 | self |
| instance_variables.rb:7:1:9:3 | self (print_foo) | instance_variables.rb:7:1:9:3 | self | instance_variables.rb:8:8:8:11 | self |
| instance_variables.rb:13:1:18:3 | self (X) | instance_variables.rb:13:1:18:3 | self | instance_variables.rb:14:3:14:4 | self |
| instance_variables.rb:15:3:17:5 | self (m) | instance_variables.rb:15:3:17:5 | self | instance_variables.rb:16:5:16:6 | self |
| instance_variables.rb:20:1:25:3 | self (M) | instance_variables.rb:20:1:25:3 | self | instance_variables.rb:21:2:21:3 | self |
| instance_variables.rb:22:2:24:4 | self (n) | instance_variables.rb:22:2:24:4 | self | instance_variables.rb:23:4:23:5 | self |
| instance_variables.rb:27:6:29:1 | <captured> | instance_variables.rb:1:1:44:4 | self | instance_variables.rb:28:3:28:4 | self |
| instance_variables.rb:32:10:32:21 | <captured> | instance_variables.rb:31:1:33:3 | self | instance_variables.rb:32:12:32:13 | self |
| instance_variables.rb:35:1:44:4 | self (C) | instance_variables.rb:35:1:44:4 | self | instance_variables.rb:36:3:36:4 | self |
| instance_variables.rb:37:3:43:5 | self (x) | instance_variables.rb:37:3:43:5 | self | instance_variables.rb:42:6:42:7 | self |
| instance_variables.rb:38:4:40:6 | self (y) | instance_variables.rb:38:4:40:6 | self | instance_variables.rb:39:6:39:7 | self |
| nested_scopes.rb:1:1:3:3 | self (a) | nested_scopes.rb:1:1:3:3 | self | nested_scopes.rb:2:3:2:17 | self |
| nested_scopes.rb:4:1:39:3 | self (C) | nested_scopes.rb:4:1:39:3 | self | nested_scopes.rb:38:3:38:8 | self |
| nested_scopes.rb:5:3:5:7 | ... = ... | nested_scopes.rb:5:3:5:3 | a | nested_scopes.rb:38:8:38:8 | a |
@@ -580,8 +625,12 @@ lastRead
| ssa.rb:84:10:86:8 | <captured> | ssa.rb:82:3:82:10 | captured | ssa.rb:85:15:85:22 | captured |
adjacentReads
| class_variables.rb:26:1:29:3 | self (N) | class_variables.rb:26:1:29:3 | self | class_variables.rb:27:3:27:11 | self | class_variables.rb:28:3:28:7 | self |
| instance_variables.rb:1:1:1:4 | self (instance_variables.rb) | instance_variables.rb:1:1:44:4 | self | instance_variables.rb:11:1:11:9 | self | instance_variables.rb:27:1:29:1 | self |
| instance_variables.rb:1:1:1:4 | self (instance_variables.rb) | instance_variables.rb:1:1:44:4 | self | instance_variables.rb:1:1:1:4 | self | instance_variables.rb:11:1:11:9 | self |
| instance_variables.rb:1:1:1:4 | self (instance_variables.rb) | instance_variables.rb:1:1:44:4 | self | instance_variables.rb:11:1:11:9 | self | instance_variables.rb:11:6:11:9 | self |
| instance_variables.rb:1:1:1:4 | self (instance_variables.rb) | instance_variables.rb:1:1:44:4 | self | instance_variables.rb:11:6:11:9 | self | instance_variables.rb:27:1:29:1 | self |
| instance_variables.rb:7:1:9:3 | self (print_foo) | instance_variables.rb:7:1:9:3 | self | instance_variables.rb:8:3:8:11 | self | instance_variables.rb:8:8:8:11 | self |
| instance_variables.rb:37:3:43:5 | self (x) | instance_variables.rb:37:3:43:5 | self | instance_variables.rb:41:4:41:4 | self | instance_variables.rb:42:4:42:7 | self |
| instance_variables.rb:37:3:43:5 | self (x) | instance_variables.rb:37:3:43:5 | self | instance_variables.rb:42:4:42:7 | self | instance_variables.rb:42:6:42:7 | self |
| nested_scopes.rb:8:5:35:7 | self (N) | nested_scopes.rb:8:5:35:7 | self | nested_scopes.rb:27:11:27:14 | self | nested_scopes.rb:30:16:30:19 | self |
| nested_scopes.rb:8:5:35:7 | self (N) | nested_scopes.rb:8:5:35:7 | self | nested_scopes.rb:30:16:30:19 | self | nested_scopes.rb:34:7:34:12 | self |
| nested_scopes.rb:13:11:13:15 | ... = ... | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:14:16:14:16 | a | nested_scopes.rb:15:11:15:11 | a |

View File

@@ -15,23 +15,36 @@ variableAccess
| class_variables.rb:28:3:28:7 | self | class_variables.rb:26:1:29:3 | self | class_variables.rb:26:1:29:3 | N |
| 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:1:1:1:4 | self | instance_variables.rb:1:1:44:4 | self | 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:4:3:4:6 | self | instance_variables.rb:3:1:5:3 | self | instance_variables.rb:3:1:5:3 | foo |
| instance_variables.rb:8:3:8:11 | self | instance_variables.rb:7:1:9:3 | self | instance_variables.rb:7:1:9:3 | print_foo |
| 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:8:8:8:11 | self | instance_variables.rb:7:1:9:3 | self | instance_variables.rb:7:1:9:3 | print_foo |
| instance_variables.rb:11:1:11:9 | self | instance_variables.rb:1:1:44:4 | self | 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:11:6:11:9 | self | instance_variables.rb:1:1:44:4 | self | 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:14:3:14:4 | self | instance_variables.rb:13:1:18:3 | self | 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:16:5:16:6 | self | instance_variables.rb:15:3:17:5 | self | instance_variables.rb:15:3:17:5 | m |
| 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:21:2:21:3 | self | instance_variables.rb:20:1:25:3 | self | 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:23:4:23:5 | self | instance_variables.rb:22:2:24:4 | self | instance_variables.rb:22:2:24:4 | n |
| instance_variables.rb:27:1:29:1 | self | instance_variables.rb:1:1:44:4 | self | instance_variables.rb:1:1:44:4 | instance_variables.rb |
| 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:28:3:28:4 | self | instance_variables.rb:1:1:44:4 | self | 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:32:12:32:13 | self | instance_variables.rb:31:1:33:3 | self | instance_variables.rb:31:1:33:3 | bar |
| 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:36:3:36:4 | self | instance_variables.rb:35:1:44:4 | self | 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:39:6:39:7 | self | instance_variables.rb:38:4:40:6 | self | instance_variables.rb:38:4:40:6 | y |
| instance_variables.rb:41:4:41:4 | self | instance_variables.rb:37:3:43:5 | self | instance_variables.rb:37:3:43:5 | x |
| instance_variables.rb:42:4:42:7 | self | instance_variables.rb:37:3:43:5 | self | instance_variables.rb:37:3:43:5 | x |
| instance_variables.rb:42:6:42: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 | self | instance_variables.rb:37:3:43:5 | self | instance_variables.rb:37:3:43:5 | x |
| nested_scopes.rb:2:3:2:17 | self | nested_scopes.rb:1:1:3:3 | self | nested_scopes.rb:1:1:3:3 | a |
| 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 |
@@ -390,14 +403,27 @@ readAccess
| class_variables.rb:27:3:27:11 | self |
| class_variables.rb:28:3:28:7 | self |
| class_variables.rb:28:5:28:7 | @@x |
| instance_variables.rb:1:1:1:4 | self |
| instance_variables.rb:4:3:4:6 | self |
| instance_variables.rb:8:3:8:11 | self |
| instance_variables.rb:8:8:8:11 | @foo |
| instance_variables.rb:8:8:8:11 | self |
| instance_variables.rb:11:1:11:9 | self |
| instance_variables.rb:11:6:11:9 | @top |
| instance_variables.rb:11:6:11:9 | self |
| instance_variables.rb:14:3:14:4 | self |
| instance_variables.rb:16:5:16:6 | self |
| instance_variables.rb:21:2:21:3 | self |
| instance_variables.rb:23:4:23:5 | self |
| instance_variables.rb:27:1:29:1 | self |
| instance_variables.rb:28:3:28:4 | self |
| instance_variables.rb:32:12:32:13 | self |
| instance_variables.rb:36:3:36:4 | self |
| instance_variables.rb:39:6:39:7 | self |
| instance_variables.rb:41:4:41:4 | self |
| instance_variables.rb:42:4:42:7 | self |
| instance_variables.rb:42:6:42:7 | @x |
| instance_variables.rb:42:6:42:7 | self |
| nested_scopes.rb:2:3:2:17 | self |
| nested_scopes.rb:14:11:14:16 | self |
| nested_scopes.rb:14:16:14:16 | a |

View File

@@ -1,7 +1,10 @@
edges
| app/controllers/foo/bars_controller.rb:9:12:9:17 | call to params : | app/controllers/foo/bars_controller.rb:9:12:9:29 | ...[...] : |
| app/controllers/foo/bars_controller.rb:9:12:9:29 | ...[...] : | app/views/foo/bars/show.html.erb:47:5:47:13 | call to user_name |
| app/controllers/foo/bars_controller.rb:13:5:13:14 | [post] self [@user_name] : | app/controllers/foo/bars_controller.rb:13:5:13:14 | [post] self [@user_name] : |
| app/controllers/foo/bars_controller.rb:13:5:13:14 | [post] self [@user_name] : | app/views/foo/bars/show.html.erb:51:5:51:18 | call to user_name_memo |
| app/controllers/foo/bars_controller.rb:13:20:13:25 | call to params : | app/controllers/foo/bars_controller.rb:13:20:13:37 | ...[...] : |
| app/controllers/foo/bars_controller.rb:13:20:13:37 | ...[...] : | app/controllers/foo/bars_controller.rb:13:5:13:14 | [post] self [@user_name] : |
| app/controllers/foo/bars_controller.rb:13:20:13:37 | ...[...] : | app/views/foo/bars/show.html.erb:51:5:51:18 | call to user_name_memo |
| app/controllers/foo/bars_controller.rb:17:21:17:26 | call to params : | app/controllers/foo/bars_controller.rb:17:21:17:36 | ...[...] : |
| app/controllers/foo/bars_controller.rb:17:21:17:36 | ...[...] : | app/views/foo/bars/show.html.erb:2:18:2:30 | @user_website |
@@ -22,6 +25,7 @@ edges
nodes
| app/controllers/foo/bars_controller.rb:9:12:9:17 | call to params : | semmle.label | call to params : |
| app/controllers/foo/bars_controller.rb:9:12:9:29 | ...[...] : | semmle.label | ...[...] : |
| app/controllers/foo/bars_controller.rb:13:5:13:14 | [post] self [@user_name] : | semmle.label | [post] self [@user_name] : |
| app/controllers/foo/bars_controller.rb:13:20:13:25 | call to params : | semmle.label | call to params : |
| app/controllers/foo/bars_controller.rb:13:20:13:37 | ...[...] : | semmle.label | ...[...] : |
| app/controllers/foo/bars_controller.rb:17:21:17:26 | call to params : | semmle.label | call to params : |