-
-
Notifications
You must be signed in to change notification settings - Fork 94
Expand file tree
/
Copy pathExpression.cs
More file actions
5951 lines (5148 loc) · 310 KB
/
Expression.cs
File metadata and controls
5951 lines (5148 loc) · 310 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// <auto-generated/>
/*
The MIT License (MIT)
Copyright (c) 2016-2026 Maksim Volkau
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// ReSharper disable CoVariantArrayConversion
#nullable disable
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
#define SUPPORTS_VISITOR
namespace FastExpressionCompiler.LightExpression;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Text;
using System.Linq;
using SysExpr = System.Linq.Expressions.Expression;
using FastExpressionCompiler.LightExpression.ImTools;
using static ExpressionCompiler;
using static ToCSharpPrinter;
using static CodePrinter;
/// <summary>The base class and the Factory methods provider for the Expression.</summary>
public abstract class Expression
{
/// <summary>Expression node type.</summary>
public abstract ExpressionType NodeType { get; }
/// <summary>All expressions should have a Type.</summary>
public abstract Type Type { get; }
/// <summary>You may use it whatever you like overloading for the specific value in your custom expression.</summary>
public virtual object Tag => null;
/// <summary>Allows to overwrite the FEC stages to customize and optimize
/// the expression constant(label, blocks, tries) collection and il emitting phase</summary>
public virtual bool IsIntrinsic => false;
/// <summary>Collects the information about closure constants, nested lambdas, non-passed parameters, goto labels and variables in blocks.
/// Returns `0` if everything is fine and positive error code for error.</summary>
[RequiresUnreferencedCode(Trimming.Message)]
public virtual Result TryCollectInfo(ref CompilerContext context, NestedLambdaInfo nestedLambda, ref SmallList<NestedLambdaInfo> rootNestedLambdas) => 0;
/// <summary>The second FEC state to emit the actual IL op-codes based on the information collected by the first traversal
/// and available in the `closure` structure. Find the expression examples below by searching `IsIntrinsic => true`.</summary>
[RequiresUnreferencedCode(Trimming.Message)]
public virtual bool TryEmit(ref CompilerContext context, ILGenerator il, ParentFlags parent, int byRefIndex = -1) => false;
public virtual bool IsCustomToCSharpString => false;
[RequiresUnreferencedCode(Trimming.Message)]
public virtual StringBuilder CustomToCSharpString(StringBuilder sb, EnclosedIn enclosedIn, ref PrintContext ctx,
int lineIndent = 0, bool stripNamespace = false, Func<Type, string, string> printType = null, int indentSpaces = 4,
ObjectToCode notRecognizedToCode = null) => sb;
#if SUPPORTS_VISITOR
[RequiresUnreferencedCode(Trimming.Message)]
protected internal abstract Expression Accept(ExpressionVisitor visitor);
#endif
protected internal virtual Expression VisitChildren(ExpressionVisitor visitor) => this;
/// <summary>Converts the LightExpression to the System Expression to enable fallback to the System Compile</summary>
public SysExpr ToExpression()
{
var exprsConverted = new SmallList<LightAndSysExpr>(Tools.Empty<LightAndSysExpr>());
return ToExpression(ref exprsConverted);
}
internal SysExpr ToExpression(ref SmallList<LightAndSysExpr> exprsConverted)
{
var i = exprsConverted.Count - 1;
while (i != -1 && !ReferenceEquals(exprsConverted.Items[i].LightObj, this)) --i;
if (i != -1)
return (SysExpr)exprsConverted.Items[i].SysExpr;
var sysExpr = CreateSysExpression(ref exprsConverted);
ref var item = ref exprsConverted.AddDefaultAndGetRef();
item.LightObj = this;
item.SysExpr = sysExpr;
return sysExpr;
}
// todo: @perf can use the SmallMap instead of the SmallList here?
internal abstract SysExpr CreateSysExpression(ref SmallList<LightAndSysExpr> convertedExpressions);
/// <summary>Converts to Expression and outputs its as string</summary>
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode",
Justification = "The method is used for debugging purposes only.")]
public override string ToString() => this.ToCSharpString(
new StringBuilder(256), stripNamespace: true,
notRecognizedToCode: static (x, stripNs, printType) => "default(" + x.GetType().ToCode(stripNs, printType) + ")/*" + x.ToString() + "*/")
.ToString();
/// <summary>Reduces the Expression to simple ones</summary>
public virtual Expression Reduce() => this;
internal static SysExpr[] ToExpressions(IReadOnlyList<Expression> exprs, ref SmallList<LightAndSysExpr> exprsConverted)
{
if (exprs.Count == 0)
return Tools.Empty<SysExpr>();
if (exprs.Count == 1)
return new[] { exprs[0].ToExpression(ref exprsConverted) };
var result = new SysExpr[exprs.Count];
for (var i = 0; i < result.Length; ++i)
result[i] = exprs[i].ToExpression(ref exprsConverted);
return result;
}
[MethodImpl((MethodImplOptions)256)]
public static ParameterExpression Parameter(Type type, string name = null) =>
type.IsByRef ? new ByRefParameterExpression(type.GetElementType(), name) :
type.IsEnum ? new TypedParameterExpression(type, name) :
TryToMakeKnownTypeParameter(type, name);
[MethodImpl((MethodImplOptions)256)]
public static ParameterExpression ParameterOf<T>(string name = null) => new TypedParameterExpression<T>(name);
public static ParameterExpression Variable(Type type, string name = null) => Parameter(type, name);
// Enum is excluded because otherwise TypeCode will return the thing for the underlying
private static ParameterExpression TryToMakeKnownTypeParameter(Type type, string name = null) =>
Type.GetTypeCode(type) switch
{
TypeCode.Boolean => new TypedParameterExpression<bool>(name),
TypeCode.Byte => new TypedParameterExpression<byte>(name),
TypeCode.Char => new TypedParameterExpression<char>(name),
TypeCode.DateTime => new TypedParameterExpression<DateTime>(name),
TypeCode.Decimal => new TypedParameterExpression<decimal>(name),
TypeCode.Double => new TypedParameterExpression<double>(name),
TypeCode.Int16 => new TypedParameterExpression<short>(name),
TypeCode.Int32 => new TypedParameterExpression<int>(name),
TypeCode.Int64 => new TypedParameterExpression<long>(name),
TypeCode.SByte => new TypedParameterExpression<sbyte>(name),
TypeCode.Single => new TypedParameterExpression<float>(name),
TypeCode.String => new TypedParameterExpression<string>(name),
TypeCode.UInt16 => new TypedParameterExpression<ushort>(name),
TypeCode.UInt32 => new TypedParameterExpression<uint>(name),
TypeCode.UInt64 => new TypedParameterExpression<ulong>(name),
// we cannot match on TypeCode.Object because it corresponds to any reference type
_ => type == typeof(object) ? new TypedParameterExpression<object>(name)
: type == typeof(object[]) ? new TypedParameterExpression<object[]>(name)
: new TypedParameterExpression(type, name)
};
public static readonly ConstantExpression NullConstant = new NullConstantExpression<object>();
public static readonly ConstantExpression FalseConstant = new ValueConstantExpression<bool>(false);
public static readonly ConstantExpression TrueConstant = new ValueConstantExpression<bool>(true);
public static readonly ConstantExpression ZeroConstant = new IntConstantExpression(0);
public static readonly ConstantExpression OneConstant = new IntConstantExpression(1);
public static readonly ConstantExpression MinusOneConstant = new IntConstantExpression(-1);
/// <summary>Holds the value that you can change lately</summary>
public sealed class ValueRef<T>
{
/// <summary>Reflection access to the value FieldInfo</summary>
public static readonly FieldInfo ValueField = typeof(ValueRef<T>).GetField(nameof(Value), BindingFlags.Public | BindingFlags.Instance);
/// <summary>The adjustable value</summary>
public T Value;
/// <summary>Construct with the initial value</summary>
public ValueRef(T value) => Value = value;
}
/// <summary>Simplifies the constant which is always hold in Closure and which Value can be modified after the compilation</summary>
public static Expression ConstantRef<T>(T value, out ValueRef<T> valueRef)
{
valueRef = new ValueRef<T>(value);
// todo: @perf try the intrinsic?
return new InstanceFieldExpression(new ValueConstantExpression<ValueRef<T>>(valueRef), ValueRef<T>.ValueField);
}
/// <summary>Avoids the boxing for all (two) bool values</summary>
public static ConstantExpression Constant(bool value) => value ? TrueConstant : FalseConstant;
public static ConstantExpression Constant(object value) =>
value == null ? NullConstant :
value is bool b ? (b ? TrueConstant : FalseConstant) :
value is int n ? (
n == 0 ? ZeroConstant :
n == 1 ? OneConstant :
n == -1 ? MinusOneConstant :
new IntConstantExpression(n)) :
new ValueConstantExpression(value);
public static ConstantExpression Constant(object value, Type type) =>
value == null ? ConstantNull(type) :
type == typeof(bool) ? ((bool)value ? TrueConstant : FalseConstant) :
type == value.GetType() ? new ValueConstantExpression(value) :
new TypedValueConstantExpression(value, type);
[MethodImpl((MethodImplOptions)256)]
public static ConstantExpression ConstantNull(Type type = null) =>
type == null || type == typeof(object) ? NullConstant : new TypedNullConstantExpression(type);
[MethodImpl((MethodImplOptions)256)]
public static ConstantExpression ConstantNull<T>() => new NullConstantExpression<T>();
[MethodImpl((MethodImplOptions)256)]
public static ConstantExpression ConstantInt(int value) => new IntConstantExpression(value);
[MethodImpl((MethodImplOptions)256)]
public static ConstantExpression ConstantOf<T>(T value) =>
value == null ? ConstantNull<T>() : new ValueConstantExpression<T>(value);
[RequiresUnreferencedCode(Trimming.Message)]
public static NewExpression New(Type type)
{
if (type.IsValueType)
return new NewValueTypeExpression(type);
foreach (var x in type.GetConstructors())
if (x.GetParameters().Length == 0)
return new NoArgsNewClassIntrinsicExpression(x);
throw new ArgumentException($"The type {type} is missing the default constructor");
}
public static NewExpression New(ConstructorInfo ctor, IReadOnlyList<Expression> arguments) =>
arguments == null || arguments.Count == 0
? new NoArgsNewClassIntrinsicExpression(ctor)
: new ManyArgumentsNewExpression(ctor, arguments);
public static NewExpression New(ConstructorInfo ctor, params Expression[] arguments) =>
New(ctor, (IReadOnlyList<Expression>)arguments);
public static NewExpression New(ConstructorInfo ctor, IEnumerable<Expression> arguments) =>
New(ctor, arguments.AsReadOnlyList());
public static NewExpression NewNoByRefArgs(ConstructorInfo ctor, IReadOnlyList<Expression> arguments) =>
arguments == null || arguments.Count == 0
? new NoArgsNewClassIntrinsicExpression(ctor)
: new NoByRefManyArgsNewIntrinsicExpression(ctor, arguments);
public static NewExpression New(ConstructorInfo ctor) => new NoArgsNewClassIntrinsicExpression(ctor);
public static NewExpression New(ConstructorInfo ctor, Expression arg) => new OneArgumentNewExpression(ctor, arg);
public static NewExpression NewObjArgs(ConstructorInfo ctor, object arg) => new OneArgumentNewExpression(ctor, arg);
public static NewExpression NewNoByRefArgs(ConstructorInfo ctor, object arg) => new NoByRefOneArgNewIntrinsicExpression(ctor, arg);
public static NewExpression New(ConstructorInfo ctor, Expression arg0, Expression arg1) =>
new TwoArgumentsNewExpression(ctor, arg0, arg1);
public static NewExpression NewObjArgs(ConstructorInfo ctor, object arg0, object arg1) =>
new TwoArgumentsNewExpression(ctor, arg0, arg1);
public static NewExpression NewNoByRefArgs(ConstructorInfo ctor, object arg0, object arg1) =>
new NoByRefTwoArgumentsNewIntrinsicExpression(ctor, arg0, arg1);
public static NewExpression New(ConstructorInfo ctor, Expression arg0, Expression arg1, Expression arg2) =>
new ThreeArgumentsNewExpression(ctor, arg0, arg1, arg2);
public static NewExpression New(ConstructorInfo ctor, object arg0, object arg1, object arg2) =>
new ThreeArgumentsNewExpression(ctor, arg0, arg1, arg2);
public static NewExpression NewNoByRefArgs(ConstructorInfo ctor, object arg0, object arg1, object arg2) =>
new NoByRefThreeArgumentsNewIntrinsicExpression(ctor, arg0, arg1, arg2);
public static NewExpression New(ConstructorInfo ctor, Expression arg0, Expression arg1, Expression arg2, Expression arg3) =>
new FourArgumentsNewExpression(ctor, arg0, arg1, arg2, arg3);
public static NewExpression NewObjArgs(ConstructorInfo ctor, object arg0, object arg1, object arg2, object arg3) =>
new FourArgumentsNewExpression(ctor, arg0, arg1, arg2, arg3);
public static NewExpression NewNoByRefArgs(ConstructorInfo ctor, object arg0, object arg1, object arg2, object arg3) =>
new NoByRefFourArgumentsNewIntrinsicExpression(ctor, arg0, arg1, arg2, arg3);
public static NewExpression New(ConstructorInfo ctor, Expression arg0, Expression arg1, Expression arg2, Expression arg3, Expression arg4) =>
new FiveArgumentsNewExpression(ctor, arg0, arg1, arg2, arg3, arg4);
public static NewExpression NewObjArgs(ConstructorInfo ctor, object arg0, object arg1, object arg2, object arg3, object arg4) =>
new FiveArgumentsNewExpression(ctor, arg0, arg1, arg2, arg3, arg4);
public static NewExpression NewNoByRefArgs(ConstructorInfo ctor, object arg0, object arg1, object arg2, object arg3, object arg4) =>
new NoByRefFiveArgumentsNewIntrinsicExpression(ctor, arg0, arg1, arg2, arg3, arg4);
public static NewExpression New(ConstructorInfo ctor,
Expression arg0, Expression arg1, Expression arg2, Expression arg3, Expression arg4, Expression arg5) =>
new SixArgumentsNewExpression(ctor, arg0, arg1, arg2, arg3, arg4, arg5);
public static NewExpression NewObjArgs(ConstructorInfo ctor,
object arg0, object arg1, object arg2, object arg3, object arg4, object arg5) =>
new SixArgumentsNewExpression(ctor, arg0, arg1, arg2, arg3, arg4, arg5);
public static NewExpression NewNoByRefArgs(ConstructorInfo ctor,
object arg0, object arg1, object arg2, object arg3, object arg4, object arg5) =>
new NoByRefSixArgumentsNewIntrinsicExpression(ctor, arg0, arg1, arg2, arg3, arg4, arg5);
public static NewExpression New(ConstructorInfo ctor,
Expression arg0, Expression arg1, Expression arg2, Expression arg3, Expression arg4, Expression arg5, Expression arg6) =>
new SevenArgumentsNewExpression(ctor, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
public static NewExpression NewObjArgs(ConstructorInfo ctor,
object arg0, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6) =>
new SevenArgumentsNewExpression(ctor, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
public static NewExpression NewNoByRefArgs(ConstructorInfo ctor,
object arg0, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6) =>
new NoByRefSevenArgumentsNewIntrinsicExpression(ctor, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
public static MethodCallExpression Call(MethodInfo method, IReadOnlyList<Expression> arguments) =>
arguments == null || arguments.Count == 0
? new NotNullMethodCallExpression(method)
: new ManyArgumentsMethodCallExpression(method, arguments);
public static MethodCallExpression Call(MethodInfo method, params Expression[] arguments) =>
Call(method, (IReadOnlyList<Expression>)arguments);
public static MethodCallExpression Call(MethodInfo method, IEnumerable<Expression> arguments) =>
Call(method, arguments.AsReadOnlyList());
public static MethodCallExpression Call(Expression instance, MethodInfo method, IReadOnlyList<Expression> arguments) =>
arguments == null || arguments.Count == 0
? new InstanceMethodCallExpression(instance, method)
: new InstanceManyArgumentsMethodCallExpression(instance, method, arguments);
public static MethodCallExpression Call(Expression instance, MethodInfo method, params Expression[] arguments) =>
Call(instance, method, (IReadOnlyList<Expression>)arguments);
public static MethodCallExpression Call(Expression instance, MethodInfo method, IEnumerable<Expression> arguments) =>
Call(instance, method, arguments.AsReadOnlyList());
[RequiresUnreferencedCode(Trimming.Message)]
public static MethodCallExpression Call(Type type, string methodName, Type[] typeArguments, IReadOnlyList<Expression> arguments) =>
Call(type.FindMethodOrThrow(methodName, typeArguments, arguments, TypeTools.StaticMethods), arguments);
[RequiresUnreferencedCode(Trimming.Message)]
public static MethodCallExpression Call(Type type, string methodName, Type[] typeArguments, params Expression[] arguments) =>
Call(type, methodName, typeArguments, (IReadOnlyList<Expression>)arguments);
[RequiresUnreferencedCode(Trimming.Message)]
public static MethodCallExpression Call(Type type, string methodName, Type[] typeArguments, IEnumerable<Expression> arguments) =>
Call(type, methodName, typeArguments, arguments.AsReadOnlyList());
[RequiresUnreferencedCode(Trimming.Message)]
public static MethodCallExpression Call(Expression instance, string methodName, Type[] typeArguments, IReadOnlyList<Expression> arguments) =>
Call(instance, instance.Type.FindMethodOrThrow(methodName, typeArguments, arguments, TypeTools.InstanceMethods), arguments);
[RequiresUnreferencedCode(Trimming.Message)]
public static MethodCallExpression Call(Expression instance, string methodName, Type[] typeArguments, params Expression[] arguments) =>
Call(instance, methodName, typeArguments, (IReadOnlyList<Expression>)arguments);
[RequiresUnreferencedCode(Trimming.Message)]
public static MethodCallExpression Call(Expression instance, string methodName, Type[] typeArguments, IEnumerable<Expression> arguments) =>
Call(instance, methodName, typeArguments, arguments.AsReadOnlyList());
public static MethodCallExpression Call(MethodInfo method) =>
new NotNullMethodCallExpression(method);
public static MethodCallExpression Call(Expression instance, MethodInfo method) =>
instance == null
? new NotNullMethodCallExpression(method)
: new InstanceMethodCallExpression(instance, method);
public static MethodCallExpression Call(MethodInfo method, Expression argument) =>
new OneArgumentMethodCallExpression(method, argument);
public static MethodCallExpression Call(Expression instance, MethodInfo method, Expression argument) =>
instance == null
? new OneArgumentMethodCallExpression(method, argument)
: new InstanceOneArgumentMethodCallExpression(instance, method, argument);
public static MethodCallExpression Call(MethodInfo method, Expression arg0, Expression arg1) =>
new TwoArgumentsMethodCallExpression(method, arg0, arg1);
public static MethodCallExpression Call(Expression instance, MethodInfo method, Expression arg0, Expression arg1) =>
instance == null
? new TwoArgumentsMethodCallExpression(method, arg0, arg1)
: new InstanceTwoArgumentsMethodCallExpression(instance, method, arg0, arg1);
public static MethodCallExpression Call(MethodInfo method, Expression arg0, Expression arg1, Expression arg2) =>
new ThreeArgumentsMethodCallExpression(method, arg0, arg1, arg2);
public static MethodCallExpression Call(Expression instance, MethodInfo method, Expression arg0, Expression arg1, Expression arg2) =>
instance == null
? new ThreeArgumentsMethodCallExpression(method, arg0, arg1, arg2)
: new InstanceThreeArgumentsMethodCallExpression(instance, method, arg0, arg1, arg2);
public static MethodCallExpression Call(MethodInfo method,
Expression arg0, Expression arg1, Expression arg2, Expression arg3) =>
new FourArgumentsMethodCallExpression(method, arg0, arg1, arg2, arg3);
public static MethodCallExpression Call(Expression instance, MethodInfo method,
Expression arg0, Expression arg1, Expression arg2, Expression arg3) =>
instance == null
? new FourArgumentsMethodCallExpression(method, arg0, arg1, arg2, arg3)
: new InstanceFourArgumentsMethodCallExpression(instance, method, arg0, arg1, arg2, arg3);
public static MethodCallExpression Call(MethodInfo method,
Expression arg0, Expression arg1, Expression arg2, Expression arg3, Expression arg4) =>
new FiveArgumentsMethodCallExpression(method, arg0, arg1, arg2, arg3, arg4);
public static MethodCallExpression Call(Expression instance, MethodInfo method,
Expression arg0, Expression arg1, Expression arg2, Expression arg3, Expression arg4) =>
instance == null
? new FiveArgumentsMethodCallExpression(method, arg0, arg1, arg2, arg3, arg4)
: new InstanceFiveArgumentsMethodCallExpression(instance, method, arg0, arg1, arg2, arg3, arg4);
public static MethodCallExpression Call(MethodInfo method,
Expression arg0, Expression arg1, Expression arg2, Expression arg3, Expression arg4, Expression arg5) =>
new SixArgumentsMethodCallExpression(method, arg0, arg1, arg2, arg3, arg4, arg5);
public static MethodCallExpression Call(Expression instance, MethodInfo method,
Expression arg0, Expression arg1, Expression arg2, Expression arg3, Expression arg4, Expression arg5) =>
instance == null
? new SixArgumentsMethodCallExpression(method, arg0, arg1, arg2, arg3, arg4, arg5)
: new InstanceSixArgumentsMethodCallExpression(instance, method, arg0, arg1, arg2, arg3, arg4, arg5);
public static MethodCallExpression Call(MethodInfo method,
Expression arg0, Expression arg1, Expression arg2, Expression arg3, Expression arg4, Expression arg5, Expression arg6) =>
new SevenArgumentsMethodCallExpression(method, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
public static MethodCallExpression Call(Expression instance, MethodInfo method,
Expression arg0, Expression arg1, Expression arg2, Expression arg3, Expression arg4, Expression arg5, Expression arg6) =>
instance == null
? new SevenArgumentsMethodCallExpression(method, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
: new InstanceSevenArgumentsMethodCallExpression(instance, method, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
public static Expression CallIfNotNull(Expression instance, MethodInfo method) =>
CallIfNotNull(instance, method, Tools.Empty<Expression>());
public static Expression CallIfNotNull(Expression instance, MethodInfo method, IEnumerable<Expression> arguments)
{
var instanceVar = Parameter(instance.Type, "x");
return Block(
new[] { instanceVar },
Assign(instanceVar, instance),
Condition(
Equal(instanceVar, Constant(null, instance.Type)),
NullConstant,
Call(instanceVar, method, arguments),
method.ReturnType));
}
public static MemberExpression Property(PropertyInfo property) =>
new PropertyExpression(property);
public static MemberExpression Property(Expression instance, PropertyInfo property) =>
instance == null
? new PropertyExpression(property)
: new InstancePropertyExpression(instance, property);
[RequiresUnreferencedCode(Trimming.Message)]
public static MemberExpression Property(Expression expression, string propertyName) =>
Property(expression, expression.Type.FindProperty(propertyName)
?? throw new ArgumentException($"Declared property with the name '{propertyName}' is not found in '{expression.Type}'", nameof(propertyName)));
public static IndexExpression Property(Expression instance, PropertyInfo indexer, Expression argument) =>
new HasIndexerOneArgumentIndexExpression(instance, indexer, argument);
public static IndexExpression Property(Expression instance, PropertyInfo indexer, params Expression[] arguments) =>
new HasIndexerManyArgumentsIndexExpression(instance, indexer, arguments);
public static IndexExpression Property(Expression instance, PropertyInfo indexer, IEnumerable<Expression> arguments) =>
new HasIndexerManyArgumentsIndexExpression(instance, indexer, arguments.AsReadOnlyList());
[RequiresUnreferencedCode(Trimming.Message)]
public static IndexExpression Property(Expression instance, string propertyName, params Expression[] arguments)
{
Debug.Assert(instance != null); // because otherwise there is no way to get type to find the indexer by name
foreach (var indexer in instance.Type.GetProperties())
if (indexer.Name == propertyName)
{
var indexerParams = indexer.GetIndexParameters();
if (indexerParams.Length == arguments.Length)
{
var mismatch = false;
for (var p = 0; !mismatch && p < indexerParams.Length; ++p)
mismatch = indexerParams[p].ParameterType != arguments[p].Type;
if (!mismatch)
return new HasIndexerManyArgumentsIndexExpression(instance, indexer, arguments);
}
}
throw new ArgumentException($"Indexer property '{propertyName}' is not found in '{instance.Type}' with the argument types '{arguments.Select(a => a.Type).ToCode()}]",
nameof(propertyName));
}
[RequiresUnreferencedCode(Trimming.Message)]
public static MemberExpression PropertyOrField(Expression expression, string memberName) =>
expression.Type.FindProperty(memberName) != null
? Property(expression, expression.Type.FindProperty(memberName)
?? throw new ArgumentException($"Declared property with the name '{memberName}' is not found in '{expression.Type}'", nameof(memberName)))
: Field(expression, expression.Type.FindField(memberName)
?? throw new ArgumentException($"Declared field with the name '{memberName}' is not found '{expression.Type}'", nameof(memberName)));
public static MemberExpression MakeMemberAccess(Expression expression, MemberInfo member)
{
if (member is FieldInfo field)
return Field(expression, field);
if (member is PropertyInfo property)
return Property(expression, property);
throw new ArgumentException($"Member is not field or property: {member}", nameof(member));
}
public static IndexExpression MakeIndex(Expression instance, PropertyInfo indexer, IEnumerable<Expression> arguments) =>
indexer != null
? Property(instance, indexer, arguments)
: ArrayAccess(instance, arguments);
public static IndexExpression ArrayAccess(Expression array, Expression index) =>
new OneArgumentIndexExpression(array, index);
public static IndexExpression ArrayAccess(Expression array, IReadOnlyList<Expression> indexes) =>
new ManyArgumentsIndexExpression(array, indexes);
public static IndexExpression ArrayAccess(Expression array, params Expression[] indexes) =>
ArrayAccess(array, (IReadOnlyList<Expression>)indexes);
public static IndexExpression ArrayAccess(Expression array, IEnumerable<Expression> indexes) =>
ArrayAccess(array, indexes.AsReadOnlyList());
public static MemberExpression Field(FieldInfo field) =>
new FieldExpression(field);
public static MemberExpression Field(Expression instance, FieldInfo field) =>
instance == null
? new FieldExpression(field)
: new InstanceFieldExpression(instance, field);
[RequiresUnreferencedCode(Trimming.Message)]
public static MemberExpression Field(Expression instance, string fieldName) =>
Field(instance, instance.Type.FindField(fieldName));
/// <summary>Creates a UnaryExpression that represents a bitwise complement operation.</summary>
public static UnaryExpression Not(Expression expression)
{
if (expression.Type == typeof(bool))
return new NotBooleanUnaryExpression(expression);
return new NodeTypedUnaryExpression(ExpressionType.Not, expression);
}
/// <summary>Creates a UnaryExpression that represents an explicit reference or boxing conversion where null is supplied if the conversion fails.</summary>
public static UnaryExpression TypeAs(Expression expression, Type type) =>
new TypedUnaryExpression(ExpressionType.TypeAs, expression, type);
public static TypeBinaryExpression TypeEqual(Expression operand, Type type) =>
new TypeBinaryExpression(ExpressionType.TypeEqual, operand, type);
public static TypeBinaryExpression TypeIs(Expression operand, Type type) =>
new TypeBinaryExpression(ExpressionType.TypeIs, operand, type);
/// <summary>Creates a UnaryExpression that represents an expression for obtaining the length of a one-dimensional array.</summary>
public static UnaryExpression ArrayLength(Expression array) =>
new TypedUnaryExpression<int>(ExpressionType.ArrayLength, array);
/// <summary>Creates a UnaryExpression that represents a type conversion operation.</summary>
public static UnaryExpression Convert(Expression expression, Type type) =>
new ConvertUnaryExpression(expression, type);
public static UnaryExpression Convert<T>(Expression expression) =>
new TypedConvertUnaryExpression<T>(expression);
public static UnaryExpression TryConvertDelegateIntrinsic(Expression expression, Type type) =>
type != expression.Type &&
typeof(Delegate).IsAssignableFrom(type) && typeof(Delegate).IsAssignableFrom(expression.Type)
? new ConvertDelegateIntrinsicExpression(expression, type)
: Convert(expression, type);
public static UnaryExpression TryConvertDelegateIntrinsic<D>(Expression expression) where D : Delegate =>
typeof(D) != expression.Type && typeof(Delegate).IsAssignableFrom(expression.Type)
? new ConvertDelegateIntrinsicExpression(expression, typeof(D))
: Convert(expression, typeof(D));
public static UnaryExpression TryConvertIntrinsic(Expression expression, Type type) =>
!type.IsValueType && (!expression.Type.IsValueType || type == typeof(object))
? new ConvertIntrinsicExpression(expression, type)
: Convert(expression, type);
public static UnaryExpression TryConvertIntrinsic<T>(Expression expression) where T : class =>
!typeof(T).IsValueType && (!expression.Type.IsValueType || typeof(T) == typeof(object))
? new ConvertIntrinsicExpression<T>(expression)
: Convert<T>(expression);
/// <summary>Creates a UnaryExpression that represents a conversion operation for which the implementing method is specified.</summary>
public static UnaryExpression Convert(Expression expression, Type type, MethodInfo method) =>
new ConvertWithMethodUnaryExpression(ExpressionType.Convert, expression, type, method);
/// <summary>Creates a UnaryExpression that represents a conversion operation that throws an exception if the target type is overflowed.</summary>
public static UnaryExpression ConvertChecked(Expression expression, Type type) =>
new TypedUnaryExpression(ExpressionType.ConvertChecked, expression, type);
/// <summary>Creates a UnaryExpression that represents a conversion operation that throws an exception if the target type is overflowed and for which the implementing method is specified.</summary>
public static UnaryExpression ConvertChecked(Expression expression, Type type, MethodInfo method) =>
new ConvertWithMethodUnaryExpression(ExpressionType.ConvertChecked, expression, type, method);
/// <summary>Creates a UnaryExpression that represents the decrementing of the expression by 1.</summary>
public static UnaryExpression Decrement(Expression expression) =>
new NodeTypedUnaryExpression(ExpressionType.Decrement, expression);
/// <summary>Creates a UnaryExpression that represents the incrementing of the expression value by 1.</summary>
public static UnaryExpression Increment(Expression expression) =>
new NodeTypedUnaryExpression(ExpressionType.Increment, expression);
/// <summary>Returns whether the expression evaluates to false.</summary>
public static UnaryExpression IsFalse(Expression expression) =>
new TypedUnaryExpression<bool>(ExpressionType.IsFalse, expression);
/// <summary>Returns whether the expression evaluates to true.</summary>
public static UnaryExpression IsTrue(Expression expression) =>
new TypedUnaryExpression<bool>(ExpressionType.IsTrue, expression);
/// <summary>Creates a UnaryExpression, given an operand and its type</summary>
public static UnaryExpression MakeUnary(ExpressionType unaryType, Expression operand, Type type = null) =>
MakeUnary(unaryType, operand, type, method: null);
internal static UnaryExpression ThrowNotSupportedUnary(string message) => throw new NotSupportedException("Negate with method is not supported");
/// <summary>Creates a UnaryExpression, given an operand, its type and a method</summary>
public static UnaryExpression MakeUnary(ExpressionType unaryType, Expression operand, Type type, MethodInfo method = null) =>
unaryType switch
{
ExpressionType.Negate => method == null ? Negate(operand) : ThrowNotSupportedUnary("Negate with method is not supported"),
ExpressionType.NegateChecked => method == null ? NegateChecked(operand) : ThrowNotSupportedUnary("NegateChecked with method is not supported"),
ExpressionType.Not => method == null ? Not(operand) : ThrowNotSupportedUnary("Not with method is not supported"),
ExpressionType.IsFalse => method == null ? IsFalse(operand) : ThrowNotSupportedUnary("IsFalse with method is not supported"),
ExpressionType.IsTrue => method == null ? IsTrue(operand) : ThrowNotSupportedUnary("IsTrue with method is not supported"),
ExpressionType.OnesComplement => method == null ? OnesComplement(operand) : ThrowNotSupportedUnary("OnesComplement with method is not supported"),
ExpressionType.ArrayLength => ArrayLength(operand),
ExpressionType.Convert => Convert(operand, type, method),
ExpressionType.ConvertChecked => ConvertChecked(operand, type, method),
ExpressionType.Throw => Throw(operand, type),
ExpressionType.TypeAs => TypeAs(operand, type),
ExpressionType.Quote => Quote(operand),
ExpressionType.UnaryPlus => method == null ? UnaryPlus(operand) : ThrowNotSupportedUnary("UnaryPlus with method is not supported"),
ExpressionType.Unbox => Unbox(operand, type),
ExpressionType.Increment => method == null ? Increment(operand) : ThrowNotSupportedUnary("Increment with method is not supported"),
ExpressionType.Decrement => method == null ? Decrement(operand) : ThrowNotSupportedUnary("Decrement with method is not supported"),
ExpressionType.PreIncrementAssign => method == null ? PreIncrementAssign(operand) : ThrowNotSupportedUnary("PreIncrementAssign with method is not supported"),
ExpressionType.PostIncrementAssign => method == null ? PostIncrementAssign(operand) : ThrowNotSupportedUnary("PostIncrementAssign with method is not supported"),
ExpressionType.PreDecrementAssign => method == null ? PreDecrementAssign(operand) : ThrowNotSupportedUnary("PreDecrementAssign with method is not supported"),
ExpressionType.PostDecrementAssign => method == null ? PostDecrementAssign(operand) : ThrowNotSupportedUnary("PostDecrementAssign with method is not supported"),
_ => ThrowNotSupportedUnary($"Making UnaryExpression of {unaryType} is not supported")
};
/// <summary>Creates a UnaryExpression that represents an arithmetic negation operation.</summary>
public static UnaryExpression Negate(Expression expression) =>
new NodeTypedUnaryExpression(ExpressionType.Negate, expression);
/// <summary>Creates a UnaryExpression that represents an arithmetic negation operation that has overflow checking.</summary>
public static UnaryExpression NegateChecked(Expression expression) =>
new NodeTypedUnaryExpression(ExpressionType.NegateChecked, expression);
/// <summary>Returns the expression representing the ones complement.</summary>
public static UnaryExpression OnesComplement(Expression expression) =>
new NodeTypedUnaryExpression(ExpressionType.OnesComplement, expression);
/// <summary>Creates a UnaryExpression that increments the expression by 1 and assigns the result back to the expression.</summary>
public static UnaryExpression PreIncrementAssign(Expression expression) =>
new NodeTypedUnaryExpression(ExpressionType.PreIncrementAssign, expression);
/// <summary>Creates a UnaryExpression that represents the assignment of the expression followed by a subsequent increment by 1 of the original expression.</summary>
public static UnaryExpression PostIncrementAssign(Expression expression) =>
new NodeTypedUnaryExpression(ExpressionType.PostIncrementAssign, expression);
/// <summary>Creates a UnaryExpression that decrements the expression by 1 and assigns the result back to the expression.</summary>
public static UnaryExpression PreDecrementAssign(Expression expression) =>
new NodeTypedUnaryExpression(ExpressionType.PreDecrementAssign, expression);
/// <summary>Creates a UnaryExpression that represents the assignment of the expression followed by a subsequent decrement by 1 of the original expression.</summary>
public static UnaryExpression PostDecrementAssign(Expression expression) =>
new NodeTypedUnaryExpression(ExpressionType.PostDecrementAssign, expression);
/// <summary>Creates a UnaryExpression that represents an expression that has a constant value of type Expression.</summary>
public static UnaryExpression Quote(Expression expression) =>
new NodeTypedUnaryExpression(ExpressionType.Quote, expression);
/// <summary>Creates a UnaryExpression that represents a unary plus operation.</summary>
public static UnaryExpression UnaryPlus(Expression expression) =>
new NodeTypedUnaryExpression(ExpressionType.UnaryPlus, expression);
/// <summary>Creates a UnaryExpression that represents an explicit unboxing.</summary>
public static UnaryExpression Unbox(Expression expression, Type type)
{
if (type.IsEnum)
return new TypedUnaryExpression(ExpressionType.Unbox, expression, type);
return Type.GetTypeCode(type) switch
{
TypeCode.Boolean => new TypedUnaryExpression<bool>(ExpressionType.Unbox, expression),
TypeCode.Byte => new TypedUnaryExpression<byte>(ExpressionType.Unbox, expression),
TypeCode.Char => new TypedUnaryExpression<char>(ExpressionType.Unbox, expression),
TypeCode.DateTime => new TypedUnaryExpression<DateTime>(ExpressionType.Unbox, expression),
TypeCode.Decimal => new TypedUnaryExpression<decimal>(ExpressionType.Unbox, expression),
TypeCode.Double => new TypedUnaryExpression<double>(ExpressionType.Unbox, expression),
TypeCode.Int16 => new TypedUnaryExpression<short>(ExpressionType.Unbox, expression),
TypeCode.Int32 => new TypedUnaryExpression<int>(ExpressionType.Unbox, expression),
TypeCode.Int64 => new TypedUnaryExpression<long>(ExpressionType.Unbox, expression),
TypeCode.SByte => new TypedUnaryExpression<sbyte>(ExpressionType.Unbox, expression),
TypeCode.Single => new TypedUnaryExpression<float>(ExpressionType.Unbox, expression),
TypeCode.String => new TypedUnaryExpression<string>(ExpressionType.Unbox, expression),
TypeCode.UInt16 => new TypedUnaryExpression<ushort>(ExpressionType.Unbox, expression),
TypeCode.UInt32 => new TypedUnaryExpression<uint>(ExpressionType.Unbox, expression),
TypeCode.UInt64 => new TypedUnaryExpression<ulong>(ExpressionType.Unbox, expression),
_ => new TypedUnaryExpression(ExpressionType.Unbox, expression, type)
};
}
[RequiresUnreferencedCode(Trimming.Message)]
public static LambdaExpression Lambda(Expression body) =>
new TypedLambdaExpression(Tools.GetFuncOrActionType(body.Type), body);
[RequiresUnreferencedCode(Trimming.Message)]
public static LambdaExpression Lambda(Type delegateType, Expression body)
{
if (delegateType == null || delegateType == typeof(Delegate))
return Lambda(body);
var returnType = GetDelegateReturnType(delegateType);
return returnType == body.Type
? new TypedLambdaExpression(delegateType, body)
: new TypedReturnLambdaExpression(delegateType, body, returnType);
}
public static LambdaExpression Lambda(Type delegateType, Expression body, Type returnType)
{
if (delegateType == null || delegateType == typeof(Delegate))
delegateType = Tools.GetFuncOrActionType(returnType);
return returnType == body.Type
? new TypedLambdaExpression(delegateType, body)
: new TypedReturnLambdaExpression(delegateType, body, returnType);
}
[RequiresUnreferencedCode(Trimming.Message)]
public static LambdaExpression Lambda(Expression body, IReadOnlyList<ParameterExpression> parameters) =>
parameters != null && parameters.Count > 0
? new ManyParametersLambdaExpression(Tools.GetFuncOrActionType(Tools.GetParamTypes(parameters), body.Type), body, parameters)
: new TypedLambdaExpression(Tools.GetFuncOrActionType(body.Type), body);
[RequiresUnreferencedCode(Trimming.Message)]
public static LambdaExpression Lambda(Expression body, params ParameterExpression[] parameters) =>
Lambda(body, (IReadOnlyList<ParameterExpression>)parameters);
[RequiresUnreferencedCode(Trimming.Message)]
public static LambdaExpression Lambda(Expression body, IEnumerable<ParameterExpression> parameters) =>
Lambda(body, parameters.AsReadOnlyList<ParameterExpression>());
[RequiresUnreferencedCode(Trimming.Message)]
public static LambdaExpression Lambda(Expression body, ParameterExpression parameter) =>
new OneParameterLambdaExpression(Tools.GetFuncOrActionType(parameter.Type, body.Type), body, parameter);
[RequiresUnreferencedCode(Trimming.Message)]
public static LambdaExpression Lambda(Expression body, ParameterExpression p0, ParameterExpression p1) =>
new TwoParametersLambdaExpression(Tools.GetFuncOrActionType(p0.Type, p1.Type, body.Type), body, p0, p1);
[RequiresUnreferencedCode(Trimming.Message)]
public static LambdaExpression Lambda(Expression body,
ParameterExpression p0, ParameterExpression p1, ParameterExpression p2) =>
new ThreeParametersLambdaExpression(Tools.GetFuncOrActionType(p0.Type, p1.Type, p2.Type, body.Type), body, p0, p1, p2);
public static LambdaExpression Lambda(Expression body,
ParameterExpression p0, ParameterExpression p1, ParameterExpression p2, ParameterExpression p3) =>
new FourParametersLambdaExpression(Tools.GetFuncOrActionType(p0.Type, p1.Type, p2.Type, p3.Type, body.Type), body, p0, p1, p2, p3);
public static LambdaExpression Lambda(Expression body,
ParameterExpression p0, ParameterExpression p1, ParameterExpression p2, ParameterExpression p3, ParameterExpression p4) =>
new FiveParametersLambdaExpression(Tools.GetFuncOrActionType(p0.Type, p1.Type, p2.Type, p3.Type, p4.Type, body.Type), body, p0, p1, p2, p3, p4);
public static LambdaExpression Lambda(Expression body,
ParameterExpression p0, ParameterExpression p1, ParameterExpression p2, ParameterExpression p3, ParameterExpression p4, ParameterExpression p5) =>
new SixParametersLambdaExpression(Tools.GetFuncOrActionType(p0.Type, p1.Type, p2.Type, p3.Type, p4.Type, p5.Type, body.Type), body, p0, p1, p2, p3, p4, p5);
[RequiresUnreferencedCode(Trimming.Message)]
public static LambdaExpression Lambda(Expression body, IReadOnlyList<ParameterExpression> parameters, Type returnType)
{
if (returnType == body.Type)
return Lambda(body, parameters);
var delegateType = Tools.GetFuncOrActionType(Tools.GetParamTypes(parameters), returnType);
return parameters?.Count > 0
? new TypedReturnManyParametersLambdaExpression(delegateType, body, parameters, returnType)
: new TypedReturnLambdaExpression(delegateType, body, returnType);
}
[RequiresUnreferencedCode(Trimming.Message)]
public static LambdaExpression Lambda(Expression body, IEnumerable<ParameterExpression> parameters, Type returnType) =>
Lambda(body, parameters.AsReadOnlyList(), returnType);
[RequiresUnreferencedCode(Trimming.Message)]
public static LambdaExpression Lambda(Type delegateType, Expression body, IReadOnlyList<ParameterExpression> parameters) =>
delegateType == null || delegateType == typeof(Delegate)
? Lambda(body, parameters)
: Lambda(delegateType, body, parameters, GetDelegateReturnType(delegateType));
[RequiresUnreferencedCode(Trimming.Message)]
public static LambdaExpression Lambda(Type delegateType, Expression body, params ParameterExpression[] parameters) =>
Lambda(delegateType, body, (IReadOnlyList<ParameterExpression>)parameters);
[RequiresUnreferencedCode(Trimming.Message)]
public static LambdaExpression Lambda(Type delegateType, Expression body, ParameterExpression p0) =>
Lambda(delegateType, body, p0, GetDelegateReturnType(delegateType));
[RequiresUnreferencedCode(Trimming.Message)]
public static LambdaExpression Lambda(Type delegateType, Expression body, ParameterExpression p0, ParameterExpression p1) =>
Lambda(delegateType, body, p0, p1, GetDelegateReturnType(delegateType));
[RequiresUnreferencedCode(Trimming.Message)]
public static LambdaExpression Lambda(Type delegateType, Expression body,
ParameterExpression p0, ParameterExpression p1, ParameterExpression p2) =>
Lambda(delegateType, body, p0, p1, p2, GetDelegateReturnType(delegateType));
[RequiresUnreferencedCode(Trimming.Message)]
public static LambdaExpression Lambda(Type delegateType, Expression body,
ParameterExpression p0, ParameterExpression p1, ParameterExpression p2, ParameterExpression p3) =>
Lambda(delegateType, body, p0, p1, p2, p3, GetDelegateReturnType(delegateType));
[RequiresUnreferencedCode(Trimming.Message)]
public static LambdaExpression Lambda(Type delegateType, Expression body,
ParameterExpression p0, ParameterExpression p1, ParameterExpression p2, ParameterExpression p3, ParameterExpression p4) =>
Lambda(delegateType, body, p0, p1, p2, p3, p4, GetDelegateReturnType(delegateType));
[RequiresUnreferencedCode(Trimming.Message)]
public static LambdaExpression Lambda(Type delegateType, Expression body,
ParameterExpression p0, ParameterExpression p1, ParameterExpression p2, ParameterExpression p3, ParameterExpression p4, ParameterExpression p5) =>
Lambda(delegateType, body, p0, p1, p2, p3, p4, p5, GetDelegateReturnType(delegateType));
[RequiresUnreferencedCode(Trimming.Message)]
public static LambdaExpression Lambda(Type delegateType, Expression body, IReadOnlyList<ParameterExpression> parameters, Type returnType)
{
if (delegateType == null || delegateType == typeof(Delegate))
return Lambda(body, parameters, returnType);
if (parameters?.Count > 0)
return returnType == body.Type
? new ManyParametersLambdaExpression(delegateType, body, parameters)
: new TypedReturnManyParametersLambdaExpression(delegateType, body, parameters, returnType);
return returnType == body.Type
? new TypedLambdaExpression(delegateType, body)
: new TypedReturnLambdaExpression(delegateType, body, returnType);
}
[RequiresUnreferencedCode(Trimming.Message)]
public static LambdaExpression Lambda(Type delegateType, Expression body, IEnumerable<ParameterExpression> parameters, Type returnType) =>
Lambda(delegateType, body, parameters.AsReadOnlyList(), returnType);
public static LambdaExpression Lambda(Type delegateType, Expression body, ParameterExpression p0, Type returnType) =>
returnType == body.Type
? new OneParameterLambdaExpression(delegateType, body, p0)
: new TypedReturnOneParameterLambdaExpression(delegateType, body, p0, returnType);
public static LambdaExpression Lambda(Type delegateType, Expression body, ParameterExpression p0, ParameterExpression p1, Type returnType) =>
returnType == body.Type
? new TwoParametersLambdaExpression(delegateType, body, p0, p1)
: new TypedReturnTwoParametersLambdaExpression(delegateType, body, p0, p1, returnType);
public static LambdaExpression Lambda(Type delegateType, Expression body,
ParameterExpression p0, ParameterExpression p1, ParameterExpression p2, Type returnType) =>
returnType == body.Type
? new ThreeParametersLambdaExpression(delegateType, body, p0, p1, p2)
: new TypedReturnThreeParametersLambdaExpression(delegateType, body, p0, p1, p2, returnType);
public static LambdaExpression Lambda(Type delegateType, Expression body,
ParameterExpression p0, ParameterExpression p1, ParameterExpression p2, ParameterExpression p3, Type returnType) =>
returnType == body.Type
? new FourParametersLambdaExpression(delegateType, body, p0, p1, p2, p3)
: new TypedReturnFourParametersLambdaExpression(delegateType, body, p0, p1, p2, p3, returnType);
public static LambdaExpression Lambda(Type delegateType, Expression body,
ParameterExpression p0, ParameterExpression p1, ParameterExpression p2, ParameterExpression p3, ParameterExpression p4, Type returnType) =>
returnType == body.Type
? new FiveParametersLambdaExpression(delegateType, body, p0, p1, p2, p3, p4)
: new TypedReturnFiveParametersLambdaExpression(delegateType, body, p0, p1, p2, p3, p4, returnType);
public static LambdaExpression Lambda(Type delegateType, Expression body,
ParameterExpression p0, ParameterExpression p1, ParameterExpression p2, ParameterExpression p3, ParameterExpression p4, ParameterExpression p5, Type returnType) =>
returnType == body.Type
? new SixParametersLambdaExpression(delegateType, body, p0, p1, p2, p3, p4, p5)
: new TypedReturnSixParametersLambdaExpression(delegateType, body, p0, p1, p2, p3, p4, p5, returnType);
[RequiresUnreferencedCode(Trimming.Message)]
public static Expression<TDelegate> Lambda<TDelegate>(Expression body) where TDelegate : System.Delegate =>
Lambda<TDelegate>(body, GetDelegateReturnType(typeof(TDelegate)));
public static Expression<TDelegate> Lambda<TDelegate>(Expression body, Type returnType) where TDelegate : System.Delegate =>
returnType == body.Type
? new Expression<TDelegate>(body)
: new TypedReturnExpression<TDelegate>(body, returnType);
public static Expression<TDelegate> Lambda<TDelegate>(Expression body, ParameterExpression p0, Type returnType)
where TDelegate : System.Delegate =>
returnType == body.Type
? new OneParameterExpression<TDelegate>(body, p0)
: new TypedReturnOneParameterExpression<TDelegate>(body, p0, returnType);
[RequiresUnreferencedCode(Trimming.Message)]
public static Expression<TDelegate> Lambda<TDelegate>(Expression body, ParameterExpression p0) where TDelegate : System.Delegate =>
Lambda<TDelegate>(body, p0, GetDelegateReturnType(typeof(TDelegate)));
public static Expression<TDelegate> Lambda<TDelegate>(Expression body, ParameterExpression p0, ParameterExpression p1, Type returnType)
where TDelegate : System.Delegate
{
if (returnType == body.Type)
return new TwoParametersExpression<TDelegate>(body, p0, p1);
return new TypedReturnTwoParametersExpression<TDelegate>(body, p0, p1, returnType);
}
[RequiresUnreferencedCode(Trimming.Message)]
public static Expression<TDelegate> Lambda<TDelegate>(Expression body, ParameterExpression p0, ParameterExpression p1)
where TDelegate : System.Delegate =>
Lambda<TDelegate>(body, p0, p1, GetDelegateReturnType(typeof(TDelegate)));
public static Expression<TDelegate> Lambda<TDelegate>(Expression body, ParameterExpression p0, ParameterExpression p1,
ParameterExpression p2, Type returnType)
where TDelegate : System.Delegate
{
if (returnType == body.Type)
return new ThreeParametersExpression<TDelegate>(body, p0, p1, p2);
return new TypedReturnThreeParametersExpression<TDelegate>(body, p0, p1, p2, returnType);
}
[RequiresUnreferencedCode(Trimming.Message)]
public static Expression<TDelegate> Lambda<TDelegate>(Expression body, ParameterExpression p0, ParameterExpression p1, ParameterExpression p2)
where TDelegate : System.Delegate =>
Lambda<TDelegate>(body, p0, p1, p2, GetDelegateReturnType(typeof(TDelegate)));
public static Expression<TDelegate> Lambda<TDelegate>(Expression body, ParameterExpression p0, ParameterExpression p1,
ParameterExpression p2, ParameterExpression p3, Type returnType)
where TDelegate : System.Delegate
{
if (returnType == body.Type)
return new FourParametersExpression<TDelegate>(body, p0, p1, p2, p3);
return new TypedReturnFourParametersExpression<TDelegate>(body, p0, p1, p2, p3, returnType);
}
[RequiresUnreferencedCode(Trimming.Message)]
public static Expression<TDelegate> Lambda<TDelegate>(Expression body, ParameterExpression p0, ParameterExpression p1, ParameterExpression p2,
ParameterExpression p3)
where TDelegate : System.Delegate =>
Lambda<TDelegate>(body, p0, p1, p2, p3, GetDelegateReturnType(typeof(TDelegate)));
public static Expression<TDelegate> Lambda<TDelegate>(Expression body, ParameterExpression p0, ParameterExpression p1,
ParameterExpression p2, ParameterExpression p3, ParameterExpression p4, Type returnType)
where TDelegate : System.Delegate
{
if (returnType == body.Type)
return new FiveParametersExpression<TDelegate>(body, p0, p1, p2, p3, p4);
return new TypedReturnFiveParametersExpression<TDelegate>(body, p0, p1, p2, p3, p4, returnType);
}
[RequiresUnreferencedCode(Trimming.Message)]
public static Expression<TDelegate> Lambda<TDelegate>(Expression body, ParameterExpression p0, ParameterExpression p1, ParameterExpression p2,
ParameterExpression p3, ParameterExpression p4)
where TDelegate : System.Delegate =>
Lambda<TDelegate>(body, p0, p1, p2, p3, p4, GetDelegateReturnType(typeof(TDelegate)));
public static Expression<TDelegate> Lambda<TDelegate>(Expression body, ParameterExpression p0, ParameterExpression p1,
ParameterExpression p2, ParameterExpression p3, ParameterExpression p4, ParameterExpression p5, Type returnType)
where TDelegate : System.Delegate
{
if (returnType == body.Type)
return new SixParametersExpression<TDelegate>(body, p0, p1, p2, p3, p4, p5);
return new TypedReturnSixParametersExpression<TDelegate>(body, p0, p1, p2, p3, p4, p5, returnType);
}
[RequiresUnreferencedCode(Trimming.Message)]
public static Expression<TDelegate> Lambda<TDelegate>(Expression body, ParameterExpression p0, ParameterExpression p1, ParameterExpression p2,
ParameterExpression p3, ParameterExpression p4, ParameterExpression p5)
where TDelegate : System.Delegate =>
Lambda<TDelegate>(body, p0, p1, p2, p3, p4, p5, GetDelegateReturnType(typeof(TDelegate)));
public static Expression<TDelegate> Lambda<TDelegate>(Expression body, IReadOnlyList<ParameterExpression> parameters, Type returnType)
where TDelegate : System.Delegate
{
if (parameters?.Count > 0)
{
if (returnType == body.Type)
return new ManyParametersExpression<TDelegate>(body, parameters);
return new TypedReturnManyParametersExpression<TDelegate>(body, parameters, returnType);
}
return Lambda<TDelegate>(body, returnType);