mirror of
https://github.com/github/codeql.git
synced 2026-05-01 03:35:13 +02:00
Extract region directives
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
internal class EndRegionDirective : PreprocessorDirective<EndRegionDirectiveTriviaSyntax>
|
||||
{
|
||||
public EndRegionDirective(Context cx, EndRegionDirectiveTriviaSyntax trivia)
|
||||
: base(cx, trivia)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void PopulatePreprocessor(TextWriter trapFile)
|
||||
{
|
||||
trapFile.directive_endregions(this);
|
||||
}
|
||||
|
||||
internal static void WriteRegionBlock(Context cx, RegionDirective region, EndRegionDirective endregion)
|
||||
{
|
||||
cx.TrapWriter.Writer.regions(region, endregion);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
internal class RegionDirective : PreprocessorDirective<RegionDirectiveTriviaSyntax>
|
||||
{
|
||||
public RegionDirective(Context cx, RegionDirectiveTriviaSyntax trivia)
|
||||
: base(cx, trivia)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void PopulatePreprocessor(TextWriter trapFile)
|
||||
{
|
||||
trapFile.directive_regions(this, trivia.EndOfDirectiveToken.LeadingTrivia.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
@@ -52,5 +54,26 @@ namespace Semmle.Extraction.CSharp.Populators
|
||||
{
|
||||
new Entities.LineDirective(cx, node);
|
||||
}
|
||||
|
||||
private readonly Stack<Entities.RegionDirective> regionStarts = new Stack<Entities.RegionDirective>();
|
||||
|
||||
public override void VisitRegionDirectiveTrivia(RegionDirectiveTriviaSyntax node)
|
||||
{
|
||||
var region = new Entities.RegionDirective(cx, node);
|
||||
regionStarts.Push(region);
|
||||
}
|
||||
|
||||
public override void VisitEndRegionDirectiveTrivia(EndRegionDirectiveTriviaSyntax node)
|
||||
{
|
||||
var endregion = new Entities.EndRegionDirective(cx, node);
|
||||
if (regionStarts.Count == 0)
|
||||
{
|
||||
cx.ExtractionError("Couldn't find start region", null,
|
||||
Extraction.Entities.Location.Create(cx, node.GetLocation()), null, Util.Logging.Severity.Warning);
|
||||
return;
|
||||
}
|
||||
var start = regionStarts.Pop();
|
||||
Entities.EndRegionDirective.WriteRegionBlock(cx, start, endregion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -655,5 +655,20 @@ namespace Semmle.Extraction.CSharp
|
||||
{
|
||||
trapFile.WriteTuple("directive_line_values", directive, line, file);
|
||||
}
|
||||
|
||||
internal static void directive_regions(this TextWriter trapFile, RegionDirective directive, string name)
|
||||
{
|
||||
trapFile.WriteTuple("directive_regions", directive, name);
|
||||
}
|
||||
|
||||
internal static void directive_endregions(this TextWriter trapFile, EndRegionDirective directive)
|
||||
{
|
||||
trapFile.WriteTuple("directive_endregions", directive);
|
||||
}
|
||||
|
||||
internal static void regions(this TextWriter trapFile, RegionDirective start, EndRegionDirective end)
|
||||
{
|
||||
trapFile.WriteTuple("regions", start, end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,3 +209,30 @@ class NumericLineDirective extends LineDirective {
|
||||
|
||||
override string getAPrimaryQlClass() { result = "NumericLineDirective" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `#region` directive.
|
||||
*/
|
||||
class RegionDirective extends PreprocessorDirective, @directive_region {
|
||||
/** Gets the name of this region. */
|
||||
string getName() { directive_regions(this, result) }
|
||||
|
||||
/** Gets the closing `#endregion` directive. */
|
||||
EndRegionDirective getEnd() { regions(this, result) }
|
||||
|
||||
override string toString() { result = "#region ..." }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "RegionDirective" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `#endregion` directive.
|
||||
*/
|
||||
class EndRegionDirective extends PreprocessorDirective, @directive_endregion {
|
||||
/** Gets the opening `#region` directive. */
|
||||
RegionDirective getStart() { regions(result, this) }
|
||||
|
||||
override string toString() { result = "#endregion" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "EndRegionDirective" }
|
||||
}
|
||||
|
||||
@@ -332,7 +332,19 @@ using_directive_location(
|
||||
int loc: @location ref);
|
||||
|
||||
@preprocessor_directive = @pragma_warning | @pragma_checksum | @directive_define | @directive_undefine | @directive_warning
|
||||
| @directive_error | @directive_nullable | @directive_line;
|
||||
| @directive_error | @directive_nullable | @directive_line | @directive_region | @directive_endregion;
|
||||
|
||||
directive_regions(
|
||||
unique int id: @directive_region,
|
||||
string name: string ref);
|
||||
|
||||
directive_endregions(
|
||||
unique int id: @directive_endregion);
|
||||
|
||||
#keyset[start, end]
|
||||
regions(
|
||||
unique int start: @directive_region ref,
|
||||
unique int end: @directive_endregion ref);
|
||||
|
||||
directive_lines(
|
||||
unique int id: @directive_line,
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
regionDirectives
|
||||
| trivia.cs:36:9:36:22 | #region ... | fields | trivia.cs:41:9:41:18 | #endregion |
|
||||
| trivia.cs:38:9:38:22 | #region ... | nested | trivia.cs:40:9:40:18 | #endregion |
|
||||
endregions
|
||||
| trivia.cs:40:9:40:18 | #endregion | trivia.cs:38:9:38:22 | #region ... |
|
||||
| trivia.cs:41:9:41:18 | #endregion | trivia.cs:36:9:36:22 | #region ... |
|
||||
@@ -0,0 +1,8 @@
|
||||
import csharp
|
||||
|
||||
query predicate regionDirectives(RegionDirective d, string name, EndRegionDirective end) {
|
||||
d.getName() = name and
|
||||
d.getEnd() = end
|
||||
}
|
||||
|
||||
query predicate endregions(EndRegionDirective d, RegionDirective start) { d.getStart() = start }
|
||||
Reference in New Issue
Block a user