forked from github/codeql
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCommentedOutCode.qll
More file actions
134 lines (119 loc) · 4.85 KB
/
CommentedOutCode.qll
File metadata and controls
134 lines (119 loc) · 4.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import cpp
/**
* Holds if `line` looks like a line of code.
* Matches comment lines ending with '{', '}' or ';' that do not start with '>' or contain '@{' or '@}', but first filters out:
* * HTML entities in common notation (e.g. > and é)
* * HTML entities in decimal notation (e.g. à)
* * HTML entities in hexadecimal notation (e.g. 灟)
* To account for the code generated by protobuf, we also insist that the comment
* does not begin with `optional` or `repeated` and end with a `;`, which would
* normally be a quoted bit of literal `.proto` specification above the associated
* declaration.
* To account for emacs folding markers, we ignore any line containing
* `{{{` or `}}}`.
*
* Finally, some code tends to embed GUIDs in comments, so we also exclude those.
*/
bindingset[line]
private predicate looksLikeCode(string line) {
exists(string trimmed |
trimmed = line.regexpReplaceAll("(?i)(^\\s+|&#?[a-z0-9]{1,31};|\\s+$)", "") |
trimmed.regexpMatch(".*[{};]")
and not trimmed.regexpMatch("(>.*|.*[\\\\@][{}].*|(optional|repeated) .*;|.*(\\{\\{\\{|\\}\\}\\}).*|\\{[-0-9a-zA-Z]+\\})"))
}
/**
* The line of a C++-style comment within its file `f`.
*/
private int lineInFile(CppStyleComment c, File f) {
f = c.getFile() and
result = c.getLocation().getStartLine()
}
/**
* The "comment block ID" for a comment line in a file.
* The block ID is obtained by subtracting the line rank of the line from
* the line itself, where the line rank is the (1-based) rank within `f`
* of lines containing a C++-style comment. As a result, line comments on
* consecutive lines are assigned the same block ID (as both line number
* and line rank increase by 1 for each line), while intervening lines
* without line comments would increase the line number without increasing
* the rank and thus force a change of block ID.
*/
private pragma[nomagic] int commentLineBlockID(File f, int line) {
exists(int lineRank |
line = rank[lineRank](lineInFile(_, f)) and
result = line - lineRank
)
}
/**
* The comment ID of the given comment (on line `line` of file `f`).
* The resulting number is meaningless, except that it will be the same
* for all comments in a run of consecutive comment lines, and different
* for separate runs.
*/
private int commentId(CppStyleComment c, File f, int line) {
result = commentLineBlockID(f, line) and
line = lineInFile(c, f)
}
/**
* A contiguous block of comments.
*/
class CommentBlock extends Comment {
CommentBlock() {
this instanceof CppStyleComment implies
not exists(CppStyleComment pred, File f | lineInFile(pred, f) + 1 = lineInFile(this, f))
}
/**
* Gets the `i`th comment associated with this comment block.
*/
Comment getComment(int i) {
(i = 0 and result = this) or
exists(File f, int thisLine, int resultLine |
commentId(this, f, thisLine) = commentId(result, f, resultLine) |
i = resultLine - thisLine
)
}
Comment lastComment() {
result = this.getComment(max(int i | exists(this.getComment(i))))
}
string getLine(int i) {
this instanceof CStyleComment and result = this.getContents().regexpCapture("(?s)/\\*+(.*)\\*+/", 1).splitAt("\n", i)
or
this instanceof CppStyleComment and result = this.getComment(i).getContents().suffix(2)
}
int numLines() {
result = strictcount(int i, string line | line = this.getLine(i) and line.trim() != "")
}
int numCodeLines() {
result = strictcount(int i, string line | line = this.getLine(i) and looksLikeCode(line))
}
predicate isDocumentation() {
// If a C-style comment starts each line with a *, then it's
// probably documentation rather than code.
this instanceof CStyleComment and
forex(int i | i in [1 .. this.numLines() - 1]
| this.getLine(i).trim().matches("*%"))
}
predicate isCommentedOutCode() {
not this.isDocumentation() and
this.numCodeLines().(float) / this.numLines().(float) > 0.5
}
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [LGTM locations](https://lgtm.com/help/ql/locations).
*/
predicate hasLocationInfo(string filepath, int startline, int startcolumn, int endline, int endcolumn) {
this.getLocation().hasLocationInfo(filepath, startline, startcolumn, _, _) and
this.lastComment().getLocation().hasLocationInfo(_, _, _, endline, endcolumn)
}
}
/**
* A piece of commented-out code, identified using heuristics
*/
class CommentedOutCode extends CommentBlock {
CommentedOutCode() {
this.isCommentedOutCode()
}
}