Files
2026-08-27 10:56:38 -06:00

1063 lines
41 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp;
internal class ExpressionLambdaRewriter
{
private enum InitializerKind
{
Expression,
MemberInitializer,
CollectionInitializer
}
private readonly SyntheticBoundNodeFactory _bound;
private readonly TypeMap _typeMap;
private readonly Dictionary<ParameterSymbol, BoundExpression> _parameterMap = new Dictionary<ParameterSymbol, BoundExpression>();
private readonly bool _ignoreAccessibility;
private int _recursionDepth;
private NamedTypeSymbol _ExpressionType;
private NamedTypeSymbol _ParameterExpressionType;
private NamedTypeSymbol _ElementInitType;
private NamedTypeSymbol _MemberBindingType;
private readonly NamedTypeSymbol _int32Type;
private readonly NamedTypeSymbol _objectType;
private readonly NamedTypeSymbol _nullableType;
private NamedTypeSymbol _MemberInfoType;
private readonly NamedTypeSymbol _IEnumerableType;
private NamedTypeSymbol ExpressionType
{
get
{
if ((object)_ExpressionType == null)
{
_ExpressionType = _bound.WellKnownType((WellKnownType)216);
}
return _ExpressionType;
}
}
private NamedTypeSymbol ParameterExpressionType
{
get
{
if ((object)_ParameterExpressionType == null)
{
_ParameterExpressionType = _bound.WellKnownType((WellKnownType)218);
}
return _ParameterExpressionType;
}
}
private NamedTypeSymbol ElementInitType
{
get
{
if ((object)_ElementInitType == null)
{
_ElementInitType = _bound.WellKnownType((WellKnownType)219);
}
return _ElementInitType;
}
}
public NamedTypeSymbol MemberBindingType
{
get
{
if ((object)_MemberBindingType == null)
{
_MemberBindingType = _bound.WellKnownType((WellKnownType)220);
}
return _MemberBindingType;
}
}
private NamedTypeSymbol MemberInfoType
{
get
{
if ((object)_MemberInfoType == null)
{
_MemberInfoType = _bound.WellKnownType((WellKnownType)68);
}
return _MemberInfoType;
}
}
private BindingDiagnosticBag Diagnostics => _bound.Diagnostics;
private ExpressionLambdaRewriter(TypeCompilationState compilationState, TypeMap typeMap, SyntaxNode node, int recursionDepth, BindingDiagnosticBag diagnostics)
{
_bound = new SyntheticBoundNodeFactory(null, compilationState.Type, node, compilationState, diagnostics);
_ignoreAccessibility = compilationState.ModuleBuilderOpt.IgnoreAccessibility;
_int32Type = _bound.SpecialType((SpecialType)13);
_objectType = _bound.SpecialType((SpecialType)1);
_nullableType = _bound.SpecialType((SpecialType)32);
_IEnumerableType = _bound.SpecialType((SpecialType)25);
_typeMap = typeMap;
_recursionDepth = recursionDepth;
}
internal static BoundNode RewriteLambda(BoundLambda node, TypeCompilationState compilationState, TypeMap typeMap, int recursionDepth, BindingDiagnosticBag diagnostics)
{
try
{
ExpressionLambdaRewriter expressionLambdaRewriter = new ExpressionLambdaRewriter(compilationState, typeMap, node.Syntax, recursionDepth, diagnostics);
BoundExpression boundExpression = expressionLambdaRewriter.VisitLambdaInternal(node);
if (!node.Type.Equals(boundExpression.Type, (TypeCompareKind)8))
{
diagnostics.Add(ErrorCode.ERR_MissingPredefinedMember, node.Syntax.Location, expressionLambdaRewriter.ExpressionType, "Lambda");
}
return boundExpression;
}
catch (SyntheticBoundNodeFactory.MissingPredefinedMember missingPredefinedMember)
{
((BindingDiagnosticBag)diagnostics).Add(missingPredefinedMember.Diagnostic);
return node;
}
}
private BoundExpression TranslateLambdaBody(BoundBlock block)
{
ImmutableArray<BoundStatement>.Enumerator enumerator = block.Statements.GetEnumerator();
while (enumerator.MoveNext())
{
BoundStatement boundStatement = enumerator.Current;
while (boundStatement != null)
{
switch (boundStatement.Kind)
{
case BoundKind.ReturnStatement:
{
BoundExpression boundExpression = Visit(((BoundReturnStatement)boundStatement).ExpressionOpt);
if (boundExpression != null)
{
return boundExpression;
}
boundStatement = null;
break;
}
case BoundKind.ExpressionStatement:
return Visit(((BoundExpressionStatement)boundStatement).Expression);
case BoundKind.SequencePoint:
boundStatement = ((BoundSequencePoint)boundStatement).StatementOpt;
break;
case BoundKind.SequencePointWithSpan:
boundStatement = ((BoundSequencePointWithSpan)boundStatement).StatementOpt;
break;
default:
throw ExceptionUtilities.UnexpectedValue((object)boundStatement.Kind);
}
}
}
return null;
}
private BoundExpression Visit(BoundExpression node)
{
if (node == null)
{
return null;
}
SyntaxNode syntax = _bound.Syntax;
_bound.Syntax = node.Syntax;
BoundExpression arg = VisitInternal(node);
_bound.Syntax = syntax;
return _bound.Convert(ExpressionType, arg);
}
private BoundExpression VisitExpressionWithoutStackGuard(BoundExpression node)
{
switch (node.Kind)
{
case BoundKind.ArrayAccess:
return VisitArrayAccess((BoundArrayAccess)node);
case BoundKind.ArrayCreation:
return VisitArrayCreation((BoundArrayCreation)node);
case BoundKind.ArrayLength:
return VisitArrayLength((BoundArrayLength)node);
case BoundKind.AsOperator:
return VisitAsOperator((BoundAsOperator)node);
case BoundKind.BaseReference:
return VisitBaseReference((BoundBaseReference)node);
case BoundKind.BinaryOperator:
{
BoundBinaryOperator boundBinaryOperator = (BoundBinaryOperator)node;
return VisitBinaryOperator(boundBinaryOperator.OperatorKind, boundBinaryOperator.Method, boundBinaryOperator.Type, boundBinaryOperator.Left, boundBinaryOperator.Right);
}
case BoundKind.UserDefinedConditionalLogicalOperator:
{
BoundUserDefinedConditionalLogicalOperator boundUserDefinedConditionalLogicalOperator = (BoundUserDefinedConditionalLogicalOperator)node;
return VisitBinaryOperator(boundUserDefinedConditionalLogicalOperator.OperatorKind, boundUserDefinedConditionalLogicalOperator.LogicalOperator, boundUserDefinedConditionalLogicalOperator.Type, boundUserDefinedConditionalLogicalOperator.Left, boundUserDefinedConditionalLogicalOperator.Right);
}
case BoundKind.Call:
return VisitCall((BoundCall)node);
case BoundKind.ConditionalOperator:
return VisitConditionalOperator((BoundConditionalOperator)node);
case BoundKind.Conversion:
return VisitConversion((BoundConversion)node);
case BoundKind.PassByCopy:
return Visit(((BoundPassByCopy)node).Expression);
case BoundKind.DelegateCreationExpression:
return VisitDelegateCreationExpression((BoundDelegateCreationExpression)node);
case BoundKind.FieldAccess:
{
BoundFieldAccess boundFieldAccess = (BoundFieldAccess)node;
if (boundFieldAccess.FieldSymbol.IsCapturedFrame)
{
return Constant(boundFieldAccess);
}
return VisitFieldAccess(boundFieldAccess);
}
case BoundKind.IsOperator:
return VisitIsOperator((BoundIsOperator)node);
case BoundKind.Lambda:
return VisitLambda((BoundLambda)node);
case BoundKind.NewT:
return VisitNewT((BoundNewT)node);
case BoundKind.NullCoalescingOperator:
return VisitNullCoalescingOperator((BoundNullCoalescingOperator)node);
case BoundKind.ObjectCreationExpression:
return VisitObjectCreationExpression((BoundObjectCreationExpression)node);
case BoundKind.Parameter:
return VisitParameter((BoundParameter)node);
case BoundKind.PointerIndirectionOperator:
return VisitPointerIndirectionOperator((BoundPointerIndirectionOperator)node);
case BoundKind.PointerElementAccess:
return VisitPointerElementAccess((BoundPointerElementAccess)node);
case BoundKind.PropertyAccess:
return VisitPropertyAccess((BoundPropertyAccess)node);
case BoundKind.SizeOfOperator:
return VisitSizeOfOperator((BoundSizeOfOperator)node);
case BoundKind.UnaryOperator:
return VisitUnaryOperator((BoundUnaryOperator)node);
case BoundKind.TypeOfOperator:
case BoundKind.MethodInfo:
case BoundKind.DefaultExpression:
case BoundKind.Literal:
case BoundKind.ThisReference:
case BoundKind.PreviousSubmissionReference:
case BoundKind.HostObjectMemberReference:
case BoundKind.Local:
return Constant(node);
default:
throw ExceptionUtilities.UnexpectedValue((object)node.Kind);
}
}
private BoundExpression VisitInternal(BoundExpression node)
{
_recursionDepth++;
BoundExpression result;
if (_recursionDepth > 1)
{
StackGuard.EnsureSufficientExecutionStack(_recursionDepth);
result = VisitExpressionWithoutStackGuard(node);
}
else
{
result = VisitExpressionWithStackGuard(node);
}
_recursionDepth--;
return result;
}
private BoundExpression VisitExpressionWithStackGuard(BoundExpression node)
{
try
{
return VisitExpressionWithoutStackGuard(node);
}
catch (InsufficientExecutionStackException inner)
{
throw new BoundTreeVisitor.CancelledByStackGuardException(inner, node);
}
}
private BoundExpression VisitArrayAccess(BoundArrayAccess node)
{
BoundExpression boundExpression = Visit(node.Expression);
if (node.Indices.Length == 1)
{
BoundExpression boundExpression2 = node.Indices[0];
BoundExpression boundExpression3 = Visit(boundExpression2);
if (!TypeSymbol.Equals(boundExpression3.Type, _int32Type, (TypeCompareKind)0))
{
boundExpression3 = ConvertIndex(boundExpression3, boundExpression2.Type, _int32Type);
}
return ExprFactory("ArrayIndex", boundExpression, boundExpression3);
}
return ExprFactory("ArrayIndex", boundExpression, Indices(node.Indices));
}
private BoundExpression Indices(ImmutableArray<BoundExpression> expressions)
{
ArrayBuilder<BoundExpression> instance = ArrayBuilder<BoundExpression>.GetInstance();
ImmutableArray<BoundExpression>.Enumerator enumerator = expressions.GetEnumerator();
while (enumerator.MoveNext())
{
BoundExpression current = enumerator.Current;
BoundExpression boundExpression = Visit(current);
if (!TypeSymbol.Equals(boundExpression.Type, _int32Type, (TypeCompareKind)0))
{
boundExpression = ConvertIndex(boundExpression, current.Type, _int32Type);
}
instance.Add(boundExpression);
}
return _bound.ArrayOrEmpty(ExpressionType, instance.ToImmutableAndFree());
}
private BoundExpression Expressions(ImmutableArray<BoundExpression> expressions)
{
ArrayBuilder<BoundExpression> instance = ArrayBuilder<BoundExpression>.GetInstance();
ImmutableArray<BoundExpression>.Enumerator enumerator = expressions.GetEnumerator();
while (enumerator.MoveNext())
{
BoundExpression current = enumerator.Current;
instance.Add(Visit(current));
}
return _bound.ArrayOrEmpty(ExpressionType, instance.ToImmutableAndFree());
}
private BoundExpression VisitArrayCreation(BoundArrayCreation node)
{
ArrayTypeSymbol arrayTypeSymbol = (ArrayTypeSymbol)node.Type;
BoundExpression boundExpression = _bound.Typeof(arrayTypeSymbol.ElementType);
if (node.InitializerOpt != null)
{
if (arrayTypeSymbol.IsSZArray)
{
return ExprFactory("NewArrayInit", boundExpression, Expressions(node.InitializerOpt.Initializers));
}
return new BoundBadExpression(node.Syntax, LookupResultKind.Empty, ImmutableArray<Symbol>.Empty, ImmutableArray.Create((BoundExpression)node), ExpressionType);
}
return ExprFactory("NewArrayBounds", boundExpression, Expressions(node.Bounds));
}
private BoundExpression VisitArrayLength(BoundArrayLength node)
{
return ExprFactory("ArrayLength", Visit(node.Expression));
}
private BoundExpression VisitAsOperator(BoundAsOperator node)
{
if (node.Operand.IsLiteralNull() && (object)node.Operand.Type == null)
{
BoundExpression operand = _bound.Null(_bound.SpecialType((SpecialType)1));
node = node.Update(operand, node.TargetType, node.OperandPlaceholder, node.OperandConversion, node.Type);
}
return ExprFactory("TypeAs", Visit(node.Operand), _bound.Typeof(node.Type));
}
private BoundExpression VisitBaseReference(BoundBaseReference node)
{
return new BoundBadExpression(node.Syntax, LookupResultKind.Empty, ImmutableArray<Symbol>.Empty, ImmutableArray.Create((BoundExpression)node), ExpressionType);
}
private static string GetBinaryOperatorName(BinaryOperatorKind opKind, MethodSymbol methodOpt, out bool isChecked, out bool isLifted, out bool requiresLifted)
{
isChecked = opKind.IsChecked();
isLifted = opKind.IsLifted();
requiresLifted = opKind.IsComparison();
switch (opKind.Operator())
{
case BinaryOperatorKind.Addition:
if (!useCheckedFactory(isChecked, methodOpt))
{
return "Add";
}
return "AddChecked";
case BinaryOperatorKind.Multiplication:
if (!useCheckedFactory(isChecked, methodOpt))
{
return "Multiply";
}
return "MultiplyChecked";
case BinaryOperatorKind.Subtraction:
if (!useCheckedFactory(isChecked, methodOpt))
{
return "Subtract";
}
return "SubtractChecked";
case BinaryOperatorKind.Division:
return "Divide";
case BinaryOperatorKind.Remainder:
return "Modulo";
case BinaryOperatorKind.And:
if (!opKind.IsLogical())
{
return "And";
}
return "AndAlso";
case BinaryOperatorKind.Xor:
return "ExclusiveOr";
case BinaryOperatorKind.Or:
if (!opKind.IsLogical())
{
return "Or";
}
return "OrElse";
case BinaryOperatorKind.LeftShift:
return "LeftShift";
case BinaryOperatorKind.RightShift:
return "RightShift";
case BinaryOperatorKind.Equal:
return "Equal";
case BinaryOperatorKind.NotEqual:
return "NotEqual";
case BinaryOperatorKind.LessThan:
return "LessThan";
case BinaryOperatorKind.LessThanOrEqual:
return "LessThanOrEqual";
case BinaryOperatorKind.GreaterThan:
return "GreaterThan";
case BinaryOperatorKind.GreaterThanOrEqual:
return "GreaterThanOrEqual";
default:
throw ExceptionUtilities.UnexpectedValue((object)opKind.Operator());
}
static bool useCheckedFactory(bool flag, MethodSymbol methodSymbol)
{
if (!flag)
{
if ((object)methodSymbol != null)
{
string name = methodSymbol.Name;
if (name != null)
{
return SyntaxFacts.IsCheckedOperator(name);
}
}
return false;
}
return true;
}
}
private BoundExpression VisitBinaryOperator(BinaryOperatorKind opKind, MethodSymbol methodOpt, TypeSymbol type, BoundExpression left, BoundExpression right)
{
bool isChecked;
bool isLifted;
bool requiresLifted;
string binaryOperatorName = GetBinaryOperatorName(opKind, methodOpt, out isChecked, out isLifted, out requiresLifted);
if ((object)left.Type == null && left.IsLiteralNull())
{
left = _bound.Default(right.Type);
}
if ((object)right.Type == null && right.IsLiteralNull())
{
right = _bound.Default(left.Type);
}
BinaryOperatorKind binaryOperatorKind = opKind.OperandTypes();
if ((uint)(binaryOperatorKind - 20) <= 2u)
{
BoundExpression boundExpression = ((opKind.OperandTypes() == BinaryOperatorKind.UnderlyingAndEnum) ? right : left);
TypeSymbol typeSymbol = PromotedType(boundExpression.Type.StrippedType().GetEnumUnderlyingType());
if (opKind.IsLifted())
{
typeSymbol = _nullableType.Construct(typeSymbol);
}
BoundExpression loweredLeft = VisitAndPromoteEnumOperand(left, typeSymbol, isChecked);
BoundExpression loweredRight = VisitAndPromoteEnumOperand(right, typeSymbol, isChecked);
BoundExpression node = MakeBinary(methodOpt, type, isLifted, requiresLifted, binaryOperatorName, loweredLeft, loweredRight);
return Demote(node, type, isChecked);
}
BoundExpression loweredLeft2 = Visit(left);
BoundExpression loweredRight2 = Visit(right);
return MakeBinary(methodOpt, type, isLifted, requiresLifted, binaryOperatorName, loweredLeft2, loweredRight2);
}
private static BoundExpression DemoteEnumOperand(BoundExpression operand)
{
if (operand.Kind == BoundKind.Conversion)
{
BoundConversion boundConversion = (BoundConversion)operand;
if (!boundConversion.ConversionKind.IsUserDefinedConversion() && boundConversion.ConversionKind.IsImplicitConversion() && boundConversion.ConversionKind != ConversionKind.NullLiteral && boundConversion.Type.StrippedType().IsEnumType())
{
operand = boundConversion.Operand;
}
}
return operand;
}
private BoundExpression VisitAndPromoteEnumOperand(BoundExpression operand, TypeSymbol promotedType, bool isChecked)
{
if (operand is BoundLiteral boundLiteral)
{
return Constant(boundLiteral.Update(boundLiteral.ConstantValueOpt, promotedType));
}
BoundExpression node = DemoteEnumOperand(operand);
BoundExpression operand2 = Visit(node);
return Convert(operand2, operand.Type, promotedType, isChecked, isExplicit: false);
}
private BoundExpression MakeBinary(MethodSymbol methodOpt, TypeSymbol type, bool isLifted, bool requiresLifted, string opName, BoundExpression loweredLeft, BoundExpression loweredRight)
{
if ((object)methodOpt != null)
{
if (!requiresLifted)
{
return ExprFactory(opName, loweredLeft, loweredRight, _bound.MethodInfo(methodOpt));
}
return ExprFactory(opName, loweredLeft, loweredRight, _bound.Literal(isLifted && !TypeSymbol.Equals(methodOpt.ReturnType, type, (TypeCompareKind)0)), _bound.MethodInfo(methodOpt));
}
return ExprFactory(opName, loweredLeft, loweredRight);
}
private TypeSymbol PromotedType(TypeSymbol underlying)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
if ((int)underlying.SpecialType == 7)
{
return underlying;
}
SpecialType enumPromotedType = Binder.GetEnumPromotedType(underlying.SpecialType);
if (enumPromotedType == underlying.SpecialType)
{
return underlying;
}
return _bound.SpecialType(enumPromotedType);
}
private BoundExpression Demote(BoundExpression node, TypeSymbol type, bool isChecked)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Invalid comparison between Unknown and I4
if (type is NamedTypeSymbol namedTypeSymbol)
{
if ((int)namedTypeSymbol.StrippedType().TypeKind == 5)
{
return Convert(node, type, isChecked);
}
if (!TypeSymbol.Equals(namedTypeSymbol.IsNullableType() ? _nullableType.Construct(PromotedType(namedTypeSymbol.GetNullableUnderlyingType())) : PromotedType(namedTypeSymbol), type, (TypeCompareKind)0))
{
return Convert(node, type, isChecked);
}
}
return node;
}
private BoundExpression ConvertIndex(BoundExpression expr, TypeSymbol oldType, TypeSymbol newType)
{
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
CompoundUseSiteInfo<AssemblySymbol> useSiteInfo = default(CompoundUseSiteInfo<AssemblySymbol>);
useSiteInfo._002Ector((BindingDiagnosticBag<AssemblySymbol>)(object)Diagnostics, _bound.Compilation.Assembly);
ConversionKind kind = _bound.Compilation.Conversions.ClassifyConversionFromType(oldType, newType, isChecked: false, ref useSiteInfo).Kind;
((BindingDiagnosticBag<AssemblySymbol>)(object)Diagnostics).AddDependencies(useSiteInfo);
return kind switch
{
ConversionKind.Identity => expr,
ConversionKind.ExplicitNumeric => Convert(expr, newType, isChecked: true),
_ => Convert(expr, _int32Type, isChecked: false),
};
}
private BoundExpression VisitCall(BoundCall node)
{
if (node.IsDelegateCall)
{
return ExprFactory("Invoke", Visit(node.ReceiverOpt), Expressions(node.Arguments));
}
MethodSymbol method = node.Method;
return ExprFactory("Call", method.RequiresInstanceReceiver ? Visit(node.ReceiverOpt) : _bound.Null(ExpressionType), _bound.MethodInfo(method), Expressions(node.Arguments));
}
private BoundExpression VisitConditionalOperator(BoundConditionalOperator node)
{
BoundExpression boundExpression = Visit(node.Condition);
BoundExpression boundExpression2 = VisitExactType(node.Consequence);
BoundExpression boundExpression3 = VisitExactType(node.Alternative);
return ExprFactory("Condition", boundExpression, boundExpression2, boundExpression3);
}
private BoundExpression VisitExactType(BoundExpression e)
{
if (e is BoundConversion { ExplicitCastInCode: false } boundConversion)
{
e = boundConversion.Update(boundConversion.Operand, boundConversion.Conversion, boundConversion.IsBaseConversion, boundConversion.Checked, explicitCastInCode: true, conversionGroupOpt: boundConversion.ConversionGroupOpt, constantValueOpt: boundConversion.ConstantValueOpt, type: boundConversion.Type);
}
return Visit(e);
}
private BoundExpression VisitConversion(BoundConversion node)
{
switch (node.ConversionKind)
{
case ConversionKind.MethodGroup:
{
BoundMethodGroup boundMethodGroup = (BoundMethodGroup)node.Operand;
return DelegateCreation(boundMethodGroup.ReceiverOpt, node.SymbolOpt, node.Type, !node.SymbolOpt.RequiresInstanceReceiver && !node.IsExtensionMethod);
}
case ConversionKind.ImplicitUserDefined:
case ConversionKind.ExplicitUserDefined:
case ConversionKind.IntPtr:
{
MethodSymbol symbolOpt = node.SymbolOpt;
TypeSymbol? type2 = node.Operand.Type;
TypeSymbol left = type2.StrippedType();
TypeSymbol type3 = symbolOpt.Parameters[0].Type;
bool num = !TypeSymbol.Equals(type2, type3, (TypeCompareKind)0) && TypeSymbol.Equals(left, type3, (TypeCompareKind)0);
bool flag = !TypeSymbol.Equals(left, (node.ConversionKind == ConversionKind.ExplicitUserDefined) ? type3 : type3.StrippedType(), (TypeCompareKind)0);
TypeSymbol typeSymbol = ((num && symbolOpt.ReturnType.IsNonNullableValueType() && node.Type.IsNullableType()) ? _nullableType.Construct(symbolOpt.ReturnType) : symbolOpt.ReturnType);
BoundExpression boundExpression = (flag ? Convert(Visit(node.Operand), node.Operand.Type, symbolOpt.Parameters[0].Type, node.Checked, isExplicit: false) : Visit(node.Operand));
BoundExpression operand2 = ExprFactory((node.Checked && SyntaxFacts.IsCheckedOperator(symbolOpt.Name)) ? "ConvertChecked" : "Convert", boundExpression, _bound.Typeof(typeSymbol), _bound.MethodInfo(symbolOpt));
return Convert(operand2, typeSymbol, node.Type, node.Checked, isExplicit: false);
}
case ConversionKind.Identity:
case ConversionKind.ImplicitReference:
{
BoundExpression boundExpression2 = Visit(node.Operand);
if (!node.ExplicitCastInCode)
{
return boundExpression2;
}
return Convert(boundExpression2, node.Type, isChecked: false);
}
case ConversionKind.ImplicitNullable:
{
if (node.Operand.Type.IsNullableType())
{
return Convert(Visit(node.Operand), node.Operand.Type, node.Type, node.Checked, node.ExplicitCastInCode);
}
TypeSymbol type = ((NamedTypeSymbol)node.Type).TypeArgumentsWithAnnotationsNoUseSiteDiagnostics[0].Type;
BoundExpression operand = Convert(Visit(node.Operand), node.Operand.Type, type, node.Checked, isExplicit: false);
return Convert(operand, type, node.Type, node.Checked, isExplicit: false);
}
case ConversionKind.NullLiteral:
return Convert(Constant(_bound.Null(_objectType)), _objectType, node.Type, isChecked: false, node.ExplicitCastInCode);
default:
return Convert(Visit(node.Operand), node.Operand.Type, node.Type, node.Checked, node.ExplicitCastInCode);
}
}
private BoundExpression Convert(BoundExpression operand, TypeSymbol oldType, TypeSymbol newType, bool isChecked, bool isExplicit)
{
if (!TypeSymbol.Equals(oldType, newType, (TypeCompareKind)0) || isExplicit)
{
return Convert(operand, newType, isChecked);
}
return operand;
}
private BoundExpression Convert(BoundExpression expr, TypeSymbol type, bool isChecked)
{
return ExprFactory(isChecked ? "ConvertChecked" : "Convert", expr, _bound.Typeof(type));
}
private BoundExpression DelegateCreation(BoundExpression receiver, MethodSymbol method, TypeSymbol delegateType, bool requiresInstanceReceiver)
{
BoundExpression boundExpression = _bound.Null(_objectType);
receiver = (requiresInstanceReceiver ? boundExpression : (receiver.Type.IsReferenceType ? receiver : _bound.Convert(_objectType, receiver)));
MethodSymbol methodSymbol = _bound.WellKnownMethod((WellKnownMember)49, isOptional: true);
BoundExpression node = (((object)methodSymbol == null) ? _bound.StaticCall(_bound.SpecialType((SpecialType)4), "CreateDelegate", _bound.Typeof(delegateType), receiver, _bound.MethodInfo(method)) : _bound.Call(_bound.MethodInfo(method), methodSymbol, _bound.Typeof(delegateType), receiver));
return Convert(Visit(node), delegateType, isChecked: false);
}
private BoundExpression VisitDelegateCreationExpression(BoundDelegateCreationExpression node)
{
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Invalid comparison between Unknown and I4
if (node.Argument.Kind == BoundKind.MethodGroup)
{
throw ExceptionUtilities.UnexpectedValue((object)BoundKind.MethodGroup);
}
if ((object)node.MethodOpt != null)
{
bool requiresInstanceReceiver = !node.MethodOpt.RequiresInstanceReceiver && !node.IsExtensionMethod;
return DelegateCreation(node.Argument, node.MethodOpt, node.Type, requiresInstanceReceiver);
}
if (node.Argument.Type is NamedTypeSymbol namedTypeSymbol && (int)namedTypeSymbol.TypeKind == 3)
{
return DelegateCreation(node.Argument, namedTypeSymbol.DelegateInvokeMethod, node.Type, requiresInstanceReceiver: false);
}
throw ExceptionUtilities.UnexpectedValue((object)node.Argument);
}
private BoundExpression VisitFieldAccess(BoundFieldAccess node)
{
BoundExpression boundExpression = (node.FieldSymbol.IsStatic ? _bound.Null(ExpressionType) : Visit(node.ReceiverOpt));
return ExprFactory("Field", boundExpression, _bound.FieldInfo(node.FieldSymbol));
}
private BoundExpression VisitIsOperator(BoundIsOperator node)
{
BoundExpression boundExpression = node.Operand;
if ((object)boundExpression.Type == null && boundExpression.ConstantValueOpt != (ConstantValue)null && boundExpression.ConstantValueOpt.IsNull)
{
boundExpression = _bound.Null(_objectType);
}
return ExprFactory("TypeIs", Visit(boundExpression), _bound.Typeof(node.TargetType.Type));
}
private BoundExpression VisitLambda(BoundLambda node)
{
BoundExpression boundExpression = VisitLambdaInternal(node);
if (!node.Type.IsExpressionTree())
{
return boundExpression;
}
return ExprFactory("Quote", boundExpression);
}
private BoundExpression VisitLambdaInternal(BoundLambda node)
{
ArrayBuilder<LocalSymbol> instance = ArrayBuilder<LocalSymbol>.GetInstance();
ArrayBuilder<BoundExpression> instance2 = ArrayBuilder<BoundExpression>.GetInstance();
ArrayBuilder<BoundExpression> instance3 = ArrayBuilder<BoundExpression>.GetInstance();
ImmutableArray<ParameterSymbol>.Enumerator enumerator = node.Symbol.Parameters.GetEnumerator();
while (enumerator.MoveNext())
{
ParameterSymbol current = enumerator.Current;
LocalSymbol localSymbol = _bound.SynthesizedLocal(ParameterExpressionType, null, isPinned: false, isKnownToReferToTempIfReferenceType: false, (RefKind)0, (SynthesizedLocalKind)(-2));
instance.Add(localSymbol);
BoundLocal boundLocal = _bound.Local(localSymbol);
instance3.Add((BoundExpression)boundLocal);
BoundExpression right = ExprFactory("Parameter", _bound.Typeof(_typeMap.SubstituteType(current.Type).Type), _bound.Literal(current.Name));
instance2.Add(_bound.AssignmentExpression(boundLocal, right));
_parameterMap[current] = boundLocal;
}
NamedTypeSymbol delegateType = node.Type.GetDelegateType();
BoundExpression result = _bound.Sequence(instance.ToImmutableAndFree(), instance2.ToImmutableAndFree(), ExprFactory("Lambda", ImmutableArray.Create((TypeSymbol)delegateType), TranslateLambdaBody(node.Body), _bound.ArrayOrEmpty(ParameterExpressionType, instance3.ToImmutableAndFree())));
enumerator = node.Symbol.Parameters.GetEnumerator();
while (enumerator.MoveNext())
{
ParameterSymbol current2 = enumerator.Current;
_parameterMap.Remove(current2);
}
return result;
}
private BoundExpression VisitNewT(BoundNewT node)
{
return VisitObjectCreationContinued(ExprFactory("New", _bound.Typeof(node.Type)), node.InitializerExpressionOpt);
}
private BoundExpression VisitNullCoalescingOperator(BoundNullCoalescingOperator node)
{
BoundExpression boundExpression = Visit(node.LeftOperand);
BoundExpression boundExpression2 = Visit(node.RightOperand);
Conversion conversion = BoundNode.GetConversion(node.LeftConversion, node.LeftPlaceholder);
if (conversion.IsUserDefined)
{
TypeSymbol type = node.LeftPlaceholder.Type;
return ExprFactory("Coalesce", boundExpression, boundExpression2, MakeConversionLambda(conversion, type, node.LeftConversion.Type));
}
return ExprFactory("Coalesce", boundExpression, boundExpression2);
}
private BoundExpression MakeConversionLambda(Conversion conversion, TypeSymbol fromType, TypeSymbol toType)
{
string text = "p";
ParameterSymbol parameterSymbol = _bound.SynthesizedParameter(fromType, text);
LocalSymbol localSymbol = _bound.SynthesizedLocal(ParameterExpressionType, null, isPinned: false, isKnownToReferToTempIfReferenceType: false, (RefKind)0, (SynthesizedLocalKind)(-2));
BoundLocal boundLocal = _bound.Local(localSymbol);
BoundExpression right = ExprFactory("Parameter", _bound.Typeof(fromType), _bound.Literal(text));
_parameterMap[parameterSymbol] = boundLocal;
BoundExpression boundExpression = Visit(_bound.Convert(toType, _bound.Parameter(parameterSymbol), conversion));
_parameterMap.Remove(parameterSymbol);
return _bound.Sequence(ImmutableArray.Create(localSymbol), ImmutableArray.Create(_bound.AssignmentExpression(boundLocal, right)), ExprFactory("Lambda", boundExpression, _bound.ArrayOrEmpty(ParameterExpressionType, ImmutableArray.Create((BoundExpression)boundLocal))));
}
private BoundExpression InitializerMemberSetter(Symbol symbol)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Invalid comparison between Unknown and I4
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Invalid comparison between Unknown and I4
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Invalid comparison between Unknown and I4
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
SymbolKind kind = symbol.Kind;
if ((int)kind != 5)
{
if ((int)kind != 6)
{
if ((int)kind == 15)
{
return _bound.MethodInfo(((PropertySymbol)symbol).GetOwnOrInheritedSetMethod());
}
throw ExceptionUtilities.UnexpectedValue((object)symbol.Kind);
}
return _bound.Convert(MemberInfoType, _bound.FieldInfo((FieldSymbol)symbol));
}
return _bound.Convert(MemberInfoType, _bound.FieldInfo(((EventSymbol)symbol).AssociatedField));
}
private BoundExpression InitializerMemberGetter(Symbol symbol)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Invalid comparison between Unknown and I4
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Invalid comparison between Unknown and I4
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Invalid comparison between Unknown and I4
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
SymbolKind kind = symbol.Kind;
if ((int)kind != 5)
{
if ((int)kind != 6)
{
if ((int)kind == 15)
{
return _bound.MethodInfo(((PropertySymbol)symbol).GetOwnOrInheritedGetMethod());
}
throw ExceptionUtilities.UnexpectedValue((object)symbol.Kind);
}
return _bound.Convert(MemberInfoType, _bound.FieldInfo((FieldSymbol)symbol));
}
return _bound.Convert(MemberInfoType, _bound.FieldInfo(((EventSymbol)symbol).AssociatedField));
}
private BoundExpression VisitInitializer(BoundExpression node, out InitializerKind kind)
{
switch (node.Kind)
{
case BoundKind.ObjectInitializerExpression:
{
BoundObjectInitializerExpression obj2 = (BoundObjectInitializerExpression)node;
ArrayBuilder<BoundExpression> instance2 = ArrayBuilder<BoundExpression>.GetInstance();
ImmutableArray<BoundExpression>.Enumerator enumerator = obj2.Initializers.GetEnumerator();
while (enumerator.MoveNext())
{
BoundAssignmentOperator boundAssignmentOperator = (BoundAssignmentOperator)enumerator.Current;
Symbol memberSymbol = ((BoundObjectInitializerMember)boundAssignmentOperator.Left).MemberSymbol;
InitializerKind kind2;
BoundExpression boundExpression2 = VisitInitializer(boundAssignmentOperator.Right, out kind2);
switch (kind2)
{
case InitializerKind.CollectionInitializer:
{
BoundExpression boundExpression5 = InitializerMemberGetter(memberSymbol);
instance2.Add(ExprFactory("ListBind", boundExpression5, boundExpression2));
break;
}
case InitializerKind.Expression:
{
BoundExpression boundExpression4 = InitializerMemberSetter(memberSymbol);
instance2.Add(ExprFactory("Bind", boundExpression4, boundExpression2));
break;
}
case InitializerKind.MemberInitializer:
{
BoundExpression boundExpression3 = InitializerMemberGetter(memberSymbol);
instance2.Add(ExprFactory("MemberBind", boundExpression3, boundExpression2));
break;
}
default:
throw ExceptionUtilities.UnexpectedValue((object)kind2);
}
}
kind = InitializerKind.MemberInitializer;
return _bound.ArrayOrEmpty(MemberBindingType, instance2.ToImmutableAndFree());
}
case BoundKind.CollectionInitializerExpression:
{
BoundCollectionInitializerExpression obj = (BoundCollectionInitializerExpression)node;
kind = InitializerKind.CollectionInitializer;
ArrayBuilder<BoundExpression> instance = ArrayBuilder<BoundExpression>.GetInstance();
ImmutableArray<BoundExpression>.Enumerator enumerator = obj.Initializers.GetEnumerator();
while (enumerator.MoveNext())
{
BoundCollectionElementInitializer boundCollectionElementInitializer = (BoundCollectionElementInitializer)enumerator.Current;
BoundExpression boundExpression = ExprFactory("ElementInit", _bound.MethodInfo(boundCollectionElementInitializer.AddMethod), Expressions(boundCollectionElementInitializer.Arguments));
instance.Add(boundExpression);
}
return _bound.ArrayOrEmpty(ElementInitType, instance.ToImmutableAndFree());
}
default:
kind = InitializerKind.Expression;
return Visit(node);
}
}
private BoundExpression VisitObjectCreationExpression(BoundObjectCreationExpression node)
{
return VisitObjectCreationContinued(VisitObjectCreationExpressionInternal(node), node.InitializerExpressionOpt);
}
private BoundExpression VisitObjectCreationContinued(BoundExpression creation, BoundExpression initializerExpressionOpt)
{
if (initializerExpressionOpt == null)
{
return creation;
}
InitializerKind kind;
BoundExpression boundExpression = VisitInitializer(initializerExpressionOpt, out kind);
return kind switch
{
InitializerKind.CollectionInitializer => ExprFactory("ListInit", creation, boundExpression),
InitializerKind.MemberInitializer => ExprFactory("MemberInit", creation, boundExpression),
_ => throw ExceptionUtilities.UnexpectedValue((object)kind),
};
}
private BoundExpression VisitObjectCreationExpressionInternal(BoundObjectCreationExpression node)
{
if (node.ConstantValueOpt != (ConstantValue)null)
{
return Constant(node);
}
if ((object)node.Constructor == null || (node.Arguments.Length == 0 && !node.Type.IsStructType()) || node.Constructor.IsDefaultValueTypeConstructor())
{
return ExprFactory("New", _bound.Typeof(node.Type));
}
BoundExpression boundExpression = _bound.ConstructorInfo(node.Constructor);
BoundExpression boundExpression2 = _bound.Convert(_IEnumerableType.Construct(ExpressionType), Expressions(node.Arguments));
if (node.Type.IsAnonymousType && node.Arguments.Length != 0)
{
NamedTypeSymbol type = (NamedTypeSymbol)node.Type;
ArrayBuilder<BoundExpression> instance = ArrayBuilder<BoundExpression>.GetInstance();
for (int i = 0; i < node.Arguments.Length; i++)
{
instance.Add(_bound.MethodInfo(AnonymousTypeManager.GetAnonymousTypeProperty(type, i).GetMethod));
}
return ExprFactory("New", boundExpression, boundExpression2, _bound.ArrayOrEmpty(MemberInfoType, instance.ToImmutableAndFree()));
}
return ExprFactory("New", boundExpression, boundExpression2);
}
private BoundExpression VisitParameter(BoundParameter node)
{
return _parameterMap[node.ParameterSymbol];
}
private static BoundExpression VisitPointerIndirectionOperator(BoundPointerIndirectionOperator node)
{
return new BoundBadExpression(node.Syntax, LookupResultKind.Empty, ImmutableArray<Symbol>.Empty, ImmutableArray.Create((BoundExpression)node), node.Type);
}
private static BoundExpression VisitPointerElementAccess(BoundPointerElementAccess node)
{
return new BoundBadExpression(node.Syntax, LookupResultKind.Empty, ImmutableArray<Symbol>.Empty, ImmutableArray.Create((BoundExpression)node), node.Type);
}
private BoundExpression VisitPropertyAccess(BoundPropertyAccess node)
{
BoundExpression boundExpression = (node.PropertySymbol.IsStatic ? _bound.Null(ExpressionType) : Visit(node.ReceiverOpt));
MethodSymbol ownOrInheritedGetMethod = node.PropertySymbol.GetOwnOrInheritedGetMethod();
BoundExpression? receiverOpt = node.ReceiverOpt;
if (receiverOpt != null && receiverOpt.Type.IsTypeParameter() && !node.ReceiverOpt.Type.IsReferenceType)
{
boundExpression = Convert(boundExpression, ownOrInheritedGetMethod.ReceiverType, isChecked: false);
}
return ExprFactory("Property", boundExpression, _bound.MethodInfo(ownOrInheritedGetMethod));
}
private static BoundExpression VisitSizeOfOperator(BoundSizeOfOperator node)
{
return new BoundBadExpression(node.Syntax, LookupResultKind.Empty, ImmutableArray<Symbol>.Empty, ImmutableArray.Create((BoundExpression)node), node.Type);
}
private BoundExpression VisitUnaryOperator(BoundUnaryOperator node)
{
BoundExpression operand = node.Operand;
BoundExpression boundExpression = Visit(operand);
UnaryOperatorKind operatorKind = node.OperatorKind;
UnaryOperatorKind unaryOperatorKind = operatorKind & UnaryOperatorKind.OpMask;
bool flag = (operatorKind & UnaryOperatorKind.Checked) != 0;
string name;
object obj;
switch (unaryOperatorKind)
{
case UnaryOperatorKind.UnaryPlus:
if ((object)node.MethodOpt == null)
{
return boundExpression;
}
name = "UnaryPlus";
break;
case UnaryOperatorKind.UnaryMinus:
{
if (flag)
{
goto IL_0096;
}
MethodSymbol methodOpt = node.MethodOpt;
if ((object)methodOpt != null)
{
string name2 = methodOpt.Name;
if (name2 != null && SyntaxFacts.IsCheckedOperator(name2))
{
goto IL_0096;
}
}
obj = "Negate";
goto IL_009b;
}
case UnaryOperatorKind.LogicalNegation:
case UnaryOperatorKind.BitwiseComplement:
name = "Not";
break;
default:
{
throw ExceptionUtilities.UnexpectedValue((object)unaryOperatorKind);
}
IL_0096:
obj = "NegateChecked";
goto IL_009b;
IL_009b:
name = (string)obj;
break;
}
if (node.OperatorKind.OperandTypes() == UnaryOperatorKind.Enum && (operatorKind & UnaryOperatorKind.Lifted) != UnaryOperatorKind.Error)
{
TypeSymbol typeSymbol = PromotedType(operand.Type.StrippedType().GetEnumUnderlyingType());
typeSymbol = _nullableType.Construct(typeSymbol);
boundExpression = Convert(boundExpression, operand.Type, typeSymbol, flag, isExplicit: false);
BoundExpression node2 = ExprFactory(name, boundExpression);
return Demote(node2, node.Type, flag);
}
if ((object)node.MethodOpt != null)
{
return ExprFactory(name, boundExpression, _bound.MethodInfo(node.MethodOpt));
}
return ExprFactory(name, boundExpression);
}
private BoundExpression ExprFactory(string name, params BoundExpression[] arguments)
{
return _bound.StaticCall(ExpressionType, name, arguments);
}
private BoundExpression ExprFactory(string name, ImmutableArray<TypeSymbol> typeArgs, params BoundExpression[] arguments)
{
return _bound.StaticCall(_ignoreAccessibility ? BinderFlags.IgnoreAccessibility : BinderFlags.None, ExpressionType, name, typeArgs, arguments);
}
private BoundExpression Constant(BoundExpression node)
{
return ExprFactory("Constant", _bound.Convert(_objectType, node), _bound.Typeof(node.Type));
}
}