internal DkmClrValue( object value, object hostObjectValue, DkmClrType type, string alias, IDkmClrFormatter formatter, DkmEvaluationResultFlags evalFlags, DkmClrValueFlags valueFlags, DkmEvaluationResultCategory category = default(DkmEvaluationResultCategory), DkmEvaluationResultAccessType access = default(DkmEvaluationResultAccessType), ulong nativeComPointer = 0) { Debug.Assert(!type.GetLmrType().IsTypeVariables() || (valueFlags == DkmClrValueFlags.Synthetic)); Debug.Assert((alias == null) || evalFlags.Includes(DkmEvaluationResultFlags.HasObjectId)); // The "real" DkmClrValue will always have a value of zero for null pointers. Debug.Assert(!type.GetLmrType().IsPointer || (value != null)); this.RawValue = value; this.HostObjectValue = hostObjectValue; this.Type = type; _formatter = formatter; this.Alias = alias; this.EvalFlags = evalFlags; this.ValueFlags = valueFlags; this.Category = category; this.Access = access; this.NativeComPointer = nativeComPointer; }
internal static MemberAndDeclarationInfo GetMemberByName(this DkmClrType type, string name) { var members = type.GetLmrType().GetMember(name, TypeHelpers.MemberBindingFlags); Debug.Assert(members.Length == 1); return(new MemberAndDeclarationInfo(members[0], browsableState: null, info: DeclarationInfo.None, inheritanceLevel: 0)); }
/// <returns> /// The qualified name (i.e. including containing types and namespaces) of a named, pointer, /// or array type followed by the qualified name of the actual runtime type, if provided. /// </returns> private static string GetTypeName(DkmInspectionContext inspectionContext, DkmClrValue value, DkmClrType declaredType, DkmClrCustomTypeInfo declaredTypeInfo, ExpansionKind kind) { var declaredLmrType = declaredType.GetLmrType(); var runtimeType = value.Type; var declaredTypeName = inspectionContext.GetTypeName(declaredType, declaredTypeInfo, Formatter.NoFormatSpecifiers); // Include the runtime type if distinct. if (!declaredLmrType.IsPointer && (kind != ExpansionKind.PointerDereference) && (!declaredLmrType.IsNullable() || value.EvalFlags.Includes(DkmEvaluationResultFlags.ExceptionThrown))) { // Generate the declared type name without tuple element names. var declaredTypeInfoNoTupleElementNames = declaredTypeInfo.WithNoTupleElementNames(); var declaredTypeNameNoTupleElementNames = (declaredTypeInfo == declaredTypeInfoNoTupleElementNames) ? declaredTypeName : inspectionContext.GetTypeName(declaredType, declaredTypeInfoNoTupleElementNames, Formatter.NoFormatSpecifiers); // Generate the runtime type name with no tuple element names and no dynamic. var runtimeTypeName = inspectionContext.GetTypeName(runtimeType, null, FormatSpecifiers: Formatter.NoFormatSpecifiers); // If the two names are distinct, include both. if (!string.Equals(declaredTypeNameNoTupleElementNames, runtimeTypeName, StringComparison.Ordinal)) // Names will reflect "dynamic", types will not. { return(string.Format("{0} {{{1}}}", declaredTypeName, runtimeTypeName)); } } return(declaredTypeName); }
/// <summary> /// Generate a Results Only row if the value is a synthesized /// value declared as IEnumerable or IEnumerable<T>. /// </summary> internal static EvalResultDataItem CreateResultsOnlyRowIfSynthesizedEnumerable( DkmInspectionContext inspectionContext, string name, DkmClrType declaredType, DkmClrValue value, Formatter formatter) { if ((value.ValueFlags & DkmClrValueFlags.Synthetic) == 0) { return(null); } // Must be declared as IEnumerable or IEnumerable<T>, not a derived type. var enumerableType = GetEnumerableType(value, declaredType, requireExactInterface: true); if (enumerableType == null) { return(null); } var expansion = CreateExpansion(inspectionContext, value, enumerableType, formatter); if (expansion == null) { return(null); } return(expansion.CreateResultsViewRow(inspectionContext, name, declaredType.GetLmrType(), value, includeResultsFormatSpecifier: false, formatter: formatter)); }
/// <summary> /// Get the first attribute from <see cref="DkmClrType.GetEvalAttributes"/> (including inherited attributes) /// that is of type T, as well as the type that it targeted. /// </summary> internal static bool TryGetEvalAttribute <T>(this DkmClrType type, out DkmClrType attributeTarget, out T evalAttribute) where T : DkmClrEvalAttribute { attributeTarget = null; evalAttribute = null; var appDomain = type.AppDomain; var underlyingType = type.GetLmrType(); while ((underlyingType != null) && !underlyingType.IsObject()) { foreach (var attribute in type.GetEvalAttributes()) { evalAttribute = attribute as T; if (evalAttribute != null) { attributeTarget = type; return(true); } } underlyingType = underlyingType.GetBaseTypeOrNull(appDomain, out type); } return(false); }
/// <returns>The qualified name (i.e. including containing types and namespaces) of a named, /// pointer, or array type followed by the qualified name of the actual runtime type, if it /// differs from the declared type.</returns> private static string GetTypeName(DkmInspectionContext inspectionContext, DkmClrType declaredType, DkmClrType runtimeType) { var declaredTypeName = inspectionContext.GetTypeName(declaredType); var declaredLmrType = declaredType.GetLmrType(); var runtimeLmrType = runtimeType.GetLmrType(); return(declaredLmrType.Equals(runtimeLmrType) || declaredLmrType.IsPointer ? declaredTypeName : string.Format("{0} {{{1}}}", declaredTypeName, inspectionContext.GetTypeName(runtimeType))); }
internal DkmClrValue( object value, object hostObjectValue, DkmClrType type, string alias, IDkmClrFormatter formatter, DkmEvaluationResultFlags evalFlags, DkmClrValueFlags valueFlags) { Debug.Assert(!type.GetLmrType().IsTypeVariables() || (valueFlags == DkmClrValueFlags.Synthetic)); Debug.Assert((alias == null) || evalFlags.Includes(DkmEvaluationResultFlags.HasObjectId)); // The "real" DkmClrValue will always have a value of zero for null pointers. Debug.Assert(!type.GetLmrType().IsPointer || (value != null)); _rawValue = value; this.HostObjectValue = hostObjectValue; this.Type = type; _formatter = formatter; this.Alias = alias; this.EvalFlags = evalFlags; this.ValueFlags = valueFlags; }
void IDkmClrResultProvider.GetResult(DkmClrValue clrValue, DkmWorkList workList, DkmClrType declaredType, DkmClrCustomTypeInfo customTypeInfo, DkmInspectionContext inspectionContext, ReadOnlyCollection <string> formatSpecifiers, string resultName, string resultFullName, DkmCompletionRoutine <DkmEvaluationAsyncResult> completionRoutine) { clrValue.GetResult( workList, declaredType, customTypeInfo, inspectionContext, formatSpecifiers, resultName, resultFullName, result => { var type = declaredType.GetLmrType(); if (type.IsPointer) { var r = (DkmSuccessEvaluationResult)result.Result; // TODO: Why aren't modopts for & properties included? r.GetChildren( workList, 1, inspectionContext, children => { var c = (DkmSuccessEvaluationResult)children.InitialChildren[0]; r = DkmSuccessEvaluationResult.Create( c.InspectionContext, c.StackFrame, r.Name, r.FullName, c.Flags, c.Value, r.EditableValue, r.Type, r.Category, r.Access, r.StorageType, r.TypeModifierFlags, null, r.CustomUIVisualizers, null, null); completionRoutine(new DkmEvaluationAsyncResult(r)); }); } else { completionRoutine(result); } }); }
internal DkmClrValue CreateDkmClrValue( object value, DkmClrType type, string alias = null, DkmEvaluationResultFlags evalFlags = DkmEvaluationResultFlags.None, DkmClrValueFlags valueFlags = DkmClrValueFlags.None) { return(new DkmClrValue( value, DkmClrValue.GetHostObjectValue(type.GetLmrType(), value), type, alias, _formatter, evalFlags, valueFlags)); }
/// <returns> /// The qualified name (i.e. including containing types and namespaces) of a named, pointer, /// or array type followed by the qualified name of the actual runtime type, if provided. /// </returns> private static string GetTypeName(DkmInspectionContext inspectionContext, DkmClrValue value, DkmClrType declaredType, DkmClrCustomTypeInfo declaredTypeInfo, ExpansionKind kind) { var declaredLmrType = declaredType.GetLmrType(); var runtimeType = value.Type; var runtimeLmrType = runtimeType.GetLmrType(); var declaredTypeName = inspectionContext.GetTypeName(declaredType, declaredTypeInfo, Formatter.NoFormatSpecifiers); var runtimeTypeName = inspectionContext.GetTypeName(runtimeType, CustomTypeInfo: null, FormatSpecifiers: Formatter.NoFormatSpecifiers); var includeRuntimeTypeName = !string.Equals(declaredTypeName, runtimeTypeName, StringComparison.OrdinalIgnoreCase) && // Names will reflect "dynamic", types will not. !declaredLmrType.IsPointer && (kind != ExpansionKind.PointerDereference) && (!declaredLmrType.IsNullable() || value.EvalFlags.Includes(DkmEvaluationResultFlags.ExceptionThrown)); return(includeRuntimeTypeName ? string.Format("{0} {{{1}}}", declaredTypeName, runtimeTypeName) : declaredTypeName); }
internal DkmClrValue CreateDkmClrValue( object value, DkmClrType type, string alias = null, DkmEvaluationResultFlags evalFlags = DkmEvaluationResultFlags.None, DkmClrValueFlags valueFlags = DkmClrValueFlags.None, ulong nativeComPointer = 0) { return(new DkmClrValue( value, DkmClrValue.GetHostObjectValue(type.GetLmrType(), value), type, alias, evalFlags, valueFlags, nativeComPointer: nativeComPointer)); }
internal static DkmCustomUIVisualizerInfo[] GetDebuggerCustomUIVisualizerInfo( this DkmClrType type ) { var builder = ArrayBuilder <DkmCustomUIVisualizerInfo> .GetInstance(); var appDomain = type.AppDomain; var underlyingType = type.GetLmrType(); while ((underlyingType != null) && !underlyingType.IsObject()) { foreach (var attribute in type.GetEvalAttributes()) { var visualizerAttribute = attribute as DkmClrDebuggerVisualizerAttribute; if (visualizerAttribute == null) { continue; } builder.Add( DkmCustomUIVisualizerInfo.Create( (uint)builder.Count, visualizerAttribute.VisualizerDescription, visualizerAttribute.VisualizerDescription, // ClrCustomVisualizerVSHost is a registry entry that specifies the CLSID of the // IDebugCustomViewer class that will be instantiated to display the custom visualizer. "ClrCustomVisualizerVSHost", visualizerAttribute.UISideVisualizerTypeName, visualizerAttribute.UISideVisualizerAssemblyName, visualizerAttribute.UISideVisualizerAssemblyLocation, visualizerAttribute.DebuggeeSideVisualizerTypeName, visualizerAttribute.DebuggeeSideVisualizerAssemblyName ) ); } underlyingType = underlyingType.GetBaseTypeOrNull(appDomain, out type); } var result = (builder.Count > 0) ? builder.ToArray() : null; builder.Free(); return(result); }
/// <summary> /// This method is called by the debug engine to populate the text representing the type of /// a result. /// </summary> /// <param name="inspectionContext">Context of the evaluation. This contains options/flags /// to be used during compilation. It also contains the InspectionSession. The inspection /// session is the object that provides lifetime management for our objects. When the user /// steps or continues the process, the debug engine will dispose of the inspection session</param> /// <param name="clrType">This is the raw type we want to format</param> /// <param name="customTypeInfo">If Expression Compiler passed any additional information /// about the type that doesn't exist in metadata, this parameter contais that information.</param> /// <param name="formatSpecifiers">A list of custom format specifiers that the debugger did /// not understand. If you want special format specifiers for your language, handle them /// here. The formatter should ignore any format specifiers it does not understand.</param> /// <returns>The text of the type name to display</returns> string IDkmClrFormatter.GetTypeName( DkmInspectionContext inspectionContext, DkmClrType clrType, DkmClrCustomTypeInfo customTypeInfo, ReadOnlyCollection <string> formatSpecifiers) { // Get the LMR type for the DkmClrType. LMR Types (Microsoft.VisualStudio.Debugger.Metadata.Type) // are similar to System.Type, but represent types that live in the process being debugged. Type lmrType = clrType.GetLmrType(); XSharpType xType = Utility.GetXSharpTypeForLmrType(lmrType); if (xType == XSharpType.Invalid) { // We don't know about this type. Delegate to the C# Formatter to format the // type name. return(inspectionContext.GetTypeName(clrType, customTypeInfo, formatSpecifiers)); } return(xType.ToString()); }
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); } } }
string IDkmClrFormatter.GetTypeName(DkmInspectionContext inspectionContext, DkmClrType type, DkmClrCustomTypeInfo typeInfo, ReadOnlyCollection <string> formatSpecifiers) { bool unused; return(GetTypeName(new TypeAndCustomInfo(type.GetLmrType(), typeInfo), escapeKeywordIdentifiers: false, sawInvalidIdentifier: out unused)); }
string IDkmClrFormatter.GetTypeName(DkmInspectionContext inspectionContext, DkmClrType type, ReadOnlyCollection <string> formatSpecifiers) { return(GetTypeName(type.GetLmrType())); }
string IDkmClrFormatter.GetTypeName(DkmInspectionContext inspectionContext, DkmClrType type, DkmClrCustomTypeInfo typeInfo, ReadOnlyCollection <string> formatSpecifiers) { return(GetTypeName(new TypeAndCustomInfo(type.GetLmrType(), typeInfo))); }
public TypeAndCustomInfo(DkmClrType type) : this(type.GetLmrType(), null) { }
string IDkmClrFormatter.GetTypeName(DkmInspectionContext inspectionContext, DkmClrType clrType) { return(GetTypeName(clrType.GetLmrType())); }