public ObjectFormattingOptions( MemberDisplayFormat memberFormat = MemberDisplayFormat.NoMembers, bool quoteStrings = true, bool useHexadecimalNumbers = false, bool includeCodePoints = false, int maxLineLength = Int32.MaxValue, int maxOutputLength = Int32.MaxValue, string memberIndentation = null, string ellipsis = null, string lineBreak = null) { if (!memberFormat.IsValid()) { throw new ArgumentOutOfRangeException("memberFormat"); } this.MemberFormat = memberFormat; this.QuoteStrings = quoteStrings; this.IncludeCodePoints = includeCodePoints; this.MaxOutputLength = (maxOutputLength >= 0) ? maxOutputLength : int.MaxValue; this.MaxLineLength = (maxLineLength >= 0) ? maxLineLength : int.MaxValue; this.UseHexadecimalNumbers = useHexadecimalNumbers; this.MemberIndentation = memberIndentation ?? " "; this.Ellipsis = ellipsis ?? "..."; this.NewLine = lineBreak ?? Environment.NewLine; }
public ObjectFormattingOptions( MemberDisplayFormat memberFormat = MemberDisplayFormat.NoMembers, bool quoteStrings = true, bool useHexadecimalNumbers = false, bool includeCodePoints = false, int maxLineLength = Int32.MaxValue, int maxOutputLength = Int32.MaxValue, string memberIndentation = null, string ellipsis = null, string lineBreak = null) { if (!memberFormat.IsValid()) { throw new ArgumentOutOfRangeException(nameof(memberFormat)); } this.MemberFormat = memberFormat; this.QuoteStrings = quoteStrings; this.IncludeCodePoints = includeCodePoints; this.MaxOutputLength = (maxOutputLength >= 0) ? maxOutputLength : int.MaxValue; this.MaxLineLength = (maxLineLength >= 0) ? maxLineLength : int.MaxValue; this.UseHexadecimalNumbers = useHexadecimalNumbers; this.MemberIndentation = memberIndentation ?? " "; this.Ellipsis = ellipsis ?? "..."; this.NewLine = lineBreak ?? Environment.NewLine; }
public Visitor( CommonObjectFormatter formatter, BuilderOptions builderOptions, CommonPrimitiveFormatterOptions primitiveOptions, CommonTypeNameFormatterOptions typeNameOptions, MemberDisplayFormat memberDisplayFormat) { _formatter = formatter; _builderOptions = builderOptions; _primitiveOptions = primitiveOptions; _typeNameOptions = typeNameOptions; _memberDisplayFormat = memberDisplayFormat; }
public ObjectFormattingOptions Copy( MemberDisplayFormat? memberFormat = null, bool? quoteStrings = null, bool? useHexadecimalNumbers = null, bool? includeCodePoints = null, int? maxLineLength = null, int? maxOutputLength = null, string memberIndentation = null, string ellipsis = null, string newLine = null) { return new ObjectFormattingOptions( memberFormat ?? this.MemberFormat, quoteStrings ?? this.QuoteStrings, useHexadecimalNumbers ?? this.UseHexadecimalNumbers, includeCodePoints ?? this.IncludeCodePoints, maxLineLength ?? this.MaxLineLength, maxOutputLength ?? this.MaxOutputLength, memberIndentation ?? this.MemberIndentation, ellipsis ?? this.Ellipsis, newLine ?? this.NewLine); }
internal static bool IsValid(this MemberDisplayFormat value) { return(MemberDisplayFormat.SingleLine <= value && value <= MemberDisplayFormat.Hidden); }
private Builder FormatObjectRecursive(Builder result, object obj, bool quoteStrings, MemberDisplayFormat memberFormat, out string name) { name = null; string primitive = _language.FormatPrimitive(obj, quoteStrings, _options.IncludeCodePoints, _options.UseHexadecimalNumbers); if (primitive != null) { result.Append(primitive); return result; } object originalObj = obj; Type originalType = originalObj.GetType(); // // Override KeyValuePair<,>.ToString() to get better dictionary elements formatting: // // { { format(key), format(value) }, ... } // instead of // { [key.ToString(), value.ToString()], ... } // // This is more general than overriding Dictionary<,> debugger proxy attribute since it applies on all // types that return an array of KeyValuePair in their DebuggerDisplay to display items. // if (originalType.IsGenericType && originalType.GetGenericTypeDefinition() == typeof(KeyValuePair<,>)) { if (memberFormat != MemberDisplayFormat.InlineValue) { result.Append(_language.FormatTypeName(originalType, _options)); result.Append(' '); } FormatKeyValuePair(result, originalObj); return result; } if (originalType.IsArray) { if (!VisitedObjects.Add(originalObj)) { result.AppendInfiniteRecursionMarker(); return result; } FormatArray(result, (Array)originalObj, inline: memberFormat != MemberDisplayFormat.List); VisitedObjects.Remove(originalObj); return result; } DebuggerDisplayAttribute debuggerDisplay = GetApplicableDebuggerDisplayAttribute(originalType); if (debuggerDisplay != null) { name = debuggerDisplay.Name; } bool suppressMembers = false; // // TypeName(count) for ICollection implementers // or // TypeName([[DebuggerDisplay.Value]]) // Inline // [[DebuggerDisplay.Value]] // InlineValue // or // [[ToString()]] if ToString overridden // or // TypeName // ICollection collection; if ((collection = originalObj as ICollection) != null) { FormatCollectionHeader(result, collection); } else if (debuggerDisplay != null && !String.IsNullOrEmpty(debuggerDisplay.Value)) { if (memberFormat != MemberDisplayFormat.InlineValue) { result.Append(_language.FormatTypeName(originalType, _options)); result.Append('('); } FormatWithEmbeddedExpressions(result, debuggerDisplay.Value, originalObj); if (memberFormat != MemberDisplayFormat.InlineValue) { result.Append(')'); } suppressMembers = true; } else if (HasOverriddenToString(originalType)) { ObjectToString(result, originalObj); suppressMembers = true; } else { result.Append(_language.FormatTypeName(originalType, _options)); } if (memberFormat == MemberDisplayFormat.NoMembers) { return result; } bool includeNonPublic = memberFormat == MemberDisplayFormat.List; object proxy = GetDebuggerTypeProxy(obj); if (proxy != null) { obj = proxy; includeNonPublic = false; suppressMembers = false; } if (memberFormat != MemberDisplayFormat.List && suppressMembers) { return result; } // TODO (tomat): we should not use recursion RuntimeHelpers.EnsureSufficientExecutionStack(); result.Append(' '); if (!VisitedObjects.Add(originalObj)) { result.AppendInfiniteRecursionMarker(); return result; } // handle special types only if a proxy isn't defined if (proxy == null) { IDictionary dictionary; if ((dictionary = obj as IDictionary) != null) { FormatDictionary(result, dictionary, inline: memberFormat != MemberDisplayFormat.List); return result; } IEnumerable enumerable; if ((enumerable = obj as IEnumerable) != null) { FormatSequence(result, enumerable, inline: memberFormat != MemberDisplayFormat.List); return result; } } FormatObjectMembers(result, obj, originalType, includeNonPublic, inline: memberFormat != MemberDisplayFormat.List); VisitedObjects.Remove(obj); return result; }
private Builder FormatObjectRecursive(Builder result, object obj, bool isRoot, out string debuggerDisplayName) { // TODO (https://github.com/dotnet/roslyn/issues/6689): remove this if (!isRoot && _memberDisplayFormat == MemberDisplayFormat.SeparateLines) { _memberDisplayFormat = MemberDisplayFormat.SingleLine; } debuggerDisplayName = null; string primitive = _formatter.PrimitiveFormatter.FormatPrimitive(obj, _primitiveOptions); if (primitive != null) { result.Append(primitive); return(result); } Type type = obj.GetType(); TypeInfo typeInfo = type.GetTypeInfo(); // // Override KeyValuePair<,>.ToString() to get better dictionary elements formatting: // // { { format(key), format(value) }, ... } // instead of // { [key.ToString(), value.ToString()], ... } // // This is more general than overriding Dictionary<,> debugger proxy attribute since it applies on all // types that return an array of KeyValuePair in their DebuggerDisplay to display items. // if (typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(KeyValuePair <,>)) { if (isRoot) { result.Append(_formatter.TypeNameFormatter.FormatTypeName(type, _typeNameOptions)); result.Append(' '); } FormatKeyValuePair(result, obj); return(result); } if (typeInfo.IsArray) { if (VisitedObjects.Add(obj)) { FormatArray(result, (Array)obj); VisitedObjects.Remove(obj); } else { result.AppendInfiniteRecursionMarker(); } return(result); } DebuggerDisplayAttribute debuggerDisplay = GetApplicableDebuggerDisplayAttribute(typeInfo); if (debuggerDisplay != null) { debuggerDisplayName = debuggerDisplay.Name; } // Suppresses members if inlineMembers is true, // does nothing otherwise. bool suppressInlineMembers = false; // // TypeName(count) for ICollection implementers // or // TypeName([[DebuggerDisplay.Value]]) // Inline // [[DebuggerDisplay.Value]] // Inline && !isRoot // or // [[ToString()]] if ToString overridden // or // TypeName // ICollection collection; if ((collection = obj as ICollection) != null) { FormatCollectionHeader(result, collection); } else if (debuggerDisplay != null && !string.IsNullOrEmpty(debuggerDisplay.Value)) { if (isRoot) { result.Append(_formatter.TypeNameFormatter.FormatTypeName(type, _typeNameOptions)); result.Append('('); } FormatWithEmbeddedExpressions(result, debuggerDisplay.Value, obj); if (isRoot) { result.Append(')'); } suppressInlineMembers = true; } else if (HasOverriddenToString(typeInfo)) { ObjectToString(result, obj); suppressInlineMembers = true; } else { result.Append(_formatter.TypeNameFormatter.FormatTypeName(type, _typeNameOptions)); } MemberDisplayFormat memberFormat = _memberDisplayFormat; if (memberFormat == MemberDisplayFormat.Hidden) { if (collection != null) { // NB: Collections specifically ignore MemberDisplayFormat.Hidden. memberFormat = MemberDisplayFormat.SingleLine; } else { return(result); } } bool includeNonPublic = memberFormat == MemberDisplayFormat.SeparateLines; bool inlineMembers = memberFormat == MemberDisplayFormat.SingleLine; object proxy = GetDebuggerTypeProxy(obj); if (proxy != null) { includeNonPublic = false; suppressInlineMembers = false; } if (!suppressInlineMembers || !inlineMembers) { FormatMembers(result, obj, proxy, includeNonPublic, inlineMembers); } return(result); }
private Builder FormatWithEmbeddedExpressions(Builder result, string format, object obj) { int i = 0; while (i < format.Length) { char c = format[i++]; if (c == '{') { if (i >= 2 && format[i - 2] == '\\') { result.Append('{'); } else { int expressionEnd = format.IndexOf('}', i); bool noQuotes, callableOnly; string memberName; if (expressionEnd == -1 || (memberName = ParseSimpleMemberName(format, i, expressionEnd, out noQuotes, out callableOnly)) == null) { // the expression isn't properly formatted result.Append(format, i - 1, format.Length - i + 1); break; } MemberInfo member = ResolveMember(obj, memberName, callableOnly); if (member == null) { result.AppendFormat(callableOnly ? "!<Method '{0}' not found>" : "!<Member '{0}' not found>", memberName); } else { Exception exception; object value = GetMemberValue(member, obj, out exception); if (exception != null) { FormatException(result, exception); } else { MemberDisplayFormat oldMemberDisplayFormat = _memberDisplayFormat; CommonPrimitiveFormatterOptions oldPrimitiveOptions = _primitiveOptions; _memberDisplayFormat = MemberDisplayFormat.Hidden; _primitiveOptions = new CommonPrimitiveFormatterOptions( _primitiveOptions.NumberRadix, _primitiveOptions.IncludeCharacterCodePoints, quoteStringsAndCharacters: !noQuotes, escapeNonPrintableCharacters: _primitiveOptions.EscapeNonPrintableCharacters, cultureInfo: _primitiveOptions.CultureInfo); string _; FormatObjectRecursive(result, value, isRoot: false, debuggerDisplayName: out _); _primitiveOptions = oldPrimitiveOptions; _memberDisplayFormat = oldMemberDisplayFormat; } } i = expressionEnd + 1; } } else { result.Append(c); } } return(result); }
internal static bool IsValid(this MemberDisplayFormat value) { return(value is >= MemberDisplayFormat.SingleLine and <= MemberDisplayFormat.Hidden); }
private Builder FormatWithEmbeddedExpressions(Builder result, string format, object obj) { int i = 0; while (i < format.Length) { char c = format[i++]; if (c == '{') { if (i >= 2 && format[i - 2] == '\\') { result.Append('{'); } else { int expressionEnd = format.IndexOf('}', i); bool noQuotes, callableOnly; string memberName; if (expressionEnd == -1 || (memberName = ParseSimpleMemberName(format, i, expressionEnd, out noQuotes, out callableOnly)) == null) { // the expression isn't properly formatted result.Append(format, i - 1, format.Length - i + 1); break; } MemberInfo member = ResolveMember(obj, memberName, callableOnly); if (member == null) { result.AppendFormat(callableOnly ? "!<Method '{0}' not found>" : "!<Member '{0}' not found>", memberName); } else { Exception exception; object value = GetMemberValue(member, obj, out exception); if (exception != null) { FormatException(result, exception); } else { MemberDisplayFormat oldMemberDisplayFormat = _memberDisplayFormat; CommonPrimitiveFormatterOptions oldPrimitiveOptions = _primitiveOptions; _memberDisplayFormat = MemberDisplayFormat.Hidden; _primitiveOptions = new CommonPrimitiveFormatterOptions( _primitiveOptions.NumberRadix, _primitiveOptions.IncludeCharacterCodePoints, quoteStringsAndCharacters: !noQuotes, escapeNonPrintableCharacters: _primitiveOptions.EscapeNonPrintableCharacters, cultureInfo: _primitiveOptions.CultureInfo); string _; FormatObjectRecursive(result, value, isRoot: false, debuggerDisplayName: out _); _primitiveOptions = oldPrimitiveOptions; _memberDisplayFormat = oldMemberDisplayFormat; } } i = expressionEnd + 1; } } else { result.Append(c); } } return result; }
private Builder FormatObjectRecursive(Builder result, object obj, bool isRoot, out string debuggerDisplayName) { // TODO (https://github.com/dotnet/roslyn/issues/6689): remove this if (!isRoot && _memberDisplayFormat == MemberDisplayFormat.SeparateLines) { _memberDisplayFormat = MemberDisplayFormat.SingleLine; } debuggerDisplayName = null; string primitive = _formatter.PrimitiveFormatter.FormatPrimitive(obj, _primitiveOptions); if (primitive != null) { result.Append(primitive); return result; } Type type = obj.GetType(); TypeInfo typeInfo = type.GetTypeInfo(); // // Override KeyValuePair<,>.ToString() to get better dictionary elements formatting: // // { { format(key), format(value) }, ... } // instead of // { [key.ToString(), value.ToString()], ... } // // This is more general than overriding Dictionary<,> debugger proxy attribute since it applies on all // types that return an array of KeyValuePair in their DebuggerDisplay to display items. // if (typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(KeyValuePair<,>)) { if (isRoot) { result.Append(_formatter.TypeNameFormatter.FormatTypeName(type, _typeNameOptions)); result.Append(' '); } FormatKeyValuePair(result, obj); return result; } if (typeInfo.IsArray) { if (VisitedObjects.Add(obj)) { FormatArray(result, (Array)obj); VisitedObjects.Remove(obj); } else { result.AppendInfiniteRecursionMarker(); } return result; } DebuggerDisplayAttribute debuggerDisplay = GetApplicableDebuggerDisplayAttribute(typeInfo); if (debuggerDisplay != null) { debuggerDisplayName = debuggerDisplay.Name; } // Suppresses members if inlineMembers is true, // does nothing otherwise. bool suppressInlineMembers = false; // // TypeName(count) for ICollection implementers // or // TypeName([[DebuggerDisplay.Value]]) // Inline // [[DebuggerDisplay.Value]] // Inline && !isRoot // or // [[ToString()]] if ToString overridden // or // TypeName // ICollection collection; if ((collection = obj as ICollection) != null) { FormatCollectionHeader(result, collection); } else if (debuggerDisplay != null && !string.IsNullOrEmpty(debuggerDisplay.Value)) { if (isRoot) { result.Append(_formatter.TypeNameFormatter.FormatTypeName(type, _typeNameOptions)); result.Append('('); } FormatWithEmbeddedExpressions(result, debuggerDisplay.Value, obj); if (isRoot) { result.Append(')'); } suppressInlineMembers = true; } else if (HasOverriddenToString(typeInfo)) { ObjectToString(result, obj); suppressInlineMembers = true; } else { result.Append(_formatter.TypeNameFormatter.FormatTypeName(type, _typeNameOptions)); } MemberDisplayFormat memberFormat = _memberDisplayFormat; if (memberFormat == MemberDisplayFormat.Hidden) { if (collection != null) { // NB: Collections specifically ignore MemberDisplayFormat.Hidden. memberFormat = MemberDisplayFormat.SingleLine; } else { return result; } } bool includeNonPublic = memberFormat == MemberDisplayFormat.SeparateLines; bool inlineMembers = memberFormat == MemberDisplayFormat.SingleLine; object proxy = GetDebuggerTypeProxy(obj); if (proxy != null) { includeNonPublic = false; suppressInlineMembers = false; } if (!suppressInlineMembers || !inlineMembers) { FormatMembers(result, obj, proxy, includeNonPublic, inlineMembers); } return result; }
internal static bool IsValid(this MemberDisplayFormat value) { return(value >= MemberDisplayFormat.NoMembers && value <= MemberDisplayFormat.List); }
private Builder FormatObjectRecursive(Builder result, object obj, bool quoteStrings, MemberDisplayFormat memberFormat, out string name) { name = null; string primitive = _language.FormatPrimitive(obj, quoteStrings, _options.IncludeCodePoints, _options.UseHexadecimalNumbers); if (primitive != null) { result.Append(primitive); return(result); } object originalObj = obj; Type originalType = originalObj.GetType(); // // Override KeyValuePair<,>.ToString() to get better dictionary elements formatting: // // { { format(key), format(value) }, ... } // instead of // { [key.ToString(), value.ToString()], ... } // // This is more general than overriding Dictionary<,> debugger proxy attribute since it applies on all // types that return an array of KeyValuePair in their DebuggerDisplay to display items. // if (originalType.IsGenericType && originalType.GetGenericTypeDefinition() == typeof(KeyValuePair <,>)) { if (memberFormat != MemberDisplayFormat.InlineValue) { result.Append(_language.FormatTypeName(originalType, _options)); result.Append(' '); } FormatKeyValuePair(result, originalObj); return(result); } if (originalType.IsArray) { if (!VisitedObjects.Add(originalObj)) { result.AppendInfiniteRecursionMarker(); return(result); } FormatArray(result, (Array)originalObj, inline: memberFormat != MemberDisplayFormat.List); VisitedObjects.Remove(originalObj); return(result); } DebuggerDisplayAttribute debuggerDisplay = GetApplicableDebuggerDisplayAttribute(originalType); if (debuggerDisplay != null) { name = debuggerDisplay.Name; } bool suppressMembers = false; // // TypeName(count) for ICollection implementers // or // TypeName([[DebuggerDisplay.Value]]) // Inline // [[DebuggerDisplay.Value]] // InlineValue // or // [[ToString()]] if ToString overridden // or // TypeName // ICollection collection; if ((collection = originalObj as ICollection) != null) { FormatCollectionHeader(result, collection); } else if (debuggerDisplay != null && !String.IsNullOrEmpty(debuggerDisplay.Value)) { if (memberFormat != MemberDisplayFormat.InlineValue) { result.Append(_language.FormatTypeName(originalType, _options)); result.Append('('); } FormatWithEmbeddedExpressions(result, debuggerDisplay.Value, originalObj); if (memberFormat != MemberDisplayFormat.InlineValue) { result.Append(')'); } suppressMembers = true; } else if (HasOverriddenToString(originalType)) { ObjectToString(result, originalObj); suppressMembers = true; } else { result.Append(_language.FormatTypeName(originalType, _options)); } if (memberFormat == MemberDisplayFormat.NoMembers) { return(result); } bool includeNonPublic = memberFormat == MemberDisplayFormat.List; object proxy = GetDebuggerTypeProxy(obj); if (proxy != null) { obj = proxy; includeNonPublic = false; suppressMembers = false; } if (memberFormat != MemberDisplayFormat.List && suppressMembers) { return(result); } // TODO (tomat): we should not use recursion RuntimeHelpers.EnsureSufficientExecutionStack(); result.Append(' '); if (!VisitedObjects.Add(originalObj)) { result.AppendInfiniteRecursionMarker(); return(result); } // handle special types only if a proxy isn't defined if (proxy == null) { IDictionary dictionary; if ((dictionary = obj as IDictionary) != null) { FormatDictionary(result, dictionary, inline: memberFormat != MemberDisplayFormat.List); return(result); } IEnumerable enumerable; if ((enumerable = obj as IEnumerable) != null) { FormatSequence(result, enumerable, inline: memberFormat != MemberDisplayFormat.List); return(result); } } FormatObjectMembers(result, obj, originalType, includeNonPublic, inline: memberFormat != MemberDisplayFormat.List); VisitedObjects.Remove(obj); return(result); }