Skip to content

Commit f650a15

Browse files
Switch behavior of "Go to definition" and "Go to implementation" for partial members (#78857)
2 parents 4f87104 + 43676e9 commit f650a15

File tree

7 files changed

+205
-40
lines changed

7 files changed

+205
-40
lines changed

src/EditorFeatures/Test2/GoToDefinition/CSharpGoToDefinitionTests.vb

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -217,15 +217,17 @@ class Program
217217
Await TestAsync(workspace)
218218
End Function
219219

220-
<WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/900438")>
220+
<WpfFact>
221+
<WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/900438")>
222+
<WorkItem("https://github.com/dotnet/roslyn/issues/77916")>
221223
Public Async Function TestCSharpGotoDefinitionPartialMethod() As Task
222224
Dim workspace =
223225
<Workspace>
224226
<Project Language="C#" CommonReferences="true">
225227
<Document>
226228
partial class Test
227229
{
228-
partial void M();
230+
partial void [|M|]();
229231
}
230232
</Document>
231233
<Document>
@@ -237,7 +239,7 @@ class Program
237239
t.M$$();
238240
}
239241

240-
partial void [|M|]()
242+
partial void M()
241243
{
242244
throw new NotImplementedException();
243245
}
@@ -249,15 +251,15 @@ class Program
249251
Await TestAsync(workspace)
250252
End Function
251253

252-
<WpfFact>
254+
<WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/77916")>
253255
Public Async Function TestCSharpGotoDefinitionExtendedPartialMethod() As Task
254256
Dim workspace =
255257
<Workspace>
256258
<Project Language="C#" CommonReferences="true">
257259
<Document>
258260
partial class Test
259261
{
260-
public partial void M();
262+
public partial void [|M|]();
261263
}
262264
</Document>
263265
<Document>
@@ -269,7 +271,7 @@ class Program
269271
t.M$$();
270272
}
271273

272-
public partial void [|M|]()
274+
public partial void M()
273275
{
274276
throw new NotImplementedException();
275277
}
@@ -281,15 +283,15 @@ class Program
281283
Await TestAsync(workspace)
282284
End Function
283285

284-
<WpfFact>
286+
<WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/77916")>
285287
Public Async Function TestCSharpGotoDefinitionPartialProperty() As Task
286288
Dim workspace =
287289
<Workspace>
288290
<Project Language="C#" CommonReferences="true">
289291
<Document>
290292
partial class Test
291293
{
292-
public partial int Prop { get; set; }
294+
public partial int [|Prop|] { get; set; }
293295
}
294296
</Document>
295297
<Document>
@@ -301,7 +303,7 @@ class Program
301303
int i = t.Prop$$;
302304
}
303305

304-
public partial void [|Prop|]
306+
public partial void Prop
305307
{
306308
get => throw new NotImplementedException();
307309
set => throw new NotImplementedException();
@@ -314,15 +316,15 @@ class Program
314316
Await TestAsync(workspace)
315317
End Function
316318

317-
<WpfFact>
319+
<WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/77916")>
318320
Public Async Function TestCSharpGotoDefinitionPartialEvent() As Task
319321
Dim workspace =
320322
<Workspace>
321323
<Project Language="C#" CommonReferences="true">
322324
<Document>
323325
partial class Test
324326
{
325-
public partial event System.Action E;
327+
public partial event System.Action [|E|];
326328
}
327329
</Document>
328330
<Document>
@@ -334,7 +336,7 @@ class Program
334336
int i = t.E$$;
335337
}
336338

337-
public partial event System.Action [|E|]
339+
public partial event System.Action E
338340
{
339341
add { }
340342
remove { }
@@ -347,15 +349,15 @@ class Program
347349
Await TestAsync(workspace)
348350
End Function
349351

350-
<WpfFact>
352+
<WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/77916")>
351353
Public Async Function TestCSharpGotoDefinitionPartialConstructor() As Task
352354
Dim workspace =
353355
<Workspace>
354356
<Project Language="C#" CommonReferences="true" LanguageVersion="Preview">
355357
<Document>
356358
partial class Test
357359
{
358-
public partial Test();
360+
public partial [|Test|]();
359361
}
360362
</Document>
361363
<Document>
@@ -366,7 +368,7 @@ class Program
366368
var t = new Te$$st();
367369
}
368370

369-
public partial [|Test|]()
371+
public partial Test()
370372
{
371373
}
372374
}

src/EditorFeatures/Test2/GoToDefinition/VisualBasicGoToDefinitionTests.vb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ End Class
216216
<Project Language="Visual Basic" CommonReferences="true">
217217
<Document>
218218
Partial Class Customer
219-
Private Sub [|OnNameChanged|]()
219+
Private Sub OnNameChanged()
220220

221221
End Sub
222222
End Class
@@ -227,7 +227,7 @@ End Class
227227
Dim x As New Customer()
228228
x.OnNameChanged$$()
229229
End Sub
230-
Partial Private Sub OnNameChanged()
230+
Partial Private Sub [|OnNameChanged|]()
231231

232232
End Sub
233233
End Class

src/EditorFeatures/Test2/GoToImplementation/GoToImplementationTests.vb

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -999,5 +999,170 @@ class D : C
999999

10001000
Await TestAsync(workspace, host)
10011001
End Function
1002+
1003+
<Theory, CombinatorialData>
1004+
<WorkItem("https://github.com/dotnet/roslyn/issues/77916")>
1005+
Public Async Function TestPartialMethod(host As TestHost) As Task
1006+
Dim workspace =
1007+
<Workspace>
1008+
<Project Language="C#" CommonReferences="true">
1009+
<Document>
1010+
partial class Test
1011+
{
1012+
partial void M();
1013+
}
1014+
</Document>
1015+
<Document>
1016+
partial class Test
1017+
{
1018+
void Goo()
1019+
{
1020+
var t = new Test();
1021+
t.M$$();
1022+
}
1023+
1024+
partial void [|M|]()
1025+
{
1026+
throw new NotImplementedException();
1027+
}
1028+
}
1029+
</Document>
1030+
</Project>
1031+
</Workspace>
1032+
1033+
Await TestAsync(workspace, host)
1034+
End Function
1035+
1036+
<Theory, CombinatorialData>
1037+
<WorkItem("https://github.com/dotnet/roslyn/issues/77916")>
1038+
Public Async Function TestExtendedPartialMethod(host As TestHost) As Task
1039+
Dim workspace =
1040+
<Workspace>
1041+
<Project Language="C#" CommonReferences="true">
1042+
<Document>
1043+
partial class Test
1044+
{
1045+
public partial void M();
1046+
}
1047+
</Document>
1048+
<Document>
1049+
partial class Test
1050+
{
1051+
void Goo()
1052+
{
1053+
var t = new Test();
1054+
t.M$$();
1055+
}
1056+
1057+
public partial void [|M|]()
1058+
{
1059+
throw new NotImplementedException();
1060+
}
1061+
}
1062+
</Document>
1063+
</Project>
1064+
</Workspace>
1065+
1066+
Await TestAsync(workspace, host)
1067+
End Function
1068+
1069+
<Theory, CombinatorialData>
1070+
<WorkItem("https://github.com/dotnet/roslyn/issues/77916")>
1071+
Public Async Function TestPartialProperty(host As TestHost) As Task
1072+
Dim workspace =
1073+
<Workspace>
1074+
<Project Language="C#" CommonReferences="true">
1075+
<Document>
1076+
partial class Test
1077+
{
1078+
public partial int Prop { get; set; }
1079+
}
1080+
</Document>
1081+
<Document>
1082+
partial class Test
1083+
{
1084+
void Goo()
1085+
{
1086+
var t = new Test();
1087+
int i = t.Prop$$;
1088+
}
1089+
1090+
public partial void [|Prop|]
1091+
{
1092+
get => throw new NotImplementedException();
1093+
set => throw new NotImplementedException();
1094+
}
1095+
}
1096+
</Document>
1097+
</Project>
1098+
</Workspace>
1099+
1100+
Await TestAsync(workspace, host)
1101+
End Function
1102+
1103+
<Theory, CombinatorialData>
1104+
<WorkItem("https://github.com/dotnet/roslyn/issues/77916")>
1105+
Public Async Function TestPartialEvent(host As TestHost) As Task
1106+
Dim workspace =
1107+
<Workspace>
1108+
<Project Language="C#" CommonReferences="true">
1109+
<Document>
1110+
partial class Test
1111+
{
1112+
public partial event System.Action E;
1113+
}
1114+
</Document>
1115+
<Document>
1116+
partial class Test
1117+
{
1118+
void Goo()
1119+
{
1120+
var t = new Test();
1121+
int i = t.E$$;
1122+
}
1123+
1124+
public partial event System.Action [|E|]
1125+
{
1126+
add { }
1127+
remove { }
1128+
}
1129+
}
1130+
</Document>
1131+
</Project>
1132+
</Workspace>
1133+
1134+
Await TestAsync(workspace, host)
1135+
End Function
1136+
1137+
<Theory, CombinatorialData>
1138+
<WorkItem("https://github.com/dotnet/roslyn/issues/77916")>
1139+
Public Async Function TestPartialConstructor(host As TestHost) As Task
1140+
Dim workspace =
1141+
<Workspace>
1142+
<Project Language="C#" CommonReferences="true" LanguageVersion="Preview">
1143+
<Document>
1144+
partial class Test
1145+
{
1146+
public partial Test();
1147+
}
1148+
</Document>
1149+
<Document>
1150+
partial class Test
1151+
{
1152+
void Goo()
1153+
{
1154+
var t = new Te$$st();
1155+
}
1156+
1157+
public partial [|Test|]()
1158+
{
1159+
}
1160+
}
1161+
</Document>
1162+
</Project>
1163+
</Workspace>
1164+
1165+
Await TestAsync(workspace, host)
1166+
End Function
10021167
End Class
10031168
End Namespace

src/EditorFeatures/Test2/Peek/PeekTests.vb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,13 +234,13 @@ public partial class D
234234
$$PartialMethod();
235235
}
236236

237-
partial void PartialMethod();
237+
partial void {|Identifier:PartialMethod|}();
238238
}
239239
]]></Document>
240240
<Document><![CDATA[
241241
public partial class D
242242
{
243-
partial void {|Identifier:PartialMethod|}() { }
243+
partial void PartialMethod() { }
244244
}
245245
]]></Document>
246246
</Project>

src/Features/Core/Portable/FindUsages/AbstractFindUsagesService_FindImplementations.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,16 @@ private static async Task<ImmutableArray<ISymbol>> FindSourceAndMetadataImplemen
206206
}
207207
else
208208
{
209-
return [];
209+
// If a symbol is partial definition, return its implementation part
210+
var implementationPart = symbol switch
211+
{
212+
IMethodSymbol method => method.PartialImplementationPart,
213+
IPropertySymbol property => property.PartialImplementationPart,
214+
IEventSymbol ev => ev.PartialImplementationPart,
215+
_ => symbol,
216+
};
217+
218+
return implementationPart is null ? [] : [implementationPart];
210219
}
211220
}
212221
}

src/Features/Core/Portable/GoToDefinition/GoToDefinitionFeatureHelpers.cs

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,7 @@ internal static class GoToDefinitionFeatureHelpers
4646
var definition = await SymbolFinder.FindSourceDefinitionAsync(symbol, solution, cancellationToken).ConfigureAwait(false);
4747
cancellationToken.ThrowIfCancellationRequested();
4848

49-
symbol = definition ?? symbol;
50-
51-
// If symbol has a partial implementation part, prefer to go to it, since that is where the body is.
52-
symbol = symbol switch
53-
{
54-
IMethodSymbol method => method.PartialImplementationPart,
55-
IPropertySymbol property => property.PartialImplementationPart,
56-
IEventSymbol ev => ev.PartialImplementationPart,
57-
_ => symbol,
58-
} ?? symbol;
59-
60-
return symbol;
49+
return definition ?? symbol;
6150
}
6251

6352
public static async Task<ImmutableArray<DefinitionItem>> GetDefinitionsAsync(

0 commit comments

Comments
 (0)