|
6 | 6 | * To add this framework to a new language, add a new file |
7 | 7 | * (usually called `InlineExpectationsTest.qll`) with: |
8 | 8 | * - `private import codeql.util.test.InlineExpectationsTest` (this file) |
9 | | - * - An implementation of the class signature in `ExpectationCommentSig`. |
10 | | - * This class can e.g. be called `ExpectationComment`. |
| 9 | + * - An implementation of the signature in `InlineExpectationsTestSig`. |
| 10 | + * Usually this is done in a mdule called `Impl`. |
| 11 | + * `Impl` has to define a `Location` class, and an `ExpectationComment` class. |
11 | 12 | * The `ExpectationComment` class must support a `getContents` method that returns |
12 | 13 | * the contents of the given comment, _excluding_ the comment indicator itself. |
13 | | - * It should also define `toString` and `hasLocationInfo` as usual. |
14 | | - * - `import Make<ExpectationComment>` to expose the query predicates constructed in the `Make` module. |
| 14 | + * It should also define `toString` and `getLocation` as usual. |
| 15 | + * - `import Make<Impl>` to expose the query predicates constructed in the `Make` module. |
15 | 16 | * |
16 | 17 | * To create a new inline expectations test: |
17 | 18 | * - Declare a class that extends `InlineExpectationsTest`. In the characteristic predicate of the |
|
95 | 96 | * `tag1=expected-value tag2=expected-value` |
96 | 97 | */ |
97 | 98 |
|
98 | | -/** A comment that may contain inline expectations. */ |
99 | | -signature class ExpectationCommentSig { |
100 | | - /** Gets the contents of this comment, _excluding_ the comment indicator. */ |
101 | | - string getContents(); |
102 | | - |
103 | | - /** Gets a textual representation of this element. */ |
104 | | - string toString(); |
105 | | - |
106 | | - predicate hasLocationInfo( |
107 | | - string filename, int startLine, int startColumn, int endLine, int endColumn |
108 | | - ); |
109 | | -} |
110 | | - |
111 | 99 | /** |
112 | | - * Classes and predicates implementing inline expectations. |
| 100 | + * A signature specifying the required parts for |
| 101 | + * constructing inline expectations. |
113 | 102 | */ |
114 | | -module Make<ExpectationCommentSig ExpectationComment> { |
115 | | - private newtype TTLocation = |
116 | | - TLocation(string filename, int startLine, int startColumn, int endLine, int endColumn) { |
117 | | - any(ExpectationComment c) |
118 | | - .hasLocationInfo(filename, startLine, startColumn, endLine, endColumn) |
119 | | - } |
120 | | - |
121 | | - private class Location extends TLocation { |
122 | | - string filename; |
123 | | - int startLine; |
124 | | - int startColumn; |
125 | | - int endLine; |
126 | | - int endColumn; |
127 | | - |
128 | | - Location() { this = TLocation(filename, startLine, startColumn, endLine, endColumn) } |
129 | | - |
130 | | - string getFilename() { result = filename } |
131 | | - |
132 | | - int getStartLine() { result = startLine } |
133 | | - |
134 | | - int getStartColumn() { result = startColumn } |
135 | | - |
136 | | - int getEndLine() { result = endLine } |
| 103 | +signature module InlineExpectationsTestSig { |
| 104 | + /** The location of an element in the source code. */ |
| 105 | + class Location { |
| 106 | + predicate hasLocationInfo( |
| 107 | + string filename, int startLine, int startColumn, int endLine, int endColumn |
| 108 | + ); |
| 109 | + } |
137 | 110 |
|
138 | | - int getEndColumn() { result = endColumn } |
| 111 | + /** A comment that may contain inline expectations. */ |
| 112 | + class ExpectationComment { |
| 113 | + /** Gets the contents of this comment, _excluding_ the comment indicator. */ |
| 114 | + string getContents(); |
139 | 115 |
|
140 | | - string toString() { |
141 | | - result = filename + ":" + startLine + ":" + startColumn + "-" + endLine + ":" + endColumn |
142 | | - } |
| 116 | + /** Gets the location of this comment. */ |
| 117 | + Location getLocation(); |
143 | 118 |
|
144 | | - predicate hasLocationInfo(string f, int sl, int sc, int el, int ec) { |
145 | | - f = filename and |
146 | | - sl = startLine and |
147 | | - sc = startColumn and |
148 | | - el = endLine and |
149 | | - ec = endColumn |
150 | | - } |
| 119 | + /** Gets a textual representation of this element. */ |
| 120 | + string toString(); |
151 | 121 | } |
| 122 | +} |
152 | 123 |
|
153 | | - private Location getLocation(ExpectationComment c) { |
154 | | - exists(string filename, int startLine, int startColumn, int endLine, int endColumn | |
155 | | - c.hasLocationInfo(filename, startLine, startColumn, endLine, endColumn) and |
156 | | - result = TLocation(filename, startLine, startColumn, endLine, endColumn) |
157 | | - ) |
158 | | - } |
| 124 | +/** |
| 125 | + * Classes and predicates implementing inline expectations. |
| 126 | + */ |
| 127 | +module Make<InlineExpectationsTestSig Impl> { |
| 128 | + private import Impl |
159 | 129 |
|
160 | 130 | /** |
161 | 131 | * The base class for tests with inline expectations. The test extends this class to provide the actual |
@@ -402,7 +372,7 @@ module Make<ExpectationCommentSig ExpectationComment> { |
402 | 372 |
|
403 | 373 | override string toString() { result = comment.toString() } |
404 | 374 |
|
405 | | - override Location getLocation() { result = getLocation(comment) } |
| 375 | + override Location getLocation() { result = comment.getLocation() } |
406 | 376 | } |
407 | 377 |
|
408 | 378 | private predicate onSameLine(ValidExpectation a, ActualResult b) { |
|
0 commit comments