C#: Base IDs for constructed methods on their unconstructed counterparts

This commit is contained in:
Tom Hvitved
2021-05-25 13:40:30 +02:00
committed by Tamas Vajk
parent d044b15533
commit 3d60c146ad
2 changed files with 40 additions and 15 deletions

View File

@@ -146,6 +146,15 @@ namespace Semmle.Extraction.CSharp.Entities
public override void WriteId(EscapingTextWriter trapFile)
{
if (!SymbolEqualityComparer.Default.Equals(Symbol, Symbol.OriginalDefinition))
{
trapFile.WriteSubId(ContainingType!);
trapFile.Write(".");
trapFile.WriteSubId(OriginalDefinition);
trapFile.Write(";constructor");
return;
}
if (Symbol.IsStatic)
trapFile.Write("static");
trapFile.WriteSubId(ContainingType!);

View File

@@ -129,6 +129,30 @@ namespace Semmle.Extraction.CSharp.Entities
/// </summary>
private static void BuildMethodId(Method m, EscapingTextWriter trapFile)
{
if (!SymbolEqualityComparer.Default.Equals(m.Symbol, m.Symbol.OriginalDefinition))
{
if (!SymbolEqualityComparer.Default.Equals(m.Symbol, m.ConstructedFromSymbol))
{
trapFile.WriteSubId(Create(m.Context, m.ConstructedFromSymbol));
trapFile.Write('<');
// Encode the nullability of the type arguments in the label.
// Type arguments with different nullability can result in
// a constructed method with different nullability of its parameters and return type,
// so we need to create a distinct database entity for it.
trapFile.BuildList(",", m.Symbol.GetAnnotatedTypeArguments(), ta => { ta.Symbol.BuildOrWriteId(m.Context, trapFile, m.Symbol); trapFile.Write((int)ta.Nullability); });
trapFile.Write('>');
}
else
{
trapFile.WriteSubId(m.ContainingType!);
trapFile.Write(".");
trapFile.WriteSubId(m.OriginalDefinition);
}
WritePostfix(m, trapFile);
return;
}
m.Symbol.ReturnType.BuildOrWriteId(m.Context, trapFile, m.Symbol);
trapFile.Write(" ");
@@ -141,24 +165,16 @@ namespace Semmle.Extraction.CSharp.Entities
if (m.Symbol.IsGenericMethod)
{
if (SymbolEqualityComparer.Default.Equals(m.Symbol, m.Symbol.OriginalDefinition))
{
trapFile.Write('`');
trapFile.Write(m.Symbol.TypeParameters.Length);
}
else
{
trapFile.Write('<');
// Encode the nullability of the type arguments in the label.
// Type arguments with different nullability can result in
// a constructed method with different nullability of its parameters and return type,
// so we need to create a distinct database entity for it.
trapFile.BuildList(",", m.Symbol.GetAnnotatedTypeArguments(), ta => { ta.Symbol.BuildOrWriteId(m.Context, trapFile, m.Symbol); trapFile.Write((int)ta.Nullability); });
trapFile.Write('>');
}
trapFile.Write('`');
trapFile.Write(m.Symbol.TypeParameters.Length);
}
AddParametersToId(m.Context, trapFile, m.Symbol);
WritePostfix(m, trapFile);
}
private static void WritePostfix(Method m, EscapingTextWriter trapFile)
{
switch (m.Symbol.MethodKind)
{
case MethodKind.PropertyGet: