@@ -45,6 +45,22 @@ private static bool IsCompilerGenerated(FieldDefinition fieldDefinition)
45
45
return fieldDefinition . DeclaringType . CustomAttributes . Any ( ca => ca . AttributeType . FullName == typeof ( CompilerGeneratedAttribute ) . FullName ) ;
46
46
}
47
47
48
+ private static bool IsCompilerGeneratedField ( Instruction instruction , out FieldDefinition field )
49
+ {
50
+ switch ( instruction . Operand )
51
+ {
52
+ case FieldDefinition fieldDefinition when IsCompilerGenerated ( fieldDefinition ) :
53
+ field = fieldDefinition ;
54
+ return true ;
55
+ case FieldReference fieldReference when IsCompilerGenerated ( fieldReference . Resolve ( ) ) :
56
+ field = fieldReference . Resolve ( ) ;
57
+ return true ;
58
+ default :
59
+ field = null ;
60
+ return false ;
61
+ }
62
+ }
63
+
48
64
private static bool IsMoveNextInsideAsyncStateMachine ( MethodDefinition methodDefinition )
49
65
{
50
66
if ( methodDefinition . FullName . EndsWith ( "::MoveNext()" ) && IsCompilerGenerated ( methodDefinition ) )
@@ -537,11 +553,9 @@ static bool CheckForAsyncEnumerator(List<Instruction> instructions, Instruction
537
553
( instructions [ currentIndex - 2 ] . OpCode == OpCodes . Ldarg ||
538
554
instructions [ currentIndex - 2 ] . OpCode == OpCodes . Ldarg_0 ) &&
539
555
instructions [ currentIndex - 1 ] . OpCode == OpCodes . Ldfld &&
540
- (
541
- ( instructions [ currentIndex - 1 ] . Operand is FieldDefinition field && IsCompilerGenerated ( field ) && field . FieldType . FullName . StartsWith ( "System.Collections.Generic.IAsyncEnumerator" ) ) ||
542
- ( instructions [ currentIndex - 1 ] . Operand is FieldReference fieldRef && IsCompilerGenerated ( fieldRef . Resolve ( ) ) && fieldRef . FieldType . FullName . StartsWith ( "System.Collections.Generic.IAsyncEnumerator" ) )
543
- )
544
- )
556
+ IsCompilerGeneratedField ( instructions [ currentIndex - 1 ] , out FieldDefinition field ) &&
557
+ field . FieldType . FullName . StartsWith ( "System.Collections.Generic.IAsyncEnumerator" )
558
+ )
545
559
{
546
560
return true ;
547
561
}
@@ -582,10 +596,8 @@ static bool CheckIfExceptionThrown(List<Instruction> instructions, Instruction i
582
596
for ( int i = currentIndex - 1 ; i >= minFieldIndex ; -- i )
583
597
{
584
598
if ( instructions [ i ] . OpCode == OpCodes . Ldfld &&
585
- (
586
- ( instructions [ i ] . Operand is FieldDefinition field && IsCompilerGenerated ( field ) && field . FieldType . FullName == "System.Object" ) ||
587
- ( instructions [ i ] . Operand is FieldReference fieldRef && IsCompilerGenerated ( fieldRef . Resolve ( ) ) && fieldRef . FieldType . FullName == "System.Object" )
588
- ) )
599
+ IsCompilerGeneratedField ( instructions [ i ] , out FieldDefinition field ) &&
600
+ field . FieldType . FullName == "System.Object" )
589
601
{
590
602
// We expect the call to GetResult() to be no more than four
591
603
// instructions before the loading of the field's value.
@@ -708,16 +720,16 @@ static bool CheckForSkipDisposal(List<Instruction> instructions, Instruction ins
708
720
709
721
bool isFollowedByDisposeAsync = false ;
710
722
711
- if ( instructions [ currentIndex - 1 ] . OpCode == OpCodes . Ldfld &&
712
- instructions [ currentIndex - 1 ] . Operand is FieldDefinition field &&
713
- IsCompilerGenerated ( field ) )
723
+ if ( instructions [ currentIndex - 1 ] . OpCode == OpCodes . Ldfld )
714
724
{
725
+ if ( ! IsCompilerGeneratedField ( instructions [ currentIndex - 1 ] , out FieldDefinition field ) ) return false ;
726
+
715
727
int maxReloadFieldIndex = Math . Min ( currentIndex + 2 , instructions . Count - 2 ) ;
716
728
717
729
for ( int i = currentIndex + 1 ; i <= maxReloadFieldIndex ; ++ i )
718
730
{
719
731
if ( instructions [ i ] . OpCode == OpCodes . Ldfld &&
720
- instructions [ i ] . Operand is FieldDefinition reloadedField &&
732
+ IsCompilerGeneratedField ( instructions [ i ] , out FieldDefinition reloadedField ) &&
721
733
field . Equals ( reloadedField ) &&
722
734
instructions [ i + 1 ] . OpCode == OpCodes . Callvirt &&
723
735
instructions [ i + 1 ] . Operand is MethodReference method &&
@@ -758,8 +770,8 @@ instructions[i].Operand is FieldDefinition reloadedField &&
758
770
if ( ( instructions [ i ] . OpCode == OpCodes . Leave ||
759
771
instructions [ i ] . OpCode == OpCodes . Leave_S ) &&
760
772
instructions [ i - 1 ] . OpCode == OpCodes . Stfld &&
761
- instructions [ i - 1 ] . Operand is FieldDefinition storeField &&
762
- IsCompilerGenerated ( storeField ) )
773
+ IsCompilerGeneratedField ( instructions [ i - 1 ] , out FieldDefinition _ )
774
+ )
763
775
{
764
776
return true ;
765
777
}
@@ -811,9 +823,7 @@ static bool CheckForCleanup(List<Instruction> instructions, Instruction instruct
811
823
812
824
for ( int i = currentIndex - 2 ; i >= minLoadFieldIndex ; -- i )
813
825
{
814
- if ( instructions [ i ] . OpCode == OpCodes . Ldfld &&
815
- instructions [ i ] . Operand is FieldDefinition loadedField &&
816
- IsCompilerGenerated ( loadedField ) )
826
+ if ( instructions [ i ] . OpCode == OpCodes . Ldfld && IsCompilerGeneratedField ( instructions [ i ] , out FieldDefinition _ ) )
817
827
{
818
828
int minRethrowIndex = Math . Max ( 0 , i - 4 ) ;
819
829
@@ -918,10 +928,8 @@ static bool DisposeCheck(List<Instruction> instructions, Instruction instruction
918
928
919
929
if ( currentIndex >= 2 &&
920
930
instructions [ currentIndex - 1 ] . OpCode == OpCodes . Ldfld &&
921
- (
922
- ( instructions [ currentIndex - 1 ] . Operand is FieldDefinition field && IsCompilerGenerated ( field ) && field . FullName . EndsWith ( "__disposeMode" ) ) ||
923
- ( instructions [ currentIndex - 1 ] . Operand is FieldReference fieldRef && IsCompilerGenerated ( fieldRef . Resolve ( ) ) && fieldRef . FullName . EndsWith ( "__disposeMode" ) )
924
- ) &&
931
+ IsCompilerGeneratedField ( instructions [ currentIndex - 1 ] , out FieldDefinition field ) &&
932
+ field . FullName . EndsWith ( "__disposeMode" ) &&
925
933
( instructions [ currentIndex - 2 ] . OpCode == OpCodes . Ldarg ||
926
934
instructions [ currentIndex - 2 ] . OpCode == OpCodes . Ldarg_0 ) )
927
935
{
0 commit comments