Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fe0a494

Browse files
committed
Extract line directives
1 parent 4bb8b6c commit fe0a494

8 files changed

Lines changed: 155 additions & 2 deletions

File tree

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using Microsoft.CodeAnalysis;
2+
using Microsoft.CodeAnalysis.CSharp;
3+
using Microsoft.CodeAnalysis.CSharp.Syntax;
4+
using System.IO;
5+
6+
namespace Semmle.Extraction.CSharp.Entities
7+
{
8+
internal class LineDirective : PreprocessorDirective<LineDirectiveTriviaSyntax>
9+
{
10+
public LineDirective(Context cx, LineDirectiveTriviaSyntax trivia)
11+
: base(cx, trivia)
12+
{
13+
}
14+
15+
protected override void PopulatePreprocessor(TextWriter trapFile)
16+
{
17+
var type = trivia.Line.Kind() switch
18+
{
19+
SyntaxKind.DefaultKeyword => 0,
20+
SyntaxKind.HiddenKeyword => 1,
21+
SyntaxKind.NumericLiteralToken => 2,
22+
_ => throw new InternalError(trivia, "Unhandled line token kind")
23+
};
24+
25+
trapFile.directive_lines(this, type);
26+
27+
if (trivia.Line.IsKind(SyntaxKind.NumericLiteralToken))
28+
{
29+
var value = (int)trivia.Line.Value;
30+
trapFile.directive_line_values(this, value, trivia.File.ValueText);
31+
}
32+
}
33+
}
34+
}

csharp/extractor/Semmle.Extraction.CSharp/Populators/DirectiveVisitor.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,10 @@ public override void VisitNullableDirectiveTrivia(NullableDirectiveTriviaSyntax
4747
{
4848
new Entities.NullableDirective(cx, node);
4949
}
50+
51+
public override void VisitLineDirectiveTrivia(LineDirectiveTriviaSyntax node)
52+
{
53+
new Entities.LineDirective(cx, node);
54+
}
5055
}
5156
}

csharp/extractor/Semmle.Extraction.CSharp/Tuples.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,5 +645,15 @@ internal static void directive_nullables(this TextWriter trapFile, NullableDirec
645645
{
646646
trapFile.WriteTuple("directive_nullables", directive, setting, target);
647647
}
648+
649+
internal static void directive_lines(this TextWriter trapFile, LineDirective directive, int kind)
650+
{
651+
trapFile.WriteTuple("directive_lines", directive, kind);
652+
}
653+
654+
internal static void directive_line_values(this TextWriter trapFile, LineDirective directive, int line, string file)
655+
{
656+
trapFile.WriteTuple("directive_line_values", directive, line, file);
657+
}
648658
}
649659
}

csharp/ql/src/semmle/code/csharp/Preprocessor.qll

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,3 +140,72 @@ class NullableDirective extends PreprocessorDirective, @directive_nullable {
140140

141141
override string getAPrimaryQlClass() { result = "NullableDirective" }
142142
}
143+
144+
/**
145+
* A `#line` directive, such as `#line default`, `#line hidden`, or `#line`
146+
* directive with line number.
147+
*/
148+
class LineDirective extends PreprocessorDirective, @directive_line {
149+
/** Gets the succeeding `#line` directive in the file, if any. */
150+
LineDirective getSuccLineDirective() {
151+
result =
152+
rank[1](LineDirective next |
153+
next.getFile() = this.getFile() and
154+
next.getLocation().getStartLine() > this.getLocation().getStartLine()
155+
|
156+
next order by next.getLocation().getStartLine()
157+
)
158+
}
159+
160+
/** Holds if there is a succeeding `#line` directive in the file. */
161+
predicate hasSuccLineDirective() {
162+
exists(LineDirective other |
163+
other.getFile() = this.getFile() and
164+
other.getLocation().getStartLine() > this.getLocation().getStartLine()
165+
)
166+
}
167+
168+
override string toString() { result = "#line ..." }
169+
170+
override string getAPrimaryQlClass() { result = "LineDirective" }
171+
}
172+
173+
/**
174+
* A `#line default` directive.
175+
*/
176+
class DefaultLineDirective extends LineDirective {
177+
DefaultLineDirective() { directive_lines(this, 0) }
178+
179+
override string toString() { result = "#line default" }
180+
181+
override string getAPrimaryQlClass() { result = "DefaultLineDirective" }
182+
}
183+
184+
/**
185+
* A `#line hidden` directive.
186+
*/
187+
class HiddenLineDirective extends LineDirective {
188+
HiddenLineDirective() { directive_lines(this, 1) }
189+
190+
override string toString() { result = "#line hidden" }
191+
192+
override string getAPrimaryQlClass() { result = "HiddenLineDirective" }
193+
}
194+
195+
/**
196+
* A numeric `#line` directive, such as `#line 200 file`
197+
*/
198+
class NumericLineDirective extends LineDirective {
199+
NumericLineDirective() { directive_lines(this, 2) }
200+
201+
/** Gets the line number of this directive. */
202+
int getLine() { directive_line_values(this, result, _) }
203+
204+
/** Holds if this directive specifies a file name. */
205+
predicate hasFileName() { this.getFileName() != "" }
206+
207+
/** Gets the file name of this directive. */
208+
string getFileName() { directive_line_values(this, _, result) }
209+
210+
override string getAPrimaryQlClass() { result = "NumericLineDirective" }
211+
}

csharp/ql/src/semmlecode.csharp.dbscheme

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,16 @@ using_directive_location(
332332
int loc: @location ref);
333333

334334
@preprocessor_directive = @pragma_warning | @pragma_checksum | @directive_define | @directive_undefine | @directive_warning
335-
| @directive_error | @directive_nullable;
335+
| @directive_error | @directive_nullable | @directive_line;
336+
337+
directive_lines(
338+
unique int id: @directive_line,
339+
int kind: int ref); /* 0: default, 1: hidden, 2: numeric */
340+
341+
directive_line_values(
342+
unique int id: @directive_line ref,
343+
int line: int ref,
344+
string file: string ref);
336345

337346
directive_nullables(
338347
unique int id: @directive_nullable,
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
default
2+
| trivia.cs:21:1:21:13 | #line default |
3+
hidden
4+
| trivia.cs:25:1:25:38 | #line hidden |
5+
lines
6+
| trivia.cs:18:1:18:19 | #line ... | 200 | Special |
7+
| trivia.cs:27:1:27:9 | #line ... | 300 | |
8+
succ
9+
| trivia.cs:18:1:18:19 | #line ... | trivia.cs:21:1:21:13 | #line default |
10+
| trivia.cs:21:1:21:13 | #line default | trivia.cs:25:1:25:38 | #line hidden |
11+
| trivia.cs:25:1:25:38 | #line hidden | trivia.cs:27:1:27:9 | #line ... |
12+
last
13+
| trivia.cs:27:1:27:9 | #line ... |
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import csharp
2+
3+
query predicate default(DefaultLineDirective line) { any() }
4+
5+
query predicate hidden(HiddenLineDirective line) { any() }
6+
7+
query predicate lines(NumericLineDirective line, int l, string file) {
8+
line.getLine() = l and line.getFileName() = file
9+
}
10+
11+
query predicate succ(LineDirective d, LineDirective succ) { d.getSuccLineDirective() = succ }
12+
13+
query predicate last(LineDirective d) { not d.hasSuccLineDirective() }

csharp/ql/test/library-tests/comments/trivia.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ static void M1()
2424
float f;
2525
#line hidden // numbering not affected
2626
string s;
27-
#line default
27+
#line 300
2828
double d;
2929
}
3030
}

0 commit comments

Comments
 (0)