mirror of
https://github.com/github/codeql.git
synced 2026-04-24 08:15:14 +02:00
Merge pull request #168 from github/aibaars/typetrack-method
Call graph
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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`
|
||||
|
||||
@@ -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() }
|
||||
|
||||
|
||||
@@ -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() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
|
||||
91
ql/test/library-tests/modules/callgraph.expected
Normal file
91
ql/test/library-tests/modules/callgraph.expected
Normal 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 |
|
||||
6
ql/test/library-tests/modules/callgraph.ql
Normal file
6
ql/test/library-tests/modules/callgraph.ql
Normal 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()) }
|
||||
161
ql/test/library-tests/modules/calls.rb
Normal file
161
ql/test/library-tests/modules/calls.rb
Normal 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
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user