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); } } }
string IDkmClrFormatter.GetTypeName(DkmInspectionContext inspectionContext, DkmClrType type, DkmClrCustomTypeInfo typeInfo, ReadOnlyCollection <string> formatSpecifiers) { bool unused; return(GetTypeName(new TypeAndCustomInfo(type, typeInfo), escapeKeywordIdentifiers: false, sawInvalidIdentifier: out unused)); }
string IDkmClrFullNameProvider.GetClrObjectCreationExpression(DkmInspectionContext inspectionContext, DkmClrType type, DkmClrCustomTypeInfo customTypeInfo, string[] arguments) { bool sawInvalidIdentifier; var name = GetTypeName(new TypeAndCustomInfo(type, customTypeInfo), escapeKeywordIdentifiers: true, sawInvalidIdentifier: out sawInvalidIdentifier); if (sawInvalidIdentifier) { return(null); } return(GetObjectCreationExpression(name, arguments)); }
/// <summary> /// Returns the array of <see cref="DkmCustomUIVisualizerInfo"/> objects of the type from its <see cref="DkmClrDebuggerVisualizerAttribute"/> attributes, /// or null if the type has no [DebuggerVisualizer] attributes associated with it. /// </summary> 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); }
internal DkmEvaluationResult FormatResult(string name, string fullName, DkmClrValue value, DkmClrType declaredType = null, DkmClrCustomTypeInfo declaredTypeInfo = null, DkmInspectionContext inspectionContext = null) { var asyncResult = FormatAsyncResult(name, fullName, value, declaredType, declaredTypeInfo, inspectionContext); var exception = asyncResult.Exception; if (exception != null) { ExceptionDispatchInfo.Capture(exception).Throw(); } return(asyncResult.Result); }
public DkmClrValue InstantiateResultsViewProxy(DkmInspectionContext inspectionContext, DkmClrType enumerableType) { if (EvalFlags.Includes(DkmEvaluationResultFlags.ExceptionThrown)) { throw new InvalidOperationException(); } if (inspectionContext == null) { throw new ArgumentNullException("inspectionContext"); } var appDomain = enumerableType.AppDomain; var module = GetModule(appDomain, "System.Core.dll"); if (module == null) { return(null); } var typeArgs = enumerableType.GenericArguments; Debug.Assert(typeArgs.Count <= 1); var proxyTypeName = (typeArgs.Count == 0) ? "System.Linq.SystemCore_EnumerableDebugView" : "System.Linq.SystemCore_EnumerableDebugView`1"; DkmClrType proxyType; try { proxyType = module.ResolveTypeName(proxyTypeName, typeArgs); } catch (ArgumentException) { // ResolveTypeName throws ArgumentException if type is not found. return(null); } return(this.InstantiateProxyType(inspectionContext, proxyType)); }
internal static Type GetBaseTypeOrNull(this Type underlyingType, DkmClrAppDomain appDomain, out DkmClrType type) { Debug.Assert((underlyingType.BaseType != null) || underlyingType.IsPointer || underlyingType.IsArray, "BaseType should only return null if the underlyingType is a pointer or array."); underlyingType = underlyingType.BaseType; type = (underlyingType != null) ? DkmClrType.Create(appDomain, underlyingType) : null; return(underlyingType); }
public DebuggerDisplayInfo WithDebuggerDisplayAttribute(DkmClrDebuggerDisplayAttribute attribute, DkmClrType attributeTarget) { var name = Name; var value = m_value; var simpleValue = m_simpleValue; var typeName = TypeName; if (attribute.Name != null) { name = new DebuggerDisplayItemInfo(attribute.Name, attributeTarget); } // Favorites info takes priority for value and simple value if (!m_hasFavoritesInfo && attribute.Value != null) { value = new DebuggerDisplayItemInfo(attribute.Value, attributeTarget); simpleValue = null; } if (attribute.TypeName != null) { typeName = new DebuggerDisplayItemInfo(attribute.TypeName, attributeTarget); } return(new DebuggerDisplayInfo( targetType: m_targetType, name: name, value: value, simpleValue: simpleValue, typeName: typeName, hasFavoritesInfo: m_hasFavoritesInfo)); }
public string GetTypeName(DkmClrType ClrType, DkmClrCustomTypeInfo CustomTypeInfo, ReadOnlyCollection <string> FormatSpecifiers) { // The real version does some sort of dynamic dispatch that ultimately calls this method. return(_formatter.GetTypeName(this, ClrType, CustomTypeInfo, FormatSpecifiers)); }
public DebuggerDisplayItemInfo(string value, DkmClrType targetType) { Value = value; TargetType = targetType; }
public DebuggerDisplayInfo(DkmClrType targetType) { m_targetType = targetType; }
string IDkmClrFormatter.GetTypeName(DkmInspectionContext inspectionContext, DkmClrType type, DkmClrCustomTypeInfo typeInfo, ReadOnlyCollection <string> formatSpecifiers) { return(GetTypeName(new TypeAndCustomInfo(type.GetLmrType(), typeInfo))); }
string IDkmClrFullNameProvider.GetClrCastExpression(DkmInspectionContext inspectionContext, string argument, DkmClrType type, DkmClrCustomTypeInfo customTypeInfo, bool parenthesizeArgument, bool parenthesizeEntireExpression) { bool sawInvalidIdentifier; var name = GetTypeName(new TypeAndCustomInfo(type, customTypeInfo), escapeKeywordIdentifiers: true, sawInvalidIdentifier: out sawInvalidIdentifier); if (sawInvalidIdentifier) { return(null); } return(GetCastExpression(argument, name, parenthesizeArgument, parenthesizeEntireExpression)); }
private DkmEvaluationResult GetResult( DkmInspectionContext inspectionContext, EvalResultDataItem dataItem, DkmClrType declaredType, DkmClrCustomTypeInfo declaredTypeInfo, string displayName, string displayValue, string displayType, EvalResultDataItem parent) { var name = dataItem.Name; Debug.Assert(name != null); var typeDeclaringMemberAndInfo = dataItem.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 && parent != null) { name = displayName; } else if (typeDeclaringMemberAndInfo.Type != null) { bool unused; if (typeDeclaringMemberAndInfo.Type.IsInterface) { var interfaceTypeName = this.Formatter.GetTypeName(typeDeclaringMemberAndInfo, escapeKeywordIdentifiers: true, sawInvalidIdentifier: out unused); name = string.Format("{0}.{1}", interfaceTypeName, name); } else { var pooled = PooledStringBuilder.GetInstance(); var builder = pooled.Builder; builder.Append(name); builder.Append(" ("); builder.Append(this.Formatter.GetTypeName(typeDeclaringMemberAndInfo, escapeKeywordIdentifiers: false, sawInvalidIdentifier: out unused)); builder.Append(')'); name = pooled.ToStringAndFree(); } } var value = dataItem.Value; string display; if (value.HasExceptionThrown()) { display = dataItem.DisplayValue ?? value.GetExceptionMessage(dataItem.FullNameWithoutFormatSpecifiers ?? dataItem.Name, this.Formatter); } else if (displayValue != null) { display = value.IncludeObjectId(displayValue); } else { display = value.GetValueString(inspectionContext, Formatter.NoFormatSpecifiers); } var typeName = displayType ?? GetTypeName(inspectionContext, value, declaredType, declaredTypeInfo, dataItem.Kind); return(CreateEvaluationResult(inspectionContext, value, name, typeName, display, dataItem)); }
/// <remarks> /// Very simple expression evaluation (may not support all syntax supported by Concord). /// </remarks> public void EvaluateDebuggerDisplayString(DkmWorkList workList, DkmInspectionContext inspectionContext, DkmClrType targetType, string formatString, DkmCompletionRoutine <DkmEvaluateDebuggerDisplayStringAsyncResult> completionRoutine) { Debug.Assert(!this.IsNull, "Not supported by VIL"); if (inspectionContext == null) { throw new ArgumentNullException("inspectionContext"); } var pooled = PooledStringBuilder.GetInstance(); var builder = pooled.Builder; int openPos = -1; int length = formatString.Length; for (int i = 0; i < length; i++) { char ch = formatString[i]; if (ch == '{') { if (openPos >= 0) { throw new ArgumentException(string.Format("Nested braces in '{0}'", formatString)); } openPos = i; } else if (ch == '}') { if (openPos < 0) { throw new ArgumentException(string.Format("Unmatched closing brace in '{0}'", formatString)); } string name = formatString.Substring(openPos + 1, i - openPos - 1); openPos = -1; // Ignore any format specifiers. int commaIndex = name.IndexOf(','); if (commaIndex >= 0) { name = name.Substring(0, commaIndex); } var type = ((TypeImpl)this.Type.GetLmrType()).Type; const System.Reflection.BindingFlags bindingFlags = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Static; DkmClrValue exprValue; var appDomain = this.Type.AppDomain; var field = type.GetField(name, bindingFlags); if (field != null) { var fieldValue = field.GetValue(RawValue); exprValue = new DkmClrValue( fieldValue, fieldValue, DkmClrType.Create(appDomain, (TypeImpl)((fieldValue == null) ? field.FieldType : fieldValue.GetType())), alias: null, formatter: _formatter, evalFlags: GetEvaluationResultFlags(fieldValue), valueFlags: DkmClrValueFlags.None); } else { var property = type.GetProperty(name, bindingFlags); if (property != null) { var propertyValue = property.GetValue(RawValue); exprValue = new DkmClrValue( propertyValue, propertyValue, DkmClrType.Create(appDomain, (TypeImpl)((propertyValue == null) ? property.PropertyType : propertyValue.GetType())), alias: null, formatter: _formatter, evalFlags: GetEvaluationResultFlags(propertyValue), valueFlags: DkmClrValueFlags.None); } else { var openParenIndex = name.IndexOf('('); if (openParenIndex >= 0) { name = name.Substring(0, openParenIndex); } var method = type.GetMethod(name, bindingFlags); // The real implementation requires parens on method invocations, so // we'll return error if there wasn't at least an open paren... if ((openParenIndex >= 0) && method != null) { var methodValue = method.Invoke(RawValue, new object[] { }); exprValue = new DkmClrValue( methodValue, methodValue, DkmClrType.Create(appDomain, (TypeImpl)((methodValue == null) ? method.ReturnType : methodValue.GetType())), alias: null, formatter: _formatter, evalFlags: GetEvaluationResultFlags(methodValue), valueFlags: DkmClrValueFlags.None); } else { var stringValue = "Problem evaluating expression"; var stringType = DkmClrType.Create(appDomain, (TypeImpl)typeof(string)); exprValue = new DkmClrValue( stringValue, stringValue, stringType, alias: null, formatter: _formatter, evalFlags: DkmEvaluationResultFlags.None, valueFlags: DkmClrValueFlags.Error); } } } builder.Append(exprValue.GetValueString(inspectionContext, Formatter.NoFormatSpecifiers)); // Re-enter the formatter. } else if (openPos < 0) { builder.Append(ch); } } if (openPos >= 0) { throw new ArgumentException(string.Format("Unmatched open brace in '{0}'", formatString)); } workList.AddWork(() => completionRoutine(new DkmEvaluateDebuggerDisplayStringAsyncResult(pooled.ToStringAndFree()))); }
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); } }); }
public DkmClrValue InstantiateProxyType(DkmInspectionContext inspectionContext, DkmClrType proxyType) { if (inspectionContext == null) { throw new ArgumentNullException("inspectionContext"); } var lmrType = proxyType.GetLmrType(); Debug.Assert(!lmrType.IsGenericTypeDefinition); const BindingFlags bindingFlags = BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public; var constructor = lmrType.GetConstructors(bindingFlags).Single(); var value = constructor.Invoke(bindingFlags, null, new[] { RawValue }, null); return(new DkmClrValue( value, value, type: proxyType, alias: null, formatter: _formatter, evalFlags: DkmEvaluationResultFlags.None, valueFlags: DkmClrValueFlags.None)); }
string IDkmClrFormatter.GetTypeName(DkmInspectionContext inspectionContext, DkmClrType clrType, DkmClrCustomTypeInfo customTypeInfo, ReadOnlyCollection <string> formatSpecifiers) { return(inspectionContext.GetTypeName(clrType, customTypeInfo, formatSpecifiers)); }
internal static void AppendTypeMembers( this Type type, ArrayBuilder <MemberAndDeclarationInfo> includedMembers, Predicate <MemberInfo> predicate, Type declaredType, DkmClrAppDomain appDomain, bool includeInherited, bool hideNonPublic, bool isProxyType, bool includeCompilerGenerated, bool supportsFavorites, DkmClrObjectFavoritesInfo favoritesInfo) { Debug.Assert(!type.IsInterface); var memberLocation = DeclarationInfo.FromSubTypeOfDeclaredType; var previousDeclarationMap = includeInherited ? new Dictionary <string, DeclarationInfo>() : null; int inheritanceLevel = 0; while (!type.IsObject()) { if (type.Equals(declaredType)) { Debug.Assert(memberLocation == DeclarationInfo.FromSubTypeOfDeclaredType); memberLocation = DeclarationInfo.FromDeclaredTypeOrBase; } // Get the state from DebuggerBrowsableAttributes for the members of the current type. var browsableState = DkmClrType.Create(appDomain, type).GetDebuggerBrowsableAttributeState(); // Disable favorites if any of the members have a browsable state of RootHidden if (supportsFavorites && browsableState != null) { foreach (var browsableStateValue in browsableState.Values) { if (browsableStateValue == DkmClrDebuggerBrowsableAttributeState.RootHidden) { supportsFavorites = false; break; } } } // Get the favorites information if it is supported. // NOTE: Using a Dictionary since Hashset is not available in .net 2.0 Dictionary <string, object> favoritesMemberNames = null; if (supportsFavorites && favoritesInfo?.Favorites != null) { favoritesMemberNames = new Dictionary <string, object>(favoritesInfo.Favorites.Count); foreach (var favorite in favoritesInfo.Favorites) { favoritesMemberNames.Add(favorite, null); } } // Hide non-public members if hideNonPublic is specified (intended to reflect the // DkmInspectionContext's DkmEvaluationFlags), and the type is from an assembly // with no symbols. var hideNonPublicBehavior = DeclarationInfo.None; if (hideNonPublic) { var moduleInstance = appDomain.FindClrModuleInstance(type.Module.ModuleVersionId); if (moduleInstance == null || moduleInstance.Module == null) { // Synthetic module or no symbols loaded. hideNonPublicBehavior = DeclarationInfo.HideNonPublic; } } foreach (var member in type.GetMembers(MemberBindingFlags)) { var memberName = member.Name; if (!includeCompilerGenerated && memberName.IsCompilerGenerated()) { continue; } // The native EE shows proxy members regardless of accessibility if they have a // DebuggerBrowsable attribute of any value. Match that behaviour here. if (!isProxyType || browsableState == null || !browsableState.ContainsKey(memberName)) { if (!predicate(member)) { continue; } } // This represents information about the immediately preceding (more derived) // declaration with the same name as the current member. var previousDeclaration = DeclarationInfo.None; var memberNameAlreadySeen = false; if (includeInherited) { memberNameAlreadySeen = previousDeclarationMap.TryGetValue(memberName, out previousDeclaration); if (memberNameAlreadySeen) { // There was a name conflict, so we'll need to include the declaring // type of the member to disambiguate. previousDeclaration |= DeclarationInfo.IncludeTypeInMemberName; } // Update previous member with name hiding (casting) and declared location information for next time. previousDeclarationMap[memberName] = (previousDeclaration & ~(DeclarationInfo.RequiresExplicitCast | DeclarationInfo.FromSubTypeOfDeclaredType)) | member.AccessingBaseMemberWithSameNameRequiresExplicitCast() | memberLocation; } Debug.Assert(memberNameAlreadySeen != (previousDeclaration == DeclarationInfo.None)); // Decide whether to include this member in the list of members to display. if (!memberNameAlreadySeen || previousDeclaration.IsSet(DeclarationInfo.RequiresExplicitCast)) { DkmClrDebuggerBrowsableAttributeState?browsableStateValue = null; if (browsableState != null) { DkmClrDebuggerBrowsableAttributeState value; if (browsableState.TryGetValue(memberName, out value)) { browsableStateValue = value; } } if (memberLocation.IsSet(DeclarationInfo.FromSubTypeOfDeclaredType)) { // If the current type is a sub-type of the declared type, then // we always need to insert a cast to access the member previousDeclaration |= DeclarationInfo.RequiresExplicitCast; } else if (previousDeclaration.IsSet(DeclarationInfo.FromSubTypeOfDeclaredType)) { // If the immediately preceding member (less derived) was // declared on a sub-type of the declared type, then we'll // ignore the casting bit. Accessing a member through the // declared type is the same as casting to that type, so // the cast would be redundant. previousDeclaration &= ~DeclarationInfo.RequiresExplicitCast; } previousDeclaration |= hideNonPublicBehavior; includedMembers.Add( new MemberAndDeclarationInfo( member, browsableStateValue, previousDeclaration, inheritanceLevel, canFavorite: supportsFavorites, isFavorite: favoritesMemberNames?.ContainsKey(memberName) == true)); } } if (!includeInherited) { break; } type = type.BaseType; inheritanceLevel++; } includedMembers.Sort(MemberAndDeclarationInfo.Comparer); }
string IDkmClrFullNameProvider.GetClrTypeName(DkmInspectionContext inspectionContext, DkmClrType clrType, DkmClrCustomTypeInfo customTypeInfo) { throw new NotImplementedException(); }
/// <summary> /// Returns the set of DebuggerBrowsableAttribute state for the /// members of the type, indexed by member name, or null if there /// are no DebuggerBrowsableAttributes on members of the type. /// </summary> private static Dictionary <string, DkmClrDebuggerBrowsableAttributeState> GetDebuggerBrowsableAttributeState(this DkmClrType type) { Dictionary <string, DkmClrDebuggerBrowsableAttributeState> result = null; foreach (var attribute in type.GetEvalAttributes()) { var browsableAttribute = attribute as DkmClrDebuggerBrowsableAttribute; if (browsableAttribute == null) { continue; } if (result == null) { result = new Dictionary <string, DkmClrDebuggerBrowsableAttributeState>(); } // There can be multiple same attributes for derived classes. // Debugger provides attributes starting from derived classes and then up to base ones. // We should use derived attributes if there is more than one instance. if (!result.ContainsKey(browsableAttribute.TargetMember)) { result.Add(browsableAttribute.TargetMember, browsableAttribute.State); } } return(result); }
string IDkmClrFullNameProvider.GetClrCastExpression(DkmInspectionContext inspectionContext, string argument, DkmClrType type, DkmClrCustomTypeInfo customTypeInfo, DkmClrCastExpressionOptions castExpressionOptions) { throw new NotImplementedException(); }
internal DkmEvaluationResult FormatResult(string name, DkmClrValue value, DkmClrType declaredType = null, DkmInspectionContext inspectionContext = null) { return(FormatResult(name, name, value, declaredType, inspectionContext: inspectionContext)); }
string IDkmClrFullNameProvider.GetClrObjectCreationExpression(DkmInspectionContext inspectionContext, DkmClrType type, DkmClrCustomTypeInfo customTypeInfo, string[] arguments) { throw new NotImplementedException(); }
internal DkmEvaluationAsyncResult FormatAsyncResult(string name, string fullName, DkmClrValue value, DkmClrType declaredType = null, DkmClrCustomTypeInfo declaredTypeInfo = null, DkmInspectionContext inspectionContext = null) { DkmEvaluationAsyncResult asyncResult = default(DkmEvaluationAsyncResult); var workList = new DkmWorkList(); value.GetResult( workList, DeclaredType: declaredType ?? value.Type, CustomTypeInfo: declaredTypeInfo, InspectionContext: inspectionContext ?? DefaultInspectionContext, FormatSpecifiers: Formatter.NoFormatSpecifiers, ResultName: name, ResultFullName: fullName, CompletionRoutine: r => asyncResult = r); workList.Execute(); return(asyncResult); }
internal StaticMembersExpansion(DkmClrType type, Expansion members) { _type = type; _members = members; }
string IDkmClrFullNameProvider.GetClrTypeName(DkmInspectionContext inspectionContext, DkmClrType clrType, DkmClrCustomTypeInfo customTypeInfo) { Debug.Assert(inspectionContext != null); bool sawInvalidIdentifier; var name = GetTypeName(new TypeAndCustomInfo(clrType, customTypeInfo), escapeKeywordIdentifiers: true, sawInvalidIdentifier: out sawInvalidIdentifier); return(sawInvalidIdentifier ? null : name); }
internal static EvalResult CreateMemberDataItem( ResultProvider resultProvider, DkmInspectionContext inspectionContext, MemberAndDeclarationInfo member, DkmClrValue memberValue, EvalResultDataItem parent, CustomTypeInfoTypeArgumentMap customTypeInfoMap, ExpansionFlags flags, bool supportsFavorites ) { var fullNameProvider = resultProvider.FullNameProvider; var declaredType = member.Type; var declaredTypeInfo = customTypeInfoMap.SubstituteCustomTypeInfo( member.OriginalDefinitionType, member.TypeInfo ); string memberName; // Considering, we're not handling the case of a member inherited from a generic base type. var typeDeclaringMember = member.GetExplicitlyImplementedInterface(out memberName) ?? member.DeclaringType; var typeDeclaringMemberInfo = typeDeclaringMember.IsInterface ? customTypeInfoMap.SubstituteCustomTypeInfo( typeDeclaringMember.GetInterfaceListEntry(member.DeclaringType), customInfo: null ) : null; var memberNameForFullName = fullNameProvider.GetClrValidIdentifier( inspectionContext, memberName ); var appDomain = memberValue.Type.AppDomain; string fullName; if (memberNameForFullName == null) { fullName = null; } else { memberName = memberNameForFullName; fullName = MakeFullName( fullNameProvider, inspectionContext, memberNameForFullName, new TypeAndCustomInfo( DkmClrType.Create(appDomain, typeDeclaringMember), typeDeclaringMemberInfo ), // Note: Won't include DynamicAttribute. member.RequiresExplicitCast, member.IsStatic, parent ); } return(resultProvider.CreateDataItem( inspectionContext, memberName, typeDeclaringMemberAndInfo: ( member.IncludeTypeInMemberName || typeDeclaringMember.IsInterface ) ? new TypeAndCustomInfo( DkmClrType.Create(appDomain, typeDeclaringMember), typeDeclaringMemberInfo ) : default(TypeAndCustomInfo), // Note: Won't include DynamicAttribute. declaredTypeAndInfo: new TypeAndCustomInfo( DkmClrType.Create(appDomain, declaredType), declaredTypeInfo ), value: memberValue, useDebuggerDisplay: parent != null, expansionFlags: flags, childShouldParenthesize: false, fullName: fullName, formatSpecifiers: Formatter.NoFormatSpecifiers, category: DkmEvaluationResultCategory.Other, flags: memberValue.EvalFlags, evalFlags: DkmEvaluationFlags.None, canFavorite: member.CanFavorite, isFavorite: member.IsFavorite, supportsFavorites: supportsFavorites )); }
private static ResultsViewExpansion CreateExpansion(DkmInspectionContext inspectionContext, DkmClrValue value, DkmClrType enumerableType, ResultProvider resultProvider) { var proxyValue = value.InstantiateResultsViewProxy(inspectionContext, enumerableType); // InstantiateResultsViewProxy may return null (if required assembly is missing, for instance). if (proxyValue == null) { return(null); } var proxyMembers = MemberExpansion.CreateExpansion( inspectionContext, new TypeAndCustomInfo(proxyValue.Type), proxyValue, flags: ExpansionFlags.None, predicate: TypeHelpers.IsPublic, resultProvider: resultProvider, isProxyType: false); return(new ResultsViewExpansion(proxyValue, proxyMembers)); }
void IDkmClrResultProvider.GetResult(DkmClrValue value, DkmWorkList workList, DkmClrType declaredType, DkmClrCustomTypeInfo declaredTypeInfo, DkmInspectionContext inspectionContext, ReadOnlyCollection <string> formatSpecifiers, string resultName, string resultFullName, DkmCompletionRoutine <DkmEvaluationAsyncResult> completionRoutine) { // TODO: Use full name var wl = new WorkList(workList, e => completionRoutine(DkmEvaluationAsyncResult.CreateErrorResult(e))); GetRootResultAndContinue( value, wl, declaredType, declaredTypeInfo, inspectionContext, resultName, result => wl.ContinueWith(() => completionRoutine(new DkmEvaluationAsyncResult(result)))); wl.Execute(); }