Skip to content

Commit 8d7f8a5

Browse files
authored
Merge pull request github#5997 from tamasvajk/fix/colliding-method-ids
C#: Base IDs for constructed methods on their unconstructed counterparts
2 parents 63c6ddd + 5a3a011 commit 8d7f8a5

18 files changed

+702
-542
lines changed

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,15 @@ private ConstructorDeclarationSyntax? Syntax
146146

147147
public override void WriteId(EscapingTextWriter trapFile)
148148
{
149+
if (!SymbolEqualityComparer.Default.Equals(Symbol, Symbol.OriginalDefinition))
150+
{
151+
trapFile.WriteSubId(ContainingType!);
152+
trapFile.Write(".");
153+
trapFile.WriteSubId(OriginalDefinition);
154+
trapFile.Write(";constructor");
155+
return;
156+
}
157+
149158
if (Symbol.IsStatic)
150159
trapFile.Write("static");
151160
trapFile.WriteSubId(ContainingType!);

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

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,30 @@ public void Overrides(TextWriter trapFile)
129129
/// </summary>
130130
private static void BuildMethodId(Method m, EscapingTextWriter trapFile)
131131
{
132+
if (!SymbolEqualityComparer.Default.Equals(m.Symbol, m.Symbol.OriginalDefinition))
133+
{
134+
if (!SymbolEqualityComparer.Default.Equals(m.Symbol, m.ConstructedFromSymbol))
135+
{
136+
trapFile.WriteSubId(Create(m.Context, m.ConstructedFromSymbol));
137+
trapFile.Write('<');
138+
// Encode the nullability of the type arguments in the label.
139+
// Type arguments with different nullability can result in
140+
// a constructed method with different nullability of its parameters and return type,
141+
// so we need to create a distinct database entity for it.
142+
trapFile.BuildList(",", m.Symbol.GetAnnotatedTypeArguments(), ta => { ta.Symbol.BuildOrWriteId(m.Context, trapFile, m.Symbol); trapFile.Write((int)ta.Nullability); });
143+
trapFile.Write('>');
144+
}
145+
else
146+
{
147+
trapFile.WriteSubId(m.ContainingType!);
148+
trapFile.Write(".");
149+
trapFile.WriteSubId(m.OriginalDefinition);
150+
}
151+
152+
WritePostfix(m, trapFile);
153+
return;
154+
}
155+
132156
m.Symbol.ReturnType.BuildOrWriteId(m.Context, trapFile, m.Symbol);
133157
trapFile.Write(" ");
134158

@@ -141,24 +165,16 @@ private static void BuildMethodId(Method m, EscapingTextWriter trapFile)
141165

142166
if (m.Symbol.IsGenericMethod)
143167
{
144-
if (SymbolEqualityComparer.Default.Equals(m.Symbol, m.Symbol.OriginalDefinition))
145-
{
146-
trapFile.Write('`');
147-
trapFile.Write(m.Symbol.TypeParameters.Length);
148-
}
149-
else
150-
{
151-
trapFile.Write('<');
152-
// Encode the nullability of the type arguments in the label.
153-
// Type arguments with different nullability can result in
154-
// a constructed method with different nullability of its parameters and return type,
155-
// so we need to create a distinct database entity for it.
156-
trapFile.BuildList(",", m.Symbol.GetAnnotatedTypeArguments(), ta => { ta.Symbol.BuildOrWriteId(m.Context, trapFile, m.Symbol); trapFile.Write((int)ta.Nullability); });
157-
trapFile.Write('>');
158-
}
168+
trapFile.Write('`');
169+
trapFile.Write(m.Symbol.TypeParameters.Length);
159170
}
160171

161172
AddParametersToId(m.Context, trapFile, m.Symbol);
173+
WritePostfix(m, trapFile);
174+
}
175+
176+
private static void WritePostfix(Method m, EscapingTextWriter trapFile)
177+
{
162178
switch (m.Symbol.MethodKind)
163179
{
164180
case MethodKind.PropertyGet:
Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
| methods.cs:118:44:118:55 | call to method ToInt32 | 0 | methods.cs:118:52:118:54 | "0" |
2-
| methods.cs:127:34:127:52 | call to method Slice | 0 | methods.cs:127:34:127:40 | access to local variable strings |
3-
| methods.cs:127:34:127:52 | call to method Slice | 1 | methods.cs:127:48:127:48 | 1 |
4-
| methods.cs:127:34:127:52 | call to method Slice | 2 | methods.cs:127:51:127:51 | 2 |
5-
| methods.cs:129:42:129:52 | call to method ToInt32 | 0 | methods.cs:129:42:129:42 | access to local variable s |
6-
| methods.cs:132:13:132:34 | call to method ToInt32 | 0 | methods.cs:132:32:132:33 | "" |
7-
| methods.cs:132:13:132:34 | call to method ToInt32 | -1 | methods.cs:132:13:132:22 | access to type Extensions |
8-
| methods.cs:134:13:134:49 | call to method ToBool | 0 | methods.cs:134:31:134:36 | "true" |
9-
| methods.cs:134:13:134:49 | call to method ToBool | 1 | methods.cs:134:39:134:48 | delegate creation of type Func<String,Boolean> |
10-
| methods.cs:134:13:134:49 | call to method ToBool | -1 | methods.cs:134:13:134:22 | access to type Extensions |
11-
| methods.cs:180:20:180:39 | call to method SkipTwo | 0 | methods.cs:180:20:180:23 | access to parameter list |
12-
| methods.cs:180:20:180:39 | call to method SkipTwo | 1 | methods.cs:180:38:180:38 | access to parameter i |
1+
| methods.cs:119:44:119:55 | call to method ToInt32 | 0 | methods.cs:119:52:119:54 | "0" |
2+
| methods.cs:128:34:128:52 | call to method Slice | 0 | methods.cs:128:34:128:40 | access to local variable strings |
3+
| methods.cs:128:34:128:52 | call to method Slice | 1 | methods.cs:128:48:128:48 | 1 |
4+
| methods.cs:128:34:128:52 | call to method Slice | 2 | methods.cs:128:51:128:51 | 2 |
5+
| methods.cs:130:42:130:52 | call to method ToInt32 | 0 | methods.cs:130:42:130:42 | access to local variable s |
6+
| methods.cs:133:13:133:34 | call to method ToInt32 | 0 | methods.cs:133:32:133:33 | "" |
7+
| methods.cs:133:13:133:34 | call to method ToInt32 | -1 | methods.cs:133:13:133:22 | access to type Extensions |
8+
| methods.cs:135:13:135:49 | call to method ToBool | 0 | methods.cs:135:31:135:36 | "true" |
9+
| methods.cs:135:13:135:49 | call to method ToBool | 1 | methods.cs:135:39:135:48 | delegate creation of type Func<String,Boolean> |
10+
| methods.cs:135:13:135:49 | call to method ToBool | -1 | methods.cs:135:13:135:22 | access to type Extensions |
11+
| methods.cs:181:20:181:39 | call to method SkipTwo | 0 | methods.cs:181:20:181:23 | access to parameter list |
12+
| methods.cs:181:20:181:39 | call to method SkipTwo | 1 | methods.cs:181:38:181:38 | access to parameter i |
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
| methods.cs:9:21:9:24 | Swap |
1+
| methods.cs:10:21:10:24 | Swap |
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
| methods.cs:28:28:28:33 | Divide |
1+
| methods.cs:29:28:29:33 | Divide |
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
| methods.cs:49:11:49:25 | TestOverloading |
1+
| methods.cs:50:11:50:25 | TestOverloading |
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
| methods.cs:49:11:49:25 | TestOverloading | methods.cs:57:21:57:21 | F | Object |
1+
| methods.cs:50:11:50:25 | TestOverloading | methods.cs:58:21:58:21 | F | Object |
Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,28 @@
1-
| methods.cs:16:14:16:17 | Main | methods.cs:9:21:9:24 | Swap | methods.cs:6:18:6:24 | TestRef |
2-
| methods.cs:16:14:16:17 | Main | methods.cs:46:28:46:36 | WriteLine | methods.cs:6:18:6:24 | TestRef |
3-
| methods.cs:34:14:34:17 | Main | methods.cs:28:28:28:33 | Divide | methods.cs:25:18:25:24 | TestOut |
4-
| methods.cs:34:14:34:17 | Main | methods.cs:46:28:46:36 | WriteLine | methods.cs:25:18:25:24 | TestOut |
5-
| methods.cs:52:21:52:21 | F | methods.cs:46:28:46:36 | WriteLine | methods.cs:49:11:49:25 | TestOverloading |
6-
| methods.cs:57:21:57:21 | F | methods.cs:46:28:46:36 | WriteLine | methods.cs:49:11:49:25 | TestOverloading |
7-
| methods.cs:62:21:62:21 | F | methods.cs:46:28:46:36 | WriteLine | methods.cs:49:11:49:25 | TestOverloading |
8-
| methods.cs:67:21:67:21 | F | methods.cs:46:28:46:36 | WriteLine | methods.cs:49:11:49:25 | TestOverloading |
9-
| methods.cs:72:21:72:24 | F | methods.cs:46:28:46:36 | WriteLine | methods.cs:49:11:49:25 | TestOverloading |
10-
| methods.cs:77:21:77:21 | F | methods.cs:46:28:46:36 | WriteLine | methods.cs:49:11:49:25 | TestOverloading |
11-
| methods.cs:82:14:82:17 | Main | methods.cs:52:21:52:21 | F | methods.cs:49:11:49:25 | TestOverloading |
12-
| methods.cs:82:14:82:17 | Main | methods.cs:57:21:57:21 | F | methods.cs:49:11:49:25 | TestOverloading |
13-
| methods.cs:82:14:82:17 | Main | methods.cs:62:21:62:21 | F | methods.cs:49:11:49:25 | TestOverloading |
14-
| methods.cs:82:14:82:17 | Main | methods.cs:67:21:67:21 | F | methods.cs:49:11:49:25 | TestOverloading |
15-
| methods.cs:82:14:82:17 | Main | methods.cs:72:21:72:24 | F | methods.cs:49:11:49:25 | TestOverloading |
16-
| methods.cs:82:14:82:17 | Main | methods.cs:72:21:72:24 | F | methods.cs:49:11:49:25 | TestOverloading |
17-
| methods.cs:82:14:82:17 | Main | methods.cs:77:21:77:21 | F | methods.cs:49:11:49:25 | TestOverloading |
18-
| methods.cs:118:27:118:37 | CallToInt32 | methods.cs:99:27:99:33 | ToInt32 | methods.cs:96:25:96:34 | Extensions |
19-
| methods.cs:124:21:124:24 | Main | methods.cs:99:27:99:33 | ToInt32 | methods.cs:121:18:121:31 | TestExtensions |
20-
| methods.cs:124:21:124:24 | Main | methods.cs:104:28:104:33 | ToBool | methods.cs:121:18:121:31 | TestExtensions |
21-
| methods.cs:124:21:124:24 | Main | methods.cs:109:27:109:34 | Slice | methods.cs:121:18:121:31 | TestExtensions |
22-
| methods.cs:178:67:178:76 | SkipTwoInt | methods.cs:173:65:173:74 | SkipTwo | methods.cs:166:18:166:47 | TestDefaultExtensionParameters |
1+
| methods.cs:17:14:17:17 | Main | methods.cs:10:21:10:24 | Swap | methods.cs:7:18:7:24 | TestRef |
2+
| methods.cs:17:14:17:17 | Main | methods.cs:47:28:47:36 | WriteLine | methods.cs:7:18:7:24 | TestRef |
3+
| methods.cs:35:14:35:17 | Main | methods.cs:29:28:29:33 | Divide | methods.cs:26:18:26:24 | TestOut |
4+
| methods.cs:35:14:35:17 | Main | methods.cs:47:28:47:36 | WriteLine | methods.cs:26:18:26:24 | TestOut |
5+
| methods.cs:53:21:53:21 | F | methods.cs:47:28:47:36 | WriteLine | methods.cs:50:11:50:25 | TestOverloading |
6+
| methods.cs:58:21:58:21 | F | methods.cs:47:28:47:36 | WriteLine | methods.cs:50:11:50:25 | TestOverloading |
7+
| methods.cs:63:21:63:21 | F | methods.cs:47:28:47:36 | WriteLine | methods.cs:50:11:50:25 | TestOverloading |
8+
| methods.cs:68:21:68:21 | F | methods.cs:47:28:47:36 | WriteLine | methods.cs:50:11:50:25 | TestOverloading |
9+
| methods.cs:73:21:73:24 | F | methods.cs:47:28:47:36 | WriteLine | methods.cs:50:11:50:25 | TestOverloading |
10+
| methods.cs:78:21:78:21 | F | methods.cs:47:28:47:36 | WriteLine | methods.cs:50:11:50:25 | TestOverloading |
11+
| methods.cs:83:14:83:17 | Main | methods.cs:53:21:53:21 | F | methods.cs:50:11:50:25 | TestOverloading |
12+
| methods.cs:83:14:83:17 | Main | methods.cs:58:21:58:21 | F | methods.cs:50:11:50:25 | TestOverloading |
13+
| methods.cs:83:14:83:17 | Main | methods.cs:63:21:63:21 | F | methods.cs:50:11:50:25 | TestOverloading |
14+
| methods.cs:83:14:83:17 | Main | methods.cs:68:21:68:21 | F | methods.cs:50:11:50:25 | TestOverloading |
15+
| methods.cs:83:14:83:17 | Main | methods.cs:73:21:73:24 | F | methods.cs:50:11:50:25 | TestOverloading |
16+
| methods.cs:83:14:83:17 | Main | methods.cs:73:21:73:24 | F | methods.cs:50:11:50:25 | TestOverloading |
17+
| methods.cs:83:14:83:17 | Main | methods.cs:78:21:78:21 | F | methods.cs:50:11:50:25 | TestOverloading |
18+
| methods.cs:119:27:119:37 | CallToInt32 | methods.cs:100:27:100:33 | ToInt32 | methods.cs:97:25:97:34 | Extensions |
19+
| methods.cs:125:21:125:24 | Main | methods.cs:100:27:100:33 | ToInt32 | methods.cs:122:18:122:31 | TestExtensions |
20+
| methods.cs:125:21:125:24 | Main | methods.cs:105:28:105:33 | ToBool | methods.cs:122:18:122:31 | TestExtensions |
21+
| methods.cs:125:21:125:24 | Main | methods.cs:110:27:110:34 | Slice | methods.cs:122:18:122:31 | TestExtensions |
22+
| methods.cs:179:67:179:76 | SkipTwoInt | methods.cs:174:65:174:74 | SkipTwo | methods.cs:167:18:167:47 | TestDefaultExtensionParameters |
23+
| methods.cs:190:21:190:25 | Calls | methods.cs:187:21:187:21 | M | methods.cs:185:18:185:40 | TestCollidingMethods<> |
24+
| methods.cs:190:21:190:25 | Calls | methods.cs:188:21:188:21 | M | methods.cs:185:18:185:40 | TestCollidingMethods<> |
25+
| methods.cs:190:21:190:25 | Calls | methods.cs:188:21:188:21 | M | methods.cs:185:18:185:40 | TestCollidingMethods<> |
26+
| methods.cs:203:20:203:25 | Nested | methods.cs:202:20:202:25 | Nested | methods.cs:200:22:200:27 | Nested |
27+
| methods.cs:203:20:203:25 | Nested | methods.cs:202:20:202:25 | Nested | methods.cs:200:22:200:27 | Nested |
28+
| methods.cs:203:20:203:25 | Nested | methods.cs:203:20:203:25 | Nested | methods.cs:200:22:200:27 | Nested |
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
| methods.cs:9:21:9:24 | Swap | methods.cs:9:34:9:34 | x |
2-
| methods.cs:9:21:9:24 | Swap | methods.cs:9:45:9:45 | y |
1+
| methods.cs:10:21:10:24 | Swap | methods.cs:10:34:10:34 | x |
2+
| methods.cs:10:21:10:24 | Swap | methods.cs:10:45:10:45 | y |
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
| methods.cs:28:28:28:33 | Divide | methods.cs:28:39:28:39 | x |
2-
| methods.cs:28:28:28:33 | Divide | methods.cs:28:46:28:46 | y |
3-
| methods.cs:28:28:28:33 | Divide | methods.cs:28:57:28:62 | result |
4-
| methods.cs:28:28:28:33 | Divide | methods.cs:28:73:28:81 | remainder |
1+
| methods.cs:29:28:29:33 | Divide | methods.cs:29:39:29:39 | x |
2+
| methods.cs:29:28:29:33 | Divide | methods.cs:29:46:29:46 | y |
3+
| methods.cs:29:28:29:33 | Divide | methods.cs:29:57:29:62 | result |
4+
| methods.cs:29:28:29:33 | Divide | methods.cs:29:73:29:81 | remainder |

0 commit comments

Comments
 (0)