mirror of
https://github.com/github/codeql.git
synced 2026-04-28 18:25:24 +02:00
Rework if/elif/else/endif extraction
This commit is contained in:
@@ -5,16 +5,22 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
internal class ElifDirective : PreprocessorDirective<ElifDirectiveTriviaSyntax>, IIfSiblingDirective, IExpressionParentEntity
|
||||
{
|
||||
public ElifDirective(Context cx, ElifDirectiveTriviaSyntax trivia)
|
||||
: base(cx, trivia)
|
||||
private readonly IfDirective start;
|
||||
private readonly int index;
|
||||
|
||||
public ElifDirective(Context cx, ElifDirectiveTriviaSyntax trivia, IfDirective start, int index)
|
||||
: base(cx, trivia, populateFromBase: false)
|
||||
{
|
||||
this.start = start;
|
||||
this.index = index;
|
||||
TryPopulate();
|
||||
}
|
||||
|
||||
public bool IsTopLevelParent => true;
|
||||
|
||||
protected override void PopulatePreprocessor(TextWriter trapFile)
|
||||
{
|
||||
trapFile.directive_elifs(this, trivia.BranchTaken, trivia.ConditionValue);
|
||||
trapFile.directive_elifs(this, trivia.BranchTaken, trivia.ConditionValue, start, index);
|
||||
|
||||
Expression.Create(cx, trivia.Condition, this, 0);
|
||||
}
|
||||
|
||||
@@ -5,14 +5,20 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
internal class ElseDirective : PreprocessorDirective<ElseDirectiveTriviaSyntax>, IIfSiblingDirective
|
||||
{
|
||||
public ElseDirective(Context cx, ElseDirectiveTriviaSyntax trivia)
|
||||
: base(cx, trivia)
|
||||
private readonly IfDirective start;
|
||||
private readonly int index;
|
||||
|
||||
public ElseDirective(Context cx, ElseDirectiveTriviaSyntax trivia, IfDirective start, int index)
|
||||
: base(cx, trivia, populateFromBase: false)
|
||||
{
|
||||
this.start = start;
|
||||
this.index = index;
|
||||
TryPopulate();
|
||||
}
|
||||
|
||||
protected override void PopulatePreprocessor(TextWriter trapFile)
|
||||
{
|
||||
trapFile.directive_elses(this, trivia.BranchTaken);
|
||||
trapFile.directive_elses(this, trivia.BranchTaken, start, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,14 +5,18 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
internal class EndIfDirective : PreprocessorDirective<EndIfDirectiveTriviaSyntax>
|
||||
{
|
||||
public EndIfDirective(Context cx, EndIfDirectiveTriviaSyntax trivia)
|
||||
: base(cx, trivia)
|
||||
private readonly IfDirective start;
|
||||
|
||||
public EndIfDirective(Context cx, EndIfDirectiveTriviaSyntax trivia, IfDirective start)
|
||||
: base(cx, trivia, populateFromBase: false)
|
||||
{
|
||||
this.start = start;
|
||||
TryPopulate();
|
||||
}
|
||||
|
||||
protected override void PopulatePreprocessor(TextWriter trapFile)
|
||||
{
|
||||
trapFile.directive_endifs(this);
|
||||
trapFile.directive_endifs(this, start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
internal class IfDirective : PreprocessorDirective<IfDirectiveTriviaSyntax>, IExpressionParentEntity
|
||||
{
|
||||
private readonly List<IIfSiblingDirective> branches = new List<IIfSiblingDirective>();
|
||||
|
||||
public IfDirective(Context cx, IfDirectiveTriviaSyntax trivia)
|
||||
: base(cx, trivia)
|
||||
{
|
||||
@@ -21,20 +18,5 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
Expression.Create(cx, trivia.Condition, this, 0);
|
||||
}
|
||||
|
||||
internal void Add(IIfSiblingDirective branch)
|
||||
{
|
||||
branches.Add(branch);
|
||||
}
|
||||
|
||||
internal void WriteBranches(EndIfDirective endif)
|
||||
{
|
||||
cx.TrapWriter.Writer.directive_if_endif(this, endif);
|
||||
var siblings = 0;
|
||||
foreach (var branch in branches)
|
||||
{
|
||||
cx.TrapWriter.Writer.directive_if_siblings(this, branch, siblings++);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,51 +76,63 @@ namespace Semmle.Extraction.CSharp.Populators
|
||||
new Entities.EndRegionDirective(cx, node, start);
|
||||
}
|
||||
|
||||
private readonly Stack<Entities.IfDirective> ifStarts = new Stack<Entities.IfDirective>();
|
||||
private class IfDirectiveStackElement
|
||||
{
|
||||
public Entities.IfDirective Entity { get; }
|
||||
public int SiblingCount { get; set; }
|
||||
|
||||
|
||||
public IfDirectiveStackElement(Entities.IfDirective entity)
|
||||
{
|
||||
Entity = entity;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Stack<IfDirectiveStackElement> ifStarts = new Stack<IfDirectiveStackElement>();
|
||||
|
||||
public override void VisitIfDirectiveTrivia(IfDirectiveTriviaSyntax node)
|
||||
{
|
||||
var ifStart = new Entities.IfDirective(cx, node);
|
||||
ifStarts.Push(ifStart);
|
||||
ifStarts.Push(new IfDirectiveStackElement(ifStart));
|
||||
}
|
||||
|
||||
public override void VisitEndIfDirectiveTrivia(EndIfDirectiveTriviaSyntax node)
|
||||
{
|
||||
var endif = new Entities.EndIfDirective(cx, node);
|
||||
if (ifStarts.Count == 0)
|
||||
{
|
||||
cx.ExtractionError("Couldn't find start if", null,
|
||||
Extraction.Entities.Location.Create(cx, node.GetLocation()), null, Util.Logging.Severity.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
var start = ifStarts.Pop();
|
||||
start.WriteBranches(endif);
|
||||
new Entities.EndIfDirective(cx, node, start.Entity);
|
||||
}
|
||||
|
||||
public override void VisitElifDirectiveTrivia(ElifDirectiveTriviaSyntax node)
|
||||
{
|
||||
var elif = new Entities.ElifDirective(cx, node);
|
||||
if (ifStarts.Count == 0)
|
||||
{
|
||||
cx.ExtractionError("Couldn't find start if", null,
|
||||
Extraction.Entities.Location.Create(cx, node.GetLocation()), null, Util.Logging.Severity.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
var start = ifStarts.Peek();
|
||||
start.Add(elif);
|
||||
new Entities.ElifDirective(cx, node, start.Entity, start.SiblingCount++);
|
||||
}
|
||||
|
||||
public override void VisitElseDirectiveTrivia(ElseDirectiveTriviaSyntax node)
|
||||
{
|
||||
var elseDirective = new Entities.ElseDirective(cx, node);
|
||||
if (ifStarts.Count == 0)
|
||||
{
|
||||
cx.ExtractionError("Couldn't find start if", null,
|
||||
Extraction.Entities.Location.Create(cx, node.GetLocation()), null, Util.Logging.Severity.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
var start = ifStarts.Peek();
|
||||
start.Add(elseDirective);
|
||||
new Entities.ElseDirective(cx, node, start.Entity, start.SiblingCount++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -684,29 +684,21 @@ namespace Semmle.Extraction.CSharp
|
||||
trapFile.WriteTuple("directive_ifs", directive, branchTaken ? 1 : 0, conditionValue ? 1 : 0);
|
||||
}
|
||||
|
||||
internal static void directive_elifs(this TextWriter trapFile, ElifDirective directive, bool branchTaken, bool conditionValue)
|
||||
internal static void directive_elifs(this TextWriter trapFile, ElifDirective directive, bool branchTaken, bool conditionValue,
|
||||
IfDirective start, int index)
|
||||
{
|
||||
trapFile.WriteTuple("directive_elifs", directive, branchTaken ? 1 : 0, conditionValue ? 1 : 0);
|
||||
trapFile.WriteTuple("directive_elifs", directive, branchTaken ? 1 : 0, conditionValue ? 1 : 0, start, index);
|
||||
}
|
||||
|
||||
internal static void directive_elses(this TextWriter trapFile, ElseDirective directive, bool branchTaken)
|
||||
internal static void directive_elses(this TextWriter trapFile, ElseDirective directive, bool branchTaken,
|
||||
IfDirective start, int index)
|
||||
{
|
||||
trapFile.WriteTuple("directive_elses", directive, branchTaken ? 1 : 0);
|
||||
trapFile.WriteTuple("directive_elses", directive, branchTaken ? 1 : 0, start, index);
|
||||
}
|
||||
|
||||
internal static void directive_endifs(this TextWriter trapFile, EndIfDirective directive)
|
||||
internal static void directive_endifs(this TextWriter trapFile, EndIfDirective directive, IfDirective start)
|
||||
{
|
||||
trapFile.WriteTuple("directive_endifs", directive);
|
||||
}
|
||||
|
||||
internal static void directive_if_endif(this TextWriter trapFile, IfDirective start, EndIfDirective end)
|
||||
{
|
||||
trapFile.WriteTuple("directive_if_endif", start, end);
|
||||
}
|
||||
|
||||
internal static void directive_if_siblings(this TextWriter trapFile, IfDirective start, IIfSiblingDirective siblingDirective, int index)
|
||||
{
|
||||
trapFile.WriteTuple("directive_if_siblings", start, siblingDirective, index);
|
||||
trapFile.WriteTuple("directive_endifs", directive, start);
|
||||
}
|
||||
|
||||
internal static void directive_define_symbols(this TextWriter trapFile, DefineSymbol symb, string name)
|
||||
|
||||
Reference in New Issue
Block a user