internal Field( TypeAndCustomInfo declaringTypeAndInfo, TypeAndCustomInfo fieldTypeAndInfo, FieldInfo fieldInfo, string name, Field parent, bool isRest ) { Debug.Assert(declaringTypeAndInfo.ClrType != null); Debug.Assert(fieldTypeAndInfo.ClrType != null); Debug.Assert(fieldInfo != null); Debug.Assert(name != null); Debug.Assert(declaringTypeAndInfo.Type.Equals(fieldInfo.DeclaringType)); Debug.Assert(fieldTypeAndInfo.Type.Equals(fieldInfo.FieldType)); Debug.Assert( parent == null || parent.FieldInfo.FieldType.Equals(fieldInfo.DeclaringType) ); DeclaringTypeAndInfo = declaringTypeAndInfo; FieldTypeAndInfo = fieldTypeAndInfo; FieldInfo = fieldInfo; Name = name; Parent = parent; IsRest = isRest; }
/// <returns>The qualified name (i.e. including containing types and namespaces) of a named, /// pointer, or array type.</returns> internal string GetTypeName(TypeAndCustomInfo typeAndInfo, bool escapeKeywordIdentifiers, out bool sawInvalidIdentifier) { var type = typeAndInfo.Type; if (type == null) { throw new ArgumentNullException(nameof(type)); } ReadOnlyCollection <byte> dynamicFlags = null; ReadOnlyCollection <string> tupleElementNames = null; var typeInfo = typeAndInfo.Info; if (typeInfo != null) { CustomTypeInfo.Decode(typeInfo.PayloadTypeId, typeInfo.Payload, out dynamicFlags, out tupleElementNames); } var dynamicFlagIndex = 0; var tupleElementIndex = 0; var pooled = PooledStringBuilder.GetInstance(); AppendQualifiedTypeName( pooled.Builder, type, dynamicFlags, ref dynamicFlagIndex, tupleElementNames, ref tupleElementIndex, escapeKeywordIdentifiers, out sawInvalidIdentifier); return(pooled.ToStringAndFree()); }
private static EvalResult GetRow( ResultProvider resultProvider, DkmInspectionContext inspectionContext, TypeAndCustomInfo declaredTypeAndInfo, DkmClrValue value, Expansion expansion) { var fullName = resultProvider.FullNameProvider.GetClrTypeName(inspectionContext, declaredTypeAndInfo.ClrType, declaredTypeAndInfo.Info); return(new EvalResult( ExpansionKind.StaticMembers, name: resultProvider.StaticMembersString, typeDeclaringMemberAndInfo: default(TypeAndCustomInfo), declaredTypeAndInfo: declaredTypeAndInfo, useDebuggerDisplay: false, value: value, displayValue: null, expansion: expansion, childShouldParenthesize: false, fullName: fullName, childFullNamePrefixOpt: fullName, formatSpecifiers: Formatter.NoFormatSpecifiers, category: DkmEvaluationResultCategory.Class, flags: DkmEvaluationResultFlags.ReadOnly, editableValue: null, inspectionContext: inspectionContext)); }
private EvalResult CreateDynamicViewRow(DkmInspectionContext inspectionContext, string name, EvalResultDataItem parent, IDkmClrFullNameProvider fullNameProvider) { var proxyTypeAndInfo = new TypeAndCustomInfo(_proxyValue.Type); var isRootExpression = parent == null; var fullName = isRootExpression ? name : parent.ChildFullNamePrefix; var childFullNamePrefix = (fullName == null) ? null : fullNameProvider.GetClrObjectCreationExpression( inspectionContext, proxyTypeAndInfo.ClrType, proxyTypeAndInfo.Info, new[] { fullName }); var formatSpecifiers = isRootExpression ? Formatter.NoFormatSpecifiers : parent.FormatSpecifiers; return(new EvalResult( ExpansionKind.DynamicView, name, typeDeclaringMemberAndInfo: default(TypeAndCustomInfo), declaredTypeAndInfo: proxyTypeAndInfo, useDebuggerDisplay: false, 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)); }
private EvalResultDataItem CreateResultsViewRow(DkmInspectionContext inspectionContext, EvalResultDataItem parent, Formatter formatter) { Debug.Assert(parent != null); var proxyTypeAndInfo = new TypeAndCustomInfo(_proxyValue.Type); var fullName = parent.ChildFullNamePrefix; var sawInvalidIdentifier = false; var childFullNamePrefix = (fullName == null) ? null : formatter.GetObjectCreationExpression(formatter.GetTypeName(proxyTypeAndInfo, escapeKeywordIdentifiers: true, sawInvalidIdentifier: out sawInvalidIdentifier), fullName); Debug.Assert(!sawInvalidIdentifier); // Expected proxy type name is "System.Linq.SystemCore_EnumerableDebugView". 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)); }
/// <returns>The qualified name (i.e. including containing types and namespaces) of a named, /// pointer, or array type.</returns> internal string GetTypeName(TypeAndCustomInfo typeAndInfo, bool escapeKeywordIdentifiers, out bool sawInvalidIdentifier) { var type = typeAndInfo.Type; if (type == null) { throw new ArgumentNullException(nameof(type)); } ReadOnlyCollection<byte> dynamicFlags = null; ReadOnlyCollection<string> tupleElementNames = null; var typeInfo = typeAndInfo.Info; if (typeInfo != null) { CustomTypeInfo.Decode(typeInfo.PayloadTypeId, typeInfo.Payload, out dynamicFlags, out tupleElementNames); } var dynamicFlagIndex = 0; var tupleElementIndex = 0; var pooled = PooledStringBuilder.GetInstance(); AppendQualifiedTypeName( pooled.Builder, type, dynamicFlags, ref dynamicFlagIndex, tupleElementNames, ref tupleElementIndex, escapeKeywordIdentifiers, out sawInvalidIdentifier); return pooled.ToStringAndFree(); }
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 ? name : parent.ChildFullNamePrefix; var sawInvalidIdentifier = false; var childFullNamePrefix = (fullName == null) ? null : formatter.GetObjectCreationExpression(formatter.GetTypeName(proxyTypeAndInfo, escapeKeywordIdentifiers: true, sawInvalidIdentifier: out sawInvalidIdentifier), fullName); Debug.Assert(!sawInvalidIdentifier); // Expected type name is "Microsoft.CSharp.RuntimeBinder.DynamicMetaObjectProviderDebugView". var formatSpecifiers = isRootExpression ? Formatter.NoFormatSpecifiers : parent.FormatSpecifiers; 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)); }
private EvalResult CreateResultsViewRow( DkmInspectionContext inspectionContext, string name, string fullName, ReadOnlyCollection <string> formatSpecifiers, TypeAndCustomInfo declaredTypeAndInfo, DkmClrValue value, bool includeResultsFormatSpecifier, IDkmClrFullNameProvider fullNameProvider) { if (includeResultsFormatSpecifier) { formatSpecifiers = Formatter.AddFormatSpecifier(formatSpecifiers, ResultsFormatSpecifier); } var childFullNamePrefix = fullNameProvider.GetClrObjectCreationExpression(inspectionContext, _proxyValue.Type, customTypeInfo: null, arguments: fullName); return(new EvalResult( ExpansionKind.Default, name, typeDeclaringMemberAndInfo: default(TypeAndCustomInfo), declaredTypeAndInfo: declaredTypeAndInfo, useDebuggerDisplay: false, 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 EvalResultDataItem GetRow( ResultProvider resultProvider, DkmInspectionContext inspectionContext, TypeAndCustomInfo declaredTypeAndInfo, DkmClrValue value, Expansion expansion) { var formatter = resultProvider.Formatter; var fullName = formatter.GetTypeName(declaredTypeAndInfo, escapeKeywordIdentifiers: true); return(new EvalResultDataItem( ExpansionKind.StaticMembers, name: formatter.StaticMembersString, typeDeclaringMemberAndInfo: default(TypeAndCustomInfo), declaredTypeAndInfo: declaredTypeAndInfo, parent: null, value: value, displayValue: null, expansion: expansion, childShouldParenthesize: false, fullName: fullName, childFullNamePrefixOpt: fullName, formatSpecifiers: Formatter.NoFormatSpecifiers, category: DkmEvaluationResultCategory.Class, flags: DkmEvaluationResultFlags.ReadOnly, editableValue: null, inspectionContext: inspectionContext)); }
private ArrayExpansion(TypeAndCustomInfo elementTypeAndInfo, ReadOnlyCollection<int> sizes, ReadOnlyCollection<int> lowerBounds, int count) { Debug.Assert(count > 0); _elementTypeAndInfo = elementTypeAndInfo; _divisors = CalculateDivisors(sizes); _lowerBounds = lowerBounds; _count = count; }
private static Expansion CreateRawView( ResultProvider resultProvider, DkmInspectionContext inspectionContext, TypeAndCustomInfo declaredTypeAndInfo, DkmClrValue value) { return(resultProvider.GetTypeExpansion(inspectionContext, declaredTypeAndInfo, value, ExpansionFlags.IncludeBaseMembers)); }
private ArrayExpansion(TypeAndCustomInfo elementTypeAndInfo, ReadOnlyCollection <int> sizes, ReadOnlyCollection <int> lowerBounds, int count) { Debug.Assert(count > 0); _elementTypeAndInfo = elementTypeAndInfo; _divisors = CalculateDivisors(sizes); _lowerBounds = lowerBounds; _count = count; }
internal static TupleExpansion CreateExpansion(DkmClrValue value, TypeAndCustomInfo declaredTypeAndInfo, int cardinality) { if (value.IsNull) { // No expansion. return(null); } return(new TupleExpansion(new TypeAndCustomInfo(value.Type, declaredTypeAndInfo.Info), cardinality)); }
internal static TupleExpansion CreateExpansion(DkmClrValue value, TypeAndCustomInfo declaredTypeAndInfo, int cardinality) { if (value.IsNull) { // No expansion. return null; } return new TupleExpansion(new TypeAndCustomInfo(value.Type, declaredTypeAndInfo.Info), cardinality); }
private static EvalResult GetRow( ResultProvider resultProvider, DkmInspectionContext inspectionContext, DkmClrValue pointer, TypeAndCustomInfo elementTypeAndInfo, EvalResultDataItem parent ) { var value = pointer.Dereference(inspectionContext); var wasExceptionThrown = value.EvalFlags.Includes( DkmEvaluationResultFlags.ExceptionThrown ); var expansion = wasExceptionThrown ? null : resultProvider.GetTypeExpansion( inspectionContext, elementTypeAndInfo, value, ExpansionFlags.None, supportsFavorites: false ); var parentFullName = parent.ChildFullNamePrefix; var fullName = parentFullName == null ? null : $"*{parentFullName}"; var editableValue = resultProvider.Formatter2.GetEditableValueString( value, inspectionContext, elementTypeAndInfo.Info ); // NB: Full name is based on the real (i.e. not DebuggerDisplay) name. This is a change from dev12, // which used the DebuggerDisplay name, causing surprising results in "Add Watch" scenarios. return(new EvalResult( ExpansionKind.PointerDereference, name: fullName ?? $"*{parent.Name}", typeDeclaringMemberAndInfo: default(TypeAndCustomInfo), declaredTypeAndInfo: elementTypeAndInfo, useDebuggerDisplay: false, value: value, displayValue: wasExceptionThrown ? string.Format(Resources.InvalidPointerDereference, fullName ?? parent.Name) : null, expansion: expansion, childShouldParenthesize: true, fullName: fullName, childFullNamePrefixOpt: fullName, formatSpecifiers: Formatter.NoFormatSpecifiers, category: DkmEvaluationResultCategory.Other, flags: DkmEvaluationResultFlags.None, editableValue: editableValue, inspectionContext: inspectionContext )); }
private static string GetQualifiedMemberName( DkmInspectionContext inspectionContext, TypeAndCustomInfo typeDeclaringMember, string memberName, IDkmClrFullNameProvider fullNameProvider) { var typeName = fullNameProvider.GetClrTypeName(inspectionContext, typeDeclaringMember.ClrType, typeDeclaringMember.Info) ?? inspectionContext.GetTypeName(typeDeclaringMember.ClrType, typeDeclaringMember.Info, Formatter.NoFormatSpecifiers); return(typeDeclaringMember.Type.IsInterface ? $"{typeName}.{memberName}" : $"{memberName} ({typeName})"); }
public EvalResult( ExpansionKind kind, string name, TypeAndCustomInfo typeDeclaringMemberAndInfo, TypeAndCustomInfo declaredTypeAndInfo, bool useDebuggerDisplay, DkmClrValue value, string displayValue, Expansion expansion, bool childShouldParenthesize, string fullName, string childFullNamePrefixOpt, ReadOnlyCollection <string> formatSpecifiers, DkmEvaluationResultCategory category, DkmEvaluationResultFlags flags, string editableValue, DkmInspectionContext inspectionContext, string displayName = null, string displayType = null, bool canFavorite = false, bool isFavorite = false ) { Debug.Assert(name != null); Debug.Assert(formatSpecifiers != null); Debug.Assert((flags & DkmEvaluationResultFlags.Expandable) == 0); m_rawFlags = flags; this.Kind = kind; this.Name = name; this.TypeDeclaringMemberAndInfo = typeDeclaringMemberAndInfo; this.DeclaredTypeAndInfo = declaredTypeAndInfo; this.UseDebuggerDisplay = useDebuggerDisplay; this.Value = value; this.DisplayValue = displayValue; this.ChildShouldParenthesize = childShouldParenthesize; this.FullNameWithoutFormatSpecifiers = fullName; this.ChildFullNamePrefix = childFullNamePrefixOpt; this.FormatSpecifiers = formatSpecifiers; this.Category = category; this.EditableValue = editableValue; this.Flags = flags | GetFlags(value, inspectionContext, expansion, canFavorite, isFavorite); this.Expansion = expansion; this.InspectionContext = inspectionContext; this.DisplayName = displayName; this.DisplayType = displayType; this.CanFavorite = canFavorite; this.IsFavorite = isFavorite; }
internal static CustomTypeInfoTypeArgumentMap Create(TypeAndCustomInfo typeAndInfo) { var typeInfo = typeAndInfo.Info; if (typeInfo == null) { return(s_empty); } var type = typeAndInfo.Type; Debug.Assert(type != null); if (!type.IsGenericType) { return(s_empty); } ReadOnlyCollection <byte> dynamicFlags; ReadOnlyCollection <string> tupleElementNames; CustomTypeInfo.Decode( typeInfo.PayloadTypeId, typeInfo.Payload, out dynamicFlags, out tupleElementNames ); if (dynamicFlags == null && tupleElementNames == null) { return(s_empty); } var typeDefinition = type.GetGenericTypeDefinition(); Debug.Assert(typeDefinition != null); var dynamicFlagStartIndices = (dynamicFlags == null) ? null : GetStartIndices(type, t => 1); var tupleElementNameStartIndices = (tupleElementNames == null) ? null : GetStartIndices(type, TypeHelpers.GetTupleCardinalityIfAny); return(new CustomTypeInfoTypeArgumentMap( typeDefinition, dynamicFlags, dynamicFlagStartIndices, tupleElementNames, tupleElementNameStartIndices )); }
/// <returns>The qualified name (i.e. including containing types and namespaces) of a named, /// pointer, or array type.</returns> internal string GetTypeName(TypeAndCustomInfo typeAndInfo, bool escapeKeywordIdentifiers, out bool sawInvalidIdentifier) { var type = typeAndInfo.Type; if (type == null) { throw new ArgumentNullException(nameof(type)); } var dynamicFlags = DynamicFlagsCustomTypeInfo.Create(typeAndInfo.Info); var index = 0; var pooled = PooledStringBuilder.GetInstance(); AppendQualifiedTypeName(pooled.Builder, type, dynamicFlags, ref index, escapeKeywordIdentifiers, out sawInvalidIdentifier); return pooled.ToStringAndFree(); }
internal static ArrayExpansion CreateExpansion(TypeAndCustomInfo elementTypeAndInfo, ReadOnlyCollection<int> sizes, ReadOnlyCollection<int> lowerBounds) { Debug.Assert(elementTypeAndInfo.Type != null); Debug.Assert(sizes != null); Debug.Assert(lowerBounds != null); Debug.Assert(sizes.Count > 0); Debug.Assert(sizes.Count == lowerBounds.Count); int count = 1; foreach (var size in sizes) { count *= size; } return (count > 0) ? new ArrayExpansion(elementTypeAndInfo, sizes, lowerBounds, count) : null; }
internal static TupleExpansion CreateExpansion( DkmInspectionContext inspectionContext, TypeAndCustomInfo declaredTypeAndInfo, DkmClrValue value, int cardinality) { if (value.IsNull) { // No expansion. return null; } bool useRawView = (inspectionContext.EvaluationFlags & DkmEvaluationFlags.ShowValueRaw) != 0; return new TupleExpansion(new TypeAndCustomInfo(value.Type, declaredTypeAndInfo.Info), cardinality, useRawView); }
private static string MakeFullName( IDkmClrFullNameProvider fullNameProvider, DkmInspectionContext inspectionContext, 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.Parenthesize(); } var typeDeclaringMember = typeDeclaringMemberAndInfo.Type; if (typeDeclaringMember.IsInterface) { memberAccessRequiresExplicitCast = !typeDeclaringMember.Equals( parent.DeclaredTypeAndInfo.Type ); } return(fullNameProvider.GetClrMemberName( inspectionContext, parentFullName, typeDeclaringMemberAndInfo.ClrType, typeDeclaringMemberAndInfo.Info, name, memberAccessRequiresExplicitCast, memberIsStatic )); }
internal TypeVariablesExpansion(TypeAndCustomInfo declaredTypeAndInfo) { var declaredType = declaredTypeAndInfo.Type; Debug.Assert(declaredType.IsGenericType); Debug.Assert(!declaredType.IsGenericTypeDefinition); _customTypeInfoMap = CustomTypeInfoTypeArgumentMap.Create(declaredTypeAndInfo); var typeDef = declaredType.GetGenericTypeDefinition(); _typeParameters = typeDef.GetGenericArguments(); _typeArguments = declaredType.GetGenericArguments(); Debug.Assert(_typeParameters.Length == _typeArguments.Length); Debug.Assert(Array.TrueForAll(_typeParameters, t => t.IsGenericParameter)); Debug.Assert(Array.TrueForAll(_typeArguments, t => !t.IsGenericParameter)); }
internal static TupleExpansion CreateExpansion( DkmInspectionContext inspectionContext, TypeAndCustomInfo declaredTypeAndInfo, DkmClrValue value, int cardinality) { if (value.IsNull) { // No expansion. return(null); } bool useRawView = (inspectionContext.EvaluationFlags & DkmEvaluationFlags.ShowValueRaw) != 0; return(new TupleExpansion(new TypeAndCustomInfo(value.Type, declaredTypeAndInfo.Info), cardinality, useRawView)); }
/// <returns>The qualified name (i.e. including containing types and namespaces) of a named, /// pointer, or array type.</returns> internal string GetTypeName(TypeAndCustomInfo typeAndInfo, bool escapeKeywordIdentifiers = false) { var type = typeAndInfo.Type; if (type == null) { throw new ArgumentNullException("type"); } var dynamicFlags = new DynamicFlagsCustomTypeInfo(typeAndInfo.Info); var index = 0; var pooled = PooledStringBuilder.GetInstance(); AppendQualifiedTypeName(pooled.Builder, type, dynamicFlags, ref index, escapeKeywordIdentifiers); return(pooled.ToStringAndFree()); }
internal static ArrayExpansion CreateExpansion(TypeAndCustomInfo elementTypeAndInfo, ReadOnlyCollection <int> sizes, ReadOnlyCollection <int> lowerBounds) { Debug.Assert(elementTypeAndInfo.Type != null); Debug.Assert(sizes != null); Debug.Assert(lowerBounds != null); Debug.Assert(sizes.Count > 0); Debug.Assert(sizes.Count == lowerBounds.Count); int count = 1; foreach (var size in sizes) { count *= size; } return((count > 0) ? new ArrayExpansion(elementTypeAndInfo, sizes, lowerBounds, count) : null); }
public EvalResultDataItem( string name, TypeAndCustomInfo declaredTypeAndInfo, DkmClrValue value, Expansion expansion, bool childShouldParenthesize, string fullNameWithoutFormatSpecifiers, string childFullNamePrefixOpt, ReadOnlyCollection <string> formatSpecifiers) { this.Name = name; this.DeclaredTypeAndInfo = declaredTypeAndInfo; this.Value = value; this.ChildShouldParenthesize = childShouldParenthesize; this.FullNameWithoutFormatSpecifiers = fullNameWithoutFormatSpecifiers; this.ChildFullNamePrefix = childFullNamePrefixOpt; this.FormatSpecifiers = formatSpecifiers; this.Expansion = expansion; }
public EvalResultDataItem( string name, TypeAndCustomInfo declaredTypeAndInfo, DkmClrValue value, Expansion expansion, bool childShouldParenthesize, string fullNameWithoutFormatSpecifiers, string childFullNamePrefixOpt, ReadOnlyCollection<string> formatSpecifiers) { this.Name = name; this.DeclaredTypeAndInfo = declaredTypeAndInfo; this.Value = value; this.ChildShouldParenthesize = childShouldParenthesize; this.FullNameWithoutFormatSpecifiers = fullNameWithoutFormatSpecifiers; this.ChildFullNamePrefix = childFullNamePrefixOpt; this.FormatSpecifiers = formatSpecifiers; this.Expansion = expansion; }
internal static DynamicFlagsMap Create(TypeAndCustomInfo typeAndInfo) { var type = typeAndInfo.Type; Debug.Assert(type != null); if (!type.IsGenericType) { return(s_empty); } var dynamicFlags = DynamicFlagsCustomTypeInfo.Create(typeAndInfo.Info); if (!dynamicFlags.Any()) { return(s_empty); } var typeDefinition = type.GetGenericTypeDefinition(); Debug.Assert(typeDefinition != null); var typeArgs = type.GetGenericArguments(); Debug.Assert(typeArgs.Length > 0); int pos = 1; // Consider "type" to have already been consumed. var startsBuilder = ArrayBuilder <int> .GetInstance(); foreach (var typeArg in typeArgs) { startsBuilder.Add(pos); foreach (Type curr in new TypeWalker(typeArg)) { pos++; } } Debug.Assert(pos > 1); startsBuilder.Add(pos); return(new DynamicFlagsMap(typeDefinition, dynamicFlags, startsBuilder.ToArrayAndFree())); }
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 sawInvalidIdentifier; var childFullNamePrefix = formatter.GetObjectCreationExpression(formatter.GetTypeName(proxyTypeAndInfo, escapeKeywordIdentifiers: true, sawInvalidIdentifier: out sawInvalidIdentifier), fullName); Debug.Assert(!sawInvalidIdentifier); // Expected proxy type name is "System.Linq.SystemCore_EnumerableDebugView". 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)); }
internal static DynamicFlagsMap Create(TypeAndCustomInfo typeAndInfo) { var type = typeAndInfo.Type; Debug.Assert(type != null); if (!type.IsGenericType) { return s_empty; } var dynamicFlags = DynamicFlagsCustomTypeInfo.Create(typeAndInfo.Info); if (!dynamicFlags.Any()) { return s_empty; } var typeDefinition = type.GetGenericTypeDefinition(); Debug.Assert(typeDefinition != null); var typeArgs = type.GetGenericArguments(); Debug.Assert(typeArgs.Length > 0); int pos = 1; // Consider "type" to have already been consumed. var startsBuilder = ArrayBuilder<int>.GetInstance(); foreach (var typeArg in typeArgs) { startsBuilder.Add(pos); foreach (Type curr in new TypeWalker(typeArg)) { pos++; } } Debug.Assert(pos > 1); startsBuilder.Add(pos); return new DynamicFlagsMap(typeDefinition, dynamicFlags, startsBuilder.ToArrayAndFree()); }
public EvalResultDataItem( ExpansionKind kind, string name, TypeAndCustomInfo typeDeclaringMemberAndInfo, TypeAndCustomInfo declaredTypeAndInfo, EvalResultDataItem parent, DkmClrValue value, string displayValue, Expansion expansion, bool childShouldParenthesize, string fullName, string childFullNamePrefixOpt, ReadOnlyCollection <string> formatSpecifiers, DkmEvaluationResultCategory category, DkmEvaluationResultFlags flags, string editableValue, DkmInspectionContext inspectionContext) { Debug.Assert(name != null); Debug.Assert(formatSpecifiers != null); Debug.Assert((flags & DkmEvaluationResultFlags.Expandable) == 0); this.Kind = kind; this.Name = name; this.TypeDeclaringMemberAndInfo = typeDeclaringMemberAndInfo; this.DeclaredTypeAndInfo = declaredTypeAndInfo; this.Parent = parent; this.Value = value; this.DisplayValue = displayValue; this.ChildShouldParenthesize = childShouldParenthesize; this.FullNameWithoutFormatSpecifiers = fullName; this.ChildFullNamePrefix = childFullNamePrefixOpt; this.FormatSpecifiers = formatSpecifiers; this.Category = category; this.EditableValue = editableValue; this.Flags = flags | GetFlags(value, inspectionContext) | ((expansion == null) ? DkmEvaluationResultFlags.None : DkmEvaluationResultFlags.Expandable); this.Expansion = expansion; }
private static EvalResultDataItem GetRow( ResultProvider resultProvider, DkmInspectionContext inspectionContext, DkmClrValue pointer, TypeAndCustomInfo elementTypeAndInfo, EvalResultDataItem parent) { var value = pointer.Dereference(inspectionContext); var wasExceptionThrown = value.EvalFlags.Includes(DkmEvaluationResultFlags.ExceptionThrown); var expansion = wasExceptionThrown ? null : resultProvider.GetTypeExpansion(inspectionContext, elementTypeAndInfo, value, ExpansionFlags.None); var parentFullName = parent.ChildFullNamePrefix; var fullName = parentFullName == null ? null : $"*{parentFullName}"; var editableValue = resultProvider.Formatter.GetEditableValue(value, inspectionContext); // NB: Full name is based on the real (i.e. not DebuggerDisplay) name. This is a change from dev12, // which used the DebuggerDisplay name, causing surprising results in "Add Watch" scenarios. return new EvalResultDataItem( ExpansionKind.PointerDereference, name: fullName ?? $"*{parent.Name}", typeDeclaringMemberAndInfo: default(TypeAndCustomInfo), declaredTypeAndInfo: elementTypeAndInfo, parent: null, value: value, displayValue: wasExceptionThrown ? string.Format(Resources.InvalidPointerDereference, fullName ?? parent.Name) : null, expansion: expansion, childShouldParenthesize: true, fullName: fullName, childFullNamePrefixOpt: fullName, formatSpecifiers: Formatter.NoFormatSpecifiers, category: DkmEvaluationResultCategory.Other, flags: DkmEvaluationResultFlags.None, editableValue: editableValue, inspectionContext: inspectionContext); }
internal static Expansion CreateExpansion( ResultProvider resultProvider, DkmInspectionContext inspectionContext, string name, TypeAndCustomInfo typeDeclaringMemberAndInfoOpt, TypeAndCustomInfo declaredTypeAndInfo, DkmClrValue value, bool childShouldParenthesize, string fullName, string childFullNamePrefix, ReadOnlyCollection <string> formatSpecifiers, DkmEvaluationResultFlags flags, string editableValue) { Debug.Assert((inspectionContext.EvaluationFlags & DkmEvaluationFlags.NoExpansion) == 0); // Note: The native EE uses the proxy type, even for // null instances, so statics on the proxy type are // displayed. That case is not supported currently. if (!value.IsNull) { var proxyType = value.Type.GetProxyType(); if (proxyType != null) { if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.ShowValueRaw) != 0) { var rawView = CreateRawView(resultProvider, inspectionContext, declaredTypeAndInfo, value); Debug.Assert(rawView != null); return(rawView); } DkmClrValue proxyValue; try { proxyValue = value.InstantiateProxyType(inspectionContext, proxyType); } catch { proxyValue = null; } if (proxyValue != null) { return(new DebuggerTypeProxyExpansion( inspectionContext, proxyValue, name, typeDeclaringMemberAndInfoOpt, declaredTypeAndInfo, value, childShouldParenthesize, fullName, childFullNamePrefix, formatSpecifiers, flags, editableValue, resultProvider)); } } } return(null); }
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); }
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); }
private EvalResult CreateResultsViewRow( DkmInspectionContext inspectionContext, string name, string fullName, ReadOnlyCollection<string> formatSpecifiers, TypeAndCustomInfo declaredTypeAndInfo, DkmClrValue value, bool includeResultsFormatSpecifier, IDkmClrFullNameProvider fullNameProvider) { if (includeResultsFormatSpecifier) { formatSpecifiers = Formatter.AddFormatSpecifier(formatSpecifiers, ResultsFormatSpecifier); } var childFullNamePrefix = fullNameProvider.GetClrObjectCreationExpression(inspectionContext, _proxyValue.Type, customTypeInfo: null, arguments: fullName); return new EvalResult( ExpansionKind.Default, name, typeDeclaringMemberAndInfo: default(TypeAndCustomInfo), declaredTypeAndInfo: declaredTypeAndInfo, useDebuggerDisplay: false, 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 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); }
public PointerDereferenceExpansion(TypeAndCustomInfo elementTypeAndInfo) { Debug.Assert(elementTypeAndInfo.Type != null); _elementTypeAndInfo = elementTypeAndInfo; }
private static string GetQualifiedMemberName( DkmInspectionContext inspectionContext, TypeAndCustomInfo typeDeclaringMember, string memberName, IDkmClrFullNameProvider fullNameProvider) { var typeName = fullNameProvider.GetClrTypeName(inspectionContext, typeDeclaringMember.ClrType, typeDeclaringMember.Info) ?? inspectionContext.GetTypeName(typeDeclaringMember.ClrType, typeDeclaringMember.Info, Formatter.NoFormatSpecifiers); return typeDeclaringMember.Type.IsInterface ? $"{typeName}.{memberName}" : $"{memberName} ({typeName})"; }
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); }
private static EvalResultDataItem GetRow( ResultProvider resultProvider, DkmInspectionContext inspectionContext, TypeAndCustomInfo declaredTypeAndInfo, DkmClrValue value, Expansion expansion) { var formatter = resultProvider.Formatter; var fullName = formatter.GetTypeName(declaredTypeAndInfo, escapeKeywordIdentifiers: true); return new EvalResultDataItem( ExpansionKind.StaticMembers, name: formatter.StaticMembersString, typeDeclaringMemberAndInfo: default(TypeAndCustomInfo), declaredTypeAndInfo: declaredTypeAndInfo, parent: null, value: value, displayValue: null, expansion: expansion, childShouldParenthesize: false, fullName: fullName, childFullNamePrefixOpt: fullName, formatSpecifiers: Formatter.NoFormatSpecifiers, category: DkmEvaluationResultCategory.Class, flags: DkmEvaluationResultFlags.ReadOnly, editableValue: null, inspectionContext: inspectionContext); }
private void GetRootResultAndContinue( DkmClrValue value, WorkList workList, DkmClrType declaredType, DkmClrCustomTypeInfo declaredTypeInfo, DkmInspectionContext inspectionContext, string name, string fullName, ReadOnlyCollection <string> formatSpecifiers, CompletionRoutine <DkmEvaluationResult> completionRoutine) { Debug.Assert(formatSpecifiers != null); var type = value.Type.GetLmrType(); if (type.IsTypeVariables()) { Debug.Assert(type.Equals(declaredType.GetLmrType())); var declaredTypeAndInfo = new TypeAndCustomInfo(declaredType, declaredTypeInfo); var expansion = new TypeVariablesExpansion(declaredTypeAndInfo); var dataItem = new EvalResult( ExpansionKind.Default, name, typeDeclaringMemberAndInfo: default(TypeAndCustomInfo), declaredTypeAndInfo: declaredTypeAndInfo, useDebuggerDisplay: false, value: value, displayValue: null, expansion: expansion, childShouldParenthesize: false, fullName: null, childFullNamePrefixOpt: null, formatSpecifiers: Formatter.NoFormatSpecifiers, category: DkmEvaluationResultCategory.Data, flags: DkmEvaluationResultFlags.ReadOnly, editableValue: null, inspectionContext: inspectionContext); Debug.Assert(dataItem.Flags == (DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.Expandable)); // Note: We're not including value.EvalFlags in Flags parameter // below (there shouldn't be a reason to do so). completionRoutine(DkmSuccessEvaluationResult.Create( InspectionContext: inspectionContext, StackFrame: value.StackFrame, Name: Resources.TypeVariablesName, FullName: dataItem.FullName, Flags: dataItem.Flags, Value: "", EditableValue: null, Type: "", Category: dataItem.Category, Access: value.Access, StorageType: value.StorageType, TypeModifierFlags: value.TypeModifierFlags, Address: value.Address, CustomUIVisualizers: null, ExternalModules: null, DataItem: dataItem.ToDataItem())); } else if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.ResultsOnly) != 0) { var dataItem = ResultsViewExpansion.CreateResultsOnlyRow( inspectionContext, name, fullName, formatSpecifiers, declaredType, declaredTypeInfo, value, this); CreateEvaluationResultAndContinue( dataItem, workList, inspectionContext, value.StackFrame, completionRoutine); } else if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.DynamicView) != 0) { var dataItem = DynamicViewExpansion.CreateMembersOnlyRow( inspectionContext, name, value, this); CreateEvaluationResultAndContinue( dataItem, workList, inspectionContext, value.StackFrame, completionRoutine); } else { var dataItem = ResultsViewExpansion.CreateResultsOnlyRowIfSynthesizedEnumerable( inspectionContext, name, fullName, formatSpecifiers, declaredType, declaredTypeInfo, value, this); if (dataItem != null) { CreateEvaluationResultAndContinue( dataItem, workList, inspectionContext, value.StackFrame, completionRoutine); } else { var useDebuggerDisplay = (inspectionContext.EvaluationFlags & NotRoot) != 0; var expansionFlags = (inspectionContext.EvaluationFlags & NoResults) != 0 ? ExpansionFlags.IncludeBaseMembers : ExpansionFlags.All; dataItem = CreateDataItem( inspectionContext, name, typeDeclaringMemberAndInfo: default(TypeAndCustomInfo), declaredTypeAndInfo: new TypeAndCustomInfo(declaredType, declaredTypeInfo), value: value, useDebuggerDisplay: useDebuggerDisplay, expansionFlags: expansionFlags, childShouldParenthesize: (fullName == null) ? false : FullNameProvider.ClrExpressionMayRequireParentheses(inspectionContext, fullName), fullName: fullName, formatSpecifiers: formatSpecifiers, category: DkmEvaluationResultCategory.Other, flags: value.EvalFlags, evalFlags: inspectionContext.EvaluationFlags); GetResultAndContinue(dataItem, workList, declaredType, declaredTypeInfo, inspectionContext, useDebuggerDisplay, completionRoutine); } } }
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); }
private static EvalResult GetRow( ResultProvider resultProvider, DkmInspectionContext inspectionContext, TypeAndCustomInfo declaredTypeAndInfo, DkmClrValue value, Expansion expansion) { var fullName = resultProvider.FullNameProvider.GetClrTypeName(inspectionContext, declaredTypeAndInfo.ClrType, declaredTypeAndInfo.Info); return new EvalResult( ExpansionKind.StaticMembers, name: resultProvider.StaticMembersString, typeDeclaringMemberAndInfo: default(TypeAndCustomInfo), declaredTypeAndInfo: declaredTypeAndInfo, useDebuggerDisplay: false, value: value, displayValue: null, expansion: expansion, childShouldParenthesize: false, fullName: fullName, childFullNamePrefixOpt: fullName, formatSpecifiers: Formatter.NoFormatSpecifiers, category: DkmEvaluationResultCategory.Class, flags: DkmEvaluationResultFlags.ReadOnly, editableValue: null, inspectionContext: inspectionContext); }
internal Field( TypeAndCustomInfo declaringTypeAndInfo, TypeAndCustomInfo fieldTypeAndInfo, FieldInfo fieldInfo, string name, Field parent, bool isRest) { Debug.Assert(declaringTypeAndInfo.ClrType != null); Debug.Assert(fieldTypeAndInfo.ClrType != null); Debug.Assert(fieldInfo != null); Debug.Assert(name != null); Debug.Assert(declaringTypeAndInfo.Type.Equals(fieldInfo.DeclaringType)); Debug.Assert(fieldTypeAndInfo.Type.Equals(fieldInfo.FieldType)); Debug.Assert(parent == null || parent.FieldInfo.FieldType.Equals(fieldInfo.DeclaringType)); DeclaringTypeAndInfo = declaringTypeAndInfo; FieldTypeAndInfo = fieldTypeAndInfo; FieldInfo = fieldInfo; Name = name; Parent = parent; IsRest = isRest; }
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; }
private static Fields GetFields(TypeAndCustomInfo declaringTypeAndInfo, int cardinality, bool useRawView) { Debug.Assert(declaringTypeAndInfo.Type.GetTupleCardinalityIfAny() == cardinality); var appDomain = declaringTypeAndInfo.ClrType.AppDomain; var customTypeInfoMap = CustomTypeInfoTypeArgumentMap.Create(declaringTypeAndInfo); var tupleElementNames = customTypeInfoMap.TupleElementNames; var builder = ArrayBuilder<Field>.GetInstance(); Field parent = null; int offset = 0; bool includeRawView = false; while (true) { var declaringType = declaringTypeAndInfo.Type; int n = Math.Min(cardinality, TypeHelpers.TupleFieldRestPosition - 1); for (int index = 0; index < n; index++) { var fieldName = TypeHelpers.GetTupleFieldName(index); var field = declaringType.GetTupleField(fieldName); if (field == null) { // Ignore missing fields. continue; } var fieldTypeAndInfo = GetTupleFieldTypeAndInfo(appDomain, field, customTypeInfoMap); if (!useRawView) { var name = CustomTypeInfo.GetTupleElementNameIfAny(tupleElementNames, offset + index); if (name != null) { includeRawView = true; builder.Add(new Field(declaringTypeAndInfo, fieldTypeAndInfo, field, name, parent, isRest: false)); continue; } } builder.Add(new Field( declaringTypeAndInfo, fieldTypeAndInfo, field, (offset == 0) ? fieldName : TypeHelpers.GetTupleFieldName(offset + index), parent, isRest: false)); } cardinality -= n; if (cardinality == 0) { break; } var rest = declaringType.GetTupleField(TypeHelpers.TupleFieldRestName); if (rest == null) { // Ignore remaining fields. break; } var restTypeAndInfo = GetTupleFieldTypeAndInfo(appDomain, rest, customTypeInfoMap); var restField = new Field(declaringTypeAndInfo, restTypeAndInfo, rest, TypeHelpers.TupleFieldRestName, parent, isRest: true); if (useRawView) { builder.Add(restField); break; } includeRawView = true; parent = restField; declaringTypeAndInfo = restTypeAndInfo; offset += TypeHelpers.TupleFieldRestPosition - 1; } return new Fields(builder.ToImmutableAndFree(), includeRawView); }
private TupleExpansion(TypeAndCustomInfo typeAndInfo, int cardinality, bool useRawView) { _typeAndInfo = typeAndInfo; _cardinality = cardinality; _useRawView = useRawView; }
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, ResultProvider resultProvider) { Debug.Assert(proxyValue != null); var proxyType = proxyValue.Type; var proxyTypeAndInfo = new TypeAndCustomInfo(proxyType); var proxyMembers = MemberExpansion.CreateExpansion( inspectionContext, proxyTypeAndInfo, proxyValue, ExpansionFlags.IncludeBaseMembers, TypeHelpers.IsPublic, resultProvider, isProxyType: true); if (proxyMembers != null) { string proxyMemberFullNamePrefix = null; if (childFullNamePrefix != null) { proxyMemberFullNamePrefix = resultProvider.FullNameProvider.GetClrObjectCreationExpression( inspectionContext, proxyTypeAndInfo.ClrType, proxyTypeAndInfo.Info, new[] { childFullNamePrefix }); } _proxyItem = new EvalResult( ExpansionKind.Default, name: string.Empty, typeDeclaringMemberAndInfo: default(TypeAndCustomInfo), declaredTypeAndInfo: proxyTypeAndInfo, useDebuggerDisplay: false, 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 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)); }
private void GetRootResultAndContinue( DkmClrValue value, WorkList workList, DkmClrType declaredType, DkmClrCustomTypeInfo declaredTypeInfo, DkmInspectionContext inspectionContext, string name, CompletionRoutine<DkmEvaluationResult> completionRoutine) { var type = value.Type.GetLmrType(); if (type.IsTypeVariables()) { Debug.Assert(type.Equals(declaredType.GetLmrType())); var declaredTypeAndInfo = new TypeAndCustomInfo(type, declaredTypeInfo); var expansion = new TypeVariablesExpansion(declaredTypeAndInfo); var dataItem = new EvalResultDataItem( ExpansionKind.Default, name, typeDeclaringMemberAndInfo: default(TypeAndCustomInfo), declaredTypeAndInfo: declaredTypeAndInfo, parent: null, value: value, displayValue: null, expansion: expansion, childShouldParenthesize: false, fullName: null, childFullNamePrefixOpt: null, formatSpecifiers: Formatter.NoFormatSpecifiers, category: DkmEvaluationResultCategory.Data, flags: DkmEvaluationResultFlags.ReadOnly, editableValue: null, inspectionContext: inspectionContext); Debug.Assert(dataItem.Flags == (DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.Expandable)); // Note: We're not including value.EvalFlags in Flags parameter // below (there shouldn't be a reason to do so). completionRoutine(DkmSuccessEvaluationResult.Create( InspectionContext: inspectionContext, StackFrame: value.StackFrame, Name: Resources.TypeVariablesName, FullName: dataItem.FullName, Flags: dataItem.Flags, Value: "", EditableValue: null, Type: "", Category: dataItem.Category, Access: value.Access, StorageType: value.StorageType, TypeModifierFlags: value.TypeModifierFlags, Address: value.Address, CustomUIVisualizers: null, ExternalModules: null, DataItem: dataItem)); } else if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.ResultsOnly) != 0) { var dataItem = ResultsViewExpansion.CreateResultsOnlyRow( inspectionContext, name, declaredType, declaredTypeInfo, value, this.Formatter); CreateEvaluationResultAndContinue( dataItem, workList, inspectionContext, value.StackFrame, completionRoutine); } else if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.DynamicView) != 0) { var dataItem = DynamicViewExpansion.CreateMembersOnlyRow( inspectionContext, name, value, this.Formatter); CreateEvaluationResultAndContinue( dataItem, workList, inspectionContext, value.StackFrame, completionRoutine); } else { var dataItem = ResultsViewExpansion.CreateResultsOnlyRowIfSynthesizedEnumerable( inspectionContext, name, declaredType, declaredTypeInfo, value, this.Formatter); if (dataItem != null) { CreateEvaluationResultAndContinue( dataItem, workList, inspectionContext, value.StackFrame, completionRoutine); } else { ReadOnlyCollection<string> formatSpecifiers; var fullName = this.Formatter.TrimAndGetFormatSpecifiers(name, out formatSpecifiers); dataItem = CreateDataItem( inspectionContext, name, typeDeclaringMemberAndInfo: default(TypeAndCustomInfo), declaredTypeAndInfo: new TypeAndCustomInfo(declaredType.GetLmrType(), declaredTypeInfo), value: value, parent: null, expansionFlags: ExpansionFlags.All, childShouldParenthesize: this.Formatter.NeedsParentheses(fullName), fullName: fullName, formatSpecifiers: formatSpecifiers, category: DkmEvaluationResultCategory.Other, flags: value.EvalFlags, evalFlags: inspectionContext.EvaluationFlags); GetResultAndContinue(dataItem, workList, declaredType, declaredTypeInfo, inspectionContext, parent: null, completionRoutine: completionRoutine); } } }
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); }
private static string MakeFullName( IDkmClrFullNameProvider fullNameProvider, DkmInspectionContext inspectionContext, 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.Parenthesize(); } var typeDeclaringMember = typeDeclaringMemberAndInfo.Type; if (typeDeclaringMember.IsInterface) { memberAccessRequiresExplicitCast = !typeDeclaringMember.Equals(parent.DeclaredTypeAndInfo.Type); } return fullNameProvider.GetClrMemberName( inspectionContext, parentFullName, typeDeclaringMemberAndInfo.ClrType, typeDeclaringMemberAndInfo.Info, name, memberAccessRequiresExplicitCast, memberIsStatic); }
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 EvalResult CreateDynamicViewRow(DkmInspectionContext inspectionContext, string name, EvalResultDataItem parent, IDkmClrFullNameProvider fullNameProvider) { var proxyTypeAndInfo = new TypeAndCustomInfo(_proxyValue.Type); var isRootExpression = parent == null; var fullName = isRootExpression ? name : parent.ChildFullNamePrefix; var childFullNamePrefix = (fullName == null) ? null : fullNameProvider.GetClrObjectCreationExpression(inspectionContext, proxyTypeAndInfo.ClrType, proxyTypeAndInfo.Info, fullName); var formatSpecifiers = isRootExpression ? Formatter.NoFormatSpecifiers : parent.FormatSpecifiers; return new EvalResult( ExpansionKind.DynamicView, name, typeDeclaringMemberAndInfo: default(TypeAndCustomInfo), declaredTypeAndInfo: proxyTypeAndInfo, useDebuggerDisplay: false, 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); }
public EvalResultDataItem( ExpansionKind kind, string name, TypeAndCustomInfo typeDeclaringMemberAndInfo, TypeAndCustomInfo declaredTypeAndInfo, EvalResultDataItem parent, DkmClrValue value, string displayValue, Expansion expansion, bool childShouldParenthesize, string fullName, string childFullNamePrefixOpt, ReadOnlyCollection<string> formatSpecifiers, DkmEvaluationResultCategory category, DkmEvaluationResultFlags flags, string editableValue, DkmInspectionContext inspectionContext) { Debug.Assert(name != null); Debug.Assert(formatSpecifiers != null); Debug.Assert((flags & DkmEvaluationResultFlags.Expandable) == 0); this.Kind = kind; this.Name = name; this.TypeDeclaringMemberAndInfo = typeDeclaringMemberAndInfo; this.DeclaredTypeAndInfo = declaredTypeAndInfo; this.Parent = parent; this.Value = value; this.DisplayValue = displayValue; this.ChildShouldParenthesize = childShouldParenthesize; this.FullNameWithoutFormatSpecifiers = fullName; this.ChildFullNamePrefix = childFullNamePrefixOpt; this.FormatSpecifiers = formatSpecifiers; this.Category = category; this.EditableValue = editableValue; this.Flags = flags | GetFlags(value, inspectionContext) | ((expansion == null) ? DkmEvaluationResultFlags.None : DkmEvaluationResultFlags.Expandable); this.Expansion = expansion; }
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; }