Merge pull request #21325 from michaelnebel/csharp14/partialmembers

C# 14: Support for partial `event` declarations.
This commit is contained in:
Michael Nebel
2026-02-17 15:00:00 +01:00
committed by GitHub
18 changed files with 209 additions and 143 deletions

View File

@@ -11,6 +11,10 @@ namespace Semmle.Extraction.CSharp.Entities
private Event(Context cx, IEventSymbol init)
: base(cx, init) { }
protected override IEventSymbol BodyDeclaringSymbol => Symbol.PartialImplementationPart ?? Symbol;
public override Microsoft.CodeAnalysis.Location? ReportingLocation => BodyDeclaringSymbol.Locations.BestOrDefault();
public override void WriteId(EscapingTextWriter trapFile)
{
trapFile.WriteSubId(ContainingType!);
@@ -27,13 +31,13 @@ namespace Semmle.Extraction.CSharp.Entities
var type = Type.Create(Context, Symbol.Type);
trapFile.events(this, Symbol.GetName(), ContainingType!, type.TypeRef, Create(Context, Symbol.OriginalDefinition));
var adder = Symbol.AddMethod;
var remover = Symbol.RemoveMethod;
var adder = BodyDeclaringSymbol.AddMethod;
var remover = BodyDeclaringSymbol.RemoveMethod;
if (!(adder is null))
if (adder is not null)
Method.Create(Context, adder);
if (!(remover is null))
if (remover is not null)
Method.Create(Context, remover);
PopulateModifiers(trapFile);

View File

@@ -13,6 +13,10 @@ namespace Semmle.Extraction.CSharp.Entities
this.@event = @event;
}
public override bool NeedsPopulation =>
base.NeedsPopulation &&
!Symbol.IsPartialDefinition; // Accessors always have an implementing declaration as well.
/// <summary>
/// Gets the event symbol associated with accessor `symbol`, or `null`
/// if there is no associated symbol.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* C# 14: Added support for partial events.

View File

@@ -270,7 +270,9 @@
| ViableCallable.cs:679:17:679:20 | Run3 | ViableCallable.cs:637:21:637:21 | M |
| ViableCallable.cs:679:17:679:20 | Run3 | ViableCallable.cs:646:21:646:21 | M |
| ViableCallable.cs:679:17:679:20 | Run3 | ViableCallable.cs:648:21:648:21 | M |
| ViableCallable.cs:707:17:707:20 | Run1 | ViableCallable.cs:702:42:702:44 | get_Property |
| ViableCallable.cs:707:17:707:20 | Run1 | ViableCallable.cs:702:63:702:65 | set_Property |
| ViableCallable.cs:707:17:707:20 | Run1 | ViableCallable.cs:704:49:704:51 | get_Item |
| ViableCallable.cs:707:17:707:20 | Run1 | ViableCallable.cs:704:70:704:72 | set_Item |
| ViableCallable.cs:709:17:709:20 | Run1 | ViableCallable.cs:703:42:703:44 | get_Property |
| ViableCallable.cs:709:17:709:20 | Run1 | ViableCallable.cs:703:63:703:65 | set_Property |
| ViableCallable.cs:709:17:709:20 | Run1 | ViableCallable.cs:705:49:705:51 | get_Item |
| ViableCallable.cs:709:17:709:20 | Run1 | ViableCallable.cs:705:70:705:72 | set_Item |
| ViableCallable.cs:709:17:709:20 | Run1 | ViableCallable.cs:706:51:706:53 | add_Event |
| ViableCallable.cs:709:17:709:20 | Run1 | ViableCallable.cs:706:59:706:64 | remove_Event |

View File

@@ -518,7 +518,9 @@
| ViableCallable.cs:683:9:683:16 | call to method M | C22+TestOverloadResolution2<System.Int32>.M(Int32[]) |
| ViableCallable.cs:687:9:687:16 | call to method M | C22+TestOverloadResolution1<System.Int32>.M(List<int>) |
| ViableCallable.cs:687:9:687:16 | call to method M | C22+TestOverloadResolution2<System.Int32>.M(List<int>) |
| ViableCallable.cs:712:9:712:18 | access to property Property | C23+Partial1.set_Property(object) |
| ViableCallable.cs:715:13:715:22 | access to property Property | C23+Partial1.get_Property() |
| ViableCallable.cs:718:9:718:12 | access to indexer | C23+Partial1.set_Item(int, object) |
| ViableCallable.cs:721:13:721:16 | access to indexer | C23+Partial1.get_Item(int) |
| ViableCallable.cs:714:9:714:18 | access to property Property | C23+Partial1.set_Property(object) |
| ViableCallable.cs:717:13:717:22 | access to property Property | C23+Partial1.get_Property() |
| ViableCallable.cs:720:9:720:12 | access to indexer | C23+Partial1.set_Item(int, object) |
| ViableCallable.cs:723:13:723:16 | access to indexer | C23+Partial1.get_Item(int) |
| ViableCallable.cs:726:9:726:15 | access to event Event | C23+Partial1.add_Event(EventHandler) |
| ViableCallable.cs:729:9:729:15 | access to event Event | C23+Partial1.remove_Event(EventHandler) |

View File

@@ -695,6 +695,7 @@ public class C23
public partial object Property { get; set; }
public partial object this[int index] { get; set; }
public partial event EventHandler Event;
}
public partial class Partial1
@@ -702,6 +703,7 @@ public class C23
public partial object Property { get { return null; } set { } }
public partial object this[int index] { get { return null; } set { } }
public partial event EventHandler Event { add { } remove { } }
}
public void Run1(Partial1 p)
@@ -719,5 +721,11 @@ public class C23
// Viable callable: Partial1.get_Item(int)
o = p[0];
// Viable callable: Partial1.add_Event
p.Event += (sender, e) => { };
// Viable callable: Partial1.remove_Event
p.Event -= (sender, e) => { };
}
}

View File

@@ -1,7 +1,7 @@
| Partial.cs:4:18:4:42 | PartialMethodWithoutBody1 | true |
| Partial.cs:5:17:5:23 | Method2 | false |
| Partial.cs:14:18:14:39 | PartialMethodWithBody1 | true |
| Partial.cs:15:17:15:23 | Method3 | false |
| Partial.cs:34:18:34:42 | PartialMethodWithoutBody2 | true |
| Partial.cs:35:17:35:23 | Method4 | false |
| Partial.cs:40:17:40:23 | Method5 | false |
| Partial.cs:6:18:6:42 | PartialMethodWithoutBody1 | true |
| Partial.cs:7:17:7:23 | Method2 | false |
| Partial.cs:18:18:18:39 | PartialMethodWithBody1 | true |
| Partial.cs:19:17:19:23 | Method3 | false |
| Partial.cs:41:18:41:42 | PartialMethodWithoutBody2 | true |
| Partial.cs:42:17:42:23 | Method4 | false |
| Partial.cs:47:17:47:23 | Method5 | false |

View File

@@ -1,3 +1,5 @@
using System;
partial class TwoPartClass
{
partial void PartialMethodWithBody1();
@@ -7,6 +9,8 @@ partial class TwoPartClass
public partial object PartialProperty1 { get; set; }
// Declaring declaration.
public partial object this[int index] { get; set; }
// Declaring declaration.
public partial event EventHandler PartialEvent1;
}
partial class TwoPartClass
@@ -27,6 +31,9 @@ partial class TwoPartClass
get { return _backingArray[index]; }
set { _backingArray[index] = value; }
}
// Implementation declaration.
public partial event EventHandler PartialEvent1 { add { } remove { } }
}
partial class OnePartPartialClass
@@ -44,4 +51,5 @@ class NonPartialClass
get { return null; }
set { }
}
public event EventHandler Event;
}

View File

@@ -1,14 +1,17 @@
| Partial.cs:1:15:1:26 | TwoPartClass |
| Partial.cs:4:18:4:42 | PartialMethodWithoutBody1 |
| Partial.cs:12:15:12:26 | TwoPartClass |
| Partial.cs:14:18:14:39 | PartialMethodWithBody1 |
| Partial.cs:18:27:18:42 | PartialProperty1 |
| Partial.cs:20:9:20:11 | get_PartialProperty1 |
| Partial.cs:21:9:21:11 | set_PartialProperty1 |
| Partial.cs:25:27:25:30 | Item |
| Partial.cs:27:9:27:11 | get_Item |
| Partial.cs:28:9:28:11 | set_Item |
| Partial.cs:32:15:32:33 | OnePartPartialClass |
| Partial.cs:34:18:34:42 | PartialMethodWithoutBody2 |
| Partial.cs:3:15:3:26 | TwoPartClass |
| Partial.cs:6:18:6:42 | PartialMethodWithoutBody1 |
| Partial.cs:16:15:16:26 | TwoPartClass |
| Partial.cs:18:18:18:39 | PartialMethodWithBody1 |
| Partial.cs:22:27:22:42 | PartialProperty1 |
| Partial.cs:24:9:24:11 | get_PartialProperty1 |
| Partial.cs:25:9:25:11 | set_PartialProperty1 |
| Partial.cs:29:27:29:30 | Item |
| Partial.cs:31:9:31:11 | get_Item |
| Partial.cs:32:9:32:11 | set_Item |
| Partial.cs:36:39:36:51 | PartialEvent1 |
| Partial.cs:36:55:36:57 | add_PartialEvent1 |
| Partial.cs:36:63:36:68 | remove_PartialEvent1 |
| Partial.cs:39:15:39:33 | OnePartPartialClass |
| Partial.cs:41:18:41:42 | PartialMethodWithoutBody2 |
| PartialMultipleFiles1.cs:1:22:1:41 | PartialMultipleFiles |
| PartialMultipleFiles2.cs:1:22:1:41 | PartialMultipleFiles |

View File

@@ -1,15 +1,15 @@
| Partial.cs:1:15:1:26 | TwoPartClass | Partial.cs:1:15:1:26 | <object initializer> |
| Partial.cs:1:15:1:26 | TwoPartClass | Partial.cs:4:18:4:42 | PartialMethodWithoutBody1 |
| Partial.cs:1:15:1:26 | TwoPartClass | Partial.cs:5:17:5:23 | Method2 |
| Partial.cs:1:15:1:26 | TwoPartClass | Partial.cs:14:18:14:39 | PartialMethodWithBody1 |
| Partial.cs:1:15:1:26 | TwoPartClass | Partial.cs:15:17:15:23 | Method3 |
| Partial.cs:12:15:12:26 | TwoPartClass | Partial.cs:1:15:1:26 | <object initializer> |
| Partial.cs:12:15:12:26 | TwoPartClass | Partial.cs:4:18:4:42 | PartialMethodWithoutBody1 |
| Partial.cs:12:15:12:26 | TwoPartClass | Partial.cs:5:17:5:23 | Method2 |
| Partial.cs:12:15:12:26 | TwoPartClass | Partial.cs:14:18:14:39 | PartialMethodWithBody1 |
| Partial.cs:12:15:12:26 | TwoPartClass | Partial.cs:15:17:15:23 | Method3 |
| Partial.cs:32:15:32:33 | OnePartPartialClass | Partial.cs:32:15:32:33 | <object initializer> |
| Partial.cs:32:15:32:33 | OnePartPartialClass | Partial.cs:34:18:34:42 | PartialMethodWithoutBody2 |
| Partial.cs:32:15:32:33 | OnePartPartialClass | Partial.cs:35:17:35:23 | Method4 |
| Partial.cs:3:15:3:26 | TwoPartClass | Partial.cs:3:15:3:26 | <object initializer> |
| Partial.cs:3:15:3:26 | TwoPartClass | Partial.cs:6:18:6:42 | PartialMethodWithoutBody1 |
| Partial.cs:3:15:3:26 | TwoPartClass | Partial.cs:7:17:7:23 | Method2 |
| Partial.cs:3:15:3:26 | TwoPartClass | Partial.cs:18:18:18:39 | PartialMethodWithBody1 |
| Partial.cs:3:15:3:26 | TwoPartClass | Partial.cs:19:17:19:23 | Method3 |
| Partial.cs:16:15:16:26 | TwoPartClass | Partial.cs:3:15:3:26 | <object initializer> |
| Partial.cs:16:15:16:26 | TwoPartClass | Partial.cs:6:18:6:42 | PartialMethodWithoutBody1 |
| Partial.cs:16:15:16:26 | TwoPartClass | Partial.cs:7:17:7:23 | Method2 |
| Partial.cs:16:15:16:26 | TwoPartClass | Partial.cs:18:18:18:39 | PartialMethodWithBody1 |
| Partial.cs:16:15:16:26 | TwoPartClass | Partial.cs:19:17:19:23 | Method3 |
| Partial.cs:39:15:39:33 | OnePartPartialClass | Partial.cs:39:15:39:33 | <object initializer> |
| Partial.cs:39:15:39:33 | OnePartPartialClass | Partial.cs:41:18:41:42 | PartialMethodWithoutBody2 |
| Partial.cs:39:15:39:33 | OnePartPartialClass | Partial.cs:42:17:42:23 | Method4 |
| PartialMultipleFiles1.cs:1:22:1:41 | PartialMultipleFiles | PartialMultipleFiles1.cs:1:22:1:41 | <object initializer> |
| PartialMultipleFiles2.cs:1:22:1:41 | PartialMultipleFiles | PartialMultipleFiles1.cs:1:22:1:41 | <object initializer> |

View File

@@ -1,8 +1,12 @@
| Partial.cs:20:9:20:11 | get_PartialProperty1 | true |
| Partial.cs:21:9:21:11 | set_PartialProperty1 | true |
| Partial.cs:27:9:27:11 | get_Item | true |
| Partial.cs:28:9:28:11 | set_Item | true |
| Partial.cs:41:30:41:32 | get_Property | false |
| Partial.cs:41:35:41:37 | set_Property | false |
| Partial.cs:44:9:44:11 | get_Item | false |
| Partial.cs:45:9:45:11 | set_Item | false |
| Partial.cs:24:9:24:11 | get_PartialProperty1 | true |
| Partial.cs:25:9:25:11 | set_PartialProperty1 | true |
| Partial.cs:31:9:31:11 | get_Item | true |
| Partial.cs:32:9:32:11 | set_Item | true |
| Partial.cs:36:55:36:57 | add_PartialEvent1 | true |
| Partial.cs:36:63:36:68 | remove_PartialEvent1 | true |
| Partial.cs:48:30:48:32 | get_Property | false |
| Partial.cs:48:35:48:37 | set_Property | false |
| Partial.cs:51:9:51:11 | get_Item | false |
| Partial.cs:52:9:52:11 | set_Item | false |
| Partial.cs:54:31:54:35 | add_Event | false |
| Partial.cs:54:31:54:35 | remove_Event | false |

View File

@@ -1,4 +1,4 @@
| Partial.cs:1:15:1:26 | TwoPartClass | Partial.cs:1:15:1:26 | {...} |
| Partial.cs:32:15:32:33 | OnePartPartialClass | Partial.cs:32:15:32:33 | {...} |
| Partial.cs:38:7:38:21 | NonPartialClass | Partial.cs:38:7:38:21 | {...} |
| Partial.cs:3:15:3:26 | TwoPartClass | Partial.cs:3:15:3:26 | {...} |
| Partial.cs:39:15:39:33 | OnePartPartialClass | Partial.cs:39:15:39:33 | {...} |
| Partial.cs:45:7:45:21 | NonPartialClass | Partial.cs:45:7:45:21 | {...} |
| PartialMultipleFiles1.cs:1:22:1:41 | PartialMultipleFiles | PartialMultipleFiles1.cs:1:22:1:41 | {...} |

View File

@@ -0,0 +1,2 @@
| Partial.cs:36:39:36:51 | PartialEvent1 | true |
| Partial.cs:54:31:54:35 | Event | false |

View File

@@ -0,0 +1,7 @@
import csharp
private boolean isPartial(Event e) { if e.isPartial() then result = true else result = false }
from Event e
where e.fromSource()
select e, isPartial(e)

View File

@@ -1,2 +1,2 @@
| Partial.cs:25:27:25:30 | Item | true |
| Partial.cs:42:19:42:22 | Item | false |
| Partial.cs:29:27:29:30 | Item | true |
| Partial.cs:49:19:49:22 | Item | false |

View File

@@ -1,3 +1,3 @@
| Partial.cs:4:18:4:42 | PartialMethodWithoutBody1 | false |
| Partial.cs:14:18:14:39 | PartialMethodWithBody1 | true |
| Partial.cs:34:18:34:42 | PartialMethodWithoutBody2 | false |
| Partial.cs:6:18:6:42 | PartialMethodWithoutBody1 | false |
| Partial.cs:18:18:18:39 | PartialMethodWithBody1 | true |
| Partial.cs:41:18:41:42 | PartialMethodWithoutBody2 | false |

View File

@@ -1,2 +1,2 @@
| Partial.cs:18:27:18:42 | PartialProperty1 | true |
| Partial.cs:41:19:41:26 | Property | false |
| Partial.cs:22:27:22:42 | PartialProperty1 | true |
| Partial.cs:48:19:48:26 | Property | false |

View File

@@ -1,94 +1,112 @@
Partial.cs:
# 1| [Class] TwoPartClass
# 4| 6: [Method] PartialMethodWithoutBody1
# 4| -1: [TypeMention] Void
# 5| 7: [Method] Method2
# 3| [Class] TwoPartClass
# 6| 6: [Method] PartialMethodWithoutBody1
# 6| -1: [TypeMention] Void
# 7| 7: [Method] Method2
# 7| -1: [TypeMention] Void
# 7| 4: [BlockStmt] {...}
# 18| 8: [Method] PartialMethodWithBody1
# 5| -1: [TypeMention] Void
# 5| 4: [BlockStmt] {...}
# 14| 8: [Method] PartialMethodWithBody1
# 3| -1: [TypeMention] Void
# 14| 4: [BlockStmt] {...}
# 15| 9: [Method] Method3
# 15| -1: [TypeMention] Void
# 15| 4: [BlockStmt] {...}
# 16| 10: [Field] _backingField
# 16| -1: [TypeMention] object
# 18| 11: [Property] PartialProperty1
# 7| -1: [TypeMention] object
# 18| -1: [TypeMention] object
# 20| 3: [Getter] get_PartialProperty1
# 20| 4: [BlockStmt] {...}
# 20| 0: [ReturnStmt] return ...;
# 20| 0: [FieldAccess] access to field _backingField
# 21| 4: [Setter] set_PartialProperty1
#-----| 2: (Parameters)
# 21| 0: [Parameter] value
# 21| 4: [BlockStmt] {...}
# 21| 0: [ExprStmt] ...;
# 21| 0: [AssignExpr] ... = ...
# 21| 0: [FieldAccess] access to field _backingField
# 21| 1: [ParameterAccess] access to parameter value
# 23| 12: [Field] _backingArray
# 23| -1: [TypeMention] Object[]
# 23| 1: [TypeMention] object
# 25| 13: [Indexer] Item
# 18| 4: [BlockStmt] {...}
# 19| 9: [Method] Method3
# 19| -1: [TypeMention] Void
# 19| 4: [BlockStmt] {...}
# 20| 10: [Field] _backingField
# 20| -1: [TypeMention] object
# 22| 11: [Property] PartialProperty1
# 9| -1: [TypeMention] object
# 25| -1: [TypeMention] object
# 22| -1: [TypeMention] object
# 24| 3: [Getter] get_PartialProperty1
# 24| 4: [BlockStmt] {...}
# 24| 0: [ReturnStmt] return ...;
# 24| 0: [FieldAccess] access to field _backingField
# 25| 4: [Setter] set_PartialProperty1
#-----| 2: (Parameters)
# 25| 0: [Parameter] value
# 25| 4: [BlockStmt] {...}
# 25| 0: [ExprStmt] ...;
# 25| 0: [AssignExpr] ... = ...
# 25| 0: [FieldAccess] access to field _backingField
# 25| 1: [ParameterAccess] access to parameter value
# 27| 12: [Field] _backingArray
# 27| -1: [TypeMention] Object[]
# 27| 1: [TypeMention] object
# 29| 13: [Indexer] Item
# 11| -1: [TypeMention] object
# 29| -1: [TypeMention] object
#-----| 1: (Parameters)
# 9| 0: [Parameter] index
# 9| -1: [TypeMention] int
# 25| -1: [TypeMention] int
# 27| 3: [Getter] get_Item
# 11| 0: [Parameter] index
# 11| -1: [TypeMention] int
# 29| -1: [TypeMention] int
# 31| 3: [Getter] get_Item
#-----| 2: (Parameters)
# 25| 0: [Parameter] index
# 27| 4: [BlockStmt] {...}
# 27| 0: [ReturnStmt] return ...;
# 27| 0: [ArrayAccess] access to array element
# 27| -1: [FieldAccess] access to field _backingArray
# 27| 0: [ParameterAccess] access to parameter index
# 28| 4: [Setter] set_Item
# 29| 0: [Parameter] index
# 31| 4: [BlockStmt] {...}
# 31| 0: [ReturnStmt] return ...;
# 31| 0: [ArrayAccess] access to array element
# 31| -1: [FieldAccess] access to field _backingArray
# 31| 0: [ParameterAccess] access to parameter index
# 32| 4: [Setter] set_Item
#-----| 2: (Parameters)
# 25| 0: [Parameter] index
# 28| 1: [Parameter] value
# 28| 4: [BlockStmt] {...}
# 28| 0: [ExprStmt] ...;
# 28| 0: [AssignExpr] ... = ...
# 28| 0: [ArrayAccess] access to array element
# 28| -1: [FieldAccess] access to field _backingArray
# 28| 0: [ParameterAccess] access to parameter index
# 28| 1: [ParameterAccess] access to parameter value
# 32| [Class] OnePartPartialClass
# 34| 6: [Method] PartialMethodWithoutBody2
# 34| -1: [TypeMention] Void
# 35| 7: [Method] Method4
# 35| -1: [TypeMention] Void
# 35| 4: [BlockStmt] {...}
# 38| [Class] NonPartialClass
# 40| 6: [Method] Method5
# 40| -1: [TypeMention] Void
# 40| 4: [BlockStmt] {...}
# 41| 7: [Property] Property
# 41| -1: [TypeMention] object
# 41| 3: [Getter] get_Property
# 41| 4: [Setter] set_Property
# 29| 0: [Parameter] index
# 32| 1: [Parameter] value
# 32| 4: [BlockStmt] {...}
# 32| 0: [ExprStmt] ...;
# 32| 0: [AssignExpr] ... = ...
# 32| 0: [ArrayAccess] access to array element
# 32| -1: [FieldAccess] access to field _backingArray
# 32| 0: [ParameterAccess] access to parameter index
# 32| 1: [ParameterAccess] access to parameter value
# 36| 14: [Event] PartialEvent1
# 13| -1: [TypeMention] EventHandler
# 36| 3: [AddEventAccessor] add_PartialEvent1
#-----| 2: (Parameters)
# 41| 0: [Parameter] value
# 42| 8: [Indexer] Item
# 42| -1: [TypeMention] object
# 36| 0: [Parameter] value
# 36| 4: [BlockStmt] {...}
# 36| 4: [RemoveEventAccessor] remove_PartialEvent1
#-----| 2: (Parameters)
# 36| 0: [Parameter] value
# 36| 4: [BlockStmt] {...}
# 39| [Class] OnePartPartialClass
# 41| 6: [Method] PartialMethodWithoutBody2
# 41| -1: [TypeMention] Void
# 42| 7: [Method] Method4
# 42| -1: [TypeMention] Void
# 42| 4: [BlockStmt] {...}
# 45| [Class] NonPartialClass
# 47| 6: [Method] Method5
# 47| -1: [TypeMention] Void
# 47| 4: [BlockStmt] {...}
# 48| 7: [Property] Property
# 48| -1: [TypeMention] object
# 48| 3: [Getter] get_Property
# 48| 4: [Setter] set_Property
#-----| 2: (Parameters)
# 48| 0: [Parameter] value
# 49| 8: [Indexer] Item
# 49| -1: [TypeMention] object
#-----| 1: (Parameters)
# 42| 0: [Parameter] index
# 42| -1: [TypeMention] int
# 44| 3: [Getter] get_Item
# 49| 0: [Parameter] index
# 49| -1: [TypeMention] int
# 51| 3: [Getter] get_Item
#-----| 2: (Parameters)
# 42| 0: [Parameter] index
# 44| 4: [BlockStmt] {...}
# 44| 0: [ReturnStmt] return ...;
# 44| 0: [NullLiteral] null
# 45| 4: [Setter] set_Item
# 49| 0: [Parameter] index
# 51| 4: [BlockStmt] {...}
# 51| 0: [ReturnStmt] return ...;
# 51| 0: [NullLiteral] null
# 52| 4: [Setter] set_Item
#-----| 2: (Parameters)
# 42| 0: [Parameter] index
# 45| 1: [Parameter] value
# 45| 4: [BlockStmt] {...}
# 49| 0: [Parameter] index
# 52| 1: [Parameter] value
# 52| 4: [BlockStmt] {...}
# 54| 9: [Event] Event
# 54| -1: [TypeMention] EventHandler
# 54| 3: [AddEventAccessor] add_Event
#-----| 2: (Parameters)
# 54| 0: [Parameter] value
# 54| 4: [RemoveEventAccessor] remove_Event
#-----| 2: (Parameters)
# 54| 0: [Parameter] value
PartialMultipleFiles1.cs:
# 1| [Class] PartialMultipleFiles
PartialMultipleFiles2.cs: