public virtual CSharpTypeKind ToCSharpKind(LanguageTypeKind kind) { switch (kind.Switch()) { case LanguageTypeKind.None: return(CSharpTypeKind.Unknown); case LanguageTypeKind.Module: return(CSharpTypeKind.Module); case LanguageTypeKind.NamedType: return(CSharpTypeKind.Class); case LanguageTypeKind.Enum: return(CSharpTypeKind.Enum); case LanguageTypeKind.Error: return(CSharpTypeKind.Error); case LanguageTypeKind.Dynamic: return(CSharpTypeKind.Dynamic); case LanguageTypeKind.Constructed: return(CSharpTypeKind.Unknown); default: throw new ArgumentException("Unexpected type kind: " + kind.ToString(), nameof(kind)); } }
// Get the type kind of a symbol, going to candidates if possible. internal static LanguageTypeKind ExtractNonErrorTypeKind(TypeSymbol oldSymbol) { if (oldSymbol.TypeKind != LanguageTypeKind.Error) { return(oldSymbol.TypeKind); } // At this point, we know that oldSymbol is a non-null type symbol with kind error. // Hence, it is either an ErrorTypeSymbol or it has an ErrorTypeSymbol as its // original definition. In the former case, it is its own original definition. // Thus, if there's a CSErrorTypeSymbol in there somewhere, it's returned by // OriginalDefinition. ExtendedErrorTypeSymbol oldError = oldSymbol.OriginalDefinition as ExtendedErrorTypeSymbol; // If the original definition isn't a CSErrorTypeSymbol, then we don't know how to // pull out a non-error type. If it is, then if there is a unambiguous type inside it, // use that. LanguageTypeKind commonTypeKind = LanguageTypeKind.Error; if ((object)oldError != null && !oldError._candidateSymbols.IsDefault && oldError._candidateSymbols.Length > 0) { foreach (Symbol sym in oldError._candidateSymbols) { TypeSymbol type = sym as TypeSymbol; if ((object)type != null && type.TypeKind != LanguageTypeKind.Error) { if (commonTypeKind == LanguageTypeKind.Error) { commonTypeKind = type.TypeKind; } else if (commonTypeKind != type.TypeKind) { return(LanguageTypeKind.Error); // no common kind. } } } } return(commonTypeKind); }