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 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); } } }