@@ -71,9 +71,14 @@ private static List<Expression> CreateInjectingArguments(MethodInfo method, IRea
7171 var paramArrayType = parameter . ParameterType . GetElementType ( ) ! ;
7272
7373 for ( ; i < args . Count ; i ++ )
74- paramArray . Add ( Convert ( args [ i ] , paramArrayType ) ) ;
74+ paramArray . Add (
75+ Convert ( args [ i ] , paramArrayType ) ) ;
76+
77+ list . Add (
78+ Expression . NewArrayInit (
79+ paramArrayType ,
80+ paramArray ) ) ;
7581
76- list . Add ( Expression . NewArrayInit ( paramArrayType , paramArray ) ) ;
7782 break ;
7883 }
7984
@@ -112,10 +117,8 @@ private static Expression ApplyBinaryExpression(Identifier op, Func<Expression,
112117 if ( enumUnderlyingType is not null )
113118 {
114119 if ( lhs . Type != rhs . Type )
115- {
116120 if ( lhs . Type . IsEnum ? enumUnderlyingType != rhs . Type : enumUnderlyingType != lhs . Type )
117121 Error . NonApplicableBinaryOperator ( op , lhs . Type , rhs . Type ) ;
118- }
119122
120123 if ( lhs . Type . IsEnum )
121124 lhs = Expression . Convert ( lhs , enumUnderlyingType ) ;
@@ -128,35 +131,35 @@ private static Expression ApplyBinaryExpression(Identifier op, Func<Expression,
128131 {
129132 if ( ! TypeUtils . IsInteger ( lhs . Type ) && TypeUtils . IsInteger ( rhs . Type ) )
130133 Error . NonApplicableBinaryOperator ( op , lhs . Type , rhs . Type ) ;
131-
134+
132135 if ( rhs . Type == typeof ( sbyte )
133136 || rhs . Type == typeof ( byte )
134137 || rhs . Type == typeof ( short )
135138 || rhs . Type == typeof ( ushort ) )
136139 rhs = Expression . Convert ( rhs , typeof ( int ) ) ;
137-
140+
138141 if ( rhs . Type != typeof ( int ) )
139142 Error . NonApplicableBinaryOperator ( op , lhs . Type , rhs . Type ) ;
140-
143+
141144 if ( lhs . Type == typeof ( sbyte )
142145 || lhs . Type == typeof ( byte )
143146 || lhs . Type == typeof ( short )
144147 || lhs . Type == typeof ( ushort ) )
145148 lhs = Expression . Convert ( lhs , typeof ( int ) ) ;
146-
149+
147150 if ( op . Name == ">>>" )
148151 {
149152 if ( lhs . Type == typeof ( int ) )
150153 return Expression . Convert (
151154 apply ( Expression . Convert ( lhs , typeof ( uint ) ) , rhs ) ,
152155 typeof ( int ) ) ;
153-
156+
154157 if ( lhs . Type == typeof ( long ) )
155158 return Expression . Convert (
156159 apply ( Expression . Convert ( lhs , typeof ( ulong ) ) , rhs ) ,
157160 typeof ( long ) ) ;
158161 }
159-
162+
160163 return apply ( lhs , rhs ) ;
161164 }
162165
@@ -183,12 +186,28 @@ private static Expression ApplyBinaryExpression(Identifier op, Func<Expression,
183186 return result ;
184187 }
185188
186- //
187- // 12.4.7 Numeric promotions
188- // https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#1247-numeric-promotions
189- //
190189 private static void ApplyBinaryNumericPromotions ( Identifier op , ref Expression lhs , ref Expression rhs )
191190 {
191+ //
192+ // 12.4.7.3 Binary numeric promotions
193+ // https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#12473-binary-numeric-promotions
194+ //
195+ // Binary numeric promotion implicitly converts both operands to a common type which,
196+ // in case of the non-relational operators, also becomes the result type of the operation.
197+ // Binary numeric promotion consists of applying the following rules, in the order they appear here:
198+ //
199+ // * If either operand is of type decimal, the other operand is converted to type decimal,
200+ // or a binding-time error occurs if the other operand is of type float or double.
201+ // * Otherwise, if either operand is of type double, the other operand is converted to type double.
202+ // * Otherwise, if either operand is of type float, the other operand is converted to type float.
203+ // * Otherwise, if either operand is of type ulong, the other operand is converted to type ulong,
204+ // or a binding-time error occurs if the other operand is of type sbyte, short, int, or long.
205+ // * Otherwise, if either operand is of type long, the other operand is converted to type long.
206+ // * Otherwise, if either operand is of type uint and the other operand is of type sbyte, short, or int,
207+ // both operands are converted to type long.
208+ // * Otherwise, if either operand is of type uint, the other operand is converted to type uint.
209+ // * Otherwise, both operands are converted to type int.
210+
192211 var lhsType = lhs . Type ;
193212 var rhsType = rhs . Type ;
194213
@@ -218,8 +237,10 @@ private static void ApplyBinaryNumericPromotions(Identifier op, ref Expression l
218237
219238 if ( conversionType == typeof ( decimal ) )
220239 {
240+ //
221241 // If either operand is of type decimal, the other operand is converted to type decimal,
222242 // or a compile-time error occurs if the other operand is of type float or double.
243+ //
223244 if ( lhsType == typeof ( double )
224245 || lhsType == typeof ( float )
225246 || rhsType == typeof ( double )
@@ -228,8 +249,10 @@ private static void ApplyBinaryNumericPromotions(Identifier op, ref Expression l
228249 }
229250 else if ( conversionType == typeof ( ulong ) )
230251 {
231- // if either operand is of type ulong, the other operand is converted to type ulong,
252+ //
253+ // If either operand is of type ulong, the other operand is converted to type ulong,
232254 // or a compile-time error occurs if the other operand is of type sbyte, short, int, or long.
255+ //
233256 if ( lhsType == typeof ( sbyte )
234257 || lhsType == typeof ( short )
235258 || lhsType == typeof ( int )
@@ -242,8 +265,10 @@ private static void ApplyBinaryNumericPromotions(Identifier op, ref Expression l
242265 }
243266 else if ( conversionType == typeof ( uint ) )
244267 {
245- // if either operand is of type uint and the other operand is of type sbyte, short, or int,
268+ //
269+ // If either operand is of type uint and the other operand is of type sbyte, short, or int,
246270 // both operands are converted to type long.
271+ //
247272 if ( lhsType == typeof ( sbyte )
248273 || lhsType == typeof ( short )
249274 || lhsType == typeof ( int )
@@ -263,25 +288,25 @@ private static void ApplyBinaryNumericPromotions(Identifier op, ref Expression l
263288 }
264289 }
265290
266- private static Func < Expression , Expression , Expression > CreateOperatorFactory ( string @operator )
291+ private static Func < Expression , Expression , Expression > ResolveBinaryOperatorFactory ( string @operator )
267292 {
268293 return @operator switch
269294 {
270295 "??" => Expression . Coalesce ,
271- "||" => Expression . OrElse ,
272296 "&&" => Expression . AndAlso ,
273- "|" => Expression . Or ,
274- "^" => Expression . ExclusiveOr ,
275- "&" => Expression . And ,
297+ "||" => Expression . OrElse ,
276298 "==" => Expression . Equal ,
277299 "!=" => Expression . NotEqual ,
278300 "<=" => Expression . LessThanOrEqual ,
279- "<" => Expression . LessThan ,
280301 ">=" => Expression . GreaterThanOrEqual ,
281- ">" => Expression . GreaterThan ,
282302 ">>" => Expression . RightShift ,
283- ">>>" => Expression . RightShift ,
284303 "<<" => Expression . LeftShift ,
304+ ">>>" => Expression . RightShift ,
305+ "<" => Expression . LessThan ,
306+ ">" => Expression . GreaterThan ,
307+ "&" => Expression . And ,
308+ "|" => Expression . Or ,
309+ "^" => Expression . ExclusiveOr ,
285310 "+" => Expression . Add ,
286311 "-" => Expression . Subtract ,
287312 "*" => Expression . Multiply ,
0 commit comments