private static DkmClrDebuggerVisualizerAttribute[] GetDebuggerVisualizerAttributes(System.Type type) { var attributesData = type.GetCustomAttributesData().Where(data => data.AttributeType == typeof(DebuggerVisualizerAttribute)); if (attributesData.Count() == 0) { return null; } var builder = ArrayBuilder<DkmClrDebuggerVisualizerAttribute>.GetInstance(); foreach (var attributeData in attributesData) { var argValueTypeBuilder = ArrayBuilder<System.Type>.GetInstance(); foreach (var typedArg in attributeData.ConstructorArguments) { var argumentType = typedArg.ArgumentType.FullName; System.Type argValueType = null; if (string.Equals(argumentType, "System.String", System.StringComparison.Ordinal)) { var typeName = (string)typedArg.Value; var assembly = type.Assembly; argValueType = assembly.GetType(typeName); } else if (string.Equals(argumentType, "System.Type", System.StringComparison.Ordinal)) { argValueType = typedArg.Value as System.Type; } if (argValueType != null) { argValueTypeBuilder.Add(argValueType); } else { Debug.Fail("Failed to resolve the type of the arguments for DebuggerVisualizer attribute."); return null; } } // Attribute not recognized. if (argValueTypeBuilder.Count == 0) { Debug.Fail("Failed to retrieve the visualizer types from a [DebuggerVisualizer] attribute"); return null; } string uiSideVisualizerTypeName = argValueTypeBuilder[0].FullName; string uiSideVisualizerAssemblyName = argValueTypeBuilder[0].Assembly.FullName; string debuggeeSideVisualizerTypeName; string debuggeeSideVisualizerAssemblyName; if (argValueTypeBuilder.Count > 1) { System.Type debuggeeSideType = argValueTypeBuilder[1]; debuggeeSideVisualizerTypeName = debuggeeSideType.FullName; debuggeeSideVisualizerAssemblyName = debuggeeSideType.Assembly.FullName; } else { debuggeeSideVisualizerTypeName = "Microsoft.VisualStudio.DebuggerVisualizers.VisualizerObjectSource"; var vsVersion = System.Environment.GetEnvironmentVariable("VisualStudioVersion") ?? "14.0"; debuggeeSideVisualizerAssemblyName = $"Microsoft.VisualStudio.DebuggerVisualizers, Version={vsVersion}.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; } string visualizerDescription = uiSideVisualizerTypeName; argValueTypeBuilder.Free(); // Try to get the Visualizer Description. If no description is specified, we will fall back to the Visualizer Type Name. foreach (var namedArg in attributeData.NamedArguments) { if (namedArg.MemberInfo.Name == "Description") { visualizerDescription = (string)namedArg.TypedValue.Value; break; } } builder.Add(new DkmClrDebuggerVisualizerAttribute( targetMember: null, uiSideVisualizerTypeName: uiSideVisualizerTypeName, uiSideVisualizerAssemblyName: uiSideVisualizerAssemblyName, uiSideVisualizerAssemblyLocation: Evaluation.DkmClrCustomVisualizerAssemblyLocation.Unknown, debuggeeSideVisualizerTypeName: debuggeeSideVisualizerTypeName, debuggeeSideVisualizerAssemblyName: debuggeeSideVisualizerAssemblyName, visualizerDescription: visualizerDescription)); } return builder.ToArrayAndFree(); }
private static DkmClrDebuggerDisplayAttribute GetDebuggerDisplayAttribute(System.Type type) { var attributeData = type.GetCustomAttributesData().FirstOrDefault(data => data.AttributeType == typeof(DebuggerDisplayAttribute)); if (attributeData == null) { return null; } return new DkmClrDebuggerDisplayAttribute(type.AssemblyQualifiedName) { Name = (string)attributeData.NamedArguments.SingleOrDefault(arg => arg.MemberName == "Name").TypedValue.Value, Value = (string)attributeData.ConstructorArguments.Single().Value, TypeName = (string)attributeData.NamedArguments.SingleOrDefault(arg => arg.MemberName == "Type").TypedValue.Value, }; }