C#: Streamline the partial implementation for properties and events.

This commit is contained in:
Michael Nebel
2026-02-20 16:32:54 +01:00
parent 03a54bfbf9
commit 003b539287
5 changed files with 17 additions and 21 deletions

View File

@@ -731,6 +731,12 @@ namespace Semmle.Extraction.CSharp
public static IMethodSymbol GetBodyDeclaringSymbol(this IMethodSymbol method) =>
method.PartialImplementationPart ?? method;
public static IPropertySymbol GetBodyDeclaringSymbol(this IPropertySymbol property) =>
property.PartialImplementationPart ?? property;
public static IEventSymbol GetBodyDeclaringSymbol(this IEventSymbol symbol) =>
symbol.PartialImplementationPart ?? symbol;
[return: NotNullIfNotNull(nameof(symbol))]
public static IEntity? CreateEntity(this Context cx, ISymbol symbol)
{

View File

@@ -15,8 +15,8 @@ namespace Semmle.Extraction.CSharp.Entities
protected CachedSymbol(Context cx, T init)
: base(cx, init)
{
blockLazy = new Lazy<BlockSyntax?>(() => GetBlock(BodyDeclaringSymbol));
expressionBodyLazy = new Lazy<ExpressionSyntax?>(() => GetExpressionBody(BodyDeclaringSymbol));
blockLazy = new Lazy<BlockSyntax?>(() => GetBlock(Symbol));
expressionBodyLazy = new Lazy<ExpressionSyntax?>(() => GetExpressionBody(Symbol));
}
public virtual Type? ContainingType => Symbol.ContainingType is not null
@@ -92,8 +92,6 @@ namespace Semmle.Extraction.CSharp.Entities
Context.BindComments(this, FullLocation);
}
protected virtual T BodyDeclaringSymbol => Symbol;
private static BlockSyntax? GetBlock(T symbol)
{
return symbol.DeclaringSyntaxReferences

View File

@@ -11,10 +11,6 @@ namespace Semmle.Extraction.CSharp.Entities
private Event(Context cx, IEventSymbol init)
: base(cx, init) { }
protected override IEventSymbol BodyDeclaringSymbol => Symbol.PartialImplementationPart ?? Symbol;
public override Microsoft.CodeAnalysis.Location? ReportingLocation => BodyDeclaringSymbol.Locations.BestOrDefault();
public override void WriteId(EscapingTextWriter trapFile)
{
trapFile.WriteSubId(ContainingType!);
@@ -31,8 +27,8 @@ namespace Semmle.Extraction.CSharp.Entities
var type = Type.Create(Context, Symbol.Type);
trapFile.events(this, Symbol.GetName(), ContainingType!, type.TypeRef, Create(Context, Symbol.OriginalDefinition));
var adder = BodyDeclaringSymbol.AddMethod;
var remover = BodyDeclaringSymbol.RemoveMethod;
var adder = Symbol.AddMethod;
var remover = Symbol.RemoveMethod;
if (adder is not null)
Method.Create(Context, adder);
@@ -76,7 +72,7 @@ namespace Semmle.Extraction.CSharp.Entities
}
}
public static Event Create(Context cx, IEventSymbol symbol) => EventFactory.Instance.CreateEntityFromSymbol(cx, symbol);
public static Event Create(Context cx, IEventSymbol symbol) => EventFactory.Instance.CreateEntityFromSymbol(cx, symbol.GetBodyDeclaringSymbol());
private class EventFactory : CachedEntityFactory<IEventSymbol, Event>
{

View File

@@ -20,8 +20,8 @@ namespace Semmle.Extraction.CSharp.Entities
var type = Type.Create(Context, Symbol.Type);
trapFile.indexers(this, Symbol.GetName(useMetadataName: true), ContainingType!, type.TypeRef, OriginalDefinition);
var getter = BodyDeclaringSymbol.GetMethod;
var setter = BodyDeclaringSymbol.SetMethod;
var getter = Symbol.GetMethod;
var setter = Symbol.SetMethod;
if (getter is null && setter is null)
Context.ModelError(Symbol, "No indexer accessor defined");
@@ -81,7 +81,7 @@ namespace Semmle.Extraction.CSharp.Entities
TypeMention.Create(Context, syntax.Type, this, type);
}
public static new Indexer Create(Context cx, IPropertySymbol prop) => IndexerFactory.Instance.CreateEntityFromSymbol(cx, prop);
public static new Indexer Create(Context cx, IPropertySymbol prop) => IndexerFactory.Instance.CreateEntityFromSymbol(cx, prop.GetBodyDeclaringSymbol());
public override void WriteId(EscapingTextWriter trapFile)
{

View File

@@ -21,10 +21,6 @@ namespace Semmle.Extraction.CSharp.Entities
private Type Type => type.Value;
protected override IPropertySymbol BodyDeclaringSymbol => Symbol.PartialImplementationPart ?? Symbol;
public override Microsoft.CodeAnalysis.Location? ReportingLocation => BodyDeclaringSymbol.Locations.BestOrDefault();
public override void WriteId(EscapingTextWriter trapFile)
{
trapFile.WriteSubId(Type);
@@ -46,8 +42,8 @@ namespace Semmle.Extraction.CSharp.Entities
var type = Type;
trapFile.properties(this, Symbol.GetName(), ContainingType!, type.TypeRef, Create(Context, Symbol.OriginalDefinition));
var getter = BodyDeclaringSymbol.GetMethod;
var setter = BodyDeclaringSymbol.SetMethod;
var getter = Symbol.GetMethod;
var setter = Symbol.SetMethod;
if (getter is not null)
Method.Create(Context, getter);
@@ -132,7 +128,7 @@ namespace Semmle.Extraction.CSharp.Entities
{
var isIndexer = prop.IsIndexer || prop.Parameters.Any();
return isIndexer ? Indexer.Create(cx, prop) : PropertyFactory.Instance.CreateEntityFromSymbol(cx, prop);
return isIndexer ? Indexer.Create(cx, prop) : PropertyFactory.Instance.CreateEntityFromSymbol(cx, prop.GetBodyDeclaringSymbol());
}
private class PropertyFactory : CachedEntityFactory<IPropertySymbol, Property>