Skip to content

Commit f737804

Browse files
authored
Merge pull request #9610 from tamasvajk/fix/global-statements
C#: Fix global statement extraction
2 parents c9eef0c + 51f0a92 commit f737804

File tree

7 files changed

+63
-17
lines changed

7 files changed

+63
-17
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using Microsoft.CodeAnalysis;
2+
using Microsoft.CodeAnalysis.CSharp.Syntax;
3+
using Semmle.Extraction.CSharp.Entities.Statements;
4+
using System.Collections.Generic;
5+
using System.IO;
6+
7+
namespace Semmle.Extraction.CSharp.Entities
8+
{
9+
internal class ImplicitMainMethod : OrdinaryMethod
10+
{
11+
private readonly List<GlobalStatementSyntax> globalStatements;
12+
13+
public ImplicitMainMethod(Context cx, IMethodSymbol symbol, List<GlobalStatementSyntax> globalStatements)
14+
: base(cx, symbol)
15+
{
16+
this.globalStatements = globalStatements;
17+
}
18+
19+
protected override void PopulateMethodBody(TextWriter trapFile)
20+
{
21+
GlobalStatementsBlock.Create(Context, this, globalStatements);
22+
}
23+
24+
public static ImplicitMainMethod Create(Context cx, IMethodSymbol method, List<GlobalStatementSyntax> globalStatements)
25+
{
26+
return ImplicitMainMethodFactory.Instance.CreateEntity(cx, method, (method, globalStatements));
27+
}
28+
29+
private class ImplicitMainMethodFactory : CachedEntityFactory<(IMethodSymbol, List<GlobalStatementSyntax>), ImplicitMainMethod>
30+
{
31+
public static ImplicitMainMethodFactory Instance { get; } = new ImplicitMainMethodFactory();
32+
33+
public override ImplicitMainMethod Create(Context cx, (IMethodSymbol, List<GlobalStatementSyntax>) init) => new ImplicitMainMethod(cx, init.Item1, init.Item2);
34+
}
35+
}
36+
}

csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ protected virtual void ExtractInitializers(TextWriter trapFile)
4646
// so there's nothing to extract.
4747
}
4848

49-
private void PopulateMethodBody(TextWriter trapFile)
49+
protected virtual void PopulateMethodBody(TextWriter trapFile)
5050
{
5151
if (!IsSourceDeclaration)
5252
return;

csharp/extractor/Semmle.Extraction.CSharp/Entities/OrdinaryMethod.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace Semmle.Extraction.CSharp.Entities
88
{
99
internal class OrdinaryMethod : Method
1010
{
11-
private OrdinaryMethod(Context cx, IMethodSymbol init)
11+
protected OrdinaryMethod(Context cx, IMethodSymbol init)
1212
: base(cx, init) { }
1313

1414
public override string Name => Symbol.GetName();

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

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,22 @@
22
using System.Linq;
33
using System.IO;
44
using Semmle.Extraction.Entities;
5+
using System.Collections.Generic;
6+
using Microsoft.CodeAnalysis.CSharp.Syntax;
7+
using System;
58

69
namespace Semmle.Extraction.CSharp.Entities.Statements
710
{
811
internal class GlobalStatementsBlock : Statement
912
{
1013
private readonly Method parent;
14+
private readonly List<GlobalStatementSyntax> globalStatements;
1115

12-
private GlobalStatementsBlock(Context cx, Method parent)
16+
private GlobalStatementsBlock(Context cx, Method parent, List<GlobalStatementSyntax> globalStatements)
1317
: base(cx, StmtKind.BLOCK, parent, 0)
1418
{
1519
this.parent = parent;
20+
this.globalStatements = globalStatements;
1621
}
1722

1823
public override Microsoft.CodeAnalysis.Location? ReportingLocation
@@ -27,16 +32,24 @@ public override Microsoft.CodeAnalysis.Location? ReportingLocation
2732
}
2833
}
2934

30-
public static GlobalStatementsBlock Create(Context cx, Method parent)
35+
public static GlobalStatementsBlock Create(Context cx, Method parent, List<GlobalStatementSyntax> globalStatements)
3136
{
32-
var ret = new GlobalStatementsBlock(cx, parent);
37+
var ret = new GlobalStatementsBlock(cx, parent, globalStatements);
3338
ret.TryPopulate();
3439
return ret;
3540
}
3641

3742
protected override void PopulateStatement(TextWriter trapFile)
3843
{
3944
trapFile.stmt_location(this, Context.CreateLocation(ReportingLocation));
45+
46+
for (var i = 0; i < globalStatements.Count; i++)
47+
{
48+
if (globalStatements[i].Statement is not null)
49+
{
50+
Statement.Create(Context, globalStatements[i].Statement, this, i);
51+
}
52+
}
4053
}
4154
}
4255
}

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

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
using Microsoft.CodeAnalysis.CSharp.Syntax;
44
using Semmle.Util.Logging;
55
using Semmle.Extraction.CSharp.Entities;
6-
using Semmle.Extraction.CSharp.Entities.Statements;
76
using System.Linq;
87

98
namespace Semmle.Extraction.CSharp.Populators
@@ -60,23 +59,14 @@ private void ExtractGlobalStatements(CompilationUnitSyntax compilationUnit)
6059
}
6160

6261
var entryPoint = Cx.Compilation.GetEntryPoint(System.Threading.CancellationToken.None);
63-
var entryMethod = Method.Create(Cx, entryPoint);
64-
if (entryMethod is null)
62+
if (entryPoint is null)
6563
{
6664
Cx.ExtractionError("No entry method found. Skipping the extraction of global statements.",
6765
null, Cx.CreateLocation(globalStatements[0].GetLocation()), null, Severity.Info);
6866
return;
6967
}
7068

71-
var block = GlobalStatementsBlock.Create(Cx, entryMethod);
72-
73-
for (var i = 0; i < globalStatements.Count; i++)
74-
{
75-
if (globalStatements[i].Statement is not null)
76-
{
77-
Statement.Create(Cx, globalStatements[i].Statement, block, i);
78-
}
79-
}
69+
ImplicitMainMethod.Create(Cx, entryPoint, globalStatements);
8070
}
8171
}
8272
}

csharp/ql/test/library-tests/csharp9-standalone/ExtractorError.expected

Whitespace-only changes.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import csharp
2+
import semmle.code.csharp.commons.Diagnostics
3+
4+
from ExtractorError error
5+
where not exists(CompilerError ce | ce.getLocation().getFile() = error.getLocation().getFile())
6+
select error,
7+
"Unexpected " + error.getOrigin() + " error: " + error.getText() + "\n" + error.getStackTrace()

0 commit comments

Comments
 (0)