internal static DynamicViewExpansion CreateExpansion(DkmInspectionContext inspectionContext, DkmClrValue value, Formatter formatter) { if (value.IsError() || value.IsNull || value.HasExceptionThrown()) { return null; } var type = value.Type.GetLmrType(); if (!(type.IsComObject() || type.IsIDynamicMetaObjectProvider())) { return null; } var proxyValue = value.InstantiateDynamicViewProxy(inspectionContext); Debug.Assert((proxyValue == null) || (!proxyValue.IsNull && !proxyValue.IsError() && !proxyValue.HasExceptionThrown())); // InstantiateDynamicViewProxy may return null (if required assembly is missing, for instance). if (proxyValue == null) { return null; } // Expansion is based on the 'DynamicMetaObjectProviderDebugView.Items' property. var proxyType = proxyValue.Type; var itemsMemberExpansion = RootHiddenExpansion.CreateExpansion( proxyType.GetMemberByName("Items"), DynamicFlagsMap.Create(new TypeAndCustomInfo(proxyType))); return new DynamicViewExpansion(proxyValue, itemsMemberExpansion); }
/// <summary> /// Generate a Results Only row if the value is a synthesized /// value declared as IEnumerable or IEnumerable<T>. /// </summary> internal static EvalResultDataItem CreateResultsOnlyRowIfSynthesizedEnumerable( DkmInspectionContext inspectionContext, string name, DkmClrType declaredType, DkmClrCustomTypeInfo declaredTypeInfo, DkmClrValue value, Formatter formatter) { if ((value.ValueFlags & DkmClrValueFlags.Synthetic) == 0) { return null; } // Must be declared as IEnumerable or IEnumerable<T>, not a derived type. var enumerableType = GetEnumerableType(value, declaredType, requireExactInterface: true); if (enumerableType == null) { return null; } var expansion = CreateExpansion(inspectionContext, value, enumerableType, formatter); if (expansion == null) { return null; } return expansion.CreateResultsViewRow( inspectionContext, name, new TypeAndCustomInfo(declaredType.GetLmrType(), declaredTypeInfo), value, includeResultsFormatSpecifier: false, formatter: formatter); }
internal static string GetExceptionMessage(this DkmClrValue value, string fullNameWithoutFormatSpecifiers, Formatter formatter) { return string.Format( Resources.ExceptionThrown, fullNameWithoutFormatSpecifiers, formatter.GetTypeName(value.Type.GetLmrType())); }
internal static string GetExceptionMessage(this DkmClrValue value, string fullNameWithoutFormatSpecifiers, Formatter formatter) { bool unused; return string.Format( Resources.ExceptionThrown, fullNameWithoutFormatSpecifiers, formatter.GetTypeName(new TypeAndCustomInfo(value.Type), escapeKeywordIdentifiers: false, sawInvalidIdentifier: out unused)); }
internal static ResultsViewExpansion CreateExpansion(DkmInspectionContext inspectionContext, DkmClrValue value, Formatter formatter) { var enumerableType = GetEnumerableType(value); if (enumerableType == null) { return null; } return CreateExpansion(inspectionContext, value, enumerableType, formatter); }
internal static EvalResultDataItem CreateMembersOnlyRow( DkmInspectionContext inspectionContext, string name, DkmClrValue value, Formatter formatter) { var expansion = CreateExpansion(inspectionContext, value, formatter); return (expansion != null) ? expansion.CreateDynamicViewRow(inspectionContext, name, parent: null, formatter: formatter) : new EvalResultDataItem(name, Resources.DynamicViewNotDynamic); }
internal static DkmEvaluationResult CreateResultsOnly( string name, DkmClrType declaredType, DkmClrValue value, EvalResultDataItem parent, Formatter formatter) { string errorMessage; if (value.IsError()) { errorMessage = (string)value.HostObjectValue; } else if (value.HasExceptionThrown(parent)) { errorMessage = value.GetExceptionMessage(name, formatter); } else { var enumerableType = GetEnumerableType(value); if (enumerableType != null) { var expansion = CreateExpansion(value, enumerableType, formatter); if (expansion != null) { return expansion.CreateEvaluationResult(name, parent, formatter); } errorMessage = Resources.ResultsViewNoSystemCore; } else { errorMessage = Resources.ResultsViewNotEnumerable; } } Debug.Assert(errorMessage != null); return DkmFailedEvaluationResult.Create( InspectionContext: value.InspectionContext, StackFrame: value.StackFrame, Name: name, FullName: null, ErrorMessage: errorMessage, Flags: DkmEvaluationResultFlags.None, Type: null, DataItem: null); }
internal static EvalResultDataItem CreateResultsOnlyRow( DkmInspectionContext inspectionContext, string name, DkmClrType declaredType, DkmClrCustomTypeInfo declaredTypeInfo, DkmClrValue value, Formatter formatter) { string errorMessage; if (value.IsError()) { errorMessage = (string)value.HostObjectValue; } else if (value.HasExceptionThrown()) { errorMessage = value.GetExceptionMessage(name, formatter); } else { var enumerableType = GetEnumerableType(value); if (enumerableType != null) { var expansion = CreateExpansion(inspectionContext, value, enumerableType, formatter); if (expansion != null) { return expansion.CreateResultsViewRow( inspectionContext, name, new TypeAndCustomInfo(declaredType.GetLmrType(), declaredTypeInfo), value, includeResultsFormatSpecifier: true, formatter: formatter); } errorMessage = Resources.ResultsViewNoSystemCore; } else { errorMessage = Resources.ResultsViewNotEnumerable; } } Debug.Assert(errorMessage != null); return new EvalResultDataItem(name, errorMessage); }
private EvalResultDataItem CreateResultsViewRow( DkmInspectionContext inspectionContext, string name, TypeAndCustomInfo declaredTypeAndInfo, DkmClrValue value, bool includeResultsFormatSpecifier, Formatter formatter) { var proxyTypeAndInfo = new TypeAndCustomInfo(_proxyValue.Type); ReadOnlyCollection<string> formatSpecifiers; var fullName = formatter.TrimAndGetFormatSpecifiers(name, out formatSpecifiers); if (includeResultsFormatSpecifier) { formatSpecifiers = Formatter.AddFormatSpecifier(formatSpecifiers, ResultsFormatSpecifier); } bool unused; var childFullNamePrefix = formatter.GetObjectCreationExpression(formatter.GetTypeName(proxyTypeAndInfo, escapeKeywordIdentifiers: true, sawInvalidIdentifier: out unused), fullName); return new EvalResultDataItem( ExpansionKind.Default, name, typeDeclaringMemberAndInfo: default(TypeAndCustomInfo), declaredTypeAndInfo: declaredTypeAndInfo, parent: null, value: value, displayValue: null, expansion: new IndirectExpansion(_proxyValue, _proxyMembers), childShouldParenthesize: false, fullName: fullName, childFullNamePrefixOpt: childFullNamePrefix, formatSpecifiers: formatSpecifiers, category: DkmEvaluationResultCategory.Method, flags: DkmEvaluationResultFlags.ReadOnly, editableValue: null, inspectionContext: inspectionContext); }
private static string GetFullName(EvalResultDataItem parent, string name, Formatter formatter) { var parentFullName = parent.ChildFullNamePrefix; if (parent.ChildShouldParenthesize) { parentFullName = $"({parentFullName})"; } var parentRuntimeType = parent.Value.Type.GetLmrType(); if (!parent.DeclaredTypeAndInfo.Type.Equals(parentRuntimeType)) { parentFullName = formatter.GetCastExpression( parentFullName, formatter.GetTypeName(new TypeAndCustomInfo(parentRuntimeType), escapeKeywordIdentifiers: true), parenthesizeEntireExpression: true); } return parentFullName + name; }
internal static Expansion CreateExpansion( DkmInspectionContext inspectionContext, TypeAndCustomInfo declaredTypeAndInfo, DkmClrValue value, ExpansionFlags flags, Predicate <MemberInfo> predicate, Formatter formatter) { // 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 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); } // As in the old C# EE, DynamicProperty members are only expandable if they have a Dynamic View expansion. var dynamicViewExpansion = DynamicViewExpansion.CreateExpansion(inspectionContext, value, formatter); if (isDynamicProperty && (dynamicViewExpansion == null)) { 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); } } if (dynamicViewExpansion != null) { expansions.Add(dynamicViewExpansion); } var result = AggregateExpansion.CreateExpansion(expansions); expansions.Free(); return(result); }
private EvalResultDataItem CreateResultsViewRow(DkmInspectionContext inspectionContext, EvalResultDataItem parent, Formatter formatter) { Debug.Assert(parent != null); var proxyTypeAndInfo = new TypeAndCustomInfo(_proxyValue.Type); var fullName = parent.ChildFullNamePrefix; bool unused; var childFullNamePrefix = (fullName == null) ? null : formatter.GetObjectCreationExpression(formatter.GetTypeName(proxyTypeAndInfo, escapeKeywordIdentifiers: true, sawInvalidIdentifier: out unused), fullName); return new EvalResultDataItem( ExpansionKind.ResultsView, Resources.ResultsView, typeDeclaringMemberAndInfo: default(TypeAndCustomInfo), declaredTypeAndInfo: proxyTypeAndInfo, parent: null, value: _proxyValue, displayValue: Resources.ResultsViewValueWarning, expansion: _proxyMembers, childShouldParenthesize: false, fullName: fullName, childFullNamePrefixOpt: childFullNamePrefix, formatSpecifiers: Formatter.AddFormatSpecifier(parent.FormatSpecifiers, ResultsFormatSpecifier), category: DkmEvaluationResultCategory.Method, flags: DkmEvaluationResultFlags.ReadOnly, editableValue: null, inspectionContext: inspectionContext); }
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)); }
private static ResultsViewExpansion CreateExpansion(DkmInspectionContext inspectionContext, DkmClrValue value, DkmClrType enumerableType, Formatter formatter) { var proxyValue = value.InstantiateResultsViewProxy(inspectionContext, enumerableType); // InstantiateResultsViewProxy may return null (if required assembly is missing, for instance). if (proxyValue == null) { return null; } var proxyMembers = MemberExpansion.CreateExpansion( inspectionContext, new TypeAndCustomInfo(proxyValue.Type), proxyValue, flags: ExpansionFlags.None, predicate: TypeHelpers.IsPublic, formatter: formatter); return new ResultsViewExpansion(proxyValue, proxyMembers); }
private DebuggerTypeProxyExpansion( DkmInspectionContext inspectionContext, DkmClrValue proxyValue, string name, TypeAndCustomInfo typeDeclaringMemberAndInfoOpt, TypeAndCustomInfo declaredTypeAndInfo, DkmClrValue value, bool childShouldParenthesize, string fullName, string childFullNamePrefix, ReadOnlyCollection <string> formatSpecifiers, DkmEvaluationResultFlags flags, string editableValue, Formatter formatter) { Debug.Assert(proxyValue != null); var proxyType = proxyValue.Type.GetLmrType(); var proxyTypeAndInfo = new TypeAndCustomInfo(proxyType); var proxyMembers = MemberExpansion.CreateExpansion( inspectionContext, proxyTypeAndInfo, proxyValue, ExpansionFlags.IncludeBaseMembers, TypeHelpers.IsPublic, formatter); if (proxyMembers != null) { var proxyMemberFullNamePrefix = (childFullNamePrefix == null) ? null : formatter.GetObjectCreationExpression(formatter.GetTypeName(proxyTypeAndInfo, escapeKeywordIdentifiers: true), childFullNamePrefix); _proxyItem = new EvalResultDataItem( ExpansionKind.Default, name: string.Empty, typeDeclaringMemberAndInfo: default(TypeAndCustomInfo), declaredTypeAndInfo: proxyTypeAndInfo, parent: null, value: proxyValue, displayValue: null, expansion: proxyMembers, childShouldParenthesize: false, fullName: null, childFullNamePrefixOpt: proxyMemberFullNamePrefix, formatSpecifiers: Formatter.NoFormatSpecifiers, category: default(DkmEvaluationResultCategory), flags: default(DkmEvaluationResultFlags), editableValue: null, inspectionContext: inspectionContext); } _name = name; _typeDeclaringMemberAndInfoOpt = typeDeclaringMemberAndInfoOpt; _declaredTypeAndInfo = declaredTypeAndInfo; _value = value; _childShouldParenthesize = childShouldParenthesize; _fullName = fullName; _childFullNamePrefix = childFullNamePrefix; _formatSpecifiers = formatSpecifiers; _flags = flags; _editableValue = editableValue; }
internal static string GetExceptionMessage(this DkmClrValue value, string fullNameWithoutFormatSpecifiers, Formatter formatter) { return(string.Format( Resources.ExceptionThrown, fullNameWithoutFormatSpecifiers, formatter.GetTypeName(new TypeAndCustomInfo(value.Type)))); }
private static string MakeFullName( Formatter formatter, string name, TypeAndCustomInfo typeDeclaringMemberAndInfo, bool memberAccessRequiresExplicitCast, bool memberIsStatic, EvalResultDataItem parent) { // If the parent is an exception thrown during evaluation, // there is no valid fullname expression for the child. if (parent.Value.EvalFlags.Includes(DkmEvaluationResultFlags.ExceptionThrown)) { return(null); } var parentFullName = parent.ChildFullNamePrefix; if (parentFullName == null) { return(null); } if (parent.ChildShouldParenthesize) { parentFullName = $"({parentFullName})"; } if (!typeDeclaringMemberAndInfo.Type.IsInterface) { string qualifier; if (memberIsStatic) { qualifier = formatter.GetTypeName(typeDeclaringMemberAndInfo, escapeKeywordIdentifiers: false); } else if (memberAccessRequiresExplicitCast) { var typeName = formatter.GetTypeName(typeDeclaringMemberAndInfo, escapeKeywordIdentifiers: true); qualifier = formatter.GetCastExpression( parentFullName, typeName, parenthesizeEntireExpression: true); } else { qualifier = parentFullName; } return($"{qualifier}.{name}"); } else { // NOTE: This should never interact with debugger proxy types: // 1) Interfaces cannot have debugger proxy types. // 2) Debugger proxy types cannot be interfaces. if (typeDeclaringMemberAndInfo.Type.Equals(parent.DeclaredTypeAndInfo.Type)) { var memberAccessTemplate = parent.ChildShouldParenthesize ? "({0}).{1}" : "{0}.{1}"; return(string.Format(memberAccessTemplate, parent.ChildFullNamePrefix, name)); } else { var interfaceName = formatter.GetTypeName(typeDeclaringMemberAndInfo, escapeKeywordIdentifiers: true); var memberAccessTemplate = parent.ChildShouldParenthesize ? "(({0})({1})).{2}" : "(({0}){1}).{2}"; return(string.Format(memberAccessTemplate, interfaceName, parent.ChildFullNamePrefix, name)); } } }
private static ResultsViewExpansion CreateExpansion(DkmClrValue value, DkmClrType enumerableType, Formatter formatter) { var proxyValue = value.InstantiateResultsViewProxy(enumerableType); // InstantiateResultsViewProxy may return null // (if assembly is missing for instance). if (proxyValue == null) { return(null); } var proxyMembers = MemberExpansion.CreateExpansion( proxyValue.Type.GetLmrType(), proxyValue, ExpansionFlags.None, TypeHelpers.IsPublic, formatter); return(new ResultsViewExpansion(proxyValue, proxyMembers)); }
internal static Expansion CreateExpansion( DkmInspectionContext inspectionContext, TypeAndCustomInfo declaredTypeAndInfo, DkmClrValue value, ExpansionFlags flags, Predicate<MemberInfo> predicate, Formatter formatter) { // 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 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; } // As in the old C# EE, DynamicProperty members are only expandable if they have a Dynamic View expansion. var dynamicViewExpansion = DynamicViewExpansion.CreateExpansion(inspectionContext, value, formatter); if (isDynamicProperty && (dynamicViewExpansion == null)) { 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); } } if (dynamicViewExpansion != null) { expansions.Add(dynamicViewExpansion); } var result = AggregateExpansion.CreateExpansion(expansions); expansions.Free(); return result; }
private static ResultsViewExpansion CreateExpansion(DkmClrValue value, DkmClrType enumerableType, Formatter formatter) { var proxyValue = value.InstantiateResultsViewProxy(enumerableType); // InstantiateResultsViewProxy may return null // (if assembly is missing for instance). if (proxyValue == null) { return null; } var proxyMembers = MemberExpansion.CreateExpansion( proxyValue.Type.GetLmrType(), proxyValue, ExpansionFlags.None, TypeHelpers.IsPublic, formatter); return new ResultsViewExpansion(proxyValue, proxyMembers); }
private static EvalResult GetMemberRow( ResultProvider resultProvider, DkmInspectionContext inspectionContext, DkmClrValue value, Field field, EvalResultDataItem parent, int cardinality) { var fullNameProvider = resultProvider.FullNameProvider; var parentFullName = parent.ChildFullNamePrefix; if (parentFullName != null) { if (parent.ChildShouldParenthesize) { parentFullName = parentFullName.Parenthesize(); } var parentRuntimeType = parent.Value.Type; if (!parent.DeclaredTypeAndInfo.Type.Equals(parentRuntimeType.GetLmrType())) { parentFullName = fullNameProvider.GetClrCastExpression( inspectionContext, parentFullName, parentRuntimeType, customTypeInfo: null, castExpressionOptions: DkmClrCastExpressionOptions.ParenthesizeEntireExpression); } } // Ideally if the caller requests multiple items in a nested tuple // we should only evaluate Rest once, and should only calculate // the full name for Rest once. string fullName; var fieldValue = GetValueAndFullName( fullNameProvider, inspectionContext, value, field, parentFullName, out fullName); var name = field.Name; var typeDeclaringMemberAndInfo = default(TypeAndCustomInfo); var declaredTypeAndInfo = field.FieldTypeAndInfo; var flags = fieldValue.EvalFlags; var formatSpecifiers = Formatter.NoFormatSpecifiers; if (field.IsRest) { var displayValue = fieldValue.GetValueString(inspectionContext, Formatter.NoFormatSpecifiers); var displayType = ResultProvider.GetTypeName( inspectionContext, fieldValue, declaredTypeAndInfo.ClrType, declaredTypeAndInfo.Info, isPointerDereference: false); var expansion = new TupleExpansion(declaredTypeAndInfo, cardinality - (TypeHelpers.TupleFieldRestPosition - 1), useRawView: true); return(new EvalResult( ExpansionKind.Explicit, name, typeDeclaringMemberAndInfo, declaredTypeAndInfo, useDebuggerDisplay: false, value: fieldValue, displayValue: displayValue, expansion: expansion, childShouldParenthesize: false, fullName: fullName, childFullNamePrefixOpt: flags.Includes(DkmEvaluationResultFlags.ExceptionThrown) ? null : fullName, formatSpecifiers: Formatter.AddFormatSpecifier(formatSpecifiers, "raw"), category: DkmEvaluationResultCategory.Other, flags: flags, editableValue: null, inspectionContext: inspectionContext, displayName: name, displayType: displayType)); } return(resultProvider.CreateDataItem( inspectionContext, name, typeDeclaringMemberAndInfo: typeDeclaringMemberAndInfo, declaredTypeAndInfo: declaredTypeAndInfo, value: fieldValue, useDebuggerDisplay: false, expansionFlags: ExpansionFlags.All, childShouldParenthesize: false, fullName: fullName, formatSpecifiers: formatSpecifiers, category: DkmEvaluationResultCategory.Other, flags: flags, evalFlags: DkmEvaluationFlags.None, canFavorite: false, isFavorite: false, supportsFavorites: true)); }
private DebuggerTypeProxyExpansion( DkmInspectionContext inspectionContext, DkmClrValue proxyValue, string name, TypeAndCustomInfo typeDeclaringMemberAndInfoOpt, TypeAndCustomInfo declaredTypeAndInfo, DkmClrValue value, bool childShouldParenthesize, string fullName, string childFullNamePrefix, ReadOnlyCollection<string> formatSpecifiers, DkmEvaluationResultFlags flags, string editableValue, Formatter formatter) { Debug.Assert(proxyValue != null); var proxyType = proxyValue.Type.GetLmrType(); var proxyTypeAndInfo = new TypeAndCustomInfo(proxyType); var proxyMembers = MemberExpansion.CreateExpansion( inspectionContext, proxyTypeAndInfo, proxyValue, ExpansionFlags.IncludeBaseMembers, TypeHelpers.IsPublic, formatter); if (proxyMembers != null) { var proxyMemberFullNamePrefix = (childFullNamePrefix == null) ? null : formatter.GetObjectCreationExpression(formatter.GetTypeName(proxyTypeAndInfo, escapeKeywordIdentifiers: true), childFullNamePrefix); _proxyItem = new EvalResultDataItem( ExpansionKind.Default, name: string.Empty, typeDeclaringMemberAndInfo: default(TypeAndCustomInfo), declaredTypeAndInfo: proxyTypeAndInfo, parent: null, value: proxyValue, displayValue: null, expansion: proxyMembers, childShouldParenthesize: false, fullName: null, childFullNamePrefixOpt: proxyMemberFullNamePrefix, formatSpecifiers: Formatter.NoFormatSpecifiers, category: default(DkmEvaluationResultCategory), flags: default(DkmEvaluationResultFlags), editableValue: null, inspectionContext: inspectionContext); } _name = name; _typeDeclaringMemberAndInfoOpt = typeDeclaringMemberAndInfoOpt; _declaredTypeAndInfo = declaredTypeAndInfo; _value = value; _childShouldParenthesize = childShouldParenthesize; _fullName = fullName; _childFullNamePrefix = childFullNamePrefix; _formatSpecifiers = formatSpecifiers; _flags = flags; _editableValue = editableValue; }
internal ResultProvider(Formatter formatter) { this.Formatter = formatter; }
private DkmEvaluationResult CreateEvaluationResult(string name, EvalResultDataItem parent, Formatter formatter) { var proxyType = _proxyValue.Type.GetLmrType(); string fullName; ReadOnlyCollection<string> formatSpecifiers; bool childShouldParenthesize; if (parent == null) { Debug.Assert(name != null); fullName = formatter.TrimAndGetFormatSpecifiers(name, out formatSpecifiers); childShouldParenthesize = formatter.NeedsParentheses(fullName); } else { fullName = parent.ChildFullNamePrefix; formatSpecifiers = parent.FormatSpecifiers; childShouldParenthesize = false; } var childFullNamePrefix = (fullName == null) ? null : formatter.GetObjectCreationExpression(formatter.GetTypeName(proxyType, escapeKeywordIdentifiers: true), fullName); var dataItem = new EvalResultDataItem( name: name, typeDeclaringMember: null, declaredType: proxyType, value: _proxyValue, expansion: _proxyMembers, childShouldParenthesize: childShouldParenthesize, fullName: fullName, childFullNamePrefixOpt: childFullNamePrefix, formatSpecifiers: Formatter.AddFormatSpecifier(formatSpecifiers, "results"), category: DkmEvaluationResultCategory.Method, flags: DkmEvaluationResultFlags.ReadOnly, editableValue: null); return ResultProvider.CreateEvaluationResult( value: _proxyValue, name: name, typeName: string.Empty, display: Resources.ResultsViewValueWarning, dataItem: dataItem); }
private DkmEvaluationResult CreateEvaluationResult(string name, EvalResultDataItem parent, Formatter formatter) { var proxyType = _proxyValue.Type.GetLmrType(); string fullName; ReadOnlyCollection <string> formatSpecifiers; bool childShouldParenthesize; if (parent == null) { Debug.Assert(name != null); fullName = formatter.TrimAndGetFormatSpecifiers(name, out formatSpecifiers); childShouldParenthesize = formatter.NeedsParentheses(fullName); } else { fullName = parent.ChildFullNamePrefix; formatSpecifiers = parent.FormatSpecifiers; childShouldParenthesize = false; } var childFullNamePrefix = (fullName == null) ? null : formatter.GetObjectCreationExpression(formatter.GetTypeName(proxyType, escapeKeywordIdentifiers: true), fullName); var dataItem = new EvalResultDataItem( name: name, typeDeclaringMember: null, declaredType: proxyType, value: _proxyValue, expansion: _proxyMembers, childShouldParenthesize: childShouldParenthesize, fullName: fullName, childFullNamePrefixOpt: childFullNamePrefix, formatSpecifiers: Formatter.AddFormatSpecifier(formatSpecifiers, "results"), category: DkmEvaluationResultCategory.Method, flags: DkmEvaluationResultFlags.ReadOnly, editableValue: null); return(ResultProvider.CreateEvaluationResult( value: _proxyValue, name: name, typeName: string.Empty, display: Resources.ResultsViewValueWarning, dataItem: dataItem)); }
private static string MakeFullName( Formatter formatter, string name, TypeAndCustomInfo typeDeclaringMemberAndInfo, bool memberAccessRequiresExplicitCast, bool memberIsStatic, EvalResultDataItem parent) { // If the parent is an exception thrown during evaluation, // there is no valid fullname expression for the child. if (parent.Value.EvalFlags.Includes(DkmEvaluationResultFlags.ExceptionThrown)) { return null; } var parentFullName = parent.ChildFullNamePrefix; if (parentFullName == null) { return null; } if (parent.ChildShouldParenthesize) { parentFullName = $"({parentFullName})"; } if (!typeDeclaringMemberAndInfo.Type.IsInterface) { string qualifier; if (memberIsStatic) { qualifier = formatter.GetTypeName(typeDeclaringMemberAndInfo, escapeKeywordIdentifiers: false); } else if (memberAccessRequiresExplicitCast) { var typeName = formatter.GetTypeName(typeDeclaringMemberAndInfo, escapeKeywordIdentifiers: true); qualifier = formatter.GetCastExpression( parentFullName, typeName, parenthesizeEntireExpression: true); } else { qualifier = parentFullName; } return $"{qualifier}.{name}"; } else { // NOTE: This should never interact with debugger proxy types: // 1) Interfaces cannot have debugger proxy types. // 2) Debugger proxy types cannot be interfaces. if (typeDeclaringMemberAndInfo.Type.Equals(parent.DeclaredTypeAndInfo.Type)) { var memberAccessTemplate = parent.ChildShouldParenthesize ? "({0}).{1}" : "{0}.{1}"; return string.Format(memberAccessTemplate, parent.ChildFullNamePrefix, name); } else { var interfaceName = formatter.GetTypeName(typeDeclaringMemberAndInfo, escapeKeywordIdentifiers: true); var memberAccessTemplate = parent.ChildShouldParenthesize ? "(({0})({1})).{2}" : "(({0}){1}).{2}"; return string.Format(memberAccessTemplate, interfaceName, parent.ChildFullNamePrefix, name); } } }
private EvalResultDataItem CreateDynamicViewRow(DkmInspectionContext inspectionContext, string name, EvalResultDataItem parent, Formatter formatter) { var proxyTypeAndInfo = new TypeAndCustomInfo(_proxyValue.Type); var isRootExpression = parent == null; Debug.Assert(isRootExpression != (name == Resources.DynamicView)); var fullName = (!isRootExpression) ? parent.ChildFullNamePrefix : name; var childFullNamePrefix = (fullName == null) ? null : formatter.GetObjectCreationExpression(formatter.GetTypeName(proxyTypeAndInfo, escapeKeywordIdentifiers: true), fullName); var formatSpecifiers = (!isRootExpression) ? parent.FormatSpecifiers : Formatter.NoFormatSpecifiers; return new EvalResultDataItem( ExpansionKind.DynamicView, name, typeDeclaringMemberAndInfo: default(TypeAndCustomInfo), declaredTypeAndInfo: proxyTypeAndInfo, parent: null, value: _proxyValue, displayValue: Resources.DynamicViewValueWarning, expansion: _proxyMembers, childShouldParenthesize: false, fullName: fullName, childFullNamePrefixOpt: childFullNamePrefix, formatSpecifiers: Formatter.AddFormatSpecifier(formatSpecifiers, DynamicFormatSpecifier), category: DkmEvaluationResultCategory.Method, flags: DkmEvaluationResultFlags.ReadOnly, editableValue: null, inspectionContext: inspectionContext); }
internal ResultProvider(Formatter formatter) { this.Formatter = formatter; }
private DebuggerTypeProxyExpansion( DkmClrValue proxyValue, string name, Type typeDeclaringMemberOpt, Type declaredType, DkmClrValue value, bool childShouldParenthesize, string fullName, string childFullNamePrefix, ReadOnlyCollection<string> formatSpecifiers, DkmEvaluationResultFlags flags, string editableValue, Formatter formatter) { Debug.Assert(proxyValue != null); var proxyType = proxyValue.Type.GetLmrType(); var proxyMembers = MemberExpansion.CreateExpansion( proxyType, proxyValue, ExpansionFlags.IncludeBaseMembers, TypeHelpers.IsPublic, formatter); if (proxyMembers != null) { var proxyMemberFullNamePrefix = (childFullNamePrefix == null) ? null : formatter.GetObjectCreationExpression(formatter.GetTypeName(proxyType, escapeKeywordIdentifiers: true), childFullNamePrefix); this.proxyItem = new EvalResultDataItem( name: null, typeDeclaringMember: null, declaredType: proxyType, value: proxyValue, expansion: proxyMembers, childShouldParenthesize: false, fullName: null, childFullNamePrefixOpt: proxyMemberFullNamePrefix, formatSpecifiers: Formatter.NoFormatSpecifiers, category: default(DkmEvaluationResultCategory), flags: default(DkmEvaluationResultFlags), editableValue: null); } this.name = name; this.typeDeclaringMemberOpt = typeDeclaringMemberOpt; _declaredType = declaredType; this.value = value; this.childShouldParenthesize = childShouldParenthesize; this.fullName = fullName; this.childFullNamePrefix = childFullNamePrefix; this.formatSpecifiers = formatSpecifiers; this.flags = flags; this.editableValue = editableValue; }