File: BoundTree\BoundDagTest.cs
Web Access
Project: src\src\Compilers\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.csproj (Microsoft.CodeAnalysis.CSharp)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using Roslyn.Utilities;
 
namespace Microsoft.CodeAnalysis.CSharp
{
#if DEBUG
    [DebuggerDisplay("{GetDebuggerDisplay(),nq}")]
#endif
    partial class BoundDagTest
    {
        public override bool Equals([NotNullWhen(true)] object? obj) => this.Equals(obj as BoundDagTest);
 
        private bool Equals(BoundDagTest? other)
        {
            if (other is null || this.Kind != other.Kind)
                return false;
            if (this == other)
                return true;
            if (!this.Input.Equals(other.Input))
                return false;
 
            switch (this, other)
            {
                case (BoundDagTypeTest x, BoundDagTypeTest y):
                    return x.Type.Equals(y.Type, TypeCompareKind.AllIgnoreOptions);
                case (BoundDagNonNullTest x, BoundDagNonNullTest y):
                    return x.IsExplicitTest == y.IsExplicitTest;
                case (BoundDagExplicitNullTest x, BoundDagExplicitNullTest y):
                    return true;
                case (BoundDagValueTest x, BoundDagValueTest y):
                    return x.Value.Equals(y.Value);
                case (BoundDagRelationalTest x, BoundDagRelationalTest y):
                    return x.Relation == y.Relation && x.Value.Equals(y.Value);
                default:
                    throw ExceptionUtilities.UnexpectedValue(this);
            }
        }
 
        public override int GetHashCode()
        {
            return Hash.Combine(((int)Kind).GetHashCode(), Input.GetHashCode());
        }
 
#if DEBUG
        internal new string GetDebuggerDisplay()
        {
            switch (this)
            {
                case BoundDagTypeEvaluation a:
                    return $"{a.GetOutputTempDebuggerDisplay()} = ({a.Type}){a.Input.GetDebuggerDisplay()}";
                case BoundDagPropertyEvaluation e:
                    return $"{e.GetOutputTempDebuggerDisplay()} = {e.Input.GetDebuggerDisplay()}.{e.Property.Name}";
                case BoundDagFieldEvaluation e:
                    return $"{e.GetOutputTempDebuggerDisplay()} = {e.Input.GetDebuggerDisplay()}.{e.Field.Name}";
                case BoundDagDeconstructEvaluation d:
                    var result = "(";
                    var first = true;
                    foreach (var param in d.DeconstructMethod.Parameters)
                    {
                        if (!first)
                        {
                            result += ", ";
                        }
                        first = false;
                        result += $"Item{param.Ordinal + 1}";
                    }
                    result += $") {d.GetOutputTempDebuggerDisplay()} = {d.Input.GetDebuggerDisplay()}";
                    return result;
                case BoundDagIndexEvaluation i:
                    return $"{i.GetOutputTempDebuggerDisplay()} = {i.Input.GetDebuggerDisplay()}[{i.Index}]";
                case BoundDagIndexerEvaluation i:
                    return $"{i.GetOutputTempDebuggerDisplay()} = {i.Input.GetDebuggerDisplay()}[{i.Index}]";
                case BoundDagAssignmentEvaluation i:
                    return $"{i.Target.GetDebuggerDisplay()} <-- {i.Input.GetDebuggerDisplay()}";
                case BoundDagEvaluation e:
                    return $"{e.GetOutputTempDebuggerDisplay()} = {e.Kind}({e.Input.GetDebuggerDisplay()})";
                case BoundDagTypeTest b:
                    var typeName = b.Type.TypeKind == TypeKind.Error ? "<error type>" : b.Type.ToString();
                    return $"{b.Input.GetDebuggerDisplay()} is {typeName}";
                case BoundDagValueTest v:
                    return $"{v.Input.GetDebuggerDisplay()} == {v.Value.GetValueToDisplay()}";
                case BoundDagNonNullTest nn:
                    return $"{nn.Input.GetDebuggerDisplay()} != null";
                case BoundDagExplicitNullTest n:
                    return $"{n.Input.GetDebuggerDisplay()} == null";
                case BoundDagRelationalTest r:
                    var operatorName = r.Relation.Operator() switch
                    {
                        BinaryOperatorKind.LessThan => "<",
                        BinaryOperatorKind.LessThanOrEqual => "<=",
                        BinaryOperatorKind.GreaterThan => ">",
                        BinaryOperatorKind.GreaterThanOrEqual => ">=",
                        _ => "??"
                    };
                    return $"{r.Input.GetDebuggerDisplay()} {operatorName} {r.Value.GetValueToDisplay()}";
                default:
                    return $"{this.Kind}({this.Input.GetDebuggerDisplay()})";
            }
        }
#endif
    }
}