Merge pull request #14229 from hvitved/ruby/splat-flow-performance

Ruby: Improve performance of flow through (hash) splats
This commit is contained in:
Tom Hvitved
2023-09-27 14:41:33 +02:00
committed by GitHub
23 changed files with 5003 additions and 4771 deletions

View File

@@ -886,8 +886,6 @@ module API {
)
or
implicitCallEdge(pred, succ)
or
exists(DataFlow::HashLiteralNode splat | hashSplatEdge(splat, pred, succ))
}
/**
@@ -986,29 +984,6 @@ module API {
)
}
pragma[nomagic]
private DataFlow::Node getHashSplatArgument(DataFlow::HashLiteralNode literal) {
result = DataFlowPrivate::TSynthHashSplatArgumentNode(literal.asExpr())
}
/**
* Holds if the epsilon edge `pred -> succ` should be generated to account for the members of a hash literal.
*
* This currently exists because hash literals are desugared to `Hash.[]` calls, whose summary relies on `WithContent`.
* However, `contentEdge` does not currently generate edges for `WithContent` steps.
*/
bindingset[literal]
pragma[inline_late]
private predicate hashSplatEdge(DataFlow::HashLiteralNode literal, ApiNode pred, ApiNode succ) {
exists(TypeTracker t |
pred = Impl::MkForwardNode(getALocalSourceStrict(getHashSplatArgument(literal)), t) and
succ = Impl::MkForwardNode(pragma[only_bind_out](literal), pragma[only_bind_out](t))
or
succ = Impl::MkBackwardNode(getALocalSourceStrict(getHashSplatArgument(literal)), t) and
pred = Impl::MkBackwardNode(pragma[only_bind_out](literal), pragma[only_bind_out](t))
)
}
pragma[nomagic]
private DataFlow::LocalSourceNode getAModuleReference(DataFlow::ModuleNode mod) {
result = mod.getAnImmediateReference()

View File

@@ -437,6 +437,7 @@ private module Cached {
FlowSummaryImplSpecific::ParsePositions::isParsedKeywordParameterPosition(_, name)
} or
THashSplatArgumentPosition() or
TSynthHashSplatArgumentPosition() or
TSplatArgumentPosition(int pos) { exists(Call c | c.getArgument(pos) instanceof SplatExpr) } or
TSynthSplatArgumentPosition() or
TAnyArgumentPosition() or
@@ -461,14 +462,10 @@ private module Cached {
FlowSummaryImplSpecific::ParsePositions::isParsedKeywordArgumentPosition(_, name)
} or
THashSplatParameterPosition() or
// To get flow from a hash-splat argument to a keyword parameter, we add a read-step
// from a synthetic hash-splat parameter. We need this separate synthetic ParameterNode,
// since we clear content of the normal hash-splat parameter for the names that
// correspond to normal keyword parameters. Since we cannot re-use the same parameter
// position for multiple parameter nodes in the same callable, we introduce this
// synthetic parameter position.
TSynthHashSplatParameterPosition() or
TSplatParameterPosition(int pos) {
pos = 0
or
exists(Parameter p | p.getPosition() = pos and p instanceof SplatParameter)
} or
TSynthSplatParameterPosition() or
@@ -1297,12 +1294,15 @@ class ParameterPosition extends TParameterPosition {
/** Holds if this position represents a hash-splat parameter. */
predicate isHashSplat() { this = THashSplatParameterPosition() }
/** Holds if this position represents a synthetic hash-splat parameter. */
predicate isSynthHashSplat() { this = TSynthHashSplatParameterPosition() }
predicate isSynthSplat() { this = TSynthSplatParameterPosition() }
/** Holds if this position represents a splat parameter at position `n`. */
predicate isSplat(int n) { this = TSplatParameterPosition(n) }
/** Holds if this position represents a synthetic splat parameter. */
predicate isSynthSplat() { this = TSynthSplatParameterPosition() }
/**
* Holds if this position represents any parameter, except `self` parameters. This
* includes both positional, named, and block parameters.
@@ -1334,9 +1334,9 @@ class ParameterPosition extends TParameterPosition {
or
this.isAnyNamed() and result = "any-named"
or
this.isSynthSplat() and result = "synthetic *"
or
exists(int pos | this.isSplat(pos) and result = "* (position " + pos + ")")
or
this.isSynthSplat() and result = "synthetic *"
}
}
@@ -1366,14 +1366,16 @@ class ArgumentPosition extends TArgumentPosition {
/** Holds if this position represents any positional parameter. */
predicate isAnyNamed() { this = TAnyKeywordArgumentPosition() }
/**
* Holds if this position represents a synthesized argument containing all keyword
* arguments wrapped in a hash.
*/
/** Holds if this position represents a hash-splat argument. */
predicate isHashSplat() { this = THashSplatArgumentPosition() }
/** Holds if this position represents a synthetic hash-splat argument. */
predicate isSynthHashSplat() { this = TSynthHashSplatArgumentPosition() }
/** Holds if this position represents a splat argument at position `n`. */
predicate isSplat(int n) { this = TSplatArgumentPosition(n) }
/** Holds if this position represents a synthetic splat argument. */
predicate isSynthSplat() { this = TSynthSplatArgumentPosition() }
/** Gets a textual representation of this position. */
@@ -1394,9 +1396,11 @@ class ArgumentPosition extends TArgumentPosition {
or
this.isHashSplat() and result = "**"
or
this.isSynthSplat() and result = "synthetic *"
this.isSynthHashSplat() and result = "synthetic **"
or
exists(int pos | this.isSplat(pos) and result = "* (position " + pos + ")")
or
this.isSynthSplat() and result = "synthetic *"
}
}
@@ -1429,17 +1433,21 @@ predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) {
or
exists(string name | ppos.isKeyword(name) and apos.isKeyword(name))
or
ppos.isHashSplat() and apos.isHashSplat()
(ppos.isHashSplat() or ppos.isSynthHashSplat()) and
(apos.isHashSplat() or apos.isSynthHashSplat())
or
ppos.isSynthHashSplat() and apos.isHashSplat()
or
ppos.isSplat(0) and apos.isSynthSplat()
or
ppos.isSynthSplat() and
(apos.isSynthSplat() or apos.isSplat(0))
or
// Exact splat match
exists(int n | apos.isSplat(n) and ppos.isSplat(n))
exists(int pos |
(
ppos.isSplat(pos)
or
ppos.isSynthSplat() and pos = 0
) and
(
apos.isSplat(pos)
or
apos.isSynthSplat() and pos = 0
)
)
or
ppos.isAny() and argumentPositionIsNotSelf(apos)
or

View File

@@ -427,6 +427,14 @@ module VariableCapture {
}
}
private predicate splatParameterAt(Callable c, int pos) {
c.getParameter(pos) instanceof SplatParameter
}
private predicate splatArgumentAt(CfgNodes::ExprNodes::CallCfgNode c, int pos) {
exists(Argument arg, ArgumentPosition apos | arg.isArgumentOf(c, apos) and apos.isSplat(pos))
}
/** A collection of cached types and predicates to be evaluated in the same stage. */
cached
private module Cached {
@@ -452,12 +460,11 @@ private module Cached {
isParameterNode(_, c, any(ParameterPosition p | p.isKeyword(_)))
} or
TSynthSplatParameterNode(DataFlowCallable c) {
exists(c.asCallable()) and // exclude library callables
exists(c.asCallable()) and // exclude library callables (for now)
isParameterNode(_, c, any(ParameterPosition p | p.isPositional(_)))
} or
TSynthSplatParameterElementNode(DataFlowCallable c, int n) {
exists(c.asCallable()) and // exclude library callables
isParameterNode(_, c, any(ParameterPosition p | p.isSplat(any(int i | i > 0)))) and
TSynthSplatParameterShiftNode(DataFlowCallable c, int splatPos, int n) {
splatPos = unique(int i | splatParameterAt(c.asCallable(), i) and i > 0) and
n in [0 .. 10]
} or
TExprPostUpdateNode(CfgNodes::ExprCfgNode n) {
@@ -476,12 +483,10 @@ private module Cached {
c.getAnArgument() instanceof CfgNodes::ExprNodes::PairCfgNode
} or
TSynthSplatArgumentNode(CfgNodes::ExprNodes::CallCfgNode c) or
TSynthSplatArgumentElementNode(CfgNodes::ExprNodes::CallCfgNode c, int n) {
TSynthSplatArgumentShiftNode(CfgNodes::ExprNodes::CallCfgNode c, int splatPos, int n) {
// we use -1 to represent data at an unknown index
n in [-1 .. 10] and
exists(Argument arg, ArgumentPosition pos |
pos.isSplat(any(int p | p > 0)) and arg.isArgumentOf(c, pos)
)
splatPos = unique(int i | splatArgumentAt(c, i) and i > 0)
} or
TCaptureNode(VariableCapture::Flow::SynthesizedCaptureNode cn)
@@ -646,6 +651,8 @@ private module Cached {
name = [input, output].regexpFind("(?<=(^|\\.)Field\\[)[^\\]]+(?=\\])", _, _).trim()
)
} or
TSplatContent(int i, Boolean shifted) { i in [0 .. 10] } or
THashSplatContent(ConstantValue cv) { not cv.isInt(_) } or
TCapturedVariableContent(VariableCapture::CapturedVariable v) or
// Only used by type-tracking
TAttributeName(string name) { name = any(SetterMethodCall c).getTargetName() }
@@ -669,11 +676,14 @@ private module Cached {
TUnknownElementContentApprox() or
TKnownIntegerElementContentApprox() or
TKnownElementContentApprox(string approx) { approx = approxKnownElementIndex(_) } or
TSplatContentApprox(Boolean shifted) or
THashSplatContentApprox(string approx) { approx = approxKnownElementIndex(_) } or
TNonElementContentApprox(Content c) { not c instanceof Content::ElementContent } or
TCapturedVariableContentApprox(VariableCapture::CapturedVariable v)
}
class TElementContent = TKnownElementContent or TUnknownElementContent;
class TElementContent =
TKnownElementContent or TUnknownElementContent or TSplatContent or THashSplatContent;
import Cached
@@ -695,7 +705,9 @@ predicate nodeIsHidden(Node n) {
or
n instanceof SynthSplatArgumentNode
or
n instanceof SynthSplatParameterElementNode
n instanceof SynthSplatParameterShiftNode
or
n instanceof SynthSplatArgumentShiftNode
or
n instanceof LambdaSelfReferenceNode
or
@@ -952,15 +964,15 @@ private module ParameterNodes {
}
/**
* A synthetic data-flow node to allow for flow into keyword parameters from
* hash-splat arguments.
*
* For all methods containing keyword parameters, we construct a synthesized
* (hidden) parameter node to contain all keyword arguments. This allows us
* to handle cases like
*
* ```rb
* def foo(p1:, p2:)
* sink(p1)
* sink(p2)
* end
* def foo(p1:, p2:); end
*
* args = {:p1 => taint(1), :p2 => taint(2) }
* foo(**args)
@@ -969,36 +981,34 @@ private module ParameterNodes {
* by adding read steps out of the synthesized parameter node to the relevant
* keyword parameters.
*
* Note that this will introduce a bit of redundancy in cases like
* In order to avoid redundancy (and improve performance) in cases like
*
* ```rb
* foo(p1: taint(1), p2: taint(2))
* ```
*
* where direct keyword matching is possible, since we construct a synthesized hash
* splat argument (`SynthHashSplatArgumentNode`) at the call site, which means that
* `taint(1)` will flow into `p1` both via normal keyword matching and via the synthesized
* nodes (and similarly for `p2`). However, this redundancy is OK since
* (a) it means that type-tracking through keyword arguments also works in most cases,
* (b) read/store steps can be avoided when direct keyword matching is possible, and
* hence access path limits are not a concern, and
* (c) since the synthesized nodes are hidden, the reported data-flow paths will be
* collapsed anyway.
* where direct keyword matching is possible, we use a special `HashSplatContent`
* (instead of reusing `KnownElementContent`) when we construct a synthesized hash
* splat argument (`SynthHashSplatArgumentNode`) at the call site, and then only
* add read steps out of this node for actual hash-splat arguments (which will use
* a normal `KnownElementContent`).
*/
class SynthHashSplatParameterNode extends ParameterNodeImpl, TSynthHashSplatParameterNode {
private DataFlowCallable callable;
SynthHashSplatParameterNode() { this = TSynthHashSplatParameterNode(callable) }
/**
* Gets a keyword parameter that will be the result of reading `c` out of this
* synthesized node.
*/
ParameterNode getAKeywordParameter(ContentSet c) {
/** Holds if a read-step should be added into parameter `p`. */
predicate readInto(ParameterNode p, ContentSet c) {
exists(string name |
isParameterNode(result, callable, any(ParameterPosition p | p.isKeyword(name)))
isParameterNode(p, callable, any(ParameterPosition pos | pos.isKeyword(name)))
|
c = getKeywordContent(name) or
// Important: do not include `HashSplatContent` here, as normal parameter matching is possible
exists(ConstantValue::ConstantSymbolValue key |
c.isSingleton(TKnownElementContent(key)) and
key.isSymbol(name)
)
or
c.isSingleton(TUnknownElementContent())
)
}
@@ -1015,13 +1025,16 @@ private module ParameterNodes {
final override Location getLocationImpl() { result = callable.getLocation() }
final override string toStringImpl() { result = "**kwargs" }
final override string toStringImpl() { result = "synthetic hash-splat parameter" }
}
/**
* A synthetic data-flow node to allow flow to positional parameters from a splat argument.
* A synthetic data-flow node to allow for flow into positional parameters from
* splat arguments.
*
* For example, in the following code:
* For all methods containing positional parameters, we construct a synthesized
* (hidden) parameter node to contain all positional arguments. This allows us
* to handle cases like
*
* ```rb
* def foo(x, y, z); end
@@ -1029,45 +1042,47 @@ private module ParameterNodes {
* foo(a, *[b, c])
* ```
*
* We want `b` to flow to `y` and `c` to flow to `z`. We do this by constructing
* a `SynthSplatParameterNode` for the method `foo`, and matching the splat argument to this
* parameter node via `parameterMatch/2`. We then add read steps from this node to parameters
* `y` and `z`, for content at indices 0 and 1 respectively (see `readStep`).
* by adding read steps out of the synthesized parameter node to the relevant
* positional parameters.
*
* This node stores the index of the splat argument it is matched to, which allows us to shift
* indices correctly when adding read steps. Without this, in the example above we would erroneously
* get a read step to `x` at index 0 and `y` at index 1 etc.
* In order to avoid redundancy (and improve performance) in cases like
*
* ```rb
* foo(a, b, c)
* ```
*
* where direct positional matching is possible, we use a special `SplatContent`
* (instead of reusing `KnownElementContent`) when we construct a synthesized
* splat argument (`SynthSplatArgumentNode`) at the call site, and then only
* add read steps out of this node for actual splat arguments (which will use
* `KnownElementContent` or `TSplatContent(_, true)`).
*
* We don't yet correctly handle cases where a positional argument follows the
* splat argument, e.g. in
*
* We don't yet correctly handle cases where a positional argument follows the splat argument, e.g. in
* ```rb
* foo(a, *[b], c)
* ```
*
* but this appears to be rare in practice.
*/
class SynthSplatParameterNode extends ParameterNodeImpl, TSynthSplatParameterNode {
private DataFlowCallable callable;
SynthSplatParameterNode() { this = TSynthSplatParameterNode(callable) }
/**
* Gets a parameter which will contain the value given by `c`.
* For example, if the synth splat parameter is for the following method and method call:
*
* ```rb
* def foo(x, y, a:, *rest); end
*
* foo(arg1, *args)
* ```
*
* then `getAParameter(element 0) = y`.
*/
ParameterNode getAParameter(ContentSet c) {
/** Holds if a read-step should be added into parameter `p`. */
predicate readInto(ParameterNode p, ContentSet c) {
exists(int n |
isParameterNode(result, callable, (any(ParameterPosition p | p.isPositional(n)))) and
(
c = getPositionalContent(n)
or
c.isSingleton(TUnknownElementContent())
)
isParameterNode(p, callable, any(ParameterPosition pos | pos.isPositional(n))) and
not exists(int i | splatParameterAt(callable.asCallable(), i) and i < n)
|
// Important: do not include `TSplatContent(_, false)` here, as normal parameter matching is possible
c = getSplatContent(n, true)
or
c = getArrayContent(n)
or
c.isSingleton(TUnknownElementContent())
)
}
@@ -1083,28 +1098,50 @@ private module ParameterNodes {
final override Location getLocationImpl() { result = callable.getLocation() }
final override string toStringImpl() { result = "synthetic *args" }
final override string toStringImpl() { result = "synthetic splat parameter" }
}
/**
* A node that holds the content of a specific positional argument.
* See `SynthSplatArgumentNode` for more information.
* A data-flow node that holds data from values inside the synthetic splat parameter,
* which need to have their indices shifted before being passed onto real splat
* parameters.
*
* For example, in
*
* ```rb
* def foo(a, b, *rest); end
* ```
*
* the elements of the synthetic splat parameter (`SynthSplatParameterNode`) need to
* have their indices shifted by `2` before being passed into `rest`.
*/
class SynthSplatParameterElementNode extends NodeImpl, TSynthSplatParameterElementNode {
class SynthSplatParameterShiftNode extends NodeImpl, TSynthSplatParameterShiftNode {
private DataFlowCallable callable;
private int splatPos;
private int pos;
SynthSplatParameterElementNode() { this = TSynthSplatParameterElementNode(callable, pos) }
SynthSplatParameterShiftNode() { this = TSynthSplatParameterShiftNode(callable, splatPos, pos) }
pragma[nomagic]
NormalParameterNode getSplatParameterNode(int splatPos) {
result
.isParameterOf(this.getEnclosingCallable(), any(ParameterPosition p | p.isSplat(splatPos)))
/**
* Holds if a read-step should be added from synthetic splat parameter `synthSplat`
* into this node.
*/
predicate readFrom(SynthSplatParameterNode synthSplat, ContentSet cs) {
synthSplat.isParameterOf(callable, _) and
(
cs = getSplatContent(pos + splatPos, _)
or
cs = getArrayContent(pos + splatPos)
)
}
int getStorePosition() { result = pos }
int getReadPosition() { result = pos }
/**
* Holds if a store-step should be added from this node into splat parameter `splat`.
*/
predicate storeInto(NormalParameterNode splat, ContentSet cs) {
splat.isParameterOf(callable, any(ParameterPosition p | p.isSplat(splatPos))) and
cs = getArrayContent(pos)
}
final override CfgScope getCfgScope() { result = callable.asCallable() }
@@ -1112,7 +1149,9 @@ private module ParameterNodes {
final override Location getLocationImpl() { result = callable.getLocation() }
final override string toStringImpl() { result = "synthetic *args[" + pos + "]" }
final override string toStringImpl() {
result = "synthetic splat parameter shift [" + pos + "]"
}
}
/** A parameter for a library callable with a flow summary. */
@@ -1211,104 +1250,189 @@ module ArgumentNodes {
}
}
abstract class SynthHashSplatOrSplatArgumentNode extends ArgumentNode, NodeImpl {
CfgNodes::ExprNodes::CallCfgNode call_;
final string getMethodName() {
result = call_.(CfgNodes::ExprNodes::MethodCallCfgNode).getMethodName()
or
not call_ instanceof CfgNodes::ExprNodes::MethodCallCfgNode and
result = call_.getExpr().getEnclosingMethod().getName() + "_yield"
}
final override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
this.sourceArgumentOf(call.asCall(), pos)
}
final override CfgScope getCfgScope() { result = call_.getExpr().getCfgScope() }
final override Location getLocationImpl() { result = call_.getLocation() }
}
/**
* A data-flow node that represents all keyword arguments wrapped in a hash.
*
* The callee is responsible for filtering out the keyword arguments that are
* part of the method signature, such that those cannot end up in the hash-splat
* parameter.
* parameter. See also `SynthHashSplatParameterNode`.
*/
class SynthHashSplatArgumentNode extends ArgumentNode, NodeImpl, TSynthHashSplatArgumentNode {
CfgNodes::ExprNodes::CallCfgNode c;
class SynthHashSplatArgumentNode extends SynthHashSplatOrSplatArgumentNode,
TSynthHashSplatArgumentNode
{
SynthHashSplatArgumentNode() { this = TSynthHashSplatArgumentNode(call_) }
SynthHashSplatArgumentNode() { this = TSynthHashSplatArgumentNode(c) }
/**
* Holds if a store-step should be added from argument `arg` into this synthetic
* hash-splat argument.
*/
predicate storeFrom(Node arg, ContentSet c) {
exists(ConstantValue cv |
if call_ instanceof CfgNodes::ExprNodes::HashLiteralCfgNode
then
/*
* Needed for cases like
*
* ```rb
* hash = { a: taint, b: safe }
*
* def foo(a:, b:)
* sink(a)
* end
*
* foo(**hash)
* ```
*/
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
this.sourceArgumentOf(call.asCall(), pos)
c.isSingleton(TKnownElementContent(cv))
else c.isSingleton(THashSplatContent(cv))
|
// symbol key
exists(ArgumentPosition keywordPos, string name |
arg.asExpr().(Argument).isArgumentOf(call_, keywordPos) and
keywordPos.isKeyword(name) and
cv.isSymbol(name)
)
or
// non-symbol key
exists(CfgNodes::ExprNodes::PairCfgNode pair, CfgNodes::ExprCfgNode key |
arg.asExpr() = pair.getValue() and
pair = call_.getAnArgument() and
key = pair.getKey() and
cv = key.getConstantValue() and
not cv.isSymbol(_)
)
)
}
override predicate sourceArgumentOf(CfgNodes::ExprNodes::CallCfgNode call, ArgumentPosition pos) {
call = c and
pos.isHashSplat()
call = call_ and
pos.isSynthHashSplat()
}
override CfgScope getCfgScope() { result = c.getExpr().getCfgScope() }
override Location getLocationImpl() { result = c.getLocation() }
override string toStringImpl() { result = "**" }
override string toStringImpl() { result = "synthetic hash-splat argument" }
}
/**
* A data-flow node that represents all arguments passed to the call.
* We use this to model data flow via splat parameters.
* Consider this example:
* A data-flow node that represents all positional arguments wrapped in an array.
*
* ```rb
* def foo(x, y, *z)
* end
*
* foo(1, 2, 3, 4)
* ```
*
* 1. We want `3` to flow to `z[0]` and `4` to flow to `z[1]`. We model this by first storing all arguments
* in a synthetic argument node `SynthSplatArgumentNode` (see `storeStepCommon`).
* 2. We match this to an analogous parameter node `SynthSplatParameterNode` on the callee side
* (see `parameterMatch`).
* 3. For each content element stored in the `SynthSplatParameterNode`, we add a read step to a separate
* `SynthSplatParameterElementNode`, which is parameterized by the element index (see `readStep`).
* 4. Finally, we add store steps from these `SynthSplatParameterElementNode`s to the real splat parameter node
* (see `storeStep`).
* We only add store steps for elements that will not flow to the earlier positional parameters.
* In practice that means we ignore elements at index `<= N`, where `N` is the index of the splat parameter.
* For the remaining elements we subtract `N` from their index and store them in the splat parameter.
* The callee is responsible for filtering out the positional arguments that are
* part of the method signature, such that those cannot end up in the splat
* parameter. See also `SynthSplatParameterNode`.
*/
class SynthSplatArgumentNode extends ArgumentNode, NodeImpl, TSynthSplatArgumentNode {
CfgNodes::ExprNodes::CallCfgNode c;
class SynthSplatArgumentNode extends SynthHashSplatOrSplatArgumentNode, TSynthSplatArgumentNode {
SynthSplatArgumentNode() { this = TSynthSplatArgumentNode(call_) }
SynthSplatArgumentNode() { this = TSynthSplatArgumentNode(c) }
/**
* Holds if a store-step should be added from argument `arg` into this synthetic
* splat argument.
*/
predicate storeFrom(Node arg, ContentSet c) {
exists(ArgumentPosition pos, int n |
arg.asExpr().(Argument).isArgumentOf(call_, pos) and
pos.isPositional(n) and
not exists(int i | splatArgumentAt(call_, i) and i < n) and
if call_ instanceof CfgNodes::ExprNodes::ArrayLiteralCfgNode
then
/*
* Needed for cases like
*
* ```rb
* arr = [taint, safe]
*
* def foo(a, b)
* sink(a)
* end
*
* foo(*arr)
* ```
*/
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
this.sourceArgumentOf(call.asCall(), pos)
c = getArrayContent(n)
else c = getSplatContent(n, false)
)
}
override predicate sourceArgumentOf(CfgNodes::ExprNodes::CallCfgNode call, ArgumentPosition pos) {
call = c and
call = call_ and
pos.isSynthSplat()
}
override CfgScope getCfgScope() { result = c.getExpr().getCfgScope() }
override Location getLocationImpl() { result = c.getLocation() }
override string toStringImpl() { result = "*" }
override string toStringImpl() { result = "synthetic splat argument" }
}
/**
* A data-flow node that holds data from values inside splat arguments.
* A data-flow node that holds data from values inside splat arguments, which
* need to have their indices shifted.
*
* For example, in the following call
*
* ```rb
* foo(1, 2, *[3, 4])
* foo(a, b, *[c, d])
* ```
*
* We add read steps such that `3` flows into `SynthSplatArgumentElementNode(2)` and `4` flows into `SynthSplatArgumentElementNode(3)`.
* `c` and `d` need to have their indices shifted by `2`.
*/
class SynthSplatArgumentElementNode extends NodeImpl, TSynthSplatArgumentElementNode {
class SynthSplatArgumentShiftNode extends NodeImpl, TSynthSplatArgumentShiftNode {
CfgNodes::ExprNodes::CallCfgNode c;
int splatPos;
int n;
SynthSplatArgumentElementNode() { this = TSynthSplatArgumentElementNode(c, n) }
SynthSplatArgumentShiftNode() { this = TSynthSplatArgumentShiftNode(c, splatPos, n) }
CfgNodes::ExprNodes::CallCfgNode getCall() { result = c }
/**
* Holds if a read-step should be added from splat argument `splatArg` into this node.
*/
predicate readFrom(Node splatArg, ContentSet cs) {
splatArg.asExpr().(Argument).isArgumentOf(c, any(ArgumentPosition p | p.isSplat(splatPos))) and
(
cs = getSplatContent(n - splatPos, _)
or
cs = getArrayContent(n - splatPos)
or
n = -1 and
cs.isSingleton(TUnknownElementContent())
)
}
int getPosition() { result = n }
/**
* Holds if a store-step should be added from this node into synthetic splat
* argument `synthSplat`.
*/
predicate storeInto(SynthSplatArgumentNode synthSplat, ContentSet cs) {
synthSplat = TSynthSplatArgumentNode(c) and
(
cs = getSplatContent(n, true)
or
n = -1 and
cs.isSingleton(TUnknownElementContent())
)
}
override CfgScope getCfgScope() { result = c.getExpr().getCfgScope() }
override Location getLocationImpl() { result = c.getLocation() }
override string toStringImpl() { result = "*[" + n + "]" }
override string toStringImpl() { result = "synthetic splat argument shift [" + n + "]" }
}
}
@@ -1502,78 +1626,24 @@ predicate jumpStep(Node pred, Node succ) {
any(AdditionalJumpStep s).step(pred, succ)
}
private ContentSet getKeywordContent(string name) {
exists(ConstantValue::ConstantSymbolValue key |
result.isSingleton(TKnownElementContent(key)) and
key.isSymbol(name)
)
}
ContentSet getPositionalContent(int n) {
private ContentSet getArrayContent(int n) {
exists(ConstantValue::ConstantIntegerValue i |
result.isSingleton(TKnownElementContent(i)) and
i.isInt(n)
)
}
private ContentSet getSplatContent(int n, boolean adjusted) {
result.isSingleton(TSplatContent(n, adjusted))
}
/**
* Subset of `storeStep` that should be shared with type-tracking.
*/
predicate storeStepCommon(Node node1, ContentSet c, Node node2) {
// Wrap all key-value arguments in a synthesized hash-splat argument node
exists(CfgNodes::ExprNodes::CallCfgNode call | node2 = TSynthHashSplatArgumentNode(call) |
// symbol key
exists(ArgumentPosition keywordPos, string name |
node1.asExpr().(Argument).isArgumentOf(call, keywordPos) and
keywordPos.isKeyword(name) and
c = getKeywordContent(name)
)
or
// non-symbol key
exists(CfgNodes::ExprNodes::PairCfgNode pair, CfgNodes::ExprCfgNode key, ConstantValue cv |
node1.asExpr() = pair.getValue() and
pair = call.getAnArgument() and
key = pair.getKey() and
cv = key.getConstantValue() and
not cv.isSymbol(_) and
c.isSingleton(TKnownElementContent(cv))
)
)
node2.(SynthHashSplatArgumentNode).storeFrom(node1, c)
or
// Wrap all positional arguments in a synthesized splat argument node
exists(CfgNodes::ExprNodes::CallCfgNode call, ArgumentPosition pos |
node2 = TSynthSplatArgumentNode(call) and
node1.asExpr().(Argument).isArgumentOf(call, pos)
|
exists(int n | pos.isPositional(n) and c = getPositionalContent(n))
)
}
/**
* Holds if data can flow from a `SynthSplatArgumentElementNode` into a `SynthSplatArgumentNode` via a store step.
* For example in
*
* ```rb
* foo(1, 2, *[3, 4])
* ```
*
* We have flow from `3` into `SynthSplatArgumentElementNode(2)`. This step stores the value from this node into element `2` of the `SynthSplatArgumentNode`.
*
* This allows us to match values inside splat arguments to the correct parameter in the callable.
*/
predicate synthSplatArgumentElementStoreStep(
SynthSplatArgumentElementNode node1, ContentSet c, SynthSplatArgumentNode node2
) {
exists(CfgNodes::ExprNodes::CallCfgNode call, int n |
node2 = TSynthSplatArgumentNode(call) and
node1 = TSynthSplatArgumentElementNode(call, n) and
(
c = getPositionalContent(n)
or
n = -1 and
c.isSingleton(TUnknownElementContent())
)
)
node2.(SynthSplatArgumentNode).storeFrom(node1, c)
}
/**
@@ -1607,13 +1677,9 @@ predicate storeStep(Node node1, ContentSet c, Node node2) {
FlowSummaryImpl::Private::Steps::summaryStoreStep(node1.(FlowSummaryNode).getSummaryNode(), c,
node2.(FlowSummaryNode).getSummaryNode())
or
exists(SynthSplatParameterElementNode elemNode, int splatPos |
node1 = elemNode and
node2 = elemNode.getSplatParameterNode(splatPos) and
c = getPositionalContent(elemNode.getStorePosition() - splatPos)
)
node1.(SynthSplatParameterShiftNode).storeInto(node2, c)
or
synthSplatArgumentElementStoreStep(node1, c, node2)
node1.(SynthSplatArgumentShiftNode).storeInto(node2, c)
or
storeStepCommon(node1, c, node2)
or
@@ -1625,37 +1691,9 @@ predicate storeStep(Node node1, ContentSet c, Node node2) {
* Subset of `readStep` that should be shared with type-tracking.
*/
predicate readStepCommon(Node node1, ContentSet c, Node node2) {
node2 = node1.(SynthHashSplatParameterNode).getAKeywordParameter(c)
node1.(SynthHashSplatParameterNode).readInto(node2, c)
or
node2 = node1.(SynthSplatParameterNode).getAParameter(c)
}
/**
* Holds if data can flow from a splat argument to a `SynthSplatArgumentElementNode` via a read step.
* For example in
* ```rb
* foo(x, y, *[1, 2])
* ```
*
* we read `1` into `SynthSplatArgumentElementNode(2)` and `2` into `SynthSplatArgumentElementNode(3)`.
*/
predicate synthSplatArgumentElementReadStep(
Node node1, ContentSet c, SynthSplatArgumentElementNode node2
) {
exists(int splatPos, CfgNodes::ExprNodes::CallCfgNode call |
node1.asExpr().(Argument).isArgumentOf(call, any(ArgumentPosition p | p.isSplat(splatPos))) and
splatPos > 0 and
node2.getCall() = call and
(
exists(int n |
node2.getPosition() = n + splatPos and
c = getPositionalContent(n)
)
or
node2.getPosition() = -1 and
c.isSingleton(TUnknownElementContent())
)
)
node1.(SynthSplatParameterNode).readInto(node2, c)
}
/**
@@ -1690,14 +1728,9 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
or
VariableCapture::readStep(node1, any(Content::CapturedVariableContent v | c.isSingleton(v)), node2)
or
// Read from SynthSplatParameterNode into SynthSplatParameterElementNode
node2 =
any(SynthSplatParameterElementNode e |
node1.(SynthSplatParameterNode).isParameterOf(e.getEnclosingCallable(), _) and
c = getPositionalContent(e.getReadPosition())
)
node2.(SynthSplatParameterShiftNode).readFrom(node1, c)
or
synthSplatArgumentElementReadStep(node1, c, node2)
node2.(SynthSplatArgumentShiftNode).readFrom(node1, c)
or
readStepCommon(node1, c, node2)
}
@@ -1714,13 +1747,14 @@ predicate clearsContent(Node n, ContentSet c) {
// the hash-splat parameter
exists(
DataFlowCallable callable, HashSplatParameter hashSplatParam, ParameterNodeImpl keywordParam,
ParameterPosition keywordPos, string name
ParameterPosition keywordPos, ConstantValue::ConstantSymbolValue cv, string name
|
n = TNormalParameterNode(hashSplatParam) and
callable.asCallable() = hashSplatParam.getCallable() and
keywordParam.isParameterOf(callable, keywordPos) and
keywordPos.isKeyword(name) and
c = getKeywordContent(name)
c.isKnownOrUnknownElement(TKnownElementContent(cv)) and
cv.isSymbol(name)
)
}
@@ -1734,6 +1768,16 @@ predicate expectsContent(Node n, ContentSet c) {
private newtype TDataFlowType =
TLambdaDataFlowType(Callable c) { c = any(LambdaSelfReferenceNode n).getCallable() } or
// In order to reduce the set of cons-candidates, we annotate all implicit (hash) splat
// creations with the name of the method that they are passed into. This includes
// array/hash literals as well (where the name is simply `[]`), because of how they
// are modeled (see `Array.qll` and `Hash.qll`).
TSynthHashSplatArgumentType(string methodName) {
methodName = any(SynthHashSplatArgumentNode n).getMethodName()
} or
TSynthSplatArgumentType(string methodName) {
methodName = any(SynthSplatArgumentNode n).getMethodName()
} or
TUnknownDataFlowType()
class DataFlowType extends TDataFlowType {
@@ -1741,12 +1785,14 @@ class DataFlowType extends TDataFlowType {
}
predicate typeStrongerThan(DataFlowType t1, DataFlowType t2) {
t1 = TLambdaDataFlowType(_) and
t1 != TUnknownDataFlowType() and
t2 = TUnknownDataFlowType()
}
private predicate mustHaveLambdaType(CfgNodes::ExprCfgNode e, Callable c) {
exists(VariableCapture::ClosureExpr ce | ce.hasBody(c) |
private predicate mustHaveLambdaType(ExprNode n, Callable c) {
exists(VariableCapture::ClosureExpr ce, CfgNodes::ExprCfgNode e |
e = n.asExpr() and ce.hasBody(c)
|
e = ce or
ce.hasAliasedAccess(e)
)
@@ -1759,12 +1805,17 @@ DataFlowType getNodeType(Node n) {
result = TLambdaDataFlowType(n.(LambdaSelfReferenceNode).getCallable())
or
exists(Callable c |
mustHaveLambdaType(n.asExpr(), c) and
mustHaveLambdaType(n, c) and
result = TLambdaDataFlowType(c)
)
or
result = TSynthHashSplatArgumentType(n.(SynthHashSplatArgumentNode).getMethodName())
or
result = TSynthSplatArgumentType(n.(SynthSplatArgumentNode).getMethodName())
or
not n instanceof LambdaSelfReferenceNode and
not mustHaveLambdaType(n.asExpr(), _) and
not mustHaveLambdaType(n, _) and
not n instanceof SynthHashSplatOrSplatArgumentNode and
result = TUnknownDataFlowType()
}
@@ -1773,7 +1824,7 @@ string ppReprType(DataFlowType t) { none() }
pragma[inline]
private predicate compatibleTypesNonSymRefl(DataFlowType t1, DataFlowType t2) {
t1 = TLambdaDataFlowType(_) and
t1 != TUnknownDataFlowType() and
t2 = TUnknownDataFlowType()
}
@@ -1975,6 +2026,17 @@ class ContentApprox extends TContentApprox {
result = "approximated element " + approx
)
or
exists(boolean shifted, string s |
this = TSplatContentApprox(shifted) and
(if shifted = true then s = " (shifted)" else s = "") and
result = "approximated splat position" + s
)
or
exists(string s |
this = THashSplatContentApprox(s) and
result = "approximated hash-splat position " + s
)
or
exists(Content c |
this = TNonElementContentApprox(c) and
result = c.toString()
@@ -1988,9 +2050,9 @@ class ContentApprox extends TContentApprox {
* We take two characters from the serialized index as the projection,
* since for symbols this will include the first character.
*/
private string approxKnownElementIndex(Content::KnownElementContent c) {
not c.getIndex().isInt(_) and
exists(string s | s = c.getIndex().serialize() |
private string approxKnownElementIndex(ConstantValue cv) {
not cv.isInt(_) and
exists(string s | s = cv.serialize() |
s.length() < 2 and
result = s
or
@@ -2011,7 +2073,15 @@ ContentApprox getContentApprox(Content c) {
c.(Content::KnownElementContent).getIndex().isInt(_) and
result = TKnownIntegerElementContentApprox()
or
result = TKnownElementContentApprox(approxKnownElementIndex(c))
result =
TKnownElementContentApprox(approxKnownElementIndex(c.(Content::KnownElementContent).getIndex()))
or
exists(boolean shifted |
c = TSplatContent(_, shifted) and
result = TSplatContentApprox(shifted)
)
or
result = THashSplatContentApprox(approxKnownElementIndex(c.(Content::HashSplatContent).getKey()))
or
result = TNonElementContentApprox(c)
}

View File

@@ -549,6 +549,73 @@ module Content {
result = getElementContent(e.getConstantValue()).(KnownElementContent).getIndex()
}
/**
* INTERNAL: Do not use.
*
* An element inside a synthetic splat argument. All positional arguments
* (including splat arguments) are implicitly stored inside a synthetic
* splat argument. For example, in
*
* ```rb
* foo(1, 2, 3)
* ```
*
* we have an implicit splat argument containing `[1, 2, 3]`.
*/
class SplatContent extends ElementContent, TSplatContent {
private int i;
private boolean shifted;
SplatContent() { this = TSplatContent(i, shifted) }
/** Gets the position of this splat element. */
int getPosition() { result = i }
/**
* Holds if this element represents a value from an actual splat argument
* that had its index shifted. For example, in
*
* ```rb
* foo(x, *args)
* ```
*
* the elements of `args` will have their index shifted by 1 before being
* put into the synthetic splat argument.
*/
predicate isShifted() { shifted = true }
override string toString() {
exists(string s |
(if this.isShifted() then s = " (shifted)" else s = "") and
result = "splat position " + i + s
)
}
}
/**
* INTERNAL: Do not use.
*
* An element inside a synthetic hash-splat argument. All keyword arguments
* are implicitly stored inside a synthetic hash-splat argument. For example,
* in
*
* ```rb
* foo(a: 1, b: 2, c: 3)
* ```
*
* we have an implicit hash-splat argument containing `{:a => 1, :b => 2, :c => 3}`.
*/
class HashSplatContent extends ElementContent, THashSplatContent {
private ConstantValue cv;
HashSplatContent() { this = THashSplatContent(cv) }
/** Gets the hash key. */
ConstantValue getKey() { result = cv }
override string toString() { result = "hash-splat position " + cv }
}
/**
* A value stored behind a getter/setter pair.
*
@@ -705,6 +772,8 @@ class ContentSet extends TContentSet {
or
exists(Content::KnownElementContent c | this.isKnownOrUnknownElement(c) |
result = c or
result = TSplatContent(c.getIndex().getInt(), _) or
result = THashSplatContent(c.getIndex()) or
result = TUnknownElementContent()
)
or
@@ -712,7 +781,9 @@ class ContentSet extends TContentSet {
this = TElementLowerBoundContent(lower, includeUnknown)
|
exists(int i |
result.(Content::KnownElementContent).getIndex().isInt(i) and
result.(Content::KnownElementContent).getIndex().isInt(i) or
result = TSplatContent(i, _)
|
i >= lower
)
or
@@ -725,6 +796,11 @@ class ContentSet extends TContentSet {
|
type = result.(Content::KnownElementContent).getIndex().getValueType()
or
type = "int" and
result instanceof Content::SplatContent
or
type = result.(Content::HashSplatContent).getKey().getValueType()
or
includeUnknown = true and
result = TUnknownElementContent()
)

View File

@@ -128,6 +128,9 @@ SummaryComponent interpretComponentSpecific(AccessPathToken c) {
or
arg = "hash-splat" and
ppos.isHashSplat()
or
arg = "splat" and
ppos.isSplat(0)
)
or
result = interpretElementArg(c.getAnArgument("Element"))
@@ -229,6 +232,9 @@ string getParameterPosition(ParameterPosition pos) {
or
pos.isHashSplat() and
result = "hash-splat"
or
pos.isSplat(0) and
result = "splat"
}
/** Gets the textual representation of an argument position in the format used for flow summaries. */

View File

@@ -47,11 +47,11 @@ module Array {
override MethodCall getACallSimple() { result = getAStaticArrayCall("[]") }
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
exists(ArrayIndex i |
input = "Argument[" + i + "]" and
output = "ReturnValue.Element[" + i + "]" and
preservesValue = true
)
// we make use of the special `splat` argument kind, which contains all positional
// arguments wrapped in an implicit array, as well as explicit splat arguments
input = "Argument[splat]" and
output = "ReturnValue" and
preservesValue = true
}
}

View File

@@ -34,7 +34,7 @@ module Hash {
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
// we make use of the special `hash-splat` argument kind, which contains all keyword
// arguments wrapped in an implicit hash, as well as explicit hash splat arguments
input = "Argument[hash-splat].WithElement[any]" and
input = "Argument[hash-splat]" and
output = "ReturnValue" and
preservesValue = true
}

View File

@@ -333,16 +333,14 @@ predicate basicLoadStoreStep(
predicate readStoreStepIntoSourceNode(
Node nodeFrom, Node nodeTo, DataFlow::ContentSet loadContent, DataFlow::ContentSet storeContent
) {
exists(DataFlowPrivate::SynthSplatParameterElementNode mid |
nodeFrom.(DataFlowPrivate::SynthSplatParameterNode).isParameterOf(mid.getEnclosingCallable(), _) and
loadContent = DataFlowPrivate::getPositionalContent(mid.getReadPosition()) and
nodeTo = mid.getSplatParameterNode(_) and
storeContent = DataFlowPrivate::getPositionalContent(mid.getStorePosition())
exists(DataFlowPrivate::SynthSplatParameterShiftNode shift |
shift.readFrom(nodeFrom, loadContent) and
shift.storeInto(nodeTo, storeContent)
)
or
exists(DataFlowPrivate::SynthSplatArgumentElementNode mid |
DataFlowPrivate::synthSplatArgumentElementReadStep(nodeFrom, loadContent, mid) and
DataFlowPrivate::synthSplatArgumentElementStoreStep(mid, storeContent, nodeTo)
exists(DataFlowPrivate::SynthSplatArgumentShiftNode shift |
shift.readFrom(nodeFrom, loadContent) and
shift.storeInto(nodeTo, storeContent)
)
}

View File

@@ -1,6 +1,6 @@
WARNING: Type BarrierGuard has been deprecated and may be removed in future (barrier-guards.ql:10,3-15)
failures
testFailures
failures
oldStyleBarrierGuards
| barrier-guards.rb:3:4:3:15 | ... == ... | barrier-guards.rb:4:5:4:7 | foo | barrier-guards.rb:3:4:3:6 | foo | true |
| barrier-guards.rb:3:4:3:15 | ... == ... | barrier-guards.rb:4:5:4:7 | foo | barrier-guards.rb:3:11:3:15 | "foo" | true |

View File

@@ -203,24 +203,24 @@ private class S16 extends Summary {
}
/**
* `Argument[hash-splat]` (output) 1
* `Argument[splat]` (input) 1
*/
private class S17 extends Summary {
S17() { this = "s17" }
override predicate propagates(string input, string output) {
input = "Argument[0]" and output = "Argument[hash-splat]"
input = "Argument[splat]" and output = "ReturnValue"
}
}
/**
* `Argument[hash-splat]` (output) 2
* `Argument[splat]` (input) 2
*/
private class S18 extends Summary {
S18() { this = "s18" }
override predicate propagates(string input, string output) {
input = "Argument[0]" and output = "Argument[hash-splat].Element[:foo]"
input = "Argument[splat].Element[any]" and output = "ReturnValue"
}
}

View File

@@ -103,11 +103,11 @@ def m14(w, x, y, z)
sink z # $ hasValueFlow=a
end
def m15
def m15
a = source "a"
b = source "b"
sink s15(**a) # $ SPURIOUS: hasTaintFlow=a MISSING: hasValueFlow=a
sink s15(0, 1, foo: b, **a) # $ SPURIOUS: hasTaintFlow=a MISSING: hasValueFlow=a
sink s15(foo: a, bar: b)[:foo] # $ hasValueFlow=a
sink s15(foo: a, bar: b)[:bar] # $ hasValueFlow=b
end
def m16
@@ -121,19 +121,20 @@ def m16
sink s16(b: b, **h) # $ hasValueFlow=a hasValueFlow=b
end
def m17(h, x)
def m17
a = source "a"
s17(a, **h, foo: x)
sink h # $ hasValueFlow=a
sink x
b = source "b"
sink s17(a, b) # $ hasTaintFlow=a $ hasTaintFlow=b
sink s17(a, b)[0] # $ hasValueFlow=a
sink s17(a, b)[1] # $ hasValueFlow=b
end
def m18(x)
def m18
a = source "a"
s18(a, **h, foo: x)
sink h
sink h[:foo] # $ MISSING: hasValueFlow=a
sink x # $ MISSING: hasValueFlow=a
b = source "b"
arr = [a, b]
sink s18(*arr) # $ hasValueFlow=a $ hasValueFlow=b
sink s18(a) # $ hasValueFlow=a
end
def m19(i)

View File

@@ -42,10 +42,10 @@ edges
| hash_flow.rb:44:10:44:13 | hash [element 0] | hash_flow.rb:44:10:44:16 | ...[...] |
| hash_flow.rb:46:10:46:13 | hash [element :a] | hash_flow.rb:46:10:46:17 | ...[...] |
| hash_flow.rb:48:10:48:13 | hash [element a] | hash_flow.rb:48:10:48:18 | ...[...] |
| hash_flow.rb:55:5:55:9 | hash1 [element :a] | hash_flow.rb:56:10:56:14 | hash1 [element :a] |
| hash_flow.rb:55:13:55:37 | ...[...] [element :a] | hash_flow.rb:55:5:55:9 | hash1 [element :a] |
| hash_flow.rb:55:21:55:30 | call to taint | hash_flow.rb:55:13:55:37 | ...[...] [element :a] |
| hash_flow.rb:56:10:56:14 | hash1 [element :a] | hash_flow.rb:56:10:56:18 | ...[...] |
| hash_flow.rb:55:5:55:9 | hash1 [hash-splat position :a] | hash_flow.rb:56:10:56:14 | hash1 [hash-splat position :a] |
| hash_flow.rb:55:13:55:37 | ...[...] [hash-splat position :a] | hash_flow.rb:55:5:55:9 | hash1 [hash-splat position :a] |
| hash_flow.rb:55:21:55:30 | call to taint | hash_flow.rb:55:13:55:37 | ...[...] [hash-splat position :a] |
| hash_flow.rb:56:10:56:14 | hash1 [hash-splat position :a] | hash_flow.rb:56:10:56:18 | ...[...] |
| hash_flow.rb:59:5:59:5 | x [element :a] | hash_flow.rb:60:18:60:18 | x [element :a] |
| hash_flow.rb:59:13:59:22 | call to taint | hash_flow.rb:59:5:59:5 | x [element :a] |
| hash_flow.rb:60:5:60:9 | hash2 [element :a] | hash_flow.rb:61:10:61:14 | hash2 [element :a] |
@@ -62,10 +62,10 @@ edges
| hash_flow.rb:68:13:68:39 | ...[...] [element :a] | hash_flow.rb:68:5:68:9 | hash4 [element :a] |
| hash_flow.rb:68:22:68:31 | call to taint | hash_flow.rb:68:13:68:39 | ...[...] [element :a] |
| hash_flow.rb:69:10:69:14 | hash4 [element :a] | hash_flow.rb:69:10:69:18 | ...[...] |
| hash_flow.rb:72:5:72:9 | hash5 [element a] | hash_flow.rb:73:10:73:14 | hash5 [element a] |
| hash_flow.rb:72:13:72:45 | ...[...] [element a] | hash_flow.rb:72:5:72:9 | hash5 [element a] |
| hash_flow.rb:72:25:72:34 | call to taint | hash_flow.rb:72:13:72:45 | ...[...] [element a] |
| hash_flow.rb:73:10:73:14 | hash5 [element a] | hash_flow.rb:73:10:73:19 | ...[...] |
| hash_flow.rb:72:5:72:9 | hash5 [hash-splat position a] | hash_flow.rb:73:10:73:14 | hash5 [hash-splat position a] |
| hash_flow.rb:72:13:72:45 | ...[...] [hash-splat position a] | hash_flow.rb:72:5:72:9 | hash5 [hash-splat position a] |
| hash_flow.rb:72:25:72:34 | call to taint | hash_flow.rb:72:13:72:45 | ...[...] [hash-splat position a] |
| hash_flow.rb:73:10:73:14 | hash5 [hash-splat position a] | hash_flow.rb:73:10:73:19 | ...[...] |
| hash_flow.rb:76:5:76:9 | hash6 [element a] | hash_flow.rb:77:10:77:14 | hash6 [element a] |
| hash_flow.rb:76:13:76:47 | ...[...] [element a] | hash_flow.rb:76:5:76:9 | hash6 [element a] |
| hash_flow.rb:76:26:76:35 | call to taint | hash_flow.rb:76:13:76:47 | ...[...] [element a] |
@@ -1015,10 +1015,10 @@ nodes
| hash_flow.rb:46:10:46:17 | ...[...] | semmle.label | ...[...] |
| hash_flow.rb:48:10:48:13 | hash [element a] | semmle.label | hash [element a] |
| hash_flow.rb:48:10:48:18 | ...[...] | semmle.label | ...[...] |
| hash_flow.rb:55:5:55:9 | hash1 [element :a] | semmle.label | hash1 [element :a] |
| hash_flow.rb:55:13:55:37 | ...[...] [element :a] | semmle.label | ...[...] [element :a] |
| hash_flow.rb:55:5:55:9 | hash1 [hash-splat position :a] | semmle.label | hash1 [hash-splat position :a] |
| hash_flow.rb:55:13:55:37 | ...[...] [hash-splat position :a] | semmle.label | ...[...] [hash-splat position :a] |
| hash_flow.rb:55:21:55:30 | call to taint | semmle.label | call to taint |
| hash_flow.rb:56:10:56:14 | hash1 [element :a] | semmle.label | hash1 [element :a] |
| hash_flow.rb:56:10:56:14 | hash1 [hash-splat position :a] | semmle.label | hash1 [hash-splat position :a] |
| hash_flow.rb:56:10:56:18 | ...[...] | semmle.label | ...[...] |
| hash_flow.rb:59:5:59:5 | x [element :a] | semmle.label | x [element :a] |
| hash_flow.rb:59:13:59:22 | call to taint | semmle.label | call to taint |
@@ -1039,10 +1039,10 @@ nodes
| hash_flow.rb:68:22:68:31 | call to taint | semmle.label | call to taint |
| hash_flow.rb:69:10:69:14 | hash4 [element :a] | semmle.label | hash4 [element :a] |
| hash_flow.rb:69:10:69:18 | ...[...] | semmle.label | ...[...] |
| hash_flow.rb:72:5:72:9 | hash5 [element a] | semmle.label | hash5 [element a] |
| hash_flow.rb:72:13:72:45 | ...[...] [element a] | semmle.label | ...[...] [element a] |
| hash_flow.rb:72:5:72:9 | hash5 [hash-splat position a] | semmle.label | hash5 [hash-splat position a] |
| hash_flow.rb:72:13:72:45 | ...[...] [hash-splat position a] | semmle.label | ...[...] [hash-splat position a] |
| hash_flow.rb:72:25:72:34 | call to taint | semmle.label | call to taint |
| hash_flow.rb:73:10:73:14 | hash5 [element a] | semmle.label | hash5 [element a] |
| hash_flow.rb:73:10:73:14 | hash5 [hash-splat position a] | semmle.label | hash5 [hash-splat position a] |
| hash_flow.rb:73:10:73:19 | ...[...] | semmle.label | ...[...] |
| hash_flow.rb:76:5:76:9 | hash6 [element a] | semmle.label | hash6 [element a] |
| hash_flow.rb:76:13:76:47 | ...[...] [element a] | semmle.label | ...[...] [element a] |

View File

@@ -1,4 +1,3 @@
failures
testFailures
| hash_flow.rb:65:21:65:40 | # $ hasValueFlow=3.3 | Missing result:hasValueFlow=3.3 |
| hash_flow.rb:66:21:66:49 | # $ SPURIOUS hasValueFlow=3.3 | Missing result:hasValueFlow=3.3 |
@@ -39,3 +38,4 @@ testFailures
| hash_flow.rb:935:22:935:42 | # $ hasValueFlow=51.4 | Missing result:hasValueFlow=51.4 |
| hash_flow.rb:963:22:963:42 | # $ hasValueFlow=52.3 | Missing result:hasValueFlow=52.3 |
| hash_flow.rb:965:22:965:42 | # $ hasValueFlow=52.4 | Missing result:hasValueFlow=52.4 |
failures

View File

@@ -2425,6 +2425,7 @@
| local_dataflow.rb:9:1:9:5 | array | local_dataflow.rb:10:14:10:18 | array |
| local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:5 | array |
| local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:15 | ... = ... |
| local_dataflow.rb:9:9:9:15 | synthetic splat argument | local_dataflow.rb:9:9:9:15 | call to [] |
| local_dataflow.rb:10:5:13:3 | ... | local_dataflow.rb:10:1:13:3 | ... = ... |
| local_dataflow.rb:10:5:13:3 | <captured entry> self | local_dataflow.rb:11:1:11:2 | self |
| local_dataflow.rb:10:5:13:3 | <captured exit> x | local_dataflow.rb:15:5:15:5 | x |
@@ -2487,6 +2488,7 @@
| local_dataflow.rb:50:18:50:18 | [post] x | local_dataflow.rb:51:20:51:20 | x |
| local_dataflow.rb:50:18:50:18 | x | local_dataflow.rb:51:20:51:20 | x |
| local_dataflow.rb:51:9:51:15 | "break" | local_dataflow.rb:51:3:51:15 | break |
| local_dataflow.rb:55:5:55:13 | synthetic splat argument | local_dataflow.rb:55:5:55:13 | call to [] |
| local_dataflow.rb:60:1:90:3 | self (test_case) | local_dataflow.rb:78:12:78:20 | self |
| local_dataflow.rb:60:1:90:3 | self in test_case | local_dataflow.rb:60:1:90:3 | self (test_case) |
| local_dataflow.rb:60:15:60:15 | x | local_dataflow.rb:60:15:60:15 | x |
@@ -2545,6 +2547,7 @@
| local_dataflow.rb:81:16:81:16 | e | local_dataflow.rb:84:12:84:12 | e |
| local_dataflow.rb:81:20:84:33 | then ... | local_dataflow.rb:78:7:88:5 | case ... |
| local_dataflow.rb:81:25:84:14 | call to [] | local_dataflow.rb:81:20:84:33 | then ... |
| local_dataflow.rb:81:25:84:14 | synthetic splat argument | local_dataflow.rb:81:25:84:14 | call to [] |
| local_dataflow.rb:82:7:82:13 | [post] self | local_dataflow.rb:83:7:83:13 | self |
| local_dataflow.rb:82:7:82:13 | self | local_dataflow.rb:83:7:83:13 | self |
| local_dataflow.rb:83:7:83:13 | [post] self | local_dataflow.rb:84:7:84:13 | self |

File diff suppressed because it is too large Load Diff

View File

@@ -2796,7 +2796,7 @@
| UseUseExplosion.rb:21:3675:21:3680 | call to use | UseUseExplosion.rb:21:3670:21:3680 | else ... |
| UseUseExplosion.rb:21:3686:21:3696 | else ... | UseUseExplosion.rb:21:9:21:3700 | if ... |
| UseUseExplosion.rb:21:3691:21:3696 | call to use | UseUseExplosion.rb:21:3686:21:3696 | else ... |
| UseUseExplosion.rb:24:5:25:7 | synthetic *args | UseUseExplosion.rb:24:13:24:13 | i |
| UseUseExplosion.rb:24:5:25:7 | synthetic splat parameter | UseUseExplosion.rb:24:13:24:13 | i |
| UseUseExplosion.rb:24:5:25:7 | use | UseUseExplosion.rb:1:1:26:3 | C |
| file://:0:0:0:0 | [summary param] position 0 in & | file://:0:0:0:0 | [summary] read: Argument[0].Element[any] in & |
| file://:0:0:0:0 | [summary param] position 0 in + | file://:0:0:0:0 | [summary] read: Argument[0].Element[any] in + |
@@ -2841,7 +2841,7 @@
| file://:0:0:0:0 | [summary] read: Argument[0].Element[any] in Hash[] | file://:0:0:0:0 | [summary] read: Argument[0].Element[any].Element[1] in Hash[] |
| local_dataflow.rb:1:1:7:3 | self (foo) | local_dataflow.rb:3:8:3:10 | self |
| local_dataflow.rb:1:1:7:3 | self in foo | local_dataflow.rb:1:1:7:3 | self (foo) |
| local_dataflow.rb:1:1:7:3 | synthetic *args | local_dataflow.rb:1:9:1:9 | a |
| local_dataflow.rb:1:1:7:3 | synthetic splat parameter | local_dataflow.rb:1:9:1:9 | a |
| local_dataflow.rb:1:1:150:3 | <uninitialized> | local_dataflow.rb:10:9:10:9 | x |
| local_dataflow.rb:1:1:150:3 | self (local_dataflow.rb) | local_dataflow.rb:49:1:53:3 | self |
| local_dataflow.rb:1:9:1:9 | a | local_dataflow.rb:1:9:1:9 | a |
@@ -2871,6 +2871,7 @@
| local_dataflow.rb:9:9:9:15 | Array | local_dataflow.rb:9:9:9:15 | call to [] |
| local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:5 | array |
| local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:15 | ... = ... |
| local_dataflow.rb:9:9:9:15 | synthetic splat argument | local_dataflow.rb:9:9:9:15 | call to [] |
| local_dataflow.rb:10:5:13:3 | ... | local_dataflow.rb:10:1:13:3 | ... = ... |
| local_dataflow.rb:10:5:13:3 | <captured entry> self | local_dataflow.rb:11:1:11:2 | self |
| local_dataflow.rb:10:5:13:3 | <captured exit> x | local_dataflow.rb:15:5:15:5 | x |
@@ -2879,7 +2880,7 @@
| local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | __synth__0__1 |
| local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:9:10:9 | x |
| local_dataflow.rb:10:5:13:3 | call to each | local_dataflow.rb:10:5:13:3 | ... |
| local_dataflow.rb:10:5:13:3 | synthetic *args | local_dataflow.rb:10:5:13:3 | __synth__0__1 |
| local_dataflow.rb:10:5:13:3 | synthetic splat parameter | local_dataflow.rb:10:5:13:3 | __synth__0__1 |
| local_dataflow.rb:10:9:10:9 | ... = ... | local_dataflow.rb:10:9:10:9 | if ... |
| local_dataflow.rb:10:9:10:9 | defined? ... | local_dataflow.rb:10:9:10:9 | [false] ! ... |
| local_dataflow.rb:10:9:10:9 | defined? ... | local_dataflow.rb:10:9:10:9 | [true] ! ... |
@@ -2898,7 +2899,7 @@
| local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:1:17:3 | __synth__0__1 |
| local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:5:15:5 | x |
| local_dataflow.rb:15:1:17:3 | call to each | local_dataflow.rb:15:1:17:3 | ... |
| local_dataflow.rb:15:1:17:3 | synthetic *args | local_dataflow.rb:15:1:17:3 | __synth__0__1 |
| local_dataflow.rb:15:1:17:3 | synthetic splat parameter | local_dataflow.rb:15:1:17:3 | __synth__0__1 |
| local_dataflow.rb:15:5:15:5 | ... = ... | local_dataflow.rb:15:5:15:5 | if ... |
| local_dataflow.rb:15:5:15:5 | defined? ... | local_dataflow.rb:15:5:15:5 | [false] ! ... |
| local_dataflow.rb:15:5:15:5 | defined? ... | local_dataflow.rb:15:5:15:5 | [true] ! ... |
@@ -2914,7 +2915,7 @@
| local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:1:21:3 | __synth__0__1 |
| local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:5:19:5 | x |
| local_dataflow.rb:19:1:21:3 | call to each | local_dataflow.rb:19:1:21:3 | ... |
| local_dataflow.rb:19:1:21:3 | synthetic *args | local_dataflow.rb:19:1:21:3 | __synth__0__1 |
| local_dataflow.rb:19:1:21:3 | synthetic splat parameter | local_dataflow.rb:19:1:21:3 | __synth__0__1 |
| local_dataflow.rb:19:5:19:5 | ... = ... | local_dataflow.rb:19:5:19:5 | if ... |
| local_dataflow.rb:19:5:19:5 | defined? ... | local_dataflow.rb:19:5:19:5 | [false] ! ... |
| local_dataflow.rb:19:5:19:5 | defined? ... | local_dataflow.rb:19:5:19:5 | [true] ! ... |
@@ -2933,13 +2934,13 @@
| local_dataflow.rb:30:14:30:20 | "class" | local_dataflow.rb:30:5:30:24 | C |
| local_dataflow.rb:32:5:32:25 | bar | local_dataflow.rb:32:1:32:1 | x |
| local_dataflow.rb:32:5:32:25 | bar | local_dataflow.rb:32:1:32:25 | ... = ... |
| local_dataflow.rb:34:1:39:3 | synthetic *args | local_dataflow.rb:34:7:34:7 | x |
| local_dataflow.rb:34:1:39:3 | synthetic splat parameter | local_dataflow.rb:34:7:34:7 | x |
| local_dataflow.rb:34:7:34:7 | x | local_dataflow.rb:34:7:34:7 | x |
| local_dataflow.rb:34:7:34:7 | x | local_dataflow.rb:35:6:35:6 | x |
| local_dataflow.rb:35:6:35:6 | x | local_dataflow.rb:35:6:35:11 | ... == ... |
| local_dataflow.rb:35:11:35:11 | 4 | local_dataflow.rb:35:6:35:11 | ... == ... |
| local_dataflow.rb:36:13:36:13 | 7 | local_dataflow.rb:36:6:36:13 | return |
| local_dataflow.rb:41:1:47:3 | synthetic *args | local_dataflow.rb:41:7:41:7 | x |
| local_dataflow.rb:41:1:47:3 | synthetic splat parameter | local_dataflow.rb:41:7:41:7 | x |
| local_dataflow.rb:41:7:41:7 | x | local_dataflow.rb:41:7:41:7 | x |
| local_dataflow.rb:41:7:41:7 | x | local_dataflow.rb:42:6:42:6 | x |
| local_dataflow.rb:42:6:42:6 | x | local_dataflow.rb:42:6:42:11 | ... == ... |
@@ -2958,10 +2959,11 @@
| local_dataflow.rb:51:20:51:20 | x | local_dataflow.rb:51:20:51:24 | ... < ... |
| local_dataflow.rb:51:24:51:24 | 9 | local_dataflow.rb:51:20:51:24 | ... < ... |
| local_dataflow.rb:55:5:55:13 | Array | local_dataflow.rb:55:5:55:13 | call to [] |
| local_dataflow.rb:57:1:58:3 | synthetic *args | local_dataflow.rb:57:9:57:9 | x |
| local_dataflow.rb:55:5:55:13 | synthetic splat argument | local_dataflow.rb:55:5:55:13 | call to [] |
| local_dataflow.rb:57:1:58:3 | synthetic splat parameter | local_dataflow.rb:57:9:57:9 | x |
| local_dataflow.rb:60:1:90:3 | self (test_case) | local_dataflow.rb:78:12:78:20 | self |
| local_dataflow.rb:60:1:90:3 | self in test_case | local_dataflow.rb:60:1:90:3 | self (test_case) |
| local_dataflow.rb:60:1:90:3 | synthetic *args | local_dataflow.rb:60:15:60:15 | x |
| local_dataflow.rb:60:1:90:3 | synthetic splat parameter | local_dataflow.rb:60:15:60:15 | x |
| local_dataflow.rb:60:15:60:15 | x | local_dataflow.rb:60:15:60:15 | x |
| local_dataflow.rb:60:15:60:15 | x | local_dataflow.rb:61:12:61:12 | x |
| local_dataflow.rb:61:7:68:5 | SSA phi read(x) | local_dataflow.rb:69:12:69:12 | x |
@@ -3029,6 +3031,7 @@
| local_dataflow.rb:81:20:84:33 | then ... | local_dataflow.rb:78:7:88:5 | case ... |
| local_dataflow.rb:81:25:84:14 | Array | local_dataflow.rb:81:25:84:14 | call to [] |
| local_dataflow.rb:81:25:84:14 | call to [] | local_dataflow.rb:81:20:84:33 | then ... |
| local_dataflow.rb:81:25:84:14 | synthetic splat argument | local_dataflow.rb:81:25:84:14 | call to [] |
| local_dataflow.rb:82:7:82:13 | [post] self | local_dataflow.rb:83:7:83:13 | self |
| local_dataflow.rb:82:7:82:13 | self | local_dataflow.rb:83:7:83:13 | self |
| local_dataflow.rb:83:7:83:13 | [post] self | local_dataflow.rb:84:7:84:13 | self |
@@ -3134,7 +3137,7 @@
| local_dataflow.rb:118:3:118:11 | call to source | local_dataflow.rb:118:3:118:31 | call to tap |
| local_dataflow.rb:118:3:118:11 | self | local_dataflow.rb:119:3:119:31 | self |
| local_dataflow.rb:118:17:118:31 | <captured entry> self | local_dataflow.rb:118:23:118:29 | self |
| local_dataflow.rb:118:17:118:31 | synthetic *args | local_dataflow.rb:118:20:118:20 | x |
| local_dataflow.rb:118:17:118:31 | synthetic splat parameter | local_dataflow.rb:118:20:118:20 | x |
| local_dataflow.rb:118:20:118:20 | x | local_dataflow.rb:118:20:118:20 | x |
| local_dataflow.rb:118:20:118:20 | x | local_dataflow.rb:118:28:118:28 | x |
| local_dataflow.rb:119:3:119:31 | [post] self | local_dataflow.rb:119:8:119:16 | self |
@@ -3149,10 +3152,10 @@
| local_dataflow.rb:123:8:123:20 | call to dup | local_dataflow.rb:123:8:123:45 | call to tap |
| local_dataflow.rb:123:8:123:45 | call to tap | local_dataflow.rb:123:8:123:49 | call to dup |
| local_dataflow.rb:123:26:123:45 | <captured entry> self | local_dataflow.rb:123:32:123:43 | self |
| local_dataflow.rb:123:26:123:45 | synthetic *args | local_dataflow.rb:123:29:123:29 | x |
| local_dataflow.rb:123:26:123:45 | synthetic splat parameter | local_dataflow.rb:123:29:123:29 | x |
| local_dataflow.rb:126:1:128:3 | self (use) | local_dataflow.rb:127:3:127:8 | self |
| local_dataflow.rb:126:1:128:3 | self in use | local_dataflow.rb:126:1:128:3 | self (use) |
| local_dataflow.rb:126:1:128:3 | synthetic *args | local_dataflow.rb:126:9:126:9 | x |
| local_dataflow.rb:126:1:128:3 | synthetic splat parameter | local_dataflow.rb:126:9:126:9 | x |
| local_dataflow.rb:130:1:150:3 | self (use_use_madness) | local_dataflow.rb:132:6:132:11 | self |
| local_dataflow.rb:130:1:150:3 | self in use_use_madness | local_dataflow.rb:130:1:150:3 | self (use_use_madness) |
| local_dataflow.rb:131:3:131:3 | x | local_dataflow.rb:132:10:132:10 | x |

File diff suppressed because it is too large Load Diff

View File

@@ -15,13 +15,17 @@ edges
| params_flow.rb:25:12:25:13 | p1 | params_flow.rb:26:10:26:11 | p1 |
| params_flow.rb:25:17:25:24 | **kwargs [element :p2] | params_flow.rb:28:11:28:16 | kwargs [element :p2] |
| params_flow.rb:25:17:25:24 | **kwargs [element :p3] | params_flow.rb:29:11:29:16 | kwargs [element :p3] |
| params_flow.rb:25:17:25:24 | **kwargs [hash-splat position :p2] | params_flow.rb:28:11:28:16 | kwargs [hash-splat position :p2] |
| params_flow.rb:25:17:25:24 | **kwargs [hash-splat position :p3] | params_flow.rb:29:11:29:16 | kwargs [hash-splat position :p3] |
| params_flow.rb:28:11:28:16 | kwargs [element :p2] | params_flow.rb:28:11:28:21 | ...[...] |
| params_flow.rb:28:11:28:16 | kwargs [hash-splat position :p2] | params_flow.rb:28:11:28:21 | ...[...] |
| params_flow.rb:28:11:28:21 | ...[...] | params_flow.rb:28:10:28:22 | ( ... ) |
| params_flow.rb:29:11:29:16 | kwargs [element :p3] | params_flow.rb:29:11:29:21 | ...[...] |
| params_flow.rb:29:11:29:16 | kwargs [hash-splat position :p3] | params_flow.rb:29:11:29:21 | ...[...] |
| params_flow.rb:29:11:29:21 | ...[...] | params_flow.rb:29:10:29:22 | ( ... ) |
| params_flow.rb:33:12:33:19 | call to taint | params_flow.rb:25:12:25:13 | p1 |
| params_flow.rb:33:26:33:34 | call to taint | params_flow.rb:25:17:25:24 | **kwargs [element :p2] |
| params_flow.rb:33:41:33:49 | call to taint | params_flow.rb:25:17:25:24 | **kwargs [element :p3] |
| params_flow.rb:33:26:33:34 | call to taint | params_flow.rb:25:17:25:24 | **kwargs [hash-splat position :p2] |
| params_flow.rb:33:41:33:49 | call to taint | params_flow.rb:25:17:25:24 | **kwargs [hash-splat position :p3] |
| params_flow.rb:34:1:34:4 | args [element :p3] | params_flow.rb:35:25:35:28 | args [element :p3] |
| params_flow.rb:34:14:34:22 | call to taint | params_flow.rb:34:1:34:4 | args [element :p3] |
| params_flow.rb:35:12:35:20 | call to taint | params_flow.rb:25:12:25:13 | p1 |
@@ -42,9 +46,8 @@ edges
| params_flow.rb:41:26:41:29 | args [element :p1] | params_flow.rb:41:24:41:29 | ** ... [element :p1] |
| params_flow.rb:43:1:43:4 | args [element 0] | params_flow.rb:44:24:44:27 | args [element 0] |
| params_flow.rb:43:9:43:17 | call to taint | params_flow.rb:43:1:43:4 | args [element 0] |
| params_flow.rb:44:1:44:28 | *[1] | params_flow.rb:9:20:9:21 | p2 |
| params_flow.rb:44:12:44:20 | call to taint | params_flow.rb:9:16:9:17 | p1 |
| params_flow.rb:44:23:44:27 | * ... [element 0] | params_flow.rb:44:1:44:28 | *[1] |
| params_flow.rb:44:23:44:27 | * ... [element 0] | params_flow.rb:9:20:9:21 | p2 |
| params_flow.rb:44:24:44:27 | args [element 0] | params_flow.rb:44:23:44:27 | * ... [element 0] |
| params_flow.rb:46:1:46:4 | args [element 0] | params_flow.rb:47:13:47:16 | args [element 0] |
| params_flow.rb:46:1:46:4 | args [element 1] | params_flow.rb:47:13:47:16 | args [element 1] |
@@ -56,16 +59,17 @@ edges
| params_flow.rb:47:13:47:16 | args [element 1] | params_flow.rb:47:12:47:16 | * ... [element 1] |
| params_flow.rb:49:13:49:14 | p1 | params_flow.rb:50:10:50:11 | p1 |
| params_flow.rb:49:17:49:24 | *posargs [element 0] | params_flow.rb:51:11:51:17 | posargs [element 0] |
| params_flow.rb:49:17:49:24 | *posargs [element 0] | params_flow.rb:51:11:51:17 | posargs [element 0] |
| params_flow.rb:51:11:51:17 | posargs [element 0] | params_flow.rb:51:11:51:20 | ...[...] |
| params_flow.rb:51:11:51:17 | posargs [element 0] | params_flow.rb:51:11:51:20 | ...[...] |
| params_flow.rb:51:11:51:20 | ...[...] | params_flow.rb:51:10:51:21 | ( ... ) |
| params_flow.rb:55:9:55:17 | call to taint | params_flow.rb:49:13:49:14 | p1 |
| params_flow.rb:55:20:55:28 | call to taint | params_flow.rb:49:17:49:24 | *posargs [element 0] |
| params_flow.rb:57:1:57:4 | args [element 0] | params_flow.rb:58:21:58:24 | args [element 0] |
| params_flow.rb:57:9:57:17 | call to taint | params_flow.rb:57:1:57:4 | args [element 0] |
| params_flow.rb:58:1:58:25 | *[1] | params_flow.rb:49:17:49:24 | *posargs [element 0] |
| params_flow.rb:58:9:58:17 | call to taint | params_flow.rb:49:13:49:14 | p1 |
| params_flow.rb:58:20:58:24 | * ... [element 0] | params_flow.rb:49:17:49:24 | *posargs [element 0] |
| params_flow.rb:58:20:58:24 | * ... [element 0] | params_flow.rb:58:1:58:25 | *[1] |
| params_flow.rb:58:20:58:24 | * ... [element 0] | params_flow.rb:49:17:49:24 | *posargs [element 0] |
| params_flow.rb:58:21:58:24 | args [element 0] | params_flow.rb:58:20:58:24 | * ... [element 0] |
| params_flow.rb:60:1:60:4 | args [element 0] | params_flow.rb:61:10:61:13 | args [element 0] |
| params_flow.rb:60:1:60:4 | args [element 1] | params_flow.rb:61:10:61:13 | args [element 1] |
@@ -90,21 +94,10 @@ edges
| params_flow.rb:78:43:78:51 | call to taint | params_flow.rb:69:24:69:24 | w |
| params_flow.rb:78:54:78:62 | call to taint | params_flow.rb:69:27:69:27 | r |
| params_flow.rb:80:1:80:4 | args [element 0] | params_flow.rb:81:22:81:25 | args [element 0] |
| params_flow.rb:80:1:80:4 | args [element 2] | params_flow.rb:81:22:81:25 | args [element 2] |
| params_flow.rb:80:1:80:4 | args [element 3] | params_flow.rb:81:22:81:25 | args [element 3] |
| params_flow.rb:80:9:80:17 | call to taint | params_flow.rb:80:1:80:4 | args [element 0] |
| params_flow.rb:80:31:80:39 | call to taint | params_flow.rb:80:1:80:4 | args [element 2] |
| params_flow.rb:80:42:80:50 | call to taint | params_flow.rb:80:1:80:4 | args [element 3] |
| params_flow.rb:81:1:81:37 | *[1] | params_flow.rb:69:17:69:17 | y |
| params_flow.rb:81:1:81:37 | *[3] | params_flow.rb:69:24:69:24 | w |
| params_flow.rb:81:1:81:37 | *[4] | params_flow.rb:69:27:69:27 | r |
| params_flow.rb:81:10:81:18 | call to taint | params_flow.rb:69:14:69:14 | x |
| params_flow.rb:81:21:81:25 | * ... [element 0] | params_flow.rb:81:1:81:37 | *[1] |
| params_flow.rb:81:21:81:25 | * ... [element 2] | params_flow.rb:81:1:81:37 | *[3] |
| params_flow.rb:81:21:81:25 | * ... [element 3] | params_flow.rb:81:1:81:37 | *[4] |
| params_flow.rb:81:21:81:25 | * ... [element 0] | params_flow.rb:69:17:69:17 | y |
| params_flow.rb:81:22:81:25 | args [element 0] | params_flow.rb:81:21:81:25 | * ... [element 0] |
| params_flow.rb:81:22:81:25 | args [element 2] | params_flow.rb:81:21:81:25 | * ... [element 2] |
| params_flow.rb:81:22:81:25 | args [element 3] | params_flow.rb:81:21:81:25 | * ... [element 3] |
| params_flow.rb:83:14:83:14 | t | params_flow.rb:84:10:84:10 | t |
| params_flow.rb:83:17:83:17 | u | params_flow.rb:85:10:85:10 | u |
| params_flow.rb:83:20:83:20 | v | params_flow.rb:86:10:86:10 | v |
@@ -119,37 +112,24 @@ edges
| params_flow.rb:93:20:93:28 | call to taint | params_flow.rb:93:1:93:4 | args [element 1] |
| params_flow.rb:93:31:93:39 | call to taint | params_flow.rb:93:1:93:4 | args [element 2] |
| params_flow.rb:93:42:93:50 | call to taint | params_flow.rb:93:1:93:4 | args [element 3] |
| params_flow.rb:94:1:94:48 | *[2] | params_flow.rb:83:20:83:20 | v |
| params_flow.rb:94:1:94:48 | *[3] | params_flow.rb:83:23:83:23 | w |
| params_flow.rb:94:1:94:48 | *[4] | params_flow.rb:83:26:83:26 | x |
| params_flow.rb:94:1:94:48 | *[5] | params_flow.rb:83:29:83:29 | y |
| params_flow.rb:94:10:94:18 | call to taint | params_flow.rb:83:14:83:14 | t |
| params_flow.rb:94:21:94:29 | call to taint | params_flow.rb:83:17:83:17 | u |
| params_flow.rb:94:32:94:36 | * ... [element 0] | params_flow.rb:94:1:94:48 | *[2] |
| params_flow.rb:94:32:94:36 | * ... [element 1] | params_flow.rb:94:1:94:48 | *[3] |
| params_flow.rb:94:32:94:36 | * ... [element 2] | params_flow.rb:94:1:94:48 | *[4] |
| params_flow.rb:94:32:94:36 | * ... [element 3] | params_flow.rb:94:1:94:48 | *[5] |
| params_flow.rb:94:32:94:36 | * ... [element 0] | params_flow.rb:83:20:83:20 | v |
| params_flow.rb:94:32:94:36 | * ... [element 1] | params_flow.rb:83:23:83:23 | w |
| params_flow.rb:94:32:94:36 | * ... [element 2] | params_flow.rb:83:26:83:26 | x |
| params_flow.rb:94:32:94:36 | * ... [element 3] | params_flow.rb:83:29:83:29 | y |
| params_flow.rb:94:33:94:36 | args [element 0] | params_flow.rb:94:32:94:36 | * ... [element 0] |
| params_flow.rb:94:33:94:36 | args [element 1] | params_flow.rb:94:32:94:36 | * ... [element 1] |
| params_flow.rb:94:33:94:36 | args [element 2] | params_flow.rb:94:32:94:36 | * ... [element 2] |
| params_flow.rb:94:33:94:36 | args [element 3] | params_flow.rb:94:32:94:36 | * ... [element 3] |
| params_flow.rb:94:39:94:47 | call to taint | params_flow.rb:83:23:83:23 | w |
| params_flow.rb:96:1:96:88 | *[3] | params_flow.rb:69:24:69:24 | w |
| params_flow.rb:96:1:96:88 | *[4] | params_flow.rb:69:27:69:27 | r |
| params_flow.rb:96:10:96:18 | call to taint | params_flow.rb:69:14:69:14 | x |
| params_flow.rb:96:21:96:29 | call to taint | params_flow.rb:69:17:69:17 | y |
| params_flow.rb:96:32:96:65 | * ... [element 1] | params_flow.rb:96:1:96:88 | *[3] |
| params_flow.rb:96:32:96:65 | * ... [element 2] | params_flow.rb:96:1:96:88 | *[4] |
| params_flow.rb:96:45:96:53 | call to taint | params_flow.rb:96:32:96:65 | * ... [element 1] |
| params_flow.rb:96:56:96:64 | call to taint | params_flow.rb:96:32:96:65 | * ... [element 2] |
| params_flow.rb:96:68:96:76 | call to taint | params_flow.rb:69:24:69:24 | w |
| params_flow.rb:96:79:96:87 | call to taint | params_flow.rb:69:27:69:27 | r |
| params_flow.rb:98:19:98:19 | a | params_flow.rb:99:10:99:10 | a |
| params_flow.rb:98:31:98:31 | b | params_flow.rb:102:10:102:10 | b |
| params_flow.rb:105:1:105:49 | *[2] | params_flow.rb:98:31:98:31 | b |
| params_flow.rb:105:15:105:23 | call to taint | params_flow.rb:98:19:98:19 | a |
| params_flow.rb:105:26:105:48 | * ... [element 1] | params_flow.rb:105:1:105:49 | *[2] |
| params_flow.rb:105:39:105:47 | call to taint | params_flow.rb:105:26:105:48 | * ... [element 1] |
| params_flow.rb:106:15:106:23 | call to taint | params_flow.rb:98:19:98:19 | a |
| params_flow.rb:106:37:106:45 | call to taint | params_flow.rb:98:31:98:31 | b |
| params_flow.rb:108:37:108:37 | a | params_flow.rb:109:10:109:10 | a |
@@ -197,12 +177,16 @@ nodes
| params_flow.rb:25:12:25:13 | p1 | semmle.label | p1 |
| params_flow.rb:25:17:25:24 | **kwargs [element :p2] | semmle.label | **kwargs [element :p2] |
| params_flow.rb:25:17:25:24 | **kwargs [element :p3] | semmle.label | **kwargs [element :p3] |
| params_flow.rb:25:17:25:24 | **kwargs [hash-splat position :p2] | semmle.label | **kwargs [hash-splat position :p2] |
| params_flow.rb:25:17:25:24 | **kwargs [hash-splat position :p3] | semmle.label | **kwargs [hash-splat position :p3] |
| params_flow.rb:26:10:26:11 | p1 | semmle.label | p1 |
| params_flow.rb:28:10:28:22 | ( ... ) | semmle.label | ( ... ) |
| params_flow.rb:28:11:28:16 | kwargs [element :p2] | semmle.label | kwargs [element :p2] |
| params_flow.rb:28:11:28:16 | kwargs [hash-splat position :p2] | semmle.label | kwargs [hash-splat position :p2] |
| params_flow.rb:28:11:28:21 | ...[...] | semmle.label | ...[...] |
| params_flow.rb:29:10:29:22 | ( ... ) | semmle.label | ( ... ) |
| params_flow.rb:29:11:29:16 | kwargs [element :p3] | semmle.label | kwargs [element :p3] |
| params_flow.rb:29:11:29:16 | kwargs [hash-splat position :p3] | semmle.label | kwargs [hash-splat position :p3] |
| params_flow.rb:29:11:29:21 | ...[...] | semmle.label | ...[...] |
| params_flow.rb:33:12:33:19 | call to taint | semmle.label | call to taint |
| params_flow.rb:33:26:33:34 | call to taint | semmle.label | call to taint |
@@ -227,7 +211,6 @@ nodes
| params_flow.rb:41:26:41:29 | args [element :p1] | semmle.label | args [element :p1] |
| params_flow.rb:43:1:43:4 | args [element 0] | semmle.label | args [element 0] |
| params_flow.rb:43:9:43:17 | call to taint | semmle.label | call to taint |
| params_flow.rb:44:1:44:28 | *[1] | semmle.label | *[1] |
| params_flow.rb:44:12:44:20 | call to taint | semmle.label | call to taint |
| params_flow.rb:44:23:44:27 | * ... [element 0] | semmle.label | * ... [element 0] |
| params_flow.rb:44:24:44:27 | args [element 0] | semmle.label | args [element 0] |
@@ -241,15 +224,16 @@ nodes
| params_flow.rb:47:13:47:16 | args [element 1] | semmle.label | args [element 1] |
| params_flow.rb:49:13:49:14 | p1 | semmle.label | p1 |
| params_flow.rb:49:17:49:24 | *posargs [element 0] | semmle.label | *posargs [element 0] |
| params_flow.rb:49:17:49:24 | *posargs [element 0] | semmle.label | *posargs [element 0] |
| params_flow.rb:50:10:50:11 | p1 | semmle.label | p1 |
| params_flow.rb:51:10:51:21 | ( ... ) | semmle.label | ( ... ) |
| params_flow.rb:51:11:51:17 | posargs [element 0] | semmle.label | posargs [element 0] |
| params_flow.rb:51:11:51:17 | posargs [element 0] | semmle.label | posargs [element 0] |
| params_flow.rb:51:11:51:20 | ...[...] | semmle.label | ...[...] |
| params_flow.rb:55:9:55:17 | call to taint | semmle.label | call to taint |
| params_flow.rb:55:20:55:28 | call to taint | semmle.label | call to taint |
| params_flow.rb:57:1:57:4 | args [element 0] | semmle.label | args [element 0] |
| params_flow.rb:57:9:57:17 | call to taint | semmle.label | call to taint |
| params_flow.rb:58:1:58:25 | *[1] | semmle.label | *[1] |
| params_flow.rb:58:9:58:17 | call to taint | semmle.label | call to taint |
| params_flow.rb:58:20:58:24 | * ... [element 0] | semmle.label | * ... [element 0] |
| params_flow.rb:58:21:58:24 | args [element 0] | semmle.label | args [element 0] |
@@ -281,21 +265,10 @@ nodes
| params_flow.rb:78:43:78:51 | call to taint | semmle.label | call to taint |
| params_flow.rb:78:54:78:62 | call to taint | semmle.label | call to taint |
| params_flow.rb:80:1:80:4 | args [element 0] | semmle.label | args [element 0] |
| params_flow.rb:80:1:80:4 | args [element 2] | semmle.label | args [element 2] |
| params_flow.rb:80:1:80:4 | args [element 3] | semmle.label | args [element 3] |
| params_flow.rb:80:9:80:17 | call to taint | semmle.label | call to taint |
| params_flow.rb:80:31:80:39 | call to taint | semmle.label | call to taint |
| params_flow.rb:80:42:80:50 | call to taint | semmle.label | call to taint |
| params_flow.rb:81:1:81:37 | *[1] | semmle.label | *[1] |
| params_flow.rb:81:1:81:37 | *[3] | semmle.label | *[3] |
| params_flow.rb:81:1:81:37 | *[4] | semmle.label | *[4] |
| params_flow.rb:81:10:81:18 | call to taint | semmle.label | call to taint |
| params_flow.rb:81:21:81:25 | * ... [element 0] | semmle.label | * ... [element 0] |
| params_flow.rb:81:21:81:25 | * ... [element 2] | semmle.label | * ... [element 2] |
| params_flow.rb:81:21:81:25 | * ... [element 3] | semmle.label | * ... [element 3] |
| params_flow.rb:81:22:81:25 | args [element 0] | semmle.label | args [element 0] |
| params_flow.rb:81:22:81:25 | args [element 2] | semmle.label | args [element 2] |
| params_flow.rb:81:22:81:25 | args [element 3] | semmle.label | args [element 3] |
| params_flow.rb:83:14:83:14 | t | semmle.label | t |
| params_flow.rb:83:17:83:17 | u | semmle.label | u |
| params_flow.rb:83:20:83:20 | v | semmle.label | v |
@@ -316,10 +289,6 @@ nodes
| params_flow.rb:93:20:93:28 | call to taint | semmle.label | call to taint |
| params_flow.rb:93:31:93:39 | call to taint | semmle.label | call to taint |
| params_flow.rb:93:42:93:50 | call to taint | semmle.label | call to taint |
| params_flow.rb:94:1:94:48 | *[2] | semmle.label | *[2] |
| params_flow.rb:94:1:94:48 | *[3] | semmle.label | *[3] |
| params_flow.rb:94:1:94:48 | *[4] | semmle.label | *[4] |
| params_flow.rb:94:1:94:48 | *[5] | semmle.label | *[5] |
| params_flow.rb:94:10:94:18 | call to taint | semmle.label | call to taint |
| params_flow.rb:94:21:94:29 | call to taint | semmle.label | call to taint |
| params_flow.rb:94:32:94:36 | * ... [element 0] | semmle.label | * ... [element 0] |
@@ -331,24 +300,15 @@ nodes
| params_flow.rb:94:33:94:36 | args [element 2] | semmle.label | args [element 2] |
| params_flow.rb:94:33:94:36 | args [element 3] | semmle.label | args [element 3] |
| params_flow.rb:94:39:94:47 | call to taint | semmle.label | call to taint |
| params_flow.rb:96:1:96:88 | *[3] | semmle.label | *[3] |
| params_flow.rb:96:1:96:88 | *[4] | semmle.label | *[4] |
| params_flow.rb:96:10:96:18 | call to taint | semmle.label | call to taint |
| params_flow.rb:96:21:96:29 | call to taint | semmle.label | call to taint |
| params_flow.rb:96:32:96:65 | * ... [element 1] | semmle.label | * ... [element 1] |
| params_flow.rb:96:32:96:65 | * ... [element 2] | semmle.label | * ... [element 2] |
| params_flow.rb:96:45:96:53 | call to taint | semmle.label | call to taint |
| params_flow.rb:96:56:96:64 | call to taint | semmle.label | call to taint |
| params_flow.rb:96:68:96:76 | call to taint | semmle.label | call to taint |
| params_flow.rb:96:79:96:87 | call to taint | semmle.label | call to taint |
| params_flow.rb:98:19:98:19 | a | semmle.label | a |
| params_flow.rb:98:31:98:31 | b | semmle.label | b |
| params_flow.rb:99:10:99:10 | a | semmle.label | a |
| params_flow.rb:102:10:102:10 | b | semmle.label | b |
| params_flow.rb:105:1:105:49 | *[2] | semmle.label | *[2] |
| params_flow.rb:105:15:105:23 | call to taint | semmle.label | call to taint |
| params_flow.rb:105:26:105:48 | * ... [element 1] | semmle.label | * ... [element 1] |
| params_flow.rb:105:39:105:47 | call to taint | semmle.label | call to taint |
| params_flow.rb:106:15:106:23 | call to taint | semmle.label | call to taint |
| params_flow.rb:106:37:106:45 | call to taint | semmle.label | call to taint |
| params_flow.rb:108:37:108:37 | a | semmle.label | a |
@@ -418,12 +378,8 @@ subpaths
| params_flow.rb:71:10:71:10 | y | params_flow.rb:80:9:80:17 | call to taint | params_flow.rb:71:10:71:10 | y | $@ | params_flow.rb:80:9:80:17 | call to taint | call to taint |
| params_flow.rb:71:10:71:10 | y | params_flow.rb:96:21:96:29 | call to taint | params_flow.rb:71:10:71:10 | y | $@ | params_flow.rb:96:21:96:29 | call to taint | call to taint |
| params_flow.rb:74:10:74:10 | w | params_flow.rb:78:43:78:51 | call to taint | params_flow.rb:74:10:74:10 | w | $@ | params_flow.rb:78:43:78:51 | call to taint | call to taint |
| params_flow.rb:74:10:74:10 | w | params_flow.rb:80:31:80:39 | call to taint | params_flow.rb:74:10:74:10 | w | $@ | params_flow.rb:80:31:80:39 | call to taint | call to taint |
| params_flow.rb:74:10:74:10 | w | params_flow.rb:96:45:96:53 | call to taint | params_flow.rb:74:10:74:10 | w | $@ | params_flow.rb:96:45:96:53 | call to taint | call to taint |
| params_flow.rb:74:10:74:10 | w | params_flow.rb:96:68:96:76 | call to taint | params_flow.rb:74:10:74:10 | w | $@ | params_flow.rb:96:68:96:76 | call to taint | call to taint |
| params_flow.rb:75:10:75:10 | r | params_flow.rb:78:54:78:62 | call to taint | params_flow.rb:75:10:75:10 | r | $@ | params_flow.rb:78:54:78:62 | call to taint | call to taint |
| params_flow.rb:75:10:75:10 | r | params_flow.rb:80:42:80:50 | call to taint | params_flow.rb:75:10:75:10 | r | $@ | params_flow.rb:80:42:80:50 | call to taint | call to taint |
| params_flow.rb:75:10:75:10 | r | params_flow.rb:96:56:96:64 | call to taint | params_flow.rb:75:10:75:10 | r | $@ | params_flow.rb:96:56:96:64 | call to taint | call to taint |
| params_flow.rb:75:10:75:10 | r | params_flow.rb:96:79:96:87 | call to taint | params_flow.rb:75:10:75:10 | r | $@ | params_flow.rb:96:79:96:87 | call to taint | call to taint |
| params_flow.rb:84:10:84:10 | t | params_flow.rb:94:10:94:18 | call to taint | params_flow.rb:84:10:84:10 | t | $@ | params_flow.rb:94:10:94:18 | call to taint | call to taint |
| params_flow.rb:84:10:84:10 | t | params_flow.rb:130:9:130:17 | call to taint | params_flow.rb:84:10:84:10 | t | $@ | params_flow.rb:130:9:130:17 | call to taint | call to taint |
@@ -437,7 +393,6 @@ subpaths
| params_flow.rb:89:10:89:10 | y | params_flow.rb:93:42:93:50 | call to taint | params_flow.rb:89:10:89:10 | y | $@ | params_flow.rb:93:42:93:50 | call to taint | call to taint |
| params_flow.rb:99:10:99:10 | a | params_flow.rb:105:15:105:23 | call to taint | params_flow.rb:99:10:99:10 | a | $@ | params_flow.rb:105:15:105:23 | call to taint | call to taint |
| params_flow.rb:99:10:99:10 | a | params_flow.rb:106:15:106:23 | call to taint | params_flow.rb:99:10:99:10 | a | $@ | params_flow.rb:106:15:106:23 | call to taint | call to taint |
| params_flow.rb:102:10:102:10 | b | params_flow.rb:105:39:105:47 | call to taint | params_flow.rb:102:10:102:10 | b | $@ | params_flow.rb:105:39:105:47 | call to taint | call to taint |
| params_flow.rb:102:10:102:10 | b | params_flow.rb:106:37:106:45 | call to taint | params_flow.rb:102:10:102:10 | b | $@ | params_flow.rb:106:37:106:45 | call to taint | call to taint |
| params_flow.rb:109:10:109:10 | a | params_flow.rb:114:33:114:41 | call to taint | params_flow.rb:109:10:109:10 | a | $@ | params_flow.rb:114:33:114:41 | call to taint | call to taint |
| params_flow.rb:110:10:110:13 | ...[...] | params_flow.rb:114:44:114:52 | call to taint | params_flow.rb:110:10:110:13 | ...[...] | $@ | params_flow.rb:114:44:114:52 | call to taint | call to taint |

View File

@@ -71,8 +71,8 @@ def splatmid(x, y, *z, w, r)
sink y # $ hasValueFlow=28 $ hasValueFlow=46 $ hasValueFlow=33
sink z[0] # MISSING: $ hasValueFlow=47 $ hasValueFlow=29 $ hasValueFlow=34
sink z[1] # $ MISSING: hasValueFlow=48 $ hasValueFlow=35
sink w # $ hasValueFlow=30 $ hasValueFlow=50 $ MISSING: hasValueFlow=36 $ SPURIOUS: hasValueFlow=35 $ hasValueFlow=48
sink r # $ hasValueFlow=31 $ hasValueFlow=51 $ MISSING: hasValueFlow=37 $ SPURIOUS: hasValueFlow=36 $ hasValueFlow=49
sink w # $ hasValueFlow=30 $ hasValueFlow=50 $ MISSING: hasValueFlow=36
sink r # $ hasValueFlow=31 $ hasValueFlow=51 $ MISSING: hasValueFlow=37
end
splatmid(taint(27), taint(28), taint(29), taint(30), taint(31))
@@ -99,7 +99,7 @@ def splatmidsmall(a, *splats, b)
sink a # $ hasValueFlow=52 $ hasValueFlow=55
sink splats[0] # $ MISSING: hasValueFlow=53
sink splats[1]
sink b # $ hasValueFlow=57 $ hasValueFlow=54
sink b # $ hasValueFlow=57 $ MISSING: hasValueFlow=54
end
splatmidsmall(taint(52), *[taint(53), taint(54)])

View File

@@ -250,7 +250,7 @@ edges
| summaries.rb:122:33:122:33 | [post] z | summaries.rb:125:6:125:6 | z |
| summaries.rb:128:1:128:1 | [post] x | summaries.rb:129:6:129:6 | x |
| summaries.rb:128:14:128:20 | tainted | summaries.rb:128:1:128:1 | [post] x |
| summaries.rb:131:16:131:22 | tainted | summaries.rb:131:1:131:23 | * |
| summaries.rb:131:16:131:22 | tainted | summaries.rb:131:1:131:23 | synthetic splat argument |
| summaries.rb:157:14:160:3 | do ... end [captured tainted] | summaries.rb:158:15:158:21 | tainted |
| summaries.rb:157:14:160:3 | do ... end [captured tainted] | summaries.rb:158:15:158:21 | tainted |
nodes
@@ -469,7 +469,7 @@ nodes
| summaries.rb:128:1:128:1 | [post] x | semmle.label | [post] x |
| summaries.rb:128:14:128:20 | tainted | semmle.label | tainted |
| summaries.rb:129:6:129:6 | x | semmle.label | x |
| summaries.rb:131:1:131:23 | * | semmle.label | * |
| summaries.rb:131:1:131:23 | synthetic splat argument | semmle.label | synthetic splat argument |
| summaries.rb:131:16:131:22 | tainted | semmle.label | tainted |
| summaries.rb:131:16:131:22 | tainted | semmle.label | tainted |
| summaries.rb:131:16:131:22 | tainted | semmle.label | tainted |
@@ -584,7 +584,7 @@ invalidSpecComponent
| summaries.rb:124:6:124:6 | y | summaries.rb:1:20:1:36 | call to source | summaries.rb:124:6:124:6 | y | $@ | summaries.rb:1:20:1:36 | call to source | call to source |
| summaries.rb:125:6:125:6 | z | summaries.rb:1:20:1:36 | call to source | summaries.rb:125:6:125:6 | z | $@ | summaries.rb:1:20:1:36 | call to source | call to source |
| summaries.rb:129:6:129:6 | x | summaries.rb:1:20:1:36 | call to source | summaries.rb:129:6:129:6 | x | $@ | summaries.rb:1:20:1:36 | call to source | call to source |
| summaries.rb:131:1:131:23 | * | summaries.rb:1:20:1:36 | call to source | summaries.rb:131:1:131:23 | * | $@ | summaries.rb:1:20:1:36 | call to source | call to source |
| summaries.rb:131:1:131:23 | synthetic splat argument | summaries.rb:1:20:1:36 | call to source | summaries.rb:131:1:131:23 | synthetic splat argument | $@ | summaries.rb:1:20:1:36 | call to source | call to source |
| summaries.rb:131:16:131:22 | tainted | summaries.rb:1:20:1:36 | call to source | summaries.rb:131:16:131:22 | tainted | $@ | summaries.rb:1:20:1:36 | call to source | call to source |
| summaries.rb:131:16:131:22 | tainted | summaries.rb:1:20:1:36 | call to source | summaries.rb:131:16:131:22 | tainted | $@ | summaries.rb:1:20:1:36 | call to source | call to source |
| summaries.rb:132:21:132:27 | tainted | summaries.rb:1:20:1:36 | call to source | summaries.rb:132:21:132:27 | tainted | $@ | summaries.rb:1:20:1:36 | call to source | call to source |

View File

@@ -7,19 +7,19 @@ 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 | 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:5:5:7 | synthetic *args | type tracker without call steps | type_tracker.rb:2:5:5:7 | synthetic *args |
| type_tracker.rb:2:5:5:7 | synthetic splat parameter | type tracker without call steps | type_tracker.rb:2:5:5:7 | synthetic splat parameter |
| 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:3:14:3:23 | call to field |
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:8:9:8:14 | @field |
| 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:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:15:10:15:18 | call to field |
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps with content element 0 | type_tracker.rb:3:9:3:23 | * |
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps with content element 0 | type_tracker.rb:15:5:15:18 | * |
| type_tracker.rb:3:9:3:23 | * | type tracker without call steps | type_tracker.rb:3:9:3:23 | * |
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps with content splat position 0 | type_tracker.rb:3:9:3:23 | synthetic splat argument |
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps with content splat position 0 | type_tracker.rb:15:5:15:18 | synthetic splat argument |
| 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 |
| type_tracker.rb:3:9:3:23 | synthetic splat argument | type tracker without call steps | type_tracker.rb:3:9:3:23 | synthetic splat argument |
| 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:3:14:3:23 | call to field | type tracker without call steps with content element 0 | type_tracker.rb:3:9:3:23 | * |
| type_tracker.rb:3:14:3:23 | call to field | type tracker without call steps with content splat position 0 | type_tracker.rb:3:9:3:23 | synthetic splat argument |
| type_tracker.rb:4:9:4:14 | @field | type tracker without call steps | type_tracker.rb:4:9:4:14 | @field |
| 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 |
@@ -27,8 +27,8 @@ track
| 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: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 | @field | type tracker without call steps with content element 0 | type_tracker.rb:3:9:3:23 | * |
| type_tracker.rb:8:9:8:14 | @field | type tracker without call steps with content element 0 | type_tracker.rb:15:5:15:18 | * |
| type_tracker.rb:8:9:8:14 | @field | type tracker without call steps with content splat position 0 | type_tracker.rb:3:9:3:23 | synthetic splat argument |
| type_tracker.rb:8:9:8:14 | @field | type tracker without call steps with content splat position 0 | type_tracker.rb:15:5:15:18 | synthetic splat argument |
| 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 | self in m | type tracker without call steps | type_tracker.rb:12:1:16:3 | self in m |
@@ -39,123 +39,123 @@ track
| 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 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 | * | type tracker with call steps | type_tracker.rb:2:5:5:7 | synthetic *args |
| type_tracker.rb:14:5:14:13 | * | type tracker without call steps | type_tracker.rb:14:5:14:13 | * |
| 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:5:14:13 | synthetic splat argument | type tracker with call steps | type_tracker.rb:2:5:5:7 | synthetic splat parameter |
| type_tracker.rb:14:5:14:13 | synthetic splat argument | type tracker without call steps | type_tracker.rb:14:5:14:13 | synthetic splat argument |
| 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:8:9:8:14 | @field |
| type_tracker.rb:14:17:14:23 | "hello" | type tracker with call steps with content attribute field | type_tracker.rb:7:5:9:7 | self in field |
| type_tracker.rb:14:17:14:23 | "hello" | type tracker with call steps with content element 0 | type_tracker.rb:2:5:5:7 | synthetic *args |
| type_tracker.rb:14:17:14:23 | "hello" | type tracker with call steps with content splat position 0 | type_tracker.rb:2:5:5:7 | synthetic splat parameter |
| 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" |
| type_tracker.rb:14:17:14:23 | "hello" | type tracker without call steps | type_tracker.rb:15:10:15:18 | call to field |
| type_tracker.rb:14:17:14:23 | "hello" | type tracker without call steps with content attribute field | type_tracker.rb:14:5:14:7 | [post] var |
| type_tracker.rb:14:17:14:23 | "hello" | type tracker without call steps with content element 0 | type_tracker.rb:14:5:14:13 | * |
| type_tracker.rb:14:17:14:23 | "hello" | type tracker without call steps with content element 0 | type_tracker.rb:15:5:15:18 | * |
| type_tracker.rb:14:17:14:23 | "hello" | type tracker without call steps with content splat position 0 | type_tracker.rb:14:5:14:13 | synthetic splat argument |
| type_tracker.rb:14:17:14:23 | "hello" | type tracker without call steps with content splat position 0 | type_tracker.rb:15:5:15:18 | synthetic splat argument |
| type_tracker.rb:14:17:14:23 | __synth__0 | type tracker without call steps | type_tracker.rb:14:17:14:23 | __synth__0 |
| type_tracker.rb:15:5:15:18 | * | type tracker without call steps | type_tracker.rb:15:5:15:18 | * |
| type_tracker.rb:15:5:15:18 | call to puts | type tracker without call steps | type_tracker.rb:15:5:15:18 | call to puts |
| type_tracker.rb:15:5:15:18 | synthetic splat argument | type tracker without call steps | type_tracker.rb:15:5:15:18 | synthetic splat argument |
| type_tracker.rb:15:10:15:18 | call to field | type tracker without call steps | type_tracker.rb:15:10:15:18 | call to field |
| type_tracker.rb:15:10:15:18 | call to field | type tracker without call steps with content element 0 | type_tracker.rb:15:5:15:18 | * |
| type_tracker.rb:15:10:15:18 | call to field | type tracker without call steps with content splat position 0 | type_tracker.rb:15:5:15:18 | synthetic splat argument |
| type_tracker.rb:18:1:21:3 | &block | type tracker without call steps | type_tracker.rb:18:1:21:3 | &block |
| type_tracker.rb:18:1:21:3 | positional | type tracker without call steps | type_tracker.rb:18:1:21:3 | positional |
| type_tracker.rb:18:1:21:3 | self in positional | type tracker without call steps | type_tracker.rb:18:1:21:3 | self in positional |
| type_tracker.rb:18:1:21:3 | synthetic *args | type tracker without call steps | type_tracker.rb:18:1:21:3 | synthetic *args |
| type_tracker.rb:18:1:21:3 | synthetic splat parameter | type tracker without call steps | type_tracker.rb:18:1:21:3 | synthetic splat parameter |
| type_tracker.rb:18:16:18:17 | p1 | type tracker without call steps | type_tracker.rb:18:16:18:17 | p1 |
| type_tracker.rb:18:16:18:17 | p1 | type tracker without call steps | type_tracker.rb:18:16:18:17 | p1 |
| type_tracker.rb:18:16:18:17 | p1 | type tracker without call steps with content element 0 | type_tracker.rb:19:5:19:11 | * |
| type_tracker.rb:18:16:18:17 | p1 | type tracker without call steps with content splat position 0 | type_tracker.rb:19:5:19:11 | synthetic splat argument |
| type_tracker.rb:18:20:18:21 | p2 | type tracker without call steps | type_tracker.rb:18:20:18:21 | p2 |
| type_tracker.rb:18:20:18:21 | p2 | type tracker without call steps | type_tracker.rb:18:20:18:21 | p2 |
| type_tracker.rb:18:20:18:21 | p2 | type tracker without call steps with content element 0 | type_tracker.rb:20:5:20:11 | * |
| type_tracker.rb:19:5:19:11 | * | type tracker without call steps | type_tracker.rb:19:5:19:11 | * |
| type_tracker.rb:18:20:18:21 | p2 | type tracker without call steps with content splat position 0 | type_tracker.rb:20:5:20:11 | synthetic splat argument |
| type_tracker.rb:19:5:19:11 | call to puts | type tracker without call steps | type_tracker.rb:19:5:19:11 | call to puts |
| type_tracker.rb:20:5:20:11 | * | type tracker without call steps | type_tracker.rb:20:5:20:11 | * |
| type_tracker.rb:19:5:19:11 | synthetic splat argument | type tracker without call steps | type_tracker.rb:19:5:19:11 | synthetic splat argument |
| type_tracker.rb:20:5:20:11 | call to puts | type tracker without call steps | type_tracker.rb:20:5:20:11 | call to puts |
| type_tracker.rb:20:5:20:11 | call to puts | type tracker without call steps | type_tracker.rb:23:1:23:16 | call to positional |
| type_tracker.rb:23:1:23:16 | * | type tracker with call steps | type_tracker.rb:18:1:21:3 | synthetic *args |
| type_tracker.rb:23:1:23:16 | * | type tracker without call steps | type_tracker.rb:23:1:23:16 | * |
| type_tracker.rb:20:5:20:11 | synthetic splat argument | type tracker without call steps | type_tracker.rb:20:5:20:11 | synthetic splat argument |
| type_tracker.rb:23:1:23:16 | call to positional | type tracker without call steps | type_tracker.rb:23:1:23:16 | call to positional |
| type_tracker.rb:23:1:23:16 | synthetic splat argument | type tracker with call steps | type_tracker.rb:18:1:21:3 | synthetic splat parameter |
| type_tracker.rb:23:1:23:16 | synthetic splat argument | type tracker without call steps | type_tracker.rb:23:1:23:16 | synthetic splat argument |
| type_tracker.rb:23:12:23:12 | 1 | type tracker with call steps | type_tracker.rb:18:16:18:17 | p1 |
| type_tracker.rb:23:12:23:12 | 1 | type tracker with call steps with content element 0 | type_tracker.rb:18:1:21:3 | synthetic *args |
| type_tracker.rb:23:12:23:12 | 1 | type tracker with call steps with content element 0 | type_tracker.rb:19:5:19:11 | * |
| type_tracker.rb:23:12:23:12 | 1 | type tracker with call steps with content splat position 0 | type_tracker.rb:18:1:21:3 | synthetic splat parameter |
| type_tracker.rb:23:12:23:12 | 1 | type tracker with call steps with content splat position 0 | type_tracker.rb:19:5:19:11 | synthetic splat argument |
| type_tracker.rb:23:12:23:12 | 1 | type tracker without call steps | type_tracker.rb:23:12:23:12 | 1 |
| type_tracker.rb:23:12:23:12 | 1 | type tracker without call steps with content element 0 | type_tracker.rb:23:1:23:16 | * |
| type_tracker.rb:23:12:23:12 | 1 | type tracker without call steps with content splat position 0 | type_tracker.rb:23:1:23:16 | synthetic splat argument |
| type_tracker.rb:23:15:23:15 | 2 | type tracker with call steps | type_tracker.rb:18:20:18:21 | p2 |
| type_tracker.rb:23:15:23:15 | 2 | type tracker with call steps with content element 0 | type_tracker.rb:20:5:20:11 | * |
| type_tracker.rb:23:15:23:15 | 2 | type tracker with call steps with content element 1 | type_tracker.rb:18:1:21:3 | synthetic *args |
| type_tracker.rb:23:15:23:15 | 2 | type tracker with call steps with content splat position 0 | type_tracker.rb:20:5:20:11 | synthetic splat argument |
| type_tracker.rb:23:15:23:15 | 2 | type tracker with call steps with content splat position 1 | type_tracker.rb:18:1:21:3 | synthetic splat parameter |
| type_tracker.rb:23:15:23:15 | 2 | type tracker without call steps | type_tracker.rb:23:15:23:15 | 2 |
| type_tracker.rb:23:15:23:15 | 2 | type tracker without call steps with content element 1 | type_tracker.rb:23:1:23:16 | * |
| type_tracker.rb:23:15:23:15 | 2 | type tracker without call steps with content splat position 1 | type_tracker.rb:23:1:23:16 | synthetic splat argument |
| type_tracker.rb:25:1:28:3 | &block | type tracker without call steps | type_tracker.rb:25:1:28:3 | &block |
| type_tracker.rb:25:1:28:3 | **kwargs | type tracker without call steps | type_tracker.rb:25:1:28:3 | **kwargs |
| type_tracker.rb:25:1:28:3 | keyword | type tracker without call steps | type_tracker.rb:25:1:28:3 | keyword |
| type_tracker.rb:25:1:28:3 | self in keyword | type tracker without call steps | type_tracker.rb:25:1:28:3 | self in keyword |
| type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter | type tracker without call steps | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter |
| type_tracker.rb:25:13:25:14 | p1 | type tracker without call steps | type_tracker.rb:25:13:25:14 | p1 |
| type_tracker.rb:25:13:25:14 | p1 | type tracker without call steps | type_tracker.rb:25:13:25:14 | p1 |
| type_tracker.rb:25:13:25:14 | p1 | type tracker without call steps with content element 0 | type_tracker.rb:26:5:26:11 | * |
| type_tracker.rb:25:13:25:14 | p1 | type tracker without call steps with content splat position 0 | type_tracker.rb:26:5:26:11 | synthetic splat argument |
| type_tracker.rb:25:18:25:19 | p2 | type tracker without call steps | type_tracker.rb:25:18:25:19 | p2 |
| type_tracker.rb:25:18:25:19 | p2 | type tracker without call steps | type_tracker.rb:25:18:25:19 | p2 |
| type_tracker.rb:25:18:25:19 | p2 | type tracker without call steps with content element 0 | type_tracker.rb:27:5:27:11 | * |
| type_tracker.rb:26:5:26:11 | * | type tracker without call steps | type_tracker.rb:26:5:26:11 | * |
| type_tracker.rb:25:18:25:19 | p2 | type tracker without call steps with content splat position 0 | type_tracker.rb:27:5:27:11 | synthetic splat argument |
| type_tracker.rb:26:5:26:11 | call to puts | type tracker without call steps | type_tracker.rb:26:5:26:11 | call to puts |
| type_tracker.rb:27:5:27:11 | * | type tracker without call steps | type_tracker.rb:27:5:27:11 | * |
| type_tracker.rb:26:5:26:11 | synthetic splat argument | type tracker without call steps | type_tracker.rb:26:5:26:11 | synthetic splat argument |
| type_tracker.rb:27:5:27:11 | call to puts | type tracker without call steps | type_tracker.rb:27:5:27:11 | call to puts |
| type_tracker.rb:27:5:27:11 | call to puts | type tracker without call steps | type_tracker.rb:30:1:30:21 | call to keyword |
| type_tracker.rb:27:5:27:11 | call to puts | type tracker without call steps | type_tracker.rb:31:1:31:21 | call to keyword |
| type_tracker.rb:27:5:27:11 | call to puts | type tracker without call steps | type_tracker.rb:32:1:32:27 | call to keyword |
| type_tracker.rb:30:1:30:21 | ** | type tracker with call steps | type_tracker.rb:25:1:28:3 | **kwargs |
| type_tracker.rb:30:1:30:21 | ** | type tracker without call steps | type_tracker.rb:30:1:30:21 | ** |
| type_tracker.rb:27:5:27:11 | synthetic splat argument | type tracker without call steps | type_tracker.rb:27:5:27:11 | synthetic splat argument |
| type_tracker.rb:30:1:30:21 | call to keyword | type tracker without call steps | type_tracker.rb:30:1:30:21 | call to keyword |
| type_tracker.rb:30:1:30:21 | synthetic hash-splat argument | type tracker with call steps | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter |
| type_tracker.rb:30:1:30:21 | synthetic hash-splat argument | type tracker without call steps | type_tracker.rb:30:1:30:21 | synthetic hash-splat argument |
| type_tracker.rb:30:9:30:10 | :p1 | type tracker without call steps | type_tracker.rb:30:9:30:10 | :p1 |
| type_tracker.rb:30:9:30:13 | Pair | type tracker without call steps | type_tracker.rb:30:9:30:13 | Pair |
| type_tracker.rb:30:13:30:13 | 3 | type tracker with call steps | type_tracker.rb:25:13:25:14 | p1 |
| type_tracker.rb:30:13:30:13 | 3 | type tracker with call steps with content element 0 | type_tracker.rb:26:5:26:11 | * |
| type_tracker.rb:30:13:30:13 | 3 | type tracker with call steps with content element :p1 | type_tracker.rb:25:1:28:3 | **kwargs |
| type_tracker.rb:30:13:30:13 | 3 | type tracker with call steps with content hash-splat position :p1 | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter |
| type_tracker.rb:30:13:30:13 | 3 | type tracker with call steps with content splat position 0 | type_tracker.rb:26:5:26:11 | synthetic splat argument |
| type_tracker.rb:30:13:30:13 | 3 | type tracker without call steps | type_tracker.rb:30:13:30:13 | 3 |
| type_tracker.rb:30:13:30:13 | 3 | type tracker without call steps with content element :p1 | type_tracker.rb:30:1:30:21 | ** |
| type_tracker.rb:30:13:30:13 | 3 | type tracker without call steps with content hash-splat position :p1 | type_tracker.rb:30:1:30:21 | synthetic hash-splat argument |
| type_tracker.rb:30:16:30:17 | :p2 | type tracker without call steps | type_tracker.rb:30:16:30:17 | :p2 |
| type_tracker.rb:30:16:30:20 | Pair | type tracker without call steps | type_tracker.rb:30:16:30:20 | Pair |
| type_tracker.rb:30:20:30:20 | 4 | type tracker with call steps | type_tracker.rb:25:18:25:19 | p2 |
| type_tracker.rb:30:20:30:20 | 4 | type tracker with call steps with content element 0 | type_tracker.rb:27:5:27:11 | * |
| type_tracker.rb:30:20:30:20 | 4 | type tracker with call steps with content element :p2 | type_tracker.rb:25:1:28:3 | **kwargs |
| type_tracker.rb:30:20:30:20 | 4 | type tracker with call steps with content hash-splat position :p2 | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter |
| type_tracker.rb:30:20:30:20 | 4 | type tracker with call steps with content splat position 0 | type_tracker.rb:27:5:27:11 | synthetic splat argument |
| type_tracker.rb:30:20:30:20 | 4 | type tracker without call steps | type_tracker.rb:30:20:30:20 | 4 |
| type_tracker.rb:30:20:30:20 | 4 | type tracker without call steps with content element :p2 | type_tracker.rb:30:1:30:21 | ** |
| type_tracker.rb:31:1:31:21 | ** | type tracker with call steps | type_tracker.rb:25:1:28:3 | **kwargs |
| type_tracker.rb:31:1:31:21 | ** | type tracker without call steps | type_tracker.rb:31:1:31:21 | ** |
| type_tracker.rb:30:20:30:20 | 4 | type tracker without call steps with content hash-splat position :p2 | type_tracker.rb:30:1:30:21 | synthetic hash-splat argument |
| type_tracker.rb:31:1:31:21 | call to keyword | type tracker without call steps | type_tracker.rb:31:1:31:21 | call to keyword |
| type_tracker.rb:31:1:31:21 | synthetic hash-splat argument | type tracker with call steps | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter |
| type_tracker.rb:31:1:31:21 | synthetic hash-splat argument | type tracker without call steps | type_tracker.rb:31:1:31:21 | synthetic hash-splat argument |
| type_tracker.rb:31:9:31:10 | :p2 | type tracker without call steps | type_tracker.rb:31:9:31:10 | :p2 |
| type_tracker.rb:31:9:31:13 | Pair | type tracker without call steps | type_tracker.rb:31:9:31:13 | Pair |
| type_tracker.rb:31:13:31:13 | 5 | type tracker with call steps | type_tracker.rb:25:18:25:19 | p2 |
| type_tracker.rb:31:13:31:13 | 5 | type tracker with call steps with content element 0 | type_tracker.rb:27:5:27:11 | * |
| type_tracker.rb:31:13:31:13 | 5 | type tracker with call steps with content element :p2 | type_tracker.rb:25:1:28:3 | **kwargs |
| type_tracker.rb:31:13:31:13 | 5 | type tracker with call steps with content hash-splat position :p2 | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter |
| type_tracker.rb:31:13:31:13 | 5 | type tracker with call steps with content splat position 0 | type_tracker.rb:27:5:27:11 | synthetic splat argument |
| type_tracker.rb:31:13:31:13 | 5 | type tracker without call steps | type_tracker.rb:31:13:31:13 | 5 |
| type_tracker.rb:31:13:31:13 | 5 | type tracker without call steps with content element :p2 | type_tracker.rb:31:1:31:21 | ** |
| type_tracker.rb:31:13:31:13 | 5 | type tracker without call steps with content hash-splat position :p2 | type_tracker.rb:31:1:31:21 | synthetic hash-splat argument |
| type_tracker.rb:31:16:31:17 | :p1 | type tracker without call steps | type_tracker.rb:31:16:31:17 | :p1 |
| type_tracker.rb:31:16:31:20 | Pair | type tracker without call steps | type_tracker.rb:31:16:31:20 | Pair |
| type_tracker.rb:31:20:31:20 | 6 | type tracker with call steps | type_tracker.rb:25:13:25:14 | p1 |
| type_tracker.rb:31:20:31:20 | 6 | type tracker with call steps with content element 0 | type_tracker.rb:26:5:26:11 | * |
| type_tracker.rb:31:20:31:20 | 6 | type tracker with call steps with content element :p1 | type_tracker.rb:25:1:28:3 | **kwargs |
| type_tracker.rb:31:20:31:20 | 6 | type tracker with call steps with content hash-splat position :p1 | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter |
| type_tracker.rb:31:20:31:20 | 6 | type tracker with call steps with content splat position 0 | type_tracker.rb:26:5:26:11 | synthetic splat argument |
| type_tracker.rb:31:20:31:20 | 6 | type tracker without call steps | type_tracker.rb:31:20:31:20 | 6 |
| type_tracker.rb:31:20:31:20 | 6 | type tracker without call steps with content element :p1 | type_tracker.rb:31:1:31:21 | ** |
| type_tracker.rb:32:1:32:27 | ** | type tracker with call steps | type_tracker.rb:25:1:28:3 | **kwargs |
| type_tracker.rb:32:1:32:27 | ** | type tracker without call steps | type_tracker.rb:32:1:32:27 | ** |
| type_tracker.rb:31:20:31:20 | 6 | type tracker without call steps with content hash-splat position :p1 | type_tracker.rb:31:1:31:21 | synthetic hash-splat argument |
| type_tracker.rb:32:1:32:27 | call to keyword | type tracker without call steps | type_tracker.rb:32:1:32:27 | call to keyword |
| type_tracker.rb:32:1:32:27 | synthetic hash-splat argument | type tracker with call steps | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter |
| type_tracker.rb:32:1:32:27 | synthetic hash-splat argument | type tracker without call steps | type_tracker.rb:32:1:32:27 | synthetic hash-splat argument |
| type_tracker.rb:32:9:32:11 | :p2 | type tracker without call steps | type_tracker.rb:32:9:32:11 | :p2 |
| type_tracker.rb:32:9:32:16 | Pair | type tracker without call steps | type_tracker.rb:32:9:32:16 | Pair |
| type_tracker.rb:32:16:32:16 | 7 | type tracker with call steps | type_tracker.rb:25:18:25:19 | p2 |
| type_tracker.rb:32:16:32:16 | 7 | type tracker with call steps with content element 0 | type_tracker.rb:27:5:27:11 | * |
| type_tracker.rb:32:16:32:16 | 7 | type tracker with call steps with content element :p2 | type_tracker.rb:25:1:28:3 | **kwargs |
| type_tracker.rb:32:16:32:16 | 7 | type tracker with call steps with content hash-splat position :p2 | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter |
| type_tracker.rb:32:16:32:16 | 7 | type tracker with call steps with content splat position 0 | type_tracker.rb:27:5:27:11 | synthetic splat argument |
| type_tracker.rb:32:16:32:16 | 7 | type tracker without call steps | type_tracker.rb:32:16:32:16 | 7 |
| type_tracker.rb:32:16:32:16 | 7 | type tracker without call steps with content element :p2 | type_tracker.rb:32:1:32:27 | ** |
| type_tracker.rb:32:16:32:16 | 7 | type tracker without call steps with content hash-splat position :p2 | type_tracker.rb:32:1:32:27 | synthetic hash-splat argument |
| type_tracker.rb:32:19:32:21 | :p1 | type tracker without call steps | type_tracker.rb:32:19:32:21 | :p1 |
| type_tracker.rb:32:19:32:26 | Pair | type tracker without call steps | type_tracker.rb:32:19:32:26 | Pair |
| type_tracker.rb:32:26:32:26 | 8 | type tracker with call steps | type_tracker.rb:25:13:25:14 | p1 |
| type_tracker.rb:32:26:32:26 | 8 | type tracker with call steps with content element 0 | type_tracker.rb:26:5:26:11 | * |
| type_tracker.rb:32:26:32:26 | 8 | type tracker with call steps with content element :p1 | type_tracker.rb:25:1:28:3 | **kwargs |
| type_tracker.rb:32:26:32:26 | 8 | type tracker with call steps with content hash-splat position :p1 | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter |
| type_tracker.rb:32:26:32:26 | 8 | type tracker with call steps with content splat position 0 | type_tracker.rb:26:5:26:11 | synthetic splat argument |
| type_tracker.rb:32:26:32:26 | 8 | type tracker without call steps | type_tracker.rb:32:26:32:26 | 8 |
| type_tracker.rb:32:26:32:26 | 8 | type tracker without call steps with content element :p1 | type_tracker.rb:32:1:32:27 | ** |
| type_tracker.rb:32:26:32:26 | 8 | type tracker without call steps with content hash-splat position :p1 | type_tracker.rb:32:1:32:27 | synthetic hash-splat argument |
| type_tracker.rb:34:1:53:3 | &block | type tracker without call steps | type_tracker.rb:34:1:53:3 | &block |
| type_tracker.rb:34:1:53:3 | self in throughArray | type tracker without call steps | type_tracker.rb:34:1:53:3 | self in throughArray |
| type_tracker.rb:34:1:53:3 | synthetic *args | type tracker without call steps | type_tracker.rb:34:1:53:3 | synthetic *args |
| type_tracker.rb:34:1:53:3 | synthetic splat parameter | type tracker without call steps | type_tracker.rb:34:1:53:3 | synthetic splat parameter |
| type_tracker.rb:34:1:53:3 | throughArray | type tracker without call steps | type_tracker.rb:34:1:53:3 | throughArray |
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:34:18:34:20 | obj |
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:34:18:34:20 | obj |
@@ -165,164 +165,169 @@ track
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:52:5:52:13 | ...[...] |
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element | type_tracker.rb:38:13:38:25 | call to [] |
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element | type_tracker.rb:50:14:50:26 | call to [] |
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 0 | type_tracker.rb:35:11:35:15 | * |
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 0 or unknown | type_tracker.rb:35:11:35:15 | call to [] |
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 0 | type_tracker.rb:35:11:35:15 | call to [] |
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 0 | type_tracker.rb:35:11:35:15 | synthetic splat argument |
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 0 or unknown | type_tracker.rb:42:14:42:26 | call to [] |
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 0 or unknown | type_tracker.rb:46:14:46:26 | call to [] |
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 1 | type_tracker.rb:39:5:39:12 | * |
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 1 | type_tracker.rb:43:5:43:13 | * |
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 1 | type_tracker.rb:47:5:47:13 | * |
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 1 | type_tracker.rb:51:5:51:13 | * |
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content splat position 1 | type_tracker.rb:39:5:39:12 | synthetic splat argument |
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content splat position 1 | type_tracker.rb:43:5:43:13 | synthetic splat argument |
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content splat position 1 | type_tracker.rb:47:5:47:13 | synthetic splat argument |
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content splat position 1 | type_tracker.rb:51:5:51:13 | synthetic splat argument |
| type_tracker.rb:34:23:34:23 | y | type tracker without call steps | type_tracker.rb:34:23:34:23 | y |
| type_tracker.rb:34:23:34:23 | y | type tracker without call steps | type_tracker.rb:34:23:34:23 | y |
| type_tracker.rb:34:23:34:23 | y | type tracker without call steps with content element 0 | type_tracker.rb:39:5:39:12 | * |
| type_tracker.rb:34:23:34:23 | y | type tracker without call steps with content element 0 | type_tracker.rb:44:5:44:13 | * |
| type_tracker.rb:34:23:34:23 | y | type tracker without call steps with content element 0 | type_tracker.rb:51:5:51:13 | * |
| type_tracker.rb:34:23:34:23 | y | type tracker without call steps with content splat position 0 | type_tracker.rb:39:5:39:12 | synthetic splat argument |
| type_tracker.rb:34:23:34:23 | y | type tracker without call steps with content splat position 0 | type_tracker.rb:44:5:44:13 | synthetic splat argument |
| type_tracker.rb:34:23:34:23 | y | type tracker without call steps with content splat position 0 | type_tracker.rb:51:5:51:13 | synthetic splat argument |
| type_tracker.rb:34:26:34:26 | z | type tracker without call steps | type_tracker.rb:34:26:34:26 | z |
| type_tracker.rb:34:26:34:26 | z | type tracker without call steps | type_tracker.rb:34:26:34:26 | z |
| type_tracker.rb:34:26:34:26 | z | type tracker without call steps with content element 0 | type_tracker.rb:52:5:52:13 | * |
| type_tracker.rb:34:26:34:26 | z | type tracker without call steps with content splat position 0 | type_tracker.rb:52:5:52:13 | synthetic splat argument |
| type_tracker.rb:35:5:35:7 | tmp | type tracker without call steps | type_tracker.rb:35:5:35:7 | tmp |
| type_tracker.rb:35:11:35:15 | * | type tracker without call steps | type_tracker.rb:35:11:35:15 | * |
| type_tracker.rb:35:11:35:15 | Array | type tracker without call steps | type_tracker.rb:35:11:35:15 | Array |
| type_tracker.rb:35:11:35:15 | call to [] | type tracker without call steps | type_tracker.rb:35:11:35:15 | call to [] |
| type_tracker.rb:36:5:36:10 | * | type tracker without call steps | type_tracker.rb:36:5:36:10 | * |
| type_tracker.rb:35:11:35:15 | synthetic splat argument | type tracker without call steps | type_tracker.rb:35:11:35:15 | call to [] |
| type_tracker.rb:35:11:35:15 | synthetic splat argument | type tracker without call steps | type_tracker.rb:35:11:35:15 | synthetic splat argument |
| type_tracker.rb:36:5:36:10 | ...[...] | type tracker without call steps | type_tracker.rb:36:5:36:10 | ...[...] |
| type_tracker.rb:36:5:36:10 | synthetic splat argument | type tracker without call steps | type_tracker.rb:36:5:36:10 | synthetic splat argument |
| type_tracker.rb:36:9:36:9 | 0 | type tracker without call steps | type_tracker.rb:36:9:36:9 | 0 |
| type_tracker.rb:36:9:36:9 | 0 | type tracker without call steps with content element 0 | type_tracker.rb:36:5:36:10 | * |
| type_tracker.rb:36:9:36:9 | 0 | type tracker without call steps with content splat position 0 | type_tracker.rb:36:5:36:10 | synthetic splat argument |
| type_tracker.rb:38:5:38:9 | array | type tracker without call steps | type_tracker.rb:38:5:38:9 | array |
| type_tracker.rb:38:13:38:25 | * | type tracker without call steps | type_tracker.rb:38:13:38:25 | * |
| type_tracker.rb:38:13:38:25 | Array | type tracker without call steps | type_tracker.rb:38:13:38:25 | Array |
| type_tracker.rb:38:13:38:25 | call to [] | type tracker without call steps | type_tracker.rb:38:13:38:25 | call to [] |
| type_tracker.rb:38:13:38:25 | synthetic splat argument | type tracker without call steps | type_tracker.rb:38:13:38:25 | call to [] |
| type_tracker.rb:38:13:38:25 | synthetic splat argument | type tracker without call steps | type_tracker.rb:38:13:38:25 | synthetic splat argument |
| type_tracker.rb:38:14:38:14 | 1 | type tracker without call steps | type_tracker.rb:38:14:38:14 | 1 |
| type_tracker.rb:38:14:38:14 | 1 | type tracker without call steps | type_tracker.rb:40:5:40:12 | ...[...] |
| type_tracker.rb:38:14:38:14 | 1 | type tracker without call steps with content element 0 | type_tracker.rb:38:13:38:25 | * |
| type_tracker.rb:38:14:38:14 | 1 | type tracker without call steps with content element 0 or unknown | type_tracker.rb:38:13:38:25 | call to [] |
| type_tracker.rb:38:14:38:14 | 1 | type tracker without call steps with content element 0 | type_tracker.rb:38:13:38:25 | call to [] |
| type_tracker.rb:38:14:38:14 | 1 | type tracker without call steps with content element 0 | type_tracker.rb:38:13:38:25 | synthetic splat argument |
| type_tracker.rb:38:16:38:16 | 2 | type tracker without call steps | type_tracker.rb:38:16:38:16 | 2 |
| type_tracker.rb:38:16:38:16 | 2 | type tracker without call steps with content element 1 | type_tracker.rb:38:13:38:25 | * |
| type_tracker.rb:38:16:38:16 | 2 | type tracker without call steps with content element 1 or unknown | type_tracker.rb:38:13:38:25 | call to [] |
| type_tracker.rb:38:16:38:16 | 2 | type tracker without call steps with content element 1 | type_tracker.rb:38:13:38:25 | call to [] |
| type_tracker.rb:38:16:38:16 | 2 | type tracker without call steps with content element 1 | type_tracker.rb:38:13:38:25 | synthetic splat argument |
| type_tracker.rb:38:18:38:18 | 3 | type tracker without call steps | type_tracker.rb:38:18:38:18 | 3 |
| type_tracker.rb:38:18:38:18 | 3 | type tracker without call steps with content element 2 | type_tracker.rb:38:13:38:25 | * |
| type_tracker.rb:38:18:38:18 | 3 | type tracker without call steps with content element 2 or unknown | type_tracker.rb:38:13:38:25 | call to [] |
| type_tracker.rb:38:18:38:18 | 3 | type tracker without call steps with content element 2 | type_tracker.rb:38:13:38:25 | call to [] |
| type_tracker.rb:38:18:38:18 | 3 | type tracker without call steps with content element 2 | type_tracker.rb:38:13:38:25 | synthetic splat argument |
| type_tracker.rb:38:20:38:20 | 4 | type tracker without call steps | type_tracker.rb:38:20:38:20 | 4 |
| type_tracker.rb:38:20:38:20 | 4 | type tracker without call steps with content element 3 | type_tracker.rb:38:13:38:25 | * |
| type_tracker.rb:38:20:38:20 | 4 | type tracker without call steps with content element 3 or unknown | type_tracker.rb:38:13:38:25 | call to [] |
| type_tracker.rb:38:20:38:20 | 4 | type tracker without call steps with content element 3 | type_tracker.rb:38:13:38:25 | call to [] |
| type_tracker.rb:38:20:38:20 | 4 | type tracker without call steps with content element 3 | type_tracker.rb:38:13:38:25 | synthetic splat argument |
| type_tracker.rb:38:22:38:22 | 5 | type tracker without call steps | type_tracker.rb:38:22:38:22 | 5 |
| type_tracker.rb:38:22:38:22 | 5 | type tracker without call steps with content element 4 | type_tracker.rb:38:13:38:25 | * |
| type_tracker.rb:38:22:38:22 | 5 | type tracker without call steps with content element 4 or unknown | type_tracker.rb:38:13:38:25 | call to [] |
| type_tracker.rb:38:22:38:22 | 5 | type tracker without call steps with content element 4 | type_tracker.rb:38:13:38:25 | call to [] |
| type_tracker.rb:38:22:38:22 | 5 | type tracker without call steps with content element 4 | type_tracker.rb:38:13:38:25 | synthetic splat argument |
| type_tracker.rb:38:24:38:24 | 6 | type tracker without call steps | type_tracker.rb:38:24:38:24 | 6 |
| type_tracker.rb:38:24:38:24 | 6 | type tracker without call steps with content element 5 | type_tracker.rb:38:13:38:25 | * |
| type_tracker.rb:38:24:38:24 | 6 | type tracker without call steps with content element 5 or unknown | type_tracker.rb:38:13:38:25 | call to [] |
| type_tracker.rb:38:24:38:24 | 6 | type tracker without call steps with content element 5 | type_tracker.rb:38:13:38:25 | call to [] |
| type_tracker.rb:38:24:38:24 | 6 | type tracker without call steps with content element 5 | type_tracker.rb:38:13:38:25 | synthetic splat argument |
| type_tracker.rb:39:5:39:9 | [post] array | type tracker without call steps | type_tracker.rb:39:5:39:9 | [post] array |
| type_tracker.rb:39:5:39:12 | * | type tracker without call steps | type_tracker.rb:39:5:39:12 | * |
| type_tracker.rb:39:5:39:12 | call to []= | type tracker without call steps | type_tracker.rb:39:5:39:12 | call to []= |
| type_tracker.rb:39:5:39:12 | synthetic splat argument | type tracker without call steps | type_tracker.rb:39:5:39:12 | synthetic splat argument |
| type_tracker.rb:39:16:39:18 | __synth__0 | type tracker without call steps | type_tracker.rb:39:16:39:18 | __synth__0 |
| type_tracker.rb:40:5:40:12 | * | type tracker without call steps | type_tracker.rb:40:5:40:12 | * |
| type_tracker.rb:40:5:40:12 | ...[...] | type tracker without call steps | type_tracker.rb:40:5:40:12 | ...[...] |
| type_tracker.rb:40:5:40:12 | synthetic splat argument | type tracker without call steps | type_tracker.rb:40:5:40:12 | synthetic splat argument |
| type_tracker.rb:40:11:40:11 | 0 | type tracker without call steps | type_tracker.rb:40:11:40:11 | 0 |
| type_tracker.rb:40:11:40:11 | 0 | type tracker without call steps with content element 0 | type_tracker.rb:40:5:40:12 | * |
| type_tracker.rb:40:11:40:11 | 0 | type tracker without call steps with content splat position 0 | type_tracker.rb:40:5:40:12 | synthetic splat argument |
| type_tracker.rb:42:5:42:10 | array2 | type tracker without call steps | type_tracker.rb:42:5:42:10 | array2 |
| type_tracker.rb:42:14:42:26 | * | type tracker without call steps | type_tracker.rb:42:14:42:26 | * |
| type_tracker.rb:42:14:42:26 | Array | type tracker without call steps | type_tracker.rb:42:14:42:26 | Array |
| type_tracker.rb:42:14:42:26 | call to [] | type tracker without call steps | type_tracker.rb:42:14:42:26 | call to [] |
| type_tracker.rb:42:14:42:26 | synthetic splat argument | type tracker without call steps | type_tracker.rb:42:14:42:26 | call to [] |
| type_tracker.rb:42:14:42:26 | synthetic splat argument | type tracker without call steps | type_tracker.rb:42:14:42:26 | synthetic splat argument |
| type_tracker.rb:42:15:42:15 | 1 | type tracker without call steps | type_tracker.rb:42:15:42:15 | 1 |
| type_tracker.rb:42:15:42:15 | 1 | type tracker without call steps | type_tracker.rb:44:5:44:13 | ...[...] |
| type_tracker.rb:42:15:42:15 | 1 | type tracker without call steps with content element 0 | type_tracker.rb:42:14:42:26 | * |
| type_tracker.rb:42:15:42:15 | 1 | type tracker without call steps with content element 0 or unknown | type_tracker.rb:42:14:42:26 | call to [] |
| type_tracker.rb:42:15:42:15 | 1 | type tracker without call steps with content element 0 | type_tracker.rb:42:14:42:26 | call to [] |
| type_tracker.rb:42:15:42:15 | 1 | type tracker without call steps with content element 0 | type_tracker.rb:42:14:42:26 | synthetic splat argument |
| type_tracker.rb:42:17:42:17 | 2 | type tracker without call steps | type_tracker.rb:42:17:42:17 | 2 |
| type_tracker.rb:42:17:42:17 | 2 | type tracker without call steps | type_tracker.rb:44:5:44:13 | ...[...] |
| type_tracker.rb:42:17:42:17 | 2 | type tracker without call steps with content element 1 | type_tracker.rb:42:14:42:26 | * |
| type_tracker.rb:42:17:42:17 | 2 | type tracker without call steps with content element 1 or unknown | type_tracker.rb:42:14:42:26 | call to [] |
| type_tracker.rb:42:17:42:17 | 2 | type tracker without call steps with content element 1 | type_tracker.rb:42:14:42:26 | call to [] |
| type_tracker.rb:42:17:42:17 | 2 | type tracker without call steps with content element 1 | type_tracker.rb:42:14:42:26 | synthetic splat argument |
| type_tracker.rb:42:19:42:19 | 3 | type tracker without call steps | type_tracker.rb:42:19:42:19 | 3 |
| type_tracker.rb:42:19:42:19 | 3 | type tracker without call steps | type_tracker.rb:44:5:44:13 | ...[...] |
| type_tracker.rb:42:19:42:19 | 3 | type tracker without call steps with content element 2 | type_tracker.rb:42:14:42:26 | * |
| type_tracker.rb:42:19:42:19 | 3 | type tracker without call steps with content element 2 or unknown | type_tracker.rb:42:14:42:26 | call to [] |
| type_tracker.rb:42:19:42:19 | 3 | type tracker without call steps with content element 2 | type_tracker.rb:42:14:42:26 | call to [] |
| type_tracker.rb:42:19:42:19 | 3 | type tracker without call steps with content element 2 | type_tracker.rb:42:14:42:26 | synthetic splat argument |
| type_tracker.rb:42:21:42:21 | 4 | type tracker without call steps | type_tracker.rb:42:21:42:21 | 4 |
| type_tracker.rb:42:21:42:21 | 4 | type tracker without call steps | type_tracker.rb:44:5:44:13 | ...[...] |
| type_tracker.rb:42:21:42:21 | 4 | type tracker without call steps with content element 3 | type_tracker.rb:42:14:42:26 | * |
| type_tracker.rb:42:21:42:21 | 4 | type tracker without call steps with content element 3 or unknown | type_tracker.rb:42:14:42:26 | call to [] |
| type_tracker.rb:42:21:42:21 | 4 | type tracker without call steps with content element 3 | type_tracker.rb:42:14:42:26 | call to [] |
| type_tracker.rb:42:21:42:21 | 4 | type tracker without call steps with content element 3 | type_tracker.rb:42:14:42:26 | synthetic splat argument |
| type_tracker.rb:42:23:42:23 | 5 | type tracker without call steps | type_tracker.rb:42:23:42:23 | 5 |
| type_tracker.rb:42:23:42:23 | 5 | type tracker without call steps | type_tracker.rb:44:5:44:13 | ...[...] |
| type_tracker.rb:42:23:42:23 | 5 | type tracker without call steps with content element 4 | type_tracker.rb:42:14:42:26 | * |
| type_tracker.rb:42:23:42:23 | 5 | type tracker without call steps with content element 4 or unknown | type_tracker.rb:42:14:42:26 | call to [] |
| type_tracker.rb:42:23:42:23 | 5 | type tracker without call steps with content element 4 | type_tracker.rb:42:14:42:26 | call to [] |
| type_tracker.rb:42:23:42:23 | 5 | type tracker without call steps with content element 4 | type_tracker.rb:42:14:42:26 | synthetic splat argument |
| type_tracker.rb:42:25:42:25 | 6 | type tracker without call steps | type_tracker.rb:42:25:42:25 | 6 |
| type_tracker.rb:42:25:42:25 | 6 | type tracker without call steps | type_tracker.rb:44:5:44:13 | ...[...] |
| type_tracker.rb:42:25:42:25 | 6 | type tracker without call steps with content element 5 | type_tracker.rb:42:14:42:26 | * |
| type_tracker.rb:42:25:42:25 | 6 | type tracker without call steps with content element 5 or unknown | type_tracker.rb:42:14:42:26 | call to [] |
| type_tracker.rb:42:25:42:25 | 6 | type tracker without call steps with content element 5 | type_tracker.rb:42:14:42:26 | call to [] |
| type_tracker.rb:42:25:42:25 | 6 | type tracker without call steps with content element 5 | type_tracker.rb:42:14:42:26 | synthetic splat argument |
| type_tracker.rb:43:5:43:10 | [post] array2 | type tracker without call steps | type_tracker.rb:43:5:43:10 | [post] array2 |
| type_tracker.rb:43:5:43:13 | * | type tracker without call steps | type_tracker.rb:43:5:43:13 | * |
| type_tracker.rb:43:5:43:13 | call to []= | type tracker without call steps | type_tracker.rb:43:5:43:13 | call to []= |
| type_tracker.rb:43:5:43:13 | synthetic splat argument | type tracker without call steps | type_tracker.rb:43:5:43:13 | synthetic splat argument |
| type_tracker.rb:43:12:43:12 | 0 | type tracker without call steps | type_tracker.rb:43:12:43:12 | 0 |
| type_tracker.rb:43:12:43:12 | 0 | type tracker without call steps with content element 0 | type_tracker.rb:43:5:43:13 | * |
| type_tracker.rb:43:12:43:12 | 0 | type tracker without call steps with content splat position 0 | type_tracker.rb:43:5:43:13 | synthetic splat argument |
| type_tracker.rb:43:17:43:19 | __synth__0 | type tracker without call steps | type_tracker.rb:43:17:43:19 | __synth__0 |
| type_tracker.rb:44:5:44:13 | * | type tracker without call steps | type_tracker.rb:44:5:44:13 | * |
| type_tracker.rb:44:5:44:13 | ...[...] | type tracker without call steps | type_tracker.rb:44:5:44:13 | ...[...] |
| type_tracker.rb:44:5:44:13 | synthetic splat argument | type tracker without call steps | type_tracker.rb:44:5:44:13 | synthetic splat argument |
| type_tracker.rb:46:5:46:10 | array3 | type tracker without call steps | type_tracker.rb:46:5:46:10 | array3 |
| type_tracker.rb:46:14:46:26 | * | type tracker without call steps | type_tracker.rb:46:14:46:26 | * |
| type_tracker.rb:46:14:46:26 | Array | type tracker without call steps | type_tracker.rb:46:14:46:26 | Array |
| type_tracker.rb:46:14:46:26 | call to [] | type tracker without call steps | type_tracker.rb:46:14:46:26 | call to [] |
| type_tracker.rb:46:14:46:26 | synthetic splat argument | type tracker without call steps | type_tracker.rb:46:14:46:26 | call to [] |
| type_tracker.rb:46:14:46:26 | synthetic splat argument | type tracker without call steps | type_tracker.rb:46:14:46:26 | synthetic splat argument |
| type_tracker.rb:46:15:46:15 | 1 | type tracker without call steps | type_tracker.rb:46:15:46:15 | 1 |
| type_tracker.rb:46:15:46:15 | 1 | type tracker without call steps with content element 0 | type_tracker.rb:46:14:46:26 | * |
| type_tracker.rb:46:15:46:15 | 1 | type tracker without call steps with content element 0 or unknown | type_tracker.rb:46:14:46:26 | call to [] |
| type_tracker.rb:46:15:46:15 | 1 | type tracker without call steps with content element 0 | type_tracker.rb:46:14:46:26 | call to [] |
| type_tracker.rb:46:15:46:15 | 1 | type tracker without call steps with content element 0 | type_tracker.rb:46:14:46:26 | synthetic splat argument |
| type_tracker.rb:46:17:46:17 | 2 | type tracker without call steps | type_tracker.rb:46:17:46:17 | 2 |
| type_tracker.rb:46:17:46:17 | 2 | type tracker without call steps | type_tracker.rb:48:5:48:13 | ...[...] |
| type_tracker.rb:46:17:46:17 | 2 | type tracker without call steps with content element 1 | type_tracker.rb:46:14:46:26 | * |
| type_tracker.rb:46:17:46:17 | 2 | type tracker without call steps with content element 1 or unknown | type_tracker.rb:46:14:46:26 | call to [] |
| type_tracker.rb:46:17:46:17 | 2 | type tracker without call steps with content element 1 | type_tracker.rb:46:14:46:26 | call to [] |
| type_tracker.rb:46:17:46:17 | 2 | type tracker without call steps with content element 1 | type_tracker.rb:46:14:46:26 | synthetic splat argument |
| type_tracker.rb:46:19:46:19 | 3 | type tracker without call steps | type_tracker.rb:46:19:46:19 | 3 |
| type_tracker.rb:46:19:46:19 | 3 | type tracker without call steps with content element 2 | type_tracker.rb:46:14:46:26 | * |
| type_tracker.rb:46:19:46:19 | 3 | type tracker without call steps with content element 2 or unknown | type_tracker.rb:46:14:46:26 | call to [] |
| type_tracker.rb:46:19:46:19 | 3 | type tracker without call steps with content element 2 | type_tracker.rb:46:14:46:26 | call to [] |
| type_tracker.rb:46:19:46:19 | 3 | type tracker without call steps with content element 2 | type_tracker.rb:46:14:46:26 | synthetic splat argument |
| type_tracker.rb:46:21:46:21 | 4 | type tracker without call steps | type_tracker.rb:46:21:46:21 | 4 |
| type_tracker.rb:46:21:46:21 | 4 | type tracker without call steps with content element 3 | type_tracker.rb:46:14:46:26 | * |
| type_tracker.rb:46:21:46:21 | 4 | type tracker without call steps with content element 3 or unknown | type_tracker.rb:46:14:46:26 | call to [] |
| type_tracker.rb:46:21:46:21 | 4 | type tracker without call steps with content element 3 | type_tracker.rb:46:14:46:26 | call to [] |
| type_tracker.rb:46:21:46:21 | 4 | type tracker without call steps with content element 3 | type_tracker.rb:46:14:46:26 | synthetic splat argument |
| type_tracker.rb:46:23:46:23 | 5 | type tracker without call steps | type_tracker.rb:46:23:46:23 | 5 |
| type_tracker.rb:46:23:46:23 | 5 | type tracker without call steps with content element 4 | type_tracker.rb:46:14:46:26 | * |
| type_tracker.rb:46:23:46:23 | 5 | type tracker without call steps with content element 4 or unknown | type_tracker.rb:46:14:46:26 | call to [] |
| type_tracker.rb:46:23:46:23 | 5 | type tracker without call steps with content element 4 | type_tracker.rb:46:14:46:26 | call to [] |
| type_tracker.rb:46:23:46:23 | 5 | type tracker without call steps with content element 4 | type_tracker.rb:46:14:46:26 | synthetic splat argument |
| type_tracker.rb:46:25:46:25 | 6 | type tracker without call steps | type_tracker.rb:46:25:46:25 | 6 |
| type_tracker.rb:46:25:46:25 | 6 | type tracker without call steps with content element 5 | type_tracker.rb:46:14:46:26 | * |
| type_tracker.rb:46:25:46:25 | 6 | type tracker without call steps with content element 5 or unknown | type_tracker.rb:46:14:46:26 | call to [] |
| type_tracker.rb:46:25:46:25 | 6 | type tracker without call steps with content element 5 | type_tracker.rb:46:14:46:26 | call to [] |
| type_tracker.rb:46:25:46:25 | 6 | type tracker without call steps with content element 5 | type_tracker.rb:46:14:46:26 | synthetic splat argument |
| type_tracker.rb:47:5:47:10 | [post] array3 | type tracker without call steps | type_tracker.rb:47:5:47:10 | [post] array3 |
| type_tracker.rb:47:5:47:13 | * | type tracker without call steps | type_tracker.rb:47:5:47:13 | * |
| type_tracker.rb:47:5:47:13 | call to []= | type tracker without call steps | type_tracker.rb:47:5:47:13 | call to []= |
| type_tracker.rb:47:5:47:13 | synthetic splat argument | type tracker without call steps | type_tracker.rb:47:5:47:13 | synthetic splat argument |
| type_tracker.rb:47:12:47:12 | 0 | type tracker without call steps | type_tracker.rb:47:12:47:12 | 0 |
| type_tracker.rb:47:12:47:12 | 0 | type tracker without call steps with content element 0 | type_tracker.rb:47:5:47:13 | * |
| type_tracker.rb:47:12:47:12 | 0 | type tracker without call steps with content splat position 0 | type_tracker.rb:47:5:47:13 | synthetic splat argument |
| type_tracker.rb:47:17:47:19 | __synth__0 | type tracker without call steps | type_tracker.rb:47:17:47:19 | __synth__0 |
| type_tracker.rb:48:5:48:13 | * | type tracker without call steps | type_tracker.rb:48:5:48:13 | * |
| type_tracker.rb:48:5:48:13 | ...[...] | type tracker without call steps | type_tracker.rb:48:5:48:13 | ...[...] |
| type_tracker.rb:48:5:48:13 | synthetic splat argument | type tracker without call steps | type_tracker.rb:48:5:48:13 | synthetic splat argument |
| type_tracker.rb:48:12:48:12 | 1 | type tracker without call steps | type_tracker.rb:48:12:48:12 | 1 |
| type_tracker.rb:48:12:48:12 | 1 | type tracker without call steps with content element 0 | type_tracker.rb:48:5:48:13 | * |
| type_tracker.rb:48:12:48:12 | 1 | type tracker without call steps with content splat position 0 | type_tracker.rb:48:5:48:13 | synthetic splat argument |
| type_tracker.rb:50:5:50:10 | array4 | type tracker without call steps | type_tracker.rb:50:5:50:10 | array4 |
| type_tracker.rb:50:14:50:26 | * | type tracker without call steps | type_tracker.rb:50:14:50:26 | * |
| type_tracker.rb:50:14:50:26 | Array | type tracker without call steps | type_tracker.rb:50:14:50:26 | Array |
| type_tracker.rb:50:14:50:26 | call to [] | type tracker without call steps | type_tracker.rb:50:14:50:26 | call to [] |
| type_tracker.rb:50:14:50:26 | synthetic splat argument | type tracker without call steps | type_tracker.rb:50:14:50:26 | call to [] |
| type_tracker.rb:50:14:50:26 | synthetic splat argument | type tracker without call steps | type_tracker.rb:50:14:50:26 | synthetic splat argument |
| type_tracker.rb:50:15:50:15 | 1 | type tracker without call steps | type_tracker.rb:50:15:50:15 | 1 |
| type_tracker.rb:50:15:50:15 | 1 | type tracker without call steps | type_tracker.rb:52:5:52:13 | ...[...] |
| type_tracker.rb:50:15:50:15 | 1 | type tracker without call steps with content element 0 | type_tracker.rb:50:14:50:26 | * |
| type_tracker.rb:50:15:50:15 | 1 | type tracker without call steps with content element 0 or unknown | type_tracker.rb:50:14:50:26 | call to [] |
| type_tracker.rb:50:15:50:15 | 1 | type tracker without call steps with content element 0 | type_tracker.rb:50:14:50:26 | call to [] |
| type_tracker.rb:50:15:50:15 | 1 | type tracker without call steps with content element 0 | type_tracker.rb:50:14:50:26 | synthetic splat argument |
| type_tracker.rb:50:17:50:17 | 2 | type tracker without call steps | type_tracker.rb:50:17:50:17 | 2 |
| type_tracker.rb:50:17:50:17 | 2 | type tracker without call steps | type_tracker.rb:52:5:52:13 | ...[...] |
| type_tracker.rb:50:17:50:17 | 2 | type tracker without call steps with content element 1 | type_tracker.rb:50:14:50:26 | * |
| type_tracker.rb:50:17:50:17 | 2 | type tracker without call steps with content element 1 or unknown | type_tracker.rb:50:14:50:26 | call to [] |
| type_tracker.rb:50:17:50:17 | 2 | type tracker without call steps with content element 1 | type_tracker.rb:50:14:50:26 | call to [] |
| type_tracker.rb:50:17:50:17 | 2 | type tracker without call steps with content element 1 | type_tracker.rb:50:14:50:26 | synthetic splat argument |
| type_tracker.rb:50:19:50:19 | 3 | type tracker without call steps | type_tracker.rb:50:19:50:19 | 3 |
| type_tracker.rb:50:19:50:19 | 3 | type tracker without call steps | type_tracker.rb:52:5:52:13 | ...[...] |
| type_tracker.rb:50:19:50:19 | 3 | type tracker without call steps with content element 2 | type_tracker.rb:50:14:50:26 | * |
| type_tracker.rb:50:19:50:19 | 3 | type tracker without call steps with content element 2 or unknown | type_tracker.rb:50:14:50:26 | call to [] |
| type_tracker.rb:50:19:50:19 | 3 | type tracker without call steps with content element 2 | type_tracker.rb:50:14:50:26 | call to [] |
| type_tracker.rb:50:19:50:19 | 3 | type tracker without call steps with content element 2 | type_tracker.rb:50:14:50:26 | synthetic splat argument |
| type_tracker.rb:50:21:50:21 | 4 | type tracker without call steps | type_tracker.rb:50:21:50:21 | 4 |
| type_tracker.rb:50:21:50:21 | 4 | type tracker without call steps | type_tracker.rb:52:5:52:13 | ...[...] |
| type_tracker.rb:50:21:50:21 | 4 | type tracker without call steps with content element 3 | type_tracker.rb:50:14:50:26 | * |
| type_tracker.rb:50:21:50:21 | 4 | type tracker without call steps with content element 3 or unknown | type_tracker.rb:50:14:50:26 | call to [] |
| type_tracker.rb:50:21:50:21 | 4 | type tracker without call steps with content element 3 | type_tracker.rb:50:14:50:26 | call to [] |
| type_tracker.rb:50:21:50:21 | 4 | type tracker without call steps with content element 3 | type_tracker.rb:50:14:50:26 | synthetic splat argument |
| type_tracker.rb:50:23:50:23 | 5 | type tracker without call steps | type_tracker.rb:50:23:50:23 | 5 |
| type_tracker.rb:50:23:50:23 | 5 | type tracker without call steps | type_tracker.rb:52:5:52:13 | ...[...] |
| type_tracker.rb:50:23:50:23 | 5 | type tracker without call steps with content element 4 | type_tracker.rb:50:14:50:26 | * |
| type_tracker.rb:50:23:50:23 | 5 | type tracker without call steps with content element 4 or unknown | type_tracker.rb:50:14:50:26 | call to [] |
| type_tracker.rb:50:23:50:23 | 5 | type tracker without call steps with content element 4 | type_tracker.rb:50:14:50:26 | call to [] |
| type_tracker.rb:50:23:50:23 | 5 | type tracker without call steps with content element 4 | type_tracker.rb:50:14:50:26 | synthetic splat argument |
| type_tracker.rb:50:25:50:25 | 6 | type tracker without call steps | type_tracker.rb:50:25:50:25 | 6 |
| type_tracker.rb:50:25:50:25 | 6 | type tracker without call steps | type_tracker.rb:52:5:52:13 | ...[...] |
| type_tracker.rb:50:25:50:25 | 6 | type tracker without call steps with content element 5 | type_tracker.rb:50:14:50:26 | * |
| type_tracker.rb:50:25:50:25 | 6 | type tracker without call steps with content element 5 or unknown | type_tracker.rb:50:14:50:26 | call to [] |
| type_tracker.rb:50:25:50:25 | 6 | type tracker without call steps with content element 5 | type_tracker.rb:50:14:50:26 | call to [] |
| type_tracker.rb:50:25:50:25 | 6 | type tracker without call steps with content element 5 | type_tracker.rb:50:14:50:26 | synthetic splat argument |
| type_tracker.rb:51:5:51:10 | [post] array4 | type tracker without call steps | type_tracker.rb:51:5:51:10 | [post] array4 |
| type_tracker.rb:51:5:51:13 | * | type tracker without call steps | type_tracker.rb:51:5:51:13 | * |
| type_tracker.rb:51:5:51:13 | call to []= | type tracker without call steps | type_tracker.rb:51:5:51:13 | call to []= |
| type_tracker.rb:51:5:51:13 | synthetic splat argument | type tracker without call steps | type_tracker.rb:51:5:51:13 | synthetic splat argument |
| type_tracker.rb:51:17:51:19 | __synth__0 | type tracker without call steps | type_tracker.rb:51:17:51:19 | __synth__0 |
| type_tracker.rb:52:5:52:13 | * | type tracker without call steps | type_tracker.rb:52:5:52:13 | * |
| type_tracker.rb:52:5:52:13 | ...[...] | type tracker without call steps | type_tracker.rb:52:5:52:13 | ...[...] |
| type_tracker.rb:52:5:52:13 | synthetic splat argument | type tracker without call steps | type_tracker.rb:52:5:52:13 | synthetic splat argument |
trackEnd
| type_tracker.rb:1:1:10:3 | self (Container) | type_tracker.rb:1:1:10:3 | self (Container) |
| type_tracker.rb:1:1:53:4 | self (type_tracker.rb) | type_tracker.rb:1:1:53:4 | self (type_tracker.rb) |
@@ -348,7 +353,7 @@ trackEnd
| 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:5:5:7 | synthetic *args | type_tracker.rb:2:5:5:7 | synthetic *args |
| type_tracker.rb:2:5:5:7 | synthetic splat parameter | type_tracker.rb:2:5:5:7 | synthetic splat parameter |
| 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 |
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:2:16:2:18 | val |
@@ -358,8 +363,8 @@ trackEnd
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:8:9:8:14 | @field |
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:14:5:14:13 | call to field= |
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:15:10:15:18 | call to field |
| type_tracker.rb:3:9:3:23 | * | type_tracker.rb:3:9:3:23 | * |
| type_tracker.rb:3:9:3:23 | call to puts | type_tracker.rb:3:9:3:23 | call to puts |
| type_tracker.rb:3:9:3:23 | synthetic splat argument | type_tracker.rb:3:9:3:23 | synthetic splat argument |
| 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:7:5:9:7 | &block | type_tracker.rb:7:5:9:7 | &block |
@@ -396,9 +401,9 @@ trackEnd
| 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 | * | type_tracker.rb:2:5:5:7 | synthetic *args |
| type_tracker.rb:14:5:14:13 | * | type_tracker.rb:14:5:14:13 | * |
| type_tracker.rb:14:5:14:13 | call to field= | type_tracker.rb:14:5:14:13 | call to field= |
| type_tracker.rb:14:5:14:13 | synthetic splat argument | type_tracker.rb:2:5:5:7 | synthetic splat parameter |
| type_tracker.rb:14:5:14:13 | synthetic splat argument | type_tracker.rb:14:5:14:13 | synthetic splat argument |
| type_tracker.rb:14:17:14:23 | "hello" | type_tracker.rb:2:16:2:18 | val |
| type_tracker.rb:14:17:14:23 | "hello" | type_tracker.rb:2:16:2:18 | val |
| type_tracker.rb:14:17:14:23 | "hello" | type_tracker.rb:4:9:4:20 | ... = ... |
@@ -412,8 +417,8 @@ trackEnd
| type_tracker.rb:14:17:14:23 | "hello" | type_tracker.rb:14:17:14:23 | __synth__0 |
| type_tracker.rb:14:17:14:23 | "hello" | type_tracker.rb:15:10:15:18 | call to field |
| type_tracker.rb:14:17:14:23 | __synth__0 | type_tracker.rb:14:17:14:23 | __synth__0 |
| type_tracker.rb:15:5:15:18 | * | type_tracker.rb:15:5:15:18 | * |
| type_tracker.rb:15:5:15:18 | call to puts | type_tracker.rb:15:5:15:18 | call to puts |
| type_tracker.rb:15:5:15:18 | synthetic splat argument | type_tracker.rb:15:5:15:18 | synthetic splat argument |
| type_tracker.rb:15:10:15:18 | call to field | type_tracker.rb:15:10:15:18 | call to field |
| type_tracker.rb:18:1:21:3 | &block | type_tracker.rb:18:1:21:3 | &block |
| type_tracker.rb:18:1:21:3 | positional | type_tracker.rb:18:1:21:3 | positional |
@@ -421,7 +426,7 @@ trackEnd
| type_tracker.rb:18:1:21:3 | self in positional | type_tracker.rb:18:1:21:3 | self in positional |
| type_tracker.rb:18:1:21:3 | self in positional | type_tracker.rb:19:5:19:11 | self |
| type_tracker.rb:18:1:21:3 | self in positional | type_tracker.rb:20:5:20:11 | self |
| type_tracker.rb:18:1:21:3 | synthetic *args | type_tracker.rb:18:1:21:3 | synthetic *args |
| type_tracker.rb:18:1:21:3 | synthetic splat parameter | type_tracker.rb:18:1:21:3 | synthetic splat parameter |
| type_tracker.rb:18:16:18:17 | p1 | type_tracker.rb:18:16:18:17 | p1 |
| type_tracker.rb:18:16:18:17 | p1 | type_tracker.rb:18:16:18:17 | p1 |
| type_tracker.rb:18:16:18:17 | p1 | type_tracker.rb:18:16:18:17 | p1 |
@@ -430,14 +435,14 @@ trackEnd
| type_tracker.rb:18:20:18:21 | p2 | type_tracker.rb:18:20:18:21 | p2 |
| type_tracker.rb:18:20:18:21 | p2 | type_tracker.rb:18:20:18:21 | p2 |
| type_tracker.rb:18:20:18:21 | p2 | type_tracker.rb:20:10:20:11 | p2 |
| type_tracker.rb:19:5:19:11 | * | type_tracker.rb:19:5:19:11 | * |
| type_tracker.rb:19:5:19:11 | call to puts | type_tracker.rb:19:5:19:11 | call to puts |
| type_tracker.rb:20:5:20:11 | * | type_tracker.rb:20:5:20:11 | * |
| type_tracker.rb:19:5:19:11 | synthetic splat argument | type_tracker.rb:19:5:19:11 | synthetic splat argument |
| type_tracker.rb:20:5:20:11 | call to puts | type_tracker.rb:20:5:20:11 | call to puts |
| type_tracker.rb:20:5:20:11 | call to puts | type_tracker.rb:23:1:23:16 | call to positional |
| type_tracker.rb:23:1:23:16 | * | type_tracker.rb:18:1:21:3 | synthetic *args |
| type_tracker.rb:23:1:23:16 | * | type_tracker.rb:23:1:23:16 | * |
| type_tracker.rb:20:5:20:11 | synthetic splat argument | type_tracker.rb:20:5:20:11 | synthetic splat argument |
| type_tracker.rb:23:1:23:16 | call to positional | type_tracker.rb:23:1:23:16 | call to positional |
| type_tracker.rb:23:1:23:16 | synthetic splat argument | type_tracker.rb:18:1:21:3 | synthetic splat parameter |
| type_tracker.rb:23:1:23:16 | synthetic splat argument | type_tracker.rb:23:1:23:16 | synthetic splat argument |
| type_tracker.rb:23:12:23:12 | 1 | type_tracker.rb:18:16:18:17 | p1 |
| type_tracker.rb:23:12:23:12 | 1 | type_tracker.rb:18:16:18:17 | p1 |
| type_tracker.rb:23:12:23:12 | 1 | type_tracker.rb:19:10:19:11 | p1 |
@@ -447,12 +452,12 @@ trackEnd
| type_tracker.rb:23:15:23:15 | 2 | type_tracker.rb:20:10:20:11 | p2 |
| type_tracker.rb:23:15:23:15 | 2 | type_tracker.rb:23:15:23:15 | 2 |
| type_tracker.rb:25:1:28:3 | &block | type_tracker.rb:25:1:28:3 | &block |
| type_tracker.rb:25:1:28:3 | **kwargs | type_tracker.rb:25:1:28:3 | **kwargs |
| type_tracker.rb:25:1:28:3 | keyword | type_tracker.rb:25:1:28:3 | keyword |
| type_tracker.rb:25:1:28:3 | self in keyword | type_tracker.rb:25:1:28:3 | self (keyword) |
| type_tracker.rb:25:1:28:3 | self in keyword | type_tracker.rb:25:1:28:3 | self in keyword |
| type_tracker.rb:25:1:28:3 | self in keyword | type_tracker.rb:26:5:26:11 | self |
| type_tracker.rb:25:1:28:3 | self in keyword | type_tracker.rb:27:5:27:11 | self |
| type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter |
| type_tracker.rb:25:13:25:14 | p1 | type_tracker.rb:25:13:25:14 | p1 |
| type_tracker.rb:25:13:25:14 | p1 | type_tracker.rb:25:13:25:14 | p1 |
| type_tracker.rb:25:13:25:14 | p1 | type_tracker.rb:25:13:25:14 | p1 |
@@ -461,16 +466,16 @@ trackEnd
| type_tracker.rb:25:18:25:19 | p2 | type_tracker.rb:25:18:25:19 | p2 |
| type_tracker.rb:25:18:25:19 | p2 | type_tracker.rb:25:18:25:19 | p2 |
| type_tracker.rb:25:18:25:19 | p2 | type_tracker.rb:27:10:27:11 | p2 |
| type_tracker.rb:26:5:26:11 | * | type_tracker.rb:26:5:26:11 | * |
| type_tracker.rb:26:5:26:11 | call to puts | type_tracker.rb:26:5:26:11 | call to puts |
| type_tracker.rb:27:5:27:11 | * | type_tracker.rb:27:5:27:11 | * |
| type_tracker.rb:26:5:26:11 | synthetic splat argument | type_tracker.rb:26:5:26:11 | synthetic splat argument |
| type_tracker.rb:27:5:27:11 | call to puts | type_tracker.rb:27:5:27:11 | call to puts |
| type_tracker.rb:27:5:27:11 | call to puts | type_tracker.rb:30:1:30:21 | call to keyword |
| type_tracker.rb:27:5:27:11 | call to puts | type_tracker.rb:31:1:31:21 | call to keyword |
| type_tracker.rb:27:5:27:11 | call to puts | type_tracker.rb:32:1:32:27 | call to keyword |
| type_tracker.rb:30:1:30:21 | ** | type_tracker.rb:25:1:28:3 | **kwargs |
| type_tracker.rb:30:1:30:21 | ** | type_tracker.rb:30:1:30:21 | ** |
| type_tracker.rb:27:5:27:11 | synthetic splat argument | type_tracker.rb:27:5:27:11 | synthetic splat argument |
| type_tracker.rb:30:1:30:21 | call to keyword | type_tracker.rb:30:1:30:21 | call to keyword |
| type_tracker.rb:30:1:30:21 | synthetic hash-splat argument | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter |
| type_tracker.rb:30:1:30:21 | synthetic hash-splat argument | type_tracker.rb:30:1:30:21 | synthetic hash-splat argument |
| type_tracker.rb:30:9:30:10 | :p1 | type_tracker.rb:30:9:30:10 | :p1 |
| type_tracker.rb:30:9:30:13 | Pair | type_tracker.rb:30:9:30:13 | Pair |
| type_tracker.rb:30:13:30:13 | 3 | type_tracker.rb:25:13:25:14 | p1 |
@@ -483,9 +488,9 @@ trackEnd
| type_tracker.rb:30:20:30:20 | 4 | type_tracker.rb:25:18:25:19 | p2 |
| type_tracker.rb:30:20:30:20 | 4 | type_tracker.rb:27:10:27:11 | p2 |
| type_tracker.rb:30:20:30:20 | 4 | type_tracker.rb:30:20:30:20 | 4 |
| type_tracker.rb:31:1:31:21 | ** | type_tracker.rb:25:1:28:3 | **kwargs |
| type_tracker.rb:31:1:31:21 | ** | type_tracker.rb:31:1:31:21 | ** |
| type_tracker.rb:31:1:31:21 | call to keyword | type_tracker.rb:31:1:31:21 | call to keyword |
| type_tracker.rb:31:1:31:21 | synthetic hash-splat argument | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter |
| type_tracker.rb:31:1:31:21 | synthetic hash-splat argument | type_tracker.rb:31:1:31:21 | synthetic hash-splat argument |
| type_tracker.rb:31:9:31:10 | :p2 | type_tracker.rb:31:9:31:10 | :p2 |
| type_tracker.rb:31:9:31:13 | Pair | type_tracker.rb:31:9:31:13 | Pair |
| type_tracker.rb:31:13:31:13 | 5 | type_tracker.rb:25:18:25:19 | p2 |
@@ -498,9 +503,9 @@ trackEnd
| type_tracker.rb:31:20:31:20 | 6 | type_tracker.rb:25:13:25:14 | p1 |
| type_tracker.rb:31:20:31:20 | 6 | type_tracker.rb:26:10:26:11 | p1 |
| type_tracker.rb:31:20:31:20 | 6 | type_tracker.rb:31:20:31:20 | 6 |
| type_tracker.rb:32:1:32:27 | ** | type_tracker.rb:25:1:28:3 | **kwargs |
| type_tracker.rb:32:1:32:27 | ** | type_tracker.rb:32:1:32:27 | ** |
| type_tracker.rb:32:1:32:27 | call to keyword | type_tracker.rb:32:1:32:27 | call to keyword |
| type_tracker.rb:32:1:32:27 | synthetic hash-splat argument | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter |
| type_tracker.rb:32:1:32:27 | synthetic hash-splat argument | type_tracker.rb:32:1:32:27 | synthetic hash-splat argument |
| type_tracker.rb:32:9:32:11 | :p2 | type_tracker.rb:32:9:32:11 | :p2 |
| type_tracker.rb:32:9:32:16 | Pair | type_tracker.rb:32:9:32:16 | Pair |
| type_tracker.rb:32:16:32:16 | 7 | type_tracker.rb:25:18:25:19 | p2 |
@@ -515,7 +520,7 @@ trackEnd
| type_tracker.rb:32:26:32:26 | 8 | type_tracker.rb:32:26:32:26 | 8 |
| type_tracker.rb:34:1:53:3 | &block | type_tracker.rb:34:1:53:3 | &block |
| type_tracker.rb:34:1:53:3 | self in throughArray | type_tracker.rb:34:1:53:3 | self in throughArray |
| type_tracker.rb:34:1:53:3 | synthetic *args | type_tracker.rb:34:1:53:3 | synthetic *args |
| type_tracker.rb:34:1:53:3 | synthetic splat parameter | type_tracker.rb:34:1:53:3 | synthetic splat parameter |
| type_tracker.rb:34:1:53:3 | throughArray | type_tracker.rb:34:1:53:3 | throughArray |
| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:34:18:34:20 | obj |
| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:34:18:34:20 | obj |
@@ -556,23 +561,32 @@ trackEnd
| type_tracker.rb:34:26:34:26 | z | type_tracker.rb:34:26:34:26 | z |
| type_tracker.rb:34:26:34:26 | z | type_tracker.rb:52:12:52:12 | z |
| type_tracker.rb:35:5:35:7 | tmp | type_tracker.rb:35:5:35:7 | tmp |
| type_tracker.rb:35:11:35:15 | * | type_tracker.rb:35:11:35:15 | * |
| type_tracker.rb:35:11:35:15 | Array | type_tracker.rb:35:11:35:15 | Array |
| type_tracker.rb:35:11:35:15 | call to [] | type_tracker.rb:35:5:35:7 | tmp |
| type_tracker.rb:35:11:35:15 | call to [] | type_tracker.rb:35:5:35:15 | ... = ... |
| type_tracker.rb:35:11:35:15 | call to [] | type_tracker.rb:35:11:35:15 | call to [] |
| type_tracker.rb:35:11:35:15 | call to [] | type_tracker.rb:36:5:36:7 | tmp |
| type_tracker.rb:36:5:36:10 | * | type_tracker.rb:36:5:36:10 | * |
| type_tracker.rb:35:11:35:15 | synthetic splat argument | type_tracker.rb:35:5:35:7 | tmp |
| type_tracker.rb:35:11:35:15 | synthetic splat argument | type_tracker.rb:35:5:35:15 | ... = ... |
| type_tracker.rb:35:11:35:15 | synthetic splat argument | type_tracker.rb:35:11:35:15 | call to [] |
| type_tracker.rb:35:11:35:15 | synthetic splat argument | type_tracker.rb:35:11:35:15 | synthetic splat argument |
| type_tracker.rb:35:11:35:15 | synthetic splat argument | type_tracker.rb:36:5:36:7 | tmp |
| type_tracker.rb:36:5:36:10 | ...[...] | type_tracker.rb:36:5:36:10 | ...[...] |
| type_tracker.rb:36:5:36:10 | synthetic splat argument | type_tracker.rb:36:5:36:10 | synthetic splat argument |
| type_tracker.rb:36:9:36:9 | 0 | type_tracker.rb:36:9:36:9 | 0 |
| type_tracker.rb:38:5:38:9 | array | type_tracker.rb:38:5:38:9 | array |
| type_tracker.rb:38:13:38:25 | * | type_tracker.rb:38:13:38:25 | * |
| type_tracker.rb:38:13:38:25 | Array | type_tracker.rb:38:13:38:25 | Array |
| type_tracker.rb:38:13:38:25 | call to [] | type_tracker.rb:38:5:38:9 | array |
| type_tracker.rb:38:13:38:25 | call to [] | type_tracker.rb:38:5:38:25 | ... = ... |
| type_tracker.rb:38:13:38:25 | call to [] | type_tracker.rb:38:13:38:25 | call to [] |
| type_tracker.rb:38:13:38:25 | call to [] | type_tracker.rb:39:5:39:9 | array |
| type_tracker.rb:38:13:38:25 | call to [] | type_tracker.rb:40:5:40:9 | array |
| type_tracker.rb:38:13:38:25 | synthetic splat argument | type_tracker.rb:38:5:38:9 | array |
| type_tracker.rb:38:13:38:25 | synthetic splat argument | type_tracker.rb:38:5:38:25 | ... = ... |
| type_tracker.rb:38:13:38:25 | synthetic splat argument | type_tracker.rb:38:13:38:25 | call to [] |
| type_tracker.rb:38:13:38:25 | synthetic splat argument | type_tracker.rb:38:13:38:25 | synthetic splat argument |
| type_tracker.rb:38:13:38:25 | synthetic splat argument | type_tracker.rb:39:5:39:9 | array |
| type_tracker.rb:38:13:38:25 | synthetic splat argument | type_tracker.rb:40:5:40:9 | array |
| type_tracker.rb:38:14:38:14 | 1 | type_tracker.rb:38:14:38:14 | 1 |
| type_tracker.rb:38:14:38:14 | 1 | type_tracker.rb:40:5:40:12 | ...[...] |
| type_tracker.rb:38:16:38:16 | 2 | type_tracker.rb:38:16:38:16 | 2 |
@@ -582,20 +596,25 @@ trackEnd
| type_tracker.rb:38:24:38:24 | 6 | type_tracker.rb:38:24:38:24 | 6 |
| type_tracker.rb:39:5:39:9 | [post] array | type_tracker.rb:39:5:39:9 | [post] array |
| type_tracker.rb:39:5:39:9 | [post] array | type_tracker.rb:40:5:40:9 | array |
| type_tracker.rb:39:5:39:12 | * | type_tracker.rb:39:5:39:12 | * |
| type_tracker.rb:39:5:39:12 | call to []= | type_tracker.rb:39:5:39:12 | call to []= |
| type_tracker.rb:39:5:39:12 | synthetic splat argument | type_tracker.rb:39:5:39:12 | synthetic splat argument |
| type_tracker.rb:39:16:39:18 | __synth__0 | type_tracker.rb:39:16:39:18 | __synth__0 |
| type_tracker.rb:40:5:40:12 | * | type_tracker.rb:40:5:40:12 | * |
| type_tracker.rb:40:5:40:12 | ...[...] | type_tracker.rb:40:5:40:12 | ...[...] |
| type_tracker.rb:40:5:40:12 | synthetic splat argument | type_tracker.rb:40:5:40:12 | synthetic splat argument |
| type_tracker.rb:40:11:40:11 | 0 | type_tracker.rb:40:11:40:11 | 0 |
| type_tracker.rb:42:5:42:10 | array2 | type_tracker.rb:42:5:42:10 | array2 |
| type_tracker.rb:42:14:42:26 | * | type_tracker.rb:42:14:42:26 | * |
| type_tracker.rb:42:14:42:26 | Array | type_tracker.rb:42:14:42:26 | Array |
| type_tracker.rb:42:14:42:26 | call to [] | type_tracker.rb:42:5:42:10 | array2 |
| type_tracker.rb:42:14:42:26 | call to [] | type_tracker.rb:42:5:42:26 | ... = ... |
| type_tracker.rb:42:14:42:26 | call to [] | type_tracker.rb:42:14:42:26 | call to [] |
| type_tracker.rb:42:14:42:26 | call to [] | type_tracker.rb:43:5:43:10 | array2 |
| type_tracker.rb:42:14:42:26 | call to [] | type_tracker.rb:44:5:44:10 | array2 |
| type_tracker.rb:42:14:42:26 | synthetic splat argument | type_tracker.rb:42:5:42:10 | array2 |
| type_tracker.rb:42:14:42:26 | synthetic splat argument | type_tracker.rb:42:5:42:26 | ... = ... |
| type_tracker.rb:42:14:42:26 | synthetic splat argument | type_tracker.rb:42:14:42:26 | call to [] |
| type_tracker.rb:42:14:42:26 | synthetic splat argument | type_tracker.rb:42:14:42:26 | synthetic splat argument |
| type_tracker.rb:42:14:42:26 | synthetic splat argument | type_tracker.rb:43:5:43:10 | array2 |
| type_tracker.rb:42:14:42:26 | synthetic splat argument | type_tracker.rb:44:5:44:10 | array2 |
| type_tracker.rb:42:15:42:15 | 1 | type_tracker.rb:42:15:42:15 | 1 |
| type_tracker.rb:42:15:42:15 | 1 | type_tracker.rb:44:5:44:13 | ...[...] |
| type_tracker.rb:42:17:42:17 | 2 | type_tracker.rb:42:17:42:17 | 2 |
@@ -610,20 +629,25 @@ trackEnd
| type_tracker.rb:42:25:42:25 | 6 | type_tracker.rb:44:5:44:13 | ...[...] |
| type_tracker.rb:43:5:43:10 | [post] array2 | type_tracker.rb:43:5:43:10 | [post] array2 |
| type_tracker.rb:43:5:43:10 | [post] array2 | type_tracker.rb:44:5:44:10 | array2 |
| type_tracker.rb:43:5:43:13 | * | type_tracker.rb:43:5:43:13 | * |
| type_tracker.rb:43:5:43:13 | call to []= | type_tracker.rb:43:5:43:13 | call to []= |
| type_tracker.rb:43:5:43:13 | synthetic splat argument | type_tracker.rb:43:5:43:13 | synthetic splat argument |
| type_tracker.rb:43:12:43:12 | 0 | type_tracker.rb:43:12:43:12 | 0 |
| type_tracker.rb:43:17:43:19 | __synth__0 | type_tracker.rb:43:17:43:19 | __synth__0 |
| type_tracker.rb:44:5:44:13 | * | type_tracker.rb:44:5:44:13 | * |
| type_tracker.rb:44:5:44:13 | ...[...] | type_tracker.rb:44:5:44:13 | ...[...] |
| type_tracker.rb:44:5:44:13 | synthetic splat argument | type_tracker.rb:44:5:44:13 | synthetic splat argument |
| type_tracker.rb:46:5:46:10 | array3 | type_tracker.rb:46:5:46:10 | array3 |
| type_tracker.rb:46:14:46:26 | * | type_tracker.rb:46:14:46:26 | * |
| type_tracker.rb:46:14:46:26 | Array | type_tracker.rb:46:14:46:26 | Array |
| type_tracker.rb:46:14:46:26 | call to [] | type_tracker.rb:46:5:46:10 | array3 |
| type_tracker.rb:46:14:46:26 | call to [] | type_tracker.rb:46:5:46:26 | ... = ... |
| type_tracker.rb:46:14:46:26 | call to [] | type_tracker.rb:46:14:46:26 | call to [] |
| type_tracker.rb:46:14:46:26 | call to [] | type_tracker.rb:47:5:47:10 | array3 |
| type_tracker.rb:46:14:46:26 | call to [] | type_tracker.rb:48:5:48:10 | array3 |
| type_tracker.rb:46:14:46:26 | synthetic splat argument | type_tracker.rb:46:5:46:10 | array3 |
| type_tracker.rb:46:14:46:26 | synthetic splat argument | type_tracker.rb:46:5:46:26 | ... = ... |
| type_tracker.rb:46:14:46:26 | synthetic splat argument | type_tracker.rb:46:14:46:26 | call to [] |
| type_tracker.rb:46:14:46:26 | synthetic splat argument | type_tracker.rb:46:14:46:26 | synthetic splat argument |
| type_tracker.rb:46:14:46:26 | synthetic splat argument | type_tracker.rb:47:5:47:10 | array3 |
| type_tracker.rb:46:14:46:26 | synthetic splat argument | type_tracker.rb:48:5:48:10 | array3 |
| type_tracker.rb:46:15:46:15 | 1 | type_tracker.rb:46:15:46:15 | 1 |
| type_tracker.rb:46:17:46:17 | 2 | type_tracker.rb:46:17:46:17 | 2 |
| type_tracker.rb:46:17:46:17 | 2 | type_tracker.rb:48:5:48:13 | ...[...] |
@@ -633,21 +657,26 @@ trackEnd
| type_tracker.rb:46:25:46:25 | 6 | type_tracker.rb:46:25:46:25 | 6 |
| type_tracker.rb:47:5:47:10 | [post] array3 | type_tracker.rb:47:5:47:10 | [post] array3 |
| type_tracker.rb:47:5:47:10 | [post] array3 | type_tracker.rb:48:5:48:10 | array3 |
| type_tracker.rb:47:5:47:13 | * | type_tracker.rb:47:5:47:13 | * |
| type_tracker.rb:47:5:47:13 | call to []= | type_tracker.rb:47:5:47:13 | call to []= |
| type_tracker.rb:47:5:47:13 | synthetic splat argument | type_tracker.rb:47:5:47:13 | synthetic splat argument |
| type_tracker.rb:47:12:47:12 | 0 | type_tracker.rb:47:12:47:12 | 0 |
| type_tracker.rb:47:17:47:19 | __synth__0 | type_tracker.rb:47:17:47:19 | __synth__0 |
| type_tracker.rb:48:5:48:13 | * | type_tracker.rb:48:5:48:13 | * |
| type_tracker.rb:48:5:48:13 | ...[...] | type_tracker.rb:48:5:48:13 | ...[...] |
| type_tracker.rb:48:5:48:13 | synthetic splat argument | type_tracker.rb:48:5:48:13 | synthetic splat argument |
| type_tracker.rb:48:12:48:12 | 1 | type_tracker.rb:48:12:48:12 | 1 |
| type_tracker.rb:50:5:50:10 | array4 | type_tracker.rb:50:5:50:10 | array4 |
| type_tracker.rb:50:14:50:26 | * | type_tracker.rb:50:14:50:26 | * |
| type_tracker.rb:50:14:50:26 | Array | type_tracker.rb:50:14:50:26 | Array |
| type_tracker.rb:50:14:50:26 | call to [] | type_tracker.rb:50:5:50:10 | array4 |
| type_tracker.rb:50:14:50:26 | call to [] | type_tracker.rb:50:5:50:26 | ... = ... |
| type_tracker.rb:50:14:50:26 | call to [] | type_tracker.rb:50:14:50:26 | call to [] |
| type_tracker.rb:50:14:50:26 | call to [] | type_tracker.rb:51:5:51:10 | array4 |
| type_tracker.rb:50:14:50:26 | call to [] | type_tracker.rb:52:5:52:10 | array4 |
| type_tracker.rb:50:14:50:26 | synthetic splat argument | type_tracker.rb:50:5:50:10 | array4 |
| type_tracker.rb:50:14:50:26 | synthetic splat argument | type_tracker.rb:50:5:50:26 | ... = ... |
| type_tracker.rb:50:14:50:26 | synthetic splat argument | type_tracker.rb:50:14:50:26 | call to [] |
| type_tracker.rb:50:14:50:26 | synthetic splat argument | type_tracker.rb:50:14:50:26 | synthetic splat argument |
| type_tracker.rb:50:14:50:26 | synthetic splat argument | type_tracker.rb:51:5:51:10 | array4 |
| type_tracker.rb:50:14:50:26 | synthetic splat argument | type_tracker.rb:52:5:52:10 | array4 |
| type_tracker.rb:50:15:50:15 | 1 | type_tracker.rb:50:15:50:15 | 1 |
| type_tracker.rb:50:15:50:15 | 1 | type_tracker.rb:52:5:52:13 | ...[...] |
| type_tracker.rb:50:17:50:17 | 2 | type_tracker.rb:50:17:50:17 | 2 |
@@ -662,10 +691,10 @@ trackEnd
| type_tracker.rb:50:25:50:25 | 6 | type_tracker.rb:52:5:52:13 | ...[...] |
| type_tracker.rb:51:5:51:10 | [post] array4 | type_tracker.rb:51:5:51:10 | [post] array4 |
| type_tracker.rb:51:5:51:10 | [post] array4 | type_tracker.rb:52:5:52:10 | array4 |
| type_tracker.rb:51:5:51:13 | * | type_tracker.rb:51:5:51:13 | * |
| type_tracker.rb:51:5:51:13 | call to []= | type_tracker.rb:51:5:51:13 | call to []= |
| type_tracker.rb:51:5:51:13 | synthetic splat argument | type_tracker.rb:51:5:51:13 | synthetic splat argument |
| type_tracker.rb:51:17:51:19 | __synth__0 | type_tracker.rb:51:17:51:19 | __synth__0 |
| type_tracker.rb:52:5:52:13 | * | type_tracker.rb:52:5:52:13 | * |
| type_tracker.rb:52:5:52:13 | ...[...] | type_tracker.rb:52:5:52:13 | ...[...] |
| type_tracker.rb:52:5:52:13 | synthetic splat argument | type_tracker.rb:52:5:52:13 | synthetic splat argument |
forwardButNoBackwardFlow
backwardButNoForwardFlow

View File

@@ -71,21 +71,21 @@ edges
| params_flow.rb:107:10:107:33 | call to values_at [element 0] | params_flow.rb:107:10:107:33 | call to values_at |
| params_flow.rb:107:10:107:33 | call to values_at [element 1] | params_flow.rb:107:10:107:33 | call to values_at |
| params_flow.rb:111:10:111:15 | call to params | params_flow.rb:111:10:111:29 | call to merge |
| params_flow.rb:112:10:112:29 | call to merge [element 0] | params_flow.rb:112:10:112:29 | call to merge |
| params_flow.rb:112:10:112:29 | call to merge [splat position 0] | params_flow.rb:112:10:112:29 | call to merge |
| params_flow.rb:112:23:112:28 | call to params | params_flow.rb:112:10:112:29 | call to merge |
| params_flow.rb:112:23:112:28 | call to params | params_flow.rb:112:10:112:29 | call to merge [element 0] |
| params_flow.rb:112:23:112:28 | call to params | params_flow.rb:112:10:112:29 | call to merge [splat position 0] |
| params_flow.rb:116:10:116:15 | call to params | params_flow.rb:116:10:116:37 | call to reverse_merge |
| params_flow.rb:117:31:117:36 | call to params | params_flow.rb:117:10:117:37 | call to reverse_merge |
| params_flow.rb:121:10:121:15 | call to params | params_flow.rb:121:10:121:43 | call to with_defaults |
| params_flow.rb:122:31:122:36 | call to params | params_flow.rb:122:10:122:37 | call to with_defaults |
| params_flow.rb:126:10:126:15 | call to params | params_flow.rb:126:10:126:30 | call to merge! |
| params_flow.rb:127:10:127:30 | call to merge! [element 0] | params_flow.rb:127:10:127:30 | call to merge! |
| params_flow.rb:127:10:127:30 | call to merge! [splat position 0] | params_flow.rb:127:10:127:30 | call to merge! |
| params_flow.rb:127:24:127:29 | call to params | params_flow.rb:127:10:127:30 | call to merge! |
| params_flow.rb:127:24:127:29 | call to params | params_flow.rb:127:10:127:30 | call to merge! [element 0] |
| params_flow.rb:127:24:127:29 | call to params | params_flow.rb:127:10:127:30 | call to merge! [splat position 0] |
| params_flow.rb:130:5:130:5 | [post] p | params_flow.rb:131:10:131:10 | p |
| params_flow.rb:130:5:130:5 | [post] p [element 0] | params_flow.rb:131:10:131:10 | p |
| params_flow.rb:130:5:130:5 | [post] p [splat position 0] | params_flow.rb:131:10:131:10 | p |
| params_flow.rb:130:14:130:19 | call to params | params_flow.rb:130:5:130:5 | [post] p |
| params_flow.rb:130:14:130:19 | call to params | params_flow.rb:130:5:130:5 | [post] p [element 0] |
| params_flow.rb:130:14:130:19 | call to params | params_flow.rb:130:5:130:5 | [post] p [splat position 0] |
| params_flow.rb:135:10:135:15 | call to params | params_flow.rb:135:10:135:38 | call to reverse_merge! |
| params_flow.rb:136:32:136:37 | call to params | params_flow.rb:136:10:136:38 | call to reverse_merge! |
| params_flow.rb:139:5:139:5 | [post] p | params_flow.rb:140:10:140:10 | p |
@@ -198,7 +198,7 @@ nodes
| params_flow.rb:111:10:111:15 | call to params | semmle.label | call to params |
| params_flow.rb:111:10:111:29 | call to merge | semmle.label | call to merge |
| params_flow.rb:112:10:112:29 | call to merge | semmle.label | call to merge |
| params_flow.rb:112:10:112:29 | call to merge [element 0] | semmle.label | call to merge [element 0] |
| params_flow.rb:112:10:112:29 | call to merge [splat position 0] | semmle.label | call to merge [splat position 0] |
| params_flow.rb:112:23:112:28 | call to params | semmle.label | call to params |
| params_flow.rb:116:10:116:15 | call to params | semmle.label | call to params |
| params_flow.rb:116:10:116:37 | call to reverse_merge | semmle.label | call to reverse_merge |
@@ -211,10 +211,10 @@ nodes
| params_flow.rb:126:10:126:15 | call to params | semmle.label | call to params |
| params_flow.rb:126:10:126:30 | call to merge! | semmle.label | call to merge! |
| params_flow.rb:127:10:127:30 | call to merge! | semmle.label | call to merge! |
| params_flow.rb:127:10:127:30 | call to merge! [element 0] | semmle.label | call to merge! [element 0] |
| params_flow.rb:127:10:127:30 | call to merge! [splat position 0] | semmle.label | call to merge! [splat position 0] |
| params_flow.rb:127:24:127:29 | call to params | semmle.label | call to params |
| params_flow.rb:130:5:130:5 | [post] p | semmle.label | [post] p |
| params_flow.rb:130:5:130:5 | [post] p [element 0] | semmle.label | [post] p [element 0] |
| params_flow.rb:130:5:130:5 | [post] p [splat position 0] | semmle.label | [post] p [splat position 0] |
| params_flow.rb:130:14:130:19 | call to params | semmle.label | call to params |
| params_flow.rb:131:10:131:10 | p | semmle.label | p |
| params_flow.rb:135:10:135:15 | call to params | semmle.label | call to params |