Merge pull request #9610 from tamasvajk/fix/global-statements

C#: Fix global statement extraction
This commit is contained in:
Tamás Vajk
2022-06-20 12:54:36 +02:00
committed by GitHub
7 changed files with 63 additions and 17 deletions

View File

@@ -0,0 +1,36 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Semmle.Extraction.CSharp.Entities.Statements;
using System.Collections.Generic;
using System.IO;
namespace Semmle.Extraction.CSharp.Entities
{
internal class ImplicitMainMethod : OrdinaryMethod
{
private readonly List<GlobalStatementSyntax> globalStatements;
public ImplicitMainMethod(Context cx, IMethodSymbol symbol, List<GlobalStatementSyntax> globalStatements)
: base(cx, symbol)
{
this.globalStatements = globalStatements;
}
protected override void PopulateMethodBody(TextWriter trapFile)
{
GlobalStatementsBlock.Create(Context, this, globalStatements);
}
public static ImplicitMainMethod Create(Context cx, IMethodSymbol method, List<GlobalStatementSyntax> globalStatements)
{
return ImplicitMainMethodFactory.Instance.CreateEntity(cx, method, (method, globalStatements));
}
private class ImplicitMainMethodFactory : CachedEntityFactory<(IMethodSymbol, List<GlobalStatementSyntax>), ImplicitMainMethod>
{
public static ImplicitMainMethodFactory Instance { get; } = new ImplicitMainMethodFactory();
public override ImplicitMainMethod Create(Context cx, (IMethodSymbol, List<GlobalStatementSyntax>) init) => new ImplicitMainMethod(cx, init.Item1, init.Item2);
}
}
}

View File

@@ -46,7 +46,7 @@ namespace Semmle.Extraction.CSharp.Entities
// so there's nothing to extract.
}
private void PopulateMethodBody(TextWriter trapFile)
protected virtual void PopulateMethodBody(TextWriter trapFile)
{
if (!IsSourceDeclaration)
return;

View File

@@ -8,7 +8,7 @@ namespace Semmle.Extraction.CSharp.Entities
{
internal class OrdinaryMethod : Method
{
private OrdinaryMethod(Context cx, IMethodSymbol init)
protected OrdinaryMethod(Context cx, IMethodSymbol init)
: base(cx, init) { }
public override string Name => Symbol.GetName();

View File

@@ -2,17 +2,22 @@ using Semmle.Extraction.Kinds;
using System.Linq;
using System.IO;
using Semmle.Extraction.Entities;
using System.Collections.Generic;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System;
namespace Semmle.Extraction.CSharp.Entities.Statements
{
internal class GlobalStatementsBlock : Statement
{
private readonly Method parent;
private readonly List<GlobalStatementSyntax> globalStatements;
private GlobalStatementsBlock(Context cx, Method parent)
private GlobalStatementsBlock(Context cx, Method parent, List<GlobalStatementSyntax> globalStatements)
: base(cx, StmtKind.BLOCK, parent, 0)
{
this.parent = parent;
this.globalStatements = globalStatements;
}
public override Microsoft.CodeAnalysis.Location? ReportingLocation
@@ -27,9 +32,9 @@ namespace Semmle.Extraction.CSharp.Entities.Statements
}
}
public static GlobalStatementsBlock Create(Context cx, Method parent)
public static GlobalStatementsBlock Create(Context cx, Method parent, List<GlobalStatementSyntax> globalStatements)
{
var ret = new GlobalStatementsBlock(cx, parent);
var ret = new GlobalStatementsBlock(cx, parent, globalStatements);
ret.TryPopulate();
return ret;
}
@@ -37,6 +42,14 @@ namespace Semmle.Extraction.CSharp.Entities.Statements
protected override void PopulateStatement(TextWriter trapFile)
{
trapFile.stmt_location(this, Context.CreateLocation(ReportingLocation));
for (var i = 0; i < globalStatements.Count; i++)
{
if (globalStatements[i].Statement is not null)
{
Statement.Create(Context, globalStatements[i].Statement, this, i);
}
}
}
}
}

View File

@@ -3,7 +3,6 @@ using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Semmle.Util.Logging;
using Semmle.Extraction.CSharp.Entities;
using Semmle.Extraction.CSharp.Entities.Statements;
using System.Linq;
namespace Semmle.Extraction.CSharp.Populators
@@ -60,23 +59,14 @@ namespace Semmle.Extraction.CSharp.Populators
}
var entryPoint = Cx.Compilation.GetEntryPoint(System.Threading.CancellationToken.None);
var entryMethod = Method.Create(Cx, entryPoint);
if (entryMethod is null)
if (entryPoint is null)
{
Cx.ExtractionError("No entry method found. Skipping the extraction of global statements.",
null, Cx.CreateLocation(globalStatements[0].GetLocation()), null, Severity.Info);
return;
}
var block = GlobalStatementsBlock.Create(Cx, entryMethod);
for (var i = 0; i < globalStatements.Count; i++)
{
if (globalStatements[i].Statement is not null)
{
Statement.Create(Cx, globalStatements[i].Statement, block, i);
}
}
ImplicitMainMethod.Create(Cx, entryPoint, globalStatements);
}
}
}

View File

@@ -0,0 +1,7 @@
import csharp
import semmle.code.csharp.commons.Diagnostics
from ExtractorError error
where not exists(CompilerError ce | ce.getLocation().getFile() = error.getLocation().getFile())
select error,
"Unexpected " + error.getOrigin() + " error: " + error.getText() + "\n" + error.getStackTrace()