private void GetResultAndContinue( EvalResult result, WorkList workList, DkmClrType declaredType, DkmClrCustomTypeInfo declaredTypeInfo, DkmInspectionContext inspectionContext, bool useDebuggerDisplay, CompletionRoutine <DkmEvaluationResult> completionRoutine) { var value = result.Value; // Value may have been replaced (specifically, for Nullable<T>). DebuggerDisplayInfo displayInfo; if (value.TryGetDebuggerDisplayInfo(out displayInfo)) { var targetType = displayInfo.TargetType; var attribute = displayInfo.Attribute; CompletionRoutine <Exception> onException = e => completionRoutine(CreateEvaluationResultFromException(e, result, inspectionContext)); var innerWorkList = workList.InnerWorkList; EvaluateDebuggerDisplayStringAndContinue(value, innerWorkList, inspectionContext, targetType, attribute.Name, displayName => EvaluateDebuggerDisplayStringAndContinue(value, innerWorkList, inspectionContext, targetType, attribute.Value, displayValue => EvaluateDebuggerDisplayStringAndContinue(value, innerWorkList, inspectionContext, targetType, attribute.TypeName, displayType => workList.ContinueWith(() => completionRoutine(GetResult(inspectionContext, result, declaredType, declaredTypeInfo, displayName.Result, displayValue.Result, displayType.Result, useDebuggerDisplay))), onException), onException), onException); } else { completionRoutine(GetResult(inspectionContext, result, declaredType, declaredTypeInfo, displayName: null, displayValue: null, displayType: null, useDebuggerDisplay: false)); } }
private void GetChild( DkmEvaluationResult parent, WorkList workList, EvalResult row, DkmCompletionRoutine <DkmEvaluationAsyncResult> completionRoutine) { var inspectionContext = row.InspectionContext; if ((row.Kind != ExpansionKind.Default) || (row.Value == null)) { CreateEvaluationResultAndContinue( row, workList, row.InspectionContext, parent.StackFrame, child => completionRoutine(new DkmEvaluationAsyncResult(child))); } else { var typeDeclaringMember = row.TypeDeclaringMemberAndInfo; var name = (typeDeclaringMember.Type == null) ? row.Name : GetQualifiedMemberName(row.InspectionContext, typeDeclaringMember, row.Name, FullNameProvider); row.Value.GetResult( workList.InnerWorkList, row.DeclaredTypeAndInfo.ClrType, row.DeclaredTypeAndInfo.Info, row.InspectionContext, Formatter.NoFormatSpecifiers, name, row.FullName, result => workList.ContinueWith(() => completionRoutine(result))); } }
private static DkmEvaluationResult CreateEvaluationResult( DkmInspectionContext inspectionContext, DkmClrValue value, string name, string typeName, string display, EvalResult result) { if (value.IsError()) { // Evaluation failed return(DkmFailedEvaluationResult.Create( InspectionContext: inspectionContext, StackFrame: value.StackFrame, Name: name, FullName: result.FullName, ErrorMessage: display, Flags: result.Flags, Type: typeName, DataItem: result.ToDataItem())); } else { ReadOnlyCollection <DkmCustomUIVisualizerInfo> customUIVisualizers = null; if (!value.IsNull) { DkmCustomUIVisualizerInfo[] customUIVisualizerInfo = value.Type.GetDebuggerCustomUIVisualizerInfo(); if (customUIVisualizerInfo != null) { customUIVisualizers = new ReadOnlyCollection <DkmCustomUIVisualizerInfo>(customUIVisualizerInfo); } } // If the EvalResultDataItem doesn't specify a particular category, we'll just propagate DkmClrValue.Category, // which typically appears to be set to the default value ("Other"). var category = (result.Category != DkmEvaluationResultCategory.Other) ? result.Category : value.Category; // Valid value return(DkmSuccessEvaluationResult.Create( InspectionContext: inspectionContext, StackFrame: value.StackFrame, Name: name, FullName: result.FullName, Flags: result.Flags, Value: display, EditableValue: result.EditableValue, Type: typeName, Category: category, Access: value.Access, StorageType: value.StorageType, TypeModifierFlags: value.TypeModifierFlags, Address: value.Address, CustomUIVisualizers: customUIVisualizers, ExternalModules: null, DataItem: result.ToDataItem())); } }
private DkmEvaluationResult GetResult( DkmInspectionContext inspectionContext, EvalResult result, DkmClrType declaredType, DkmClrCustomTypeInfo declaredTypeInfo, string displayName, string displayValue, string displayType, bool useDebuggerDisplay) { var name = result.Name; Debug.Assert(name != null); var typeDeclaringMemberAndInfo = result.TypeDeclaringMemberAndInfo; // Note: Don't respect the debugger display name on the root element: // 1) In the Watch window, that's where the user's text goes. // 2) In the Locals window, that's where the local name goes. // Note: Dev12 respects the debugger display name in the Locals window, // but not in the Watch window, but we can't distinguish and this // behavior seems reasonable. if (displayName != null && useDebuggerDisplay) { name = displayName; } else if (typeDeclaringMemberAndInfo.Type != null) { name = GetQualifiedMemberName(inspectionContext, typeDeclaringMemberAndInfo, name, FullNameProvider); } var value = result.Value; string display; if (value.HasExceptionThrown()) { display = result.DisplayValue ?? value.GetExceptionMessage(inspectionContext, result.FullNameWithoutFormatSpecifiers ?? result.Name); } else if (displayValue != null) { display = value.IncludeObjectId(displayValue); } else { display = value.GetValueString(inspectionContext, Formatter.NoFormatSpecifiers); } var typeName = displayType ?? GetTypeName(inspectionContext, value, declaredType, declaredTypeInfo, result.Kind); return(CreateEvaluationResult(inspectionContext, value, name, typeName, display, result)); }
internal override void GetRows( ResultProvider resultProvider, ArrayBuilder <EvalResult> rows, DkmInspectionContext inspectionContext, EvalResultDataItem parent, DkmClrValue value, int startIndex, int count, bool visitAll, ref int index) { var memberValue = value.GetMemberValue(_member, inspectionContext); var isDynamicDebugViewEmptyException = memberValue.Type.GetLmrType().IsDynamicDebugViewEmptyException(); if (isDynamicDebugViewEmptyException || memberValue.IsError()) { if (InRange(startIndex, count, index)) { if (isDynamicDebugViewEmptyException) { var emptyMember = memberValue.Type.GetMemberByName("Empty"); memberValue = memberValue.GetMemberValue(emptyMember, inspectionContext); } var row = new EvalResult(Resources.ErrorName, (string)memberValue.HostObjectValue, inspectionContext); rows.Add(row); } index++; } else { var other = MemberExpansion.CreateMemberDataItem( resultProvider, inspectionContext, _member, memberValue, parent, _customTypeInfoMap, ExpansionFlags.IncludeBaseMembers | ExpansionFlags.IncludeResultsView, supportsFavorites: false); var expansion = other.Expansion; if (expansion != null) { expansion.GetRows(resultProvider, rows, inspectionContext, other.ToDataItem(), other.Value, startIndex, count, visitAll, ref index); } } }
internal override void GetRows( ResultProvider resultProvider, ArrayBuilder<EvalResult> rows, DkmInspectionContext inspectionContext, EvalResultDataItem parent, DkmClrValue value, int startIndex, int count, bool visitAll, ref int index) { var memberValue = value.GetMemberValue(_member, inspectionContext); var isDynamicDebugViewEmptyException = memberValue.Type.GetLmrType().IsDynamicDebugViewEmptyException(); if (isDynamicDebugViewEmptyException || memberValue.IsError()) { if (InRange(startIndex, count, index)) { if (isDynamicDebugViewEmptyException) { var emptyMember = memberValue.Type.GetMemberByName("Empty"); memberValue = memberValue.GetMemberValue(emptyMember, inspectionContext); } var row = new EvalResult(Resources.ErrorName, (string)memberValue.HostObjectValue, inspectionContext); rows.Add(row); } index++; } else { var other = MemberExpansion.CreateMemberDataItem( resultProvider, inspectionContext, _member, memberValue, parent, _dynamicFlagsMap, ExpansionFlags.IncludeBaseMembers | ExpansionFlags.IncludeResultsView); var expansion = other.Expansion; if (expansion != null) { expansion.GetRows(resultProvider, rows, inspectionContext, other.ToDataItem(), other.Value, startIndex, count, visitAll, ref index); } } }
private static DkmEvaluationResult CreateEvaluationResultFromException(Exception e, EvalResult result, DkmInspectionContext inspectionContext) { return(DkmFailedEvaluationResult.Create( inspectionContext, result.Value.StackFrame, Name: result.Name, FullName: null, ErrorMessage: e.Message, Flags: DkmEvaluationResultFlags.None, Type: null, DataItem: null)); }
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); } } }
private void CreateEvaluationResultAndContinue(EvalResult result, WorkList workList, DkmInspectionContext inspectionContext, DkmStackWalkFrame stackFrame, CompletionRoutine <DkmEvaluationResult> completionRoutine) { switch (result.Kind) { case ExpansionKind.Error: completionRoutine(DkmFailedEvaluationResult.Create( inspectionContext, StackFrame: stackFrame, Name: result.Name, FullName: result.FullName, ErrorMessage: result.DisplayValue, Flags: DkmEvaluationResultFlags.None, Type: null, DataItem: null)); break; case ExpansionKind.NativeView: { var value = result.Value; var name = Resources.NativeView; var fullName = result.FullName; var display = result.Name; DkmEvaluationResult evalResult; if (value.IsError()) { evalResult = DkmFailedEvaluationResult.Create( inspectionContext, stackFrame, Name: name, FullName: fullName, ErrorMessage: display, Flags: result.Flags, Type: null, DataItem: result.ToDataItem()); } else { // For Native View, create a DkmIntermediateEvaluationResult. // This will allow the C++ EE to take over expansion. var process = inspectionContext.RuntimeInstance.Process; var cpp = process.EngineSettings.GetLanguage(new DkmCompilerId(DkmVendorId.Microsoft, DkmLanguageId.Cpp)); evalResult = DkmIntermediateEvaluationResult.Create( inspectionContext, stackFrame, Name: name, FullName: fullName, Expression: display, IntermediateLanguage: cpp, TargetRuntime: process.GetNativeRuntimeInstance(), DataItem: result.ToDataItem()); } completionRoutine(evalResult); } break; case ExpansionKind.NonPublicMembers: completionRoutine(DkmSuccessEvaluationResult.Create( inspectionContext, stackFrame, Name: Resources.NonPublicMembers, FullName: result.FullName, Flags: result.Flags, Value: null, EditableValue: null, Type: string.Empty, Category: DkmEvaluationResultCategory.Data, Access: DkmEvaluationResultAccessType.None, StorageType: DkmEvaluationResultStorageType.None, TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None, Address: result.Value.Address, CustomUIVisualizers: null, ExternalModules: null, DataItem: result.ToDataItem())); break; case ExpansionKind.StaticMembers: completionRoutine(DkmSuccessEvaluationResult.Create( inspectionContext, stackFrame, Name: StaticMembersString, FullName: result.FullName, Flags: result.Flags, Value: null, EditableValue: null, Type: string.Empty, Category: DkmEvaluationResultCategory.Class, Access: DkmEvaluationResultAccessType.None, StorageType: DkmEvaluationResultStorageType.None, TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None, Address: result.Value.Address, CustomUIVisualizers: null, ExternalModules: null, DataItem: result.ToDataItem())); break; case ExpansionKind.RawView: completionRoutine(DkmSuccessEvaluationResult.Create( inspectionContext, stackFrame, Name: Resources.RawView, FullName: result.FullName, Flags: result.Flags, Value: null, EditableValue: result.EditableValue, Type: string.Empty, Category: DkmEvaluationResultCategory.Data, Access: DkmEvaluationResultAccessType.None, StorageType: DkmEvaluationResultStorageType.None, TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None, Address: result.Value.Address, CustomUIVisualizers: null, ExternalModules: null, DataItem: result.ToDataItem())); break; case ExpansionKind.DynamicView: case ExpansionKind.ResultsView: completionRoutine(DkmSuccessEvaluationResult.Create( inspectionContext, stackFrame, result.Name, result.FullName, result.Flags, result.DisplayValue, EditableValue: null, Type: string.Empty, Category: DkmEvaluationResultCategory.Method, Access: DkmEvaluationResultAccessType.None, StorageType: DkmEvaluationResultStorageType.None, TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None, Address: result.Value.Address, CustomUIVisualizers: null, ExternalModules: null, DataItem: result.ToDataItem())); break; case ExpansionKind.TypeVariable: completionRoutine(DkmSuccessEvaluationResult.Create( inspectionContext, stackFrame, result.Name, result.FullName, result.Flags, result.DisplayValue, EditableValue: null, Type: result.DisplayValue, Category: DkmEvaluationResultCategory.Data, Access: DkmEvaluationResultAccessType.None, StorageType: DkmEvaluationResultStorageType.None, TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None, Address: result.Value.Address, CustomUIVisualizers: null, ExternalModules: null, DataItem: result.ToDataItem())); break; case ExpansionKind.PointerDereference: case ExpansionKind.Default: // This call will evaluate DebuggerDisplayAttributes. GetResultAndContinue( result, workList, declaredType: result.DeclaredTypeAndInfo.ClrType, declaredTypeInfo: result.DeclaredTypeAndInfo.Info, inspectionContext: inspectionContext, useDebuggerDisplay: result.UseDebuggerDisplay, completionRoutine: completionRoutine); break; default: throw ExceptionUtilities.UnexpectedValue(result.Kind); } }
private void GetChild( DkmEvaluationResult parent, WorkList workList, EvalResult row, DkmCompletionRoutine<DkmEvaluationAsyncResult> completionRoutine) { var inspectionContext = row.InspectionContext; if ((row.Kind != ExpansionKind.Default) || (row.Value == null)) { CreateEvaluationResultAndContinue( row, workList, row.InspectionContext, parent.StackFrame, child => completionRoutine(new DkmEvaluationAsyncResult(child))); } else { var typeDeclaringMember = row.TypeDeclaringMemberAndInfo; var name = (typeDeclaringMember.Type == null) ? row.Name : GetQualifiedMemberName(row.InspectionContext, typeDeclaringMember, row.Name, FullNameProvider); row.Value.GetResult( workList.InnerWorkList, row.DeclaredTypeAndInfo.ClrType, row.DeclaredTypeAndInfo.Info, row.InspectionContext, Formatter.NoFormatSpecifiers, name, row.FullName, result => workList.ContinueWith(() => completionRoutine(result))); } }
private static DkmEvaluationResult CreateEvaluationResultFromException(Exception e, EvalResult result, DkmInspectionContext inspectionContext) { return DkmFailedEvaluationResult.Create( inspectionContext, result.Value.StackFrame, Name: result.Name, FullName: null, ErrorMessage: e.Message, Flags: DkmEvaluationResultFlags.None, Type: null, DataItem: null); }
private DkmEvaluationResult GetResult( DkmInspectionContext inspectionContext, EvalResult result, DkmClrType declaredType, DkmClrCustomTypeInfo declaredTypeInfo, string displayName, string displayValue, string displayType, bool useDebuggerDisplay) { var name = result.Name; Debug.Assert(name != null); var typeDeclaringMemberAndInfo = result.TypeDeclaringMemberAndInfo; // Note: Don't respect the debugger display name on the root element: // 1) In the Watch window, that's where the user's text goes. // 2) In the Locals window, that's where the local name goes. // Note: Dev12 respects the debugger display name in the Locals window, // but not in the Watch window, but we can't distinguish and this // behavior seems reasonable. if (displayName != null && useDebuggerDisplay) { name = displayName; } else if (typeDeclaringMemberAndInfo.Type != null) { name = GetQualifiedMemberName(inspectionContext, typeDeclaringMemberAndInfo, name, FullNameProvider); } var value = result.Value; string display; if (value.HasExceptionThrown()) { display = result.DisplayValue ?? value.GetExceptionMessage(inspectionContext, result.FullNameWithoutFormatSpecifiers ?? result.Name); } else if (displayValue != null) { display = value.IncludeObjectId(displayValue); } else { display = value.GetValueString(inspectionContext, Formatter.NoFormatSpecifiers); } var typeName = displayType ?? GetTypeName(inspectionContext, value, declaredType, declaredTypeInfo, result.Kind); return CreateEvaluationResult(inspectionContext, value, name, typeName, display, result); }
private void GetResultAndContinue( EvalResult result, WorkList workList, DkmClrType declaredType, DkmClrCustomTypeInfo declaredTypeInfo, DkmInspectionContext inspectionContext, bool useDebuggerDisplay, CompletionRoutine<DkmEvaluationResult> completionRoutine) { var value = result.Value; // Value may have been replaced (specifically, for Nullable<T>). DebuggerDisplayInfo displayInfo; if (value.TryGetDebuggerDisplayInfo(out displayInfo)) { var targetType = displayInfo.TargetType; var attribute = displayInfo.Attribute; CompletionRoutine<Exception> onException = e => completionRoutine(CreateEvaluationResultFromException(e, result, inspectionContext)); var innerWorkList = workList.InnerWorkList; EvaluateDebuggerDisplayStringAndContinue(value, innerWorkList, inspectionContext, targetType, attribute.Name, displayName => EvaluateDebuggerDisplayStringAndContinue(value, innerWorkList, inspectionContext, targetType, attribute.Value, displayValue => EvaluateDebuggerDisplayStringAndContinue(value, innerWorkList, inspectionContext, targetType, attribute.TypeName, displayType => workList.ContinueWith(() => completionRoutine(GetResult(inspectionContext, result, declaredType, declaredTypeInfo, displayName.Result, displayValue.Result, displayType.Result, useDebuggerDisplay))), onException), onException), onException); } else { completionRoutine(GetResult(inspectionContext, result, declaredType, declaredTypeInfo, displayName: null, displayValue: null, displayType: null, useDebuggerDisplay: false)); } }
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); } } }
private static DkmEvaluationResult CreateEvaluationResult( DkmInspectionContext inspectionContext, DkmClrValue value, string name, string typeName, string display, EvalResult result) { if (value.IsError()) { // Evaluation failed return DkmFailedEvaluationResult.Create( InspectionContext: inspectionContext, StackFrame: value.StackFrame, Name: name, FullName: result.FullName, ErrorMessage: display, Flags: result.Flags, Type: typeName, DataItem: result.ToDataItem()); } else { ReadOnlyCollection<DkmCustomUIVisualizerInfo> customUIVisualizers = null; if (!value.IsNull) { DkmCustomUIVisualizerInfo[] customUIVisualizerInfo = value.Type.GetDebuggerCustomUIVisualizerInfo(); if (customUIVisualizerInfo != null) { customUIVisualizers = new ReadOnlyCollection<DkmCustomUIVisualizerInfo>(customUIVisualizerInfo); } } // If the EvalResultDataItem doesn't specify a particular category, we'll just propagate DkmClrValue.Category, // which typically appears to be set to the default value ("Other"). var category = (result.Category != DkmEvaluationResultCategory.Other) ? result.Category : value.Category; // Valid value return DkmSuccessEvaluationResult.Create( InspectionContext: inspectionContext, StackFrame: value.StackFrame, Name: name, FullName: result.FullName, Flags: result.Flags, Value: display, EditableValue: result.EditableValue, Type: typeName, Category: category, Access: value.Access, StorageType: value.StorageType, TypeModifierFlags: value.TypeModifierFlags, Address: value.Address, CustomUIVisualizers: customUIVisualizers, ExternalModules: null, DataItem: result.ToDataItem()); } }
private void CreateEvaluationResultAndContinue(EvalResult result, WorkList workList, DkmInspectionContext inspectionContext, DkmStackWalkFrame stackFrame, CompletionRoutine<DkmEvaluationResult> completionRoutine) { switch (result.Kind) { case ExpansionKind.Error: completionRoutine(DkmFailedEvaluationResult.Create( inspectionContext, StackFrame: stackFrame, Name: result.Name, FullName: result.FullName, ErrorMessage: result.DisplayValue, Flags: DkmEvaluationResultFlags.None, Type: null, DataItem: null)); break; case ExpansionKind.NativeView: { var value = result.Value; var name = Resources.NativeView; var fullName = result.FullName; var display = result.Name; DkmEvaluationResult evalResult; if (value.IsError()) { evalResult = DkmFailedEvaluationResult.Create( inspectionContext, stackFrame, Name: name, FullName: fullName, ErrorMessage: display, Flags: result.Flags, Type: null, DataItem: result.ToDataItem()); } else { // For Native View, create a DkmIntermediateEvaluationResult. // This will allow the C++ EE to take over expansion. var process = inspectionContext.RuntimeInstance.Process; var cpp = process.EngineSettings.GetLanguage(new DkmCompilerId(DkmVendorId.Microsoft, DkmLanguageId.Cpp)); evalResult = DkmIntermediateEvaluationResult.Create( inspectionContext, stackFrame, Name: name, FullName: fullName, Expression: display, IntermediateLanguage: cpp, TargetRuntime: process.GetNativeRuntimeInstance(), DataItem: result.ToDataItem()); } completionRoutine(evalResult); } break; case ExpansionKind.NonPublicMembers: completionRoutine(DkmSuccessEvaluationResult.Create( inspectionContext, stackFrame, Name: Resources.NonPublicMembers, FullName: result.FullName, Flags: result.Flags, Value: null, EditableValue: null, Type: string.Empty, Category: DkmEvaluationResultCategory.Data, Access: DkmEvaluationResultAccessType.None, StorageType: DkmEvaluationResultStorageType.None, TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None, Address: result.Value.Address, CustomUIVisualizers: null, ExternalModules: null, DataItem: result.ToDataItem())); break; case ExpansionKind.StaticMembers: completionRoutine(DkmSuccessEvaluationResult.Create( inspectionContext, stackFrame, Name: StaticMembersString, FullName: result.FullName, Flags: result.Flags, Value: null, EditableValue: null, Type: string.Empty, Category: DkmEvaluationResultCategory.Class, Access: DkmEvaluationResultAccessType.None, StorageType: DkmEvaluationResultStorageType.None, TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None, Address: result.Value.Address, CustomUIVisualizers: null, ExternalModules: null, DataItem: result.ToDataItem())); break; case ExpansionKind.RawView: completionRoutine(DkmSuccessEvaluationResult.Create( inspectionContext, stackFrame, Name: Resources.RawView, FullName: result.FullName, Flags: result.Flags, Value: null, EditableValue: result.EditableValue, Type: string.Empty, Category: DkmEvaluationResultCategory.Data, Access: DkmEvaluationResultAccessType.None, StorageType: DkmEvaluationResultStorageType.None, TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None, Address: result.Value.Address, CustomUIVisualizers: null, ExternalModules: null, DataItem: result.ToDataItem())); break; case ExpansionKind.DynamicView: case ExpansionKind.ResultsView: completionRoutine(DkmSuccessEvaluationResult.Create( inspectionContext, stackFrame, result.Name, result.FullName, result.Flags, result.DisplayValue, EditableValue: null, Type: string.Empty, Category: DkmEvaluationResultCategory.Method, Access: DkmEvaluationResultAccessType.None, StorageType: DkmEvaluationResultStorageType.None, TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None, Address: result.Value.Address, CustomUIVisualizers: null, ExternalModules: null, DataItem: result.ToDataItem())); break; case ExpansionKind.TypeVariable: completionRoutine(DkmSuccessEvaluationResult.Create( inspectionContext, stackFrame, result.Name, result.FullName, result.Flags, result.DisplayValue, EditableValue: null, Type: result.DisplayValue, Category: DkmEvaluationResultCategory.Data, Access: DkmEvaluationResultAccessType.None, StorageType: DkmEvaluationResultStorageType.None, TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None, Address: result.Value.Address, CustomUIVisualizers: null, ExternalModules: null, DataItem: result.ToDataItem())); break; case ExpansionKind.PointerDereference: case ExpansionKind.Default: // This call will evaluate DebuggerDisplayAttributes. GetResultAndContinue( result, workList, declaredType: result.DeclaredTypeAndInfo.ClrType, declaredTypeInfo: result.DeclaredTypeAndInfo.Info, inspectionContext: inspectionContext, useDebuggerDisplay: result.UseDebuggerDisplay, completionRoutine: completionRoutine); break; default: throw ExceptionUtilities.UnexpectedValue(result.Kind); } }
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; }
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); if (proxyMembers != null) { string proxyMemberFullNamePrefix = null; if (childFullNamePrefix != null) { proxyMemberFullNamePrefix = resultProvider.FullNameProvider.GetClrObjectCreationExpression(inspectionContext, proxyTypeAndInfo.ClrType, proxyTypeAndInfo.Info, 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; }