internal static EvalResult CreateMemberDataItem( ResultProvider resultProvider, DkmInspectionContext inspectionContext, MemberAndDeclarationInfo member, DkmClrValue memberValue, EvalResultDataItem parent, CustomTypeInfoTypeArgumentMap customTypeInfoMap, ExpansionFlags flags, bool supportsFavorites) { var fullNameProvider = resultProvider.FullNameProvider; var declaredType = member.Type; var declaredTypeInfo = customTypeInfoMap.SubstituteCustomTypeInfo(member.OriginalDefinitionType, member.TypeInfo); string memberName; // Considering, we're not handling the case of a member inherited from a generic base type. var typeDeclaringMember = member.GetExplicitlyImplementedInterface(out memberName) ?? member.DeclaringType; var typeDeclaringMemberInfo = typeDeclaringMember.IsInterface ? customTypeInfoMap.SubstituteCustomTypeInfo(typeDeclaringMember.GetInterfaceListEntry(member.DeclaringType), customInfo: null) : null; var memberNameForFullName = fullNameProvider.GetClrValidIdentifier(inspectionContext, memberName); var appDomain = memberValue.Type.AppDomain; string fullName; if (memberNameForFullName == null) { fullName = null; } else { memberName = memberNameForFullName; fullName = MakeFullName( fullNameProvider, inspectionContext, memberNameForFullName, new TypeAndCustomInfo(DkmClrType.Create(appDomain, typeDeclaringMember), typeDeclaringMemberInfo), // Note: Won't include DynamicAttribute. member.RequiresExplicitCast, member.IsStatic, parent); } return(resultProvider.CreateDataItem( inspectionContext, memberName, typeDeclaringMemberAndInfo: (member.IncludeTypeInMemberName || typeDeclaringMember.IsInterface) ? new TypeAndCustomInfo(DkmClrType.Create(appDomain, typeDeclaringMember), typeDeclaringMemberInfo) : default(TypeAndCustomInfo), // Note: Won't include DynamicAttribute. declaredTypeAndInfo: new TypeAndCustomInfo(DkmClrType.Create(appDomain, declaredType), declaredTypeInfo), value: memberValue, useDebuggerDisplay: parent != null, expansionFlags: flags, childShouldParenthesize: false, fullName: fullName, formatSpecifiers: Formatter.NoFormatSpecifiers, category: DkmEvaluationResultCategory.Other, flags: memberValue.EvalFlags, evalFlags: DkmEvaluationFlags.None, canFavorite: member.CanFavorite, isFavorite: member.IsFavorite, supportsFavorites: supportsFavorites)); }
public static string GetName(this ExpansionFlags flags, string separator) { if (flags == ExpansionFlags.None) { return("None"); } return(String.Join(separator, flags.EnumerateValues <ExpansionFlags>(true).Not(s => s == ExpansionFlags.None))); }
internal static EvalResultDataItem CreateMemberDataItem( ResultProvider resultProvider, DkmInspectionContext inspectionContext, MemberAndDeclarationInfo member, DkmClrValue memberValue, EvalResultDataItem parent, DynamicFlagsMap dynamicFlagsMap, ExpansionFlags flags) { var declaredType = member.Type; var declaredTypeInfo = dynamicFlagsMap.SubstituteDynamicFlags(member.OriginalDefinitionType, DynamicFlagsCustomTypeInfo.Create(member.TypeInfo)).GetCustomTypeInfo(); string memberName; // Considering, we're not handling the case of a member inherited from a generic base type. var typeDeclaringMember = member.GetExplicitlyImplementedInterface(out memberName) ?? member.DeclaringType; var typeDeclaringMemberInfo = typeDeclaringMember.IsInterface ? dynamicFlagsMap.SubstituteDynamicFlags(typeDeclaringMember.GetInterfaceListEntry(member.DeclaringType), originalDynamicFlags: default(DynamicFlagsCustomTypeInfo)).GetCustomTypeInfo() : null; var formatter = resultProvider.Formatter; bool sawInvalidIdentifier; memberName = formatter.GetIdentifierEscapingPotentialKeywords(memberName, out sawInvalidIdentifier); var fullName = sawInvalidIdentifier ? null : MakeFullName( formatter, memberName, new TypeAndCustomInfo(typeDeclaringMember, typeDeclaringMemberInfo), // Note: Won't include DynamicAttribute. member.RequiresExplicitCast, member.IsStatic, parent); return(resultProvider.CreateDataItem( inspectionContext, memberName, typeDeclaringMemberAndInfo: (member.IncludeTypeInMemberName || typeDeclaringMember.IsInterface) ? new TypeAndCustomInfo(typeDeclaringMember, typeDeclaringMemberInfo) : default(TypeAndCustomInfo), // Note: Won't include DynamicAttribute. declaredTypeAndInfo: new TypeAndCustomInfo(declaredType, declaredTypeInfo), value: memberValue, parent: parent, expansionFlags: flags, childShouldParenthesize: false, fullName: fullName, formatSpecifiers: Formatter.NoFormatSpecifiers, category: DkmEvaluationResultCategory.Other, flags: memberValue.EvalFlags, evalFlags: DkmEvaluationFlags.None)); }
public static bool CheckExpansion(this ExpansionFlags flags, Expansion ex) { if (flags == ExpansionFlags.None) { return(true); } switch (ex) { case Expansion.T2A: return(flags.HasFlag(ExpansionFlags.T2A)); case Expansion.UOR: return(flags.HasFlag(ExpansionFlags.UOR)); case Expansion.UOTD: return(flags.HasFlag(ExpansionFlags.UOTD)); case Expansion.LBR: return(flags.HasFlag(ExpansionFlags.LBR)); case Expansion.AOS: return(flags.HasFlag(ExpansionFlags.AOS)); case Expansion.SE: return(flags.HasFlag(ExpansionFlags.SE)); case Expansion.ML: return(flags.HasFlag(ExpansionFlags.ML)); case Expansion.SA: return(flags.HasFlag(ExpansionFlags.SA)); case Expansion.HS: return(flags.HasFlag(ExpansionFlags.HS)); case Expansion.TOL: return(flags.HasFlag(ExpansionFlags.TOL)); case Expansion.EJ: return(flags.HasFlag(ExpansionFlags.EJ)); default: return(false); } }
public EquipmentSetMod( string name = "Set Mod", string desc = null, int partsReq = 1, bool display = true, ExpansionFlags ex = ExpansionFlags.None) { Name = name; Desc = desc ?? String.Empty; Display = display; PartsRequired = partsReq; Expansions = ex; ActiveOwners = new List <Mobile>(); }
private static EvalResultDataItem CreateMemberDataItem( ResultProvider resultProvider, DkmInspectionContext inspectionContext, MemberAndDeclarationInfo member, DkmClrValue memberValue, EvalResultDataItem parent, ExpansionFlags flags) { var formatter = resultProvider.Formatter; string memberName; var typeDeclaringMember = member.GetExplicitlyImplementedInterface(out memberName) ?? member.DeclaringType; memberName = formatter.GetIdentifierEscapingPotentialKeywords(memberName); // If the value is actually an exception that was thrown, we can't expect it to // have any relation to the declared type of the value. Therefore, we will // pretend that the exception type was the declared type for the purposes // of creating the full name and expansion. var declaredType = memberValue.EvalFlags.Includes(DkmEvaluationResultFlags.ExceptionThrown) ? memberValue.Type.GetLmrType() : member.Type; var fullName = MakeFullName( formatter, memberName, typeDeclaringMember, member.RequiresExplicitCast, member.IsStatic, parent); return(resultProvider.CreateDataItem( inspectionContext, memberName, typeDeclaringMember: (member.IncludeTypeInMemberName || typeDeclaringMember.IsInterface) ? typeDeclaringMember : null, declaredType: declaredType, value: memberValue, parent: parent, expansionFlags: flags, childShouldParenthesize: false, fullName: fullName, formatSpecifiers: Formatter.NoFormatSpecifiers, category: DkmEvaluationResultCategory.Other, flags: memberValue.EvalFlags, evalFlags: DkmEvaluationFlags.None)); }
private static EvalResultDataItem CreateMemberDataItem( ResultProvider resultProvider, DkmInspectionContext inspectionContext, MemberAndDeclarationInfo member, DkmClrValue memberValue, EvalResultDataItem parent, ExpansionFlags flags) { var formatter = resultProvider.Formatter; string memberName; var typeDeclaringMember = member.GetExplicitlyImplementedInterface(out memberName) ?? member.DeclaringType; memberName = formatter.GetIdentifierEscapingPotentialKeywords(memberName); var fullName = MakeFullName( formatter, memberName, typeDeclaringMember, member.RequiresExplicitCast, member.IsStatic, parent); return(resultProvider.CreateDataItem( inspectionContext, memberName, typeDeclaringMember: (member.IncludeTypeInMemberName || typeDeclaringMember.IsInterface) ? typeDeclaringMember : null, declaredType: member.Type, value: memberValue, parent: parent, expansionFlags: flags, childShouldParenthesize: false, fullName: fullName, formatSpecifiers: Formatter.NoFormatSpecifiers, category: DkmEvaluationResultCategory.Other, flags: memberValue.EvalFlags, evalFlags: DkmEvaluationFlags.None)); }
internal Expansion GetTypeExpansion( DkmInspectionContext inspectionContext, TypeAndCustomInfo declaredTypeAndInfo, DkmClrValue value, ExpansionFlags flags) { var declaredType = declaredTypeAndInfo.Type; Debug.Assert(!declaredType.IsTypeVariables()); if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.NoExpansion) != 0) { return(null); } var runtimeType = value.Type.GetLmrType(); // If the value is an array, expand the array elements. if (runtimeType.IsArray) { var sizes = value.ArrayDimensions; if (sizes == null) { // Null array. No expansion. return(null); } var lowerBounds = value.ArrayLowerBounds; Type elementType; DkmClrCustomTypeInfo elementTypeInfo; if (declaredType.IsArray) { elementType = declaredType.GetElementType(); elementTypeInfo = CustomTypeInfo.SkipOne(declaredTypeAndInfo.Info); } else { elementType = runtimeType.GetElementType(); elementTypeInfo = null; } return(ArrayExpansion.CreateExpansion(new TypeAndCustomInfo(DkmClrType.Create(declaredTypeAndInfo.ClrType.AppDomain, elementType), elementTypeInfo), sizes, lowerBounds)); } if (this.IsPrimitiveType(runtimeType)) { return(null); } if (declaredType.IsFunctionPointer()) { // Function pointers have no expansion return(null); } if (declaredType.IsPointer) { // If this assert fails, the element type info is just .SkipOne(). Debug.Assert(declaredTypeAndInfo.Info?.PayloadTypeId != CustomTypeInfo.PayloadTypeId); var elementType = declaredType.GetElementType(); return(value.IsNull || elementType.IsVoid() ? null : new PointerDereferenceExpansion(new TypeAndCustomInfo(DkmClrType.Create(declaredTypeAndInfo.ClrType.AppDomain, elementType)))); } if (value.EvalFlags.Includes(DkmEvaluationResultFlags.ExceptionThrown) && runtimeType.IsEmptyResultsViewException()) { // The value is an exception thrown expanding an empty // IEnumerable. Use the runtime type of the exception and // skip base types. (This matches the native EE behavior // to expose a single property from the exception.) flags &= ~ExpansionFlags.IncludeBaseMembers; } return(MemberExpansion.CreateExpansion(inspectionContext, declaredTypeAndInfo, value, flags, TypeHelpers.IsVisibleMember, this)); }
internal EvalResult CreateDataItem( DkmInspectionContext inspectionContext, string name, TypeAndCustomInfo typeDeclaringMemberAndInfo, TypeAndCustomInfo declaredTypeAndInfo, DkmClrValue value, bool useDebuggerDisplay, ExpansionFlags expansionFlags, bool childShouldParenthesize, string fullName, ReadOnlyCollection <string> formatSpecifiers, DkmEvaluationResultCategory category, DkmEvaluationResultFlags flags, DkmEvaluationFlags evalFlags) { if ((evalFlags & DkmEvaluationFlags.ShowValueRaw) != 0) { formatSpecifiers = Formatter.AddFormatSpecifier(formatSpecifiers, "raw"); } Expansion expansion; // If the declared type is Nullable<T>, the value should // have no expansion if null, or be expanded as a T. var declaredType = declaredTypeAndInfo.Type; var lmrNullableTypeArg = declaredType.GetNullableTypeArgument(); if (lmrNullableTypeArg != null && !value.HasExceptionThrown()) { Debug.Assert(value.Type.GetProxyType() == null); DkmClrValue nullableValue; if (value.IsError()) { expansion = null; } else if ((nullableValue = value.GetNullableValue(lmrNullableTypeArg, inspectionContext)) == null) { Debug.Assert(declaredType.Equals(value.Type.GetLmrType())); // No expansion of "null". expansion = null; } else { value = nullableValue; Debug.Assert(lmrNullableTypeArg.Equals(value.Type.GetLmrType())); // If this is not the case, add a test for includeRuntimeTypeIfNecessary. // CONSIDER: The DynamicAttribute for the type argument should just be Skip(1) of the original flag array. expansion = this.GetTypeExpansion(inspectionContext, new TypeAndCustomInfo(DkmClrType.Create(declaredTypeAndInfo.ClrType.AppDomain, lmrNullableTypeArg)), value, ExpansionFlags.IncludeResultsView); } } else if (value.IsError() || (inspectionContext.EvaluationFlags & DkmEvaluationFlags.NoExpansion) != 0) { expansion = null; } else { expansion = DebuggerTypeProxyExpansion.CreateExpansion( this, inspectionContext, name, typeDeclaringMemberAndInfo, declaredTypeAndInfo, value, childShouldParenthesize, fullName, flags.Includes(DkmEvaluationResultFlags.ExceptionThrown) ? null : fullName, formatSpecifiers, flags, Formatter2.GetEditableValueString(value, inspectionContext, declaredTypeAndInfo.Info)); if (expansion == null) { expansion = value.HasExceptionThrown() ? this.GetTypeExpansion(inspectionContext, new TypeAndCustomInfo(value.Type), value, expansionFlags) : this.GetTypeExpansion(inspectionContext, declaredTypeAndInfo, value, expansionFlags); } } return(new EvalResult( ExpansionKind.Default, name, typeDeclaringMemberAndInfo, declaredTypeAndInfo, useDebuggerDisplay: useDebuggerDisplay, value: value, displayValue: null, expansion: expansion, childShouldParenthesize: childShouldParenthesize, fullName: fullName, childFullNamePrefixOpt: flags.Includes(DkmEvaluationResultFlags.ExceptionThrown) ? null : fullName, formatSpecifiers: formatSpecifiers, category: category, flags: flags, editableValue: Formatter2.GetEditableValueString(value, inspectionContext, declaredTypeAndInfo.Info), inspectionContext: inspectionContext)); }
internal static EvalResultDataItem CreateMemberDataItem( ResultProvider resultProvider, DkmInspectionContext inspectionContext, MemberAndDeclarationInfo member, DkmClrValue memberValue, EvalResultDataItem parent, DynamicFlagsMap dynamicFlagsMap, ExpansionFlags flags) { var declaredType = member.Type; var declaredTypeInfo = dynamicFlagsMap.SubstituteDynamicFlags(member.OriginalDefinitionType, DynamicFlagsCustomTypeInfo.Create(member.TypeInfo)).GetCustomTypeInfo(); string memberName; // Considering, we're not handling the case of a member inherited from a generic base type. var typeDeclaringMember = member.GetExplicitlyImplementedInterface(out memberName) ?? member.DeclaringType; var typeDeclaringMemberInfo = typeDeclaringMember.IsInterface ? dynamicFlagsMap.SubstituteDynamicFlags(typeDeclaringMember.GetInterfaceListEntry(member.DeclaringType), originalDynamicFlags: default(DynamicFlagsCustomTypeInfo)).GetCustomTypeInfo() : null; var formatter = resultProvider.Formatter; memberName = formatter.GetIdentifierEscapingPotentialKeywords(memberName); var fullName = MakeFullName( formatter, memberName, new TypeAndCustomInfo(typeDeclaringMember, typeDeclaringMemberInfo), // Note: Won't include DynamicAttribute. member.RequiresExplicitCast, member.IsStatic, parent); return resultProvider.CreateDataItem( inspectionContext, memberName, typeDeclaringMemberAndInfo: (member.IncludeTypeInMemberName || typeDeclaringMember.IsInterface) ? new TypeAndCustomInfo(typeDeclaringMember, typeDeclaringMemberInfo) : default(TypeAndCustomInfo), // Note: Won't include DynamicAttribute. declaredTypeAndInfo: new TypeAndCustomInfo(declaredType, declaredTypeInfo), value: memberValue, parent: parent, expansionFlags: flags, childShouldParenthesize: false, fullName: fullName, formatSpecifiers: Formatter.NoFormatSpecifiers, category: DkmEvaluationResultCategory.Other, flags: memberValue.EvalFlags, evalFlags: DkmEvaluationFlags.None); }
internal EvalResultDataItem CreateDataItem( DkmInspectionContext inspectionContext, string name, TypeAndCustomInfo typeDeclaringMemberAndInfo, TypeAndCustomInfo declaredTypeAndInfo, DkmClrValue value, EvalResultDataItem parent, ExpansionFlags expansionFlags, bool childShouldParenthesize, string fullName, ReadOnlyCollection<string> formatSpecifiers, DkmEvaluationResultCategory category, DkmEvaluationResultFlags flags, DkmEvaluationFlags evalFlags) { if ((evalFlags & DkmEvaluationFlags.ShowValueRaw) != 0) { formatSpecifiers = Formatter.AddFormatSpecifier(formatSpecifiers, "raw"); } Expansion expansion; // If the declared type is Nullable<T>, the value should // have no expansion if null, or be expanded as a T. var declaredType = declaredTypeAndInfo.Type; var lmrNullableTypeArg = declaredType.GetNullableTypeArgument(); if (lmrNullableTypeArg != null && !value.HasExceptionThrown()) { Debug.Assert(value.Type.GetProxyType() == null); DkmClrValue nullableValue; if (value.IsError()) { expansion = null; } else if ((nullableValue = value.GetNullableValue(inspectionContext)) == null) { Debug.Assert(declaredType.Equals(value.Type.GetLmrType())); // No expansion of "null". expansion = null; } else { value = nullableValue; Debug.Assert(lmrNullableTypeArg.Equals(value.Type.GetLmrType())); // If this is not the case, add a test for includeRuntimeTypeIfNecessary. // CONSIDER: The DynamicAttribute for the type argument should just be Skip(1) of the original flag array. expansion = this.GetTypeExpansion(inspectionContext, new TypeAndCustomInfo(lmrNullableTypeArg), value, ExpansionFlags.IncludeResultsView); } } else if (value.IsError() || (inspectionContext.EvaluationFlags & DkmEvaluationFlags.NoExpansion) != 0) { expansion = null; } else { expansion = DebuggerTypeProxyExpansion.CreateExpansion( this, inspectionContext, name, typeDeclaringMemberAndInfo, declaredTypeAndInfo, value, childShouldParenthesize, fullName, flags.Includes(DkmEvaluationResultFlags.ExceptionThrown) ? null : fullName, formatSpecifiers, flags, this.Formatter.GetEditableValue(value, inspectionContext)); if (expansion == null) { expansion = value.HasExceptionThrown() ? this.GetTypeExpansion(inspectionContext, new TypeAndCustomInfo(value.Type), value, expansionFlags) : this.GetTypeExpansion(inspectionContext, declaredTypeAndInfo, value, expansionFlags); } } return new EvalResultDataItem( ExpansionKind.Default, name, typeDeclaringMemberAndInfo, declaredTypeAndInfo, parent: parent, value: value, displayValue: null, expansion: expansion, childShouldParenthesize: childShouldParenthesize, fullName: fullName, childFullNamePrefixOpt: flags.Includes(DkmEvaluationResultFlags.ExceptionThrown) ? null : fullName, formatSpecifiers: formatSpecifiers, category: category, flags: flags, editableValue: this.Formatter.GetEditableValue(value, inspectionContext), inspectionContext: inspectionContext); }
internal Expansion GetTypeExpansion(DkmInspectionContext inspectionContext, Type declaredType, DkmClrValue value, ExpansionFlags flags) { Debug.Assert(!declaredType.IsTypeVariables()); if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.NoExpansion) != 0) { return(null); } var runtimeType = value.Type.GetLmrType(); // If the value is an array, expand the array elements. if (runtimeType.IsArray) { var sizes = value.ArrayDimensions; if (sizes == null) { // Null array. No expansion. return(null); } var lowerBounds = value.ArrayLowerBounds; return(ArrayExpansion.CreateExpansion(sizes, lowerBounds)); } if (this.Formatter.IsPredefinedType(runtimeType)) { return(null); } if (declaredType.IsPointer) { return(!value.IsNull ? new PointerDereferenceExpansion(declaredType.GetElementType()) : null); } if (value.EvalFlags.Includes(DkmEvaluationResultFlags.ExceptionThrown) && runtimeType.IsEmptyResultsViewException()) { // The value is an exception thrown expanding an empty // IEnumerable. Use the runtime type of the exception and // skip base types. (This matches the native EE behavior // to expose a single property from the exception.) flags &= ~ExpansionFlags.IncludeBaseMembers; } return(MemberExpansion.CreateExpansion(inspectionContext, declaredType, value, flags, TypeHelpers.IsVisibleMember, this.Formatter)); }
public static bool CheckExpansion(this ExpansionFlags flags) { return(CheckExpansion(flags, Core.Expansion)); }
public static string GetName(this ExpansionFlags flags) { return(GetName(flags, ", ")); }
internal static Expansion CreateExpansion( DkmInspectionContext inspectionContext, TypeAndCustomInfo declaredTypeAndInfo, DkmClrValue value, ExpansionFlags flags, Predicate<MemberInfo> predicate, ResultProvider resultProvider) { // For members of type DynamicProperty (part of Dynamic View expansion), we want // to expand the underlying value (not the members of the DynamicProperty type). var type = value.Type; var isDynamicProperty = type.GetLmrType().IsDynamicProperty(); if (isDynamicProperty) { Debug.Assert(!value.IsNull); value = value.GetFieldValue("value", inspectionContext); } var runtimeType = type.GetLmrType(); // Primitives, enums, function pointers, and null values with a declared type that is an interface have no visible members. Debug.Assert(!runtimeType.IsInterface || value.IsNull); if (resultProvider.IsPrimitiveType(runtimeType) || runtimeType.IsEnum || runtimeType.IsInterface || runtimeType.IsFunctionPointer()) { return null; } // As in the old C# EE, DynamicProperty members are only expandable if they have a Dynamic View expansion. var dynamicViewExpansion = DynamicViewExpansion.CreateExpansion(inspectionContext, value, resultProvider); if (isDynamicProperty && (dynamicViewExpansion == null)) { return null; } var customTypeInfoMap = CustomTypeInfoTypeArgumentMap.Create(declaredTypeAndInfo); var expansions = ArrayBuilder<Expansion>.GetInstance(); // From the members, collect the fields and properties, // separated into static and instance members. var staticMembers = ArrayBuilder<MemberAndDeclarationInfo>.GetInstance(); var instanceMembers = ArrayBuilder<MemberAndDeclarationInfo>.GetInstance(); var appDomain = value.Type.AppDomain; // Expand members. (Ideally, this should be done lazily.) var allMembers = ArrayBuilder<MemberAndDeclarationInfo>.GetInstance(); var includeInherited = (flags & ExpansionFlags.IncludeBaseMembers) == ExpansionFlags.IncludeBaseMembers; var hideNonPublic = (inspectionContext.EvaluationFlags & DkmEvaluationFlags.HideNonPublicMembers) == DkmEvaluationFlags.HideNonPublicMembers; runtimeType.AppendTypeMembers(allMembers, predicate, declaredTypeAndInfo.Type, appDomain, includeInherited, hideNonPublic); foreach (var member in allMembers) { var name = member.Name; if (name.IsCompilerGenerated()) { continue; } if (member.IsStatic) { staticMembers.Add(member); } else if (!value.IsNull) { instanceMembers.Add(member); } } allMembers.Free(); // Public and non-public instance members. Expansion publicInstanceExpansion; Expansion nonPublicInstanceExpansion; GetPublicAndNonPublicMembers( instanceMembers, customTypeInfoMap, out publicInstanceExpansion, out nonPublicInstanceExpansion); // Public and non-public static members. Expansion publicStaticExpansion; Expansion nonPublicStaticExpansion; GetPublicAndNonPublicMembers( staticMembers, customTypeInfoMap, out publicStaticExpansion, out nonPublicStaticExpansion); if (publicInstanceExpansion != null) { expansions.Add(publicInstanceExpansion); } if ((publicStaticExpansion != null) || (nonPublicStaticExpansion != null)) { var staticExpansions = ArrayBuilder<Expansion>.GetInstance(); if (publicStaticExpansion != null) { staticExpansions.Add(publicStaticExpansion); } if (nonPublicStaticExpansion != null) { staticExpansions.Add(nonPublicStaticExpansion); } Debug.Assert(staticExpansions.Count > 0); var staticMembersExpansion = new StaticMembersExpansion( type, AggregateExpansion.CreateExpansion(staticExpansions)); staticExpansions.Free(); expansions.Add(staticMembersExpansion); } instanceMembers.Free(); staticMembers.Free(); if (value.NativeComPointer != 0) { expansions.Add(NativeViewExpansion.Instance); } if (nonPublicInstanceExpansion != null) { expansions.Add(nonPublicInstanceExpansion); } // Include Results View if necessary. if ((flags & ExpansionFlags.IncludeResultsView) != 0) { var resultsViewExpansion = ResultsViewExpansion.CreateExpansion(inspectionContext, value, resultProvider); if (resultsViewExpansion != null) { expansions.Add(resultsViewExpansion); } } if (dynamicViewExpansion != null) { expansions.Add(dynamicViewExpansion); } var result = AggregateExpansion.CreateExpansion(expansions); expansions.Free(); return result; }
internal static EvalResult CreateMemberDataItem( ResultProvider resultProvider, DkmInspectionContext inspectionContext, MemberAndDeclarationInfo member, DkmClrValue memberValue, EvalResultDataItem parent, CustomTypeInfoTypeArgumentMap customTypeInfoMap, ExpansionFlags flags) { var fullNameProvider = resultProvider.FullNameProvider; var declaredType = member.Type; var declaredTypeInfo = customTypeInfoMap.SubstituteCustomTypeInfo(member.OriginalDefinitionType, member.TypeInfo); string memberName; // Considering, we're not handling the case of a member inherited from a generic base type. var typeDeclaringMember = member.GetExplicitlyImplementedInterface(out memberName) ?? member.DeclaringType; var typeDeclaringMemberInfo = typeDeclaringMember.IsInterface ? customTypeInfoMap.SubstituteCustomTypeInfo(typeDeclaringMember.GetInterfaceListEntry(member.DeclaringType), customInfo: null) : null; var memberNameForFullName = fullNameProvider.GetClrValidIdentifier(inspectionContext, memberName); var appDomain = memberValue.Type.AppDomain; string fullName; if (memberNameForFullName == null) { fullName = null; } else { memberName = memberNameForFullName; fullName = MakeFullName( fullNameProvider, inspectionContext, memberNameForFullName, new TypeAndCustomInfo(DkmClrType.Create(appDomain, typeDeclaringMember), typeDeclaringMemberInfo), // Note: Won't include DynamicAttribute. member.RequiresExplicitCast, member.IsStatic, parent); } return resultProvider.CreateDataItem( inspectionContext, memberName, typeDeclaringMemberAndInfo: (member.IncludeTypeInMemberName || typeDeclaringMember.IsInterface) ? new TypeAndCustomInfo(DkmClrType.Create(appDomain, typeDeclaringMember), typeDeclaringMemberInfo) : default(TypeAndCustomInfo), // Note: Won't include DynamicAttribute. declaredTypeAndInfo: new TypeAndCustomInfo(DkmClrType.Create(appDomain, declaredType), declaredTypeInfo), value: memberValue, useDebuggerDisplay: parent != null, expansionFlags: flags, childShouldParenthesize: false, fullName: fullName, formatSpecifiers: Formatter.NoFormatSpecifiers, category: DkmEvaluationResultCategory.Other, flags: memberValue.EvalFlags, evalFlags: DkmEvaluationFlags.None); }
internal static Expansion CreateExpansion( DkmInspectionContext inspectionContext, TypeAndCustomInfo declaredTypeAndInfo, DkmClrValue value, ExpansionFlags flags, Predicate <MemberInfo> predicate, Formatter formatter) { var runtimeType = value.Type.GetLmrType(); // Primitives, enums and null values with a declared type that is an interface have no visible members. Debug.Assert(!runtimeType.IsInterface || value.IsNull); if (formatter.IsPredefinedType(runtimeType) || runtimeType.IsEnum || runtimeType.IsInterface) { return(null); } var dynamicFlagsMap = DynamicFlagsMap.Create(declaredTypeAndInfo); var expansions = ArrayBuilder <Expansion> .GetInstance(); // From the members, collect the fields and properties, // separated into static and instance members. var staticMembers = ArrayBuilder <MemberAndDeclarationInfo> .GetInstance(); var instanceMembers = ArrayBuilder <MemberAndDeclarationInfo> .GetInstance(); var appDomain = value.Type.AppDomain; // Expand members. (Ideally, this should be done lazily.) var allMembers = ArrayBuilder <MemberAndDeclarationInfo> .GetInstance(); var includeInherited = (flags & ExpansionFlags.IncludeBaseMembers) == ExpansionFlags.IncludeBaseMembers; var hideNonPublic = (inspectionContext.EvaluationFlags & DkmEvaluationFlags.HideNonPublicMembers) == DkmEvaluationFlags.HideNonPublicMembers; runtimeType.AppendTypeMembers(allMembers, predicate, declaredTypeAndInfo.Type, appDomain, includeInherited, hideNonPublic); foreach (var member in allMembers) { var name = member.Name; if (name.IsCompilerGenerated()) { continue; } if (member.IsStatic) { staticMembers.Add(member); } else if (!value.IsNull) { instanceMembers.Add(member); } } allMembers.Free(); // Public and non-public instance members. Expansion publicInstanceExpansion; Expansion nonPublicInstanceExpansion; GetPublicAndNonPublicMembers( instanceMembers, dynamicFlagsMap, out publicInstanceExpansion, out nonPublicInstanceExpansion); // Public and non-public static members. Expansion publicStaticExpansion; Expansion nonPublicStaticExpansion; GetPublicAndNonPublicMembers( staticMembers, dynamicFlagsMap, out publicStaticExpansion, out nonPublicStaticExpansion); if (publicInstanceExpansion != null) { expansions.Add(publicInstanceExpansion); } if ((publicStaticExpansion != null) || (nonPublicStaticExpansion != null)) { var staticExpansions = ArrayBuilder <Expansion> .GetInstance(); if (publicStaticExpansion != null) { staticExpansions.Add(publicStaticExpansion); } if (nonPublicStaticExpansion != null) { staticExpansions.Add(nonPublicStaticExpansion); } Debug.Assert(staticExpansions.Count > 0); var staticMembersExpansion = new StaticMembersExpansion( runtimeType, AggregateExpansion.CreateExpansion(staticExpansions)); staticExpansions.Free(); expansions.Add(staticMembersExpansion); } if (value.NativeComPointer != 0) { expansions.Add(NativeViewExpansion.Instance); } if (nonPublicInstanceExpansion != null) { expansions.Add(nonPublicInstanceExpansion); } // Include Results View if necessary. if ((flags & ExpansionFlags.IncludeResultsView) != 0) { var resultsViewExpansion = ResultsViewExpansion.CreateExpansion(inspectionContext, value, formatter); if (resultsViewExpansion != null) { expansions.Add(resultsViewExpansion); } } var result = AggregateExpansion.CreateExpansion(expansions); expansions.Free(); return(result); }
internal EvalResultDataItem CreateDataItem( DkmInspectionContext inspectionContext, string name, Type typeDeclaringMember, Type declaredType, DkmClrValue value, EvalResultDataItem parent, ExpansionFlags expansionFlags, bool childShouldParenthesize, string fullName, ReadOnlyCollection <string> formatSpecifiers, DkmEvaluationResultCategory category, DkmEvaluationResultFlags flags, DkmEvaluationFlags evalFlags) { if ((evalFlags & DkmEvaluationFlags.ShowValueRaw) != 0) { formatSpecifiers = Formatter.AddFormatSpecifier(formatSpecifiers, "raw"); } Expansion expansion; // If the declared type is Nullable<T>, the value should // have no expansion if null, or be expanded as a T. var lmrNullableTypeArg = declaredType.GetNullableTypeArgument(); if (lmrNullableTypeArg != null && !value.HasExceptionThrown(parent)) { Debug.Assert(value.Type.GetProxyType() == null); var nullableValue = value.GetNullableValue(inspectionContext); if (nullableValue == null) { Debug.Assert(declaredType.Equals(value.Type.GetLmrType())); // No expansion of "null". expansion = null; } else { value = nullableValue; Debug.Assert(lmrNullableTypeArg.Equals(value.Type.GetLmrType())); // If this is not the case, add a test for includeRuntimeTypeIfNecessary. expansion = this.GetTypeExpansion(inspectionContext, lmrNullableTypeArg, value, ExpansionFlags.IncludeResultsView); } } else if (value.IsError() || (inspectionContext.EvaluationFlags & DkmEvaluationFlags.NoExpansion) != 0) { expansion = null; } else { expansion = DebuggerTypeProxyExpansion.CreateExpansion( this, inspectionContext, name, typeDeclaringMember, declaredType, value, childShouldParenthesize, fullName, flags.Includes(DkmEvaluationResultFlags.ExceptionThrown) ? null : fullName, formatSpecifiers, flags, this.Formatter.GetEditableValue(value, inspectionContext)); if (expansion == null) { var expansionType = value.HasExceptionThrown(parent) ? value.Type.GetLmrType() : declaredType; expansion = this.GetTypeExpansion(inspectionContext, expansionType, value, expansionFlags); } } return(new EvalResultDataItem( ExpansionKind.Default, name, typeDeclaringMember, declaredType, parent: parent, value: value, displayValue: null, expansion: expansion, childShouldParenthesize: childShouldParenthesize, fullName: fullName, childFullNamePrefixOpt: flags.Includes(DkmEvaluationResultFlags.ExceptionThrown) ? null : fullName, formatSpecifiers: formatSpecifiers, category: category, flags: flags, editableValue: this.Formatter.GetEditableValue(value, inspectionContext), inspectionContext: inspectionContext)); }
internal EvalResultDataItem CreateDataItem( DkmInspectionContext inspectionContext, string name, Type typeDeclaringMember, Type declaredType, DkmClrValue value, EvalResultDataItem parent, ExpansionFlags expansionFlags, bool childShouldParenthesize, string fullName, ReadOnlyCollection<string> formatSpecifiers, DkmEvaluationResultCategory category, DkmEvaluationResultFlags flags, DkmEvaluationFlags evalFlags) { if ((evalFlags & DkmEvaluationFlags.ShowValueRaw) != 0) { formatSpecifiers = Formatter.AddFormatSpecifier(formatSpecifiers, "raw"); } Expansion expansion; // If the declared type is Nullable<T>, the value should // have no expansion if null, or be expanded as a T. var lmrNullableTypeArg = declaredType.GetNullableTypeArgument(); if (lmrNullableTypeArg != null && !value.HasExceptionThrown(parent)) { Debug.Assert(value.Type.GetProxyType() == null); var nullableValue = value.GetNullableValue(); if (nullableValue == null) { Debug.Assert(declaredType.Equals(value.Type.GetLmrType())); // No expansion of "null". expansion = null; } else { value = nullableValue; Debug.Assert(lmrNullableTypeArg.Equals(value.Type.GetLmrType())); // If this is not the case, add a test for includeRuntimeTypeIfNecessary. expansion = this.GetTypeExpansion(inspectionContext, lmrNullableTypeArg, value, ExpansionFlags.IncludeResultsView); } } else if (value.IsError() || (inspectionContext.EvaluationFlags & DkmEvaluationFlags.NoExpansion) != 0) { expansion = null; } else { expansion = DebuggerTypeProxyExpansion.CreateExpansion( this, inspectionContext, name, typeDeclaringMember, declaredType, value, childShouldParenthesize, fullName, flags.Includes(DkmEvaluationResultFlags.ExceptionThrown) ? null : fullName, formatSpecifiers, flags, this.Formatter.GetEditableValue(value)); if (expansion == null) { var expansionType = value.HasExceptionThrown(parent) ? value.Type.GetLmrType() : declaredType; expansion = this.GetTypeExpansion(inspectionContext, expansionType, value, expansionFlags); } } return new EvalResultDataItem( name, typeDeclaringMember, declaredType, value, expansion, childShouldParenthesize, fullName, flags.Includes(DkmEvaluationResultFlags.ExceptionThrown) ? null : fullName, formatSpecifiers, category, flags, this.Formatter.GetEditableValue(value)); }
internal static Expansion CreateExpansion( DkmInspectionContext inspectionContext, TypeAndCustomInfo declaredTypeAndInfo, DkmClrValue value, ExpansionFlags flags, Predicate <MemberInfo> predicate, ResultProvider resultProvider, bool isProxyType) { // For members of type DynamicProperty (part of Dynamic View expansion), we want // to expand the underlying value (not the members of the DynamicProperty type). var type = value.Type; var runtimeType = type.GetLmrType(); var isDynamicProperty = runtimeType.IsDynamicProperty(); if (isDynamicProperty) { Debug.Assert(!value.IsNull); value = value.GetFieldValue("value", inspectionContext); } // Primitives, enums, function pointers, IntPtr, UIntPtr and null values with a declared type that is an interface have no visible members. Debug.Assert(!runtimeType.IsInterface || value.IsNull); if (resultProvider.IsPrimitiveType(runtimeType) || runtimeType.IsEnum || runtimeType.IsInterface || runtimeType.IsFunctionPointer() || runtimeType.IsIntPtr() || runtimeType.IsUIntPtr()) { return(null); } // As in the old C# EE, DynamicProperty members are only expandable if they have a Dynamic View expansion. var dynamicViewExpansion = DynamicViewExpansion.CreateExpansion(inspectionContext, value, resultProvider); if (isDynamicProperty && (dynamicViewExpansion == null)) { return(null); } var customTypeInfoMap = CustomTypeInfoTypeArgumentMap.Create(declaredTypeAndInfo); var expansions = ArrayBuilder <Expansion> .GetInstance(); // Expand members. TODO: Ideally, this would be done lazily (https://github.com/dotnet/roslyn/issues/32800) // From the members, collect the fields and properties, // separated into static and instance members. var staticMembers = ArrayBuilder <MemberAndDeclarationInfo> .GetInstance(); var instanceMembers = ArrayBuilder <MemberAndDeclarationInfo> .GetInstance(); var appDomain = value.Type.AppDomain; var allMembers = ArrayBuilder <MemberAndDeclarationInfo> .GetInstance(); var includeInherited = (flags & ExpansionFlags.IncludeBaseMembers) == ExpansionFlags.IncludeBaseMembers; var hideNonPublic = (inspectionContext.EvaluationFlags & DkmEvaluationFlags.HideNonPublicMembers) == DkmEvaluationFlags.HideNonPublicMembers; var includeCompilerGenerated = (inspectionContext.EvaluationFlags & DkmEvaluationFlags.ShowValueRaw) == DkmEvaluationFlags.ShowValueRaw; runtimeType.AppendTypeMembers(allMembers, predicate, declaredTypeAndInfo.Type, appDomain, includeInherited, hideNonPublic, isProxyType, includeCompilerGenerated); foreach (var member in allMembers) { if (member.IsStatic) { staticMembers.Add(member); } else if (!value.IsNull) { instanceMembers.Add(member); } } allMembers.Free(); // Public and non-public instance members. Expansion publicInstanceExpansion; Expansion nonPublicInstanceExpansion; GetPublicAndNonPublicMembers( instanceMembers, customTypeInfoMap, isProxyType, out publicInstanceExpansion, out nonPublicInstanceExpansion); // Public and non-public static members. Expansion publicStaticExpansion; Expansion nonPublicStaticExpansion; GetPublicAndNonPublicMembers( staticMembers, customTypeInfoMap, isProxyType, out publicStaticExpansion, out nonPublicStaticExpansion); if (publicInstanceExpansion != null) { expansions.Add(publicInstanceExpansion); } if ((publicStaticExpansion != null) || (nonPublicStaticExpansion != null)) { var staticExpansions = ArrayBuilder <Expansion> .GetInstance(); if (publicStaticExpansion != null) { staticExpansions.Add(publicStaticExpansion); } if (nonPublicStaticExpansion != null) { staticExpansions.Add(nonPublicStaticExpansion); } Debug.Assert(staticExpansions.Count > 0); var staticMembersExpansion = new StaticMembersExpansion( type, AggregateExpansion.CreateExpansion(staticExpansions)); staticExpansions.Free(); expansions.Add(staticMembersExpansion); } instanceMembers.Free(); staticMembers.Free(); if (value.NativeComPointer != 0) { expansions.Add(NativeViewExpansion.Instance); } if (nonPublicInstanceExpansion != null) { expansions.Add(nonPublicInstanceExpansion); } // Include Results View if necessary. if ((flags & ExpansionFlags.IncludeResultsView) != 0) { var resultsViewExpansion = ResultsViewExpansion.CreateExpansion(inspectionContext, value, resultProvider); if (resultsViewExpansion != null) { expansions.Add(resultsViewExpansion); } } if (dynamicViewExpansion != null) { expansions.Add(dynamicViewExpansion); } var result = AggregateExpansion.CreateExpansion(expansions); expansions.Free(); return(result); }
internal Expansion GetTypeExpansion(DkmInspectionContext inspectionContext, Type declaredType, DkmClrValue value, ExpansionFlags flags) { Debug.Assert(!declaredType.IsTypeVariables()); if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.NoExpansion) != 0) { return null; } var runtimeType = value.Type.GetLmrType(); // If the value is an array, expand the array elements. if (runtimeType.IsArray) { var sizes = value.ArrayDimensions; if (sizes == null) { // Null array. No expansion. return null; } var lowerBounds = value.ArrayLowerBounds; return ArrayExpansion.CreateExpansion(sizes, lowerBounds); } if (this.Formatter.IsPredefinedType(runtimeType)) { return null; } if (declaredType.IsPointer) { return !value.IsNull ? new PointerDereferenceExpansion(declaredType.GetElementType()) : null; } if (value.EvalFlags.Includes(DkmEvaluationResultFlags.ExceptionThrown) && runtimeType.IsEmptyResultsViewException()) { // The value is an exception thrown expanding an empty // IEnumerable. Use the runtime type of the exception and // skip base types. (This matches the native EE behavior // to expose a single property from the exception.) flags &= ~ExpansionFlags.IncludeBaseMembers; } return MemberExpansion.CreateExpansion(declaredType, value, flags, TypeHelpers.IsVisibleMember, this.Formatter); }
internal Expansion GetTypeExpansion( DkmInspectionContext inspectionContext, TypeAndCustomInfo declaredTypeAndInfo, DkmClrValue value, ExpansionFlags flags) { var declaredType = declaredTypeAndInfo.Type; Debug.Assert(!declaredType.IsTypeVariables()); if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.NoExpansion) != 0) { return null; } var runtimeType = value.Type.GetLmrType(); // If the value is an array, expand the array elements. if (runtimeType.IsArray) { var sizes = value.ArrayDimensions; if (sizes == null) { // Null array. No expansion. return null; } var lowerBounds = value.ArrayLowerBounds; Type elementType; DkmClrCustomTypeInfo elementTypeInfo; if (declaredType.IsArray) { elementType = declaredType.GetElementType(); elementTypeInfo = DynamicFlagsCustomTypeInfo.Create(declaredTypeAndInfo.Info).SkipOne().GetCustomTypeInfo(); } else { elementType = runtimeType.GetElementType(); elementTypeInfo = null; } return ArrayExpansion.CreateExpansion(new TypeAndCustomInfo(elementType, elementTypeInfo), sizes, lowerBounds); } if (this.Formatter.IsPredefinedType(runtimeType)) { return null; } if(declaredType.IsFunctionPointer()) { // Function pointers have no expansion return null; } if (declaredType.IsPointer) { // If this ever happens, the element type info is just .SkipOne(). Debug.Assert(!DynamicFlagsCustomTypeInfo.Create(declaredTypeAndInfo.Info).Any()); var elementType = declaredType.GetElementType(); return value.IsNull || elementType.IsVoid() ? null : new PointerDereferenceExpansion(new TypeAndCustomInfo(elementType)); } if (value.EvalFlags.Includes(DkmEvaluationResultFlags.ExceptionThrown) && runtimeType.IsEmptyResultsViewException()) { // The value is an exception thrown expanding an empty // IEnumerable. Use the runtime type of the exception and // skip base types. (This matches the native EE behavior // to expose a single property from the exception.) flags &= ~ExpansionFlags.IncludeBaseMembers; } return MemberExpansion.CreateExpansion(inspectionContext, declaredTypeAndInfo, value, flags, TypeHelpers.IsVisibleMember, this.Formatter); }
internal static Expansion CreateExpansion( DkmInspectionContext inspectionContext, TypeAndCustomInfo declaredTypeAndInfo, DkmClrValue value, ExpansionFlags flags, Predicate<MemberInfo> predicate, Formatter formatter) { var runtimeType = value.Type.GetLmrType(); // Primitives, enums and null values with a declared type that is an interface have no visible members. Debug.Assert(!runtimeType.IsInterface || value.IsNull); if (formatter.IsPredefinedType(runtimeType) || runtimeType.IsEnum || runtimeType.IsInterface) { return null; } var dynamicFlagsMap = DynamicFlagsMap.Create(declaredTypeAndInfo); var expansions = ArrayBuilder<Expansion>.GetInstance(); // From the members, collect the fields and properties, // separated into static and instance members. var staticMembers = ArrayBuilder<MemberAndDeclarationInfo>.GetInstance(); var instanceMembers = ArrayBuilder<MemberAndDeclarationInfo>.GetInstance(); var appDomain = value.Type.AppDomain; // Expand members. (Ideally, this should be done lazily.) var allMembers = ArrayBuilder<MemberAndDeclarationInfo>.GetInstance(); var includeInherited = (flags & ExpansionFlags.IncludeBaseMembers) == ExpansionFlags.IncludeBaseMembers; var hideNonPublic = (inspectionContext.EvaluationFlags & DkmEvaluationFlags.HideNonPublicMembers) == DkmEvaluationFlags.HideNonPublicMembers; runtimeType.AppendTypeMembers(allMembers, predicate, declaredTypeAndInfo.Type, appDomain, includeInherited, hideNonPublic); foreach (var member in allMembers) { var name = member.Name; if (name.IsCompilerGenerated()) { continue; } if (member.IsStatic) { staticMembers.Add(member); } else if (!value.IsNull) { instanceMembers.Add(member); } } allMembers.Free(); // Public and non-public instance members. Expansion publicInstanceExpansion; Expansion nonPublicInstanceExpansion; GetPublicAndNonPublicMembers( instanceMembers, dynamicFlagsMap, out publicInstanceExpansion, out nonPublicInstanceExpansion); // Public and non-public static members. Expansion publicStaticExpansion; Expansion nonPublicStaticExpansion; GetPublicAndNonPublicMembers( staticMembers, dynamicFlagsMap, out publicStaticExpansion, out nonPublicStaticExpansion); if (publicInstanceExpansion != null) { expansions.Add(publicInstanceExpansion); } if ((publicStaticExpansion != null) || (nonPublicStaticExpansion != null)) { var staticExpansions = ArrayBuilder<Expansion>.GetInstance(); if (publicStaticExpansion != null) { staticExpansions.Add(publicStaticExpansion); } if (nonPublicStaticExpansion != null) { staticExpansions.Add(nonPublicStaticExpansion); } Debug.Assert(staticExpansions.Count > 0); var staticMembersExpansion = new StaticMembersExpansion( runtimeType, AggregateExpansion.CreateExpansion(staticExpansions)); staticExpansions.Free(); expansions.Add(staticMembersExpansion); } if (value.NativeComPointer != 0) { expansions.Add(NativeViewExpansion.Instance); } if (nonPublicInstanceExpansion != null) { expansions.Add(nonPublicInstanceExpansion); } // Include Results View if necessary. if ((flags & ExpansionFlags.IncludeResultsView) != 0) { var resultsViewExpansion = ResultsViewExpansion.CreateExpansion(inspectionContext, value, formatter); if (resultsViewExpansion != null) { expansions.Add(resultsViewExpansion); } } var result = AggregateExpansion.CreateExpansion(expansions); expansions.Free(); return result; }