Skip to content

Commit 9ec0c8f

Browse files
committed
C#: Qualify type parameters with the entity that declares them
1 parent 39eb1a3 commit 9ec0c8f

File tree

6 files changed

+42
-27
lines changed

6 files changed

+42
-27
lines changed

csharp/extractor/Semmle.Extraction.CSharp/Entities/Constructor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ public override void WriteId(TextWriter trapFile)
114114
{
115115
if (symbol.IsStatic) trapFile.Write("static");
116116
trapFile.WriteSubId(ContainingType);
117-
AddParametersToId(Context, trapFile, symbol);
117+
AddParametersToId(Context, trapFile, symbol, symbol);
118118
trapFile.Write(";constructor");
119119
}
120120

csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,12 @@ protected static void BuildMethodId(Method m, TextWriter trapFile)
129129
// Type arguments with different nullability can result in
130130
// a constructed method with different nullability of its parameters and return type,
131131
// so we need to create a distinct database entity for it.
132-
trapFile.BuildList(",", m.symbol.GetAnnotatedTypeArguments(), (ta, tb0) => { AddSignatureTypeToId(m.Context, tb0, m.symbol, ta.Symbol); trapFile.Write((int)ta.Nullability); });
132+
trapFile.BuildList(",", m.symbol.GetAnnotatedTypeArguments(), (ta, tb0) => { AddSignatureTypeToId(m.Context, tb0, m.symbol, ta.Symbol, m.symbol); trapFile.Write((int)ta.Nullability); });
133133
trapFile.Write('>');
134134
}
135135
}
136136

137-
AddParametersToId(m.Context, trapFile, m.symbol);
137+
AddParametersToId(m.Context, trapFile, m.symbol, m.symbol);
138138
switch (m.symbol.MethodKind)
139139
{
140140
case MethodKind.PropertyGet:
@@ -199,26 +199,26 @@ public override void WriteId(TextWriter trapFile)
199199
/// to make the reference to <code>#3</code> in the label definition <code>#4</code> for
200200
/// <code>T</code> valid.
201201
/// </summary>
202-
protected static void AddSignatureTypeToId(Context cx, TextWriter trapFile, IMethodSymbol method, ITypeSymbol type)
202+
protected static void AddSignatureTypeToId(Context cx, TextWriter trapFile, IMethodSymbol method, ITypeSymbol type, ISymbol symbolBeingDefined)
203203
{
204-
type.BuildTypeId(cx, trapFile, false, (cx0, tb0, type0) => AddSignatureTypeToId(cx, tb0, method, type0));
204+
type.BuildTypeId(cx, trapFile, false, symbolBeingDefined, (cx0, tb0, type0, g) => AddSignatureTypeToId(cx, tb0, method, type0, g));
205205
}
206206

207-
protected static void AddParametersToId(Context cx, TextWriter trapFile, IMethodSymbol method)
207+
protected static void AddParametersToId(Context cx, TextWriter trapFile, IMethodSymbol method, ISymbol generic)
208208
{
209209
trapFile.Write('(');
210210
int index = 0;
211211

212212
if (method.MethodKind == MethodKind.ReducedExtension)
213213
{
214214
trapFile.WriteSeparator(",", ref index);
215-
AddSignatureTypeToId(cx, trapFile, method, method.ReceiverType);
215+
AddSignatureTypeToId(cx, trapFile, method, method.ReceiverType, generic);
216216
}
217217

218218
foreach (var param in method.Parameters)
219219
{
220220
trapFile.WriteSeparator(",", ref index);
221-
AddSignatureTypeToId(cx, trapFile, method, param.Type);
221+
AddSignatureTypeToId(cx, trapFile, method, param.Type, generic);
222222
switch (param.RefKind)
223223
{
224224
case RefKind.Out:

csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/NamedType.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ public override IEnumerable<Extraction.Entities.Location> Locations
111111

112112
public override void WriteId(TextWriter trapFile)
113113
{
114-
symbol.BuildTypeId(Context, trapFile, true, (cx0, tb0, sub) => tb0.WriteSubId(Create(cx0, sub)));
114+
symbol.BuildTypeId(Context, trapFile, true, symbol, (cx0, tb0, sub, g) => tb0.WriteSubId(Create(cx0, sub)));
115115
trapFile.Write(";type");
116116
}
117117

@@ -177,11 +177,11 @@ class NamedTypeRefFactory : ICachedEntityFactory<INamedTypeSymbol, NamedTypeRef>
177177

178178
public override void WriteId(TextWriter trapFile)
179179
{
180-
void WriteType(Context cx, TextWriter trapFile, ITypeSymbol symbol)
180+
void WriteType(Context cx, TextWriter trapFile, ITypeSymbol symbol, ISymbol symbolBeingDefined)
181181
{
182-
symbol.BuildTypeId(cx, trapFile, false, WriteType);
182+
symbol.BuildTypeId(cx, trapFile, false, symbolBeingDefined, WriteType);
183183
}
184-
WriteType(Context, trapFile, referencedType.symbol);
184+
WriteType(Context, trapFile, referencedType.symbol, referencedType.symbol);
185185
trapFile.Write(";typeRef");
186186
}
187187

csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/TupleType.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class TupleTypeFactory : ICachedEntityFactory<INamedTypeSymbol, TupleType>
3232

3333
public override void WriteId(TextWriter trapFile)
3434
{
35-
symbol.BuildTypeId(Context, trapFile, false, (cx0, tb0, sub) => tb0.WriteSubId(Create(cx0, sub)));
35+
symbol.BuildTypeId(Context, trapFile, false, symbol, (cx0, tb0, sub, g) => tb0.WriteSubId(Create(cx0, sub)));
3636
trapFile.Write(";tuple");
3737
}
3838

csharp/extractor/Semmle.Extraction.CSharp/Entities/UserOperator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public override Type ContainingType
5151

5252
public override void WriteId(TextWriter trapFile)
5353
{
54-
AddSignatureTypeToId(Context, trapFile, symbol, symbol.ReturnType); // Needed for op_explicit(), which differs only by return type.
54+
AddSignatureTypeToId(Context, trapFile, symbol, symbol.ReturnType, symbol); // Needed for op_explicit(), which differs only by return type.
5555
trapFile.Write(' ');
5656
BuildMethodId(this, trapFile);
5757
}

csharp/extractor/Semmle.Extraction.CSharp/SymbolExtensions.cs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ public static bool ContainsTypeParameters(this ITypeSymbol type, Context cx, ISy
131131
/// <param name="cx">The extraction context.</param>
132132
/// <param name="trapFile">The trap builder used to store the result.</param>
133133
/// <param name="subTermAction">The action to apply to syntactic sub terms of this type.</param>
134-
public static void BuildTypeId(this ITypeSymbol type, Context cx, TextWriter trapFile, bool prefix, Action<Context, TextWriter, ITypeSymbol> subTermAction)
134+
public static void BuildTypeId(this ITypeSymbol type, Context cx, TextWriter trapFile, bool prefix, ISymbol SymbolBeingDefined, Action<Context, TextWriter, ITypeSymbol, ISymbol> subTermAction)
135135
{
136136
if (type.SpecialType != SpecialType.None && !(type is INamedTypeSymbol n && n.IsGenericType))
137137
{
@@ -150,7 +150,7 @@ public static void BuildTypeId(this ITypeSymbol type, Context cx, TextWriter tra
150150
{
151151
case TypeKind.Array:
152152
var array = (IArrayTypeSymbol)type;
153-
subTermAction(cx, trapFile, array.ElementType);
153+
subTermAction(cx, trapFile, array.ElementType, SymbolBeingDefined);
154154
array.BuildArraySuffix(trapFile);
155155
return;
156156
case TypeKind.Class:
@@ -160,15 +160,30 @@ public static void BuildTypeId(this ITypeSymbol type, Context cx, TextWriter tra
160160
case TypeKind.Delegate:
161161
case TypeKind.Error:
162162
var named = (INamedTypeSymbol)type;
163-
named.BuildNamedTypeId(cx, trapFile, prefix, subTermAction);
163+
named.BuildNamedTypeId(cx, trapFile, prefix, SymbolBeingDefined, subTermAction);
164164
return;
165165
case TypeKind.Pointer:
166166
var ptr = (IPointerTypeSymbol)type;
167-
subTermAction(cx, trapFile, ptr.PointedAtType);
167+
subTermAction(cx, trapFile, ptr.PointedAtType, SymbolBeingDefined);
168168
trapFile.Write('*');
169169
return;
170170
case TypeKind.TypeParameter:
171171
var tp = (ITypeParameterSymbol)type;
172+
if (!SymbolEqualityComparer.Default.Equals(tp.ContainingSymbol, SymbolBeingDefined))
173+
{
174+
switch (tp.TypeParameterKind)
175+
{
176+
case TypeParameterKind.Method:
177+
var method = Method.Create(cx, (IMethodSymbol)tp.ContainingSymbol);
178+
trapFile.WriteSubId(method);
179+
trapFile.Write('_');
180+
break;
181+
case TypeParameterKind.Type:
182+
subTermAction(cx, trapFile, tp.ContainingType, SymbolBeingDefined);
183+
trapFile.Write('_');
184+
break;
185+
}
186+
}
172187
trapFile.Write(tp.Name);
173188
return;
174189
case TypeKind.Dynamic:
@@ -211,7 +226,7 @@ private static void BuildAssembly(IAssemblySymbol asm, TextWriter trapFile, bool
211226
trapFile.Write("::");
212227
}
213228

214-
static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, TextWriter trapFile, bool prefixAssembly, Action<Context, TextWriter, ITypeSymbol> subTermAction)
229+
static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, TextWriter trapFile, bool prefixAssembly, ISymbol symbolBeingDefined, Action<Context, TextWriter, ITypeSymbol, ISymbol> subTermAction)
215230
{
216231
if (named.ContainingAssembly is null) prefixAssembly = false;
217232

@@ -223,7 +238,7 @@ static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, TextWriter
223238
{
224239
trapFile.Write(f.Name);
225240
trapFile.Write(":");
226-
subTermAction(cx, tb0, f.Type);
241+
subTermAction(cx, tb0, f.Type, symbolBeingDefined);
227242
}
228243
);
229244
trapFile.Write(")");
@@ -232,7 +247,7 @@ static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, TextWriter
232247

233248
if (named.ContainingType != null)
234249
{
235-
subTermAction(cx, trapFile, named.ContainingType);
250+
subTermAction(cx, trapFile, named.ContainingType, symbolBeingDefined);
236251
trapFile.Write('.');
237252
}
238253
else if (named.ContainingNamespace != null)
@@ -254,14 +269,14 @@ static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, TextWriter
254269
}
255270
else
256271
{
257-
subTermAction(cx, trapFile, named.ConstructedFrom);
272+
subTermAction(cx, trapFile, named.ConstructedFrom, symbolBeingDefined);
258273
trapFile.Write('<');
259274
// Encode the nullability of the type arguments in the label.
260275
// Type arguments with different nullability can result in
261276
// a constructed type with different nullability of its members and methods,
262277
// so we need to create a distinct database entity for it.
263278
trapFile.BuildList(",", named.GetAnnotatedTypeArguments(),
264-
(ta, tb0) => subTermAction(cx, tb0, ta.Symbol)
279+
(ta, tb0) => subTermAction(cx, tb0, ta.Symbol, symbolBeingDefined)
265280
);
266281
trapFile.Write('>');
267282
}
@@ -273,16 +288,16 @@ static void BuildNamespace(this INamespaceSymbol ns, Context cx, TextWriter trap
273288
trapFile.Write('.');
274289
}
275290

276-
static void BuildAnonymousName(this ITypeSymbol type, Context cx, TextWriter trapFile, Action<Context, TextWriter, ITypeSymbol> subTermAction, bool includeParamName)
291+
static void BuildAnonymousName(this ITypeSymbol type, Context cx, TextWriter trapFile, Action<Context, TextWriter, ITypeSymbol, ISymbol> subTermAction, bool includeParamName)
277292
{
278293
var buildParam = includeParamName
279294
? (prop, tb0) =>
280295
{
281296
tb0.Write(prop.Name);
282297
tb0.Write(' ');
283-
subTermAction(cx, tb0, prop.Type);
298+
subTermAction(cx, tb0, prop.Type, null);
284299
}
285-
: (Action<IPropertySymbol, TextWriter>)((prop, tb0) => subTermAction(cx, tb0, prop.Type));
300+
: (Action<IPropertySymbol, TextWriter>)((prop, tb0) => subTermAction(cx, tb0, prop.Type, null));
286301
int memberCount = type.GetMembers().OfType<IPropertySymbol>().Count();
287302
int hackTypeNumber = memberCount == 1 ? 1 : 0;
288303
trapFile.Write("<>__AnonType");
@@ -354,7 +369,7 @@ public static void BuildNamedTypeDisplayName(this INamedTypeSymbol namedType, Co
354369

355370
if (namedType.IsAnonymousType)
356371
{
357-
namedType.BuildAnonymousName(cx, trapFile, (cx0, tb0, sub) => sub.BuildDisplayName(cx0, tb0), false);
372+
namedType.BuildAnonymousName(cx, trapFile, (cx0, tb0, sub, _) => sub.BuildDisplayName(cx0, tb0), false);
358373
}
359374

360375
trapFile.Write(namedType.Name);

0 commit comments

Comments
 (0)