Skip to content

Commit a247544

Browse files
committed
Add comments
1 parent 7bc5be9 commit a247544

2 files changed

Lines changed: 48 additions & 19 deletions

File tree

ql/src/codeql_ruby/ast/Module.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class Module extends TModule {
2525
result =
2626
min(Namespace n, string qName, Location loc, int weight |
2727
this = TResolved(qName) and
28-
qName = constantDefinition(n) and
28+
qName = namespaceDeclaration(n) and
2929
loc = n.getLocation() and
3030
if exists(loc.getFile().getRelativePath()) then weight = 0 else weight = 1
3131
|
@@ -174,7 +174,7 @@ class Namespace extends ModuleBase, ConstantWriteAccess, TNamespace {
174174
override predicate hasGlobalScope() { none() }
175175

176176
final override Module getModule() {
177-
result = any(string qName | qName = constantDefinition(this) | TResolved(qName))
177+
result = any(string qName | qName = namespaceDeclaration(this) | TResolved(qName))
178178
or
179179
result = TUnresolved(this)
180180
}

ql/src/codeql_ruby/ast/internal/Module.qll

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,22 @@ module Cached {
1616
TResolved(string qName) {
1717
qName = builtin()
1818
or
19-
qName = constantDefinition(_)
19+
qName = namespaceDeclaration(_)
2020
} or
21-
TUnresolved(Namespace n) { not exists(constantDefinition(n)) }
21+
TUnresolved(Namespace n) { not exists(namespaceDeclaration(n)) }
2222

2323
cached
24-
string constantDefinition(ConstantWriteAccess n) {
24+
string namespaceDeclaration(Namespace n) {
2525
isToplevel(n) and result = n.getName()
2626
or
2727
not isToplevel(n) and
2828
not exists(n.getScopeExpr()) and
29-
result = scopeAppend(constantDefinition(n.getEnclosingModule()), n.getName())
29+
result = scopeAppend(namespaceDeclaration(n.getEnclosingModule()), n.getName())
3030
or
31-
result = scopeAppend(resolveScopeExpr(n.getScopeExpr()), n.getName())
31+
exists(string container |
32+
TResolved(container) = resolveScopeExpr(n.getScopeExpr()) and
33+
result = scopeAppend(container, n.getName())
34+
)
3235
}
3336
}
3437

@@ -48,36 +51,47 @@ private predicate isDefinedConstant(string qualifiedModuleName) {
4851
}
4952

5053
/**
51-
* Resolve a scope expression
54+
* Resolve constant read access (typically a scope expression) to a qualified module name.
55+
* `resolveScopeExpr/1` picks the best (lowest priority number) result of
56+
* `resolveScopeExpr/2` that resolves to a constant definition. If the constant
57+
* definition is a Namespace then it is returned, if it's a constant assignment then
58+
* the right-hand side of the assignment is resolved.
5259
*/
53-
private string resolveScopeExpr(ConstantReadAccess r) {
54-
exists(string container |
55-
container =
56-
min(string c, int p |
57-
isDefinedConstant(c) and
58-
c = resolveScopeExpr(r, p)
60+
private TResolved resolveScopeExpr(ConstantReadAccess r) {
61+
exists(string qname |
62+
qname =
63+
min(string qn, int p |
64+
isDefinedConstant(qn) and
65+
qn = resolveScopeExpr(r, p)
5966
|
60-
c order by p
67+
qn order by p
6168
)
6269
|
63-
result = container and
64-
container = [builtin(), constantDefinition(any(Namespace x))]
70+
result = TResolved(qname)
6571
or
6672
exists(ConstantAssignment a |
67-
container = constantDefinition(a) and
73+
qname = constantDefinition0(a) and
6874
result = resolveScopeExpr(a.getParent().(Assignment).getRightOperand())
6975
)
7076
)
7177
}
7278

73-
private int maxDepth() { result = max(ConstantAccess c | | count(c.getEnclosingModule+())) }
79+
private int maxDepth() { result = 1 + max(int level | exists(enclosing(_, level))) }
7480

7581
private ModuleBase enclosing(ModuleBase m, int level) {
7682
result = m and level = 0
7783
or
7884
result = enclosing(m.getEnclosingModule(), level - 1)
7985
}
8086

87+
/**
88+
* Resolve constant read access (typically a scope expression) to a qualified name. The
89+
* `priority` value indicates the precedence of the solution with respect to the lookup order.
90+
* A constant name without scope specifier is resolved against its enclosing modules (inner-most first);
91+
* if the constant is not found in any of the enclosing modules, then the constant will be resolved
92+
* with respect to the ancestors (prepends, includes, super classes, and their ancestors) of the
93+
* directly enclosing module.
94+
*/
8195
private string resolveScopeExpr(ConstantReadAccess c, int priority) {
8296
c.hasGlobalScope() and result = c.getName() and priority = 0
8397
or
@@ -110,6 +124,12 @@ private string qualifiedModuleName(ModuleBase m) {
110124
result = constantDefinition0(m)
111125
}
112126

127+
/**
128+
* Get a qualified name for a constant definition. May return multiple qualified
129+
* names because we over-approximate when resolving scope resolutions and ignore
130+
* lookup order precedence. Taking lookup order into account here would lead to
131+
* non-monotonic recursion.
132+
*/
113133
private string constantDefinition0(ConstantWriteAccess c) {
114134
c.hasGlobalScope() and result = c.getName()
115135
or
@@ -122,6 +142,15 @@ private string constantDefinition0(ConstantWriteAccess c) {
122142
)
123143
}
124144

145+
/**
146+
* The qualified names of the ancestors of a class/module. The ancestors should be an ordered list
147+
* of the ancestores of `prepend`ed modules, the module itself , the ancestors or `include`d modules
148+
* and the ancestors of the super class. The priority value only distinguishes the kind of ancestor,
149+
* it does not order the ancestors within a group of the same kind. This is an over-approximation, however,
150+
* computing the precise order is tricky because it depends on the evaluation/file loading order.
151+
*/
152+
// TODO: the order of super classes can be determined more precisely even without knowing the evaluation
153+
// order, so we should be able to make this more precise.
125154
private string ancestors(string qname, int priority) {
126155
result = ancestors(prepends(qname), _) and priority = 0
127156
or

0 commit comments

Comments
 (0)