Merge pull request #122 from github/constants_scopes

Rework handling of scope resolution nodes, and add `ConstantAccess` class
This commit is contained in:
Arthur Baars
2021-02-11 17:19:47 +01:00
committed by GitHub
26 changed files with 712 additions and 297 deletions

View File

@@ -1,6 +1,7 @@
import codeql.Locations
import ast.Call
import ast.Control
import ast.Constant
import ast.Expr
import ast.Method
import ast.Module

View File

@@ -11,41 +11,30 @@ class Call extends Expr {
/**
* Gets the receiver of this call, if any. For example:
*
* ```rb
* foo.bar
* baz()
* Baz::qux
* corge()
* ```
* The result for the call to `bar` is the `Expr` for `foo`, while the call
* to `baz` has no result.
*
* The result for the call to `bar` is the `Expr` for `foo`; the result for
* the call to `qux` is the `Expr` for `Baz`; for the call to `corge` there
* is no result.
*/
final Expr getReceiver() { result = range.getReceiver() }
/**
* Gets the name of the method being called. For example, in:
*
* ```rb
* foo.bar x, y
* ```
* the result is `"bar"`.
*
* N.B. in the following example, where the method name is a scope
* resolution, the result is the name being resolved, i.e. `"bar"`. Use
* `getMethodScopeResolution` to get the complete `ScopeResolution`.
* ```rb
* Foo::bar x, y
* ```
* the result is `"bar"`.
*/
final string getMethodName() { result = range.getMethodName() }
/**
* Gets the scope resolution of this call, if any. In the following example,
* the result is the `ScopeResolution` for `Foo::bar`, while
* `getMethodName()` returns `"bar"`.
* ```rb
* Foo::bar()
* ```
*/
final ScopeResolution getMethodScopeResolution() { result = range.getMethodScopeResolution() }
/**
* Gets the `n`th argument of this method call. In the following example, the
* result for n=0 is the `IntegerLiteral` 0, while for n=1 the result is a

View File

@@ -0,0 +1,96 @@
private import codeql_ruby.AST
private import internal.Constant
/** An access to a constant. */
class ConstantAccess extends Expr {
override ConstantAccess::Range range;
/** Gets the name of the constant being accessed. */
string getName() { result = range.getName() }
/**
* Gets the expression used in the access's scope resolution operation, if
* any. In the following example, the result is the `Call` expression for
* `foo()`.
*
* ```rb
* foo()::MESSAGE
* ```
*
* However, there is no result for the following example, since there is no
* scope resolution operation.
*
* ```rb
* MESSAGE
* ```
*/
Expr getScopeExpr() { result = range.getScopeExpr() }
/**
* Holds if the access uses the scope resolution operator to refer to the
* global scope, as in this example:
*
* ```rb
* ::MESSAGE
* ```
*/
predicate hasGlobalScope() { range.hasGlobalScope() }
}
/**
* A use (read) of a constant.
*
* For example, the right-hand side of the assignment in:
*
* ```rb
* x = Foo
* ```
*
* Or the superclass `Bar` in this example:
*
* ```rb
* class Foo < Bar
* end
* ```
*/
class ConstantReadAccess extends ConstantAccess {
final override ConstantReadAccess::Range range;
final override string getAPrimaryQlClass() { result = "ConstantReadAccess" }
}
/**
* A definition of a constant.
*
* Examples:
*
* ```rb
* Foo = 1 # defines constant Foo as an integer
* M::Foo = 1 # defines constant Foo as an integer in module M
*
* class Bar; end # defines constant Bar as a class
* class M::Bar; end # defines constant Bar as a class in module M
*
* module Baz; end # defines constant Baz as a module
* module M::Baz; end # defines constant Baz as a module in module M
* ```
*/
class ConstantWriteAccess extends ConstantAccess {
override ConstantWriteAccess::Range range;
override string getAPrimaryQlClass() { result = "ConstantWriteAccess" }
}
/**
* A definition of a constant via assignment. For example, the left-hand
* operand in the following example:
*
* ```rb
* MAX_SIZE = 100
* ```
*/
class ConstantAssignment extends ConstantWriteAccess {
override ConstantAssignment::Range range;
override string getAPrimaryQlClass() { result = "ConstantAssignment" }
}

View File

@@ -176,39 +176,6 @@ class ParenthesizedExpr extends ExprSequence, @parenthesized_statements {
final override string getAPrimaryQlClass() { result = "ParenthesizedExpr" }
}
/**
* A scope resolution, typically used to access constants defined in a class or
* module.
* ```rb
* Foo::Bar
* ```
*/
class ScopeResolution extends Expr, @scope_resolution {
final override ScopeResolution::Range range;
final override string getAPrimaryQlClass() { result = "ScopeResolution" }
/**
* Gets the expression representing the scope, if any. In the following
* example, the scope is the `Expr` for `Foo`:
* ```rb
* Foo::Bar
* ```
* However, in the following example, accessing the `Bar` constant in the
* `Object` class, there is no result:
* ```rb
* ::Bar
* ```
*/
final Expr getScope() { result = range.getScope() }
/**
* Gets the name being resolved. For example, in `Foo::Bar`, the result is
* `"Bar"`.
*/
final string getName() { result = range.getName() }
}
/**
* A pair expression. For example, in a hash:
* ```rb

View File

@@ -1,4 +1,5 @@
private import codeql_ruby.AST
private import codeql_ruby.ast.Constant
private import internal.Module
/**
@@ -36,7 +37,7 @@ class ModuleBase extends BodyStatement {
* end
* ```
*/
class Class extends ModuleBase {
class Class extends ModuleBase, ConstantWriteAccess {
final override Class::Range range;
final override string getAPrimaryQlClass() { result = "Class" }
@@ -49,41 +50,59 @@ class Class extends ModuleBase {
* end
* ```
*
* N.B. in the following example, where the class name is a scope resolution,
* the result is the name being resolved, i.e. `"Bar"`. Use
* `getScopeResolutionName` to get the complete `ScopeResolution`.
* N.B. in the following example, where the class name uses the scope
* resolution operator, the result is the name being resolved, i.e. `"Bar"`.
* Use `getScopeExpr` to get the `Foo` for `Foo`.
* ```rb
* class Foo::Bar
* end
* ```
*/
final string getName() { result = range.getName() }
final override string getName() { result = range.getName() }
/**
* Gets the scope resolution used to define the class name, if any. In the
* following example, the result is the `ScopeResolution` for `Foo::Bar`,
* while `getName()` returns `"Bar"`.
* Gets the scope expression used in the class name's scope resolution
* operation, if any.
*
* In the following example, the result is the `Expr` for `Foo`.
*
* ```rb
* class Foo::Bar
* end
* ```
*
* In the following example, the name is not a scope resolution, so there is
* no result.
* However, there is no result for the following example, since there is no
* scope resolution operation.
*
* ```rb
* class Baz
* end
* ```
*/
final ScopeResolution getNameScopeResolution() { result = range.getNameScopeResolution() }
final override Expr getScopeExpr() { result = range.getScopeExpr() }
/**
* Holds if the class name uses the scope resolution operator to access the
* global scope, as in this example:
*
* ```rb
* class ::Foo
* end
* ```
*/
final override predicate hasGlobalScope() { range.hasGlobalScope() }
/**
* Gets the `Expr` used as the superclass in the class definition, if any.
*
* TODO: add example for `class A < Foo` once we have `ConstantAccess`
* In the following example, the result is a `ConstantReadAccess`.
* ```rb
* class Foo < Bar
* end
* ```
*
* For example, where the superclass is a call expression, the result is a
* `Call`.
* In the following example, where the superclass is a call expression, the
* result is a `Call`.
* ```rb
* class C < foo()
* end
@@ -145,7 +164,7 @@ class SingletonClass extends ModuleBase, @singleton_class {
* end
* ```
*/
class Module extends ModuleBase, @module {
class Module extends ModuleBase, ConstantWriteAccess, @module {
final override Module::Range range;
final override string getAPrimaryQlClass() { result = "Module" }
@@ -158,31 +177,45 @@ class Module extends ModuleBase, @module {
* end
* ```
*
* N.B. in the following example, where the module name is a scope
* resolution, the result is the name being resolved, i.e. `"Bar"`. Use
* `getScopeResolutionName` to get the complete `ScopeResolution`.
* N.B. in the following example, where the module name uses the scope
* resolution operator, the result is the name being resolved, i.e. `"Bar"`.
* Use `getScopeExpr` to get the `Expr` for `Foo`.
* ```rb
* module Foo::Bar
* end
* ```
*/
final string getName() { result = range.getName() }
final override string getName() { result = range.getName() }
/**
* Gets the scope resolution used to define the module name, if any. In the
* following example, the result is the `ScopeResolution` for `Foo::Bar`,
* while `getName()` returns `"bar"`.
* Gets the scope expression used in the module name's scope resolution
* operation, if any.
*
* In the following example, the result is the `Expr` for `Foo`.
*
* ```rb
* module Foo::Bar
* end
* ```
*
* In the following example, the name is not a scope resolution, so this
* predicate has no result:
* However, there is no result for the following example, since there is no
* scope resolution operation.
*
* ```rb
* module Baz
* end
* ```
*/
final ScopeResolution getNameScopeResolution() { result = range.getNameScopeResolution() }
final override Expr getScopeExpr() { result = range.getScopeExpr() }
/**
* Holds if the module name uses the scope resolution operator to access the
* global scope, as in this example:
*
* ```rb
* class ::Foo
* end
* ```
*/
final override predicate hasGlobalScope() { range.hasGlobalScope() }
}

View File

@@ -35,8 +35,6 @@ module AstNode {
or
this instanceof Generated::Rescue
or
this instanceof Generated::Constant
or
this instanceof Generated::RestAssignment
or
this = any(Generated::RestAssignment ra).getChild()

View File

@@ -9,8 +9,6 @@ module Call {
abstract string getMethodName();
abstract ScopeResolution getMethodScopeResolution();
abstract Expr getArgument(int n);
abstract Block getBlock();
@@ -27,7 +25,24 @@ module Call {
final override string getMethodName() { result = generated.getValue() }
final override ScopeResolution getMethodScopeResolution() { none() }
final override Expr getArgument(int n) { none() }
final override Block getBlock() { none() }
}
private class ScopeResolutionIdentifierCallRange extends Call::Range, @scope_resolution {
final override Generated::ScopeResolution generated;
Generated::Identifier identifier;
ScopeResolutionIdentifierCallRange() {
identifier = generated.getName() and
vcall(this) and
not access(identifier, _)
}
final override Expr getReceiver() { result = generated.getScope() }
final override string getMethodName() { result = identifier.getValue() }
final override Expr getArgument(int n) { none() }
@@ -37,15 +52,18 @@ module Call {
private class RegularCallRange extends Call::Range, @call {
final override Generated::Call generated;
final override Expr getReceiver() { result = generated.getReceiver() }
final override Expr getReceiver() {
if exists(generated.getReceiver())
then result = generated.getReceiver()
else result = generated.getMethod().(Generated::ScopeResolution).getScope()
}
final override string getMethodName() {
result = generated.getMethod().(Generated::Token).getValue() or
result = this.getMethodScopeResolution().getName()
result =
generated.getMethod().(Generated::ScopeResolution).getName().(Generated::Token).getValue()
}
final override ScopeResolution getMethodScopeResolution() { result = generated.getMethod() }
final override Expr getArgument(int n) { result = generated.getArguments().getChild(n) }
final override Block getBlock() { result = generated.getBlock() }
@@ -60,8 +78,6 @@ module YieldCall {
final override string getMethodName() { result = "yield" }
final override ScopeResolution getMethodScopeResolution() { none() }
final override Expr getArgument(int n) { result = generated.getChild().getChild(n) }
final override Block getBlock() { none() }
@@ -82,8 +98,6 @@ module SuperCall {
final override string getMethodName() { result = generated.getValue() }
final override ScopeResolution getMethodScopeResolution() { none() }
final override Expr getArgument(int n) { none() }
final override Block getBlock() { none() }
@@ -100,8 +114,6 @@ module SuperCall {
result = generated.getMethod().(Generated::Super).getValue()
}
final override ScopeResolution getMethodScopeResolution() { none() }
final override Expr getArgument(int n) { result = generated.getArguments().getChild(n) }
final override Block getBlock() { result = generated.getBlock() }

View File

@@ -0,0 +1,89 @@
private import codeql_ruby.ast.internal.Expr
private import codeql_ruby.ast.internal.Pattern
private import codeql_ruby.ast.internal.TreeSitter
private import codeql_ruby.ast.internal.Variable
module ConstantAccess {
abstract class Range extends Expr::Range {
override string toString() { result = this.getName() }
abstract string getName();
abstract Expr::Range getScopeExpr();
abstract predicate hasGlobalScope();
}
}
module ConstantReadAccess {
abstract class Range extends ConstantAccess::Range { }
private class TokenConstantReadAccessRange extends ConstantReadAccess::Range, @token_constant {
final override Generated::Constant generated;
// A tree-sitter `constant` token is a read of that constant in any context
// where an identifier would be a vcall.
TokenConstantReadAccessRange() { vcall(this) }
final override string getName() { result = generated.getValue() }
final override Expr::Range getScopeExpr() { none() }
final override predicate hasGlobalScope() { none() }
}
private class ScopeResolutionReadAccessRange extends ConstantReadAccess::Range, @scope_resolution {
final override Generated::ScopeResolution generated;
Generated::Constant constant;
// A tree-sitter `scope_resolution` node with a `constant` name field is a
// read of that constant in any context where an identifier would be a
// vcall.
ScopeResolutionReadAccessRange() {
constant = generated.getName() and
vcall(this)
}
final override string getName() { result = constant.getValue() }
final override Expr::Range getScopeExpr() { result = generated.getScope() }
final override predicate hasGlobalScope() { not exists(generated.getScope()) }
}
}
module ConstantWriteAccess {
abstract class Range extends ConstantAccess::Range { }
}
module ConstantAssignment {
abstract class Range extends ConstantWriteAccess::Range { }
private class TokenConstantAssignmentRange extends ConstantAssignment::Range, @token_constant {
final override Generated::Constant generated;
TokenConstantAssignmentRange() { explicitAssignmentNode(this, _) }
final override string getName() { result = generated.getValue() }
final override Expr::Range getScopeExpr() { none() }
final override predicate hasGlobalScope() { none() }
}
private class ScopeResolutionAssignmentRange extends ConstantAssignment::Range, @scope_resolution {
final override Generated::ScopeResolution generated;
Generated::Constant constant;
ScopeResolutionAssignmentRange() {
constant = generated.getName() and
explicitAssignmentNode(this, _)
}
final override string getName() { result = constant.getValue() }
final override Expr::Range getScopeExpr() { result = generated.getScope() }
final override predicate hasGlobalScope() { not exists(generated.getScope()) }
}
}

View File

@@ -1,5 +1,6 @@
private import codeql_ruby.AST
private import codeql_ruby.ast.internal.AST
private import codeql_ruby.ast.internal.Pattern
private import codeql_ruby.ast.internal.TreeSitter
private import codeql_ruby.ast.internal.Variable
@@ -255,18 +256,6 @@ module Ensure {
}
}
module ScopeResolution {
class Range extends Expr::Range, @scope_resolution {
final override Generated::ScopeResolution generated;
final Expr getScope() { result = generated.getScope() }
final string getName() { result = generated.getName().(Generated::Token).getValue() }
final override string toString() { result = "...::" + this.getName() }
}
}
module Pair {
class Range extends Expr::Range, @pair {
final override Generated::Pair generated;

View File

@@ -1,4 +1,5 @@
private import codeql_ruby.AST
private import codeql_ruby.ast.internal.Constant
private import codeql_ruby.ast.internal.Expr
private import codeql_ruby.ast.internal.TreeSitter
@@ -7,17 +8,27 @@ module ModuleBase {
}
module Class {
class Range extends ModuleBase::Range, @class {
class Range extends ModuleBase::Range, ConstantWriteAccess::Range, @class {
final override Generated::Class generated;
final override Generated::AstNode getChild(int i) { result = generated.getChild(i) }
final string getName() {
final override string getName() {
result = generated.getName().(Generated::Token).getValue() or
result = this.getNameScopeResolution().getName()
result =
generated.getName().(Generated::ScopeResolution).getName().(Generated::Token).getValue()
}
final ScopeResolution getNameScopeResolution() { result = generated.getName() }
final override Expr::Range getScopeExpr() {
result = generated.getName().(Generated::ScopeResolution).getScope()
}
final override predicate hasGlobalScope() {
exists(Generated::ScopeResolution sr |
sr = generated.getName() and
not exists(sr.getScope())
)
}
final Expr getSuperclassExpr() { result = generated.getSuperclass().getChild() }
@@ -38,17 +49,27 @@ module SingletonClass {
}
module Module {
class Range extends ModuleBase::Range, @module {
class Range extends ModuleBase::Range, ConstantWriteAccess::Range, @module {
final override Generated::Module generated;
final override Generated::AstNode getChild(int i) { result = generated.getChild(i) }
final string getName() {
final override string getName() {
result = generated.getName().(Generated::Token).getValue() or
result = this.getNameScopeResolution().getName()
result =
generated.getName().(Generated::ScopeResolution).getName().(Generated::Token).getValue()
}
final ScopeResolution getNameScopeResolution() { result = generated.getName() }
final override Expr::Range getScopeExpr() {
result = generated.getName().(Generated::ScopeResolution).getScope()
}
final override predicate hasGlobalScope() {
exists(Generated::ScopeResolution sr |
sr = generated.getName() and
not exists(sr.getScope())
)
}
final override string toString() { result = this.getName() }
}

View File

@@ -165,8 +165,9 @@ private module Cached {
not scope.inherits(name, _)
}
// Token types that can be vcalls
private class VcallToken = @token_identifier or @token_super;
// Db types that can be vcalls
private class VcallToken =
@scope_resolution or @token_constant or @token_identifier or @token_super;
/**
* Holds if `i` is an `identifier` node occurring in the context where it

View File

@@ -1,10 +1,15 @@
blockArguments
| calls.rb:201:5:201:8 | &... | calls.rb:201:6:201:8 | call to bar |
| calls.rb:266:5:266:8 | &... | calls.rb:266:6:266:8 | call to bar |
| calls.rb:267:5:267:11 | &... | calls.rb:267:6:267:11 | call to bar |
splatArguments
| calls.rb:204:5:204:8 | *... | calls.rb:204:6:204:8 | call to bar |
| calls.rb:270:5:270:8 | *... | calls.rb:270:6:270:8 | call to bar |
| calls.rb:271:5:271:11 | *... | calls.rb:271:6:271:11 | call to bar |
hashSplatArguments
| calls.rb:207:5:207:9 | **... | calls.rb:207:7:207:9 | call to bar |
| calls.rb:274:5:274:9 | **... | calls.rb:274:7:274:9 | call to bar |
| calls.rb:275:5:275:12 | **... | calls.rb:275:7:275:12 | call to bar |
keywordArguments
| calls.rb:210:5:210:13 | Pair | calls.rb:210:5:210:8 | :blah | calls.rb:210:11:210:13 | call to bar |
| calls.rb:278:5:278:13 | Pair | calls.rb:278:5:278:8 | :blah | calls.rb:278:11:278:13 | call to bar |
| calls.rb:279:5:279:16 | Pair | calls.rb:279:5:279:8 | :blah | calls.rb:279:11:279:16 | call to bar |
keywordArgumentsByKeyword
| calls.rb:210:1:210:14 | call to foo | blah | calls.rb:210:11:210:13 | call to bar |
| calls.rb:278:1:278:14 | call to foo | blah | calls.rb:278:11:278:13 | call to bar |
| calls.rb:279:1:279:17 | call to foo | blah | calls.rb:279:11:279:16 | call to bar |

View File

@@ -1,144 +1,214 @@
callsWithNoReceiverArgumentsOrBlock
| calls.rb:2:1:2:5 | call to foo | foo |
| calls.rb:5:1:5:10 | call to bar | bar |
| calls.rb:28:3:28:7 | call to yield | yield |
| calls.rb:42:1:42:3 | call to foo | foo |
| calls.rb:45:2:45:4 | call to foo | foo |
| calls.rb:48:11:48:13 | call to foo | foo |
| calls.rb:51:2:51:4 | call to foo | foo |
| calls.rb:54:8:54:10 | call to foo | foo |
| calls.rb:57:9:57:11 | call to bar | bar |
| calls.rb:60:8:60:10 | call to foo | foo |
| calls.rb:60:13:60:15 | call to bar | bar |
| calls.rb:64:3:64:5 | call to foo | foo |
| calls.rb:68:9:68:11 | call to foo | foo |
| calls.rb:71:7:71:9 | call to foo | foo |
| calls.rb:74:1:74:3 | call to foo | foo |
| calls.rb:74:7:74:9 | call to bar | bar |
| calls.rb:77:2:77:4 | call to foo | foo |
| calls.rb:80:9:80:11 | call to bar | bar |
| calls.rb:83:10:83:12 | call to bar | bar |
| calls.rb:86:1:86:3 | call to foo | foo |
| calls.rb:90:6:90:8 | call to foo | foo |
| calls.rb:91:6:91:8 | call to bar | bar |
| calls.rb:92:3:92:5 | call to baz | baz |
| calls.rb:97:3:97:5 | call to foo | foo |
| calls.rb:101:17:101:19 | call to foo | foo |
| calls.rb:105:10:105:12 | call to foo | foo |
| calls.rb:106:3:106:5 | call to bar | bar |
| calls.rb:111:3:111:5 | call to foo | foo |
| calls.rb:115:5:115:7 | call to foo | foo |
| calls.rb:116:3:116:5 | call to bar | bar |
| calls.rb:120:40:120:42 | call to foo | foo |
| calls.rb:124:40:124:42 | call to foo | foo |
| calls.rb:129:3:129:5 | call to foo | foo |
| calls.rb:133:1:133:3 | call to foo | foo |
| calls.rb:133:7:133:9 | call to bar | bar |
| calls.rb:133:13:133:15 | call to baz | baz |
| calls.rb:136:4:136:6 | call to foo | foo |
| calls.rb:137:3:137:8 | call to wibble | wibble |
| calls.rb:138:7:138:9 | call to bar | bar |
| calls.rb:139:3:139:8 | call to wobble | wobble |
| calls.rb:141:3:141:8 | call to wabble | wabble |
| calls.rb:145:1:145:3 | call to bar | bar |
| calls.rb:145:8:145:10 | call to foo | foo |
| calls.rb:148:8:148:10 | call to foo | foo |
| calls.rb:149:3:149:5 | call to bar | bar |
| calls.rb:153:1:153:3 | call to bar | bar |
| calls.rb:153:12:153:14 | call to foo | foo |
| calls.rb:156:7:156:9 | call to foo | foo |
| calls.rb:157:3:157:5 | call to bar | bar |
| calls.rb:161:1:161:3 | call to bar | bar |
| calls.rb:161:11:161:13 | call to foo | foo |
| calls.rb:164:7:164:9 | call to foo | foo |
| calls.rb:165:3:165:5 | call to bar | bar |
| calls.rb:169:1:169:3 | call to bar | bar |
| calls.rb:169:11:169:13 | call to foo | foo |
| calls.rb:172:10:172:12 | call to bar | bar |
| calls.rb:173:3:173:5 | call to baz | baz |
| calls.rb:177:1:177:3 | call to foo | foo |
| calls.rb:177:5:177:7 | call to bar | bar |
| calls.rb:180:8:180:10 | call to bar | bar |
| calls.rb:183:1:183:3 | call to foo | foo |
| calls.rb:186:1:186:3 | call to foo | foo |
| calls.rb:186:6:186:8 | call to bar | bar |
| calls.rb:189:3:189:5 | call to foo | foo |
| calls.rb:189:10:189:12 | call to bar | bar |
| calls.rb:193:8:193:10 | call to foo | foo |
| calls.rb:194:8:194:10 | call to bar | bar |
| calls.rb:198:1:198:3 | call to foo | foo |
| calls.rb:198:12:198:14 | call to bar | bar |
| calls.rb:201:6:201:8 | call to bar | bar |
| calls.rb:204:6:204:8 | call to bar | bar |
| calls.rb:207:7:207:9 | call to bar | bar |
| calls.rb:210:11:210:13 | call to bar | bar |
| calls.rb:217:5:217:9 | call to super | super |
| calls.rb:218:5:218:11 | call to super | super |
| calls.rb:234:5:234:7 | call to foo | foo |
| calls.rb:235:5:235:14 | call to super | super |
| calls.rb:236:5:236:9 | call to super | super |
callsWithScopeResolutionName
| calls.rb:5:1:5:10 | call to bar | calls.rb:5:1:5:8 | ...::bar |
| calls.rb:8:1:8:7 | call to bar | bar |
| calls.rb:31:3:31:7 | call to yield | yield |
| calls.rb:46:1:46:3 | call to foo | foo |
| calls.rb:50:2:50:4 | call to foo | foo |
| calls.rb:54:11:54:13 | call to foo | foo |
| calls.rb:58:2:58:4 | call to foo | foo |
| calls.rb:62:8:62:10 | call to foo | foo |
| calls.rb:66:9:66:11 | call to bar | bar |
| calls.rb:70:8:70:10 | call to foo | foo |
| calls.rb:74:3:74:5 | call to foo | foo |
| calls.rb:79:9:79:11 | call to foo | foo |
| calls.rb:82:7:82:9 | call to foo | foo |
| calls.rb:85:1:85:3 | call to foo | foo |
| calls.rb:88:2:88:4 | call to foo | foo |
| calls.rb:92:9:92:11 | call to bar | bar |
| calls.rb:96:3:96:5 | call to bar | bar |
| calls.rb:101:1:101:3 | call to foo | foo |
| calls.rb:102:1:102:3 | call to bar | bar |
| calls.rb:106:6:106:8 | call to foo | foo |
| calls.rb:107:6:107:8 | call to bar | bar |
| calls.rb:108:3:108:5 | call to baz | baz |
| calls.rb:117:3:117:5 | call to foo | foo |
| calls.rb:122:17:122:19 | call to foo | foo |
| calls.rb:128:10:128:12 | call to foo | foo |
| calls.rb:129:3:129:5 | call to bar | bar |
| calls.rb:137:3:137:5 | call to foo | foo |
| calls.rb:142:5:142:7 | call to foo | foo |
| calls.rb:143:3:143:5 | call to bar | bar |
| calls.rb:148:40:148:42 | call to foo | foo |
| calls.rb:154:40:154:42 | call to foo | foo |
| calls.rb:161:3:161:5 | call to foo | foo |
| calls.rb:166:1:166:3 | call to foo | foo |
| calls.rb:166:7:166:9 | call to bar | bar |
| calls.rb:166:13:166:15 | call to baz | baz |
| calls.rb:170:4:170:6 | call to foo | foo |
| calls.rb:171:3:171:8 | call to wibble | wibble |
| calls.rb:172:7:172:9 | call to bar | bar |
| calls.rb:173:3:173:8 | call to wobble | wobble |
| calls.rb:175:3:175:8 | call to wabble | wabble |
| calls.rb:186:1:186:3 | call to bar | bar |
| calls.rb:186:8:186:10 | call to foo | foo |
| calls.rb:190:8:190:10 | call to foo | foo |
| calls.rb:191:3:191:5 | call to bar | bar |
| calls.rb:198:1:198:3 | call to bar | bar |
| calls.rb:198:12:198:14 | call to foo | foo |
| calls.rb:202:7:202:9 | call to foo | foo |
| calls.rb:203:3:203:5 | call to bar | bar |
| calls.rb:210:1:210:3 | call to bar | bar |
| calls.rb:210:11:210:13 | call to foo | foo |
| calls.rb:214:7:214:9 | call to foo | foo |
| calls.rb:215:3:215:5 | call to bar | bar |
| calls.rb:222:1:222:3 | call to bar | bar |
| calls.rb:222:11:222:13 | call to foo | foo |
| calls.rb:226:10:226:12 | call to bar | bar |
| calls.rb:227:3:227:5 | call to baz | baz |
| calls.rb:234:1:234:3 | call to foo | foo |
| calls.rb:234:5:234:7 | call to bar | bar |
| calls.rb:238:8:238:10 | call to bar | bar |
| calls.rb:241:1:241:3 | call to foo | foo |
| calls.rb:245:1:245:3 | call to foo | foo |
| calls.rb:245:6:245:8 | call to bar | bar |
| calls.rb:249:3:249:5 | call to foo | foo |
| calls.rb:249:10:249:12 | call to bar | bar |
| calls.rb:253:8:253:10 | call to foo | foo |
| calls.rb:254:8:254:10 | call to bar | bar |
| calls.rb:262:1:262:3 | call to foo | foo |
| calls.rb:262:12:262:14 | call to bar | bar |
| calls.rb:266:6:266:8 | call to bar | bar |
| calls.rb:270:6:270:8 | call to bar | bar |
| calls.rb:274:7:274:9 | call to bar | bar |
| calls.rb:278:11:278:13 | call to bar | bar |
| calls.rb:286:5:286:9 | call to super | super |
| calls.rb:287:5:287:11 | call to super | super |
| calls.rb:303:5:303:7 | call to foo | foo |
| calls.rb:304:5:304:14 | call to super | super |
| calls.rb:305:5:305:9 | call to super | super |
callsWithArguments
| calls.rb:11:1:11:11 | call to foo | foo | 0 | calls.rb:11:5:11:5 | 0 |
| calls.rb:11:1:11:11 | call to foo | foo | 1 | calls.rb:11:8:11:8 | 1 |
| calls.rb:11:1:11:11 | call to foo | foo | 2 | calls.rb:11:11:11:11 | 2 |
| calls.rb:22:1:24:3 | call to bar | bar | 0 | calls.rb:22:9:22:13 | foo |
| calls.rb:33:3:33:16 | call to yield | yield | 0 | calls.rb:33:9:33:11 | 100 |
| calls.rb:33:3:33:16 | call to yield | yield | 1 | calls.rb:33:14:33:16 | 200 |
| calls.rb:48:1:48:14 | call to some_func | some_func | 0 | calls.rb:48:11:48:13 | call to foo |
| calls.rb:201:1:201:9 | call to foo | foo | 0 | calls.rb:201:5:201:8 | &... |
| calls.rb:204:1:204:9 | call to foo | foo | 0 | calls.rb:204:5:204:8 | *... |
| calls.rb:207:1:207:10 | call to foo | foo | 0 | calls.rb:207:5:207:9 | **... |
| calls.rb:210:1:210:14 | call to foo | foo | 0 | calls.rb:210:5:210:13 | Pair |
| calls.rb:219:5:219:16 | call to super | super | 0 | calls.rb:219:11:219:16 | blah |
| calls.rb:220:5:220:17 | call to super | super | 0 | calls.rb:220:11:220:11 | 1 |
| calls.rb:220:5:220:17 | call to super | super | 1 | calls.rb:220:14:220:14 | 2 |
| calls.rb:220:5:220:17 | call to super | super | 2 | calls.rb:220:17:220:17 | 3 |
| calls.rb:223:5:223:30 | call to super | super | 0 | calls.rb:223:11:223:11 | 4 |
| calls.rb:223:5:223:30 | call to super | super | 1 | calls.rb:223:14:223:14 | 5 |
| calls.rb:224:5:224:33 | call to super | super | 0 | calls.rb:224:11:224:11 | 6 |
| calls.rb:224:5:224:33 | call to super | super | 1 | calls.rb:224:14:224:14 | 7 |
| calls.rb:14:1:14:11 | call to foo | foo | 0 | calls.rb:14:5:14:5 | 0 |
| calls.rb:14:1:14:11 | call to foo | foo | 1 | calls.rb:14:8:14:8 | 1 |
| calls.rb:14:1:14:11 | call to foo | foo | 2 | calls.rb:14:11:14:11 | 2 |
| calls.rb:25:1:27:3 | call to bar | bar | 0 | calls.rb:25:9:25:13 | foo |
| calls.rb:36:3:36:16 | call to yield | yield | 0 | calls.rb:36:9:36:11 | 100 |
| calls.rb:36:3:36:16 | call to yield | yield | 1 | calls.rb:36:14:36:16 | 200 |
| calls.rb:54:1:54:14 | call to some_func | some_func | 0 | calls.rb:54:11:54:13 | call to foo |
| calls.rb:55:1:55:17 | call to some_func | some_func | 0 | calls.rb:55:11:55:16 | call to foo |
| calls.rb:266:1:266:9 | call to foo | foo | 0 | calls.rb:266:5:266:8 | &... |
| calls.rb:267:1:267:12 | call to foo | foo | 0 | calls.rb:267:5:267:11 | &... |
| calls.rb:270:1:270:9 | call to foo | foo | 0 | calls.rb:270:5:270:8 | *... |
| calls.rb:271:1:271:12 | call to foo | foo | 0 | calls.rb:271:5:271:11 | *... |
| calls.rb:274:1:274:10 | call to foo | foo | 0 | calls.rb:274:5:274:9 | **... |
| calls.rb:275:1:275:13 | call to foo | foo | 0 | calls.rb:275:5:275:12 | **... |
| calls.rb:278:1:278:14 | call to foo | foo | 0 | calls.rb:278:5:278:13 | Pair |
| calls.rb:279:1:279:17 | call to foo | foo | 0 | calls.rb:279:5:279:16 | Pair |
| calls.rb:288:5:288:16 | call to super | super | 0 | calls.rb:288:11:288:16 | blah |
| calls.rb:289:5:289:17 | call to super | super | 0 | calls.rb:289:11:289:11 | 1 |
| calls.rb:289:5:289:17 | call to super | super | 1 | calls.rb:289:14:289:14 | 2 |
| calls.rb:289:5:289:17 | call to super | super | 2 | calls.rb:289:17:289:17 | 3 |
| calls.rb:292:5:292:30 | call to super | super | 0 | calls.rb:292:11:292:11 | 4 |
| calls.rb:292:5:292:30 | call to super | super | 1 | calls.rb:292:14:292:14 | 5 |
| calls.rb:293:5:293:33 | call to super | super | 0 | calls.rb:293:11:293:11 | 6 |
| calls.rb:293:5:293:33 | call to super | super | 1 | calls.rb:293:14:293:14 | 7 |
callsWithReceiver
| calls.rb:8:1:8:7 | call to bar | calls.rb:8:1:8:3 | 123 |
| calls.rb:22:1:24:3 | call to bar | calls.rb:22:1:22:3 | 123 |
| calls.rb:86:1:86:9 | call to bar | calls.rb:86:1:86:3 | call to foo |
| calls.rb:234:5:234:13 | call to super | calls.rb:234:5:234:7 | call to foo |
| calls.rb:236:5:236:15 | call to super | calls.rb:236:5:236:9 | call to super |
| calls.rb:5:1:5:10 | call to bar | calls.rb:5:1:5:3 | Foo |
| calls.rb:11:1:11:7 | call to bar | calls.rb:11:1:11:3 | 123 |
| calls.rb:25:1:27:3 | call to bar | calls.rb:25:1:25:3 | 123 |
| calls.rb:47:1:47:6 | call to foo | calls.rb:47:1:47:1 | X |
| calls.rb:51:2:51:7 | call to foo | calls.rb:51:2:51:2 | X |
| calls.rb:55:11:55:16 | call to foo | calls.rb:55:11:55:11 | X |
| calls.rb:59:2:59:7 | call to foo | calls.rb:59:2:59:2 | X |
| calls.rb:63:8:63:13 | call to foo | calls.rb:63:8:63:8 | X |
| calls.rb:67:9:67:14 | call to bar | calls.rb:67:9:67:9 | X |
| calls.rb:70:13:70:18 | call to bar | calls.rb:70:13:70:13 | X |
| calls.rb:75:3:75:8 | call to foo | calls.rb:75:3:75:3 | X |
| calls.rb:79:14:79:19 | call to bar | calls.rb:79:14:79:14 | X |
| calls.rb:82:12:82:17 | call to bar | calls.rb:82:12:82:12 | X |
| calls.rb:85:7:85:12 | call to bar | calls.rb:85:7:85:7 | X |
| calls.rb:89:2:89:7 | call to bar | calls.rb:89:2:89:2 | X |
| calls.rb:92:14:92:19 | call to baz | calls.rb:92:14:92:14 | X |
| calls.rb:97:3:97:8 | call to baz | calls.rb:97:3:97:3 | X |
| calls.rb:101:1:101:9 | call to bar | calls.rb:101:1:101:3 | call to foo |
| calls.rb:102:1:102:9 | call to baz | calls.rb:102:1:102:3 | call to bar |
| calls.rb:110:6:110:11 | call to foo | calls.rb:110:6:110:6 | X |
| calls.rb:111:6:111:11 | call to bar | calls.rb:111:6:111:6 | X |
| calls.rb:112:3:112:8 | call to baz | calls.rb:112:3:112:3 | X |
| calls.rb:118:3:118:8 | call to bar | calls.rb:118:3:118:3 | X |
| calls.rb:124:18:124:23 | call to foo | calls.rb:124:18:124:18 | X |
| calls.rb:131:10:131:15 | call to foo | calls.rb:131:10:131:10 | X |
| calls.rb:132:3:132:8 | call to bar | calls.rb:132:3:132:3 | X |
| calls.rb:138:3:138:8 | call to bar | calls.rb:138:3:138:3 | X |
| calls.rb:144:3:144:8 | call to baz | calls.rb:144:3:144:3 | X |
| calls.rb:150:41:150:46 | call to foo | calls.rb:150:41:150:41 | X |
| calls.rb:156:41:156:46 | call to foo | calls.rb:156:41:156:41 | X |
| calls.rb:162:3:162:8 | call to bar | calls.rb:162:3:162:3 | X |
| calls.rb:167:1:167:6 | call to foo | calls.rb:167:1:167:1 | X |
| calls.rb:167:10:167:15 | call to bar | calls.rb:167:10:167:10 | X |
| calls.rb:167:19:167:24 | call to baz | calls.rb:167:19:167:19 | X |
| calls.rb:177:4:177:9 | call to foo | calls.rb:177:4:177:4 | X |
| calls.rb:178:3:178:11 | call to wibble | calls.rb:178:3:178:3 | X |
| calls.rb:179:7:179:12 | call to bar | calls.rb:179:7:179:7 | X |
| calls.rb:180:3:180:11 | call to wobble | calls.rb:180:3:180:3 | X |
| calls.rb:182:3:182:11 | call to wabble | calls.rb:182:3:182:3 | X |
| calls.rb:187:1:187:6 | call to bar | calls.rb:187:1:187:1 | X |
| calls.rb:187:11:187:16 | call to foo | calls.rb:187:11:187:11 | X |
| calls.rb:193:8:193:13 | call to foo | calls.rb:193:8:193:8 | X |
| calls.rb:194:3:194:8 | call to bar | calls.rb:194:3:194:3 | X |
| calls.rb:199:1:199:6 | call to bar | calls.rb:199:1:199:1 | X |
| calls.rb:199:15:199:20 | call to foo | calls.rb:199:15:199:15 | X |
| calls.rb:205:7:205:12 | call to foo | calls.rb:205:7:205:7 | X |
| calls.rb:206:3:206:8 | call to bar | calls.rb:206:3:206:3 | X |
| calls.rb:211:1:211:6 | call to bar | calls.rb:211:1:211:1 | X |
| calls.rb:211:14:211:19 | call to foo | calls.rb:211:14:211:14 | X |
| calls.rb:217:7:217:12 | call to foo | calls.rb:217:7:217:7 | X |
| calls.rb:218:3:218:8 | call to bar | calls.rb:218:3:218:3 | X |
| calls.rb:223:1:223:6 | call to bar | calls.rb:223:1:223:1 | X |
| calls.rb:223:14:223:19 | call to foo | calls.rb:223:14:223:14 | X |
| calls.rb:229:10:229:15 | call to bar | calls.rb:229:10:229:10 | X |
| calls.rb:230:3:230:8 | call to baz | calls.rb:230:3:230:3 | X |
| calls.rb:235:1:235:6 | call to foo | calls.rb:235:1:235:1 | X |
| calls.rb:235:8:235:13 | call to bar | calls.rb:235:8:235:8 | X |
| calls.rb:238:15:238:20 | call to baz | calls.rb:238:15:238:15 | X |
| calls.rb:242:1:242:6 | call to foo | calls.rb:242:1:242:1 | X |
| calls.rb:246:1:246:6 | call to foo | calls.rb:246:1:246:1 | X |
| calls.rb:246:9:246:14 | call to bar | calls.rb:246:9:246:9 | X |
| calls.rb:249:15:249:20 | call to foo | calls.rb:249:15:249:15 | X |
| calls.rb:249:25:249:30 | call to bar | calls.rb:249:25:249:25 | X |
| calls.rb:257:8:257:13 | call to foo | calls.rb:257:8:257:8 | X |
| calls.rb:258:8:258:13 | call to bar | calls.rb:258:8:258:8 | X |
| calls.rb:263:1:263:6 | call to foo | calls.rb:263:1:263:1 | X |
| calls.rb:263:15:263:20 | call to bar | calls.rb:263:15:263:15 | X |
| calls.rb:267:6:267:11 | call to bar | calls.rb:267:6:267:6 | X |
| calls.rb:271:6:271:11 | call to bar | calls.rb:271:6:271:6 | X |
| calls.rb:275:7:275:12 | call to bar | calls.rb:275:7:275:7 | X |
| calls.rb:279:11:279:16 | call to bar | calls.rb:279:11:279:11 | X |
| calls.rb:303:5:303:13 | call to super | calls.rb:303:5:303:7 | call to foo |
| calls.rb:305:5:305:15 | call to super | calls.rb:305:5:305:9 | call to super |
callsWithBlock
| calls.rb:14:1:14:17 | call to foo | calls.rb:14:5:14:17 | { ... } |
| calls.rb:17:1:19:3 | call to foo | calls.rb:17:5:19:3 | do ... end |
| calls.rb:22:1:24:3 | call to bar | calls.rb:22:16:24:3 | do ... end |
| calls.rb:80:1:80:13 | call to foo | calls.rb:80:7:80:13 | { ... } |
| calls.rb:83:1:83:16 | call to foo | calls.rb:83:7:83:16 | do ... end |
| calls.rb:221:5:221:23 | call to super | calls.rb:221:11:221:23 | { ... } |
| calls.rb:222:5:222:26 | call to super | calls.rb:222:11:222:26 | do ... end |
| calls.rb:223:5:223:30 | call to super | calls.rb:223:16:223:30 | { ... } |
| calls.rb:224:5:224:33 | call to super | calls.rb:224:16:224:33 | do ... end |
| calls.rb:17:1:17:17 | call to foo | calls.rb:17:5:17:17 | { ... } |
| calls.rb:20:1:22:3 | call to foo | calls.rb:20:5:22:3 | do ... end |
| calls.rb:25:1:27:3 | call to bar | calls.rb:25:16:27:3 | do ... end |
| calls.rb:92:1:92:21 | call to foo | calls.rb:92:7:92:21 | { ... } |
| calls.rb:95:1:98:3 | call to foo | calls.rb:95:7:98:3 | do ... end |
| calls.rb:290:5:290:23 | call to super | calls.rb:290:11:290:23 | { ... } |
| calls.rb:291:5:291:26 | call to super | calls.rb:291:11:291:26 | do ... end |
| calls.rb:292:5:292:30 | call to super | calls.rb:292:16:292:30 | { ... } |
| calls.rb:293:5:293:33 | call to super | calls.rb:293:16:293:33 | do ... end |
yieldCalls
| calls.rb:28:3:28:7 | call to yield |
| calls.rb:33:3:33:16 | call to yield |
| calls.rb:31:3:31:7 | call to yield |
| calls.rb:36:3:36:16 | call to yield |
superCalls
| calls.rb:217:5:217:9 | call to super |
| calls.rb:218:5:218:11 | call to super |
| calls.rb:219:5:219:16 | call to super |
| calls.rb:220:5:220:17 | call to super |
| calls.rb:221:5:221:23 | call to super |
| calls.rb:222:5:222:26 | call to super |
| calls.rb:223:5:223:30 | call to super |
| calls.rb:224:5:224:33 | call to super |
| calls.rb:236:5:236:9 | call to super |
| calls.rb:286:5:286:9 | call to super |
| calls.rb:287:5:287:11 | call to super |
| calls.rb:288:5:288:16 | call to super |
| calls.rb:289:5:289:17 | call to super |
| calls.rb:290:5:290:23 | call to super |
| calls.rb:291:5:291:26 | call to super |
| calls.rb:292:5:292:30 | call to super |
| calls.rb:293:5:293:33 | call to super |
| calls.rb:305:5:305:9 | call to super |
superCallsWithArguments
| calls.rb:219:5:219:16 | call to super | 0 | calls.rb:219:11:219:16 | blah |
| calls.rb:220:5:220:17 | call to super | 0 | calls.rb:220:11:220:11 | 1 |
| calls.rb:220:5:220:17 | call to super | 1 | calls.rb:220:14:220:14 | 2 |
| calls.rb:220:5:220:17 | call to super | 2 | calls.rb:220:17:220:17 | 3 |
| calls.rb:223:5:223:30 | call to super | 0 | calls.rb:223:11:223:11 | 4 |
| calls.rb:223:5:223:30 | call to super | 1 | calls.rb:223:14:223:14 | 5 |
| calls.rb:224:5:224:33 | call to super | 0 | calls.rb:224:11:224:11 | 6 |
| calls.rb:224:5:224:33 | call to super | 1 | calls.rb:224:14:224:14 | 7 |
| calls.rb:288:5:288:16 | call to super | 0 | calls.rb:288:11:288:16 | blah |
| calls.rb:289:5:289:17 | call to super | 0 | calls.rb:289:11:289:11 | 1 |
| calls.rb:289:5:289:17 | call to super | 1 | calls.rb:289:14:289:14 | 2 |
| calls.rb:289:5:289:17 | call to super | 2 | calls.rb:289:17:289:17 | 3 |
| calls.rb:292:5:292:30 | call to super | 0 | calls.rb:292:11:292:11 | 4 |
| calls.rb:292:5:292:30 | call to super | 1 | calls.rb:292:14:292:14 | 5 |
| calls.rb:293:5:293:33 | call to super | 0 | calls.rb:293:11:293:11 | 6 |
| calls.rb:293:5:293:33 | call to super | 1 | calls.rb:293:14:293:14 | 7 |
superCallsWithBlock
| calls.rb:221:5:221:23 | call to super | calls.rb:221:11:221:23 | { ... } |
| calls.rb:222:5:222:26 | call to super | calls.rb:222:11:222:26 | do ... end |
| calls.rb:223:5:223:30 | call to super | calls.rb:223:16:223:30 | { ... } |
| calls.rb:224:5:224:33 | call to super | calls.rb:224:16:224:33 | do ... end |
| calls.rb:290:5:290:23 | call to super | calls.rb:290:11:290:23 | { ... } |
| calls.rb:291:5:291:26 | call to super | calls.rb:291:11:291:26 | do ... end |
| calls.rb:292:5:292:30 | call to super | calls.rb:292:16:292:30 | { ... } |
| calls.rb:293:5:293:33 | call to super | calls.rb:293:16:293:33 | do ... end |

View File

@@ -8,10 +8,6 @@ query predicate callsWithNoReceiverArgumentsOrBlock(Call c, string name) {
not exists(c.getBlock())
}
query predicate callsWithScopeResolutionName(Call c, ScopeResolution sr) {
sr = c.getMethodScopeResolution()
}
query predicate callsWithArguments(Call c, string name, int n, Expr argN) {
name = c.getMethodName() and
argN = c.getArgument(n)

View File

@@ -4,6 +4,9 @@ foo()
# call whose name is a scope resolution
Foo::bar()
# call whose name is a global scope resolution
::bar()
# call with a receiver, no arguments or block
123.bar
@@ -35,55 +38,68 @@ end
# ------------------------------------------------------------------------------
# Calls without parentheses or arguments are parsed by tree-sitter simply as
# `identifier` nodes, so here we test that our AST library correctly represents
# them as calls in all the following contexts.
# `identifier` nodes (or `scope_resolution` nodes whose `name` field is an
# `identifier), so here we test that our AST library correctly represents them
# as calls in all the following contexts.
# root level (child of program)
foo
X::foo
# in a parenthesized statement
(foo)
(X::foo)
# in an argument list
some_func(foo)
some_func(X::foo)
# in an array
[foo]
[X::foo]
# RHS of an assignment
var1 = foo
var1 = X::foo
# RHS an operator assignment
var1 += bar
var1 += X::bar
# RHS assignment list
var1 = foo, bar
var1 = foo, X::bar
# in a begin-end block
begin
foo
X::foo
end
# in a BEGIN block
BEGIN { foo }
BEGIN { foo; X::bar }
# in an END block
END { foo }
END { foo; X::bar }
# both operands of a binary operation
foo + bar
foo + X::bar
# unary operand
!foo
~X::bar
# in a curly brace block
foo() { bar }
foo() { bar; X::baz }
# in a do-end block
foo() do bar end
foo() do
bar
X::baz
end
# the receiver in a call can itself be a call
foo.bar()
bar.baz()
# the value for a case expr
# and the when pattern and body
@@ -91,46 +107,64 @@ case foo
when bar
baz
end
case X::foo
when X::bar
X::baz
end
# in a class definition
class MyClass
foo
X::bar
end
# in a superclass
class MyClass < foo
end
class MyClass2 < X::foo
end
# in a singleton class value or body
class << foo
bar
end
class << X::foo
X::bar
end
# in a method body
def some_method
foo
X::bar
end
# in a singleton method object or body
def foo.some_method
bar
X::baz
end
# in the default value for a keyword parameter
def method_with_keyword_param(keyword: foo)
end
def method_with_keyword_param2(keyword: X::foo)
end
# in the default value for an optional parameter
def method_with_optional_param(param = foo)
end
def method_with_optional_param2(param = X::foo)
end
# in a module
module SomeModule
foo
X::bar
end
# ternary if: condition, consequence, and alternative can all be calls
foo ? bar : baz
X::foo ? X::bar : X::baz
# if/elsif/else conditions and bodies
if foo
@@ -140,74 +174,109 @@ elsif bar
else
wabble
end
if X::foo
X::wibble
elsif X::bar
X::wobble
else
X::wabble
end
# if-modifier condition/body
bar if foo
X::bar if X::foo
# unless condition/body
unless foo
bar
end
unless X::foo
X::bar
end
# unless-modifier condition/body
bar unless foo
X::bar unless X::foo
# while loop condition/body
while foo do
bar
end
while X::foo do
X::bar
end
# while-modifier loop condition/body
bar while foo
X::bar while X::foo
# until loop condition/body
until foo do
bar
end
until X::foo do
X::bar
end
# until-modifier loop condition/body
bar until foo
X::bar until X::foo
# the collection being iterated over in a for loop, and the body
for x in bar
baz
end
for x in X::bar
X::baz
end
# in an array indexing operation, both the object and the index can be calls
foo[bar]
X::foo[X::bar]
# interpolation
"foo-#{bar}"
"foo-#{bar}-#{X::baz}"
# the scope in a scope resolution
foo::Bar
X::foo::Bar
# in a range
foo..bar
X::foo..X::bar
# the key/value in a hash pair
{ foo => bar }
{ foo => bar, X::foo => X::bar }
# rescue exceptions and ensure
begin
rescue foo
ensure bar
end
begin
rescue X::foo
ensure X::bar
end
# rescue-modifier body and handler
foo rescue bar
X::foo rescue X::bar
# block argument
foo(&bar)
foo(&X::bar)
# splat argument
foo(*bar)
foo(*X::bar)
# hash-splat argument
foo(**bar)
foo(**X::bar)
# the value in a keyword argument
foo(blah: bar)
foo(blah: X::bar)
# ------------------------------------------------------------------------------
# calls to `super`

View File

@@ -0,0 +1,20 @@
| 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:6:24:6:27 | Base | read | Base | ConstantReadAccess |
| constants.rb:9:9:10:11 | ClassC | write | ClassC | Class |
| 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 |
| constants.rb:14:1:14:8 | GREETING | write | GREETING | ConstantAssignment |
| 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:7:28:13 | ModuleA | read | ModuleA | ConstantReadAccess |
| constants.rb:31:1:32:3 | ModuleC | write | ModuleC | Module |
| 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 |
| constants.rb:34:1:34:26 | MAX_SIZE | write | MAX_SIZE | ConstantAssignment |

View File

@@ -0,0 +1,8 @@
import ruby
from ConstantAccess a, string kind
where
a instanceof ConstantReadAccess and kind = "read"
or
a instanceof ConstantWriteAccess and kind = "write"
select a, kind, a.getName(), a.getAPrimaryQlClass()

View File

@@ -0,0 +1,34 @@
module ModuleA
class ClassA
end
module ModuleB
class ClassB < Base
end
class ClassC < X::Y::Z
end
end
end
GREETING = 'Hello'
def foo
Names = ['Vera', 'Chuck', 'Dave']
Names.each do |name|
puts "#{ GREETING } #{ name }"
end
# A call to Kernel::Array; despite beginning with an upper-case character,
# we don't consider this to be a constant access.
Array('foo')
end
class ModuleA::ClassD
end
module ModuleA::ModuleC
end
ModuleA::ModuleB::MAX_SIZE = 1024

View File

@@ -5,12 +5,15 @@ classes
| 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 |
classesWithScopeResolutionNames
| classes.rb:16:1:17:3 | MyClass | classes.rb:16:7:16:23 | ...::MyClass |
classesWithNameScopeExprs
| classes.rb:16:1:17:3 | MyClass | classes.rb:16:7:16:14 | MyModule |
classesWithGlobalNameScopeExprs
| classes.rb:55:1:56:3 | MyClassInGlobalScope |
exprsInClasses
| classes.rb:20:1:37:3 | Wibble | 0 | classes.rb:21:3:23:5 | method_a | Method |
| classes.rb:20:1:37:3 | Wibble | 1 | classes.rb:25:3:27:5 | method_b | Method |
@@ -26,4 +29,5 @@ classesInClasses
modulesInClasses
| classes.rb:20:1:37:3 | Wibble | classes.rb:35:3:36:5 | ModuleInWibble | ModuleInWibble |
classesWithASuperclass
| classes.rb:7:1:8:3 | Bar | classes.rb:7:13:7:21 | BaseClass |
| classes.rb:11:1:12:3 | Baz | classes.rb:11:13:11:32 | call to superclass_for |

View File

@@ -4,9 +4,9 @@ query predicate classes(Class c, string pClass, string name) {
pClass = c.getAPrimaryQlClass() and name = c.getName()
}
query predicate classesWithScopeResolutionNames(Class c, ScopeResolution name) {
name = c.getNameScopeResolution()
}
query predicate classesWithNameScopeExprs(Class c, Expr se) { se = c.getScopeExpr() }
query predicate classesWithGlobalNameScopeExprs(Class c) { c.hasGlobalScope() }
query predicate exprsInClasses(Class c, int i, Expr e, string eClass) {
e = c.getExpr(i) and eClass = e.getAPrimaryQlClass()

View File

@@ -49,4 +49,8 @@ class << x
another_method_call
$global_var2 = 456
end
# a class where the name is a scope resolution using the global scope
class ::MyClassInGlobalScope
end

View File

@@ -8,6 +8,7 @@ moduleBases
| 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:4:1:24:3 | Foo | Module |
| modules.rb:5:3:14:5 | Bar | Module |
@@ -18,6 +19,7 @@ moduleBases
| 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 |
moduleBaseClasses
| classes.rb:20:1:37:3 | Wibble | classes.rb:32:3:33:5 | ClassInWibble |
| modules.rb:4:1:24:3 | Foo | modules.rb:19:3:20:5 | ClassInFoo |

View File

@@ -7,8 +7,11 @@ modules
| 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 |
modulesWithScopeResolutionNames
| modules.rb:48:1:57:3 | Bar | modules.rb:48:8:48:15 | ...::Bar |
| modules.rb:60:1:61:3 | MyModuleInGlobalScope | Module | MyModuleInGlobalScope |
modulesWithScopeExprs
| modules.rb:48:1:57:3 | Bar | modules.rb:48:8:48:10 | Foo |
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 | 1 | modules.rb:16:3:17:5 | method_in_foo | Method |

View File

@@ -4,9 +4,9 @@ query predicate modules(Module m, string pClass, string name) {
pClass = m.getAPrimaryQlClass() and name = m.getName()
}
query predicate modulesWithScopeResolutionNames(Module m, ScopeResolution name) {
name = m.getNameScopeResolution()
}
query predicate modulesWithScopeExprs(Module m, Expr se) { se = m.getScopeExpr() }
query predicate modulesWithGlobalNameScopeExprs(Module m) { m.hasGlobalScope() }
query predicate exprsInModules(Module m, int i, Expr e, string eClass) {
e = m.getExpr(i) and eClass = e.getAPrimaryQlClass()

View File

@@ -54,4 +54,8 @@ module Foo::Bar
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

View File

@@ -894,9 +894,9 @@ cfg.rb:
#-----| -> character
# 58| Silly
#-----| -> Silly
#-----| -> (no string representation)
# 58| Silly
# 58| (no string representation)
#-----| -> Object
# 58| Superclass
@@ -1375,9 +1375,9 @@ cfg.rb:
#-----| -> ... > ...
# 115| C
#-----| -> C
#-----| -> (no string representation)
# 115| C
# 115| (no string representation)
#-----| -> 42
# 116| ... = ...
@@ -1426,9 +1426,9 @@ cfg.rb:
#-----| -> Array
# 122| M
#-----| -> M
#-----| -> (no string representation)
# 122| M
# 122| (no string representation)
#-----| -> nil
# 123| ... = ...
@@ -1588,20 +1588,20 @@ cfg.rb:
# 135| 3
#-----| -> init
# 137| ...::Constant
# 137| Constant
#-----| -> M
# 137| M
#-----| -> (no string representation)
# 137| (no string representation)
#-----| -> Constant
# 137| Constant
#-----| -> ...::Constant
# 138| ...::Constant
# 138| Constant
#-----| -> class << ...
# 138| call to itself
#-----| -> Constant
#-----| -> (no string representation)
# 138| M
#-----| -> itself
@@ -1609,8 +1609,8 @@ cfg.rb:
# 138| itself
#-----| -> call to itself
# 138| Constant
#-----| -> ...::Constant
# 138| (no string representation)
#-----| -> Constant
# 140| class << ...
#-----| -> Silly
@@ -2721,9 +2721,9 @@ loops.rb:
raise.rb:
# 1| ExceptionA
#-----| -> ExceptionA
#-----| -> (no string representation)
# 1| ExceptionA
# 1| (no string representation)
#-----| -> Exception
# 1| Superclass
@@ -2733,9 +2733,9 @@ raise.rb:
#-----| -> Superclass
# 4| ExceptionB
#-----| -> ExceptionB
#-----| -> (no string representation)
# 4| ExceptionB
# 4| (no string representation)
#-----| -> Exception
# 4| Superclass