Merge pull request #162 from github/aibaars/modules

Basic implementation of module resolution
This commit is contained in:
Arthur Baars
2021-04-09 20:50:54 +02:00
committed by GitHub
20 changed files with 610 additions and 149 deletions

View File

@@ -13,6 +13,7 @@ import ast.Scope
import ast.Statement
import ast.Variable
private import ast.internal.AST
private import ast.internal.Scope
/**
* A node in the abstract syntax tree. This class is the base class for all Ruby
@@ -28,6 +29,20 @@ class AstNode extends TAstNode {
*/
string getAPrimaryQlClass() { result = "???" }
/** Gets the enclosing module, if any. */
ModuleBase getEnclosingModule() {
exists(Scope::Range s |
s = scopeOf(toGenerated(this)) and toGenerated(result) = s.getEnclosingModule()
)
}
/** Gets the enclosing method, if any. */
MethodBase getEnclosingMethod() {
exists(Scope::Range s |
s = scopeOf(toGenerated(this)) and toGenerated(result) = s.getEnclosingMethod()
)
}
/** Gets a textual representation of this node. */
cached
string toString() { none() }

View File

@@ -137,11 +137,11 @@ class BodyStmt extends StmtSequence, TBodyStmt {
result = any(Generated::Program g | this = TToplevel(g)).getChild(i) and
not result instanceof Generated::BeginBlock
or
result = any(Generated::Class g | this = TClass(g)).getChild(i)
result = any(Generated::Class g | this = TClassDeclaration(g)).getChild(i)
or
result = any(Generated::SingletonClass g | this = TSingletonClass(g)).getChild(i)
or
result = any(Generated::Module g | this = TModule(g)).getChild(i)
result = any(Generated::Module g | this = TModuleDeclaration(g)).getChild(i)
or
result = any(Generated::Begin g | this = TBeginExpr(g)).getChild(i)
}

View File

@@ -4,7 +4,7 @@ private import internal.AST
private import internal.TreeSitter
/** A callable. */
class Callable extends Expr, TCallable {
class Callable extends Expr, Scope, TCallable {
/** Gets the number of parameters of this callable. */
final int getNumberOfParameters() { result = count(this.getAParameter()) }

View File

@@ -1,12 +1,46 @@
private import codeql_ruby.AST
private import codeql_ruby.ast.Constant
private import internal.AST
private import internal.Module
private import internal.TreeSitter
/**
* A representation of a run-time `module` or `class` value.
*/
class Module extends TModule {
/** Get a declaration of this module, if any. */
ModuleBase getADeclaration() { result.getModule() = this }
/** Gets a textual representation of this module. */
string toString() {
this = TResolved(result)
or
exists(Namespace n | this = TUnresolved(n) and result = "...::" + n.toString())
}
/** Gets the location of this module. */
Location getLocation() {
exists(Namespace n | this = TUnresolved(n) and result = n.getLocation())
or
result =
min(Namespace n, string qName, Location loc, int weight |
this = TResolved(qName) and
qName = namespaceDeclaration(n) and
loc = n.getLocation() and
if exists(loc.getFile().getRelativePath()) then weight = 0 else weight = 1
|
loc
order by
weight, count(n.getAStmt()) desc, loc.getFile().getAbsolutePath(), loc.getStartLine(),
loc.getStartColumn()
)
}
}
/**
* The base class for classes, singleton classes, and modules.
*/
class ModuleBase extends BodyStmt, TModuleBase {
class ModuleBase extends BodyStmt, Scope, TModuleBase {
/** Gets a method defined in this module/class. */
MethodBase getAMethod() { result = this.getAStmt() }
@@ -14,16 +48,21 @@ class ModuleBase extends BodyStmt, TModuleBase {
MethodBase getMethod(string name) { result = this.getAMethod() and result.getName() = name }
/** Gets a class defined in this module/class. */
Class getAClass() { result = this.getAStmt() }
ClassDeclaration getAClass() { result = this.getAStmt() }
/** Gets the class named `name` in this module/class, if any. */
Class getClass(string name) { result = this.getAClass() and result.getName() = name }
ClassDeclaration getClass(string name) { result = this.getAClass() and result.getName() = name }
/** Gets a module defined in this module/class. */
Module getAModule() { result = this.getAStmt() }
ModuleDeclaration getAModule() { result = this.getAStmt() }
/** Gets the module named `name` in this module/class, if any. */
Module getModule(string name) { result = this.getAModule() and result.getName() = name }
ModuleDeclaration getModule(string name) {
result = this.getAModule() and result.getName() = name
}
/** Gets the representation of the run-time value of this module or class. */
Module getModule() { none() }
}
/**
@@ -62,6 +101,8 @@ class Toplevel extends ModuleBase, TToplevel {
pred = "getBeginBlock" and result = this.getBeginBlock(_)
}
final override Module getModule() { result = TResolved("Object") }
final override string toString() { result = g.getLocation().getFile().getBaseName() }
}
@@ -132,6 +173,12 @@ class Namespace extends ModuleBase, ConstantWriteAccess, TNamespace {
*/
override predicate hasGlobalScope() { none() }
final override Module getModule() {
result = any(string qName | qName = namespaceDeclaration(this) | TResolved(qName))
or
result = TUnresolved(this)
}
override AstNode getAChild(string pred) {
result = ModuleBase.super.getAChild(pred) or
result = ConstantWriteAccess.super.getAChild(pred)
@@ -150,12 +197,12 @@ class Namespace extends ModuleBase, ConstantWriteAccess, TNamespace {
* end
* ```
*/
class Class extends Namespace, TClass {
class ClassDeclaration extends Namespace, TClassDeclaration {
private Generated::Class g;
Class() { this = TClass(g) }
ClassDeclaration() { this = TClassDeclaration(g) }
final override string getAPrimaryQlClass() { result = "Class" }
final override string getAPrimaryQlClass() { result = "ClassDeclaration" }
/**
* Gets the `Expr` used as the superclass in the class definition, if any.
@@ -214,7 +261,7 @@ class SingletonClass extends ModuleBase, TSingletonClass {
SingletonClass() { this = TSingletonClass(g) }
final override string getAPrimaryQlClass() { result = "Class" }
final override string getAPrimaryQlClass() { result = "ClassDeclaration" }
/**
* Gets the expression resulting in the object on which the singleton class
@@ -249,7 +296,7 @@ class SingletonClass extends ModuleBase, TSingletonClass {
* N.B. this class represents a single instance of a module definition. In the
* following example, classes `Bar` and `Baz` are both defined in the module
* `Foo`, but in two syntactically distinct definitions, meaning that there
* will be two instances of `Module` in the database.
* will be two instances of `ModuleDeclaration` in the database.
*
* ```rb
* module Foo
@@ -261,12 +308,12 @@ class SingletonClass extends ModuleBase, TSingletonClass {
* end
* ```
*/
class Module extends Namespace, TModule {
class ModuleDeclaration extends Namespace, TModuleDeclaration {
private Generated::Module g;
Module() { this = TModule(g) }
ModuleDeclaration() { this = TModuleDeclaration(g) }
final override string getAPrimaryQlClass() { result = "Module" }
final override string getAPrimaryQlClass() { result = "ModuleDeclaration" }
final override string getName() {
result = g.getName().(Generated::Token).getValue() or

View File

@@ -8,12 +8,6 @@ class Scope extends AstNode, TScopeType {
Scope() { range = toGenerated(this) }
/** Gets the enclosing module, if any. */
ModuleBase getEnclosingModule() { toGenerated(result) = range.getEnclosingModule() }
/** Gets the enclosing method, if any. */
MethodBase getEnclosingMethod() { toGenerated(result) = range.getEnclosingMethod() }
/** Gets the scope in which this scope is nested, if any. */
Scope getOuterScope() { toGenerated(result) = range.getOuterScope() }

View File

@@ -82,7 +82,7 @@ private module Cached {
TCaseEqExpr(Generated::Binary g) { g instanceof @binary_equalequalequal } or
TCaseExpr(Generated::Case g) or
TCharacterLiteral(Generated::Character g) or
TClass(Generated::Class g) or
TClassDeclaration(Generated::Class g) or
TClassVariableAccess(Generated::ClassVariable g, AST::ClassVariable v) {
ClassVariableAccess::range(g, v)
} or
@@ -139,7 +139,7 @@ private module Cached {
} or
TLogicalOrExpr(Generated::Binary g) { g instanceof @binary_or or g instanceof @binary_pipepipe } or
TMethod(Generated::Method g) or
TModule(Generated::Module g) or
TModuleDeclaration(Generated::Module g) or
TModuloExpr(Generated::Binary g) { g instanceof @binary_percent } or
TMulExpr(Generated::Binary g) { g instanceof @binary_star } or
TNEExpr(Generated::Binary g) { g instanceof @binary_bangequal } or
@@ -257,7 +257,7 @@ private module Cached {
n = TCaseEqExpr(result) or
n = TCaseExpr(result) or
n = TCharacterLiteral(result) or
n = TClass(result) or
n = TClassDeclaration(result) or
n = TClassVariableAccess(result, _) or
n = TComplementExpr(result) or
n = TComplexLiteral(result) or
@@ -302,7 +302,7 @@ private module Cached {
n = TLogicalAndExpr(result) or
n = TLogicalOrExpr(result) or
n = TMethod(result) or
n = TModule(result) or
n = TModuleDeclaration(result) or
n = TModuloExpr(result) or
n = TMulExpr(result) or
n = TNEExpr(result) or
@@ -434,7 +434,7 @@ class TBlock = TDoBlock or TBraceBlock;
class TModuleBase = TToplevel or TNamespace or TSingletonClass;
class TNamespace = TClass or TModule;
class TNamespace = TClassDeclaration or TModuleDeclaration;
class TOperation = TUnaryOperation or TBinaryOperation or TAssignment;

View File

@@ -0,0 +1,218 @@
private import codeql.Locations
private import codeql_ruby.ast.Call
private import codeql_ruby.ast.Constant
private import codeql_ruby.ast.Expr
private import codeql_ruby.ast.Module
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"] }
cached
private module Cached {
cached
newtype TModule =
TResolved(string qName) {
qName = builtin()
or
qName = namespaceDeclaration(_)
} or
TUnresolved(Namespace n) { not exists(namespaceDeclaration(n)) }
cached
string namespaceDeclaration(Namespace n) {
isToplevel(n) and result = n.getName()
or
not isToplevel(n) and
not exists(n.getScopeExpr()) and
result = scopeAppend(namespaceDeclaration(n.getEnclosingModule()), n.getName())
or
exists(string container |
TResolved(container) = resolveScopeExpr(n.getScopeExpr()) and
result = scopeAppend(container, n.getName())
)
}
}
import Cached
private predicate isToplevel(ConstantAccess n) {
not exists(n.getScopeExpr()) and
(
n.hasGlobalScope()
or
n.getEnclosingModule() instanceof Toplevel
)
}
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)
|
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) {
result = m and level = 0
or
result = enclosing(m.getEnclosingModule(), level - 1)
}
/**
* Resolve constant read access (typically a scope expression) to a qualified name. The
* `priority` value indicates the precedence of the solution with respect to the lookup order.
* A constant name without scope specifier is resolved against its enclosing modules (inner-most first);
* if the constant is not found in any of the enclosing modules, then the constant will be resolved
* with respect to the ancestors (prepends, includes, super classes, and their ancestors) of the
* directly enclosing module.
*/
private string resolveScopeExpr(ConstantReadAccess c, int priority) {
c.hasGlobalScope() and result = c.getName() and priority = 0
or
result = qualifiedModuleName(resolveScopeExpr(c.getScopeExpr(), priority), c.getName())
or
not exists(c.getScopeExpr()) and
not c.hasGlobalScope() and
exists(Namespace n |
result = qualifiedModuleName(constantDefinition0(n), c.getName()) and
n = enclosing(c.getEnclosingModule(), priority)
)
or
result =
qualifiedModuleName(ancestors(qualifiedModuleName(c.getEnclosingModule()), priority - maxDepth()),
c.getName())
or
result = c.getName() and
priority = maxDepth() + 4 and
qualifiedModuleName(c.getEnclosingModule()) != "BasicObject"
}
bindingset[qualifier, name]
private string scopeAppend(string qualifier, string name) {
if qualifier = "Object" then result = name else result = qualifier + "::" + name
}
private string qualifiedModuleName(ModuleBase m) {
result = "Object" and m instanceof Toplevel
or
result = constantDefinition0(m)
}
/**
* Get a qualified name for a constant definition. May return multiple qualified
* names because we over-approximate when resolving scope resolutions and ignore
* lookup order precedence. Taking lookup order into account here would lead to
* non-monotonic recursion.
*/
private string constantDefinition0(ConstantWriteAccess c) {
c.hasGlobalScope() and result = c.getName()
or
result = scopeAppend(resolveScopeExpr(c.getScopeExpr(), _), c.getName())
or
not exists(c.getScopeExpr()) and
not c.hasGlobalScope() and
exists(ModuleBase enclosing | enclosing = c.getEnclosingModule() |
result = scopeAppend(qualifiedModuleName(enclosing), c.getName())
)
}
/**
* The qualified names of the ancestors of a class/module. The ancestors should be an ordered list
* of the ancestores of `prepend`ed modules, the module itself , the ancestors or `include`d modules
* and the ancestors of the super class. The priority value only distinguishes the kind of ancestor,
* it does not order the ancestors within a group of the same kind. This is an over-approximation, however,
* computing the precise order is tricky because it depends on the evaluation/file loading order.
*/
// TODO: the order of super classes can be determined more precisely even without knowing the evaluation
// order, so we should be able to make this more precise.
private string ancestors(string qname, int priority) {
result = ancestors(prepends(qname), _) and priority = 0
or
result = qname and priority = 1 and isDefinedConstant(qname)
or
result = ancestors(includes(qname), _) and priority = 2
or
result = ancestors(superclass(qname), _) and priority = 3
}
private class IncludeOrPrependCall extends MethodCall {
IncludeOrPrependCall() { this.getMethodName() = ["include", "prepend"] }
string getAModule() { result = resolveScopeExpr(this.getAnArgument(), _) }
string getTarget() {
result = resolveScopeExpr(this.getReceiver(), _)
or
result = qualifiedModuleName(this.getEnclosingModule()) and
(
this.getReceiver() instanceof Self
or
not exists(this.getReceiver())
)
}
}
private string prepends(string qname) {
exists(IncludeOrPrependCall m |
m.getMethodName() = "prepend" and
qname = m.getTarget() and
result = m.getAModule()
)
}
private string includes(string qname) {
qname = "Object" and
result = "Kernel"
or
exists(IncludeOrPrependCall m |
m.getMethodName() = "include" and
qname = m.getTarget() and
result = m.getAModule()
)
}
private Expr superexpr(string qname) {
exists(ClassDeclaration c | qname = constantDefinition0(c) and result = c.getSuperclassExpr())
}
private string superclass(string qname) {
qname = "Object" and result = "BasicObject"
or
result = resolveScopeExpr(superexpr(qname), _)
}
private string qualifiedModuleName(string container, string name) {
isDefinedConstant(result) and
(
container = result.regexpCapture("(.+)::([^:]+)", 1) and
name = result.regexpCapture("(.+)::([^:]+)", 2)
or
container = "Object" and name = result
)
}

View File

@@ -7,7 +7,7 @@ class TScopeType = TMethodBase or TModuleLike or TBlockLike;
private class TBlockLike = TDoBlock or TLambda or TBlock or TEndBlock;
private class TModuleLike = TToplevel or TModule or TClass or TSingletonClass;
private class TModuleLike = TToplevel or TModuleDeclaration or TClassDeclaration or TSingletonClass;
module Scope {
class TypeRange = Callable::TypeRange or ModuleBase::TypeRange or @end_block;

View File

@@ -598,7 +598,7 @@ module Trees {
private class CharacterTree extends LeafTree, CharacterLiteral { }
private class ClassTree extends BodyStmtPreOrderTree, Class {
private class ClassDeclarationTree extends BodyStmtPreOrderTree, ClassDeclaration {
/** Gets the `i`th child in the body of this block. */
final override AstNode getBodyChild(int i, boolean rescuable) {
result = this.getScopeExpr() and i = 0 and rescuable = false
@@ -673,8 +673,8 @@ module Trees {
private class ConstantAccessTree extends PostOrderTree, ConstantAccess {
ConstantAccessTree() {
not this instanceof Class and
not this instanceof Module
not this instanceof ClassDeclaration and
not this instanceof ModuleDeclaration
}
final override predicate propagatesAbnormal(AstNode child) { child = this.getScopeExpr() }
@@ -934,7 +934,7 @@ module Trees {
}
}
private class ModuleTree extends BodyStmtPreOrderTree, Module {
private class ModuleDeclarationTree extends BodyStmtPreOrderTree, ModuleDeclaration {
/** Gets the `i`th child in the body of this block. */
final override AstNode getBodyChild(int i, boolean rescuable) {
result = this.getScopeExpr() and i = 0 and rescuable = false

View File

@@ -128,19 +128,19 @@ calls/calls.rb:
# 111| getBody: [StmtSequence] then ...
# 112| getStmt: [MethodCall] call to baz
# 112| getReceiver: [ConstantReadAccess] X
# 116| getStmt: [Class] MyClass
# 116| getStmt: [ClassDeclaration] MyClass
# 117| getStmt: [MethodCall] call to foo
# 118| getStmt: [MethodCall] call to bar
# 118| getReceiver: [ConstantReadAccess] X
# 122| getStmt: [Class] MyClass
# 122| getStmt: [ClassDeclaration] MyClass
# 122| getSuperclassExpr: [MethodCall] call to foo
# 124| getStmt: [Class] MyClass2
# 124| getStmt: [ClassDeclaration] MyClass2
# 124| getSuperclassExpr: [MethodCall] call to foo
# 124| getReceiver: [ConstantReadAccess] X
# 128| getStmt: [Class] class << ...
# 128| getStmt: [ClassDeclaration] class << ...
# 128| getValue: [MethodCall] call to foo
# 129| getStmt: [MethodCall] call to bar
# 131| getStmt: [Class] class << ...
# 131| getStmt: [ClassDeclaration] class << ...
# 131| getValue: [MethodCall] call to foo
# 131| getReceiver: [ConstantReadAccess] X
# 132| getStmt: [MethodCall] call to bar
@@ -172,7 +172,7 @@ calls/calls.rb:
# 156| getDefiningAccess: [LocalVariableAccess] param
# 156| getDefaultValue: [MethodCall] call to foo
# 156| getReceiver: [ConstantReadAccess] X
# 160| getStmt: [Module] SomeModule
# 160| getStmt: [ModuleDeclaration] SomeModule
# 161| getStmt: [MethodCall] call to foo
# 162| getStmt: [MethodCall] call to bar
# 162| getReceiver: [ConstantReadAccess] X
@@ -376,7 +376,7 @@ calls/calls.rb:
# 279| getKey: [SymbolLiteral] :blah
# 279| getValue: [MethodCall] call to bar
# 279| getReceiver: [ConstantReadAccess] X
# 284| getStmt: [Class] MyClass
# 284| getStmt: [ClassDeclaration] MyClass
# 285| getStmt: [Method] my_method
# 286| getStmt: [SuperCall] call to super
# 287| getStmt: [SuperCall] call to super
@@ -419,7 +419,7 @@ calls/calls.rb:
# 293| getStmt: [AddExpr] ... + ...
# 293| getAnOperand/getLeftOperand: [LocalVariableAccess] x
# 293| getAnOperand/getRightOperand: [IntegerLiteral] 200
# 301| getStmt: [Class] AnotherClass
# 301| getStmt: [ClassDeclaration] AnotherClass
# 302| getStmt: [Method] another_method
# 303| getStmt: [MethodCall] call to super
# 303| getReceiver: [MethodCall] call to foo
@@ -522,16 +522,16 @@ control/cases.rb:
# 21| getStmt: [IntegerLiteral] 30
modules/classes.rb:
# 2| [Toplevel] classes.rb
# 3| getStmt: [Class] Foo
# 7| getStmt: [Class] Bar
# 3| getStmt: [ClassDeclaration] Foo
# 7| getStmt: [ClassDeclaration] Bar
# 7| getSuperclassExpr: [ConstantReadAccess] BaseClass
# 11| getStmt: [Class] Baz
# 11| getStmt: [ClassDeclaration] Baz
# 11| getSuperclassExpr: [MethodCall] call to superclass_for
# 11| getArgument: [SymbolLiteral] :baz
# 15| getStmt: [Module] MyModule
# 16| getStmt: [Class] MyClass
# 15| getStmt: [ModuleDeclaration] MyModule
# 16| getStmt: [ClassDeclaration] MyClass
# 16| getScopeExpr: [ConstantReadAccess] MyModule
# 20| getStmt: [Class] Wibble
# 20| getStmt: [ClassDeclaration] Wibble
# 21| getStmt: [Method] method_a
# 22| getStmt: [MethodCall] call to puts
# 22| getArgument: [StringLiteral] "a"
@@ -544,13 +544,13 @@ modules/classes.rb:
# 30| getStmt: [AssignExpr] ... = ...
# 30| getAnOperand/getLeftOperand: [GlobalVariableAccess] $global_var
# 30| getAnOperand/getRightOperand: [IntegerLiteral] 123
# 32| getStmt: [Class] ClassInWibble
# 35| getStmt: [Module] ModuleInWibble
# 32| getStmt: [ClassDeclaration] ClassInWibble
# 35| getStmt: [ModuleDeclaration] ModuleInWibble
# 40| getStmt: [AssignExpr] ... = ...
# 40| getAnOperand/getLeftOperand: [LocalVariableAccess] x
# 40| getAnOperand/getRightOperand: [StringLiteral] "hello"
# 40| getComponent: [StringTextComponent] hello
# 41| getStmt: [Class] class << ...
# 41| getStmt: [ClassDeclaration] class << ...
# 41| getValue: [LocalVariableAccess] x
# 42| getStmt: [Method] length
# 43| getStmt: [MulExpr] ... * ...
@@ -564,7 +564,7 @@ modules/classes.rb:
# 51| getStmt: [AssignExpr] ... = ...
# 51| getAnOperand/getLeftOperand: [GlobalVariableAccess] $global_var2
# 51| getAnOperand/getRightOperand: [IntegerLiteral] 456
# 55| getStmt: [Class] MyClassInGlobalScope
# 55| getStmt: [ClassDeclaration] MyClassInGlobalScope
control/conditionals.rb:
# 1| [Toplevel] conditionals.rb
# 2| getStmt: [AssignExpr] ... = ...
@@ -687,12 +687,12 @@ control/conditionals.rb:
# 69| getStmt: [LocalVariableAccess] c
constants/constants.rb:
# 1| [Toplevel] constants.rb
# 1| getStmt: [Module] ModuleA
# 2| getStmt: [Class] ClassA
# 5| getStmt: [Module] ModuleB
# 6| getStmt: [Class] ClassB
# 1| getStmt: [ModuleDeclaration] ModuleA
# 2| getStmt: [ClassDeclaration] ClassA
# 5| getStmt: [ModuleDeclaration] ModuleB
# 6| getStmt: [ClassDeclaration] ClassB
# 6| getSuperclassExpr: [ConstantReadAccess] Base
# 9| getStmt: [Class] ClassC
# 9| getStmt: [ClassDeclaration] ClassC
# 9| getSuperclassExpr: [ConstantReadAccess] Z
# 9| getScopeExpr: [ConstantReadAccess] Y
# 9| getScopeExpr: [ConstantReadAccess] X
@@ -725,9 +725,9 @@ constants/constants.rb:
# 25| getStmt: [MethodCall] call to Array
# 25| getArgument: [StringLiteral] "foo"
# 25| getComponent: [StringTextComponent] foo
# 28| getStmt: [Class] ClassD
# 28| getStmt: [ClassDeclaration] ClassD
# 28| getScopeExpr: [ConstantReadAccess] ModuleA
# 31| getStmt: [Module] ModuleC
# 31| getStmt: [ModuleDeclaration] ModuleC
# 31| getScopeExpr: [ConstantReadAccess] ModuleA
# 34| getStmt: [AssignExpr] ... = ...
# 34| getAnOperand/getLeftOperand: [ConstantAssignment] MAX_SIZE
@@ -1322,10 +1322,10 @@ misc/misc.rb:
# 10| getComponent: [StringTextComponent] foo
modules/modules.rb:
# 1| [Toplevel] modules.rb
# 1| getStmt: [Module] Empty
# 4| getStmt: [Module] Foo
# 5| getStmt: [Module] Bar
# 6| getStmt: [Class] ClassInFooBar
# 1| getStmt: [ModuleDeclaration] Empty
# 4| getStmt: [ModuleDeclaration] Foo
# 5| getStmt: [ModuleDeclaration] Bar
# 6| getStmt: [ClassDeclaration] ClassInFooBar
# 9| getStmt: [Method] method_in_foo_bar
# 12| getStmt: [MethodCall] call to puts
# 12| getArgument: [StringLiteral] "module Foo::Bar"
@@ -1334,23 +1334,23 @@ modules/modules.rb:
# 13| getAnOperand/getLeftOperand: [GlobalVariableAccess] $global_var
# 13| getAnOperand/getRightOperand: [IntegerLiteral] 0
# 16| getStmt: [Method] method_in_foo
# 19| getStmt: [Class] ClassInFoo
# 19| getStmt: [ClassDeclaration] ClassInFoo
# 22| getStmt: [MethodCall] call to puts
# 22| getArgument: [StringLiteral] "module Foo"
# 22| getComponent: [StringTextComponent] module Foo
# 23| getStmt: [AssignExpr] ... = ...
# 23| getAnOperand/getLeftOperand: [GlobalVariableAccess] $global_var
# 23| getAnOperand/getRightOperand: [IntegerLiteral] 1
# 26| getStmt: [Module] Foo
# 26| getStmt: [ModuleDeclaration] Foo
# 27| getStmt: [Method] method_in_another_definition_of_foo
# 30| getStmt: [Class] ClassInAnotherDefinitionOfFoo
# 30| getStmt: [ClassDeclaration] ClassInAnotherDefinitionOfFoo
# 33| getStmt: [MethodCall] call to puts
# 33| getArgument: [StringLiteral] "module Foo again"
# 33| getComponent: [StringTextComponent] module Foo again
# 34| getStmt: [AssignExpr] ... = ...
# 34| getAnOperand/getLeftOperand: [GlobalVariableAccess] $global_var
# 34| getAnOperand/getRightOperand: [IntegerLiteral] 2
# 37| getStmt: [Module] Bar
# 37| getStmt: [ModuleDeclaration] Bar
# 38| getStmt: [Method] method_a
# 41| getStmt: [Method] method_b
# 44| getStmt: [MethodCall] call to puts
@@ -1359,9 +1359,9 @@ modules/modules.rb:
# 45| getStmt: [AssignExpr] ... = ...
# 45| getAnOperand/getLeftOperand: [GlobalVariableAccess] $global_var
# 45| getAnOperand/getRightOperand: [IntegerLiteral] 3
# 48| getStmt: [Module] Bar
# 48| getStmt: [ModuleDeclaration] Bar
# 48| getScopeExpr: [ConstantReadAccess] Foo
# 49| getStmt: [Class] ClassInAnotherDefinitionOfFooBar
# 49| getStmt: [ClassDeclaration] ClassInAnotherDefinitionOfFooBar
# 52| getStmt: [Method] method_in_another_definition_of_foo_bar
# 55| getStmt: [MethodCall] call to puts
# 55| getArgument: [StringLiteral] "module Foo::Bar again"
@@ -1369,7 +1369,36 @@ modules/modules.rb:
# 56| getStmt: [AssignExpr] ... = ...
# 56| getAnOperand/getLeftOperand: [GlobalVariableAccess] $global_var
# 56| getAnOperand/getRightOperand: [IntegerLiteral] 4
# 60| getStmt: [Module] MyModuleInGlobalScope
# 60| getStmt: [ModuleDeclaration] MyModuleInGlobalScope
# 63| getStmt: [ModuleDeclaration] Test
# 65| getStmt: [ModuleDeclaration] Foo1
# 66| getStmt: [ClassDeclaration] Bar
# 66| getScopeExpr: [ConstantReadAccess] Foo1
# 70| getStmt: [ModuleDeclaration] Foo2
# 71| getStmt: [ModuleDeclaration] Foo2
# 72| getStmt: [ClassDeclaration] Bar
# 72| getScopeExpr: [ConstantReadAccess] Foo2
# 76| getStmt: [ModuleDeclaration] Foo3
# 77| getStmt: [AssignExpr] ... = ...
# 77| getAnOperand/getLeftOperand: [ConstantAssignment] Foo3
# 77| getAnOperand/getRightOperand: [ConstantReadAccess] Object
# 78| getStmt: [ClassDeclaration] Bar
# 78| getScopeExpr: [ConstantReadAccess] Foo3
# 83| getStmt: [ModuleDeclaration] IncludeTest
# 84| getStmt: [MethodCall] call to include
# 84| getArgument: [ConstantReadAccess] Test
# 85| getStmt: [ModuleDeclaration] Y
# 85| getScopeExpr: [ConstantReadAccess] Foo1
# 89| getStmt: [ModuleDeclaration] IncludeTest2
# 90| getStmt: [MethodCall] call to include
# 90| getArgument: [ConstantReadAccess] Test
# 91| getStmt: [ModuleDeclaration] Z
# 91| getScopeExpr: [ConstantReadAccess] Foo1
# 95| getStmt: [ModuleDeclaration] PrependTest
# 96| getStmt: [MethodCall] call to prepend
# 96| getArgument: [ConstantReadAccess] Test
# 97| getStmt: [ModuleDeclaration] Y
# 97| getScopeExpr: [ConstantReadAccess] Foo2
operations/operations.rb:
# 1| [Toplevel] operations.rb
# 3| getStmt: [AssignExpr] ... = ...

View File

@@ -1,9 +1,9 @@
| constants.rb:1:1:12:3 | ModuleA | write | ModuleA | Module |
| constants.rb:2:5:3:7 | ClassA | write | ClassA | Class |
| constants.rb:5:5:11:7 | ModuleB | write | ModuleB | Module |
| constants.rb:6:9:7:11 | ClassB | write | ClassB | Class |
| constants.rb:1:1:12:3 | ModuleA | write | ModuleA | ModuleDeclaration |
| constants.rb:2:5:3:7 | ClassA | write | ClassA | ClassDeclaration |
| constants.rb:5:5:11:7 | ModuleB | write | ModuleB | ModuleDeclaration |
| constants.rb:6:9:7:11 | ClassB | write | ClassB | ClassDeclaration |
| constants.rb:6:24:6:27 | Base | read | Base | ConstantReadAccess |
| constants.rb:9:9:10:11 | ClassC | write | ClassC | Class |
| constants.rb:9:9:10:11 | ClassC | write | ClassC | ClassDeclaration |
| constants.rb:9:24:9:24 | X | read | X | ConstantReadAccess |
| constants.rb:9:24:9:27 | Y | read | Y | ConstantReadAccess |
| constants.rb:9:24:9:30 | Z | read | Z | ConstantReadAccess |
@@ -11,9 +11,9 @@
| constants.rb:17:5:17:9 | Names | write | Names | ConstantAssignment |
| constants.rb:19:5:19:9 | Names | read | Names | ConstantReadAccess |
| constants.rb:20:18:20:25 | GREETING | read | GREETING | ConstantReadAccess |
| constants.rb:28:1:29:3 | ClassD | write | ClassD | Class |
| constants.rb:28:1:29:3 | ClassD | write | ClassD | ClassDeclaration |
| constants.rb:28:7:28:13 | ModuleA | read | ModuleA | ConstantReadAccess |
| constants.rb:31:1:32:3 | ModuleC | write | ModuleC | Module |
| constants.rb:31:1:32:3 | ModuleC | write | ModuleC | ModuleDeclaration |
| constants.rb:31:8:31:14 | ModuleA | read | ModuleA | ConstantReadAccess |
| constants.rb:34:1:34:7 | ModuleA | read | ModuleA | ConstantReadAccess |
| constants.rb:34:1:34:16 | ModuleB | read | ModuleB | ConstantReadAccess |

View File

@@ -1,17 +1,23 @@
classes
| classes.rb:3:1:4:3 | Foo | Class | Foo |
| classes.rb:7:1:8:3 | Bar | Class | Bar |
| classes.rb:11:1:12:3 | Baz | Class | Baz |
| classes.rb:16:1:17:3 | MyClass | Class | MyClass |
| classes.rb:20:1:37:3 | Wibble | Class | Wibble |
| classes.rb:32:3:33:5 | ClassInWibble | Class | ClassInWibble |
| classes.rb:55:1:56:3 | MyClassInGlobalScope | Class | MyClassInGlobalScope |
| modules.rb:6:5:7:7 | ClassInFooBar | Class | ClassInFooBar |
| modules.rb:19:3:20:5 | ClassInFoo | Class | ClassInFoo |
| modules.rb:30:3:31:5 | ClassInAnotherDefinitionOfFoo | Class | ClassInAnotherDefinitionOfFoo |
| modules.rb:49:3:50:5 | ClassInAnotherDefinitionOfFooBar | Class | ClassInAnotherDefinitionOfFooBar |
| classes.rb:3:1:4:3 | Foo | ClassDeclaration | Foo |
| classes.rb:7:1:8:3 | Bar | ClassDeclaration | Bar |
| classes.rb:11:1:12:3 | Baz | ClassDeclaration | Baz |
| classes.rb:16:1:17:3 | MyClass | ClassDeclaration | MyClass |
| classes.rb:20:1:37:3 | Wibble | ClassDeclaration | Wibble |
| classes.rb:32:3:33:5 | ClassInWibble | ClassDeclaration | ClassInWibble |
| classes.rb:55:1:56:3 | MyClassInGlobalScope | ClassDeclaration | MyClassInGlobalScope |
| modules.rb:6:5:7:7 | ClassInFooBar | ClassDeclaration | ClassInFooBar |
| modules.rb:19:3:20:5 | ClassInFoo | ClassDeclaration | ClassInFoo |
| modules.rb:30:3:31:5 | ClassInAnotherDefinitionOfFoo | ClassDeclaration | ClassInAnotherDefinitionOfFoo |
| modules.rb:49:3:50:5 | ClassInAnotherDefinitionOfFooBar | ClassDeclaration | ClassInAnotherDefinitionOfFooBar |
| modules.rb:66:5:67:7 | Bar | ClassDeclaration | Bar |
| modules.rb:72:5:73:7 | Bar | ClassDeclaration | Bar |
| modules.rb:78:5:79:7 | Bar | ClassDeclaration | Bar |
classesWithNameScopeExprs
| classes.rb:16:1:17:3 | MyClass | classes.rb:16:7:16:14 | MyModule |
| modules.rb:66:5:67:7 | Bar | modules.rb:66:11:66:14 | Foo1 |
| modules.rb:72:5:73:7 | Bar | modules.rb:72:11:72:14 | Foo2 |
| modules.rb:78:5:79:7 | Bar | modules.rb:78:11:78:14 | Foo3 |
classesWithGlobalNameScopeExprs
| classes.rb:55:1:56:3 | MyClassInGlobalScope |
exprsInClasses
@@ -19,8 +25,8 @@ exprsInClasses
| classes.rb:20:1:37:3 | Wibble | 1 | classes.rb:25:3:27:5 | method_b | Method |
| classes.rb:20:1:37:3 | Wibble | 2 | classes.rb:29:3:29:20 | call to some_method_call | MethodCall |
| classes.rb:20:1:37:3 | Wibble | 3 | classes.rb:30:3:30:19 | ... = ... | AssignExpr |
| classes.rb:20:1:37:3 | Wibble | 4 | classes.rb:32:3:33:5 | ClassInWibble | Class |
| classes.rb:20:1:37:3 | Wibble | 5 | classes.rb:35:3:36:5 | ModuleInWibble | Module |
| classes.rb:20:1:37:3 | Wibble | 4 | classes.rb:32:3:33:5 | ClassInWibble | ClassDeclaration |
| classes.rb:20:1:37:3 | Wibble | 5 | classes.rb:35:3:36:5 | ModuleInWibble | ModuleDeclaration |
methodsInClasses
| classes.rb:20:1:37:3 | Wibble | classes.rb:21:3:23:5 | method_a | method_a |
| classes.rb:20:1:37:3 | Wibble | classes.rb:25:3:27:5 | method_b | method_b |

View File

@@ -1,21 +1,29 @@
import ruby
query predicate classes(Class c, string pClass, string name) {
query predicate classes(ClassDeclaration c, string pClass, string name) {
pClass = c.getAPrimaryQlClass() and name = c.getName()
}
query predicate classesWithNameScopeExprs(Class c, Expr se) { se = c.getScopeExpr() }
query predicate classesWithNameScopeExprs(ClassDeclaration c, Expr se) { se = c.getScopeExpr() }
query predicate classesWithGlobalNameScopeExprs(Class c) { c.hasGlobalScope() }
query predicate classesWithGlobalNameScopeExprs(ClassDeclaration c) { c.hasGlobalScope() }
query predicate exprsInClasses(Class c, int i, Expr e, string eClass) {
query predicate exprsInClasses(ClassDeclaration c, int i, Expr e, string eClass) {
e = c.getStmt(i) and eClass = e.getAPrimaryQlClass()
}
query predicate methodsInClasses(Class c, Method m, string name) { m = c.getMethod(name) }
query predicate methodsInClasses(ClassDeclaration c, Method m, string name) {
m = c.getMethod(name)
}
query predicate classesInClasses(Class c, Class child, string name) { child = c.getClass(name) }
query predicate classesInClasses(ClassDeclaration c, ClassDeclaration child, string name) {
child = c.getClass(name)
}
query predicate modulesInClasses(Class c, Module m, string name) { m = c.getModule(name) }
query predicate modulesInClasses(ClassDeclaration c, ModuleDeclaration m, string name) {
m = c.getModule(name)
}
query predicate classesWithASuperclass(Class c, Expr scExpr) { scExpr = c.getSuperclassExpr() }
query predicate classesWithASuperclass(ClassDeclaration c, Expr scExpr) {
scExpr = c.getSuperclassExpr()
}

View File

@@ -1,27 +1,41 @@
moduleBases
| classes.rb:2:1:56:3 | classes.rb | Toplevel |
| classes.rb:3:1:4:3 | Foo | Class |
| classes.rb:7:1:8:3 | Bar | Class |
| classes.rb:11:1:12:3 | Baz | Class |
| classes.rb:15:1:15:20 | MyModule | Module |
| classes.rb:16:1:17:3 | MyClass | Class |
| classes.rb:20:1:37:3 | Wibble | Class |
| classes.rb:32:3:33:5 | ClassInWibble | Class |
| classes.rb:35:3:36:5 | ModuleInWibble | Module |
| classes.rb:41:1:52:3 | class << ... | Class |
| classes.rb:55:1:56:3 | MyClassInGlobalScope | Class |
| modules.rb:1:1:2:3 | Empty | Module |
| modules.rb:1:1:61:3 | modules.rb | Toplevel |
| modules.rb:4:1:24:3 | Foo | Module |
| modules.rb:5:3:14:5 | Bar | Module |
| modules.rb:6:5:7:7 | ClassInFooBar | Class |
| modules.rb:19:3:20:5 | ClassInFoo | Class |
| modules.rb:26:1:35:3 | Foo | Module |
| modules.rb:30:3:31:5 | ClassInAnotherDefinitionOfFoo | Class |
| modules.rb:37:1:46:3 | Bar | Module |
| modules.rb:48:1:57:3 | Bar | Module |
| modules.rb:49:3:50:5 | ClassInAnotherDefinitionOfFooBar | Class |
| modules.rb:60:1:61:3 | MyModuleInGlobalScope | Module |
| classes.rb:3:1:4:3 | Foo | ClassDeclaration |
| classes.rb:7:1:8:3 | Bar | ClassDeclaration |
| classes.rb:11:1:12:3 | Baz | ClassDeclaration |
| classes.rb:15:1:15:20 | MyModule | ModuleDeclaration |
| classes.rb:16:1:17:3 | MyClass | ClassDeclaration |
| classes.rb:20:1:37:3 | Wibble | ClassDeclaration |
| classes.rb:32:3:33:5 | ClassInWibble | ClassDeclaration |
| classes.rb:35:3:36:5 | ModuleInWibble | ModuleDeclaration |
| classes.rb:41:1:52:3 | class << ... | ClassDeclaration |
| classes.rb:55:1:56:3 | MyClassInGlobalScope | ClassDeclaration |
| modules.rb:1:1:2:3 | Empty | ModuleDeclaration |
| modules.rb:1:1:99:3 | modules.rb | Toplevel |
| modules.rb:4:1:24:3 | Foo | ModuleDeclaration |
| modules.rb:5:3:14:5 | Bar | ModuleDeclaration |
| modules.rb:6:5:7:7 | ClassInFooBar | ClassDeclaration |
| modules.rb:19:3:20:5 | ClassInFoo | ClassDeclaration |
| modules.rb:26:1:35:3 | Foo | ModuleDeclaration |
| modules.rb:30:3:31:5 | ClassInAnotherDefinitionOfFoo | ClassDeclaration |
| modules.rb:37:1:46:3 | Bar | ModuleDeclaration |
| modules.rb:48:1:57:3 | Bar | ModuleDeclaration |
| modules.rb:49:3:50:5 | ClassInAnotherDefinitionOfFooBar | ClassDeclaration |
| modules.rb:60:1:61:3 | MyModuleInGlobalScope | ModuleDeclaration |
| modules.rb:63:1:81:3 | Test | ModuleDeclaration |
| modules.rb:65:3:68:5 | Foo1 | ModuleDeclaration |
| modules.rb:66:5:67:7 | Bar | ClassDeclaration |
| modules.rb:70:3:74:5 | Foo2 | ModuleDeclaration |
| modules.rb:71:5:71:19 | Foo2 | ModuleDeclaration |
| modules.rb:72:5:73:7 | Bar | ClassDeclaration |
| modules.rb:76:3:80:5 | Foo3 | ModuleDeclaration |
| modules.rb:78:5:79:7 | Bar | ClassDeclaration |
| modules.rb:83:1:87:3 | IncludeTest | ModuleDeclaration |
| modules.rb:85:3:86:5 | Y | ModuleDeclaration |
| modules.rb:89:1:93:3 | IncludeTest2 | ModuleDeclaration |
| modules.rb:91:3:92:5 | Z | ModuleDeclaration |
| modules.rb:95:1:99:3 | PrependTest | ModuleDeclaration |
| modules.rb:97:3:98:5 | Y | ModuleDeclaration |
| toplevel.rb:1:1:5:23 | toplevel.rb | Toplevel |
moduleBaseClasses
| classes.rb:2:1:56:3 | classes.rb | classes.rb:3:1:4:3 | Foo |
@@ -35,6 +49,9 @@ moduleBaseClasses
| modules.rb:5:3:14:5 | Bar | modules.rb:6:5:7:7 | ClassInFooBar |
| modules.rb:26:1:35:3 | Foo | modules.rb:30:3:31:5 | ClassInAnotherDefinitionOfFoo |
| modules.rb:48:1:57:3 | Bar | modules.rb:49:3:50:5 | ClassInAnotherDefinitionOfFooBar |
| modules.rb:65:3:68:5 | Foo1 | modules.rb:66:5:67:7 | Bar |
| modules.rb:70:3:74:5 | Foo2 | modules.rb:72:5:73:7 | Bar |
| modules.rb:76:3:80:5 | Foo3 | modules.rb:78:5:79:7 | Bar |
moduleBaseMethods
| classes.rb:20:1:37:3 | Wibble | classes.rb:21:3:23:5 | method_a |
| classes.rb:20:1:37:3 | Wibble | classes.rb:25:3:27:5 | method_b |
@@ -49,10 +66,21 @@ moduleBaseMethods
moduleBaseModules
| classes.rb:2:1:56:3 | classes.rb | classes.rb:15:1:15:20 | MyModule |
| classes.rb:20:1:37:3 | Wibble | classes.rb:35:3:36:5 | ModuleInWibble |
| modules.rb:1:1:61:3 | modules.rb | modules.rb:1:1:2:3 | Empty |
| modules.rb:1:1:61:3 | modules.rb | modules.rb:4:1:24:3 | Foo |
| modules.rb:1:1:61:3 | modules.rb | modules.rb:26:1:35:3 | Foo |
| modules.rb:1:1:61:3 | modules.rb | modules.rb:37:1:46:3 | Bar |
| modules.rb:1:1:61:3 | modules.rb | modules.rb:48:1:57:3 | Bar |
| modules.rb:1:1:61:3 | modules.rb | modules.rb:60:1:61:3 | MyModuleInGlobalScope |
| modules.rb:1:1:99:3 | modules.rb | modules.rb:1:1:2:3 | Empty |
| modules.rb:1:1:99:3 | modules.rb | modules.rb:4:1:24:3 | Foo |
| modules.rb:1:1:99:3 | modules.rb | modules.rb:26:1:35:3 | Foo |
| modules.rb:1:1:99:3 | modules.rb | modules.rb:37:1:46:3 | Bar |
| modules.rb:1:1:99:3 | modules.rb | modules.rb:48:1:57:3 | Bar |
| modules.rb:1:1:99:3 | modules.rb | modules.rb:60:1:61:3 | MyModuleInGlobalScope |
| modules.rb:1:1:99:3 | modules.rb | modules.rb:63:1:81:3 | Test |
| modules.rb:1:1:99:3 | modules.rb | modules.rb:83:1:87:3 | IncludeTest |
| modules.rb:1:1:99:3 | modules.rb | modules.rb:89:1:93:3 | IncludeTest2 |
| modules.rb:1:1:99:3 | modules.rb | modules.rb:95:1:99:3 | PrependTest |
| modules.rb:4:1:24:3 | Foo | modules.rb:5:3:14:5 | Bar |
| modules.rb:63:1:81:3 | Test | modules.rb:65:3:68:5 | Foo1 |
| modules.rb:63:1:81:3 | Test | modules.rb:70:3:74:5 | Foo2 |
| modules.rb:63:1:81:3 | Test | modules.rb:76:3:80:5 | Foo3 |
| modules.rb:70:3:74:5 | Foo2 | modules.rb:71:5:71:19 | Foo2 |
| modules.rb:83:1:87:3 | IncludeTest | modules.rb:85:3:86:5 | Y |
| modules.rb:89:1:93:3 | IncludeTest2 | modules.rb:91:3:92:5 | Z |
| modules.rb:95:1:99:3 | PrependTest | modules.rb:97:3:98:5 | Y |

View File

@@ -2,8 +2,8 @@ import ruby
query predicate moduleBases(ModuleBase mb, string pClass) { pClass = mb.getAPrimaryQlClass() }
query predicate moduleBaseClasses(ModuleBase mb, Class c) { c = mb.getAClass() }
query predicate moduleBaseClasses(ModuleBase mb, ClassDeclaration c) { c = mb.getAClass() }
query predicate moduleBaseMethods(ModuleBase mb, Method m) { m = mb.getAMethod() }
query predicate moduleBaseModules(ModuleBase mb, Module m) { m = mb.getAModule() }
query predicate moduleBaseModules(ModuleBase mb, ModuleDeclaration m) { m = mb.getAModule() }

View File

@@ -1,39 +1,67 @@
modules
| classes.rb:15:1:15:20 | MyModule | Module | MyModule |
| classes.rb:35:3:36:5 | ModuleInWibble | Module | ModuleInWibble |
| modules.rb:1:1:2:3 | Empty | Module | Empty |
| modules.rb:4:1:24:3 | Foo | Module | Foo |
| modules.rb:5:3:14:5 | Bar | Module | Bar |
| modules.rb:26:1:35:3 | Foo | Module | Foo |
| modules.rb:37:1:46:3 | Bar | Module | Bar |
| modules.rb:48:1:57:3 | Bar | Module | Bar |
| modules.rb:60:1:61:3 | MyModuleInGlobalScope | Module | MyModuleInGlobalScope |
| classes.rb:15:1:15:20 | MyModule | ModuleDeclaration | MyModule |
| classes.rb:35:3:36:5 | ModuleInWibble | ModuleDeclaration | ModuleInWibble |
| modules.rb:1:1:2:3 | Empty | ModuleDeclaration | Empty |
| modules.rb:4:1:24:3 | Foo | ModuleDeclaration | Foo |
| modules.rb:5:3:14:5 | Bar | ModuleDeclaration | Bar |
| modules.rb:26:1:35:3 | Foo | ModuleDeclaration | Foo |
| modules.rb:37:1:46:3 | Bar | ModuleDeclaration | Bar |
| modules.rb:48:1:57:3 | Bar | ModuleDeclaration | Bar |
| modules.rb:60:1:61:3 | MyModuleInGlobalScope | ModuleDeclaration | MyModuleInGlobalScope |
| modules.rb:63:1:81:3 | Test | ModuleDeclaration | Test |
| modules.rb:65:3:68:5 | Foo1 | ModuleDeclaration | Foo1 |
| modules.rb:70:3:74:5 | Foo2 | ModuleDeclaration | Foo2 |
| modules.rb:71:5:71:19 | Foo2 | ModuleDeclaration | Foo2 |
| modules.rb:76:3:80:5 | Foo3 | ModuleDeclaration | Foo3 |
| modules.rb:83:1:87:3 | IncludeTest | ModuleDeclaration | IncludeTest |
| modules.rb:85:3:86:5 | Y | ModuleDeclaration | Y |
| modules.rb:89:1:93:3 | IncludeTest2 | ModuleDeclaration | IncludeTest2 |
| modules.rb:91:3:92:5 | Z | ModuleDeclaration | Z |
| modules.rb:95:1:99:3 | PrependTest | ModuleDeclaration | PrependTest |
| modules.rb:97:3:98:5 | Y | ModuleDeclaration | Y |
modulesWithScopeExprs
| modules.rb:48:1:57:3 | Bar | modules.rb:48:8:48:10 | Foo |
| modules.rb:85:3:86:5 | Y | modules.rb:85:10:85:13 | Foo1 |
| modules.rb:91:3:92:5 | Z | modules.rb:91:10:91:13 | Foo1 |
| modules.rb:97:3:98:5 | Y | modules.rb:97:10:97:13 | Foo2 |
modulesWithGlobalNameScopeExprs
| modules.rb:60:1:61:3 | MyModuleInGlobalScope |
exprsInModules
| modules.rb:4:1:24:3 | Foo | 0 | modules.rb:5:3:14:5 | Bar | Module |
| modules.rb:4:1:24:3 | Foo | 0 | modules.rb:5:3:14:5 | Bar | ModuleDeclaration |
| modules.rb:4:1:24:3 | Foo | 1 | modules.rb:16:3:17:5 | method_in_foo | Method |
| modules.rb:4:1:24:3 | Foo | 2 | modules.rb:19:3:20:5 | ClassInFoo | Class |
| modules.rb:4:1:24:3 | Foo | 2 | modules.rb:19:3:20:5 | ClassInFoo | ClassDeclaration |
| modules.rb:4:1:24:3 | Foo | 3 | modules.rb:22:3:22:19 | call to puts | MethodCall |
| modules.rb:4:1:24:3 | Foo | 4 | modules.rb:23:3:23:17 | ... = ... | AssignExpr |
| modules.rb:5:3:14:5 | Bar | 0 | modules.rb:6:5:7:7 | ClassInFooBar | Class |
| modules.rb:5:3:14:5 | Bar | 0 | modules.rb:6:5:7:7 | ClassInFooBar | ClassDeclaration |
| modules.rb:5:3:14:5 | Bar | 1 | modules.rb:9:5:10:7 | method_in_foo_bar | Method |
| modules.rb:5:3:14:5 | Bar | 2 | modules.rb:12:5:12:26 | call to puts | MethodCall |
| modules.rb:5:3:14:5 | Bar | 3 | modules.rb:13:5:13:19 | ... = ... | AssignExpr |
| modules.rb:26:1:35:3 | Foo | 0 | modules.rb:27:3:28:5 | method_in_another_definition_of_foo | Method |
| modules.rb:26:1:35:3 | Foo | 1 | modules.rb:30:3:31:5 | ClassInAnotherDefinitionOfFoo | Class |
| modules.rb:26:1:35:3 | Foo | 1 | modules.rb:30:3:31:5 | ClassInAnotherDefinitionOfFoo | ClassDeclaration |
| modules.rb:26:1:35:3 | Foo | 2 | modules.rb:33:3:33:25 | call to puts | MethodCall |
| modules.rb:26:1:35:3 | Foo | 3 | modules.rb:34:3:34:17 | ... = ... | AssignExpr |
| modules.rb:37:1:46:3 | Bar | 0 | modules.rb:38:3:39:5 | method_a | Method |
| modules.rb:37:1:46:3 | Bar | 1 | modules.rb:41:3:42:5 | method_b | Method |
| modules.rb:37:1:46:3 | Bar | 2 | modules.rb:44:3:44:19 | call to puts | MethodCall |
| modules.rb:37:1:46:3 | Bar | 3 | modules.rb:45:3:45:17 | ... = ... | AssignExpr |
| modules.rb:48:1:57:3 | Bar | 0 | modules.rb:49:3:50:5 | ClassInAnotherDefinitionOfFooBar | Class |
| modules.rb:48:1:57:3 | Bar | 0 | modules.rb:49:3:50:5 | ClassInAnotherDefinitionOfFooBar | ClassDeclaration |
| modules.rb:48:1:57:3 | Bar | 1 | modules.rb:52:3:53:5 | method_in_another_definition_of_foo_bar | Method |
| modules.rb:48:1:57:3 | Bar | 2 | modules.rb:55:3:55:30 | call to puts | MethodCall |
| modules.rb:48:1:57:3 | Bar | 3 | modules.rb:56:3:56:17 | ... = ... | AssignExpr |
| modules.rb:63:1:81:3 | Test | 0 | modules.rb:65:3:68:5 | Foo1 | ModuleDeclaration |
| modules.rb:63:1:81:3 | Test | 1 | modules.rb:70:3:74:5 | Foo2 | ModuleDeclaration |
| modules.rb:63:1:81:3 | Test | 2 | modules.rb:76:3:80:5 | Foo3 | ModuleDeclaration |
| modules.rb:65:3:68:5 | Foo1 | 0 | modules.rb:66:5:67:7 | Bar | ClassDeclaration |
| modules.rb:70:3:74:5 | Foo2 | 0 | modules.rb:71:5:71:19 | Foo2 | ModuleDeclaration |
| modules.rb:70:3:74:5 | Foo2 | 1 | modules.rb:72:5:73:7 | Bar | ClassDeclaration |
| modules.rb:76:3:80:5 | Foo3 | 0 | modules.rb:77:5:77:17 | ... = ... | AssignExpr |
| modules.rb:76:3:80:5 | Foo3 | 1 | modules.rb:78:5:79:7 | Bar | ClassDeclaration |
| modules.rb:83:1:87:3 | IncludeTest | 0 | modules.rb:84:3:84:16 | call to include | MethodCall |
| modules.rb:83:1:87:3 | IncludeTest | 1 | modules.rb:85:3:86:5 | Y | ModuleDeclaration |
| modules.rb:89:1:93:3 | IncludeTest2 | 0 | modules.rb:90:3:90:14 | call to include | MethodCall |
| modules.rb:89:1:93:3 | IncludeTest2 | 1 | modules.rb:91:3:92:5 | Z | ModuleDeclaration |
| modules.rb:95:1:99:3 | PrependTest | 0 | modules.rb:96:3:96:16 | call to prepend | MethodCall |
| modules.rb:95:1:99:3 | PrependTest | 1 | modules.rb:97:3:98:5 | Y | ModuleDeclaration |
methodsInModules
| modules.rb:4:1:24:3 | Foo | modules.rb:16:3:17:5 | method_in_foo | method_in_foo |
| modules.rb:5:3:14:5 | Bar | modules.rb:9:5:10:7 | method_in_foo_bar | method_in_foo_bar |
@@ -46,5 +74,53 @@ classesInModules
| modules.rb:5:3:14:5 | Bar | modules.rb:6:5:7:7 | ClassInFooBar | ClassInFooBar |
| modules.rb:26:1:35:3 | Foo | modules.rb:30:3:31:5 | ClassInAnotherDefinitionOfFoo | ClassInAnotherDefinitionOfFoo |
| modules.rb:48:1:57:3 | Bar | modules.rb:49:3:50:5 | ClassInAnotherDefinitionOfFooBar | ClassInAnotherDefinitionOfFooBar |
| modules.rb:65:3:68:5 | Foo1 | modules.rb:66:5:67:7 | Bar | Bar |
| modules.rb:70:3:74:5 | Foo2 | modules.rb:72:5:73:7 | Bar | Bar |
| modules.rb:76:3:80:5 | Foo3 | modules.rb:78:5:79:7 | Bar | Bar |
modulesInModules
| modules.rb:4:1:24:3 | Foo | modules.rb:5:3:14:5 | Bar | Bar |
| modules.rb:63:1:81:3 | Test | modules.rb:65:3:68:5 | Foo1 | Foo1 |
| modules.rb:63:1:81:3 | Test | modules.rb:70:3:74:5 | Foo2 | Foo2 |
| modules.rb:63:1:81:3 | Test | modules.rb:76:3:80:5 | Foo3 | Foo3 |
| modules.rb:70:3:74:5 | Foo2 | modules.rb:71:5:71:19 | Foo2 | Foo2 |
| modules.rb:83:1:87:3 | IncludeTest | modules.rb:85:3:86:5 | Y | Y |
| modules.rb:89:1:93:3 | IncludeTest2 | modules.rb:91:3:92:5 | Z | Z |
| modules.rb:95:1:99:3 | PrependTest | modules.rb:97:3:98:5 | Y | Y |
moduleTypes
| classes.rb:2:1:56:3 | classes.rb | file://:0:0:0:0 | Object |
| classes.rb:3:1:4:3 | Foo | modules.rb:4:1:24:3 | Foo |
| classes.rb:7:1:8:3 | Bar | modules.rb:37:1:46:3 | Bar |
| classes.rb:11:1:12:3 | Baz | classes.rb:11:1:12:3 | Baz |
| classes.rb:15:1:15:20 | MyModule | classes.rb:15:1:15:20 | MyModule |
| classes.rb:16:1:17:3 | MyClass | classes.rb:16:1:17:3 | MyModule::MyClass |
| classes.rb:20:1:37:3 | Wibble | classes.rb:20:1:37:3 | Wibble |
| classes.rb:32:3:33:5 | ClassInWibble | classes.rb:32:3:33:5 | Wibble::ClassInWibble |
| classes.rb:35:3:36:5 | ModuleInWibble | classes.rb:35:3:36:5 | Wibble::ModuleInWibble |
| classes.rb:55:1:56:3 | MyClassInGlobalScope | classes.rb:55:1:56:3 | MyClassInGlobalScope |
| modules.rb:1:1:2:3 | Empty | modules.rb:1:1:2:3 | Empty |
| modules.rb:1:1:99:3 | modules.rb | file://:0:0:0:0 | Object |
| modules.rb:4:1:24:3 | Foo | modules.rb:4:1:24:3 | Foo |
| modules.rb:5:3:14:5 | Bar | modules.rb:5:3:14:5 | Foo::Bar |
| modules.rb:6:5:7:7 | ClassInFooBar | modules.rb:6:5:7:7 | Foo::Bar::ClassInFooBar |
| modules.rb:19:3:20:5 | ClassInFoo | modules.rb:19:3:20:5 | Foo::ClassInFoo |
| modules.rb:26:1:35:3 | Foo | modules.rb:4:1:24:3 | Foo |
| modules.rb:30:3:31:5 | ClassInAnotherDefinitionOfFoo | modules.rb:30:3:31:5 | Foo::ClassInAnotherDefinitionOfFoo |
| modules.rb:37:1:46:3 | Bar | modules.rb:37:1:46:3 | Bar |
| modules.rb:48:1:57:3 | Bar | modules.rb:5:3:14:5 | Foo::Bar |
| modules.rb:49:3:50:5 | ClassInAnotherDefinitionOfFooBar | modules.rb:49:3:50:5 | Foo::Bar::ClassInAnotherDefinitionOfFooBar |
| modules.rb:60:1:61:3 | MyModuleInGlobalScope | modules.rb:60:1:61:3 | MyModuleInGlobalScope |
| modules.rb:63:1:81:3 | Test | modules.rb:63:1:81:3 | Test |
| modules.rb:65:3:68:5 | Foo1 | modules.rb:65:3:68:5 | Test::Foo1 |
| modules.rb:66:5:67:7 | Bar | modules.rb:66:5:67:7 | Test::Foo1::Bar |
| modules.rb:70:3:74:5 | Foo2 | modules.rb:70:3:74:5 | Test::Foo2 |
| modules.rb:71:5:71:19 | Foo2 | modules.rb:71:5:71:19 | Test::Foo2::Foo2 |
| modules.rb:72:5:73:7 | Bar | modules.rb:72:5:73:7 | Test::Foo2::Foo2::Bar |
| modules.rb:76:3:80:5 | Foo3 | modules.rb:76:3:80:5 | Test::Foo3 |
| modules.rb:78:5:79:7 | Bar | modules.rb:37:1:46:3 | Bar |
| modules.rb:83:1:87:3 | IncludeTest | modules.rb:83:1:87:3 | IncludeTest |
| modules.rb:85:3:86:5 | Y | modules.rb:85:3:86:5 | Test::Foo1::Y |
| modules.rb:89:1:93:3 | IncludeTest2 | modules.rb:89:1:93:3 | IncludeTest2 |
| modules.rb:91:3:92:5 | Z | modules.rb:91:3:92:5 | Test::Foo1::Z |
| modules.rb:95:1:99:3 | PrependTest | modules.rb:95:1:99:3 | PrependTest |
| modules.rb:97:3:98:5 | Y | modules.rb:97:3:98:5 | Test::Foo2::Y |
| toplevel.rb:1:1:5:23 | toplevel.rb | file://:0:0:0:0 | Object |

View File

@@ -1,25 +1,27 @@
import ruby
query predicate modules(Module m, string pClass, string name) {
query predicate modules(ModuleDeclaration m, string pClass, string name) {
pClass = m.getAPrimaryQlClass() and name = m.getName()
}
query predicate modulesWithScopeExprs(Module m, Expr se) { se = m.getScopeExpr() }
query predicate modulesWithScopeExprs(ModuleDeclaration m, Expr se) { se = m.getScopeExpr() }
query predicate modulesWithGlobalNameScopeExprs(Module m) { m.hasGlobalScope() }
query predicate modulesWithGlobalNameScopeExprs(ModuleDeclaration m) { m.hasGlobalScope() }
query predicate exprsInModules(Module m, int i, Expr e, string eClass) {
query predicate exprsInModules(ModuleDeclaration m, int i, Expr e, string eClass) {
e = m.getStmt(i) and eClass = e.getAPrimaryQlClass()
}
query predicate methodsInModules(Module mod, Method method, string name) {
query predicate methodsInModules(ModuleDeclaration mod, Method method, string name) {
method = mod.getMethod(name)
}
query predicate classesInModules(Module mod, Class klass, string name) {
query predicate classesInModules(ModuleDeclaration mod, ClassDeclaration klass, string name) {
klass = mod.getClass(name)
}
query predicate modulesInModules(Module mod, Module child, string name) {
query predicate modulesInModules(ModuleDeclaration mod, ModuleDeclaration child, string name) {
child = mod.getModule(name)
}
query predicate moduleTypes(ModuleBase def, Module type) { type = def.getModule() }

View File

@@ -58,4 +58,42 @@ end
# a module where the name is a scope resolution using the global scope
module ::MyModuleInGlobalScope
end
module Test
module Foo1
class Foo1::Bar
end
end
module Foo2
module Foo2 end
class Foo2::Bar
end
end
module Foo3
Foo3 = Object
class Foo3::Bar
end
end
end
module IncludeTest
include ::Test
module Foo1::Y
end
end
module IncludeTest2
include Test
module Foo1::Z
end
end
module PrependTest
prepend ::Test
module Foo2::Y
end
end

View File

@@ -1,5 +1,5 @@
singletonClasses
| classes.rb:41:1:52:3 | class << ... | Class | classes.rb:41:10:41:10 | x |
| classes.rb:41:1:52:3 | class << ... | ClassDeclaration | classes.rb:41:10:41:10 | x |
exprsInSingletonClasses
| classes.rb:41:1:52:3 | class << ... | 0 | classes.rb:42:3:44:5 | length | Method |
| classes.rb:41:1:52:3 | class << ... | 1 | classes.rb:46:3:48:5 | wibble | Method |

View File

@@ -1,6 +1,6 @@
toplevel
| classes.rb:2:1:56:3 | classes.rb | Toplevel |
| modules.rb:1:1:61:3 | modules.rb | Toplevel |
| modules.rb:1:1:99:3 | modules.rb | Toplevel |
| toplevel.rb:1:1:5:23 | toplevel.rb | Toplevel |
beginBlocks
| toplevel.rb:1:1:5:23 | toplevel.rb | 0 | toplevel.rb:5:1:5:22 | BEGIN { ... } |