C#: Only extract the unbound locations for constructors, destructors and user defined operators and use this in the QL code.

This commit is contained in:
Michael Nebel
2025-10-09 14:03:14 +02:00
parent 02428fc467
commit 89681a49e6
4 changed files with 24 additions and 7 deletions

View File

@@ -29,7 +29,10 @@ namespace Semmle.Extraction.CSharp.Entities
ContainingType!.PopulateGenerics();
trapFile.constructors(this, Symbol.ContainingType.Name, ContainingType, (Constructor)OriginalDefinition);
WriteLocationToTrap(trapFile.constructor_location, this, Location);
if (Context.ExtractLocation(Symbol) && (!IsDefault || IsBestSourceLocation))
{
WriteLocationToTrap(trapFile.constructor_location, this, Location);
}
if (MakeSynthetic)
{
@@ -168,7 +171,15 @@ namespace Semmle.Extraction.CSharp.Entities
Symbol.ContainingType.IsSourceDeclaration() &&
!Symbol.ContainingType.IsAnonymousType;
private bool MakeSynthetic => IsPrimary || IsDefault;
/// <summary>
/// Returns true if we consider the reporting location of this constructor entity the best
/// location of the constructor.
/// For partial classes with default constructors, Roslyn consider each partial class declaration
/// as the possible location for the implicit default constructor.
/// </summary>
private bool IsBestSourceLocation => ReportingLocation is not null && Context.IsLocationInContext(ReportingLocation);
private bool MakeSynthetic => IsPrimary || (IsDefault && IsBestSourceLocation);
[return: NotNullIfNotNull(nameof(constructor))]
public static new Constructor? Create(Context cx, IMethodSymbol? constructor)

View File

@@ -15,7 +15,10 @@ namespace Semmle.Extraction.CSharp.Entities
ContainingType!.PopulateGenerics();
trapFile.destructors(this, $"~{Symbol.ContainingType.Name}", ContainingType, OriginalDefinition(Context, this, Symbol));
WriteLocationToTrap(trapFile.destructor_location, this, Location);
if (Context.ExtractLocation(Symbol))
{
WriteLocationToTrap(trapFile.destructor_location, this, Location);
}
}
private static new Destructor OriginalDefinition(Context cx, Destructor original, IMethodSymbol symbol)

View File

@@ -26,7 +26,10 @@ namespace Semmle.Extraction.CSharp.Entities
returnType.TypeRef,
(UserOperator)OriginalDefinition);
WriteLocationsToTrap(trapFile.operator_location, this, Locations);
if (Context.ExtractLocation(Symbol))
{
WriteLocationsToTrap(trapFile.operator_location, this, Locations);
}
if (IsSourceDeclaration)
{

View File

@@ -357,7 +357,7 @@ class Constructor extends Callable, Member, Attributable, @constructor {
override Constructor getUnboundDeclaration() { constructors(this, _, _, result) }
override Location getALocation() { constructor_location(this, result) }
override Location getALocation() { constructor_location(this.getUnboundDeclaration(), result) }
override predicate fromSource() { Member.super.fromSource() and not this.isCompilerGenerated() }
@@ -450,7 +450,7 @@ class Destructor extends Callable, Member, Attributable, @destructor {
override Destructor getUnboundDeclaration() { destructors(this, _, _, result) }
override Location getALocation() { destructor_location(this, result) }
override Location getALocation() { destructor_location(this.getUnboundDeclaration(), result) }
override string toString() { result = Callable.super.toString() }
@@ -484,7 +484,7 @@ class Operator extends Callable, Member, Attributable, Overridable, @operator {
override Operator getUnboundDeclaration() { operators(this, _, _, _, _, result) }
override Location getALocation() { operator_location(this, result) }
override Location getALocation() { operator_location(this.getUnboundDeclaration(), result) }
override string toString() { result = Callable.super.toString() }