mirror of
https://github.com/github/codeql.git
synced 2026-04-26 09:15:12 +02:00
C#: Qualify type parameters with the entity that declares them
This commit is contained in:
@@ -114,7 +114,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
if (symbol.IsStatic) trapFile.Write("static");
|
||||
trapFile.WriteSubId(ContainingType);
|
||||
AddParametersToId(Context, trapFile, symbol);
|
||||
AddParametersToId(Context, trapFile, symbol, symbol);
|
||||
trapFile.Write(";constructor");
|
||||
}
|
||||
|
||||
|
||||
@@ -129,12 +129,12 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
// 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, tb0) => { AddSignatureTypeToId(m.Context, tb0, m.symbol, ta.Symbol); trapFile.Write((int)ta.Nullability); });
|
||||
trapFile.BuildList(",", m.symbol.GetAnnotatedTypeArguments(), (ta, tb0) => { AddSignatureTypeToId(m.Context, tb0, m.symbol, ta.Symbol, m.symbol); trapFile.Write((int)ta.Nullability); });
|
||||
trapFile.Write('>');
|
||||
}
|
||||
}
|
||||
|
||||
AddParametersToId(m.Context, trapFile, m.symbol);
|
||||
AddParametersToId(m.Context, trapFile, m.symbol, m.symbol);
|
||||
switch (m.symbol.MethodKind)
|
||||
{
|
||||
case MethodKind.PropertyGet:
|
||||
@@ -199,12 +199,12 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
/// to make the reference to <code>#3</code> in the label definition <code>#4</code> for
|
||||
/// <code>T</code> valid.
|
||||
/// </summary>
|
||||
protected static void AddSignatureTypeToId(Context cx, TextWriter trapFile, IMethodSymbol method, ITypeSymbol type)
|
||||
protected static void AddSignatureTypeToId(Context cx, TextWriter trapFile, IMethodSymbol method, ITypeSymbol type, ISymbol symbolBeingDefined)
|
||||
{
|
||||
type.BuildTypeId(cx, trapFile, false, (cx0, tb0, type0) => AddSignatureTypeToId(cx, tb0, method, type0));
|
||||
type.BuildTypeId(cx, trapFile, false, symbolBeingDefined, (cx0, tb0, type0, g) => AddSignatureTypeToId(cx, tb0, method, type0, g));
|
||||
}
|
||||
|
||||
protected static void AddParametersToId(Context cx, TextWriter trapFile, IMethodSymbol method)
|
||||
protected static void AddParametersToId(Context cx, TextWriter trapFile, IMethodSymbol method, ISymbol generic)
|
||||
{
|
||||
trapFile.Write('(');
|
||||
int index = 0;
|
||||
@@ -212,13 +212,13 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
if (method.MethodKind == MethodKind.ReducedExtension)
|
||||
{
|
||||
trapFile.WriteSeparator(",", ref index);
|
||||
AddSignatureTypeToId(cx, trapFile, method, method.ReceiverType);
|
||||
AddSignatureTypeToId(cx, trapFile, method, method.ReceiverType, generic);
|
||||
}
|
||||
|
||||
foreach (var param in method.Parameters)
|
||||
{
|
||||
trapFile.WriteSeparator(",", ref index);
|
||||
AddSignatureTypeToId(cx, trapFile, method, param.Type);
|
||||
AddSignatureTypeToId(cx, trapFile, method, param.Type, generic);
|
||||
switch (param.RefKind)
|
||||
{
|
||||
case RefKind.Out:
|
||||
|
||||
@@ -108,7 +108,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
{
|
||||
symbol.BuildTypeId(Context, trapFile, true, (cx0, tb0, sub) => tb0.WriteSubId(Create(cx0, sub)));
|
||||
symbol.BuildTypeId(Context, trapFile, true, symbol, (cx0, tb0, sub, g) => tb0.WriteSubId(Create(cx0, sub)));
|
||||
trapFile.Write(";type");
|
||||
}
|
||||
|
||||
@@ -174,11 +174,11 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
{
|
||||
void WriteType(Context cx, TextWriter trapFile, ITypeSymbol symbol)
|
||||
void WriteType(Context cx, TextWriter trapFile, ITypeSymbol symbol, ISymbol symbolBeingDefined)
|
||||
{
|
||||
symbol.BuildTypeId(cx, trapFile, false, WriteType);
|
||||
symbol.BuildTypeId(cx, trapFile, false, symbolBeingDefined, WriteType);
|
||||
}
|
||||
WriteType(Context, trapFile, referencedType.symbol);
|
||||
WriteType(Context, trapFile, referencedType.symbol, referencedType.symbol);
|
||||
trapFile.Write(";typeRef");
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
{
|
||||
symbol.BuildTypeId(Context, trapFile, false, (cx0, tb0, sub) => tb0.WriteSubId(Create(cx0, sub)));
|
||||
symbol.BuildTypeId(Context, trapFile, false, symbol, (cx0, tb0, sub, g) => tb0.WriteSubId(Create(cx0, sub)));
|
||||
trapFile.Write(";tuple");
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
{
|
||||
AddSignatureTypeToId(Context, trapFile, symbol, symbol.ReturnType); // Needed for op_explicit(), which differs only by return type.
|
||||
AddSignatureTypeToId(Context, trapFile, symbol, symbol.ReturnType, symbol); // Needed for op_explicit(), which differs only by return type.
|
||||
trapFile.Write(' ');
|
||||
BuildMethodId(this, trapFile);
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ namespace Semmle.Extraction.CSharp
|
||||
/// <param name="cx">The extraction context.</param>
|
||||
/// <param name="trapFile">The trap builder used to store the result.</param>
|
||||
/// <param name="subTermAction">The action to apply to syntactic sub terms of this type.</param>
|
||||
public static void BuildTypeId(this ITypeSymbol type, Context cx, TextWriter trapFile, bool prefix, Action<Context, TextWriter, ITypeSymbol> subTermAction)
|
||||
public static void BuildTypeId(this ITypeSymbol type, Context cx, TextWriter trapFile, bool prefix, ISymbol SymbolBeingDefined, Action<Context, TextWriter, ITypeSymbol, ISymbol> subTermAction)
|
||||
{
|
||||
if (type.SpecialType != SpecialType.None && !(type is INamedTypeSymbol n && n.IsGenericType))
|
||||
{
|
||||
@@ -150,7 +150,7 @@ namespace Semmle.Extraction.CSharp
|
||||
{
|
||||
case TypeKind.Array:
|
||||
var array = (IArrayTypeSymbol)type;
|
||||
subTermAction(cx, trapFile, array.ElementType);
|
||||
subTermAction(cx, trapFile, array.ElementType, SymbolBeingDefined);
|
||||
array.BuildArraySuffix(trapFile);
|
||||
return;
|
||||
case TypeKind.Class:
|
||||
@@ -160,15 +160,30 @@ namespace Semmle.Extraction.CSharp
|
||||
case TypeKind.Delegate:
|
||||
case TypeKind.Error:
|
||||
var named = (INamedTypeSymbol)type;
|
||||
named.BuildNamedTypeId(cx, trapFile, prefix, subTermAction);
|
||||
named.BuildNamedTypeId(cx, trapFile, prefix, SymbolBeingDefined, subTermAction);
|
||||
return;
|
||||
case TypeKind.Pointer:
|
||||
var ptr = (IPointerTypeSymbol)type;
|
||||
subTermAction(cx, trapFile, ptr.PointedAtType);
|
||||
subTermAction(cx, trapFile, ptr.PointedAtType, SymbolBeingDefined);
|
||||
trapFile.Write('*');
|
||||
return;
|
||||
case TypeKind.TypeParameter:
|
||||
var tp = (ITypeParameterSymbol)type;
|
||||
if (!SymbolEqualityComparer.Default.Equals(tp.ContainingSymbol, SymbolBeingDefined))
|
||||
{
|
||||
switch (tp.TypeParameterKind)
|
||||
{
|
||||
case TypeParameterKind.Method:
|
||||
var method = Method.Create(cx, (IMethodSymbol)tp.ContainingSymbol);
|
||||
trapFile.WriteSubId(method);
|
||||
trapFile.Write('_');
|
||||
break;
|
||||
case TypeParameterKind.Type:
|
||||
subTermAction(cx, trapFile, tp.ContainingType, SymbolBeingDefined);
|
||||
trapFile.Write('_');
|
||||
break;
|
||||
}
|
||||
}
|
||||
trapFile.Write(tp.Name);
|
||||
return;
|
||||
case TypeKind.Dynamic:
|
||||
@@ -211,7 +226,7 @@ namespace Semmle.Extraction.CSharp
|
||||
trapFile.Write("::");
|
||||
}
|
||||
|
||||
static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, TextWriter trapFile, bool prefixAssembly, Action<Context, TextWriter, ITypeSymbol> subTermAction)
|
||||
static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, TextWriter trapFile, bool prefixAssembly, ISymbol symbolBeingDefined, Action<Context, TextWriter, ITypeSymbol, ISymbol> subTermAction)
|
||||
{
|
||||
if (named.ContainingAssembly is null) prefixAssembly = false;
|
||||
|
||||
@@ -223,7 +238,7 @@ namespace Semmle.Extraction.CSharp
|
||||
{
|
||||
trapFile.Write(f.Name);
|
||||
trapFile.Write(":");
|
||||
subTermAction(cx, tb0, f.Type);
|
||||
subTermAction(cx, tb0, f.Type, symbolBeingDefined);
|
||||
}
|
||||
);
|
||||
trapFile.Write(")");
|
||||
@@ -232,7 +247,7 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
if (named.ContainingType != null)
|
||||
{
|
||||
subTermAction(cx, trapFile, named.ContainingType);
|
||||
subTermAction(cx, trapFile, named.ContainingType, symbolBeingDefined);
|
||||
trapFile.Write('.');
|
||||
}
|
||||
else if (named.ContainingNamespace != null)
|
||||
@@ -254,14 +269,14 @@ namespace Semmle.Extraction.CSharp
|
||||
}
|
||||
else
|
||||
{
|
||||
subTermAction(cx, trapFile, named.ConstructedFrom);
|
||||
subTermAction(cx, trapFile, named.ConstructedFrom, symbolBeingDefined);
|
||||
trapFile.Write('<');
|
||||
// Encode the nullability of the type arguments in the label.
|
||||
// Type arguments with different nullability can result in
|
||||
// a constructed type with different nullability of its members and methods,
|
||||
// so we need to create a distinct database entity for it.
|
||||
trapFile.BuildList(",", named.GetAnnotatedTypeArguments(),
|
||||
(ta, tb0) => subTermAction(cx, tb0, ta.Symbol)
|
||||
(ta, tb0) => subTermAction(cx, tb0, ta.Symbol, symbolBeingDefined)
|
||||
);
|
||||
trapFile.Write('>');
|
||||
}
|
||||
@@ -273,16 +288,16 @@ namespace Semmle.Extraction.CSharp
|
||||
trapFile.Write('.');
|
||||
}
|
||||
|
||||
static void BuildAnonymousName(this ITypeSymbol type, Context cx, TextWriter trapFile, Action<Context, TextWriter, ITypeSymbol> subTermAction, bool includeParamName)
|
||||
static void BuildAnonymousName(this ITypeSymbol type, Context cx, TextWriter trapFile, Action<Context, TextWriter, ITypeSymbol, ISymbol> subTermAction, bool includeParamName)
|
||||
{
|
||||
var buildParam = includeParamName
|
||||
? (prop, tb0) =>
|
||||
{
|
||||
tb0.Write(prop.Name);
|
||||
tb0.Write(' ');
|
||||
subTermAction(cx, tb0, prop.Type);
|
||||
subTermAction(cx, tb0, prop.Type, null);
|
||||
}
|
||||
: (Action<IPropertySymbol, TextWriter>)((prop, tb0) => subTermAction(cx, tb0, prop.Type));
|
||||
: (Action<IPropertySymbol, TextWriter>)((prop, tb0) => subTermAction(cx, tb0, prop.Type, null));
|
||||
int memberCount = type.GetMembers().OfType<IPropertySymbol>().Count();
|
||||
int hackTypeNumber = memberCount == 1 ? 1 : 0;
|
||||
trapFile.Write("<>__AnonType");
|
||||
@@ -354,7 +369,7 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
if (namedType.IsAnonymousType)
|
||||
{
|
||||
namedType.BuildAnonymousName(cx, trapFile, (cx0, tb0, sub) => sub.BuildDisplayName(cx0, tb0), false);
|
||||
namedType.BuildAnonymousName(cx, trapFile, (cx0, tb0, sub, _) => sub.BuildDisplayName(cx0, tb0), false);
|
||||
}
|
||||
|
||||
trapFile.Write(namedType.Name);
|
||||
|
||||
Reference in New Issue
Block a user