@@ -94,7 +94,9 @@ public enum NotSupported
9494 /// <summary>MemberInit ListBinding is not supported</summary>
9595 MemberInit_ListBinding ,
9696 /// <summary>Goto of the Return kind from the TryCatch is not supported</summary>
97- Try_GotoReturnToTheFollowupLabel
97+ Try_GotoReturnToTheFollowupLabel ,
98+ /// <summary>Not supported assignment target</summary>
99+ Assign_Target
98100 }
99101
100102 /// <summary>FEC Not Supported exception</summary>
@@ -104,6 +106,8 @@ public sealed class NotSupportedExpressionException : InvalidOperationException
104106 public readonly NotSupported Reason ;
105107 /// <summary>Constructor</summary>
106108 public NotSupportedExpressionException ( NotSupported reason ) : base ( reason . ToString ( ) ) => Reason = reason ;
109+ /// <summary>Constructor</summary>
110+ public NotSupportedExpressionException ( NotSupported reason , string message ) : base ( reason + ": " + message ) => Reason = reason ;
107111 }
108112
109113 /// <summary>The interface is implemented by the compiled delegate Target if `CompilerFlags.EnableDelegateDebugInfo` is set.</summary>
@@ -2130,7 +2134,7 @@ private static bool TryEmitIndex(IndexExpression indexExpr, IReadOnlyList<PE> p
21302134 var indexerProp = indexExpr . Indexer ;
21312135 MethodInfo indexerPropGetter = null ;
21322136 if ( indexerProp != null )
2133- indexerPropGetter = indexerProp . DeclaringType . FindPropertyGetMethod ( indexerProp . Name ) ;
2137+ indexerPropGetter = indexerProp . GetMethod ;
21342138
21352139 var p = parent | ParentFlags . IndexAccess ;
21362140 if ( indexerPropGetter == null )
@@ -2148,13 +2152,13 @@ private static bool TryEmitIndex(IndexExpression indexExpr, IReadOnlyList<PE> p
21482152 }
21492153
21502154 if ( indexerPropGetter != null )
2151- return EmitMethodCallOrVirtCall ( il , indexerPropGetter ) ;
2155+ return EmitMethodCallOrVirtualCall ( il , indexerPropGetter ) ;
21522156
21532157 if ( indexArgCount == 1 ) // one-dimensional array
21542158 return TryEmitArrayIndex ( indexExpr . Type , il , parent , ref closure ) ;
21552159
21562160 indexerPropGetter = indexExpr . Object ? . Type . FindMethod ( "Get" ) ; // multi-dimensional array
2157- return indexerPropGetter != null && EmitMethodCallOrVirtCall ( il , indexerPropGetter ) ;
2161+ return indexerPropGetter != null && EmitMethodCallOrVirtualCall ( il , indexerPropGetter ) ;
21582162 }
21592163
21602164#if LIGHT_EXPRESSION
@@ -2747,7 +2751,7 @@ private static bool TryEmitConvert(UnaryExpression expr, IReadOnlyList<PE> param
27472751 if ( ! TryEmit ( opExpr , paramExprs , il , ref closure , setup ,
27482752 parent & ~ ParentFlags . IgnoreResult | ParentFlags . InstanceCall , - 1 ) )
27492753 return false ;
2750- return EmitMethodCallOrVirtCall ( il , method ) ;
2754+ return EmitMethodCallOrVirtualCall ( il , method ) ;
27512755 }
27522756
27532757 var sourceType = opExpr . Type ;
@@ -3419,8 +3423,8 @@ private static bool EmitMemberAssign(ILGenerator il, MemberInfo member)
34193423 {
34203424 if ( member is PropertyInfo prop )
34213425 {
3422- var method = prop . DeclaringType . FindPropertySetMethod ( prop . Name ) ;
3423- return method != null && EmitMethodCallOrVirtCall ( il , method ) ;
3426+ var method = prop . SetMethod ;
3427+ return method != null && EmitMethodCallOrVirtualCall ( il , method ) ;
34243428 }
34253429 if ( member is FieldInfo field )
34263430 {
@@ -3503,7 +3507,7 @@ private static bool TryEmitListInit(ListInitExpression expr, IReadOnlyList<PE> p
35033507 }
35043508
35053509 if ( ! exprType . IsValueType )
3506- EmitMethodCallOrVirtCall ( il , method ) ;
3510+ EmitMethodCallOrVirtualCall ( il , method ) ;
35073511 else if ( ! method . IsVirtual ) // #251 - no need for constrain or virtual call because it is already by-ref
35083512 EmitMethodCall ( il , method ) ;
35093513 else if ( method . DeclaringType == exprType )
@@ -3869,7 +3873,9 @@ private static bool TryEmitAssign(BinaryExpression expr, IReadOnlyList<PE> param
38693873 EmitLoadLocalVariable ( il , varIndex ) ;
38703874 return true ;
38713875
3872- default : // todo: not yet support assignment targets
3876+ default : // todo: @feature not yet support assignment targets
3877+ if ( ( setup & CompilerFlags . ThrowOnNotSupportedExpression ) != 0 )
3878+ throw new NotSupportedExpressionException ( NotSupported . Assign_Target , $ "Assignment target `{ nodeType } ` is not supported") ;
38733879 return false ;
38743880 }
38753881 }
@@ -3912,7 +3918,7 @@ private static bool TryEmitIndexAssign(IndexExpression indexExpr, Type instType,
39123918 }
39133919
39143920 var setter = instType ? . FindMethod ( "Set" ) ;
3915- return setter != null && EmitMethodCallOrVirtCall ( il , setter ) ; // multi dimensional array
3921+ return setter != null && EmitMethodCallOrVirtualCall ( il , setter ) ; // multi dimensional array
39163922 }
39173923
39183924#if LIGHT_EXPRESSION
@@ -3957,7 +3963,7 @@ private static bool TryEmitMethodCall(Expression expr, IReadOnlyList<PE> paramE
39573963 }
39583964
39593965 if ( ! objIsValueType )
3960- EmitMethodCallOrVirtCall ( il , method ) ;
3966+ EmitMethodCallOrVirtualCall ( il , method ) ;
39613967 else if ( ! method . IsVirtual || objExpr is ParameterExpression p && p . IsByRef )
39623968 EmitMethodCall ( il , method ) ;
39633969 else if ( method . DeclaringType == objExpr . Type )
@@ -4006,11 +4012,7 @@ private static bool TryEmitMemberAccess(MemberExpression expr, IReadOnlyList<PE>
40064012 }
40074013
40084014 closure . LastEmitIsAddress = false ;
4009- var propGetter = prop . DeclaringType . FindPropertyGetMethod ( prop . Name ) ;
4010- if ( propGetter == null )
4011- return false ;
4012-
4013- il . Emit ( propGetter . IsVirtual ? OpCodes . Callvirt : OpCodes . Call , propGetter ) ;
4015+ EmitMethodCallOrVirtualCall ( il , prop . GetMethod ) ;
40144016 return true ;
40154017 }
40164018
@@ -4674,7 +4676,7 @@ var methodName
46744676 }
46754677 }
46764678
4677- return method != null && EmitMethodCallOrVirtCall ( il , method ) ;
4679+ return method != null && EmitMethodCallOrVirtualCall ( il , method ) ;
46784680 }
46794681 }
46804682
@@ -4953,7 +4955,7 @@ private static Expression TryReduceCondition(Expression testExpr)
49534955
49544956 // get the advantage of the optimized specialized EmitCall method
49554957 [ MethodImpl ( ( MethodImplOptions ) 256 ) ]
4956- private static bool EmitMethodCallOrVirtCall ( ILGenerator il , MethodInfo method )
4958+ private static bool EmitMethodCallOrVirtualCall ( ILGenerator il , MethodInfo method )
49574959 {
49584960#if SUPPORTS_EMITCALL
49594961 il . EmitCall ( method . IsVirtual ? OpCodes . Callvirt : OpCodes . Call , method , null ) ;
@@ -5166,7 +5168,7 @@ internal static MethodInfo FindMethod(this Type type, string methodName)
51665168 }
51675169
51685170 internal static MethodInfo DelegateTargetGetterMethod =
5169- typeof ( Delegate ) . FindPropertyGetMethod ( " Target" ) ;
5171+ typeof ( Delegate ) . GetProperty ( nameof ( Delegate . Target ) ) . GetMethod ;
51705172
51715173 internal static MethodInfo FindDelegateInvokeMethod ( this Type type ) => type . GetMethod ( "Invoke" ) ;
51725174
@@ -5183,63 +5185,17 @@ internal static MethodInfo FindNullableGetValueOrDefaultMethod(this Type type)
51835185 return null ;
51845186 }
51855187
5186- internal static MethodInfo FindValueGetterMethod ( this Type type ) =>
5187- type . FindPropertyGetMethod ( "Value" ) ;
5188-
5189- internal static MethodInfo FindNullableHasValueGetterMethod ( this Type type ) =>
5190- type . FindPropertyGetMethod ( "HasValue" ) ;
5191-
5192- internal static MethodInfo FindPropertyGetMethod ( this Type propHolderType , string propName )
5193- {
5194- var methods = propHolderType . GetMethods ( ) ;
5195- for ( var i = 0 ; i < methods . Length ; i ++ )
5196- {
5197- var method = methods [ i ] ;
5198- if ( method . IsSpecialName )
5199- {
5200- var methodName = method . Name ;
5201- if ( methodName . Length == propName . Length + 4 && methodName [ 0 ] == 'g' && methodName [ 3 ] == '_' )
5202- {
5203- var j = propName . Length - 1 ;
5204- while ( j != - 1 && propName [ j ] == methodName [ j + 4 ] ) -- j ;
5205- if ( j == - 1 )
5206- return method ;
5207- }
5208- }
5209- }
5210-
5211- return propHolderType . BaseType ? . FindPropertyGetMethod ( propName ) ;
5212- }
5213-
5214- internal static MethodInfo FindPropertySetMethod ( this Type propHolderType , string propName )
5215- {
5216- var methods = propHolderType . GetMethods ( BindingFlags . Instance | BindingFlags . Static | BindingFlags . Public | BindingFlags . NonPublic ) ;
5217- for ( var i = 0 ; i < methods . Length ; i ++ )
5218- {
5219- var method = methods [ i ] ;
5220- if ( method . IsSpecialName )
5221- {
5222- var methodName = method . Name ;
5223- if ( methodName . Length == propName . Length + 4 && methodName [ 0 ] == 's' && methodName [ 3 ] == '_' )
5224- {
5225- var j = propName . Length - 1 ;
5226- while ( j != - 1 && propName [ j ] == methodName [ j + 4 ] ) -- j ;
5227- if ( j == - 1 )
5228- return method ;
5229- }
5230- }
5231- }
5188+ internal static MethodInfo FindValueGetterMethod ( this Type type ) => type . GetProperty ( "Value" ) . GetMethod ;
52325189
5233- return propHolderType . BaseType ? . FindPropertySetMethod ( propName ) ;
5234- }
5190+ internal static MethodInfo FindNullableHasValueGetterMethod ( this Type type ) => type . GetProperty ( "HasValue" ) . GetMethod ;
52355191
52365192 internal static MethodInfo FindConvertOperator ( this Type type , Type sourceType , Type targetType )
52375193 {
5238- var methods = type . GetMethods ( ) ;
5194+ var methods = type . GetMethods ( BindingFlags . Static | BindingFlags . Public | BindingFlags . NonPublic ) ;
52395195 for ( var i = 0 ; i < methods . Length ; i ++ )
52405196 {
52415197 var m = methods [ i ] ;
5242- if ( m . IsStatic && m . IsSpecialName && m . ReturnType == targetType )
5198+ if ( m . IsSpecialName && m . ReturnType == targetType )
52435199 {
52445200 var n = m . Name ;
52455201 // n == "op_Implicit" || n == "op_Explicit"
@@ -5255,7 +5211,7 @@ internal static MethodInfo FindConvertOperator(this Type type, Type sourceType,
52555211
52565212 internal static ConstructorInfo FindSingleParamConstructor ( this Type type , Type paramType )
52575213 {
5258- var ctors = type . GetConstructors ( ) ;
5214+ var ctors = type . GetConstructors ( BindingFlags . Instance | BindingFlags . Public | BindingFlags . NonPublic ) ;
52595215 for ( var i = 0 ; i < ctors . Length ; i ++ )
52605216 {
52615217 var ctor = ctors [ i ] ;
0 commit comments