| File: Compilation\TypeInfo.cs | Web Access |
| Project: src\roslyn\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())))); } } }