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

Skip to content

Commit 63b0fe1

Browse files
committed
Rework foreach_stmt_info extraction
1 parent 7c506f4 commit 63b0fe1

6 files changed

Lines changed: 70 additions & 22 deletions

File tree

csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/ForEach.cs

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@ namespace Semmle.Extraction.CSharp.Entities.Statements
88
{
99
internal class ForEach : Statement<ForEachStatementSyntax>
1010
{
11+
internal enum ForeachSymbolType
12+
{
13+
GetEnumeratorMethod = 1,
14+
CurrentProperty,
15+
MoveNextMethod,
16+
DisposeMethod,
17+
ElementType
18+
}
19+
1120
private ForEach(Context cx, ForEachStatementSyntax stmt, IStatementParentEntity parent, int child)
1221
: base(cx, stmt, StmtKind.FOREACH, parent, child) { }
1322

@@ -33,13 +42,44 @@ protected override void PopulateStatement(TextWriter trapFile)
3342
Statement.Create(cx, Stmt.Statement, this, 2);
3443

3544
var info = semanticModel.GetForEachStatementInfo(Stmt);
36-
var getEnumerator = Method.Create(cx, info.GetEnumeratorMethod);
37-
var currentProp = Property.Create(cx, info.CurrentProperty);
38-
var moveNext = Method.Create(cx, info.MoveNextMethod);
39-
var dispose = Method.Create(cx, info.DisposeMethod);
40-
var elementType = Type.Create(cx, info.ElementType);
4145

42-
trapFile.foreach_stmt_info(this, elementType, getEnumerator, moveNext, dispose, currentProp, info.IsAsynchronous);
46+
if (info.Equals(default))
47+
{
48+
cx.ExtractionError("Could not get foreach statement info", null, Location.Create(cx, this.ReportingLocation), severity: Util.Logging.Severity.Info);
49+
return;
50+
}
51+
52+
trapFile.foreach_stmt_info(this, info.IsAsynchronous);
53+
54+
if (info.GetEnumeratorMethod != null)
55+
{
56+
var m = Method.Create(cx, info.GetEnumeratorMethod);
57+
trapFile.foreach_stmt_desugar(this, m, ForeachSymbolType.GetEnumeratorMethod);
58+
}
59+
60+
if (info.MoveNextMethod != null)
61+
{
62+
var m = Method.Create(cx, info.MoveNextMethod);
63+
trapFile.foreach_stmt_desugar(this, m, ForeachSymbolType.MoveNextMethod);
64+
}
65+
66+
if (info.DisposeMethod != null)
67+
{
68+
var m = Method.Create(cx, info.DisposeMethod);
69+
trapFile.foreach_stmt_desugar(this, m, ForeachSymbolType.DisposeMethod);
70+
}
71+
72+
if (info.CurrentProperty != null)
73+
{
74+
var p = Property.Create(cx, info.CurrentProperty);
75+
trapFile.foreach_stmt_desugar(this, p, ForeachSymbolType.CurrentProperty);
76+
}
77+
78+
if (info.ElementType != null)
79+
{
80+
var t = Type.Create(cx, info.ElementType);
81+
trapFile.foreach_stmt_desugar(this, t, ForeachSymbolType.ElementType);
82+
}
4383
}
4484
}
4585

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,15 @@ internal static void catch_type(this TextWriter trapFile, Entities.Statements.Ca
5353
trapFile.WriteTuple("catch_type", @catch, type, explicityCaught ? 1 : 2);
5454
}
5555

56-
internal static void foreach_stmt_info(this TextWriter trapFile, Entities.Statements.ForEach @foreach, Type element, Method getEnumerator,
57-
Method moveNext, Method dispose, Property current, bool isAsync)
56+
internal static void foreach_stmt_info(this TextWriter trapFile, Entities.Statements.ForEach @foreach, bool isAsync)
5857
{
59-
trapFile.WriteTuple("foreach_stmt_info", @foreach, element, getEnumerator, moveNext, dispose, current, isAsync ? 2 : 1);
58+
trapFile.WriteTuple("foreach_stmt_info", @foreach, isAsync ? 2 : 1);
59+
}
60+
61+
internal static void foreach_stmt_desugar(this TextWriter trapFile, Entities.Statements.ForEach @foreach, IEntity entity,
62+
Entities.Statements.ForEach.ForeachSymbolType type)
63+
{
64+
trapFile.WriteTuple("foreach_stmt_desugar", @foreach, entity, (int)type);
6065
}
6166

6267
internal static void commentblock(this TextWriter trapFile, CommentBlock k)

csharp/ql/src/Dead Code/DeadCode.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ predicate potentiallyAccessedByForEach(Method m) {
4444
m.hasName("GetEnumerator") and
4545
m.getDeclaringType().getABaseType+().hasQualifiedName("System.Collections.IEnumerable")
4646
or
47-
foreach_stmt_info(_, _, m, _, _, _, _)
47+
foreach_stmt_desugar(_, m, 1)
4848
}
4949

5050
predicate isRecursivelyLiveExpression(Expr e) {

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -583,25 +583,25 @@ class ForeachStmt extends LoopStmt, @foreach_stmt {
583583
Expr getIterableExpr() { result = this.getChild(1) }
584584

585585
/** Gets the called `GetEnumerator` method. */
586-
Method getGetEnumerator() { foreach_stmt_info(this, _, result, _, _, _, _) }
586+
Method getGetEnumerator() { foreach_stmt_desugar(this, result, 1) }
587587

588588
/** Gets the called `MoveNext` or `MoveNextAsync` method. */
589-
Method getMoveNext() { foreach_stmt_info(this, _, _, result, _, _, _) }
589+
Method getMoveNext() { foreach_stmt_desugar(this, result, 3) }
590590

591591
/** Gets the called `Dispose` or `DisposeAsync` method. */
592-
Method getDispose() { foreach_stmt_info(this, _, _, _, result, _, _) }
592+
Method getDispose() { foreach_stmt_desugar(this, result, 4) }
593593

594594
/** Gets the called `Current` property. */
595-
Property getCurrent() { foreach_stmt_info(this, _, _, _, _, result, _) }
595+
Property getCurrent() { foreach_stmt_desugar(this, result, 2) }
596596

597597
/**
598598
* Gets the intermediate type to which the `Current` property is converted before
599599
* being converted to the iteration variable type.
600600
*/
601-
Type getElementType() { foreach_stmt_info(this, result, _, _, _, _, _) }
601+
Type getElementType() { foreach_stmt_desugar(this, result, 5) }
602602

603603
/** Holds if this `foreach` statement is asynchronous. */
604-
predicate isAsync() { foreach_stmt_info(this, _, _, _, _, _, 2) }
604+
predicate isAsync() { foreach_stmt_info(this, 2) }
605605

606606
override string toString() { result = "foreach (... ... in ...) ..." }
607607

csharp/ql/src/semmlecode.csharp.dbscheme

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -984,13 +984,16 @@ catch_type(
984984

985985
foreach_stmt_info(
986986
unique int id: @foreach_stmt ref,
987-
int element_type_id: @type_or_ref ref,
988-
int getenumerator_id: @method ref,
989-
int movenext_id: @method ref,
990-
int dispose_id: @method ref,
991-
int current_id: @property ref,
992987
int kind: int ref /* non-async = 1, async = 2 */);
993988

989+
@foreach_symbol = @method | @property | @type_or_ref;
990+
991+
#keyset[id, kind]
992+
foreach_stmt_desugar(
993+
int id: @foreach_stmt ref,
994+
int symbol: @foreach_symbol ref,
995+
int kind: int ref /* GetEnumeratorMethod = 1, CurrentProperty = 2, MoveNextMethod = 3, DisposeMethod = 4, ElementType = 5 */);
996+
994997
/** EXPRESSIONS **/
995998

996999
expressions(
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
description: Add 'foreach_stmt_info' relation.
1+
description: Add 'foreach_stmt_info' and 'foreach_stmt_desugar' relations.
22
compatibility: backwards

0 commit comments

Comments
 (0)