File: Compilation\TypeInfo.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.
 
#nullable disable
 
using Microsoft.CodeAnalysis.CSharp.Symbols;
using System;
using Roslyn.Utilities;
 
namespace Microsoft.CodeAnalysis.CSharp
{
    internal readonly struct CSharpTypeInfo : IEquatable<CSharpTypeInfo>
    {
        internal static readonly CSharpTypeInfo None = new CSharpTypeInfo(type: null, convertedType: null, nullability: default, convertedNullability: default, Conversion.Identity);
 
        // should be best guess if there is one, or error type if none.
        /// <summary>
        /// The type of the expression represented by the syntax node. For expressions that do not
        /// have a type, null is returned. If the type could not be determined due to an error, than
        /// an object derived from ErrorTypeSymbol is returned.
        /// </summary>
        public readonly TypeSymbol Type;
 
        public readonly NullabilityInfo Nullability;
 
        /// <summary>
        /// The type of the expression after it has undergone an implicit conversion. If the type
        /// did not undergo an implicit conversion, returns the same as Type.
        /// </summary>
        public readonly TypeSymbol ConvertedType;
 
        public readonly NullabilityInfo ConvertedNullability;
 
        /// <summary>
        /// If the expression underwent an implicit conversion, return information about that
        /// conversion. Otherwise, returns an identity conversion.
        /// </summary>
        public readonly Conversion ImplicitConversion;
 
        internal CSharpTypeInfo(TypeSymbol type, TypeSymbol convertedType, NullabilityInfo nullability, NullabilityInfo convertedNullability, Conversion implicitConversion)
        {
            // When constructing the result for the Caas API, we expose the underlying symbols that
            // may have been hidden under error type, if the error type was immediate. We will
            // expose error types that were constructed, or type parameters of constructed types.
            this.Type = type.GetNonErrorGuess() ?? type;
            this.ConvertedType = convertedType.GetNonErrorGuess() ?? convertedType;
            this.Nullability = nullability;
            this.ConvertedNullability = convertedNullability;
            this.ImplicitConversion = implicitConversion;
        }
 
        public static implicit operator TypeInfo(CSharpTypeInfo info)
        {
            return new TypeInfo(info.Type?.GetITypeSymbol(info.Nullability.FlowState.ToAnnotation()), info.ConvertedType?.GetITypeSymbol(info.ConvertedNullability.FlowState.ToAnnotation()),
                                info.Nullability, info.ConvertedNullability);
        }
 
        public override bool Equals(object obj)
        {
            return obj is CSharpTypeInfo && Equals((CSharpTypeInfo)obj);
        }
 
        public bool Equals(CSharpTypeInfo other)
        {
            return this.ImplicitConversion.Equals(other.ImplicitConversion)
                && TypeSymbol.Equals(this.Type, other.Type, TypeCompareKind.ConsiderEverything2)
                && TypeSymbol.Equals(this.ConvertedType, other.ConvertedType, TypeCompareKind.ConsiderEverything2)
                && this.Nullability.Equals(other.Nullability)
                && this.ConvertedNullability.Equals(other.ConvertedNullability);
        }
 
        public override int GetHashCode()
        {
            return Hash.Combine(this.ConvertedType,
                                Hash.Combine(this.Type,
                                             Hash.Combine(this.Nullability.GetHashCode(),
                                                          Hash.Combine(this.ConvertedNullability.GetHashCode(),
                                                                       this.ImplicitConversion.GetHashCode()))));
        }
    }
}