private string GetEnumDisplayString( Type lmrType, DkmClrValue value, ObjectDisplayOptions options, bool includeTypeName, DkmInspectionContext inspectionContext ) { Debug.Assert(lmrType.IsEnum); Debug.Assert(value != null); object underlyingValue = value.HostObjectValue; // check if HostObjectValue is null, since any of these types might actually be a synthetic value as well. if (underlyingValue == null) { return(_hostValueNotFoundString); } string displayString; var fields = ArrayBuilder <EnumField> .GetInstance(); FillEnumFields(fields, lmrType); // We will normalize/extend all enum values to ulong to ensure that we are always comparing the full underlying value. ulong valueForComparison = ConvertEnumUnderlyingTypeToUInt64( underlyingValue, Type.GetTypeCode(lmrType) ); var typeToDisplayOpt = includeTypeName ? lmrType : null; if (valueForComparison != 0 && IsFlagsEnum(lmrType)) { displayString = GetNamesForFlagsEnumValue( fields, underlyingValue, valueForComparison, options, typeToDisplayOpt ); } else { displayString = GetNameForEnumValue( fields, underlyingValue, valueForComparison, options, typeToDisplayOpt ); } fields.Free(); return(displayString ?? FormatPrimitive(value, options, inspectionContext)); }
private static void FillEnumFields(ArrayBuilder <EnumField> fields, Type lmrType) { var fieldInfos = lmrType.GetFields(); var enumTypeCode = Type.GetTypeCode(lmrType); foreach (var info in fieldInfos) { if (!info.IsSpecialName) // Skip __value. { fields.Add(new EnumField(info.Name, ConvertEnumUnderlyingTypeToUInt64(info.GetRawConstantValue(), enumTypeCode))); } } fields.Sort(EnumField.Comparer); }
#pragma warning disable RS0010 /// <remarks> /// The corresponding native code is in EEUserStringBuilder::ErrTryAppendConstantEnum. /// The corresponding roslyn code is in /// <see cref="M:Microsoft.CodeAnalysis.SymbolDisplay.AbstractSymbolDisplayVisitor`1.AddEnumConstantValue(Microsoft.CodeAnalysis.INamedTypeSymbol, System.Object, System.Boolean)"/>. /// NOTE: no curlies for enum values. /// </remarks> #pragma warning restore RS0010 private string GetEnumDisplayString(Type lmrType, DkmClrValue value, ObjectDisplayOptions options, bool includeTypeName) { Debug.Assert(lmrType.IsEnum); Debug.Assert(value != null); object underlyingValue = value.HostObjectValue; Debug.Assert(underlyingValue != null); string displayString; ArrayBuilder <EnumField> fields = ArrayBuilder <EnumField> .GetInstance(); FillEnumFields(fields, lmrType); // We will normalize/extend all enum values to ulong to ensure that we are always comparing the full underlying value. ulong valueForComparison = ConvertEnumUnderlyingTypeToUInt64(underlyingValue, Type.GetTypeCode(lmrType)); var typeToDisplayOpt = includeTypeName ? lmrType : null; if (valueForComparison != 0 && IsFlagsEnum(lmrType)) { displayString = GetNamesForFlagsEnumValue(fields, underlyingValue, valueForComparison, options, typeToDisplayOpt); } else { displayString = GetNameForEnumValue(fields, underlyingValue, valueForComparison, options, typeToDisplayOpt); } fields.Free(); return(displayString ?? FormatPrimitive(value, options)); }
internal static string GetPredefinedTypeName(this Type type) { if (type.IsEnum) { return(null); } switch (Type.GetTypeCode(type)) { case TypeCode.Object: if (type.IsObject()) { return("object"); } return(null); case TypeCode.Boolean: return("bool"); case TypeCode.Char: return("char"); case TypeCode.SByte: return("sbyte"); case TypeCode.Byte: return("byte"); case TypeCode.Int16: return("short"); case TypeCode.UInt16: return("ushort"); case TypeCode.Int32: return("int"); case TypeCode.UInt32: return("uint"); case TypeCode.Int64: return("long"); case TypeCode.UInt64: return("ulong"); case TypeCode.Single: return("float"); case TypeCode.Double: return("double"); case TypeCode.Decimal: return("decimal"); case TypeCode.String: return("string"); default: return(null); } }