mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
C#: Add extractor support for object initializer methods.
This commit is contained in:
@@ -74,6 +74,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
case SyntaxKind.BaseConstructorInitializer:
|
||||
initializerType = Symbol.ContainingType.BaseType!;
|
||||
ExtractObjectInitCall(trapFile);
|
||||
break;
|
||||
case SyntaxKind.ThisConstructorInitializer:
|
||||
initializerType = Symbol.ContainingType;
|
||||
@@ -90,10 +91,12 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
var primaryInfo = Context.GetSymbolInfo(primaryInitializer);
|
||||
var primarySymbol = primaryInfo.Symbol;
|
||||
|
||||
ExtractObjectInitCall(trapFile);
|
||||
ExtractSourceInitializer(trapFile, primarySymbol?.ContainingType, (IMethodSymbol?)primarySymbol, primaryInitializer.ArgumentList, primaryInitializer.GetLocation());
|
||||
}
|
||||
else if (Symbol.MethodKind is MethodKind.Constructor)
|
||||
{
|
||||
ExtractObjectInitCall(trapFile);
|
||||
var baseType = Symbol.ContainingType.BaseType;
|
||||
if (baseType is null)
|
||||
{
|
||||
@@ -127,6 +130,27 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
}
|
||||
|
||||
private void ExtractObjectInitCall(TextWriter trapFile)
|
||||
{
|
||||
var target = ObjectInitMethod.Create(Context, ContainingType!);
|
||||
|
||||
var type = Context.Compilation.GetSpecialType(SpecialType.System_Void);
|
||||
|
||||
var info = new ExpressionInfo(Context,
|
||||
AnnotatedTypeSymbol.CreateNotAnnotated(type),
|
||||
Location,
|
||||
Kinds.ExprKind.METHOD_INVOCATION,
|
||||
this,
|
||||
-2,
|
||||
isCompilerGenerated: true,
|
||||
null);
|
||||
var obinitCall = new Expression(info);
|
||||
|
||||
trapFile.expr_call(obinitCall, target);
|
||||
|
||||
Expressions.This.CreateImplicit(Context, Symbol.ContainingType, Location, obinitCall, -1);
|
||||
}
|
||||
|
||||
private void ExtractSourceInitializer(TextWriter trapFile, ITypeSymbol? type, IMethodSymbol? symbol, ArgumentListSyntax arguments, Microsoft.CodeAnalysis.Location location)
|
||||
{
|
||||
var initInfo = new ExpressionInfo(Context,
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Marker interface for method entities.
|
||||
/// </summary>
|
||||
public interface IMethodEntity : IEntity
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ using Semmle.Extraction.CSharp.Populators;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
internal abstract class Method : CachedSymbol<IMethodSymbol>, IExpressionParentEntity, IStatementParentEntity
|
||||
internal abstract class Method : CachedSymbol<IMethodSymbol>, IExpressionParentEntity, IStatementParentEntity, IMethodEntity
|
||||
{
|
||||
protected Method(Context cx, IMethodSymbol init)
|
||||
: base(cx, init) { }
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
using System.IO;
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
internal sealed class ObjectInitMethod : CachedEntity, IMethodEntity
|
||||
{
|
||||
Type ContainingType { get; }
|
||||
|
||||
private ObjectInitMethod(Context cx, Type containingType)
|
||||
: base(cx)
|
||||
{
|
||||
this.ContainingType = containingType;
|
||||
}
|
||||
|
||||
public string Name => "<object initializer>";
|
||||
|
||||
public static ObjectInitMethod Create(Context cx, Type containingType)
|
||||
{
|
||||
return ObjectInitMethodFactory.Instance.CreateEntity(cx, (typeof(ObjectInitMethod), containingType), containingType);
|
||||
}
|
||||
|
||||
public override void Populate(TextWriter trapFile)
|
||||
{
|
||||
var returnType = Type.Create(Context, Context.Compilation.GetSpecialType(SpecialType.System_Void));
|
||||
|
||||
trapFile.methods(this, Name, ContainingType, returnType.TypeRef, this);
|
||||
|
||||
trapFile.compiler_generated(this);
|
||||
|
||||
trapFile.method_location(this, Context.CreateLocation(ReportingLocation));
|
||||
}
|
||||
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.WriteSubId(ContainingType);
|
||||
trapFile.Write(".");
|
||||
trapFile.Write(Name);
|
||||
trapFile.Write(";method");
|
||||
}
|
||||
|
||||
public override Microsoft.CodeAnalysis.Location? ReportingLocation => ContainingType.ReportingLocation;
|
||||
|
||||
public override bool NeedsPopulation => true;
|
||||
|
||||
public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel;
|
||||
|
||||
private class ObjectInitMethodFactory : CachedEntityFactory<Type, ObjectInitMethod>
|
||||
{
|
||||
public static ObjectInitMethodFactory Instance { get; } = new ObjectInitMethodFactory();
|
||||
|
||||
public override ObjectInitMethod Create(Context cx, Type containingType) =>
|
||||
new ObjectInitMethod(cx, containingType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -175,7 +175,7 @@ namespace Semmle.Extraction.CSharp
|
||||
internal static void expr_argument_name(this TextWriter trapFile, Expression expr, string name) =>
|
||||
trapFile.WriteTuple("expr_argument_name", expr, name);
|
||||
|
||||
internal static void expr_call(this TextWriter trapFile, Expression expr, Method target) =>
|
||||
internal static void expr_call(this TextWriter trapFile, Expression expr, IMethodEntity target) =>
|
||||
trapFile.WriteTuple("expr_call", expr, target);
|
||||
|
||||
internal static void expr_flowstate(this TextWriter trapFile, Expression expr, int flowState) =>
|
||||
@@ -247,10 +247,10 @@ namespace Semmle.Extraction.CSharp
|
||||
internal static void localvars(this TextWriter trapFile, LocalVariable key, VariableKind kind, string name, int @var, Type type, Expression expr) =>
|
||||
trapFile.WriteTuple("localvars", key, (int)kind, name, @var, type, expr);
|
||||
|
||||
internal static void method_location(this TextWriter trapFile, Method method, Location location) =>
|
||||
internal static void method_location(this TextWriter trapFile, IMethodEntity method, Location location) =>
|
||||
trapFile.WriteTuple("method_location", method, location);
|
||||
|
||||
internal static void methods(this TextWriter trapFile, Method method, string name, Type declType, Type retType, Method originalDefinition) =>
|
||||
internal static void methods(this TextWriter trapFile, IMethodEntity method, string name, Type declType, Type retType, IMethodEntity originalDefinition) =>
|
||||
trapFile.WriteTuple("methods", method, name, declType, retType, originalDefinition);
|
||||
|
||||
internal static void modifiers(this TextWriter trapFile, Label entity, string modifier) =>
|
||||
|
||||
Reference in New Issue
Block a user