Skip to content

Commit 436f678

Browse files
committed
Speedup ErbDirective::containsStmtStart
1 parent 0d72a51 commit 436f678

File tree

1 file changed

+31
-5
lines changed

1 file changed

+31
-5
lines changed

ql/lib/codeql/ruby/ast/Erb.qll

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,20 +111,46 @@ private predicate locationIncludesPosition(Location loc, int line, int col) {
111111
col <= loc.getEndColumn()
112112
}
113113

114+
/** A file containing an ERB directive. */
115+
private class ErbDirectiveFile extends File {
116+
pragma[nomagic]
117+
ErbDirectiveFile() { this = any(ErbDirective dir).getLocation().getFile() }
118+
119+
/** Gets a statement in this file. */
120+
pragma[nomagic]
121+
Stmt getAStmt(int startLine, int startColumn) {
122+
exists(Location loc |
123+
result.getLocation() = loc and
124+
loc.getFile() = this and
125+
loc.getStartLine() = startLine and
126+
loc.getStartColumn() = startColumn
127+
)
128+
}
129+
}
130+
114131
/**
115132
* A directive in an ERB template.
116133
*/
117134
class ErbDirective extends TDirectiveNode, ErbAstNode {
118-
private predicate containsStartOf(Location loc) {
119-
loc.getFile() = this.getLocation().getFile() and
120-
locationIncludesPosition(this.getLocation(), loc.getStartLine(), loc.getStartColumn())
135+
/** Holds if this directive spans line `line` in the file `file`. */
136+
pragma[nomagic]
137+
private predicate spans(ErbDirectiveFile file, int line) {
138+
exists(Location loc |
139+
loc = this.getLocation() and
140+
file = loc.getFile() and
141+
line in [loc.getStartLine() .. loc.getEndLine()]
142+
)
121143
}
122144

123145
private predicate containsStmtStart(Stmt s) {
124-
this.containsStartOf(s.getLocation()) and
125146
// `Toplevel` statements are not contained within individual directives,
126147
// though their start location may appear within a directive location
127-
not s instanceof Toplevel
148+
not s instanceof Toplevel and
149+
exists(ErbDirectiveFile file, int startLine, int startColumn |
150+
this.spans(file, startLine) and
151+
s = file.getAStmt(startLine, startColumn) and
152+
locationIncludesPosition(this.getLocation(), startLine, startColumn)
153+
)
128154
}
129155

130156
/**

0 commit comments

Comments
 (0)