Skip to content

Commit a8e93e7

Browse files
authored
Merge pull request #21325 from michaelnebel/csharp14/partialmembers
C# 14: Support for partial `event` declarations.
2 parents 744ade6 + c29bac2 commit a8e93e7

18 files changed

+209
-143
lines changed

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ internal class Event : CachedSymbol<IEventSymbol>
1111
private Event(Context cx, IEventSymbol init)
1212
: base(cx, init) { }
1313

14+
protected override IEventSymbol BodyDeclaringSymbol => Symbol.PartialImplementationPart ?? Symbol;
15+
16+
public override Microsoft.CodeAnalysis.Location? ReportingLocation => BodyDeclaringSymbol.Locations.BestOrDefault();
17+
1418
public override void WriteId(EscapingTextWriter trapFile)
1519
{
1620
trapFile.WriteSubId(ContainingType!);
@@ -27,13 +31,13 @@ public override void Populate(TextWriter trapFile)
2731
var type = Type.Create(Context, Symbol.Type);
2832
trapFile.events(this, Symbol.GetName(), ContainingType!, type.TypeRef, Create(Context, Symbol.OriginalDefinition));
2933

30-
var adder = Symbol.AddMethod;
31-
var remover = Symbol.RemoveMethod;
34+
var adder = BodyDeclaringSymbol.AddMethod;
35+
var remover = BodyDeclaringSymbol.RemoveMethod;
3236

33-
if (!(adder is null))
37+
if (adder is not null)
3438
Method.Create(Context, adder);
3539

36-
if (!(remover is null))
40+
if (remover is not null)
3741
Method.Create(Context, remover);
3842

3943
PopulateModifiers(trapFile);

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ private EventAccessor(Context cx, IMethodSymbol init, IEventSymbol @event)
1313
this.@event = @event;
1414
}
1515

16+
public override bool NeedsPopulation =>
17+
base.NeedsPopulation &&
18+
!Symbol.IsPartialDefinition; // Accessors always have an implementing declaration as well.
19+
1620
/// <summary>
1721
/// Gets the event symbol associated with accessor `symbol`, or `null`
1822
/// if there is no associated symbol.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* C# 14: Added support for partial events.

csharp/ql/test/library-tests/dispatch/CallGraph.expected

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,9 @@
270270
| ViableCallable.cs:679:17:679:20 | Run3 | ViableCallable.cs:637:21:637:21 | M |
271271
| ViableCallable.cs:679:17:679:20 | Run3 | ViableCallable.cs:646:21:646:21 | M |
272272
| ViableCallable.cs:679:17:679:20 | Run3 | ViableCallable.cs:648:21:648:21 | M |
273-
| ViableCallable.cs:707:17:707:20 | Run1 | ViableCallable.cs:702:42:702:44 | get_Property |
274-
| ViableCallable.cs:707:17:707:20 | Run1 | ViableCallable.cs:702:63:702:65 | set_Property |
275-
| ViableCallable.cs:707:17:707:20 | Run1 | ViableCallable.cs:704:49:704:51 | get_Item |
276-
| ViableCallable.cs:707:17:707:20 | Run1 | ViableCallable.cs:704:70:704:72 | set_Item |
273+
| ViableCallable.cs:709:17:709:20 | Run1 | ViableCallable.cs:703:42:703:44 | get_Property |
274+
| ViableCallable.cs:709:17:709:20 | Run1 | ViableCallable.cs:703:63:703:65 | set_Property |
275+
| ViableCallable.cs:709:17:709:20 | Run1 | ViableCallable.cs:705:49:705:51 | get_Item |
276+
| ViableCallable.cs:709:17:709:20 | Run1 | ViableCallable.cs:705:70:705:72 | set_Item |
277+
| ViableCallable.cs:709:17:709:20 | Run1 | ViableCallable.cs:706:51:706:53 | add_Event |
278+
| ViableCallable.cs:709:17:709:20 | Run1 | ViableCallable.cs:706:59:706:64 | remove_Event |

csharp/ql/test/library-tests/dispatch/GetADynamicTarget.expected

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,9 @@
518518
| ViableCallable.cs:683:9:683:16 | call to method M | C22+TestOverloadResolution2<System.Int32>.M(Int32[]) |
519519
| ViableCallable.cs:687:9:687:16 | call to method M | C22+TestOverloadResolution1<System.Int32>.M(List<int>) |
520520
| ViableCallable.cs:687:9:687:16 | call to method M | C22+TestOverloadResolution2<System.Int32>.M(List<int>) |
521-
| ViableCallable.cs:712:9:712:18 | access to property Property | C23+Partial1.set_Property(object) |
522-
| ViableCallable.cs:715:13:715:22 | access to property Property | C23+Partial1.get_Property() |
523-
| ViableCallable.cs:718:9:718:12 | access to indexer | C23+Partial1.set_Item(int, object) |
524-
| ViableCallable.cs:721:13:721:16 | access to indexer | C23+Partial1.get_Item(int) |
521+
| ViableCallable.cs:714:9:714:18 | access to property Property | C23+Partial1.set_Property(object) |
522+
| ViableCallable.cs:717:13:717:22 | access to property Property | C23+Partial1.get_Property() |
523+
| ViableCallable.cs:720:9:720:12 | access to indexer | C23+Partial1.set_Item(int, object) |
524+
| ViableCallable.cs:723:13:723:16 | access to indexer | C23+Partial1.get_Item(int) |
525+
| ViableCallable.cs:726:9:726:15 | access to event Event | C23+Partial1.add_Event(EventHandler) |
526+
| ViableCallable.cs:729:9:729:15 | access to event Event | C23+Partial1.remove_Event(EventHandler) |

csharp/ql/test/library-tests/dispatch/ViableCallable.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,13 +695,15 @@ public partial class Partial1
695695
public partial object Property { get; set; }
696696

697697
public partial object this[int index] { get; set; }
698+
public partial event EventHandler Event;
698699
}
699700

700701
public partial class Partial1
701702
{
702703
public partial object Property { get { return null; } set { } }
703704

704705
public partial object this[int index] { get { return null; } set { } }
706+
public partial event EventHandler Event { add { } remove { } }
705707
}
706708

707709
public void Run1(Partial1 p)
@@ -719,5 +721,11 @@ public void Run1(Partial1 p)
719721

720722
// Viable callable: Partial1.get_Item(int)
721723
o = p[0];
724+
725+
// Viable callable: Partial1.add_Event
726+
p.Event += (sender, e) => { };
727+
728+
// Viable callable: Partial1.remove_Event
729+
p.Event -= (sender, e) => { };
722730
}
723731
}
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
| Partial.cs:4:18:4:42 | PartialMethodWithoutBody1 | true |
2-
| Partial.cs:5:17:5:23 | Method2 | false |
3-
| Partial.cs:14:18:14:39 | PartialMethodWithBody1 | true |
4-
| Partial.cs:15:17:15:23 | Method3 | false |
5-
| Partial.cs:34:18:34:42 | PartialMethodWithoutBody2 | true |
6-
| Partial.cs:35:17:35:23 | Method4 | false |
7-
| Partial.cs:40:17:40:23 | Method5 | false |
1+
| Partial.cs:6:18:6:42 | PartialMethodWithoutBody1 | true |
2+
| Partial.cs:7:17:7:23 | Method2 | false |
3+
| Partial.cs:18:18:18:39 | PartialMethodWithBody1 | true |
4+
| Partial.cs:19:17:19:23 | Method3 | false |
5+
| Partial.cs:41:18:41:42 | PartialMethodWithoutBody2 | true |
6+
| Partial.cs:42:17:42:23 | Method4 | false |
7+
| Partial.cs:47:17:47:23 | Method5 | false |

csharp/ql/test/library-tests/partial/Partial.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using System;
2+
13
partial class TwoPartClass
24
{
35
partial void PartialMethodWithBody1();
@@ -7,6 +9,8 @@ public void Method2() { }
79
public partial object PartialProperty1 { get; set; }
810
// Declaring declaration.
911
public partial object this[int index] { get; set; }
12+
// Declaring declaration.
13+
public partial event EventHandler PartialEvent1;
1014
}
1115

1216
partial class TwoPartClass
@@ -27,6 +31,9 @@ public partial object this[int index]
2731
get { return _backingArray[index]; }
2832
set { _backingArray[index] = value; }
2933
}
34+
35+
// Implementation declaration.
36+
public partial event EventHandler PartialEvent1 { add { } remove { } }
3037
}
3138

3239
partial class OnePartPartialClass
@@ -44,4 +51,5 @@ public object this[int index]
4451
get { return null; }
4552
set { }
4653
}
54+
public event EventHandler Event;
4755
}
Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1-
| Partial.cs:1:15:1:26 | TwoPartClass |
2-
| Partial.cs:4:18:4:42 | PartialMethodWithoutBody1 |
3-
| Partial.cs:12:15:12:26 | TwoPartClass |
4-
| Partial.cs:14:18:14:39 | PartialMethodWithBody1 |
5-
| Partial.cs:18:27:18:42 | PartialProperty1 |
6-
| Partial.cs:20:9:20:11 | get_PartialProperty1 |
7-
| Partial.cs:21:9:21:11 | set_PartialProperty1 |
8-
| Partial.cs:25:27:25:30 | Item |
9-
| Partial.cs:27:9:27:11 | get_Item |
10-
| Partial.cs:28:9:28:11 | set_Item |
11-
| Partial.cs:32:15:32:33 | OnePartPartialClass |
12-
| Partial.cs:34:18:34:42 | PartialMethodWithoutBody2 |
1+
| Partial.cs:3:15:3:26 | TwoPartClass |
2+
| Partial.cs:6:18:6:42 | PartialMethodWithoutBody1 |
3+
| Partial.cs:16:15:16:26 | TwoPartClass |
4+
| Partial.cs:18:18:18:39 | PartialMethodWithBody1 |
5+
| Partial.cs:22:27:22:42 | PartialProperty1 |
6+
| Partial.cs:24:9:24:11 | get_PartialProperty1 |
7+
| Partial.cs:25:9:25:11 | set_PartialProperty1 |
8+
| Partial.cs:29:27:29:30 | Item |
9+
| Partial.cs:31:9:31:11 | get_Item |
10+
| Partial.cs:32:9:32:11 | set_Item |
11+
| Partial.cs:36:39:36:51 | PartialEvent1 |
12+
| Partial.cs:36:55:36:57 | add_PartialEvent1 |
13+
| Partial.cs:36:63:36:68 | remove_PartialEvent1 |
14+
| Partial.cs:39:15:39:33 | OnePartPartialClass |
15+
| Partial.cs:41:18:41:42 | PartialMethodWithoutBody2 |
1316
| PartialMultipleFiles1.cs:1:22:1:41 | PartialMultipleFiles |
1417
| PartialMultipleFiles2.cs:1:22:1:41 | PartialMultipleFiles |
Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
| Partial.cs:1:15:1:26 | TwoPartClass | Partial.cs:1:15:1:26 | <object initializer> |
2-
| Partial.cs:1:15:1:26 | TwoPartClass | Partial.cs:4:18:4:42 | PartialMethodWithoutBody1 |
3-
| Partial.cs:1:15:1:26 | TwoPartClass | Partial.cs:5:17:5:23 | Method2 |
4-
| Partial.cs:1:15:1:26 | TwoPartClass | Partial.cs:14:18:14:39 | PartialMethodWithBody1 |
5-
| Partial.cs:1:15:1:26 | TwoPartClass | Partial.cs:15:17:15:23 | Method3 |
6-
| Partial.cs:12:15:12:26 | TwoPartClass | Partial.cs:1:15:1:26 | <object initializer> |
7-
| Partial.cs:12:15:12:26 | TwoPartClass | Partial.cs:4:18:4:42 | PartialMethodWithoutBody1 |
8-
| Partial.cs:12:15:12:26 | TwoPartClass | Partial.cs:5:17:5:23 | Method2 |
9-
| Partial.cs:12:15:12:26 | TwoPartClass | Partial.cs:14:18:14:39 | PartialMethodWithBody1 |
10-
| Partial.cs:12:15:12:26 | TwoPartClass | Partial.cs:15:17:15:23 | Method3 |
11-
| Partial.cs:32:15:32:33 | OnePartPartialClass | Partial.cs:32:15:32:33 | <object initializer> |
12-
| Partial.cs:32:15:32:33 | OnePartPartialClass | Partial.cs:34:18:34:42 | PartialMethodWithoutBody2 |
13-
| Partial.cs:32:15:32:33 | OnePartPartialClass | Partial.cs:35:17:35:23 | Method4 |
1+
| Partial.cs:3:15:3:26 | TwoPartClass | Partial.cs:3:15:3:26 | <object initializer> |
2+
| Partial.cs:3:15:3:26 | TwoPartClass | Partial.cs:6:18:6:42 | PartialMethodWithoutBody1 |
3+
| Partial.cs:3:15:3:26 | TwoPartClass | Partial.cs:7:17:7:23 | Method2 |
4+
| Partial.cs:3:15:3:26 | TwoPartClass | Partial.cs:18:18:18:39 | PartialMethodWithBody1 |
5+
| Partial.cs:3:15:3:26 | TwoPartClass | Partial.cs:19:17:19:23 | Method3 |
6+
| Partial.cs:16:15:16:26 | TwoPartClass | Partial.cs:3:15:3:26 | <object initializer> |
7+
| Partial.cs:16:15:16:26 | TwoPartClass | Partial.cs:6:18:6:42 | PartialMethodWithoutBody1 |
8+
| Partial.cs:16:15:16:26 | TwoPartClass | Partial.cs:7:17:7:23 | Method2 |
9+
| Partial.cs:16:15:16:26 | TwoPartClass | Partial.cs:18:18:18:39 | PartialMethodWithBody1 |
10+
| Partial.cs:16:15:16:26 | TwoPartClass | Partial.cs:19:17:19:23 | Method3 |
11+
| Partial.cs:39:15:39:33 | OnePartPartialClass | Partial.cs:39:15:39:33 | <object initializer> |
12+
| Partial.cs:39:15:39:33 | OnePartPartialClass | Partial.cs:41:18:41:42 | PartialMethodWithoutBody2 |
13+
| Partial.cs:39:15:39:33 | OnePartPartialClass | Partial.cs:42:17:42:23 | Method4 |
1414
| PartialMultipleFiles1.cs:1:22:1:41 | PartialMultipleFiles | PartialMultipleFiles1.cs:1:22:1:41 | <object initializer> |
1515
| PartialMultipleFiles2.cs:1:22:1:41 | PartialMultipleFiles | PartialMultipleFiles1.cs:1:22:1:41 | <object initializer> |

0 commit comments

Comments
 (0)