mirror of
https://github.com/github/codeql.git
synced 2026-02-20 08:53:49 +01:00
AST: introduce 'Namespace' as super class of Class/Module
This commit is contained in:
@@ -53,6 +53,76 @@ class Toplevel extends ModuleBase, @program {
|
||||
final BeginBlock getABeginBlock() { result = getBeginBlock(_) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A class or method definition.
|
||||
*
|
||||
* ```rb
|
||||
* class Foo
|
||||
* def bar
|
||||
* end
|
||||
* end
|
||||
* module Bar
|
||||
* class Baz
|
||||
* end
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
class Namespace extends ModuleBase, ConstantWriteAccess {
|
||||
override Namespace::Range range;
|
||||
|
||||
override string getAPrimaryQlClass() { result = "Namespace" }
|
||||
|
||||
/**
|
||||
* Gets the name of the module/class. In the following example, the result is
|
||||
* `"Foo"`.
|
||||
* ```rb
|
||||
* class Foo
|
||||
* end
|
||||
* ```
|
||||
*
|
||||
* N.B. in the following example, where the module/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
|
||||
* module Foo::Bar
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
override string getName() { result = range.getName() }
|
||||
|
||||
/**
|
||||
* Gets the scope expression used in the module/class name's scope resolution
|
||||
* operation, if any.
|
||||
*
|
||||
* In the following example, the result is the `Expr` for `Foo`.
|
||||
*
|
||||
* ```rb
|
||||
* module Foo::Bar
|
||||
* end
|
||||
* ```
|
||||
*
|
||||
* However, there is no result for the following example, since there is no
|
||||
* scope resolution operation.
|
||||
*
|
||||
* ```rb
|
||||
* module Baz
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
override Expr getScopeExpr() { result = range.getScopeExpr() }
|
||||
|
||||
/**
|
||||
* Holds if the module/class name uses the scope resolution operator to access the
|
||||
* global scope, as in this example:
|
||||
*
|
||||
* ```rb
|
||||
* class ::Foo
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
override predicate hasGlobalScope() { range.hasGlobalScope() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A class definition.
|
||||
*
|
||||
@@ -63,61 +133,11 @@ class Toplevel extends ModuleBase, @program {
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
class Class extends ModuleBase, ConstantWriteAccess {
|
||||
class Class extends Namespace, @class {
|
||||
final override Class::Range range;
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "Class" }
|
||||
|
||||
/**
|
||||
* Gets the name of the class. In the following example, the result is
|
||||
* `"Foo"`.
|
||||
* ```rb
|
||||
* class Foo
|
||||
* end
|
||||
* ```
|
||||
*
|
||||
* 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 override string getName() { result = range.getName() }
|
||||
|
||||
/**
|
||||
* 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
|
||||
* ```
|
||||
*
|
||||
* However, there is no result for the following example, since there is no
|
||||
* scope resolution operation.
|
||||
*
|
||||
* ```rb
|
||||
* class Baz
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
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.
|
||||
*
|
||||
@@ -190,58 +210,8 @@ class SingletonClass extends ModuleBase, @singleton_class {
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
class Module extends ModuleBase, ConstantWriteAccess, @module {
|
||||
class Module extends Namespace, @module {
|
||||
final override Module::Range range;
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "Module" }
|
||||
|
||||
/**
|
||||
* Gets the name of the module. In the following example, the result is
|
||||
* `"Foo"`.
|
||||
* ```rb
|
||||
* module Foo
|
||||
* end
|
||||
* ```
|
||||
*
|
||||
* 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 override string getName() { result = range.getName() }
|
||||
|
||||
/**
|
||||
* 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
|
||||
* ```
|
||||
*
|
||||
* However, there is no result for the following example, since there is no
|
||||
* scope resolution operation.
|
||||
*
|
||||
* ```rb
|
||||
* module Baz
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
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
|
||||
* module ::Foo
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
final override predicate hasGlobalScope() { range.hasGlobalScope() }
|
||||
}
|
||||
|
||||
@@ -8,6 +8,17 @@ module ModuleBase {
|
||||
abstract class Range extends BodyStatement::Range { }
|
||||
}
|
||||
|
||||
module Namespace {
|
||||
abstract class Range extends ModuleBase::Range, ConstantWriteAccess::Range {
|
||||
override predicate child(string label, AstNode::Range child) {
|
||||
ModuleBase::Range.super.child(label, child) or
|
||||
ConstantWriteAccess::Range.super.child(label, child)
|
||||
}
|
||||
|
||||
override string toString() { result = ModuleBase::Range.super.toString() }
|
||||
}
|
||||
}
|
||||
|
||||
module Toplevel {
|
||||
class Range extends ModuleBase::Range, @program {
|
||||
final override Generated::Program generated;
|
||||
@@ -34,7 +45,7 @@ module Toplevel {
|
||||
}
|
||||
|
||||
module Class {
|
||||
class Range extends ModuleBase::Range, ConstantWriteAccess::Range, @class {
|
||||
class Range extends Namespace::Range, @class {
|
||||
final override Generated::Class generated;
|
||||
|
||||
final override Generated::AstNode getChild(int i) { result = generated.getChild(i) }
|
||||
@@ -61,9 +72,7 @@ module Class {
|
||||
final override string toString() { result = this.getName() }
|
||||
|
||||
override predicate child(string label, AstNode::Range child) {
|
||||
ModuleBase::Range.super.child(label, child)
|
||||
or
|
||||
ConstantWriteAccess::Range.super.child(label, child)
|
||||
Namespace::Range.super.child(label, child)
|
||||
or
|
||||
label = "getSuperclassExpr" and child = getSuperclassExpr()
|
||||
}
|
||||
@@ -89,7 +98,7 @@ module SingletonClass {
|
||||
}
|
||||
|
||||
module Module {
|
||||
class Range extends ModuleBase::Range, ConstantWriteAccess::Range, @module {
|
||||
class Range extends Namespace::Range, @module {
|
||||
final override Generated::Module generated;
|
||||
|
||||
final override Generated::AstNode getChild(int i) { result = generated.getChild(i) }
|
||||
@@ -114,9 +123,7 @@ module Module {
|
||||
final override string toString() { result = this.getName() }
|
||||
|
||||
override predicate child(string label, AstNode::Range child) {
|
||||
ModuleBase::Range.super.child(label, child)
|
||||
or
|
||||
ConstantWriteAccess::Range.super.child(label, child)
|
||||
Namespace::Range.super.child(label, child)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user