C#: Synthesize an empty body for primary constructors.

This commit is contained in:
Michael Nebel
2024-02-16 15:30:38 +01:00
parent dcde6597bc
commit 28d5c11b6f
3 changed files with 33 additions and 1 deletions

View File

@@ -32,6 +32,12 @@ namespace Semmle.Extraction.CSharp.Entities
trapFile.constructors(this, Symbol.ContainingType.Name, ContainingType, (Constructor)OriginalDefinition);
trapFile.constructor_location(this, Location);
if (IsPrimary)
{
// Create a synthetic empty body for primary constructors.
Statements.SyntheticEmptyBlock.Create(Context, this, 0, Location);
}
if (Symbol.IsImplicitlyDeclared)
{
var lineCounts = new LineCounts() { Total = 2, Code = 1, Comment = 0 };

View File

@@ -0,0 +1,24 @@
using System.IO;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Semmle.Extraction.Entities;
using Semmle.Extraction.Kinds;
namespace Semmle.Extraction.CSharp.Entities.Statements
{
internal class SyntheticEmptyBlock : Statement<BlockSyntax>
{
private SyntheticEmptyBlock(Context cx, BlockSyntax block, IStatementParentEntity parent, int child, Location location)
: base(cx, block, StmtKind.BLOCK, parent, child, location) { }
public static SyntheticEmptyBlock Create(Context cx, IStatementParentEntity parent, int child, Location location)
{
var block = SyntaxFactory.Block();
var ret = new SyntheticEmptyBlock(cx, block, parent, child, location);
ret.TryPopulate();
return ret;
}
protected override void PopulateStatement(TextWriter trapFile) { }
}
}

View File

@@ -416,7 +416,9 @@ class InstanceConstructor extends Constructor {
*/
class PrimaryConstructor extends Constructor {
PrimaryConstructor() {
not this.hasBody() and
// In the extractor we use the constructor location as the location for the
// synthesized empty body of the constructor.
this.getLocation() = this.getBody().getLocation() and
this.getDeclaringType().fromSource() and
this.fromSource()
}