Merge pull request #168 from github/aibaars/typetrack-method

Call graph
This commit is contained in:
Arthur Baars
2021-05-26 14:19:21 +02:00
committed by GitHub
16 changed files with 1213 additions and 91 deletions

View File

@@ -20,6 +20,10 @@ class Module extends TModule {
/** Gets an `include`d module. */
Module getAnIncludedModule() { result = getAnIncludedModule(this) }
/** Holds if this module is a class. */
pragma[noinline]
predicate isClass() { this.getADeclaration() instanceof ClassDeclaration }
/** Gets a textual representation of this module. */
string toString() {
this = TResolved(result)

View File

@@ -8,7 +8,13 @@ private import codeql_ruby.ast.Operation
private import codeql_ruby.ast.Scope
// Names of built-in modules and classes
private string builtin() { result = ["Object", "Kernel", "BasicObject", "Class", "Module"] }
private string builtin() {
result =
[
"Object", "Kernel", "BasicObject", "Class", "Module", "NilClass", "FalseClass", "TrueClass",
"Numeric", "Integer", "Float", "Rational", "Complex", "Array", "Hash", "Symbol", "Proc"
]
}
cached
private module Cached {
@@ -39,9 +45,14 @@ private module Cached {
Module getSuperClass(Module cls) {
cls = TResolved("Object") and result = TResolved("BasicObject")
or
cls = TResolved("Module") and result = TResolved("Object")
cls = TResolved(["Module", "Numeric", "Array", "Hash", "FalseClass", "TrueClass", "NilClass"]) and
result = TResolved("Object")
or
cls = TResolved("Class") and result = TResolved("Module")
cls = TResolved(["Integer", "Float", "Rational", "Complex"]) and
result = TResolved("Numeric")
or
cls = TResolved("Class") and
result = TResolved("Module")
or
not cls = TResolved(builtin()) and
(
@@ -86,6 +97,39 @@ private module Cached {
result = resolveScopeExpr(c.getAnArgument())
)
}
/**
* Resolve constant read access (typically a scope expression) to a qualified module name.
* `resolveScopeExpr/1` picks the best (lowest priority number) result of
* `resolveScopeExpr/2` that resolves to a constant definition. If the constant
* definition is a Namespace then it is returned, if it's a constant assignment then
* the right-hand side of the assignment is resolved.
*/
cached
TResolved resolveScopeExpr(ConstantReadAccess r) {
exists(string qname |
qname =
min(string qn, int p |
isDefinedConstant(qn) and
qn = resolveScopeExpr(r, p) and
// prevent classes/modules that contain/extend themselves
not exists(ConstantWriteAccess w | qn = constantDefinition0(w) |
r = w.getScopeExpr()
or
r = w.(ClassDeclaration).getSuperclassExpr()
)
|
qn order by p
)
|
result = TResolved(qname)
or
exists(ConstantAssignment a |
qname = constantDefinition0(a) and
result = resolveScopeExpr(a.getParent().(Assignment).getRightOperand())
)
)
}
}
import Cached
@@ -103,38 +147,6 @@ private predicate isDefinedConstant(string qualifiedModuleName) {
qualifiedModuleName = [builtin(), constantDefinition0(_)]
}
/**
* Resolve constant read access (typically a scope expression) to a qualified module name.
* `resolveScopeExpr/1` picks the best (lowest priority number) result of
* `resolveScopeExpr/2` that resolves to a constant definition. If the constant
* definition is a Namespace then it is returned, if it's a constant assignment then
* the right-hand side of the assignment is resolved.
*/
private TResolved resolveScopeExpr(ConstantReadAccess r) {
exists(string qname |
qname =
min(string qn, int p |
isDefinedConstant(qn) and
qn = resolveScopeExpr(r, p) and
// prevent classes/modules that contain/extend themselves
not exists(ConstantWriteAccess w | qn = constantDefinition0(w) |
r = w.getScopeExpr()
or
r = w.(ClassDeclaration).getSuperclassExpr()
)
|
qn order by p
)
|
result = TResolved(qname)
or
exists(ConstantAssignment a |
qname = constantDefinition0(a) and
result = resolveScopeExpr(a.getParent().(Assignment).getRightOperand())
)
)
}
private int maxDepth() { result = 1 + max(int level | exists(enclosing(_, level))) }
private ModuleBase enclosing(ModuleBase m, int level) {

View File

@@ -123,15 +123,9 @@ abstract private class ExprChildMapping extends Expr {
*/
abstract predicate relevantChild(Expr child);
private AstNode getAChildStar() {
result = this
or
result.getParent() = this.getAChildStar()
}
pragma[noinline]
private BasicBlock getABasicBlockInScope() {
result.getANode() = TAstCfgNode(this.getAChildStar(), _)
result.getANode() = TAstCfgNode(this.getAChild*(), _)
}
pragma[nomagic]
@@ -231,9 +225,23 @@ module ExprNodes {
final ExprCfgNode getRightOperand() { e.hasCfgChild(e.getRightOperand(), this, result) }
}
private class BlockArgumentChildMapping extends ExprChildMapping, BlockArgument {
override predicate relevantChild(Expr e) { e = this.getValue() }
}
/** A control-flow node that wraps a `BlockArgument` AST expression. */
class BlockArgumentCfgNode extends ExprCfgNode {
override BlockArgumentChildMapping e;
final override BlockArgument getExpr() { result = ExprCfgNode.super.getExpr() }
/** Gets the value of this block argument. */
final ExprCfgNode getValue() { e.hasCfgChild(e.getValue(), this, result) }
}
private class CallExprChildMapping extends ExprChildMapping, Call {
override predicate relevantChild(Expr e) {
e = [this.getAnArgument(), this.(MethodCall).getReceiver()]
e = [this.getAnArgument(), this.(MethodCall).getReceiver(), this.(MethodCall).getBlock()]
}
}
@@ -248,6 +256,9 @@ module ExprNodes {
/** Gets the receiver of this call. */
final ExprCfgNode getReceiver() { e.hasCfgChild(e.(MethodCall).getReceiver(), this, result) }
/** Gets the block of this call. */
final ExprCfgNode getBlock() { e.hasCfgChild(e.(MethodCall).getBlock(), this, result) }
}
private class CaseExprChildMapping extends ExprChildMapping, CaseExpr {

View File

@@ -1,6 +1,9 @@
private import ruby
private import codeql_ruby.CFG
private import DataFlowPrivate
private import codeql_ruby.typetracking.TypeTracker
private import codeql_ruby.dataflow.internal.DataFlowPublic as DataFlow
private import codeql_ruby.ast.internal.Module
newtype TReturnKind =
TNormalReturnKind() or
@@ -41,15 +44,245 @@ class DataFlowCallable = CfgScope;
class DataFlowCall extends CfgNodes::ExprNodes::CallCfgNode {
DataFlowCallable getEnclosingCallable() { result = this.getScope() }
pragma[nomagic]
private predicate methodCall(DataFlow::LocalSourceNode sourceNode, string method) {
exists(DataFlow::Node nodeTo |
method = this.getExpr().(MethodCall).getMethodName() and
nodeTo.asExpr() = this.getReceiver() and
sourceNode.flowsTo(nodeTo)
)
}
private Block yieldCall() {
this.getExpr() instanceof YieldCall and
exists(BlockParameterNode node |
node = trackBlock(result) and
node.getMethod() = this.getExpr().getEnclosingMethod()
)
}
pragma[nomagic]
private predicate superCall(Module superClass, string method) {
this.getExpr() instanceof SuperCall and
exists(Module tp |
tp = this.getExpr().getEnclosingModule().getModule() and
superClass = tp.getSuperClass() and
method = this.getExpr().getEnclosingMethod().getName()
)
}
pragma[nomagic]
private predicate instanceMethodCall(Module tp, string method) {
exists(DataFlow::LocalSourceNode sourceNode |
this.methodCall(sourceNode, method) and
sourceNode = trackInstance(tp)
)
}
cached
DataFlowCallable getTarget() {
// TODO: this is a placeholder that finds a method with the same name, iff it's uniquely named.
result =
unique(DataFlowCallable c | c.(Method).getName() = this.getNode().(MethodCall).getMethodName())
exists(string method |
exists(Module tp |
this.instanceMethodCall(tp, method) and
result = lookupMethod(tp, method)
)
or
exists(DataFlow::LocalSourceNode sourceNode |
this.methodCall(sourceNode, method) and
sourceNode = trackSingletonMethod(result, method)
)
)
or
exists(Module superClass, string method |
this.superCall(superClass, method) and
result = lookupMethod(superClass, method)
)
or
result = this.yieldCall()
}
}
private DataFlow::LocalSourceNode trackInstance(Module tp, TypeTracker t) {
t.start() and
(
result.asExpr().getExpr() instanceof NilLiteral and tp = TResolved("NilClass")
or
result.asExpr().getExpr().(BooleanLiteral).isFalse() and tp = TResolved("FalseClass")
or
result.asExpr().getExpr().(BooleanLiteral).isTrue() and tp = TResolved("TrueClass")
or
result.asExpr().getExpr() instanceof IntegerLiteral and tp = TResolved("Integer")
or
result.asExpr().getExpr() instanceof FloatLiteral and tp = TResolved("Float")
or
result.asExpr().getExpr() instanceof RationalLiteral and tp = TResolved("Rational")
or
result.asExpr().getExpr() instanceof ComplexLiteral and tp = TResolved("Complex")
or
result.asExpr().getExpr() instanceof StringlikeLiteral and tp = TResolved("String")
or
result.asExpr().getExpr() instanceof ArrayLiteral and tp = TResolved("Array")
or
result.asExpr().getExpr() instanceof HashLiteral and tp = TResolved("Hash")
or
result.asExpr().getExpr() instanceof MethodBase and tp = TResolved("Symbol")
or
result.asParameter() instanceof BlockParameter and tp = TResolved("Proc")
or
result.asExpr().getExpr() instanceof Lambda and tp = TResolved("Proc")
or
exists(CfgNodes::ExprNodes::CallCfgNode call, DataFlow::Node nodeTo |
call.getExpr().(MethodCall).getMethodName() = "new" and
nodeTo.asExpr() = call.getReceiver() and
trackModule(tp).flowsTo(nodeTo) and
result.asExpr() = call
)
or
// `self` in method
exists(Self self, Method enclosing |
self = result.asExpr().getExpr() and
enclosing = self.getEnclosingMethod() and
tp = enclosing.getEnclosingModule().getModule() and
not self.getEnclosingModule().getEnclosingMethod() = enclosing
)
or
// `self` in singleton method
exists(Self self, MethodBase enclosing |
self = result.asExpr().getExpr() and
flowsToSingletonMethodObject(trackInstance(tp), enclosing) and
enclosing = self.getEnclosingMethod() and
not self.getEnclosingModule().getEnclosingMethod() = enclosing
)
or
// `self` in top-level
exists(Self self, Toplevel enclosing |
self = result.asExpr().getExpr() and
enclosing = self.getEnclosingModule() and
tp = TResolved("Object") and
not self.getEnclosingMethod().getEnclosingModule() = enclosing
)
or
// a module or class
exists(Module m |
result = trackModule(m) and
if m.isClass() then tp = TResolved("Class") else tp = TResolved("Module")
)
)
or
exists(TypeTracker t2, StepSummary summary |
result = trackInstanceRec(tp, t2, summary) and t = t2.append(summary)
)
}
pragma[nomagic]
private DataFlow::LocalSourceNode trackInstanceRec(Module tp, TypeTracker t, StepSummary summary) {
StepSummary::step(trackInstance(tp, t), result, summary)
}
private DataFlow::LocalSourceNode trackInstance(Module tp) {
result = trackInstance(tp, TypeTracker::end())
}
private DataFlow::LocalSourceNode trackBlock(Block block, TypeTracker t) {
t.start() and result.asExpr().getExpr() = block
or
exists(TypeTracker t2, StepSummary summary |
result = trackBlockRec(block, t2, summary) and t = t2.append(summary)
)
}
pragma[nomagic]
private DataFlow::LocalSourceNode trackBlockRec(Block block, TypeTracker t, StepSummary summary) {
StepSummary::step(trackBlock(block, t), result, summary)
}
private DataFlow::LocalSourceNode trackBlock(Block block) {
result = trackBlock(block, TypeTracker::end())
}
private predicate singletonMethod(MethodBase method, Expr object) {
object = method.(SingletonMethod).getObject()
or
exists(SingletonClass cls |
object = cls.getValue() and method instanceof Method and method = cls.getAMethod()
)
}
pragma[nomagic]
private predicate flowsToSingletonMethodObject(DataFlow::LocalSourceNode nodeFrom, MethodBase method) {
exists(DataFlow::LocalSourceNode nodeTo |
nodeFrom.flowsTo(nodeTo) and
singletonMethod(method, nodeTo.asExpr().getExpr())
)
}
pragma[nomagic]
private predicate moduleFlowsToSingletonMethodObject(Module m, MethodBase method) {
flowsToSingletonMethodObject(trackModule(m), method)
}
pragma[nomagic]
private DataFlow::LocalSourceNode trackSingletonMethod0(MethodBase method, TypeTracker t) {
t.start() and
(
flowsToSingletonMethodObject(result, method)
or
exists(Module m | result = trackModule(m) and moduleFlowsToSingletonMethodObject(m, method))
)
or
exists(TypeTracker t2, StepSummary summary |
result = trackSingletonMethod0Rec(method, t2, summary) and t = t2.append(summary)
)
}
pragma[nomagic]
private DataFlow::LocalSourceNode trackSingletonMethod0Rec(
MethodBase method, TypeTracker t, StepSummary summary
) {
StepSummary::step(trackSingletonMethod0(method, t), result, summary)
}
pragma[nomagic]
private DataFlow::LocalSourceNode trackSingletonMethod(MethodBase m, string name) {
result = trackSingletonMethod0(m, TypeTracker::end()) and
name = m.getName()
}
private DataFlow::Node selfInModule(Module tp) {
exists(Self self, ModuleBase enclosing |
self = result.asExpr().getExpr() and
enclosing = self.getEnclosingModule() and
tp = enclosing.getModule() and
not self.getEnclosingMethod().getEnclosingModule() = enclosing
)
}
private DataFlow::LocalSourceNode trackModule(Module tp, TypeTracker t) {
t.start() and
(
// ConstantReadAccess to Module
resolveScopeExpr(result.asExpr().getExpr()) = tp
or
// `self` reference to Module
result = selfInModule(tp)
)
or
exists(TypeTracker t2, StepSummary summary |
result = trackModuleRec(tp, t2, summary) and t = t2.append(summary)
)
}
pragma[nomagic]
private DataFlow::LocalSourceNode trackModuleRec(Module tp, TypeTracker t, StepSummary summary) {
StepSummary::step(trackModule(tp, t), result, summary)
}
private DataFlow::LocalSourceNode trackModule(Module tp) {
result = trackModule(tp, TypeTracker::end())
}
/** Gets a viable run-time target for the call `call`. */
DataFlowCallable viableCallable(DataFlowCall call) { none() }
DataFlowCallable viableCallable(DataFlowCall call) { result = call.getTarget() }
/**
* Holds if the set of viable implementations that can be called by `call`

View File

@@ -3,6 +3,7 @@ private import codeql_ruby.CFG
private import codeql_ruby.dataflow.SSA
private import DataFlowPublic
private import DataFlowDispatch
private import SsaImpl as SsaImpl
abstract class NodeImpl extends Node {
/** Do not call: use `getEnclosingCallable()` instead. */
@@ -49,6 +50,13 @@ module LocalFlow {
* SSA definition `def.
*/
predicate localSsaFlowStep(Ssa::Definition def, Node nodeFrom, Node nodeTo) {
// Flow from parameter into SSA definition
exists(BasicBlock bb, int i |
bb.getNode(i).getNode() =
nodeFrom.(ParameterNode).getParameter().(NamedParameter).getDefiningAccess() and
nodeTo.(SsaDefinitionNode).getDefinition().definesAt(_, bb, i)
)
or
// Flow from assignment into SSA definition
exists(CfgNodes::ExprNodes::AssignmentCfgNode a, BasicBlock bb, int i |
def.definesAt(_, bb, i) and
@@ -111,9 +119,13 @@ private module Cached {
TExprNode(CfgNodes::ExprCfgNode n) or
TReturningNode(CfgNodes::ReturningCfgNode n) or
TSsaDefinitionNode(Ssa::Definition def) or
TParameterNode(Parameter p) or
TNormalParameterNode(Parameter p) { not p instanceof BlockParameter } or
TSelfParameterNode(MethodBase m) or
TBlockParameterNode(MethodBase m) or
TExprPostUpdateNode(CfgNodes::ExprCfgNode n) { n.getNode() instanceof Argument }
class TParameterNode = TNormalParameterNode or TBlockParameterNode or TSelfParameterNode;
/**
* This is the local flow predicate that is used as a building block in global
* data flow. It excludes SSA flow through instance fields, as flow through fields
@@ -124,8 +136,19 @@ private module Cached {
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
exists(Ssa::Definition def | LocalFlow::localSsaFlowStep(def, nodeFrom, nodeTo))
or
nodeTo.(ParameterNode).getParameter().(OptionalParameter).getDefaultValue() =
nodeFrom.asExpr().getExpr()
or
nodeTo.(ParameterNode).getParameter().(KeywordParameter).getDefaultValue() =
nodeFrom.asExpr().getExpr()
or
nodeFrom.(SelfParameterNode).getMethod() = nodeTo.asExpr().getExpr().getEnclosingMethod() and
nodeTo.asExpr().getExpr() instanceof Self
or
nodeFrom.asExpr() = nodeTo.asExpr().(CfgNodes::ExprNodes::AssignExprCfgNode).getRhs()
or
nodeFrom.asExpr() = nodeTo.asExpr().(CfgNodes::ExprNodes::BlockArgumentCfgNode).getValue()
or
nodeFrom.asExpr() = nodeTo.asExpr().(CfgNodes::ExprNodes::StmtSequenceCfgNode).getLastStmt()
or
nodeFrom.asExpr() = nodeTo.asExpr().(CfgNodes::ExprNodes::ConditionalExprCfgNode).getBranch(_)
@@ -208,13 +231,13 @@ private module ParameterNodes {
abstract private class ParameterNodeImpl extends ParameterNode, NodeImpl { }
/**
* The value of an explicit parameter at function entry, viewed as a node in a data
* The value of a normal parameter at function entry, viewed as a node in a data
* flow graph.
*/
class ExplicitParameterNode extends ParameterNodeImpl, TParameterNode {
class NormalParameterNode extends ParameterNodeImpl, TNormalParameterNode {
private Parameter parameter;
ExplicitParameterNode() { this = TParameterNode(parameter) }
NormalParameterNode() { this = TNormalParameterNode(parameter) }
override Parameter getParameter() { result = parameter }
@@ -226,6 +249,58 @@ private module ParameterNodes {
override string toStringImpl() { result = parameter.toString() }
}
/**
* The value of the `self` parameter at function entry, viewed as a node in a data
* flow graph.
*/
class SelfParameterNode extends ParameterNodeImpl, TSelfParameterNode {
private MethodBase method;
SelfParameterNode() { this = TSelfParameterNode(method) }
final MethodBase getMethod() { result = method }
override predicate isParameterOf(Callable c, int i) { method = c and i = -1 }
override CfgScope getCfgScope() { result = method }
override Location getLocationImpl() { result = method.getLocation() }
override string toStringImpl() { result = "self in " + method.toString() }
}
/**
* The value of a block parameter at function entry, viewed as a node in a data
* flow graph.
*/
class BlockParameterNode extends ParameterNodeImpl, TBlockParameterNode {
private MethodBase method;
BlockParameterNode() { this = TBlockParameterNode(method) }
final MethodBase getMethod() { result = method }
override Parameter getParameter() {
result = method.getAParameter() and result instanceof BlockParameter
}
override predicate isParameterOf(Callable c, int i) { c = method and i = -2 }
override CfgScope getCfgScope() { result = method }
override Location getLocationImpl() {
result = getParameter().getLocation()
or
not exists(getParameter()) and result = method.getLocation()
}
override string toStringImpl() {
result = getParameter().toString()
or
not exists(getParameter()) and result = "&block"
}
}
}
import ParameterNodes
@@ -243,13 +318,44 @@ abstract class ArgumentNode extends Node {
private module ArgumentNodes {
/** A data-flow node that represents an explicit call argument. */
class ExplicitArgumentNode extends ArgumentNode {
ExplicitArgumentNode() { this.asExpr().getExpr() instanceof Argument }
ExplicitArgumentNode() {
this.asExpr().getExpr() instanceof Argument and
not this.asExpr().getExpr() instanceof BlockArgument
}
override predicate argumentOf(DataFlowCall call, int pos) {
this.asExpr() = call.getArgument(pos)
}
}
/** A data-flow node that represents the `self` argument of a call. */
class SelfArgumentNode extends ArgumentNode {
SelfArgumentNode() { this.asExpr() = any(CfgNodes::ExprNodes::CallCfgNode call).getReceiver() }
override predicate argumentOf(DataFlowCall call, int pos) {
this.asExpr() = call.getReceiver() and
pos = -1
or
this.asExpr() = call.getArgument(pos)
}
}
/** A data-flow node that represents a block argument. */
class BlockArgumentNode extends ArgumentNode {
BlockArgumentNode() {
this.asExpr().getExpr() instanceof BlockArgument or
exists(CfgNodes::ExprNodes::CallCfgNode c | c.getBlock() = this.asExpr())
}
override predicate argumentOf(DataFlowCall call, int pos) {
pos = -2 and
(
this.asExpr() = call.getBlock()
or
exists(CfgNodes::ExprCfgNode arg, int n |
arg = call.getArgument(n) and
this.asExpr() = arg and
arg.getExpr() instanceof BlockArgument
)
)
}
}
}
@@ -337,7 +443,13 @@ private module OutNodes {
import OutNodes
predicate jumpStep(Node pred, Node succ) { none() }
predicate jumpStep(Node pred, Node succ) {
SsaImpl::captureFlowIn(pred.(SsaDefinitionNode).getDefinition(),
succ.(SsaDefinitionNode).getDefinition())
or
SsaImpl::captureFlowOut(pred.(SsaDefinitionNode).getDefinition(),
succ.(SsaDefinitionNode).getDefinition())
}
predicate storeStep(Node node1, Content c, Node node2) { none() }

View File

@@ -60,18 +60,14 @@ class ExprNode extends Node, TExprNode {
* flow graph.
*/
class ParameterNode extends Node, TParameterNode {
private Parameter p;
ParameterNode() { this = TParameterNode(p) }
/** Gets the parameter corresponding to this node, if any. */
Parameter getParameter() { result = p }
Parameter getParameter() { none() }
/**
* Holds if this node is the parameter of callable `c` at the specified
* (zero-based) position.
*/
predicate isParameterOf(Callable c, int i) { p = c.getParameter(i) }
predicate isParameterOf(Callable c, int i) { none() }
}
/**

View File

@@ -176,6 +176,49 @@ private module Cached {
)
}
/**
* Holds if there is flow for a captured variable from the enclosing scope into a block.
* ```rb
* foo = 0
* bar {
* puts foo
* }
* ```
*/
cached
predicate captureFlowIn(Definition def, Definition entry) {
exists(LocalVariable v, BasicBlock bb, int i |
ssaDefReachesRead(v, def, bb, i) and
capturedCallRead(bb, i, v) and
exists(BasicBlock bb2, int i2 |
capturedEntryWrite(bb2, i2, v) and
entry.definesAt(v, bb2, i2)
)
)
}
/**
* Holds if there is outgoing flow for a captured variable that is updated in a block.
* ```rb
* foo = 0
* bar {
* foo += 10
* }
* puts foo
* ```
*/
cached
predicate captureFlowOut(Definition def, Definition exit) {
exists(LocalVariable v, BasicBlock bb, int i |
ssaDefReachesRead(v, def, bb, i) and
capturedExitRead(bb, i, v) and
exists(BasicBlock bb2, int i2 |
capturedCallWrite(bb2, i2, v) and
exit.definesAt(v, bb2, i2)
)
)
}
cached
Definition phiHasInputFromBlock(PhiNode phi, BasicBlock bb) {
phiHasInputFromBlock(phi, result, bb)

View File

@@ -1,7 +1,9 @@
private import codeql_ruby.AST as AST
private import codeql_ruby.dataflow.internal.DataFlowImplCommon as DataFlowImplCommon
private import codeql_ruby.dataflow.internal.DataFlowPublic as DataFlowPublic
private import codeql_ruby.dataflow.internal.DataFlowPrivate as DataFlowPrivate
private import codeql_ruby.dataflow.internal.DataFlowDispatch as DataFlowDispatch
private import codeql_ruby.dataflow.internal.SsaImpl as SsaImpl
private import codeql_ruby.controlflow.CfgNodes
class Node = DataFlowPublic::Node;
@@ -21,9 +23,7 @@ predicate jumpStep = DataFlowPrivate::jumpStep/2;
string getPossibleContentName() { result = getSetterCallAttributeName(_) }
/** Holds if `nodeFrom` steps to `nodeTo` by being passed as a parameter in a call. */
predicate callStep(
DataFlowPrivate::ArgumentNode nodeFrom, DataFlowPrivate::ExplicitParameterNode nodeTo
) {
predicate callStep(DataFlowPrivate::ArgumentNode nodeFrom, DataFlowPublic::ParameterNode nodeTo) {
exists(DataFlowDispatch::DataFlowCall call, DataFlowDispatch::DataFlowCallable callable, int i |
call.getTarget() = callable and
nodeFrom.argumentOf(call, i) and
@@ -34,7 +34,7 @@ predicate callStep(
/** Holds if `nodeFrom` steps to `nodeTo` by being returned from a call. */
predicate returnStep(DataFlowPrivate::ReturnNode nodeFrom, Node nodeTo) {
exists(DataFlowDispatch::DataFlowCall call |
nodeFrom.getEnclosingCallable() = call.getTarget() and
DataFlowImplCommon::getNodeEnclosingCallable(nodeFrom) = call.getTarget() and
nodeTo.asExpr().getNode() = call.getNode()
)
}

View File

@@ -1,3 +1,5 @@
| local_dataflow.rb:1:1:7:3 | self in foo | local_dataflow.rb:3:8:3:10 | self |
| local_dataflow.rb:1:9:1:9 | a | local_dataflow.rb:1:9:1:9 | a |
| local_dataflow.rb:1:9:1:9 | a | local_dataflow.rb:2:7:2:7 | a |
| local_dataflow.rb:2:3:2:7 | ... = ... | local_dataflow.rb:3:13:3:13 | b |
| local_dataflow.rb:2:7:2:7 | a | local_dataflow.rb:2:3:2:7 | ... = ... |
@@ -42,8 +44,10 @@
| 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:25 | ... = ... |
| local_dataflow.rb:32:5:32:25 | bar | local_dataflow.rb:32:1:32:25 | ... = ... |
| 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:36:13:36:13 | 7 | local_dataflow.rb:36:6:36:13 | return |
| 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:43:13:43:13 | 7 | local_dataflow.rb:43:6:43:13 | return |
| local_dataflow.rb:45:10:45:10 | 6 | local_dataflow.rb:45:3:45:10 | return |

View File

@@ -1,16 +1,72 @@
#-----| Object
calls.rb:
# 101| Hash
#-----| super -> Object
# 77| Integer
#-----| super -> Numeric
# 86| Kernel
# 90| Module
#-----| super -> Object
# 96| Object
#-----| include -> Kernel
#-----| super -> BasicObject
# 105| Array
#-----| super -> Object
#-----| BasicObject
#-----| Class
#-----| super -> Module
#-----| Kernel
#-----| Complex
#-----| super -> Numeric
#-----| Module
#-----| FalseClass
#-----| super -> Object
#-----| BasicObject
#-----| Float
#-----| super -> Numeric
#-----| NilClass
#-----| super -> Object
#-----| Numeric
#-----| super -> Object
#-----| Proc
#-----| Rational
#-----| super -> Numeric
#-----| Symbol
#-----| TrueClass
#-----| super -> Object
# 15| M
# 29| C
#-----| super -> Object
#-----| include -> M
# 51| D
#-----| super -> C
# 82| String
#-----| super -> Object
# 143| S
#-----| super -> Object
# 149| A
#-----| super -> S
# 154| B
#-----| super -> S
hello.rb:
# 1| EnglishWords

View File

@@ -0,0 +1,91 @@
getTarget
| calls.rb:2:5:2:14 | call to puts | calls.rb:87:5:87:17 | puts |
| calls.rb:5:1:5:3 | call to foo | calls.rb:1:1:3:3 | foo |
| calls.rb:5:1:5:3 | call to foo | calls.rb:71:1:75:3 | foo |
| calls.rb:8:5:8:14 | call to puts | calls.rb:87:5:87:17 | puts |
| calls.rb:11:1:11:8 | call to bar | calls.rb:7:1:9:3 | bar |
| calls.rb:13:1:13:8 | call to foo | calls.rb:1:1:3:3 | foo |
| calls.rb:13:1:13:8 | call to foo | calls.rb:71:1:75:3 | foo |
| calls.rb:22:5:22:15 | call to singleton_m | calls.rb:17:5:17:29 | singleton_m |
| calls.rb:23:5:23:20 | call to singleton_m | calls.rb:17:5:17:29 | singleton_m |
| calls.rb:27:1:27:13 | call to singleton_m | calls.rb:17:5:17:29 | singleton_m |
| calls.rb:30:5:30:13 | call to include | calls.rb:92:5:92:20 | include |
| calls.rb:38:9:38:18 | call to instance_m | calls.rb:16:5:16:23 | instance_m |
| calls.rb:39:9:39:23 | call to instance_m | calls.rb:16:5:16:23 | instance_m |
| calls.rb:46:5:46:9 | call to new | calls.rb:98:5:98:16 | new |
| calls.rb:47:1:47:5 | call to baz | calls.rb:37:5:43:7 | baz |
| calls.rb:49:1:49:12 | call to instance_m | calls.rb:16:5:16:23 | instance_m |
| calls.rb:53:9:53:13 | call to super | calls.rb:37:5:43:7 | baz |
| calls.rb:57:5:57:9 | call to new | calls.rb:98:5:98:16 | new |
| calls.rb:58:1:58:5 | call to baz | calls.rb:52:5:54:7 | baz |
| calls.rb:60:1:60:12 | call to instance_m | calls.rb:16:5:16:23 | instance_m |
| calls.rb:63:5:63:16 | call to bit_length | calls.rb:78:5:78:23 | bit_length |
| calls.rb:64:5:64:16 | call to bit_length | calls.rb:78:5:78:23 | bit_length |
| calls.rb:68:5:68:11 | yield ... | calls.rb:74:16:74:29 | { ... } |
| calls.rb:68:5:68:11 | yield ... | calls.rb:140:10:140:28 | { ... } |
| calls.rb:72:11:72:18 | call to new | calls.rb:98:5:98:16 | new |
| calls.rb:73:5:73:10 | ...[...] | calls.rb:102:5:102:15 | [] |
| calls.rb:74:5:74:29 | call to call_block | calls.rb:67:1:69:3 | call_block |
| calls.rb:74:22:74:27 | ...[...] | calls.rb:102:5:102:15 | [] |
| calls.rb:97:5:97:18 | call to include | calls.rb:92:5:92:20 | include |
| calls.rb:111:15:111:25 | call to length | calls.rb:107:3:107:17 | length |
| calls.rb:112:9:112:24 | yield ... | calls.rb:128:23:128:62 | { ... } |
| calls.rb:112:9:112:24 | yield ... | calls.rb:130:17:130:35 | { ... } |
| calls.rb:112:9:112:24 | yield ... | calls.rb:132:17:132:40 | { ... } |
| calls.rb:112:9:112:24 | yield ... | calls.rb:134:18:134:37 | { ... } |
| calls.rb:112:18:112:24 | ...[...] | calls.rb:106:3:106:13 | [] |
| calls.rb:119:5:119:20 | yield ... | calls.rb:122:7:122:30 | { ... } |
| calls.rb:122:1:122:30 | call to funny | calls.rb:118:1:120:3 | funny |
| calls.rb:122:13:122:29 | call to puts | calls.rb:87:5:87:17 | puts |
| calls.rb:122:18:122:29 | call to capitalize | calls.rb:83:5:83:23 | capitalize |
| calls.rb:124:1:124:14 | call to capitalize | calls.rb:83:5:83:23 | capitalize |
| calls.rb:125:1:125:12 | call to bit_length | calls.rb:78:5:78:23 | bit_length |
| calls.rb:126:1:126:5 | call to abs | calls.rb:79:5:79:16 | abs |
| calls.rb:128:1:128:62 | call to foreach | calls.rb:109:3:115:5 | foreach |
| calls.rb:128:32:128:61 | call to puts | calls.rb:87:5:87:17 | puts |
| calls.rb:130:1:130:35 | call to foreach | calls.rb:109:3:115:5 | foreach |
| calls.rb:130:23:130:34 | call to bit_length | calls.rb:78:5:78:23 | bit_length |
| calls.rb:132:1:132:40 | call to foreach | calls.rb:109:3:115:5 | foreach |
| calls.rb:132:23:132:39 | call to puts | calls.rb:87:5:87:17 | puts |
| calls.rb:134:1:134:37 | call to foreach | calls.rb:109:3:115:5 | foreach |
| calls.rb:134:27:134:36 | call to puts | calls.rb:87:5:87:17 | puts |
| calls.rb:137:5:137:17 | call to call_block | calls.rb:67:1:69:3 | call_block |
| calls.rb:140:1:140:28 | call to indirect | calls.rb:136:1:138:3 | indirect |
| calls.rb:140:16:140:27 | call to bit_length | calls.rb:78:5:78:23 | bit_length |
| calls.rb:145:9:145:17 | call to to_s | calls.rb:150:5:151:7 | to_s |
| calls.rb:145:9:145:17 | call to to_s | calls.rb:155:5:156:7 | to_s |
| calls.rb:159:1:159:5 | call to new | calls.rb:98:5:98:16 | new |
| calls.rb:159:1:159:14 | call to s_method | calls.rb:144:5:146:7 | s_method |
| calls.rb:160:1:160:5 | call to new | calls.rb:98:5:98:16 | new |
| calls.rb:160:1:160:14 | call to s_method | calls.rb:144:5:146:7 | s_method |
| calls.rb:161:1:161:5 | call to new | calls.rb:98:5:98:16 | new |
| calls.rb:161:1:161:14 | call to s_method | calls.rb:144:5:146:7 | s_method |
| hello.rb:12:5:12:24 | call to include | calls.rb:92:5:92:20 | include |
| hello.rb:14:16:14:20 | call to hello | hello.rb:2:5:4:7 | hello |
| hello.rb:20:16:20:20 | call to super | hello.rb:13:5:15:7 | message |
| hello.rb:20:30:20:34 | call to world | hello.rb:5:5:7:7 | world |
| modules.rb:12:5:12:26 | call to puts | calls.rb:87:5:87:17 | puts |
| modules.rb:22:3:22:19 | call to puts | calls.rb:87:5:87:17 | puts |
| modules.rb:33:3:33:25 | call to puts | calls.rb:87:5:87:17 | puts |
| modules.rb:44:3:44:19 | call to puts | calls.rb:87:5:87:17 | puts |
| modules.rb:55:3:55:30 | call to puts | calls.rb:87:5:87:17 | puts |
| modules.rb:89:3:89:16 | call to include | calls.rb:92:5:92:20 | include |
| modules.rb:90:3:90:38 | call to module_eval | calls.rb:91:5:91:24 | module_eval |
| modules.rb:90:24:90:36 | call to prepend | calls.rb:93:5:93:20 | prepend |
| modules.rb:96:3:96:14 | call to include | calls.rb:92:5:92:20 | include |
| modules.rb:102:3:102:16 | call to prepend | calls.rb:93:5:93:20 | prepend |
unresolvedCall
| calls.rb:19:5:19:14 | call to instance_m |
| calls.rb:20:5:20:19 | call to instance_m |
| calls.rb:26:1:26:12 | call to instance_m |
| calls.rb:31:5:31:14 | call to instance_m |
| calls.rb:32:5:32:19 | call to instance_m |
| calls.rb:34:5:34:15 | call to singleton_m |
| calls.rb:35:5:35:20 | call to singleton_m |
| calls.rb:41:9:41:19 | call to singleton_m |
| calls.rb:42:9:42:24 | call to singleton_m |
| calls.rb:48:1:48:13 | call to singleton_m |
| calls.rb:59:1:59:13 | call to singleton_m |
| calls.rb:128:48:128:59 | call to capitalize |
| calls.rb:132:28:132:39 | call to capitalize |
| calls.rb:134:32:134:36 | call to abs |

View File

@@ -0,0 +1,6 @@
import ruby
import codeql_ruby.dataflow.internal.DataFlowDispatch
query DataFlowCallable getTarget(DataFlowCall call) { result = call.getTarget() }
query predicate unresolvedCall(DataFlowCall call) { not exists(call.getTarget()) }

View File

@@ -0,0 +1,161 @@
def foo
puts "foo"
end
foo
def self.bar
puts "bar"
end
self.bar
self.foo
module M
def instance_m; end
def self.singleton_m; end
instance_m # NoMethodError
self.instance_m # NoMethodError
singleton_m
self.singleton_m
end
M.instance_m # NoMethodError
M.singleton_m
class C
include M
instance_m # NoMethodError
self.instance_m # NoMethodError
singleton_m # NoMethodError
self.singleton_m # NoMethodError
def baz
instance_m
self.instance_m
singleton_m # NoMethodError
self.singleton_m # NoMethodError
end
end
c = C.new
c.baz
c.singleton_m # NoMethodError
c.instance_m
class D < C
def baz
super
end
end
d = D.new
d.baz
d.singleton_m # NoMethodError
d.instance_m
def optional_arg(a = 4, b: 5)
a.bit_length
b.bit_length
end
def call_block
yield 1
end
def foo()
var = Hash.new
var[1]
call_block { |x| var[x] }
end
class Integer
def bit_length; end
def abs; end
end
class String
def capitalize; end
end
module Kernel
def puts; end
end
class Module
def module_eval; end
def include; end
def prepend; end
end
class Object < Module
include Kernel
def new; end
end
class Hash
def []; end
end
class Array
def []; end
def length; end
def foreach &body
x = 0
while x < self.length
yield x, self[x]
x += 1
end
end
end
def funny
yield "prefix: "
end
funny { |i| puts i.capitalize}
"a".capitalize
1.bit_length
1.abs
["a","b","c"].foreach { |i, v| puts "#{i} -> #{v.capitalize}"} # TODO should resolve to String.capitalize
[1,2,3].foreach { |i| i.bit_length}
[1,2,3].foreach { |i| puts i.capitalize} # NoMethodError
[1,-2,3].foreach { |_, v| puts v.abs} # TODO should resolve to Integer.abs
def indirect &b
call_block &b
end
indirect { |i| i.bit_length}
class S
def s_method
self.to_s
end
end
class A < S
def to_s
end
end
class B < S
def to_s
end
end
S.new.s_method
A.new.s_method
B.new.s_method

View File

@@ -1,4 +1,28 @@
getMethod
| calls.rb:15:1:24:3 | M | instance_m | calls.rb:16:5:16:23 | instance_m |
| calls.rb:29:1:44:3 | C | baz | calls.rb:37:5:43:7 | baz |
| calls.rb:51:1:55:3 | D | baz | calls.rb:52:5:54:7 | baz |
| calls.rb:77:1:80:3 | Integer | abs | calls.rb:79:5:79:16 | abs |
| calls.rb:77:1:80:3 | Integer | bit_length | calls.rb:78:5:78:23 | bit_length |
| calls.rb:82:1:84:3 | String | capitalize | calls.rb:83:5:83:23 | capitalize |
| calls.rb:86:1:88:3 | Kernel | puts | calls.rb:87:5:87:17 | puts |
| calls.rb:90:1:94:3 | Module | include | calls.rb:92:5:92:20 | include |
| calls.rb:90:1:94:3 | Module | module_eval | calls.rb:91:5:91:24 | module_eval |
| calls.rb:90:1:94:3 | Module | prepend | calls.rb:93:5:93:20 | prepend |
| calls.rb:96:1:99:3 | Object | call_block | calls.rb:67:1:69:3 | call_block |
| calls.rb:96:1:99:3 | Object | foo | calls.rb:1:1:3:3 | foo |
| calls.rb:96:1:99:3 | Object | foo | calls.rb:71:1:75:3 | foo |
| calls.rb:96:1:99:3 | Object | funny | calls.rb:118:1:120:3 | funny |
| calls.rb:96:1:99:3 | Object | indirect | calls.rb:136:1:138:3 | indirect |
| calls.rb:96:1:99:3 | Object | new | calls.rb:98:5:98:16 | new |
| calls.rb:96:1:99:3 | Object | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| calls.rb:101:1:103:3 | Hash | [] | calls.rb:102:5:102:15 | [] |
| calls.rb:105:1:116:3 | Array | [] | calls.rb:106:3:106:13 | [] |
| calls.rb:105:1:116:3 | Array | foreach | calls.rb:109:3:115:5 | foreach |
| calls.rb:105:1:116:3 | Array | length | calls.rb:107:3:107:17 | length |
| calls.rb:143:1:147:3 | S | s_method | calls.rb:144:5:146:7 | s_method |
| calls.rb:149:1:152:3 | A | to_s | calls.rb:150:5:151:7 | to_s |
| calls.rb:154:1:157:3 | B | to_s | calls.rb:155:5:156:7 | to_s |
| hello.rb:1:1:8:3 | EnglishWords | hello | hello.rb:2:5:4:7 | hello |
| hello.rb:1:1:8:3 | EnglishWords | world | hello.rb:5:5:7:7 | world |
| hello.rb:11:1:16:3 | Greeting | message | hello.rb:13:5:15:7 | message |
@@ -10,17 +34,281 @@ getMethod
| modules.rb:37:1:46:3 | Bar | method_a | modules.rb:38:3:39:5 | method_a |
| modules.rb:37:1:46:3 | Bar | method_b | modules.rb:41:3:42:5 | method_b |
lookupMethod
| calls.rb:15:1:24:3 | M | instance_m | calls.rb:16:5:16:23 | instance_m |
| calls.rb:29:1:44:3 | C | baz | calls.rb:37:5:43:7 | baz |
| calls.rb:29:1:44:3 | C | call_block | calls.rb:67:1:69:3 | call_block |
| calls.rb:29:1:44:3 | C | foo | calls.rb:1:1:3:3 | foo |
| calls.rb:29:1:44:3 | C | foo | calls.rb:71:1:75:3 | foo |
| calls.rb:29:1:44:3 | C | funny | calls.rb:118:1:120:3 | funny |
| calls.rb:29:1:44:3 | C | indirect | calls.rb:136:1:138:3 | indirect |
| calls.rb:29:1:44:3 | C | instance_m | calls.rb:16:5:16:23 | instance_m |
| calls.rb:29:1:44:3 | C | new | calls.rb:98:5:98:16 | new |
| calls.rb:29:1:44:3 | C | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| calls.rb:29:1:44:3 | C | puts | calls.rb:87:5:87:17 | puts |
| calls.rb:51:1:55:3 | D | baz | calls.rb:52:5:54:7 | baz |
| calls.rb:51:1:55:3 | D | call_block | calls.rb:67:1:69:3 | call_block |
| calls.rb:51:1:55:3 | D | foo | calls.rb:1:1:3:3 | foo |
| calls.rb:51:1:55:3 | D | foo | calls.rb:71:1:75:3 | foo |
| calls.rb:51:1:55:3 | D | funny | calls.rb:118:1:120:3 | funny |
| calls.rb:51:1:55:3 | D | indirect | calls.rb:136:1:138:3 | indirect |
| calls.rb:51:1:55:3 | D | instance_m | calls.rb:16:5:16:23 | instance_m |
| calls.rb:51:1:55:3 | D | new | calls.rb:98:5:98:16 | new |
| calls.rb:51:1:55:3 | D | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| calls.rb:51:1:55:3 | D | puts | calls.rb:87:5:87:17 | puts |
| calls.rb:77:1:80:3 | Integer | abs | calls.rb:79:5:79:16 | abs |
| calls.rb:77:1:80:3 | Integer | bit_length | calls.rb:78:5:78:23 | bit_length |
| calls.rb:77:1:80:3 | Integer | call_block | calls.rb:67:1:69:3 | call_block |
| calls.rb:77:1:80:3 | Integer | foo | calls.rb:1:1:3:3 | foo |
| calls.rb:77:1:80:3 | Integer | foo | calls.rb:71:1:75:3 | foo |
| calls.rb:77:1:80:3 | Integer | funny | calls.rb:118:1:120:3 | funny |
| calls.rb:77:1:80:3 | Integer | indirect | calls.rb:136:1:138:3 | indirect |
| calls.rb:77:1:80:3 | Integer | new | calls.rb:98:5:98:16 | new |
| calls.rb:77:1:80:3 | Integer | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| calls.rb:77:1:80:3 | Integer | puts | calls.rb:87:5:87:17 | puts |
| calls.rb:82:1:84:3 | String | call_block | calls.rb:67:1:69:3 | call_block |
| calls.rb:82:1:84:3 | String | capitalize | calls.rb:83:5:83:23 | capitalize |
| calls.rb:82:1:84:3 | String | foo | calls.rb:1:1:3:3 | foo |
| calls.rb:82:1:84:3 | String | foo | calls.rb:71:1:75:3 | foo |
| calls.rb:82:1:84:3 | String | funny | calls.rb:118:1:120:3 | funny |
| calls.rb:82:1:84:3 | String | indirect | calls.rb:136:1:138:3 | indirect |
| calls.rb:82:1:84:3 | String | new | calls.rb:98:5:98:16 | new |
| calls.rb:82:1:84:3 | String | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| calls.rb:82:1:84:3 | String | puts | calls.rb:87:5:87:17 | puts |
| calls.rb:86:1:88:3 | Kernel | puts | calls.rb:87:5:87:17 | puts |
| calls.rb:90:1:94:3 | Module | call_block | calls.rb:67:1:69:3 | call_block |
| calls.rb:90:1:94:3 | Module | foo | calls.rb:1:1:3:3 | foo |
| calls.rb:90:1:94:3 | Module | foo | calls.rb:71:1:75:3 | foo |
| calls.rb:90:1:94:3 | Module | funny | calls.rb:118:1:120:3 | funny |
| calls.rb:90:1:94:3 | Module | include | calls.rb:92:5:92:20 | include |
| calls.rb:90:1:94:3 | Module | indirect | calls.rb:136:1:138:3 | indirect |
| calls.rb:90:1:94:3 | Module | module_eval | calls.rb:91:5:91:24 | module_eval |
| calls.rb:90:1:94:3 | Module | new | calls.rb:98:5:98:16 | new |
| calls.rb:90:1:94:3 | Module | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| calls.rb:90:1:94:3 | Module | prepend | calls.rb:93:5:93:20 | prepend |
| calls.rb:90:1:94:3 | Module | puts | calls.rb:87:5:87:17 | puts |
| calls.rb:96:1:99:3 | Object | call_block | calls.rb:67:1:69:3 | call_block |
| calls.rb:96:1:99:3 | Object | foo | calls.rb:1:1:3:3 | foo |
| calls.rb:96:1:99:3 | Object | foo | calls.rb:71:1:75:3 | foo |
| calls.rb:96:1:99:3 | Object | funny | calls.rb:118:1:120:3 | funny |
| calls.rb:96:1:99:3 | Object | indirect | calls.rb:136:1:138:3 | indirect |
| calls.rb:96:1:99:3 | Object | new | calls.rb:98:5:98:16 | new |
| calls.rb:96:1:99:3 | Object | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| calls.rb:96:1:99:3 | Object | puts | calls.rb:87:5:87:17 | puts |
| calls.rb:101:1:103:3 | Hash | [] | calls.rb:102:5:102:15 | [] |
| calls.rb:101:1:103:3 | Hash | call_block | calls.rb:67:1:69:3 | call_block |
| calls.rb:101:1:103:3 | Hash | foo | calls.rb:1:1:3:3 | foo |
| calls.rb:101:1:103:3 | Hash | foo | calls.rb:71:1:75:3 | foo |
| calls.rb:101:1:103:3 | Hash | funny | calls.rb:118:1:120:3 | funny |
| calls.rb:101:1:103:3 | Hash | indirect | calls.rb:136:1:138:3 | indirect |
| calls.rb:101:1:103:3 | Hash | new | calls.rb:98:5:98:16 | new |
| calls.rb:101:1:103:3 | Hash | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| calls.rb:101:1:103:3 | Hash | puts | calls.rb:87:5:87:17 | puts |
| calls.rb:105:1:116:3 | Array | [] | calls.rb:106:3:106:13 | [] |
| calls.rb:105:1:116:3 | Array | call_block | calls.rb:67:1:69:3 | call_block |
| calls.rb:105:1:116:3 | Array | foo | calls.rb:1:1:3:3 | foo |
| calls.rb:105:1:116:3 | Array | foo | calls.rb:71:1:75:3 | foo |
| calls.rb:105:1:116:3 | Array | foreach | calls.rb:109:3:115:5 | foreach |
| calls.rb:105:1:116:3 | Array | funny | calls.rb:118:1:120:3 | funny |
| calls.rb:105:1:116:3 | Array | indirect | calls.rb:136:1:138:3 | indirect |
| calls.rb:105:1:116:3 | Array | length | calls.rb:107:3:107:17 | length |
| calls.rb:105:1:116:3 | Array | new | calls.rb:98:5:98:16 | new |
| calls.rb:105:1:116:3 | Array | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| calls.rb:105:1:116:3 | Array | puts | calls.rb:87:5:87:17 | puts |
| calls.rb:143:1:147:3 | S | call_block | calls.rb:67:1:69:3 | call_block |
| calls.rb:143:1:147:3 | S | foo | calls.rb:1:1:3:3 | foo |
| calls.rb:143:1:147:3 | S | foo | calls.rb:71:1:75:3 | foo |
| calls.rb:143:1:147:3 | S | funny | calls.rb:118:1:120:3 | funny |
| calls.rb:143:1:147:3 | S | indirect | calls.rb:136:1:138:3 | indirect |
| calls.rb:143:1:147:3 | S | new | calls.rb:98:5:98:16 | new |
| calls.rb:143:1:147:3 | S | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| calls.rb:143:1:147:3 | S | puts | calls.rb:87:5:87:17 | puts |
| calls.rb:143:1:147:3 | S | s_method | calls.rb:144:5:146:7 | s_method |
| calls.rb:149:1:152:3 | A | call_block | calls.rb:67:1:69:3 | call_block |
| calls.rb:149:1:152:3 | A | foo | calls.rb:1:1:3:3 | foo |
| calls.rb:149:1:152:3 | A | foo | calls.rb:71:1:75:3 | foo |
| calls.rb:149:1:152:3 | A | funny | calls.rb:118:1:120:3 | funny |
| calls.rb:149:1:152:3 | A | indirect | calls.rb:136:1:138:3 | indirect |
| calls.rb:149:1:152:3 | A | new | calls.rb:98:5:98:16 | new |
| calls.rb:149:1:152:3 | A | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| calls.rb:149:1:152:3 | A | puts | calls.rb:87:5:87:17 | puts |
| calls.rb:149:1:152:3 | A | s_method | calls.rb:144:5:146:7 | s_method |
| calls.rb:149:1:152:3 | A | to_s | calls.rb:150:5:151:7 | to_s |
| calls.rb:154:1:157:3 | B | call_block | calls.rb:67:1:69:3 | call_block |
| calls.rb:154:1:157:3 | B | foo | calls.rb:1:1:3:3 | foo |
| calls.rb:154:1:157:3 | B | foo | calls.rb:71:1:75:3 | foo |
| calls.rb:154:1:157:3 | B | funny | calls.rb:118:1:120:3 | funny |
| calls.rb:154:1:157:3 | B | indirect | calls.rb:136:1:138:3 | indirect |
| calls.rb:154:1:157:3 | B | new | calls.rb:98:5:98:16 | new |
| calls.rb:154:1:157:3 | B | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| calls.rb:154:1:157:3 | B | puts | calls.rb:87:5:87:17 | puts |
| calls.rb:154:1:157:3 | B | s_method | calls.rb:144:5:146:7 | s_method |
| calls.rb:154:1:157:3 | B | to_s | calls.rb:155:5:156:7 | to_s |
| file://:0:0:0:0 | Class | call_block | calls.rb:67:1:69:3 | call_block |
| file://:0:0:0:0 | Class | foo | calls.rb:1:1:3:3 | foo |
| file://:0:0:0:0 | Class | foo | calls.rb:71:1:75:3 | foo |
| file://:0:0:0:0 | Class | funny | calls.rb:118:1:120:3 | funny |
| file://:0:0:0:0 | Class | include | calls.rb:92:5:92:20 | include |
| file://:0:0:0:0 | Class | indirect | calls.rb:136:1:138:3 | indirect |
| file://:0:0:0:0 | Class | module_eval | calls.rb:91:5:91:24 | module_eval |
| file://:0:0:0:0 | Class | new | calls.rb:98:5:98:16 | new |
| file://:0:0:0:0 | Class | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| file://:0:0:0:0 | Class | prepend | calls.rb:93:5:93:20 | prepend |
| file://:0:0:0:0 | Class | puts | calls.rb:87:5:87:17 | puts |
| file://:0:0:0:0 | Complex | call_block | calls.rb:67:1:69:3 | call_block |
| file://:0:0:0:0 | Complex | foo | calls.rb:1:1:3:3 | foo |
| file://:0:0:0:0 | Complex | foo | calls.rb:71:1:75:3 | foo |
| file://:0:0:0:0 | Complex | funny | calls.rb:118:1:120:3 | funny |
| file://:0:0:0:0 | Complex | indirect | calls.rb:136:1:138:3 | indirect |
| file://:0:0:0:0 | Complex | new | calls.rb:98:5:98:16 | new |
| file://:0:0:0:0 | Complex | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| file://:0:0:0:0 | Complex | puts | calls.rb:87:5:87:17 | puts |
| file://:0:0:0:0 | FalseClass | call_block | calls.rb:67:1:69:3 | call_block |
| file://:0:0:0:0 | FalseClass | foo | calls.rb:1:1:3:3 | foo |
| file://:0:0:0:0 | FalseClass | foo | calls.rb:71:1:75:3 | foo |
| file://:0:0:0:0 | FalseClass | funny | calls.rb:118:1:120:3 | funny |
| file://:0:0:0:0 | FalseClass | indirect | calls.rb:136:1:138:3 | indirect |
| file://:0:0:0:0 | FalseClass | new | calls.rb:98:5:98:16 | new |
| file://:0:0:0:0 | FalseClass | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| file://:0:0:0:0 | FalseClass | puts | calls.rb:87:5:87:17 | puts |
| file://:0:0:0:0 | Float | call_block | calls.rb:67:1:69:3 | call_block |
| file://:0:0:0:0 | Float | foo | calls.rb:1:1:3:3 | foo |
| file://:0:0:0:0 | Float | foo | calls.rb:71:1:75:3 | foo |
| file://:0:0:0:0 | Float | funny | calls.rb:118:1:120:3 | funny |
| file://:0:0:0:0 | Float | indirect | calls.rb:136:1:138:3 | indirect |
| file://:0:0:0:0 | Float | new | calls.rb:98:5:98:16 | new |
| file://:0:0:0:0 | Float | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| file://:0:0:0:0 | Float | puts | calls.rb:87:5:87:17 | puts |
| file://:0:0:0:0 | NilClass | call_block | calls.rb:67:1:69:3 | call_block |
| file://:0:0:0:0 | NilClass | foo | calls.rb:1:1:3:3 | foo |
| file://:0:0:0:0 | NilClass | foo | calls.rb:71:1:75:3 | foo |
| file://:0:0:0:0 | NilClass | funny | calls.rb:118:1:120:3 | funny |
| file://:0:0:0:0 | NilClass | indirect | calls.rb:136:1:138:3 | indirect |
| file://:0:0:0:0 | NilClass | new | calls.rb:98:5:98:16 | new |
| file://:0:0:0:0 | NilClass | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| file://:0:0:0:0 | NilClass | puts | calls.rb:87:5:87:17 | puts |
| file://:0:0:0:0 | Numeric | call_block | calls.rb:67:1:69:3 | call_block |
| file://:0:0:0:0 | Numeric | foo | calls.rb:1:1:3:3 | foo |
| file://:0:0:0:0 | Numeric | foo | calls.rb:71:1:75:3 | foo |
| file://:0:0:0:0 | Numeric | funny | calls.rb:118:1:120:3 | funny |
| file://:0:0:0:0 | Numeric | indirect | calls.rb:136:1:138:3 | indirect |
| file://:0:0:0:0 | Numeric | new | calls.rb:98:5:98:16 | new |
| file://:0:0:0:0 | Numeric | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| file://:0:0:0:0 | Numeric | puts | calls.rb:87:5:87:17 | puts |
| file://:0:0:0:0 | Rational | call_block | calls.rb:67:1:69:3 | call_block |
| file://:0:0:0:0 | Rational | foo | calls.rb:1:1:3:3 | foo |
| file://:0:0:0:0 | Rational | foo | calls.rb:71:1:75:3 | foo |
| file://:0:0:0:0 | Rational | funny | calls.rb:118:1:120:3 | funny |
| file://:0:0:0:0 | Rational | indirect | calls.rb:136:1:138:3 | indirect |
| file://:0:0:0:0 | Rational | new | calls.rb:98:5:98:16 | new |
| file://:0:0:0:0 | Rational | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| file://:0:0:0:0 | Rational | puts | calls.rb:87:5:87:17 | puts |
| file://:0:0:0:0 | TrueClass | call_block | calls.rb:67:1:69:3 | call_block |
| file://:0:0:0:0 | TrueClass | foo | calls.rb:1:1:3:3 | foo |
| file://:0:0:0:0 | TrueClass | foo | calls.rb:71:1:75:3 | foo |
| file://:0:0:0:0 | TrueClass | funny | calls.rb:118:1:120:3 | funny |
| file://:0:0:0:0 | TrueClass | indirect | calls.rb:136:1:138:3 | indirect |
| file://:0:0:0:0 | TrueClass | new | calls.rb:98:5:98:16 | new |
| file://:0:0:0:0 | TrueClass | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| file://:0:0:0:0 | TrueClass | puts | calls.rb:87:5:87:17 | puts |
| hello.rb:1:1:8:3 | EnglishWords | hello | hello.rb:2:5:4:7 | hello |
| hello.rb:1:1:8:3 | EnglishWords | world | hello.rb:5:5:7:7 | world |
| hello.rb:11:1:16:3 | Greeting | call_block | calls.rb:67:1:69:3 | call_block |
| hello.rb:11:1:16:3 | Greeting | foo | calls.rb:1:1:3:3 | foo |
| hello.rb:11:1:16:3 | Greeting | foo | calls.rb:71:1:75:3 | foo |
| hello.rb:11:1:16:3 | Greeting | funny | calls.rb:118:1:120:3 | funny |
| hello.rb:11:1:16:3 | Greeting | hello | hello.rb:2:5:4:7 | hello |
| hello.rb:11:1:16:3 | Greeting | indirect | calls.rb:136:1:138:3 | indirect |
| hello.rb:11:1:16:3 | Greeting | message | hello.rb:13:5:15:7 | message |
| hello.rb:11:1:16:3 | Greeting | new | calls.rb:98:5:98:16 | new |
| hello.rb:11:1:16:3 | Greeting | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| hello.rb:11:1:16:3 | Greeting | puts | calls.rb:87:5:87:17 | puts |
| hello.rb:11:1:16:3 | Greeting | world | hello.rb:5:5:7:7 | world |
| hello.rb:18:1:22:3 | HelloWorld | call_block | calls.rb:67:1:69:3 | call_block |
| hello.rb:18:1:22:3 | HelloWorld | foo | calls.rb:1:1:3:3 | foo |
| hello.rb:18:1:22:3 | HelloWorld | foo | calls.rb:71:1:75:3 | foo |
| hello.rb:18:1:22:3 | HelloWorld | funny | calls.rb:118:1:120:3 | funny |
| hello.rb:18:1:22:3 | HelloWorld | hello | hello.rb:2:5:4:7 | hello |
| hello.rb:18:1:22:3 | HelloWorld | indirect | calls.rb:136:1:138:3 | indirect |
| hello.rb:18:1:22:3 | HelloWorld | message | hello.rb:19:5:21:7 | message |
| hello.rb:18:1:22:3 | HelloWorld | new | calls.rb:98:5:98:16 | new |
| hello.rb:18:1:22:3 | HelloWorld | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| hello.rb:18:1:22:3 | HelloWorld | puts | calls.rb:87:5:87:17 | puts |
| hello.rb:18:1:22:3 | HelloWorld | world | hello.rb:5:5:7:7 | world |
| modules.rb:4:1:24:3 | Foo | method_in_another_definition_of_foo | modules.rb:27:3:28:5 | method_in_another_definition_of_foo |
| modules.rb:4:1:24:3 | Foo | method_in_foo | modules.rb:16:3:17:5 | method_in_foo |
| modules.rb:5:3:14:5 | Foo::Bar | method_in_another_definition_of_foo_bar | modules.rb:52:3:53:5 | method_in_another_definition_of_foo_bar |
| modules.rb:5:3:14:5 | Foo::Bar | method_in_foo_bar | modules.rb:9:5:10:7 | method_in_foo_bar |
| modules.rb:6:5:7:7 | Foo::Bar::ClassInFooBar | call_block | calls.rb:67:1:69:3 | call_block |
| modules.rb:6:5:7:7 | Foo::Bar::ClassInFooBar | foo | calls.rb:1:1:3:3 | foo |
| modules.rb:6:5:7:7 | Foo::Bar::ClassInFooBar | foo | calls.rb:71:1:75:3 | foo |
| modules.rb:6:5:7:7 | Foo::Bar::ClassInFooBar | funny | calls.rb:118:1:120:3 | funny |
| modules.rb:6:5:7:7 | Foo::Bar::ClassInFooBar | indirect | calls.rb:136:1:138:3 | indirect |
| modules.rb:6:5:7:7 | Foo::Bar::ClassInFooBar | new | calls.rb:98:5:98:16 | new |
| modules.rb:6:5:7:7 | Foo::Bar::ClassInFooBar | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| modules.rb:6:5:7:7 | Foo::Bar::ClassInFooBar | puts | calls.rb:87:5:87:17 | puts |
| modules.rb:19:3:20:5 | Foo::ClassInFoo | call_block | calls.rb:67:1:69:3 | call_block |
| modules.rb:19:3:20:5 | Foo::ClassInFoo | foo | calls.rb:1:1:3:3 | foo |
| modules.rb:19:3:20:5 | Foo::ClassInFoo | foo | calls.rb:71:1:75:3 | foo |
| modules.rb:19:3:20:5 | Foo::ClassInFoo | funny | calls.rb:118:1:120:3 | funny |
| modules.rb:19:3:20:5 | Foo::ClassInFoo | indirect | calls.rb:136:1:138:3 | indirect |
| modules.rb:19:3:20:5 | Foo::ClassInFoo | new | calls.rb:98:5:98:16 | new |
| modules.rb:19:3:20:5 | Foo::ClassInFoo | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| modules.rb:19:3:20:5 | Foo::ClassInFoo | puts | calls.rb:87:5:87:17 | puts |
| modules.rb:30:3:31:5 | Foo::ClassInAnotherDefinitionOfFoo | call_block | calls.rb:67:1:69:3 | call_block |
| modules.rb:30:3:31:5 | Foo::ClassInAnotherDefinitionOfFoo | foo | calls.rb:1:1:3:3 | foo |
| modules.rb:30:3:31:5 | Foo::ClassInAnotherDefinitionOfFoo | foo | calls.rb:71:1:75:3 | foo |
| modules.rb:30:3:31:5 | Foo::ClassInAnotherDefinitionOfFoo | funny | calls.rb:118:1:120:3 | funny |
| modules.rb:30:3:31:5 | Foo::ClassInAnotherDefinitionOfFoo | indirect | calls.rb:136:1:138:3 | indirect |
| modules.rb:30:3:31:5 | Foo::ClassInAnotherDefinitionOfFoo | new | calls.rb:98:5:98:16 | new |
| modules.rb:30:3:31:5 | Foo::ClassInAnotherDefinitionOfFoo | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| modules.rb:30:3:31:5 | Foo::ClassInAnotherDefinitionOfFoo | puts | calls.rb:87:5:87:17 | puts |
| modules.rb:37:1:46:3 | Bar | call_block | calls.rb:67:1:69:3 | call_block |
| modules.rb:37:1:46:3 | Bar | foo | calls.rb:1:1:3:3 | foo |
| modules.rb:37:1:46:3 | Bar | foo | calls.rb:71:1:75:3 | foo |
| modules.rb:37:1:46:3 | Bar | funny | calls.rb:118:1:120:3 | funny |
| modules.rb:37:1:46:3 | Bar | indirect | calls.rb:136:1:138:3 | indirect |
| modules.rb:37:1:46:3 | Bar | method_a | modules.rb:38:3:39:5 | method_a |
| modules.rb:37:1:46:3 | Bar | method_b | modules.rb:41:3:42:5 | method_b |
| modules.rb:37:1:46:3 | Bar | new | calls.rb:98:5:98:16 | new |
| modules.rb:37:1:46:3 | Bar | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| modules.rb:37:1:46:3 | Bar | puts | calls.rb:87:5:87:17 | puts |
| modules.rb:49:3:50:5 | Foo::Bar::ClassInAnotherDefinitionOfFooBar | call_block | calls.rb:67:1:69:3 | call_block |
| modules.rb:49:3:50:5 | Foo::Bar::ClassInAnotherDefinitionOfFooBar | foo | calls.rb:1:1:3:3 | foo |
| modules.rb:49:3:50:5 | Foo::Bar::ClassInAnotherDefinitionOfFooBar | foo | calls.rb:71:1:75:3 | foo |
| modules.rb:49:3:50:5 | Foo::Bar::ClassInAnotherDefinitionOfFooBar | funny | calls.rb:118:1:120:3 | funny |
| modules.rb:49:3:50:5 | Foo::Bar::ClassInAnotherDefinitionOfFooBar | indirect | calls.rb:136:1:138:3 | indirect |
| modules.rb:49:3:50:5 | Foo::Bar::ClassInAnotherDefinitionOfFooBar | new | calls.rb:98:5:98:16 | new |
| modules.rb:49:3:50:5 | Foo::Bar::ClassInAnotherDefinitionOfFooBar | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| modules.rb:49:3:50:5 | Foo::Bar::ClassInAnotherDefinitionOfFooBar | puts | calls.rb:87:5:87:17 | puts |
| modules.rb:66:5:67:7 | Test::Foo1::Bar | call_block | calls.rb:67:1:69:3 | call_block |
| modules.rb:66:5:67:7 | Test::Foo1::Bar | foo | calls.rb:1:1:3:3 | foo |
| modules.rb:66:5:67:7 | Test::Foo1::Bar | foo | calls.rb:71:1:75:3 | foo |
| modules.rb:66:5:67:7 | Test::Foo1::Bar | funny | calls.rb:118:1:120:3 | funny |
| modules.rb:66:5:67:7 | Test::Foo1::Bar | indirect | calls.rb:136:1:138:3 | indirect |
| modules.rb:66:5:67:7 | Test::Foo1::Bar | new | calls.rb:98:5:98:16 | new |
| modules.rb:66:5:67:7 | Test::Foo1::Bar | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| modules.rb:66:5:67:7 | Test::Foo1::Bar | puts | calls.rb:87:5:87:17 | puts |
| modules.rb:72:5:73:7 | Test::Foo2::Foo2::Bar | call_block | calls.rb:67:1:69:3 | call_block |
| modules.rb:72:5:73:7 | Test::Foo2::Foo2::Bar | foo | calls.rb:1:1:3:3 | foo |
| modules.rb:72:5:73:7 | Test::Foo2::Foo2::Bar | foo | calls.rb:71:1:75:3 | foo |
| modules.rb:72:5:73:7 | Test::Foo2::Foo2::Bar | funny | calls.rb:118:1:120:3 | funny |
| modules.rb:72:5:73:7 | Test::Foo2::Foo2::Bar | indirect | calls.rb:136:1:138:3 | indirect |
| modules.rb:72:5:73:7 | Test::Foo2::Foo2::Bar | new | calls.rb:98:5:98:16 | new |
| modules.rb:72:5:73:7 | Test::Foo2::Foo2::Bar | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| modules.rb:72:5:73:7 | Test::Foo2::Foo2::Bar | puts | calls.rb:87:5:87:17 | puts |
| modules.rb:112:1:113:3 | YY | call_block | calls.rb:67:1:69:3 | call_block |
| modules.rb:112:1:113:3 | YY | foo | calls.rb:1:1:3:3 | foo |
| modules.rb:112:1:113:3 | YY | foo | calls.rb:71:1:75:3 | foo |
| modules.rb:112:1:113:3 | YY | funny | calls.rb:118:1:120:3 | funny |
| modules.rb:112:1:113:3 | YY | indirect | calls.rb:136:1:138:3 | indirect |
| modules.rb:112:1:113:3 | YY | new | calls.rb:98:5:98:16 | new |
| modules.rb:112:1:113:3 | YY | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| modules.rb:112:1:113:3 | YY | puts | calls.rb:87:5:87:17 | puts |
| modules.rb:116:7:117:9 | XX::YY | call_block | calls.rb:67:1:69:3 | call_block |
| modules.rb:116:7:117:9 | XX::YY | foo | calls.rb:1:1:3:3 | foo |
| modules.rb:116:7:117:9 | XX::YY | foo | calls.rb:71:1:75:3 | foo |
| modules.rb:116:7:117:9 | XX::YY | funny | calls.rb:118:1:120:3 | funny |
| modules.rb:116:7:117:9 | XX::YY | indirect | calls.rb:136:1:138:3 | indirect |
| modules.rb:116:7:117:9 | XX::YY | new | calls.rb:98:5:98:16 | new |
| modules.rb:116:7:117:9 | XX::YY | optional_arg | calls.rb:62:1:65:3 | optional_arg |
| modules.rb:116:7:117:9 | XX::YY | puts | calls.rb:87:5:87:17 | puts |

View File

@@ -1,9 +1,28 @@
getModule
| calls.rb:15:1:24:3 | M |
| calls.rb:29:1:44:3 | C |
| calls.rb:51:1:55:3 | D |
| calls.rb:77:1:80:3 | Integer |
| calls.rb:82:1:84:3 | String |
| calls.rb:86:1:88:3 | Kernel |
| calls.rb:90:1:94:3 | Module |
| calls.rb:96:1:99:3 | Object |
| calls.rb:101:1:103:3 | Hash |
| calls.rb:105:1:116:3 | Array |
| calls.rb:143:1:147:3 | S |
| calls.rb:149:1:152:3 | A |
| calls.rb:154:1:157:3 | B |
| file://:0:0:0:0 | BasicObject |
| file://:0:0:0:0 | Class |
| file://:0:0:0:0 | Kernel |
| file://:0:0:0:0 | Module |
| file://:0:0:0:0 | Object |
| file://:0:0:0:0 | Complex |
| file://:0:0:0:0 | FalseClass |
| file://:0:0:0:0 | Float |
| file://:0:0:0:0 | NilClass |
| file://:0:0:0:0 | Numeric |
| file://:0:0:0:0 | Proc |
| file://:0:0:0:0 | Rational |
| file://:0:0:0:0 | Symbol |
| file://:0:0:0:0 | TrueClass |
| hello.rb:1:1:8:3 | EnglishWords |
| hello.rb:11:1:16:3 | Greeting |
| hello.rb:18:1:22:3 | HelloWorld |
@@ -38,8 +57,22 @@ getModule
| modules.rb:116:7:117:9 | XX::YY |
| modules.rb:120:1:121:3 | Test::Foo1::Bar::Baz |
getADeclaration
| file://:0:0:0:0 | Object | hello.rb:1:1:22:3 | hello.rb |
| file://:0:0:0:0 | Object | modules.rb:1:1:122:1 | modules.rb |
| calls.rb:15:1:24:3 | M | calls.rb:15:1:24:3 | M |
| calls.rb:29:1:44:3 | C | calls.rb:29:1:44:3 | C |
| calls.rb:51:1:55:3 | D | calls.rb:51:1:55:3 | D |
| calls.rb:77:1:80:3 | Integer | calls.rb:77:1:80:3 | Integer |
| calls.rb:82:1:84:3 | String | calls.rb:82:1:84:3 | String |
| calls.rb:86:1:88:3 | Kernel | calls.rb:86:1:88:3 | Kernel |
| calls.rb:90:1:94:3 | Module | calls.rb:90:1:94:3 | Module |
| calls.rb:96:1:99:3 | Object | calls.rb:1:1:161:15 | calls.rb |
| calls.rb:96:1:99:3 | Object | calls.rb:96:1:99:3 | Object |
| calls.rb:96:1:99:3 | Object | hello.rb:1:1:22:3 | hello.rb |
| calls.rb:96:1:99:3 | Object | modules.rb:1:1:122:1 | modules.rb |
| calls.rb:101:1:103:3 | Hash | calls.rb:101:1:103:3 | Hash |
| calls.rb:105:1:116:3 | Array | calls.rb:105:1:116:3 | Array |
| calls.rb:143:1:147:3 | S | calls.rb:143:1:147:3 | S |
| calls.rb:149:1:152:3 | A | calls.rb:149:1:152:3 | A |
| calls.rb:154:1:157:3 | B | calls.rb:154:1:157:3 | B |
| hello.rb:1:1:8:3 | EnglishWords | hello.rb:1:1:8:3 | EnglishWords |
| hello.rb:11:1:16:3 | Greeting | hello.rb:11:1:16:3 | Greeting |
| hello.rb:18:1:22:3 | HelloWorld | hello.rb:18:1:22:3 | HelloWorld |
@@ -77,24 +110,41 @@ getADeclaration
| modules.rb:116:7:117:9 | XX::YY | modules.rb:116:7:117:9 | YY |
| modules.rb:120:1:121:3 | Test::Foo1::Bar::Baz | modules.rb:120:1:121:3 | Baz |
getSuperClass
| file://:0:0:0:0 | Class | file://:0:0:0:0 | Module |
| file://:0:0:0:0 | Module | file://:0:0:0:0 | Object |
| file://:0:0:0:0 | Object | file://:0:0:0:0 | BasicObject |
| hello.rb:11:1:16:3 | Greeting | file://:0:0:0:0 | Object |
| calls.rb:29:1:44:3 | C | calls.rb:96:1:99:3 | Object |
| calls.rb:51:1:55:3 | D | calls.rb:29:1:44:3 | C |
| calls.rb:77:1:80:3 | Integer | file://:0:0:0:0 | Numeric |
| calls.rb:82:1:84:3 | String | calls.rb:96:1:99:3 | Object |
| calls.rb:90:1:94:3 | Module | calls.rb:96:1:99:3 | Object |
| calls.rb:96:1:99:3 | Object | file://:0:0:0:0 | BasicObject |
| calls.rb:101:1:103:3 | Hash | calls.rb:96:1:99:3 | Object |
| calls.rb:105:1:116:3 | Array | calls.rb:96:1:99:3 | Object |
| calls.rb:143:1:147:3 | S | calls.rb:96:1:99:3 | Object |
| calls.rb:149:1:152:3 | A | calls.rb:143:1:147:3 | S |
| calls.rb:154:1:157:3 | B | calls.rb:143:1:147:3 | S |
| file://:0:0:0:0 | Class | calls.rb:90:1:94:3 | Module |
| file://:0:0:0:0 | Complex | file://:0:0:0:0 | Numeric |
| file://:0:0:0:0 | FalseClass | calls.rb:96:1:99:3 | Object |
| file://:0:0:0:0 | Float | file://:0:0:0:0 | Numeric |
| file://:0:0:0:0 | NilClass | calls.rb:96:1:99:3 | Object |
| file://:0:0:0:0 | Numeric | calls.rb:96:1:99:3 | Object |
| file://:0:0:0:0 | Rational | file://:0:0:0:0 | Numeric |
| file://:0:0:0:0 | TrueClass | calls.rb:96:1:99:3 | Object |
| hello.rb:11:1:16:3 | Greeting | calls.rb:96:1:99:3 | Object |
| hello.rb:18:1:22:3 | HelloWorld | hello.rb:11:1:16:3 | Greeting |
| modules.rb:6:5:7:7 | Foo::Bar::ClassInFooBar | file://:0:0:0:0 | Object |
| modules.rb:19:3:20:5 | Foo::ClassInFoo | file://:0:0:0:0 | Object |
| modules.rb:30:3:31:5 | Foo::ClassInAnotherDefinitionOfFoo | file://:0:0:0:0 | Object |
| modules.rb:37:1:46:3 | Bar | file://:0:0:0:0 | Object |
| modules.rb:49:3:50:5 | Foo::Bar::ClassInAnotherDefinitionOfFooBar | file://:0:0:0:0 | Object |
| modules.rb:66:5:67:7 | Test::Foo1::Bar | file://:0:0:0:0 | Object |
| modules.rb:72:5:73:7 | Test::Foo2::Foo2::Bar | file://:0:0:0:0 | Object |
| modules.rb:112:1:113:3 | YY | file://:0:0:0:0 | Object |
| modules.rb:6:5:7:7 | Foo::Bar::ClassInFooBar | calls.rb:96:1:99:3 | Object |
| modules.rb:19:3:20:5 | Foo::ClassInFoo | calls.rb:96:1:99:3 | Object |
| modules.rb:30:3:31:5 | Foo::ClassInAnotherDefinitionOfFoo | calls.rb:96:1:99:3 | Object |
| modules.rb:37:1:46:3 | Bar | calls.rb:96:1:99:3 | Object |
| modules.rb:49:3:50:5 | Foo::Bar::ClassInAnotherDefinitionOfFooBar | calls.rb:96:1:99:3 | Object |
| modules.rb:66:5:67:7 | Test::Foo1::Bar | calls.rb:96:1:99:3 | Object |
| modules.rb:72:5:73:7 | Test::Foo2::Foo2::Bar | calls.rb:96:1:99:3 | Object |
| modules.rb:112:1:113:3 | YY | calls.rb:96:1:99:3 | Object |
| modules.rb:116:7:117:9 | XX::YY | modules.rb:112:1:113:3 | YY |
getAPrependedModule
| modules.rb:101:1:105:3 | PrependTest | modules.rb:63:1:81:3 | Test |
getAnIncludedModule
| file://:0:0:0:0 | Object | file://:0:0:0:0 | Kernel |
| calls.rb:29:1:44:3 | C | calls.rb:15:1:24:3 | M |
| calls.rb:96:1:99:3 | Object | calls.rb:86:1:88:3 | Kernel |
| hello.rb:11:1:16:3 | Greeting | hello.rb:1:1:8:3 | EnglishWords |
| modules.rb:88:1:93:3 | IncludeTest | modules.rb:63:1:81:3 | Test |
| modules.rb:95:1:99:3 | IncludeTest2 | modules.rb:63:1:81:3 | Test |

View File

@@ -1,15 +1,70 @@
#-----| Object
calls.rb:
# 101| Hash
#-----| -> Object
# 77| Integer
#-----| -> Numeric
# 86| Kernel
# 90| Module
#-----| -> Object
# 96| Object
#-----| -> BasicObject
# 105| Array
#-----| -> Object
#-----| BasicObject
#-----| Class
#-----| -> Module
#-----| Kernel
#-----| Complex
#-----| -> Numeric
#-----| Module
#-----| FalseClass
#-----| -> Object
#-----| BasicObject
#-----| Float
#-----| -> Numeric
#-----| NilClass
#-----| -> Object
#-----| Numeric
#-----| -> Object
#-----| Proc
#-----| Rational
#-----| -> Numeric
#-----| Symbol
#-----| TrueClass
#-----| -> Object
# 15| M
# 29| C
#-----| -> Object
# 51| D
#-----| -> C
# 82| String
#-----| -> Object
# 143| S
#-----| -> Object
# 149| A
#-----| -> S
# 154| B
#-----| -> S
hello.rb:
# 1| EnglishWords