提交 6cbc6006 编写于 作者: C Charles Stoner

Use Unicode escape sequences for control characters

上级 fd252ab7
......@@ -284,7 +284,7 @@ internal static string FormatString(string str, bool useQuotes)
builder.Append(quote);
for (int i = 0; i < str.Length; i++)
{
FormatStringChar(ref pooledBuilder, str, i, str[i], quote, useLanguageSpecificEscapes: useQuotes, useUnicodeEscapes: false);
FormatStringChar(ref pooledBuilder, str, i, str[i], quote, useLanguageSpecificEscapes: useQuotes, useUnicodeEscapes: useQuotes);
}
builder.Append(quote);
return pooledBuilder.ToStringAndFree();
......@@ -312,7 +312,7 @@ internal static string FormatLiteral(char c, ObjectDisplayOptions options)
{
builder.Append(quote);
}
FormatStringChar(ref pooledBuilder, str: null, index: 0, c: c, quote: quote, useLanguageSpecificEscapes: useQuotes, useUnicodeEscapes: !includeCodePoints);
FormatStringChar(ref pooledBuilder, str: null, index: 0, c: c, quote: quote, useLanguageSpecificEscapes: useQuotes, useUnicodeEscapes: useQuotes);
if (useQuotes)
{
builder.Append(quote);
......
......@@ -113,7 +113,7 @@ public void Characters()
Assert.Equal("39 '\\''", ObjectDisplay.FormatLiteral('\'', ObjectDisplayOptions.UseQuotes | ObjectDisplayOptions.IncludeCodePoints));
Assert.Equal("39 '", ObjectDisplay.FormatLiteral('\'', ObjectDisplayOptions.IncludeCodePoints));
Assert.Equal("0x001e '\u001e'", ObjectDisplay.FormatLiteral('\u001e', ObjectDisplayOptions.UseQuotes | ObjectDisplayOptions.IncludeCodePoints | ObjectDisplayOptions.UseHexadecimalNumbers));
Assert.Equal("0x001e '\\u001e'", ObjectDisplay.FormatLiteral('\u001e', ObjectDisplayOptions.UseQuotes | ObjectDisplayOptions.IncludeCodePoints | ObjectDisplayOptions.UseHexadecimalNumbers));
Assert.Equal("0x001e \u001e", ObjectDisplay.FormatLiteral('\u001e', ObjectDisplayOptions.IncludeCodePoints | ObjectDisplayOptions.UseHexadecimalNumbers));
Assert.Equal("0x0008 '\\b'", ObjectDisplay.FormatLiteral('\b', ObjectDisplayOptions.UseQuotes | ObjectDisplayOptions.IncludeCodePoints | ObjectDisplayOptions.UseHexadecimalNumbers));
......@@ -157,12 +157,12 @@ public void Strings()
// Formatting with quotes should escape specific control characters.
var expected =
"\"\\0\u0001\u0002\u0003\u0004\u0005\u0006\\a\\b\\t\\n\\v\\f\\r\u000e\u000f\u0010" +
"\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d" +
"\u001e\u001f !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[" +
"\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007f\u0080\u0081\u0082\u0083\u0084\u0085" +
"\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092" +
"\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f" +
"\"\\0\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\a\\b\\t\\n\\v\\f\\r\\u000e\\u000f\\u0010" +
"\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001a\\u001b\\u001c\\u001d" +
"\\u001e\\u001f !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[" +
"\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\\u007f\\u0080\\u0081\\u0082\\u0083\\u0084\\u0085" +
"\\u0086\\u0087\\u0088\\u0089\\u008a\\u008b\\u008c\\u008d\\u008e\\u008f\\u0090\\u0091\\u0092" +
"\\u0093\\u0094\\u0095\\u0096\\u0097\\u0098\\u0099\\u009a\\u009b\\u009c\\u009d\\u009e\\u009f" +
" ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèé" +
"êëìíîïðñòóôõö÷øùúûüýþ\"";
Assert.Equal(
......
......@@ -1679,7 +1679,7 @@ public void UnicodeChar()
value = CreateDkmClrValue('\u001f');
evalResult = FormatResult("c", value, inspectionContext: CreateDkmInspectionContext(radix: 16));
Verify(evalResult,
EvalResult("c", "0x001f '\u001f'", "char", "c", editableValue: "'\\u001f'"));
EvalResult("c", "0x001f '\\u001f'", "char", "c", editableValue: "'\\u001f'"));
// This char is not printable, but there is a specific escape character.
value = CreateDkmClrValue('\u0007');
......@@ -1688,6 +1688,16 @@ public void UnicodeChar()
EvalResult("c", "0x0007 '\\a'", "char", "c", editableValue: "'\\a'"));
}
[WorkItem(1138095)]
[Fact]
public void UnicodeString()
{
var value = CreateDkmClrValue("\u1234\u001f\u0007");
var evalResult = FormatResult("s", value);
Verify(evalResult,
EvalResult("s", $"\"{'\u1234'}\\u001f\\a\"", "string", "s", editableValue: $"\"{'\u1234'}\\u001f\\a\"", flags: DkmEvaluationResultFlags.RawString));
}
[WorkItem(1002381)]
[Fact]
public void BaseTypeEditableValue()
......
......@@ -50,7 +50,7 @@ public void NoQuotes_String()
value = CreateDkmClrValue("a\r\n\tb\v\b\u001ec", type: stringType);
evalResult = FormatResult("s", value, inspectionContext: inspectionContext);
Verify(evalResult,
EvalResult("s", "a\r\n\tb\v\b\u001ec", "string", "s", editableValue: "\"a\\r\\n\\tb\\v\\b\u001ec\"", flags: DkmEvaluationResultFlags.RawString));
EvalResult("s", "a\r\n\tb\v\b\u001ec", "string", "s", editableValue: "\"a\\r\\n\\tb\\v\\b\\u001ec\"", flags: DkmEvaluationResultFlags.RawString));
// "a\0b"
value = CreateDkmClrValue("a\0b", type: stringType);
......@@ -58,6 +58,12 @@ public void NoQuotes_String()
Verify(evalResult,
EvalResult("s", "a\0b", "string", "s", editableValue: "\"a\\0b\"", flags: DkmEvaluationResultFlags.RawString));
// "\u007f\u009f"
value = CreateDkmClrValue("\u007f\u009f", type: stringType);
evalResult = FormatResult("s", value, inspectionContext: inspectionContext);
Verify(evalResult,
EvalResult("s", "\u007f\u009f", "string", "s", editableValue: "\"\\u007f\\u009f\"", flags: DkmEvaluationResultFlags.RawString));
// " " with alias
value = CreateDkmClrValue(" ", type: stringType, alias: "1", evalFlags: DkmEvaluationResultFlags.HasObjectId);
evalResult = FormatResult("s", value, inspectionContext: inspectionContext);
......@@ -118,6 +124,12 @@ public void NoQuotes_Char()
Verify(evalResult,
EvalResult("c", "30 \u001e", "char", "c", editableValue: "'\\u001e'", flags: DkmEvaluationResultFlags.None));
// '\u007f'
value = CreateDkmClrValue('\u007f', type: charType);
evalResult = FormatResult("c", value, inspectionContext: inspectionContext);
Verify(evalResult,
EvalResult("c", "127 \u007f", "char", "c", editableValue: "'\\u007f'", flags: DkmEvaluationResultFlags.None));
// array
value = CreateDkmClrValue(new char[] { '1' }, type: charType.MakeArrayType());
evalResult = FormatResult("a", value, inspectionContext: inspectionContext);
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Globalization;
using Microsoft.CodeAnalysis.ExpressionEvaluator;
using Microsoft.VisualStudio.Debugger.Evaluation;
using Xunit;
......@@ -83,7 +84,8 @@ public void Char()
// as a few double-byte characters. Testing all possible characters takes too long.
const string format = "{0} '{1}'";
const string formatUsingHex = "0x{0:x4} '{1}'";
for (char ch = (char)0; ch < 0xff; ch++)
char ch;
for (ch = (char)0; ch < 0xff; ch++)
{
string expected;
switch (ch)
......@@ -119,21 +121,28 @@ public void Char()
expected = "\\\\";
break;
default:
expected = ch.ToString();
expected = FormatStringChar(ch);
break;
}
Assert.Equal(string.Format(format, (int)ch, expected), FormatValue(ch));
Assert.Equal(string.Format(formatUsingHex, (int)ch, expected), FormatValue(ch, useHexadecimal: true));
}
foreach (char ch in new[] { (char)0xabcd, (char)0xfeef, (char)0xffef })
{
Assert.Equal(string.Format(format, (int)ch, ch), FormatValue(ch));
Assert.Equal(string.Format(formatUsingHex, (int)ch, ch), FormatValue(ch, useHexadecimal: true));
}
ch = (char)0xabcd;
Assert.Equal(string.Format(format, (int)ch, ch), FormatValue(ch));
Assert.Equal(string.Format(formatUsingHex, (int)ch, ch), FormatValue(ch, useHexadecimal: true));
Assert.Equal("65535 '\uffff'", FormatValue(char.MaxValue));
Assert.Equal("0xffff '\uffff'", FormatValue(char.MaxValue, useHexadecimal: true));
ch = (char)0xfeef;
Assert.Equal(string.Format(format, (int)ch, ch), FormatValue(ch));
Assert.Equal(string.Format(formatUsingHex, (int)ch, ch), FormatValue(ch, useHexadecimal: true));
ch = (char)0xffef;
Assert.Equal("65519 '\\uffef'", FormatValue(ch));
Assert.Equal("0xffef '\\uffef'", FormatValue(ch, useHexadecimal: true));
ch = char.MaxValue;
Assert.Equal("65535 '\\uffff'", FormatValue(ch));
Assert.Equal("0xffff '\\uffff'", FormatValue(ch, useHexadecimal: true));
}
[Fact]
......@@ -181,27 +190,41 @@ public void String()
expected = "\\\\";
break;
default:
expected = ch.ToString();
expected = FormatStringChar(ch);
break;
}
Assert.Equal(string.Format(format, expected), FormatValue(ch.ToString()));
Assert.Equal(string.Format(format, expected), FormatValue(ch.ToString(), useHexadecimal: true));
}
foreach (char ch in new[] { (char)0xabcd, (char)0xfeef, (char)0xffef })
{
Assert.Equal(string.Format(format, ch), FormatValue(ch.ToString()));
Assert.Equal(string.Format(format, ch), FormatValue(ch.ToString(), useHexadecimal: true));
}
var s = ((char)0xabcd).ToString();
Assert.Equal(string.Format(format, s), FormatValue(s));
Assert.Equal(string.Format(format, s), FormatValue(s, useHexadecimal: true));
s = ((char)0xfeef).ToString();
Assert.Equal(string.Format(format, s), FormatValue(s));
Assert.Equal(string.Format(format, s), FormatValue(s, useHexadecimal: true));
s = ((char)0xffef).ToString();
Assert.Equal("\"\\uffef\"", FormatValue(s));
Assert.Equal("\"\\uffef\"", FormatValue(s, useHexadecimal: true));
Assert.Equal("\"\uffff\"", FormatValue(char.MaxValue.ToString()));
Assert.Equal("\"\uffff\"", FormatValue(char.MaxValue.ToString(), useHexadecimal: true));
s = char.MaxValue.ToString();
Assert.Equal("\"\\uffff\"", FormatValue(s));
Assert.Equal("\"\\uffff\"", FormatValue(s, useHexadecimal: true));
string multiByte = "\ud83c\udfc8";
Assert.Equal(string.Format(format, "🏈"), FormatValue(multiByte));
Assert.Equal(string.Format(format, "🏈"), FormatValue(multiByte, useHexadecimal: true));
}
private static string FormatStringChar(char c)
{
return (CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.Control) ?
$"\\u{((int)c).ToString("x4")}" :
c.ToString();
}
[Fact]
public void Void()
{
......
......@@ -286,6 +286,15 @@ End Class
EvalResult("c", quotedChar, "Char", "c", editableValue:=quotedChar))
End Sub
<Fact>
Public Sub UnicodeString()
Const quotedString = """" & ChrW(&H1234) & """ & ChrW(7)"
Dim value = CreateDkmClrValue(New String({ChrW(&H1234), ChrW(&H0007)}))
Dim result = FormatResult("s", value)
Verify(result,
EvalResult("s", quotedString, "String", "s", editableValue:=quotedString, flags:=DkmEvaluationResultFlags.RawString))
End Sub
<Fact, WorkItem(1002381)>
Public Sub BaseTypeEditableValue()
Dim source = "
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册