/// <summary>
        /// Returns a C# string literal with the given value.
        /// </summary>
        /// <param name="value">The value that the resulting string literal should have.</param>
        /// <param name="options">Options used to customize formatting of an object value.</param>
        /// <returns>A string literal with the given value.</returns>
        /// <remarks>
        /// Escapes non-printable characters.
        /// </remarks>
        public static string FormatLiteral(string value, ObjectDisplayOptions options)
        {
            ValidateOptions(options);

            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            var useQuotes = options.IncludesOption(ObjectDisplayOptions.UseQuotes);
            var quote     = useQuotes ? '"' : '\0';
            PooledStringBuilder pooledBuilder = null;
            StringBuilder       builder       = null;

            if (useQuotes)
            {
                pooledBuilder = PooledStringBuilder.GetInstance();
                builder       = pooledBuilder.Builder;
                builder.Append(quote);
            }
            for (int i = 0; i < value.Length; i++)
            {
                FormatStringChar(ref pooledBuilder, value, i, value[i], quote, useLanguageSpecificEscapes: true, useUnicodeEscapes: true);
            }
            if (useQuotes)
            {
                builder.Append(quote);
            }
            return((pooledBuilder == null) ? value : pooledBuilder.ToStringAndFree());
        }
示例#2
0
        private string FormatPrimitive(
            DkmClrValue value,
            ObjectDisplayOptions options,
            DkmInspectionContext inspectionContext
            )
        {
            Debug.Assert(value != null);
            // check if HostObjectValue is null, since any of these types might actually be a synthetic value as well.
            if (value.HostObjectValue == null)
            {
                return(_hostValueNotFoundString);
            }

            // DateTime is primitive in VB but not in C#.
            object obj;

            if (value.Type.GetLmrType().IsDateTime())
            {
                var dateDataValue = value.GetPropertyValue("Ticks", inspectionContext);
                obj = new DateTime((long)dateDataValue.HostObjectValue);
            }
            else
            {
                obj = value.HostObjectValue;
            }

            return(FormatPrimitiveObject(obj, options));
        }
示例#3
0
        internal override string GetNamesForFlagsEnumValue(
            ArrayBuilder <EnumField> fields,
            object value,
            ulong underlyingValue,
            ObjectDisplayOptions options,
            Type typeToDisplayOpt
            )
        {
            var usedFields = ArrayBuilder <EnumField> .GetInstance();

            FillUsedEnumFields(usedFields, fields, underlyingValue);

            if (usedFields.Count == 0)
            {
                return(null);
            }

            var pooled  = PooledStringBuilder.GetInstance();
            var builder = pooled.Builder;

            for (int i = usedFields.Count - 1; i >= 0; i--) // Backwards to list smallest first.
            {
                AppendEnumTypeAndName(builder, typeToDisplayOpt, usedFields[i].Name);

                if (i > 0)
                {
                    builder.Append(" | ");
                }
            }

            usedFields.Free();

            return(pooled.ToStringAndFree());
        }
示例#4
0
        /// <summary>
        /// Returns a C# string literal with the given value.
        /// </summary>
        /// <param name="value">The value that the resulting string literal should have.</param>
        /// <param name="options">Options used to customize formatting of an object value.</param>
        /// <returns>A string literal with the given value.</returns>
        /// <remarks>
        /// Escapes non-printable characters.
        /// </remarks>
        public static string FormatLiteral(string value, ObjectDisplayOptions options)
        {
            ValidateOptions(options);

            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }

            var useQuotes = options.IncludesOption(ObjectDisplayOptions.UseQuotes);
            var quote     = useQuotes ? '"' : '\0';

            if (!useQuotes && !ReplaceAny(value, quote))
            {
                return(value);
            }

            var pooledBuilder = PooledStringBuilder.GetInstance();
            var builder       = pooledBuilder.Builder;

            if (useQuotes)
            {
                builder.Append(quote);
            }
            foreach (var c in value)
            {
                FormatStringChar(builder, c, quote);
            }
            if (useQuotes)
            {
                builder.Append(quote);
            }
            return(pooledBuilder.ToStringAndFree());
        }
示例#5
0
#pragma warning disable CA1200 // Avoid using cref tags with a prefix
        /// <remarks>
        /// The corresponding native code is in EEUserStringBuilder::ErrTryAppendConstantEnum.
        /// The corresponding roslyn code is in
        /// <see cref="M:Microsoft.CodeAnalysis.SymbolDisplay.AbstractSymbolDisplayVisitor`1.AddEnumConstantValue(Microsoft.CodeAnalysis.INamedTypeSymbol, System.Object, System.Boolean)"/>.
        /// NOTE: no curlies for enum values.
        /// </remarks>
#pragma warning restore CA1200 // Avoid using cref tags with a prefix
        private string GetEnumDisplayString(Type lmrType, DkmClrValue value, ObjectDisplayOptions options, bool includeTypeName, DkmInspectionContext inspectionContext)
        {
            Debug.Assert(lmrType.IsEnum);
            Debug.Assert(value != null);

            object underlyingValue = value.HostObjectValue;

            // check if HostObjectValue is null, since any of these types might actually be a synthetic value as well.
            if (underlyingValue == null)
            {
                return(_hostValueNotFoundString);
            }

            string displayString;

            var fields = ArrayBuilder <EnumField> .GetInstance();

            FillEnumFields(fields, lmrType);
            // We will normalize/extend all enum values to ulong to ensure that we are always comparing the full underlying value.
            ulong valueForComparison = ConvertEnumUnderlyingTypeToUInt64(underlyingValue, Type.GetTypeCode(lmrType));
            var   typeToDisplayOpt   = includeTypeName ? lmrType : null;

            if (valueForComparison != 0 && IsFlagsEnum(lmrType))
            {
                displayString = GetNamesForFlagsEnumValue(fields, underlyingValue, valueForComparison, options, typeToDisplayOpt);
            }
            else
            {
                displayString = GetNameForEnumValue(fields, underlyingValue, valueForComparison, options, typeToDisplayOpt);
            }
            fields.Free();

            return(displayString ?? FormatPrimitive(value, options, inspectionContext));
        }
示例#6
0
 internal abstract string GetNameForEnumValue(
     ArrayBuilder <EnumField> fields,
     object value,
     ulong underlyingValue,
     ObjectDisplayOptions options,
     Type typeToDisplayOpt
     );
示例#7
0
        /// <summary>
        /// Returns a string representation of an object of primitive type.
        /// </summary>
        /// <param name="obj">A value to display as a string.</param>
        /// <param name="options">Options used to customize formatting of an object value.</param>
        /// <returns>A string representation of an object of primitive type (or null if the type is not supported).</returns>
        /// <remarks>
        /// Handles <see cref="bool"/>, <see cref="string"/>, <see cref="double"/> and <c>null</c>.
        /// </remarks>
        public static string?FormatPrimitive(object?obj, ObjectDisplayOptions options)
        {
            if (obj is null)
            {
                return(NullLiteral);
            }

            var type = obj.GetType();

            if (type.IsEnum)
            {
                type = Enum.GetUnderlyingType(type);
            }

            if (type == typeof(string))
            {
                return(FormatLiteral((string)obj, options));
            }

            if (type == typeof(bool))
            {
                return(FormatLiteral((bool)obj));
            }

            if (type == typeof(double))
            {
                return(FormatLiteral((double)obj, options));
            }

            return(null);
        }
示例#8
0
 internal static bool IncludesOption(
     this ObjectDisplayOptions options,
     ObjectDisplayOptions flag
     )
 {
     return((options & flag) == flag);
 }
示例#9
0
#pragma warning disable RS0010
        /// <remarks>
        /// The corresponding native code is in EEUserStringBuilder::ErrTryAppendConstantEnum.
        /// The corresponding roslyn code is in
        /// <see cref="M:Microsoft.CodeAnalysis.SymbolDisplay.AbstractSymbolDisplayVisitor`1.AddEnumConstantValue(Microsoft.CodeAnalysis.INamedTypeSymbol, System.Object, System.Boolean)"/>.
        /// NOTE: no curlies for enum values.
        /// </remarks>
#pragma warning restore RS0010
        private string GetEnumDisplayString(Type lmrType, DkmClrValue value, ObjectDisplayOptions options, bool includeTypeName)
        {
            Debug.Assert(lmrType.IsEnum);
            Debug.Assert(value != null);

            object underlyingValue = value.HostObjectValue;

            Debug.Assert(underlyingValue != null);

            string displayString;

            ArrayBuilder <EnumField> fields = ArrayBuilder <EnumField> .GetInstance();

            FillEnumFields(fields, lmrType);
            // We will normalize/extend all enum values to ulong to ensure that we are always comparing the full underlying value.
            ulong valueForComparison = ConvertEnumUnderlyingTypeToUInt64(underlyingValue, Type.GetTypeCode(lmrType));
            var   typeToDisplayOpt   = includeTypeName ? lmrType : null;

            if (valueForComparison != 0 && IsFlagsEnum(lmrType))
            {
                displayString = GetNamesForFlagsEnumValue(fields, underlyingValue, valueForComparison, options, typeToDisplayOpt);
            }
            else
            {
                displayString = GetNameForEnumValue(fields, underlyingValue, valueForComparison, options, typeToDisplayOpt);
            }
            fields.Free();

            return(displayString ?? FormatPrimitive(value, options));
        }
示例#10
0
        internal static string FormatLiteral(
            ulong value,
            ObjectDisplayOptions options,
            CultureInfo cultureInfo = null
            )
        {
            var pooledBuilder = PooledStringBuilder.GetInstance();
            var sb            = pooledBuilder.Builder;

            if (options.IncludesOption(ObjectDisplayOptions.UseHexadecimalNumbers))
            {
                sb.Append("0x");
                sb.Append(value.ToString("x16"));
            }
            else
            {
                sb.Append(value.ToString(GetFormatCulture(cultureInfo)));
            }

            if (options.IncludesOption(ObjectDisplayOptions.IncludeTypeSuffix))
            {
                sb.Append("UL");
            }

            return(pooledBuilder.ToStringAndFree());
        }
示例#11
0
 internal abstract string GetArrayDisplayString(
     DkmClrAppDomain appDomain,
     Type lmrType,
     ReadOnlyCollection <int> sizes,
     ReadOnlyCollection <int> lowerBounds,
     ObjectDisplayOptions options
     );
示例#12
0
        /// <summary>
        /// Returns a C# string literal with the given value.
        /// </summary>
        /// <param name="value">The value that the resulting string literal should have.</param>
        /// <param name="options">Options used to customize formatting of an object value.</param>
        /// <returns>A string literal with the given value.</returns>
        /// <remarks>
        /// Optionally escapes non-printable characters.
        /// </remarks>
        public static string FormatLiteral(string value, ObjectDisplayOptions options)
        {
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }

            const char quote = '"';

            var pooledBuilder = PooledStringBuilder.GetInstance();
            var builder       = pooledBuilder.Builder;

            var useQuotes          = options.IncludesOption(ObjectDisplayOptions.UseQuotes);
            var escapeNonPrintable = options.IncludesOption(ObjectDisplayOptions.EscapeNonPrintableCharacters);

            var isVerbatim = useQuotes && !escapeNonPrintable && ContainsNewLine(value);

            if (useQuotes)
            {
                if (isVerbatim)
                {
                    builder.Append('@');
                }
                builder.Append(quote);
            }

            foreach (var c in value)
            {
                string replaceWith;
                if (escapeNonPrintable && TryReplaceChar(c, out replaceWith))
                {
                    builder.Append(replaceWith);
                }
                else if (useQuotes && c == quote)
                {
                    if (isVerbatim)
                    {
                        builder.Append(quote);
                        builder.Append(quote);
                    }
                    else
                    {
                        builder.Append('\\');
                        builder.Append(quote);
                    }
                }
                else
                {
                    builder.Append(c);
                }
            }

            if (useQuotes)
            {
                builder.Append(quote);
            }

            return(pooledBuilder.ToStringAndFree());
        }
示例#13
0
        internal static string FormatLiteral(decimal value, ObjectDisplayOptions options)
        {
            ValidateOptions(options);

            var result = value.ToString(CultureInfo.InvariantCulture);

            return(options.IncludesOption(ObjectDisplayOptions.IncludeTypeSuffix) ? result + "M" : result);
        }
        protected override string FormatLiteral(
            string value,
            bool useQuotes,
            bool escapeNonPrintable)
        {
            ObjectDisplayOptions objectDisplayOptions = ObjectFormatterHelpers.GetObjectDisplayOptions(useQuotes, escapeNonPrintable, false);

            return(ObjectDisplay.FormatLiteral(value, objectDisplayOptions));
        }
示例#15
0
        internal override string GetArrayDisplayString(Type lmrType, ReadOnlyCollection<int> sizes, ReadOnlyCollection<int> lowerBounds, ObjectDisplayOptions options)
        {
            Debug.Assert(lmrType.IsArray);

            Type originalLmrType = lmrType;

            // Strip off all array types.  We'll process them at the end.
            while (lmrType.IsArray)
            {
                lmrType = lmrType.GetElementType();
            }

            var pooled = PooledStringBuilder.GetInstance();
            var builder = pooled.Builder;
            builder.Append('{');

            // We're showing the type of a value, so "dynamic" does not apply.
            bool unused;
            builder.Append(GetTypeName(new TypeAndCustomInfo(lmrType), escapeKeywordIdentifiers: false, sawInvalidIdentifier: out unused)); // NOTE: call our impl directly, since we're coupled anyway.

            var numSizes = sizes.Count;

            builder.Append('[');
            for (int i = 0; i < numSizes; i++)
            {
                if (i > 0)
                {
                    builder.Append(", ");
                }
                var lowerBound = lowerBounds[i];
                var size = sizes[i];
                if (lowerBound == 0)
                {
                    builder.Append(FormatLiteral(size, options));
                }
                else
                {
                    builder.Append(FormatLiteral(lowerBound, options));
                    builder.Append("..");
                    builder.Append(FormatLiteral(size + lowerBound - 1, options));
                }
            }
            builder.Append(']');

            lmrType = originalLmrType.GetElementType(); // Strip off one layer (already handled).
            while (lmrType.IsArray)
            {
                builder.Append('[');
                builder.Append(',', lmrType.GetArrayRank() - 1);
                builder.Append(']');

                lmrType = lmrType.GetElementType();
            }

            builder.Append('}');
            return pooled.ToStringAndFree();
        }
        protected override string FormatLiteral(
            char c,
            bool useQuotes,
            bool escapeNonPrintable,
            bool includeCodePoints = false)
        {
            ObjectDisplayOptions objectDisplayOptions = ObjectFormatterHelpers.GetObjectDisplayOptions(useQuotes, escapeNonPrintable, includeCodePoints);

            return(ObjectDisplay.FormatLiteral(c, objectDisplayOptions));
        }
示例#17
0
 internal static string FormatLiteral(int value, ObjectDisplayOptions options)
 {
     if (options.IncludesOption(ObjectDisplayOptions.UseHexadecimalNumbers))
     {
         return("0x" + value.ToString("x8"));
     }
     else
     {
         return(value.ToString(CultureInfo.InvariantCulture));
     }
 }
示例#18
0
 internal static string FormatLiteral(
     short value,
     ObjectDisplayOptions options,
     CultureInfo cultureInfo = null)
 {
     if (options.IncludesOption(ObjectDisplayOptions.UseHexadecimalNumbers))
     {
         return("0x" + (value >= 0 ? value.ToString("x4") : ((int)value).ToString("x8")));
     }
     return(value.ToString(ObjectDisplay.GetFormatCulture(cultureInfo)));
 }
示例#19
0
 internal static string FormatLiteral(int value, ObjectDisplayOptions options, CultureInfo cultureInfo = null)
 {
     if (options.IncludesOption(ObjectDisplayOptions.UseHexadecimalNumbers))
     {
         return("0x" + value.ToString("x8"));
     }
     else
     {
         return(value.ToString(GetFormatCulture(cultureInfo)));
     }
 }
示例#20
0
        /// <summary>
        /// Returns a C# string literal with the given value.
        /// </summary>
        /// <param name="value">The value that the resulting string literal should have.</param>
        /// <param name="options">Options used to customize formatting of an object value.</param>
        /// <returns>A string literal with the given value.</returns>
        /// <remarks>
        /// Escapes non-printable characters.
        /// </remarks>
        public static string FormatLiteral(string value, ObjectDisplayOptions options)
        {
            ValidateOptions(options);

            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            return(FormatString(value, options.IncludesOption(ObjectDisplayOptions.UseQuotes) ? '"' : '\0', escapeNonPrintable: true));
        }
示例#21
0
 internal override string FormatLiteral(int value, ObjectDisplayOptions options)
 {
     return(ObjectDisplay.FormatLiteral(
                value,
                options
                & ~(
                    ObjectDisplayOptions.UseQuotes
                    | ObjectDisplayOptions.EscapeNonPrintableCharacters
                    )
                ));
 }
示例#22
0
        /// <summary>
        /// Gets the string representation of a character literal without including the numeric code point.
        /// </summary>
        internal string GetValueStringForCharacter(DkmClrValue value, ObjectDisplayOptions options)
        {
            Debug.Assert(value.Type.GetLmrType().IsCharacter());
            if (UsesHexadecimalNumbers(value))
            {
                options |= ObjectDisplayOptions.UseHexadecimalNumbers;
            }
            var charTemp = FormatLiteral((char)value.HostObjectValue, options);

            Debug.Assert(charTemp != null);
            return(charTemp);
        }
示例#23
0
        internal static string FormatLiteral(
            decimal value,
            ObjectDisplayOptions options,
            CultureInfo cultureInfo = null
            )
        {
            var result = value.ToString(GetFormatCulture(cultureInfo));

            return(options.IncludesOption(ObjectDisplayOptions.IncludeTypeSuffix)
              ? result + "M"
              : result);
        }
示例#24
0
        internal static string FormatLiteral(
            Decimal value,
            ObjectDisplayOptions options,
            CultureInfo cultureInfo = null)
        {
            string str = value.ToString(ObjectDisplay.GetFormatCulture(cultureInfo));

            if (!options.IncludesOption(ObjectDisplayOptions.IncludeTypeSuffix))
            {
                return(str);
            }
            return(str + "M");
        }
示例#25
0
 internal static string FormatLiteral(short value, ObjectDisplayOptions options, CultureInfo cultureInfo = null)
 {
     if (options.IncludesOption(ObjectDisplayOptions.UseHexadecimalNumbers))
     {
         // Special Case: for sbyte and short, specifically, negatives are shown
         // with extra precision.
         return("0x" + (value >= 0 ? value.ToString("x4") : ((int)value).ToString("x8")));
     }
     else
     {
         return(value.ToString(GetFormatCulture(cultureInfo)));
     }
 }
示例#26
0
        internal static string FormatLiteral(char c, ObjectDisplayOptions options)
        {
            const char quote = '\'';

            var pooledBuilder = PooledStringBuilder.GetInstance();
            var builder       = pooledBuilder.Builder;

            if (options.IncludesOption(ObjectDisplayOptions.IncludeCodePoints))
            {
                builder.Append(
                    options.IncludesOption(ObjectDisplayOptions.UseHexadecimalNumbers)
                      ? "0x" + ((int)c).ToString("x4")
                      : ((int)c).ToString()
                    );
                builder.Append(" ");
            }

            var useQuotes          = options.IncludesOption(ObjectDisplayOptions.UseQuotes);
            var escapeNonPrintable = options.IncludesOption(
                ObjectDisplayOptions.EscapeNonPrintableCharacters
                );

            if (useQuotes)
            {
                builder.Append(quote);
            }

            string replaceWith;

            if (escapeNonPrintable && TryReplaceChar(c, out replaceWith))
            {
                builder.Append(replaceWith);
            }
            else if (useQuotes && c == quote)
            {
                builder.Append('\\');
                builder.Append(quote);
            }
            else
            {
                builder.Append(c);
            }

            if (useQuotes)
            {
                builder.Append(quote);
            }

            return(pooledBuilder.ToStringAndFree());
        }
示例#27
0
        internal static string FormatLiteral(sbyte value, ObjectDisplayOptions options)
        {
            ValidateOptions(options);

            if (options.IncludesOption(ObjectDisplayOptions.UseHexadecimalNumbers))
            {
                // Special Case: for sbyte and short, specifically, negatives are shown
                // with extra precision.
                return("0x" + (value >= 0 ? value.ToString("x2") : ((int)value).ToString("x8")));
            }
            else
            {
                return(value.ToString(CultureInfo.InvariantCulture));
            }
        }
示例#28
0
        /// <summary>
        /// Returns a C# character literal with the given value.
        /// </summary>
        /// <param name="c">The value that the resulting character literal should have.</param>
        /// <param name="options">Options used to customize formatting of an object value.</param>
        /// <returns>A character literal with the given value.</returns>
        internal static string FormatLiteral(char c, ObjectDisplayOptions options)
        {
            var includeCodePoints = options.IncludesOption(ObjectDisplayOptions.IncludeCodePoints);
            var result            = FormatString(c.ToString(),
                                                 quote: options.IncludesOption(ObjectDisplayOptions.UseQuotes) ? '\'' : '\0',
                                                 escapeNonPrintable: !includeCodePoints);

            if (includeCodePoints)
            {
                var codepoint = options.IncludesOption(ObjectDisplayOptions.UseHexadecimalNumbers) ? "0x" + ((int)c).ToString("x4") : ((int)c).ToString();
                return(codepoint + " " + result);
            }

            return(result);
        }
示例#29
0
        /// <summary>
        /// Returns a Lua string literal with the given value.
        /// </summary>
        /// <param name="value">The value that the resulting string literal should have.</param>
        /// <param name="options">Options used to customize formatting of an object value.</param>
        /// <returns>A string literal with the given value.</returns>
        /// <remarks>
        /// Optionally escapes non-printable characters.
        /// </remarks>
        public static string FormatLiteral(string value, ObjectDisplayOptions options)
        {
            const char shortStringQuote = '"';

            if (value is null)
            {
                throw new ArgumentNullException(nameof(value));
            }

            var pooledBuilder = PooledStringBuilder.GetInstance();
            var builder       = pooledBuilder.Builder;

            var useQuotes          = options.IncludesOption(ObjectDisplayOptions.UseQuotes);
            var escapeNonPrintable = options.IncludesOption(ObjectDisplayOptions.EscapeNonPrintableCharacters);
            var utf8Escape         = options.IncludesOption(ObjectDisplayOptions.EscapeWithUtf8);

            var isVerbatim = useQuotes && !escapeNonPrintable && ContainsNewLine(value);

            string endDelimiter = "";

            if (useQuotes)
            {
                if (isVerbatim)
                {
                    if (!TryFastGetVerbatimEquals(value.AsSpan(), out var startDelimiter, out endDelimiter !))
                    {
                        (startDelimiter, endDelimiter) = SlowGetVerbatimEquals(value);
                    }
                    builder.Append(startDelimiter);
                }
                else
                {
                    endDelimiter = shortStringQuote.ToString();
                }
            }

            for (var idx = 0; idx < value.Length; idx++)
            {
                var ch = value[idx];
                if (escapeNonPrintable && TryReplaceChar(ch, out var replaceWith, utf8Escape))
                {
                    builder.Append(replaceWith);
                }
示例#30
0
        internal static ObjectDisplayOptions GetObjectDisplayOptions(
            bool useQuotes          = false,
            bool escapeNonPrintable = false,
            bool includeCodePoints  = false)
        {
            ObjectDisplayOptions objectDisplayOptions = ObjectDisplayOptions.None;

            if (useQuotes)
            {
                objectDisplayOptions |= ObjectDisplayOptions.UseQuotes;
            }
            if (escapeNonPrintable)
            {
                objectDisplayOptions |= ObjectDisplayOptions.EscapeNonPrintableCharacters;
            }
            if (includeCodePoints)
            {
                objectDisplayOptions |= ObjectDisplayOptions.IncludeCodePoints;
            }
            return(objectDisplayOptions);
        }
示例#31
0
        internal string FormatPrimitive(DkmClrValue value, ObjectDisplayOptions options)
        {
            Debug.Assert(value != null);

            object obj;

            if (value.Type.GetLmrType().IsDateTime())
            {
                DkmClrValue dateDataValue = value.GetFieldValue(DateTimeUtilities.DateTimeDateDataFieldName);
                Debug.Assert(dateDataValue.HostObjectValue != null);

                obj = DateTimeUtilities.ToDateTime((ulong)dateDataValue.HostObjectValue);
            }
            else
            {
                Debug.Assert(value.HostObjectValue != null);
                obj = value.HostObjectValue;
            }

            return(FormatPrimitiveObject(obj, options));
        }
示例#32
0
        internal static string FormatLiteral(decimal value, ObjectDisplayOptions options, CultureInfo cultureInfo = null)
        {
            var result = value.ToString(GetFormatCulture(cultureInfo));

            return options.IncludesOption(ObjectDisplayOptions.IncludeTypeSuffix) ? result + "M" : result;
        }
 /// <summary>
 /// Gets the string representation of a character literal without including the numeric code point.
 /// </summary>
 internal string GetValueStringForCharacter(DkmClrValue value, DkmInspectionContext inspectionContext, ObjectDisplayOptions options)
 {
     Debug.Assert(value.Type.GetLmrType().IsCharacter());
     if (UsesHexadecimalNumbers(inspectionContext))
     {
         options |= ObjectDisplayOptions.UseHexadecimalNumbers;
     }
     var charTemp = FormatLiteral((char)value.HostObjectValue, options);
     Debug.Assert(charTemp != null);
     return charTemp;
 }
 internal abstract string FormatString(string str, ObjectDisplayOptions options);
 internal override string FormatString(string str, ObjectDisplayOptions options)
 {
     return ObjectDisplay.FormatString(str, useQuotes: options.IncludesOption(ObjectDisplayOptions.UseQuotes));
 }
 internal abstract string FormatLiteral(int value, ObjectDisplayOptions options);
 internal abstract string FormatPrimitiveObject(object value, ObjectDisplayOptions options);
示例#38
0
        internal static string FormatLiteral(ulong value, ObjectDisplayOptions options)
        {
            var pooledBuilder = PooledStringBuilder.GetInstance();
            var sb = pooledBuilder.Builder;

            if (options.IncludesOption(ObjectDisplayOptions.UseHexadecimalNumbers))
            {
                sb.Append("0x");
                sb.Append(value.ToString("x16"));
            }
            else
            {
                sb.Append(value.ToString(CultureInfo.InvariantCulture));
            }

            if (options.IncludesOption(ObjectDisplayOptions.IncludeTypeSuffix))
            {
                sb.Append("UL");
            }

            return pooledBuilder.ToStringAndFree();
        }
示例#39
0
        internal static string FormatLiteral(uint value, ObjectDisplayOptions options, CultureInfo cultureInfo = null)
        {
            var pooledBuilder = PooledStringBuilder.GetInstance();
            var sb = pooledBuilder.Builder;

            if (options.IncludesOption(ObjectDisplayOptions.UseHexadecimalNumbers))
            {
                sb.Append("0x");
                sb.Append(value.ToString("x8"));
            }
            else
            {
                sb.Append(value.ToString(GetFormatCulture(cultureInfo)));
            }

            if (options.IncludesOption(ObjectDisplayOptions.IncludeTypeSuffix))
            {
                sb.Append('U');
            }

            return pooledBuilder.ToStringAndFree();
        }
示例#40
0
        /// <summary>
        /// Returns a C# character literal with the given value.
        /// </summary>
        /// <param name="c">The value that the resulting character literal should have.</param>
        /// <param name="options">Options used to customize formatting of an object value.</param>
        /// <returns>A character literal with the given value.</returns>
        internal static string FormatLiteral(char c, ObjectDisplayOptions options)
        {
            const char quote = '\'';

            var pooledBuilder = PooledStringBuilder.GetInstance();
            var builder = pooledBuilder.Builder;

            if (options.IncludesOption(ObjectDisplayOptions.IncludeCodePoints))
            {
                builder.Append(options.IncludesOption(ObjectDisplayOptions.UseHexadecimalNumbers) ? "0x" + ((int)c).ToString("x4") : ((int)c).ToString());
                builder.Append(" ");
            }

            var useQuotes = options.IncludesOption(ObjectDisplayOptions.UseQuotes);
            var escapeNonPrintable = options.IncludesOption(ObjectDisplayOptions.EscapeNonPrintableCharacters);

            if (useQuotes)
            {
                builder.Append(quote);
            }

            string replaceWith;
            if (escapeNonPrintable && TryReplaceChar(c, out replaceWith))
            {
                builder.Append(replaceWith);
            }
            else if (useQuotes && c == quote)
            {
                builder.Append('\\');
                builder.Append(quote);
            }
            else
            {
                builder.Append(c);
            }

            if (useQuotes)
            {
                builder.Append(quote);
            }

            return pooledBuilder.ToStringAndFree();
        }
示例#41
0
 internal static string FormatLiteral(short value, ObjectDisplayOptions options)
 {
     if (options.IncludesOption(ObjectDisplayOptions.UseHexadecimalNumbers))
     {
         // Special Case: for sbyte and short, specifically, negatives are shown
         // with extra precision.
         return "0x" + (value >= 0 ? value.ToString("x4") : ((int)value).ToString("x8"));
     }
     else
     {
         return value.ToString(CultureInfo.InvariantCulture);
     }
 }
 internal override string FormatLiteral(int value, ObjectDisplayOptions options)
 {
     return ObjectDisplay.FormatLiteral(value, options & ~ObjectDisplayOptions.UseQuotes);
 }
示例#43
0
 internal override string FormatPrimitiveObject(object value, ObjectDisplayOptions options)
 {
     return ObjectDisplay.FormatPrimitive(value, options);
 }
示例#44
0
 internal override string FormatLiteral(char c, ObjectDisplayOptions options)
 {
     return ObjectDisplay.FormatLiteral(c, options);
 }
示例#45
0
        internal override string GetNamesForFlagsEnumValue(ArrayBuilder<EnumField> fields, object value, ulong underlyingValue, ObjectDisplayOptions options, Type typeToDisplayOpt)
        {
            var usedFields = ArrayBuilder<EnumField>.GetInstance();
            FillUsedEnumFields(usedFields, fields, underlyingValue);

            if (usedFields.Count == 0)
            {
                return null;
            }

            var pooled = PooledStringBuilder.GetInstance();
            var builder = pooled.Builder;

            for (int i = usedFields.Count - 1; i >= 0; i--) // Backwards to list smallest first.
            {
                AppendEnumTypeAndName(builder, typeToDisplayOpt, usedFields[i].Name);

                if (i > 0)
                {
                    builder.Append(" | ");
                }
            }

            usedFields.Free();

            return pooled.ToStringAndFree();
        }
示例#46
0
 /// <summary>
 /// Determines if a flag is set on the <see cref="ObjectDisplayOptions"/> enum.
 /// </summary>
 /// <param name="options">The value to check.</param>
 /// <param name="flag">An enum field that specifies the flag.</param>
 /// <returns>Whether the <paramref name="flag"/> is set on the <paramref name="options"/>.</returns>
 internal static bool IncludesOption(this ObjectDisplayOptions options, ObjectDisplayOptions flag)
 {
     return (options & flag) == flag;
 }
示例#47
0
        internal override string GetNameForEnumValue(ArrayBuilder<EnumField> fields, object value, ulong underlyingValue, ObjectDisplayOptions options, Type typeToDisplayOpt)
        {
            foreach (var field in fields)
            {
                // First match wins (deterministic since sorted).
                if (underlyingValue == field.Value)
                {
                    var pooled = PooledStringBuilder.GetInstance();
                    var builder = pooled.Builder;

                    AppendEnumTypeAndName(builder, typeToDisplayOpt, field.Name);

                    return pooled.ToStringAndFree();
                }
            }

            return null;
        }
#pragma warning disable RS0010
        /// <remarks>
        /// The corresponding native code is in EEUserStringBuilder::ErrTryAppendConstantEnum.
        /// The corresponding roslyn code is in 
        /// <see cref="M:Microsoft.CodeAnalysis.SymbolDisplay.AbstractSymbolDisplayVisitor`1.AddEnumConstantValue(Microsoft.CodeAnalysis.INamedTypeSymbol, System.Object, System.Boolean)"/>.
        /// NOTE: no curlies for enum values.
        /// </remarks>
#pragma warning restore RS0010
        private string GetEnumDisplayString(Type lmrType, DkmClrValue value, ObjectDisplayOptions options, bool includeTypeName, DkmInspectionContext inspectionContext)
        {
            Debug.Assert(lmrType.IsEnum);
            Debug.Assert(value != null);

            object underlyingValue = value.HostObjectValue;
            Debug.Assert(underlyingValue != null);

            string displayString;

            ArrayBuilder<EnumField> fields = ArrayBuilder<EnumField>.GetInstance();
            FillEnumFields(fields, lmrType);
            // We will normalize/extend all enum values to ulong to ensure that we are always comparing the full underlying value.
            ulong valueForComparison = ConvertEnumUnderlyingTypeToUInt64(underlyingValue, Type.GetTypeCode(lmrType));
            var typeToDisplayOpt = includeTypeName ? lmrType : null;
            if (valueForComparison != 0 && IsFlagsEnum(lmrType))
            {
                displayString = GetNamesForFlagsEnumValue(fields, underlyingValue, valueForComparison, options, typeToDisplayOpt);
            }
            else
            {
                displayString = GetNameForEnumValue(fields, underlyingValue, valueForComparison, options, typeToDisplayOpt);
            }
            fields.Free();

            return displayString ?? FormatPrimitive(value, options, inspectionContext);
        }
示例#49
0
 internal override string FormatLiteral(int value, ObjectDisplayOptions options)
 {
     return ObjectDisplay.FormatLiteral(value, options & ~(ObjectDisplayOptions.UseQuotes | ObjectDisplayOptions.EscapeNonPrintableCharacters));
 }
        internal string GetValueString(DkmClrValue value, DkmInspectionContext inspectionContext, ObjectDisplayOptions options, GetValueFlags flags)
        {
            if (value.IsError())
            {
                return (string)value.HostObjectValue;
            }

            if (UsesHexadecimalNumbers(inspectionContext))
            {
                options |= ObjectDisplayOptions.UseHexadecimalNumbers;
            }

            var lmrType = value.Type.GetLmrType();
            if (IsPredefinedType(lmrType) && !lmrType.IsObject())
            {
                if (lmrType.IsString())
                {
                    var stringValue = (string)value.HostObjectValue;
                    if (stringValue == null)
                    {
                        return _nullString;
                    }
                    return IncludeObjectId(
                        value,
                        FormatString(stringValue, options),
                        flags);
                }
                else if (lmrType.IsCharacter())
                {
                    return IncludeObjectId(
                        value,
                        FormatLiteral((char)value.HostObjectValue, options | ObjectDisplayOptions.IncludeCodePoints),
                        flags);
                }
                else
                {
                    return IncludeObjectId(
                        value,
                        FormatPrimitive(value, options & ~ObjectDisplayOptions.UseQuotes, inspectionContext),
                        flags);
                }
            }
            else if (value.IsNull && !lmrType.IsPointer)
            {
                return _nullString;
            }
            else if (lmrType.IsEnum)
            {
                return IncludeObjectId(
                    value,
                    GetEnumDisplayString(lmrType, value, options, (flags & GetValueFlags.IncludeTypeName) != 0, inspectionContext),
                    flags);
            }
            else if (lmrType.IsArray)
            {
                return IncludeObjectId(
                    value,
                    GetArrayDisplayString(lmrType, value.ArrayDimensions, value.ArrayLowerBounds, options),
                    flags);
            }
            else if (lmrType.IsPointer)
            {
                // NOTE: the HostObjectValue will have a size corresponding to the process bitness
                // and FormatPrimitive will adjust accordingly.
                var tmp = FormatPrimitive(value, ObjectDisplayOptions.UseHexadecimalNumbers, inspectionContext); // Always in hex.
                Debug.Assert(tmp != null);
                return tmp;
            }
            else if (lmrType.IsNullable())
            {
                var nullableValue = value.GetNullableValue(inspectionContext);
                // It should be impossible to nest nullables, so this recursion should introduce only a single extra stack frame.
                return nullableValue == null
                    ? _nullString
                    : GetValueString(nullableValue, inspectionContext, ObjectDisplayOptions.None, GetValueFlags.IncludeTypeName);
            }

            // "value.EvaluateToString()" will check "Call string-conversion function on objects in variables windows"
            // (Tools > Options setting) and call "value.ToString()" if appropriate.
            return IncludeObjectId(
                value,
                string.Format(_defaultFormat, value.EvaluateToString(inspectionContext) ?? inspectionContext.GetTypeName(value.Type, CustomTypeInfo: null, FormatSpecifiers: NoFormatSpecifiers)),
                flags);
        }
示例#51
0
 internal override string FormatString(string str, ObjectDisplayOptions options)
 {
     return ObjectDisplay.FormatLiteral(str, options);
 }
        internal string FormatPrimitive(DkmClrValue value, ObjectDisplayOptions options, DkmInspectionContext inspectionContext)
        {
            Debug.Assert(value != null);

            object obj;
            if (value.Type.GetLmrType().IsDateTime())
            {
                DkmClrValue dateDataValue = value.GetFieldValue(DateTimeUtilities.DateTimeDateDataFieldName, inspectionContext);
                Debug.Assert(dateDataValue.HostObjectValue != null);

                obj = DateTimeUtilities.ToDateTime((ulong)dateDataValue.HostObjectValue);
            }
            else
            {
                Debug.Assert(value.HostObjectValue != null);
                obj = value.HostObjectValue;
            }

            return FormatPrimitiveObject(obj, options);
        }
示例#53
0
        /// <summary>
        /// Returns a C# string literal with the given value.
        /// </summary>
        /// <param name="value">The value that the resulting string literal should have.</param>
        /// <param name="options">Options used to customize formatting of an object value.</param>
        /// <returns>A string literal with the given value.</returns>
        /// <remarks>
        /// Optionally escapes non-printable characters.
        /// </remarks>
        public static string FormatLiteral(string value, ObjectDisplayOptions options)
        {
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }

            const char quote = '"';

            var pooledBuilder = PooledStringBuilder.GetInstance();
            var builder = pooledBuilder.Builder;

            var useQuotes = options.IncludesOption(ObjectDisplayOptions.UseQuotes);
            var escapeNonPrintable = options.IncludesOption(ObjectDisplayOptions.EscapeNonPrintableCharacters);

            var isVerbatim = useQuotes && !escapeNonPrintable && ContainsNewLine(value);

            if (useQuotes)
            {
                if (isVerbatim)
                {
                    builder.Append('@');
                }
                builder.Append(quote);
            }

            foreach (var c in value)
            {
                string replaceWith;
                if (escapeNonPrintable && TryReplaceChar(c, out replaceWith))
                {
                    builder.Append(replaceWith);
                }
                else if (useQuotes && c == quote)
                {
                    if (isVerbatim)
                    {
                        builder.Append(quote);
                        builder.Append(quote);
                    }
                    else
                    {
                        builder.Append('\\');
                        builder.Append(quote);
                    }
                }
                else
                {
                    builder.Append(c);
                }
            }

            if (useQuotes)
            {
                builder.Append(quote);
            }

            return pooledBuilder.ToStringAndFree();
        }
 internal abstract string GetArrayDisplayString(Type lmrType, ReadOnlyCollection<int> sizes, ReadOnlyCollection<int> lowerBounds, ObjectDisplayOptions options);
示例#55
0
        /// <summary>
        /// Returns a string representation of an object of primitive type.
        /// </summary>
        /// <param name="obj">A value to display as a string.</param>
        /// <param name="options">Options used to customize formatting of an object value.</param>
        /// <returns>A string representation of an object of primitive type (or null if the type is not supported).</returns>
        /// <remarks>
        /// Handles <see cref="bool"/>, <see cref="string"/>, <see cref="char"/>, <see cref="sbyte"/>
        /// <see cref="byte"/>, <see cref="short"/>, <see cref="ushort"/>, <see cref="int"/>, <see cref="uint"/>,
        /// <see cref="long"/>, <see cref="ulong"/>, <see cref="double"/>, <see cref="float"/>, <see cref="decimal"/>,
        /// and <c>null</c>.
        /// </remarks>
        public static string FormatPrimitive(object obj, ObjectDisplayOptions options)
        {
            if (obj == null)
            {
                return NullLiteral;
            }

            Type type = obj.GetType();
            if (type.GetTypeInfo().IsEnum)
            {
                type = Enum.GetUnderlyingType(type);
            }

            if (type == typeof(int))
            {
                return FormatLiteral((int)obj, options);
            }

            if (type == typeof(string))
            {
                return FormatLiteral((string)obj, options);
            }

            if (type == typeof(bool))
            {
                return FormatLiteral((bool)obj);
            }

            if (type == typeof(char))
            {
                return FormatLiteral((char)obj, options);
            }

            if (type == typeof(byte))
            {
                return FormatLiteral((byte)obj, options);
            }

            if (type == typeof(short))
            {
                return FormatLiteral((short)obj, options);
            }

            if (type == typeof(long))
            {
                return FormatLiteral((long)obj, options);
            }

            if (type == typeof(double))
            {
                return FormatLiteral((double)obj, options);
            }

            if (type == typeof(ulong))
            {
                return FormatLiteral((ulong)obj, options);
            }

            if (type == typeof(uint))
            {
                return FormatLiteral((uint)obj, options);
            }

            if (type == typeof(ushort))
            {
                return FormatLiteral((ushort)obj, options);
            }

            if (type == typeof(sbyte))
            {
                return FormatLiteral((sbyte)obj, options);
            }

            if (type == typeof(float))
            {
                return FormatLiteral((float)obj, options);
            }

            if (type == typeof(decimal))
            {
                return FormatLiteral((decimal)obj, options);
            }

            return null;
        }
 internal abstract string GetNameForEnumValue(ArrayBuilder<EnumField> fields, object value, ulong underlyingValue, ObjectDisplayOptions options, Type typeToDisplayOpt);
示例#57
0
 internal static string FormatLiteral(int value, ObjectDisplayOptions options)
 {
     if (options.IncludesOption(ObjectDisplayOptions.UseHexadecimalNumbers))
     {
         return "0x" + value.ToString("x8");
     }
     else
     {
         return value.ToString(CultureInfo.InvariantCulture);
     }
 }
 internal abstract string FormatLiteral(char c, ObjectDisplayOptions options);
示例#59
0
        internal static string FormatLiteral(decimal value, ObjectDisplayOptions options)
        {
            var result = value.ToString(CultureInfo.InvariantCulture);

            return options.IncludesOption(ObjectDisplayOptions.IncludeTypeSuffix) ? result + "M" : result;
        }
示例#60
0
 internal static string FormatLiteral(int value, ObjectDisplayOptions options, CultureInfo cultureInfo = null)
 {
     if (options.IncludesOption(ObjectDisplayOptions.UseHexadecimalNumbers))
     {
         return "0x" + value.ToString("x8");
     }
     else
     {
         return value.ToString(GetFormatCulture(cultureInfo));
     }
 }