295 lines
7.9 KiB
C#
295 lines
7.9 KiB
C#
using System;
|
|
using System.Collections.Immutable;
|
|
using System.Diagnostics;
|
|
using Microsoft.CodeAnalysis.CSharp.Symbols;
|
|
using Microsoft.CodeAnalysis.Operations;
|
|
using Roslyn.Utilities;
|
|
|
|
namespace Microsoft.CodeAnalysis.CSharp;
|
|
|
|
[DebuggerDisplay("{GetDebuggerDisplay(), nq}")]
|
|
internal abstract class BoundNode : IBoundNodeWithIOperationChildren
|
|
{
|
|
[Flags]
|
|
private enum BoundNodeAttributes : short
|
|
{
|
|
HasErrors = 1,
|
|
CompilerGenerated = 2,
|
|
IsSuppressed = 4,
|
|
TopLevelFlowStateMaybeNull = 8,
|
|
TopLevelNotAnnotated = 0x10,
|
|
TopLevelAnnotated = 0x20,
|
|
TopLevelNone = 0x30,
|
|
TopLevelAnnotationMask = 0x30,
|
|
WasCompilerGeneratedIsChecked = 0x40,
|
|
WasTopLevelNullabilityChecked = 0x80,
|
|
WasConverted = 0x100,
|
|
AttributesPreservedInClone = 0x107
|
|
}
|
|
|
|
private readonly BoundKind _kind;
|
|
|
|
private BoundNodeAttributes _attributes;
|
|
|
|
public readonly SyntaxNode Syntax;
|
|
|
|
public bool HasAnyErrors
|
|
{
|
|
get
|
|
{
|
|
if (HasErrors || (Syntax != null && Syntax.HasErrors))
|
|
{
|
|
return true;
|
|
}
|
|
BoundExpression obj = this as BoundExpression;
|
|
if (obj == null)
|
|
{
|
|
return false;
|
|
}
|
|
return obj.Type?.IsErrorType() == true;
|
|
}
|
|
}
|
|
|
|
public bool HasErrors
|
|
{
|
|
get
|
|
{
|
|
return (_attributes & BoundNodeAttributes.HasErrors) != 0;
|
|
}
|
|
private set
|
|
{
|
|
if (value)
|
|
{
|
|
_attributes |= BoundNodeAttributes.HasErrors;
|
|
}
|
|
}
|
|
}
|
|
|
|
public SyntaxTree? SyntaxTree
|
|
{
|
|
get
|
|
{
|
|
SyntaxNode syntax = Syntax;
|
|
if (syntax == null)
|
|
{
|
|
return null;
|
|
}
|
|
return syntax.SyntaxTree;
|
|
}
|
|
}
|
|
|
|
public bool WasCompilerGenerated
|
|
{
|
|
get
|
|
{
|
|
return (_attributes & BoundNodeAttributes.CompilerGenerated) != 0;
|
|
}
|
|
internal set
|
|
{
|
|
if (value)
|
|
{
|
|
_attributes |= BoundNodeAttributes.CompilerGenerated;
|
|
}
|
|
}
|
|
}
|
|
|
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
|
protected NullabilityInfo TopLevelNullability
|
|
{
|
|
get
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
return TopLevelNullabilityCore;
|
|
}
|
|
set
|
|
{
|
|
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0030: Expected I4, but got Unknown
|
|
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0060: Invalid comparison between Unknown and I4
|
|
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0064: Invalid comparison between Unknown and I4
|
|
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
|
|
_attributes &= ~(BoundNodeAttributes.TopLevelNone | BoundNodeAttributes.TopLevelFlowStateMaybeNull);
|
|
BoundNodeAttributes attributes = _attributes;
|
|
NullableAnnotation annotation = ((NullabilityInfo)(ref value)).Annotation;
|
|
_attributes = (BoundNodeAttributes)((int)attributes | ((int)annotation switch
|
|
{
|
|
2 => 32,
|
|
1 => 16,
|
|
0 => 48,
|
|
_ => throw ExceptionUtilities.UnexpectedValue((object)annotation),
|
|
}));
|
|
NullableFlowState flowState = ((NullabilityInfo)(ref value)).FlowState;
|
|
if ((int)flowState != 1)
|
|
{
|
|
if ((int)flowState != 2)
|
|
{
|
|
throw ExceptionUtilities.UnexpectedValue((object)((NullabilityInfo)(ref value)).FlowState);
|
|
}
|
|
_attributes |= BoundNodeAttributes.TopLevelFlowStateMaybeNull;
|
|
}
|
|
}
|
|
}
|
|
|
|
private NullabilityInfo TopLevelNullabilityCore
|
|
{
|
|
get
|
|
{
|
|
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
|
|
if ((_attributes & BoundNodeAttributes.TopLevelNone) == 0)
|
|
{
|
|
return default(NullabilityInfo);
|
|
}
|
|
BoundNodeAttributes boundNodeAttributes = _attributes & BoundNodeAttributes.TopLevelNone;
|
|
_003F val = boundNodeAttributes switch
|
|
{
|
|
BoundNodeAttributes.TopLevelAnnotated => 2,
|
|
BoundNodeAttributes.TopLevelNotAnnotated => 1,
|
|
BoundNodeAttributes.TopLevelNone => 0,
|
|
_ => throw ExceptionUtilities.UnexpectedValue((object)boundNodeAttributes),
|
|
};
|
|
NullableFlowState val2 = (NullableFlowState)(((_attributes & BoundNodeAttributes.TopLevelFlowStateMaybeNull) == 0) ? 1 : 2);
|
|
return new NullabilityInfo((NullableAnnotation)val, val2);
|
|
}
|
|
}
|
|
|
|
public bool IsSuppressed
|
|
{
|
|
get
|
|
{
|
|
return (_attributes & BoundNodeAttributes.IsSuppressed) != 0;
|
|
}
|
|
protected set
|
|
{
|
|
if (value)
|
|
{
|
|
_attributes |= BoundNodeAttributes.IsSuppressed;
|
|
}
|
|
}
|
|
}
|
|
|
|
public BoundKind Kind => _kind;
|
|
|
|
ImmutableArray<BoundNode?> IBoundNodeWithIOperationChildren.Children => Children;
|
|
|
|
protected virtual ImmutableArray<BoundNode?> Children => ImmutableArray<BoundNode>.Empty;
|
|
|
|
protected new BoundNode MemberwiseClone()
|
|
{
|
|
BoundNode obj = (BoundNode)base.MemberwiseClone();
|
|
obj._attributes &= BoundNodeAttributes.AttributesPreservedInClone;
|
|
return obj;
|
|
}
|
|
|
|
protected BoundNode(BoundKind kind, SyntaxNode syntax)
|
|
{
|
|
_kind = kind;
|
|
Syntax = syntax;
|
|
}
|
|
|
|
protected BoundNode(BoundKind kind, SyntaxNode syntax, bool hasErrors)
|
|
: this(kind, syntax)
|
|
{
|
|
if (hasErrors)
|
|
{
|
|
_attributes = BoundNodeAttributes.HasErrors;
|
|
}
|
|
}
|
|
|
|
protected void CopyAttributes(BoundNode original)
|
|
{
|
|
WasCompilerGenerated = original.WasCompilerGenerated;
|
|
IsSuppressed = original.IsSuppressed;
|
|
}
|
|
|
|
public void ResetCompilerGenerated(bool newCompilerGenerated)
|
|
{
|
|
if (newCompilerGenerated)
|
|
{
|
|
_attributes |= BoundNodeAttributes.CompilerGenerated;
|
|
}
|
|
else
|
|
{
|
|
_attributes &= ~BoundNodeAttributes.CompilerGenerated;
|
|
}
|
|
}
|
|
|
|
public virtual BoundNode? Accept(BoundTreeVisitor visitor)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
internal BoundNode WithHasErrors()
|
|
{
|
|
if (HasErrors)
|
|
{
|
|
return this;
|
|
}
|
|
BoundNode boundNode = MemberwiseClone();
|
|
boundNode.HasErrors = true;
|
|
return boundNode;
|
|
}
|
|
|
|
internal string GetDebuggerDisplay()
|
|
{
|
|
string text = GetType().Name;
|
|
if (Syntax != null)
|
|
{
|
|
text = text + " " + ((object)Syntax).ToString();
|
|
}
|
|
return text;
|
|
}
|
|
|
|
[Conditional("DEBUG")]
|
|
public void CheckLocalsDefined()
|
|
{
|
|
}
|
|
|
|
public static Conversion GetConversion(BoundExpression? conversion, BoundValuePlaceholder? placeholder)
|
|
{
|
|
if (conversion != null)
|
|
{
|
|
BoundConversion boundConversion = conversion as BoundConversion;
|
|
if (boundConversion == null)
|
|
{
|
|
if (conversion is BoundValuePlaceholder boundValuePlaceholder && boundValuePlaceholder == placeholder)
|
|
{
|
|
return Conversion.Identity;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (boundConversion.Operand == placeholder)
|
|
{
|
|
return boundConversion.Conversion;
|
|
}
|
|
if (!boundConversion.Conversion.IsUserDefined)
|
|
{
|
|
boundConversion = (BoundConversion)boundConversion.Operand;
|
|
}
|
|
BoundConversion boundConversion2;
|
|
if (boundConversion.Conversion.IsUserDefined && (boundConversion.Operand == placeholder || (boundConversion2 = (BoundConversion)boundConversion.Operand).Operand == placeholder || ((BoundConversion)boundConversion2.Operand).Operand == placeholder))
|
|
{
|
|
return boundConversion.Conversion;
|
|
}
|
|
}
|
|
throw ExceptionUtilities.UnexpectedValue((object)conversion);
|
|
}
|
|
return Conversion.NoConversion;
|
|
}
|
|
}
|