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

382 lines
11 KiB
C#

using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp;
internal static class BoundExpressionExtensions
{
public static RefKind GetRefKind(this BoundExpression node)
{
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_0140: Unknown result type (might be due to invalid IL or missing references)
//IL_0145: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Invalid comparison between Unknown and I4
//IL_0180: Unknown result type (might be due to invalid IL or missing references)
//IL_014b: Unknown result type (might be due to invalid IL or missing references)
//IL_0150: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
//IL_00f6: Invalid comparison between Unknown and I4
//IL_0155: Unknown result type (might be due to invalid IL or missing references)
//IL_016b: Unknown result type (might be due to invalid IL or missing references)
switch (node.Kind)
{
case BoundKind.Local:
return ((BoundLocal)node).LocalSymbol.RefKind;
case BoundKind.Parameter:
return ((BoundParameter)node).ParameterSymbol.RefKind;
case BoundKind.FieldAccess:
return ((BoundFieldAccess)node).FieldSymbol.RefKind;
case BoundKind.Call:
return ((BoundCall)node).Method.RefKind;
case BoundKind.PropertyAccess:
return ((BoundPropertyAccess)node).PropertySymbol.RefKind;
case BoundKind.IndexerAccess:
return ((BoundIndexerAccess)node).Indexer.RefKind;
case BoundKind.ImplicitIndexerAccess:
return ((BoundImplicitIndexerAccess)node).IndexerOrSliceAccess.GetRefKind();
case BoundKind.InlineArrayAccess:
{
BoundInlineArrayAccess boundInlineArrayAccess = (BoundInlineArrayAccess)node;
if (!boundInlineArrayAccess.IsValue)
{
WellKnownMember getItemOrSliceHelper = boundInlineArrayAccess.GetItemOrSliceHelper;
if ((int)getItemOrSliceHelper == 400)
{
return (RefKind)1;
}
if ((int)getItemOrSliceHelper == 406)
{
return (RefKind)3;
}
}
return (RefKind)0;
}
case BoundKind.ObjectInitializerMember:
{
BoundObjectInitializerMember boundObjectInitializerMember = (BoundObjectInitializerMember)node;
if (boundObjectInitializerMember.HasErrors)
{
return (RefKind)0;
}
Symbol memberSymbol = boundObjectInitializerMember.MemberSymbol;
if (!(memberSymbol is FieldSymbol { RefKind: var refKind }))
{
if (!(memberSymbol is PropertySymbol { RefKind: var refKind2 }))
{
if (memberSymbol is EventSymbol)
{
return (RefKind)0;
}
throw ExceptionUtilities.UnexpectedValue((object)memberSymbol?.Kind);
}
return refKind2;
}
return refKind;
}
default:
return (RefKind)0;
}
}
public static bool IsLiteralNull(this BoundExpression node)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Invalid comparison between Unknown and I4
if (node != null && node.Kind == BoundKind.Literal)
{
ConstantValue constantValueOpt = node.ConstantValueOpt;
if (constantValueOpt != null)
{
return (int)constantValueOpt.Discriminator == 0;
}
}
return false;
}
public static bool IsLiteralDefault(this BoundExpression node)
{
return node.Kind == BoundKind.DefaultLiteral;
}
public static bool IsImplicitObjectCreation(this BoundExpression node)
{
return node.Kind == BoundKind.UnconvertedObjectCreationExpression;
}
public static bool IsLiteralDefaultOrImplicitObjectCreation(this BoundExpression node)
{
if (!node.IsLiteralDefault())
{
return node.IsImplicitObjectCreation();
}
return true;
}
public static bool IsDefaultValue(this BoundExpression node)
{
if (node.Kind == BoundKind.DefaultExpression || node.Kind == BoundKind.DefaultLiteral)
{
return true;
}
ConstantValue constantValueOpt = node.ConstantValueOpt;
if (constantValueOpt != (ConstantValue)null)
{
return constantValueOpt.IsDefaultValue;
}
return false;
}
public static bool HasExpressionType(this BoundExpression node)
{
return (object)node.Type != null;
}
public static bool HasDynamicType(this BoundExpression node)
{
return node.Type?.IsDynamic() ?? false;
}
public static NamedTypeSymbol? GetInferredDelegateType(this BoundExpression expr, ref CompoundUseSiteInfo<AssemblySymbol> useSiteInfo)
{
NamedTypeSymbol? obj = expr.GetFunctionType()?.GetInternalDelegateType();
if ((object)obj != null)
{
obj.AddUseSiteInfo(ref useSiteInfo);
return obj;
}
return obj;
}
public static TypeSymbol? GetTypeOrFunctionType(this BoundExpression expr)
{
TypeSymbol type = expr.Type;
if ((object)type != null)
{
return type;
}
return expr.GetFunctionType();
}
public static FunctionTypeSymbol? GetFunctionType(this BoundExpression expr)
{
if (!(expr is BoundMethodGroup boundMethodGroup))
{
if (expr is UnboundLambda unboundLambda)
{
return unboundLambda.FunctionType;
}
return null;
}
return boundMethodGroup.FunctionType;
}
public static bool MethodGroupReceiverIsDynamic(this BoundMethodGroup node)
{
if (node.InstanceOpt != null)
{
return node.InstanceOpt.HasDynamicType();
}
return false;
}
public static void GetExpressionSymbols(this BoundExpression node, ArrayBuilder<Symbol> symbols, BoundNode parent, Binder binder)
{
switch (node.Kind)
{
case BoundKind.MethodGroup:
if (parent is BoundDelegateCreationExpression { MethodOpt: not null } boundDelegateCreationExpression)
{
symbols.Add((Symbol)boundDelegateCreationExpression.MethodOpt);
}
else
{
symbols.AddRange<MethodSymbol>(CSharpSemanticModel.GetReducedAndFilteredMethodGroupSymbols(binder, (BoundMethodGroup)node));
}
return;
case BoundKind.BadExpression:
{
ImmutableArray<Symbol>.Enumerator enumerator = ((BoundBadExpression)node).Symbols.GetEnumerator();
while (enumerator.MoveNext())
{
Symbol current = enumerator.Current;
if ((object)current != null)
{
symbols.Add(current);
}
}
return;
}
case BoundKind.DelegateCreationExpression:
{
Symbol symbol = ((BoundDelegateCreationExpression)node).Type.GetMembers(".ctor").FirstOrDefault();
if ((object)symbol != null)
{
symbols.Add(symbol);
}
return;
}
case BoundKind.Call:
{
ImmutableArray<MethodSymbol> originalMethodsOpt = ((BoundCall)node).OriginalMethodsOpt;
if (!originalMethodsOpt.IsDefault)
{
symbols.AddRange<MethodSymbol>(originalMethodsOpt);
return;
}
break;
}
case BoundKind.IndexerAccess:
{
ImmutableArray<PropertySymbol> originalIndexersOpt = ((BoundIndexerAccess)node).OriginalIndexersOpt;
if (!originalIndexersOpt.IsDefault)
{
symbols.AddRange<PropertySymbol>(originalIndexersOpt);
return;
}
break;
}
}
Symbol expressionSymbol = node.ExpressionSymbol;
if ((object)expressionSymbol != null)
{
symbols.Add(expressionSymbol);
}
}
public static Conversion GetConversion(this BoundExpression boundNode)
{
if (boundNode.Kind == BoundKind.Conversion)
{
return ((BoundConversion)boundNode).Conversion;
}
return Conversion.Identity;
}
internal static bool IsExpressionOfComImportType([NotNullWhen(true)] this BoundExpression? expressionOpt)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Invalid comparison between Unknown and I4
if (expressionOpt == null)
{
return false;
}
if (expressionOpt.Type is NamedTypeSymbol namedTypeSymbol && (int)namedTypeSymbol.Kind == 11)
{
return namedTypeSymbol.IsComImport;
}
return false;
}
internal static bool IsDiscardExpression(this BoundExpression expr)
{
if (!(expr is BoundDiscardExpression))
{
if (expr is OutDeconstructVarPendingInference outDeconstructVarPendingInference)
{
if (outDeconstructVarPendingInference.IsDiscardExpression)
{
return true;
}
}
else if (expr is BoundDeconstructValuePlaceholder { IsDiscardExpression: not false })
{
return true;
}
return false;
}
return true;
}
public static bool NullableAlwaysHasValue(this BoundExpression expr)
{
if ((object)expr.Type == null)
{
return false;
}
if (expr.Type.IsDynamic())
{
return false;
}
if (!expr.Type.IsNullableType())
{
return true;
}
if (expr.Kind == BoundKind.ObjectCreationExpression)
{
return ((BoundObjectCreationExpression)expr).Constructor.ParameterCount != 0;
}
if (expr.Kind == BoundKind.Conversion)
{
BoundConversion boundConversion = (BoundConversion)expr;
switch (boundConversion.ConversionKind)
{
case ConversionKind.ImplicitNullable:
case ConversionKind.ExplicitNullable:
return boundConversion.Operand.NullableAlwaysHasValue();
case ConversionKind.ImplicitEnumeration:
return boundConversion.Operand.NullableAlwaysHasValue();
}
}
return false;
}
public static bool NullableNeverHasValue(this BoundExpression expr)
{
if ((object)expr.Type == null && expr.ConstantValueOpt == ConstantValue.Null)
{
return true;
}
if ((object)expr.Type == null || !expr.Type.IsNullableType())
{
return false;
}
if (expr is BoundDefaultLiteral || expr is BoundDefaultExpression)
{
return true;
}
if (expr.Kind == BoundKind.ObjectCreationExpression)
{
return ((BoundObjectCreationExpression)expr).Constructor.ParameterCount == 0;
}
if (expr.Kind == BoundKind.Conversion)
{
BoundConversion boundConversion = (BoundConversion)expr;
switch (boundConversion.ConversionKind)
{
case ConversionKind.NullLiteral:
return true;
case ConversionKind.DefaultLiteral:
return true;
case ConversionKind.ImplicitNullable:
case ConversionKind.ExplicitNullable:
return boundConversion.Operand.NullableNeverHasValue();
}
}
return false;
}
public static bool IsNullableNonBoolean(this BoundExpression expr)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Invalid comparison between Unknown and I4
if (expr.Type.IsNullableType() && (int)expr.Type.GetNullableUnderlyingType().SpecialType != 7)
{
return true;
}
return false;
}
}