mirror of
https://github.com/github/codeql.git
synced 2026-02-19 16:33:40 +01:00
Merge pull request #165 from github/aibaars/methods
Implement method lookup
This commit is contained in:
@@ -85,6 +85,21 @@ class MethodCall extends Call, TMethodCall {
|
||||
*/
|
||||
Expr getReceiver() { none() }
|
||||
|
||||
/**
|
||||
* Holds if the receiver is `self` or there is no receiver, which has the same
|
||||
* meaning as an explict `self`. For example:
|
||||
*
|
||||
* ```rb
|
||||
* self.foo
|
||||
* foo
|
||||
* ```
|
||||
*/
|
||||
predicate receiverIsSelf() {
|
||||
this.getReceiver() instanceof Self
|
||||
or
|
||||
not exists(this.getReceiver())
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the method being called. For example, in:
|
||||
*
|
||||
|
||||
@@ -8,9 +8,18 @@ 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. */
|
||||
/** Gets a declaration of this module, if any. */
|
||||
ModuleBase getADeclaration() { result.getModule() = this }
|
||||
|
||||
/** Gets the super class of this module, if any. */
|
||||
Module getSuperClass() { result = getSuperClass(this) }
|
||||
|
||||
/** Gets a `prepend`ed module. */
|
||||
Module getAPrependedModule() { result = getAPrependedModule(this) }
|
||||
|
||||
/** Gets an `include`d module. */
|
||||
Module getAnIncludedModule() { result = getAnIncludedModule(this) }
|
||||
|
||||
/** Gets a textual representation of this module. */
|
||||
string toString() {
|
||||
this = TResolved(result)
|
||||
|
||||
@@ -34,6 +34,58 @@ private module Cached {
|
||||
result = scopeAppend(container, n.getName())
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
Module getSuperClass(Module cls) {
|
||||
cls = TResolved("Object") and result = TResolved("BasicObject")
|
||||
or
|
||||
cls = TResolved("Module") and result = TResolved("Object")
|
||||
or
|
||||
cls = TResolved("Class") and result = TResolved("Module")
|
||||
or
|
||||
not cls = TResolved(builtin()) and
|
||||
(
|
||||
exists(ClassDeclaration d |
|
||||
d = cls.getADeclaration() and
|
||||
result = resolveScopeExpr(d.getSuperclassExpr())
|
||||
)
|
||||
or
|
||||
result = TResolved("Object") and
|
||||
forex(ClassDeclaration d | d = cls.getADeclaration() |
|
||||
not exists(resolveScopeExpr(d.getSuperclassExpr()))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
Module getAnIncludedModule(Module m) {
|
||||
m = TResolved("Object") and result = TResolved("Kernel")
|
||||
or
|
||||
exists(IncludeOrPrependCall c |
|
||||
c.getMethodName() = "include" and
|
||||
(
|
||||
m = resolveScopeExpr(c.getReceiver())
|
||||
or
|
||||
m = enclosingModule(c).getModule() and
|
||||
c.receiverIsSelf()
|
||||
) and
|
||||
result = resolveScopeExpr(c.getAnArgument())
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
Module getAPrependedModule(Module m) {
|
||||
exists(IncludeOrPrependCall c |
|
||||
c.getMethodName() = "prepend" and
|
||||
(
|
||||
m = resolveScopeExpr(c.getReceiver())
|
||||
or
|
||||
m = enclosingModule(c).getModule() and
|
||||
c.receiverIsSelf()
|
||||
) and
|
||||
result = resolveScopeExpr(c.getAnArgument())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
import Cached
|
||||
@@ -242,3 +294,31 @@ private string qualifiedModuleName(string container, string name) {
|
||||
container = "Object" and name = result
|
||||
)
|
||||
}
|
||||
|
||||
private Module getAncestors(Module m) {
|
||||
result = m or
|
||||
result = getAncestors(m.getAnIncludedModule()) or
|
||||
result = getAncestors(m.getAPrependedModule())
|
||||
}
|
||||
|
||||
Method getMethod(TModule owner, string name) {
|
||||
exists(ModuleBase m | m.getModule() = owner and result = m.getMethod(name))
|
||||
}
|
||||
|
||||
private Method lookupMethod0(Module m, string name) {
|
||||
result = lookupMethod0(m.getAPrependedModule(), name)
|
||||
or
|
||||
not exists(getMethod(getAncestors(m.getAPrependedModule()), name)) and
|
||||
(
|
||||
result = getMethod(m, name)
|
||||
or
|
||||
not exists(getMethod(m, name)) and result = lookupMethod0(m.getAnIncludedModule(), name)
|
||||
)
|
||||
}
|
||||
|
||||
Method lookupMethod(Module m, string name) {
|
||||
result = lookupMethod0(m, name)
|
||||
or
|
||||
not exists(lookupMethod0(m, name)) and
|
||||
result = lookupMethod(m.getSuperClass(), name)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/**
|
||||
* @kind graph
|
||||
* @id rb/test/cfg
|
||||
*/
|
||||
|
||||
import codeql_ruby.CFG
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/**
|
||||
* @kind graph
|
||||
* @id rb/test/print-ast
|
||||
*/
|
||||
|
||||
import codeql_ruby.printAst
|
||||
|
||||
@@ -101,49 +101,3 @@ modulesInModules
|
||||
| modules.rb:95:1:99:3 | IncludeTest2 | modules.rb:97:3:98:5 | Z | Z |
|
||||
| modules.rb:101:1:105:3 | PrependTest | modules.rb:103:3:104:5 | Y | Y |
|
||||
| modules.rb:107:1:110:3 | MM | modules.rb:108:3:109:5 | MM | MM |
|
||||
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:122:1 | 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:86:3 | Other | modules.rb:83:1:86:3 | Other |
|
||||
| modules.rb:84:3:85:5 | Foo1 | modules.rb:84:3:85:5 | Other::Foo1 |
|
||||
| modules.rb:88:1:93:3 | IncludeTest | modules.rb:88:1:93:3 | IncludeTest |
|
||||
| modules.rb:91:3:92:5 | Y | modules.rb:91:3:92:5 | Test::Foo1::Y |
|
||||
| modules.rb:95:1:99:3 | IncludeTest2 | modules.rb:95:1:99:3 | IncludeTest2 |
|
||||
| modules.rb:97:3:98:5 | Z | modules.rb:97:3:98:5 | Test::Foo1::Z |
|
||||
| modules.rb:101:1:105:3 | PrependTest | modules.rb:101:1:105:3 | PrependTest |
|
||||
| modules.rb:103:3:104:5 | Y | modules.rb:103:3:104:5 | Test::Foo2::Y |
|
||||
| modules.rb:107:1:110:3 | MM | modules.rb:107:1:110:3 | MM |
|
||||
| modules.rb:108:3:109:5 | MM | modules.rb:108:3:109:5 | MM::MM |
|
||||
| modules.rb:112:1:113:3 | YY | modules.rb:112:1:113:3 | YY |
|
||||
| modules.rb:115:1:118:3 | XX | modules.rb:115:1:118:3 | XX |
|
||||
| modules.rb:116:7:117:9 | YY | modules.rb:116:7:117:9 | XX::YY |
|
||||
| modules.rb:120:1:121:3 | Baz | modules.rb:120:1:121:3 | Test::Foo1::Bar::Baz |
|
||||
| toplevel.rb:1:1:5:23 | toplevel.rb | file://:0:0:0:0 | Object |
|
||||
|
||||
@@ -23,5 +23,3 @@ query predicate classesInModules(ModuleDeclaration mod, ClassDeclaration klass,
|
||||
query predicate modulesInModules(ModuleDeclaration mod, ModuleDeclaration child, string name) {
|
||||
child = mod.getModule(name)
|
||||
}
|
||||
|
||||
query predicate moduleTypes(ModuleBase def, Module type) { type = def.getModule() }
|
||||
|
||||
96
ql/test/library-tests/modules/ancestors.expected
Normal file
96
ql/test/library-tests/modules/ancestors.expected
Normal file
@@ -0,0 +1,96 @@
|
||||
#-----| Object
|
||||
#-----| include -> Kernel
|
||||
#-----| super -> BasicObject
|
||||
|
||||
#-----| Class
|
||||
#-----| super -> Module
|
||||
|
||||
#-----| Kernel
|
||||
|
||||
#-----| Module
|
||||
#-----| super -> Object
|
||||
|
||||
#-----| BasicObject
|
||||
|
||||
hello.rb:
|
||||
# 1| EnglishWords
|
||||
|
||||
# 11| Greeting
|
||||
#-----| super -> Object
|
||||
#-----| include -> EnglishWords
|
||||
|
||||
# 18| HelloWorld
|
||||
#-----| super -> Greeting
|
||||
|
||||
modules.rb:
|
||||
# 1| Empty
|
||||
|
||||
# 4| Foo
|
||||
|
||||
# 37| Bar
|
||||
#-----| super -> Object
|
||||
|
||||
# 60| MyModuleInGlobalScope
|
||||
|
||||
# 63| Test
|
||||
|
||||
# 83| Other
|
||||
|
||||
# 88| IncludeTest
|
||||
#-----| include -> Test
|
||||
|
||||
# 95| IncludeTest2
|
||||
#-----| include -> Test
|
||||
|
||||
# 101| PrependTest
|
||||
#-----| prepend -> Test
|
||||
|
||||
# 107| MM
|
||||
|
||||
# 112| YY
|
||||
#-----| super -> Object
|
||||
|
||||
# 115| XX
|
||||
|
||||
# 5| Foo::Bar
|
||||
|
||||
# 19| Foo::ClassInFoo
|
||||
#-----| super -> Object
|
||||
|
||||
# 30| Foo::ClassInAnotherDefinitionOfFoo
|
||||
#-----| super -> Object
|
||||
|
||||
# 65| Test::Foo1
|
||||
|
||||
# 70| Test::Foo2
|
||||
|
||||
# 76| Test::Foo3
|
||||
|
||||
# 84| Other::Foo1
|
||||
|
||||
# 116| XX::YY
|
||||
#-----| super -> YY
|
||||
|
||||
# 6| Foo::Bar::ClassInFooBar
|
||||
#-----| super -> Object
|
||||
|
||||
# 71| Test::Foo2::Foo2
|
||||
|
||||
# 108| MM::MM
|
||||
|
||||
# 49| Foo::Bar::ClassInAnotherDefinitionOfFooBar
|
||||
#-----| super -> Object
|
||||
|
||||
# 66| Test::Foo1::Bar
|
||||
#-----| super -> Object
|
||||
|
||||
# 91| Test::Foo1::Y
|
||||
|
||||
# 97| Test::Foo1::Z
|
||||
|
||||
# 103| Test::Foo2::Y
|
||||
|
||||
# 72| Test::Foo2::Foo2::Bar
|
||||
#-----| super -> Object
|
||||
|
||||
# 120| Test::Foo1::Bar::Baz
|
||||
21
ql/test/library-tests/modules/ancestors.ql
Normal file
21
ql/test/library-tests/modules/ancestors.ql
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @kind graph
|
||||
* @id rb/test/ancestors
|
||||
*/
|
||||
|
||||
import ruby
|
||||
|
||||
query predicate nodes(Module node, string key, string value) {
|
||||
key = "semmle.label" and value = node.toString()
|
||||
}
|
||||
|
||||
query predicate edges(Module source, Module target, string key, string value) {
|
||||
key = "semmle.label" and
|
||||
(
|
||||
target = source.getSuperClass() and value = "super"
|
||||
or
|
||||
target = source.getAPrependedModule() and value = "prepend"
|
||||
or
|
||||
target = source.getAnIncludedModule() and value = "include"
|
||||
)
|
||||
}
|
||||
22
ql/test/library-tests/modules/hello.rb
Normal file
22
ql/test/library-tests/modules/hello.rb
Normal file
@@ -0,0 +1,22 @@
|
||||
module EnglishWords
|
||||
def hello
|
||||
return "hello"
|
||||
end
|
||||
def world
|
||||
return "world"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
class Greeting
|
||||
include EnglishWords
|
||||
def message
|
||||
return hello
|
||||
end
|
||||
end
|
||||
|
||||
class HelloWorld < Greeting
|
||||
def message
|
||||
return super + " " + world + "!"
|
||||
end
|
||||
end
|
||||
26
ql/test/library-tests/modules/methods.expected
Normal file
26
ql/test/library-tests/modules/methods.expected
Normal file
@@ -0,0 +1,26 @@
|
||||
getMethod
|
||||
| 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 |
|
||||
| hello.rb:18:1:22:3 | HelloWorld | message | hello.rb:19:5:21:7 | message |
|
||||
| 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: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
|
||||
| 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 | hello | hello.rb:2:5:4:7 | hello |
|
||||
| hello.rb:11:1:16:3 | Greeting | message | hello.rb:13:5:15:7 | message |
|
||||
| hello.rb:11:1:16:3 | Greeting | world | hello.rb:5:5:7:7 | world |
|
||||
| hello.rb:18:1:22:3 | HelloWorld | hello | hello.rb:2:5:4:7 | hello |
|
||||
| hello.rb:18:1:22:3 | HelloWorld | message | hello.rb:19:5:21:7 | message |
|
||||
| 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: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 |
|
||||
6
ql/test/library-tests/modules/methods.ql
Normal file
6
ql/test/library-tests/modules/methods.ql
Normal file
@@ -0,0 +1,6 @@
|
||||
import ruby
|
||||
import codeql_ruby.ast.internal.Module as M
|
||||
|
||||
query MethodBase getMethod(Module m, string name) { result = M::getMethod(m, name) }
|
||||
|
||||
query MethodBase lookupMethod(Module m, string name) { result = M::lookupMethod(m, name) }
|
||||
100
ql/test/library-tests/modules/modules.expected
Normal file
100
ql/test/library-tests/modules/modules.expected
Normal file
@@ -0,0 +1,100 @@
|
||||
getModule
|
||||
| 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 |
|
||||
| hello.rb:1:1:8:3 | EnglishWords |
|
||||
| hello.rb:11:1:16:3 | Greeting |
|
||||
| hello.rb:18:1:22:3 | HelloWorld |
|
||||
| modules.rb:1:1:2:3 | Empty |
|
||||
| modules.rb:4:1:24:3 | Foo |
|
||||
| modules.rb:5:3:14:5 | Foo::Bar |
|
||||
| modules.rb:6:5:7:7 | Foo::Bar::ClassInFooBar |
|
||||
| modules.rb:19:3:20:5 | Foo::ClassInFoo |
|
||||
| modules.rb:30:3:31:5 | Foo::ClassInAnotherDefinitionOfFoo |
|
||||
| modules.rb:37:1:46:3 | Bar |
|
||||
| modules.rb:49:3:50:5 | Foo::Bar::ClassInAnotherDefinitionOfFooBar |
|
||||
| modules.rb:60:1:61:3 | MyModuleInGlobalScope |
|
||||
| modules.rb:63:1:81:3 | Test |
|
||||
| modules.rb:65:3:68:5 | Test::Foo1 |
|
||||
| modules.rb:66:5:67:7 | Test::Foo1::Bar |
|
||||
| modules.rb:70:3:74:5 | Test::Foo2 |
|
||||
| modules.rb:71:5:71:19 | Test::Foo2::Foo2 |
|
||||
| modules.rb:72:5:73:7 | Test::Foo2::Foo2::Bar |
|
||||
| modules.rb:76:3:80:5 | Test::Foo3 |
|
||||
| modules.rb:83:1:86:3 | Other |
|
||||
| modules.rb:84:3:85:5 | Other::Foo1 |
|
||||
| modules.rb:88:1:93:3 | IncludeTest |
|
||||
| modules.rb:91:3:92:5 | Test::Foo1::Y |
|
||||
| modules.rb:95:1:99:3 | IncludeTest2 |
|
||||
| modules.rb:97:3:98:5 | Test::Foo1::Z |
|
||||
| modules.rb:101:1:105:3 | PrependTest |
|
||||
| modules.rb:103:3:104:5 | Test::Foo2::Y |
|
||||
| modules.rb:107:1:110:3 | MM |
|
||||
| modules.rb:108:3:109:5 | MM::MM |
|
||||
| modules.rb:112:1:113:3 | YY |
|
||||
| modules.rb:115:1:118:3 | XX |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| modules.rb:1:1:2:3 | Empty | modules.rb:1:1:2:3 | Empty |
|
||||
| modules.rb:4:1:24:3 | Foo | modules.rb:4:1:24:3 | Foo |
|
||||
| modules.rb:4:1:24:3 | Foo | modules.rb:26:1:35:3 | Foo |
|
||||
| modules.rb:5:3:14:5 | Foo::Bar | modules.rb:5:3:14:5 | Bar |
|
||||
| modules.rb:5:3:14:5 | Foo::Bar | modules.rb:48:1:57:3 | Bar |
|
||||
| modules.rb:6:5:7:7 | Foo::Bar::ClassInFooBar | modules.rb:6:5:7:7 | ClassInFooBar |
|
||||
| modules.rb:19:3:20:5 | Foo::ClassInFoo | modules.rb:19:3:20:5 | ClassInFoo |
|
||||
| modules.rb:30:3:31:5 | Foo::ClassInAnotherDefinitionOfFoo | modules.rb:30:3:31:5 | ClassInAnotherDefinitionOfFoo |
|
||||
| modules.rb:37:1:46:3 | Bar | modules.rb:37:1:46:3 | Bar |
|
||||
| modules.rb:37:1:46:3 | Bar | modules.rb:78:5:79:7 | Bar |
|
||||
| modules.rb:49:3:50:5 | Foo::Bar::ClassInAnotherDefinitionOfFooBar | modules.rb:49:3:50:5 | 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 | Test::Foo1 | modules.rb:65:3:68:5 | Foo1 |
|
||||
| modules.rb:66:5:67:7 | Test::Foo1::Bar | modules.rb:66:5:67:7 | Bar |
|
||||
| modules.rb:70:3:74:5 | Test::Foo2 | modules.rb:70:3:74:5 | Foo2 |
|
||||
| modules.rb:71:5:71:19 | Test::Foo2::Foo2 | modules.rb:71:5:71:19 | Foo2 |
|
||||
| modules.rb:72:5:73:7 | Test::Foo2::Foo2::Bar | modules.rb:72:5:73:7 | Bar |
|
||||
| modules.rb:76:3:80:5 | Test::Foo3 | modules.rb:76:3:80:5 | Foo3 |
|
||||
| modules.rb:83:1:86:3 | Other | modules.rb:83:1:86:3 | Other |
|
||||
| modules.rb:84:3:85:5 | Other::Foo1 | modules.rb:84:3:85:5 | Foo1 |
|
||||
| modules.rb:88:1:93:3 | IncludeTest | modules.rb:88:1:93:3 | IncludeTest |
|
||||
| modules.rb:91:3:92:5 | Test::Foo1::Y | modules.rb:91:3:92:5 | Y |
|
||||
| modules.rb:95:1:99:3 | IncludeTest2 | modules.rb:95:1:99:3 | IncludeTest2 |
|
||||
| modules.rb:97:3:98:5 | Test::Foo1::Z | modules.rb:97:3:98:5 | Z |
|
||||
| modules.rb:101:1:105:3 | PrependTest | modules.rb:101:1:105:3 | PrependTest |
|
||||
| modules.rb:103:3:104:5 | Test::Foo2::Y | modules.rb:103:3:104:5 | Y |
|
||||
| modules.rb:107:1:110:3 | MM | modules.rb:107:1:110:3 | MM |
|
||||
| modules.rb:108:3:109:5 | MM::MM | modules.rb:108:3:109:5 | MM |
|
||||
| modules.rb:112:1:113:3 | YY | modules.rb:112:1:113:3 | YY |
|
||||
| modules.rb:115:1:118:3 | XX | modules.rb:115:1:118:3 | XX |
|
||||
| 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 |
|
||||
| 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: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 |
|
||||
| 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 |
|
||||
11
ql/test/library-tests/modules/modules.ql
Normal file
11
ql/test/library-tests/modules/modules.ql
Normal file
@@ -0,0 +1,11 @@
|
||||
import ruby
|
||||
|
||||
query Module getModule() { any() }
|
||||
|
||||
query ModuleBase getADeclaration(Module m) { result = m.getADeclaration() }
|
||||
|
||||
query Module getSuperClass(Module m) { result = m.getSuperClass() }
|
||||
|
||||
query Module getAPrependedModule(Module m) { result = m.getAPrependedModule() }
|
||||
|
||||
query Module getAnIncludedModule(Module m) { result = m.getAnIncludedModule() }
|
||||
122
ql/test/library-tests/modules/modules.rb
Normal file
122
ql/test/library-tests/modules/modules.rb
Normal file
@@ -0,0 +1,122 @@
|
||||
module Empty
|
||||
end
|
||||
|
||||
module Foo
|
||||
module Bar
|
||||
class ClassInFooBar
|
||||
end
|
||||
|
||||
def method_in_foo_bar
|
||||
end
|
||||
|
||||
puts 'module Foo::Bar'
|
||||
$global_var = 0
|
||||
end
|
||||
|
||||
def method_in_foo
|
||||
end
|
||||
|
||||
class ClassInFoo
|
||||
end
|
||||
|
||||
puts 'module Foo'
|
||||
$global_var = 1
|
||||
end
|
||||
|
||||
module Foo
|
||||
def method_in_another_definition_of_foo
|
||||
end
|
||||
|
||||
class ClassInAnotherDefinitionOfFoo
|
||||
end
|
||||
|
||||
puts 'module Foo again'
|
||||
$global_var = 2
|
||||
end
|
||||
|
||||
module Bar
|
||||
def method_a
|
||||
end
|
||||
|
||||
def method_b
|
||||
end
|
||||
|
||||
puts 'module Bar'
|
||||
$global_var = 3
|
||||
end
|
||||
|
||||
module Foo::Bar
|
||||
class ClassInAnotherDefinitionOfFooBar
|
||||
end
|
||||
|
||||
def method_in_another_definition_of_foo_bar
|
||||
end
|
||||
|
||||
puts 'module Foo::Bar again'
|
||||
$global_var = 4
|
||||
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 Other
|
||||
module Foo1
|
||||
end
|
||||
end
|
||||
|
||||
module IncludeTest
|
||||
include ::Test
|
||||
Object.module_eval { prepend Other }
|
||||
module Foo1::Y
|
||||
end
|
||||
end
|
||||
|
||||
module IncludeTest2
|
||||
include Test
|
||||
module Foo1::Z
|
||||
end
|
||||
end
|
||||
|
||||
module PrependTest
|
||||
prepend ::Test
|
||||
module Foo2::Y
|
||||
end
|
||||
end
|
||||
|
||||
module MM
|
||||
module MM::MM
|
||||
end
|
||||
end
|
||||
|
||||
class YY
|
||||
end
|
||||
|
||||
module XX
|
||||
class YY < YY
|
||||
end
|
||||
end
|
||||
|
||||
module Test::Foo1::Bar::Baz
|
||||
end
|
||||
|
||||
91
ql/test/library-tests/modules/superclasses.expected
Normal file
91
ql/test/library-tests/modules/superclasses.expected
Normal file
@@ -0,0 +1,91 @@
|
||||
#-----| Object
|
||||
#-----| -> BasicObject
|
||||
|
||||
#-----| Class
|
||||
#-----| -> Module
|
||||
|
||||
#-----| Kernel
|
||||
|
||||
#-----| Module
|
||||
#-----| -> Object
|
||||
|
||||
#-----| BasicObject
|
||||
|
||||
hello.rb:
|
||||
# 1| EnglishWords
|
||||
|
||||
# 11| Greeting
|
||||
#-----| -> Object
|
||||
|
||||
# 18| HelloWorld
|
||||
#-----| -> Greeting
|
||||
|
||||
modules.rb:
|
||||
# 1| Empty
|
||||
|
||||
# 4| Foo
|
||||
|
||||
# 37| Bar
|
||||
#-----| -> Object
|
||||
|
||||
# 60| MyModuleInGlobalScope
|
||||
|
||||
# 63| Test
|
||||
|
||||
# 83| Other
|
||||
|
||||
# 88| IncludeTest
|
||||
|
||||
# 95| IncludeTest2
|
||||
|
||||
# 101| PrependTest
|
||||
|
||||
# 107| MM
|
||||
|
||||
# 112| YY
|
||||
#-----| -> Object
|
||||
|
||||
# 115| XX
|
||||
|
||||
# 5| Foo::Bar
|
||||
|
||||
# 19| Foo::ClassInFoo
|
||||
#-----| -> Object
|
||||
|
||||
# 30| Foo::ClassInAnotherDefinitionOfFoo
|
||||
#-----| -> Object
|
||||
|
||||
# 65| Test::Foo1
|
||||
|
||||
# 70| Test::Foo2
|
||||
|
||||
# 76| Test::Foo3
|
||||
|
||||
# 84| Other::Foo1
|
||||
|
||||
# 116| XX::YY
|
||||
#-----| -> YY
|
||||
|
||||
# 6| Foo::Bar::ClassInFooBar
|
||||
#-----| -> Object
|
||||
|
||||
# 71| Test::Foo2::Foo2
|
||||
|
||||
# 108| MM::MM
|
||||
|
||||
# 49| Foo::Bar::ClassInAnotherDefinitionOfFooBar
|
||||
#-----| -> Object
|
||||
|
||||
# 66| Test::Foo1::Bar
|
||||
#-----| -> Object
|
||||
|
||||
# 91| Test::Foo1::Y
|
||||
|
||||
# 97| Test::Foo1::Z
|
||||
|
||||
# 103| Test::Foo2::Y
|
||||
|
||||
# 72| Test::Foo2::Foo2::Bar
|
||||
#-----| -> Object
|
||||
|
||||
# 120| Test::Foo1::Bar::Baz
|
||||
12
ql/test/library-tests/modules/superclasses.ql
Normal file
12
ql/test/library-tests/modules/superclasses.ql
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* @kind graph
|
||||
* @id rb/test/supertypes
|
||||
*/
|
||||
|
||||
import ruby
|
||||
|
||||
query predicate nodes(Module node, string key, string value) {
|
||||
key = "semmle.label" and value = node.toString()
|
||||
}
|
||||
|
||||
query predicate edges(Module source, Module target) { target = source.getSuperClass() }
|
||||
Reference in New Issue
Block a user