提交 a99a8234 编写于 作者: C Charles Stoner

Implement IDkmClrFormatter2 and IDkmClrFullNameProvider

上级 54bbd967
{
"dependencies": {
"Microsoft.VisualStudio.Debugger.Engine": "14.3.25422"
"Microsoft.VisualStudio.Debugger.Engine": "15.0.25824-RC"
},
"frameworks": {
"netstandard1.3": {
......
......@@ -98,30 +98,12 @@ internal override string GetArrayDisplayString(DkmClrAppDomain appDomain, Type l
return pooled.ToStringAndFree();
}
internal override string GetArrayIndexExpression(int[] indices)
internal override string GetArrayIndexExpression(string[] indices)
{
Debug.Assert(indices != null);
var pooled = PooledStringBuilder.GetInstance();
var builder = pooled.Builder;
builder.Append('[');
bool any = false;
foreach (var index in indices)
{
if (any)
{
builder.Append(", ");
}
builder.Append(index);
any = true;
}
builder.Append(']');
return pooled.ToStringAndFree();
return indices.ToCommaSeparatedString('[', ']');
}
internal override string GetCastExpression(string argument, string type, bool parenthesizeArgument, bool parenthesizeEntireExpression)
internal override string GetCastExpression(string argument, string type, DkmClrCastExpressionOptions options)
{
Debug.Assert(!string.IsNullOrEmpty(argument));
Debug.Assert(!string.IsNullOrEmpty(type));
......@@ -129,15 +111,28 @@ internal override string GetCastExpression(string argument, string type, bool pa
var pooled = PooledStringBuilder.GetInstance();
var builder = pooled.Builder;
if (parenthesizeEntireExpression)
if ((options & DkmClrCastExpressionOptions.ParenthesizeEntireExpression) != 0)
{
builder.Append('(');
}
var castExpressionFormat = parenthesizeArgument ? "({0})({1})" : "({0}){1}";
builder.AppendFormat(castExpressionFormat, type, argument);
if (parenthesizeEntireExpression)
if ((options & DkmClrCastExpressionOptions.ParenthesizeArgument) != 0)
{
argument = $"({argument})";
}
if ((options & DkmClrCastExpressionOptions.ConditionalCast) != 0)
{
builder.Append(argument);
builder.Append(" as ");
builder.Append(type);
}
else
{
builder.Append('(');
builder.Append(type);
builder.Append(')');
builder.Append(argument);
}
if ((options & DkmClrCastExpressionOptions.ParenthesizeEntireExpression) != 0)
{
builder.Append(')');
}
......@@ -147,25 +142,7 @@ internal override string GetCastExpression(string argument, string type, bool pa
internal override string GetTupleExpression(string[] values)
{
Debug.Assert(values != null);
var pooled = PooledStringBuilder.GetInstance();
var builder = pooled.Builder;
builder.Append('(');
bool any = false;
foreach (var value in values)
{
if (any)
{
builder.Append(", ");
}
builder.Append(value);
any = true;
}
builder.Append(')');
return pooled.ToStringAndFree();
return values.ToCommaSeparatedString('(', ')');
}
internal override string GetNamesForFlagsEnumValue(ArrayBuilder<EnumField> fields, object value, ulong underlyingValue, ObjectDisplayOptions options, Type typeToDisplayOpt)
......@@ -215,7 +192,7 @@ internal override string GetNameForEnumValue(ArrayBuilder<EnumField> fields, obj
return null;
}
internal override string GetObjectCreationExpression(string type, string arguments)
internal override string GetObjectCreationExpression(string type, string[] arguments)
{
Debug.Assert(!string.IsNullOrEmpty(type));
......@@ -225,7 +202,7 @@ internal override string GetObjectCreationExpression(string type, string argumen
builder.Append("new ");
builder.Append(type);
builder.Append('(');
builder.Append(arguments);
builder.AppendCommaSeparatedList(arguments);
builder.Append(')');
return pooled.ToStringAndFree();
......
......@@ -10,7 +10,7 @@ namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
internal sealed partial class CSharpFormatter : Formatter
{
public CSharpFormatter()
: base(defaultFormat: "{{{0}}}", nullString: "null")
: base(defaultFormat: "{{{0}}}", nullString: "null", thisString: "this")
{
}
......
{
"dependencies": {
"Microsoft.VisualStudio.Debugger.Engine": "14.3.25422",
"Microsoft.VisualStudio.Debugger.Metadata": "14.3.25421"
"Microsoft.VisualStudio.Debugger.Engine": "15.0.25824-RC",
"Microsoft.VisualStudio.Debugger.Metadata": "15.0.25824-RC"
},
"frameworks": {
".NETPortable,Version=v4.5,Profile=Profile7": { }
......
{
"dependencies": {
"Microsoft.VisualStudio.Debugger.Engine": "14.3.25422",
"Microsoft.VisualStudio.Debugger.Engine": "15.0.25824-RC",
"Microsoft.DiaSymReader": "1.1.0",
"xunit": "2.2.0-beta4-build3444",
"xunit.runner.console": "2.2.0-beta4-build3444",
......
......@@ -279,6 +279,40 @@ public void NonZeroLowerBounds()
EvalResult("[4, 6]", "6", "int", "arrayExpr[4, 6]"));
}
[Fact]
public void Hexadecimal()
{
var value = CreateDkmClrValue(new[] { 10, 20, 30 });
var inspectionContext = CreateDkmInspectionContext(radix: 16);
var evalResult = FormatResult("o", value, inspectionContext: inspectionContext);
Verify(evalResult,
EvalResult("o", "{int[0x00000003]}", "int[]", "o", DkmEvaluationResultFlags.Expandable));
var children = GetChildren(evalResult, inspectionContext);
// Hex could be used for indices: [0x00000000], etc.
Verify(children,
EvalResult("[0]", "0x0000000a", "int", "o[0]"),
EvalResult("[1]", "0x00000014", "int", "o[1]"),
EvalResult("[2]", "0x0000001e", "int", "o[2]"));
}
[Fact]
public void HexadecimalNonZeroLowerBounds()
{
var array = (int[,])System.Array.CreateInstance(typeof(int), new[] { 2, 1 }, new[] { -3, 4 });
array[-3, 4] = 1;
array[-2, 4] = 2;
var value = CreateDkmClrValue(array);
var inspectionContext = CreateDkmInspectionContext(radix: 16);
var evalResult = FormatResult("a", value, inspectionContext: inspectionContext);
Verify(evalResult,
EvalResult("a", "{int[0xfffffffd..0xfffffffe, 0x00000004..0x00000004]}", "int[,]", "a", DkmEvaluationResultFlags.Expandable));
var children = GetChildren(evalResult, inspectionContext);
// Hex could be used for indices: [0xfffffffd, 0x00000004], etc.
Verify(children,
EvalResult("[-3, 4]", "0x00000001", "int", "a[-3, 4]"),
EvalResult("[-2, 4]", "0x00000002", "int", "a[-2, 4]"));
}
/// <summary>
/// Expansion should be lazy so that the IDE can
/// reduce overhead by expanding a subset of rows.
......
......@@ -210,17 +210,17 @@ string IDkmClrFullNameProvider.GetClrTypeName(DkmInspectionContext inspectionCon
throw new NotImplementedException();
}
string IDkmClrFullNameProvider.GetClrArrayIndexExpression(DkmInspectionContext inspectionContext, int[] indices)
string IDkmClrFullNameProvider.GetClrArrayIndexExpression(DkmInspectionContext inspectionContext, string[] indices)
{
throw new NotImplementedException();
}
string IDkmClrFullNameProvider.GetClrCastExpression(DkmInspectionContext inspectionContext, string argument, DkmClrType type, DkmClrCustomTypeInfo customTypeInfo, bool parenthesizeArgument, bool parenthesizeEntireExpression)
string IDkmClrFullNameProvider.GetClrCastExpression(DkmInspectionContext inspectionContext, string argument, DkmClrType type, DkmClrCustomTypeInfo customTypeInfo, DkmClrCastExpressionOptions castExpressionOptions)
{
throw new NotImplementedException();
}
string IDkmClrFullNameProvider.GetClrObjectCreationExpression(DkmInspectionContext inspectionContext, DkmClrType type, DkmClrCustomTypeInfo customTypeInfo, string arguments)
string IDkmClrFullNameProvider.GetClrObjectCreationExpression(DkmInspectionContext inspectionContext, DkmClrType type, DkmClrCustomTypeInfo customTypeInfo, string[] arguments)
{
throw new NotImplementedException();
}
......@@ -251,6 +251,16 @@ bool IDkmClrFullNameProvider.ClrExpressionMayRequireParentheses(DkmInspectionCon
{
return ((IDkmClrFullNameProvider)_fallback).GetClrMemberName(inspectionContext, parentFullName, declaringType, declaringTypeInfo, memberName, memberAccessRequiresExplicitCast, memberIsStatic);
}
string IDkmClrFullNameProvider.GetClrExpressionForNull(DkmInspectionContext inspectionContext)
{
throw new NotImplementedException();
}
string IDkmClrFullNameProvider.GetClrExpressionForThis(DkmInspectionContext inspectionContext)
{
throw new NotImplementedException();
}
}
}
}
......@@ -5,6 +5,7 @@
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.ExpressionEvaluator;
using Microsoft.VisualStudio.Debugger.ComponentInterfaces;
using Microsoft.VisualStudio.Debugger.Clr;
using Microsoft.VisualStudio.Debugger.Evaluation;
using Roslyn.Test.Utilities;
......@@ -14,6 +15,66 @@ namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator.UnitTests
{
public class FullNameTests : CSharpResultProviderTestBase
{
[Fact]
public void Null()
{
IDkmClrFullNameProvider fullNameProvider = new CSharpFormatter();
var inspectionContext = CreateDkmInspectionContext();
Assert.Equal("null", fullNameProvider.GetClrExpressionForNull(inspectionContext));
}
[Fact]
public void This()
{
IDkmClrFullNameProvider fullNameProvider = new CSharpFormatter();
var inspectionContext = CreateDkmInspectionContext();
Assert.Equal("this", fullNameProvider.GetClrExpressionForThis(inspectionContext));
}
[Fact]
public void ArrayIndex()
{
IDkmClrFullNameProvider fullNameProvider = new CSharpFormatter();
var inspectionContext = CreateDkmInspectionContext();
Assert.Equal("[]", fullNameProvider.GetClrArrayIndexExpression(inspectionContext, new string[0]));
Assert.Equal("[]", fullNameProvider.GetClrArrayIndexExpression(inspectionContext, new[] { "" }));
Assert.Equal("[ ]", fullNameProvider.GetClrArrayIndexExpression(inspectionContext, new[] { " " }));
Assert.Equal("[1]", fullNameProvider.GetClrArrayIndexExpression(inspectionContext, new[] { "1" }));
Assert.Equal("[[], 2, 3]", fullNameProvider.GetClrArrayIndexExpression(inspectionContext, new[] { "[]", "2", "3" }));
Assert.Equal("[, , ]", fullNameProvider.GetClrArrayIndexExpression(inspectionContext, new[] { "", "", "" }));
}
[Fact]
public void Cast()
{
var source =
@"class C
{
}";
var runtime = new DkmClrRuntimeInstance(ReflectionUtilities.GetMscorlib(GetAssembly(source)));
using (runtime.Load())
{
IDkmClrFullNameProvider fullNameProvider = new CSharpFormatter();
var inspectionContext = CreateDkmInspectionContext();
var type = runtime.GetType("C");
Assert.Equal("(C)o", fullNameProvider.GetClrCastExpression(inspectionContext, "o", type, null, DkmClrCastExpressionOptions.None));
Assert.Equal("o as C", fullNameProvider.GetClrCastExpression(inspectionContext, "o", type, null, DkmClrCastExpressionOptions.ConditionalCast));
Assert.Equal("(C)(o)", fullNameProvider.GetClrCastExpression(inspectionContext, "o", type, null, DkmClrCastExpressionOptions.ParenthesizeArgument));
Assert.Equal("(o) as C", fullNameProvider.GetClrCastExpression(inspectionContext, "o", type, null, DkmClrCastExpressionOptions.ParenthesizeArgument | DkmClrCastExpressionOptions.ConditionalCast));
Assert.Equal("((C)o)", fullNameProvider.GetClrCastExpression(inspectionContext, "o", type, null, DkmClrCastExpressionOptions.ParenthesizeEntireExpression));
Assert.Equal("(o as C)", fullNameProvider.GetClrCastExpression(inspectionContext, "o", type, null, DkmClrCastExpressionOptions.ParenthesizeEntireExpression | DkmClrCastExpressionOptions.ConditionalCast));
Assert.Equal("((C)(o))", fullNameProvider.GetClrCastExpression(inspectionContext, "o", type, null, DkmClrCastExpressionOptions.ParenthesizeEntireExpression | DkmClrCastExpressionOptions.ParenthesizeArgument));
Assert.Equal("((o) as C)", fullNameProvider.GetClrCastExpression(inspectionContext, "o", type, null, DkmClrCastExpressionOptions.ParenthesizeEntireExpression | DkmClrCastExpressionOptions.ParenthesizeArgument | DkmClrCastExpressionOptions.ConditionalCast));
// Some of the same tests with "..." as the expression ("..." is used
// by the debugger when the expression cannot be determined).
Assert.Equal("(C)...", fullNameProvider.GetClrCastExpression(inspectionContext, "...", type, null, DkmClrCastExpressionOptions.None));
Assert.Equal("... as C", fullNameProvider.GetClrCastExpression(inspectionContext, "...", type, null, DkmClrCastExpressionOptions.ConditionalCast));
Assert.Equal("(... as C)", fullNameProvider.GetClrCastExpression(inspectionContext, "...", type, null, DkmClrCastExpressionOptions.ParenthesizeEntireExpression | DkmClrCastExpressionOptions.ConditionalCast));
}
}
[Fact]
public void RootComment()
{
......
......@@ -22,10 +22,10 @@
<None Include="project.json" />
</ItemGroup>
<ItemGroup>
<Content Include="$(NuGetPackageRoot)\Microsoft.VisualStudio.Debugger.Engine\14.3.25422\lib\portable-net45+win8\Microsoft.VisualStudio.Debugger.Engine.dll">
<Content Include="$(NuGetPackageRoot)\Microsoft.VisualStudio.Debugger.Engine\15.0.25824-RC\lib\portable-net45+win8\Microsoft.VisualStudio.Debugger.Engine.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(NuGetPackageRoot)\Microsoft.VisualStudio.Debugger.Metadata\14.3.25421\lib\portable-net45+win8\Microsoft.VisualStudio.Debugger.Metadata.dll">
<Content Include="$(NuGetPackageRoot)\Microsoft.VisualStudio.Debugger.Metadata\15.0.25824-RC\lib\portable-net45+win8\Microsoft.VisualStudio.Debugger.Metadata.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
......
{
"dependencies": {
"Microsoft.VisualStudio.Debugger.Engine": "14.3.25422",
"Microsoft.VisualStudio.Debugger.Metadata": "14.3.25421"
"Microsoft.VisualStudio.Debugger.Engine": "15.0.25824-RC",
"Microsoft.VisualStudio.Debugger.Metadata": "15.0.25824-RC"
},
"frameworks": {
".NETPortable,Version=v4.5,Profile=Profile7": { }
......
......@@ -18,8 +18,6 @@ namespace Microsoft.CodeAnalysis.ExpressionEvaluator
{
internal static class DkmUtilities
{
private static readonly Guid s_symUnmanagedReaderClassId = Guid.Parse("B4CE6286-2A6B-3712-A3B7-1EE1DAD467B5");
internal unsafe delegate IntPtr GetMetadataBytesPtrFunction(AssemblyIdentity assemblyIdentity, out uint uSize);
// Return the set of managed module instances from the AppDomain.
......@@ -146,7 +144,14 @@ private unsafe static MetadataBlock GetMetadataBlock(IntPtr ptr, uint size)
internal static object GetSymReader(this DkmClrModuleInstance clrModule)
{
var module = clrModule.Module; // Null if there are no symbols.
return (module == null) ? null : module.GetSymbolInterface(s_symUnmanagedReaderClassId);
if (module == null)
{
return null;
}
// Use DkmClrModuleInstance.GetSymUnmanagedReader()
// rather than DkmModule.GetSymbolInterface() since the
// latter does not handle .NET Native modules.
return clrModule.GetSymUnmanagedReader();
}
internal static DkmCompiledClrInspectionQuery ToQueryResult(
......
{
"dependencies": {
"Microsoft.VisualStudio.Debugger.Engine": "14.3.25422",
"Microsoft.VisualStudio.Debugger.Engine": "15.0.25824-RC",
"Microsoft.DiaSymReader": "1.1.0"
},
"frameworks": {
......
......@@ -3,7 +3,7 @@
"Microsoft.NETCore.Portable.Compatibility": "1.0.1",
"System.Collections.Immutable": "1.3.1",
"System.Reflection.Metadata": "1.4.2",
"Microsoft.VisualStudio.Debugger.Engine": "14.3.25422",
"Microsoft.VisualStudio.Debugger.Engine": "15.0.25824-RC",
},
"frameworks": {
"netstandard1.3": {
......
......@@ -2,6 +2,7 @@
using System.Collections.ObjectModel;
using System.Diagnostics;
using Microsoft.VisualStudio.Debugger.Clr;
using Microsoft.VisualStudio.Debugger.ComponentInterfaces;
using Microsoft.VisualStudio.Debugger.Evaluation;
using Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation;
......@@ -74,7 +75,7 @@ private ArrayExpansion(TypeAndCustomInfo elementTypeAndInfo, ReadOnlyCollection<
{
var indices = GetIndices(index);
var fullNameProvider = resultProvider.FullNameProvider;
var name = fullNameProvider.GetClrArrayIndexExpression(inspectionContext, indices);
var name = fullNameProvider.GetClrArrayIndexExpression(inspectionContext, GetIndicesAsStrings(indices));
var element = value.GetArrayElement(indices, inspectionContext);
var fullName = GetFullName(inspectionContext, parent, name, fullNameProvider);
return resultProvider.CreateDataItem(
......@@ -111,6 +112,17 @@ private int[] GetIndices(int index)
return indices;
}
private static string[] GetIndicesAsStrings(int[] indices)
{
var n = indices.Length;
var strings = new string[n];
for (int i = 0; i < n; i++)
{
strings[i] = indices[i].ToString();
}
return strings;
}
private static ReadOnlyCollection<int> CalculateDivisors(ReadOnlyCollection<int> sizes)
{
var n = sizes.Count;
......@@ -143,7 +155,12 @@ private static string GetFullName(DkmInspectionContext inspectionContext, EvalRe
var parentRuntimeType = parent.Value.Type;
if (!parent.DeclaredTypeAndInfo.Type.Equals(parentRuntimeType.GetLmrType()))
{
parentFullName = fullNameProvider.GetClrCastExpression(inspectionContext, parentFullName, parentRuntimeType, customTypeInfo: null, parenthesizeArgument: false, parenthesizeEntireExpression: true);
parentFullName = fullNameProvider.GetClrCastExpression(
inspectionContext,
parentFullName,
parentRuntimeType,
customTypeInfo: null,
castExpressionOptions: DkmClrCastExpressionOptions.ParenthesizeEntireExpression);
if (parentFullName == null)
{
return null; // Contains invalid identifier.
......
......@@ -123,7 +123,11 @@ internal sealed class DebuggerTypeProxyExpansion : Expansion
string proxyMemberFullNamePrefix = null;
if (childFullNamePrefix != null)
{
proxyMemberFullNamePrefix = resultProvider.FullNameProvider.GetClrObjectCreationExpression(inspectionContext, proxyTypeAndInfo.ClrType, proxyTypeAndInfo.Info, childFullNamePrefix);
proxyMemberFullNamePrefix = resultProvider.FullNameProvider.GetClrObjectCreationExpression(
inspectionContext,
proxyTypeAndInfo.ClrType,
proxyTypeAndInfo.Info,
new[] { childFullNamePrefix });
}
_proxyItem = new EvalResult(
ExpansionKind.Default,
......
......@@ -91,7 +91,11 @@ private EvalResult CreateDynamicViewRow(DkmInspectionContext inspectionContext,
var fullName = isRootExpression ? name : parent.ChildFullNamePrefix;
var childFullNamePrefix = (fullName == null) ?
null :
fullNameProvider.GetClrObjectCreationExpression(inspectionContext, proxyTypeAndInfo.ClrType, proxyTypeAndInfo.Info, fullName);
fullNameProvider.GetClrObjectCreationExpression(
inspectionContext,
proxyTypeAndInfo.ClrType,
proxyTypeAndInfo.Info,
new[] { fullName });
var formatSpecifiers = isRootExpression ? Formatter.NoFormatSpecifiers : parent.FormatSpecifiers;
return new EvalResult(
ExpansionKind.DynamicView,
......
......@@ -225,7 +225,11 @@ private ResultsViewExpansion(DkmClrValue proxyValue, Expansion proxyMembers)
var fullName = parent.ChildFullNamePrefix;
var childFullNamePrefix = (fullName == null) ?
null :
fullNameProvider.GetClrObjectCreationExpression(inspectionContext, proxyTypeAndInfo.ClrType, proxyTypeAndInfo.Info, fullName);
fullNameProvider.GetClrObjectCreationExpression(
inspectionContext,
proxyTypeAndInfo.ClrType,
proxyTypeAndInfo.Info,
new[] { fullName });
return new EvalResult(
ExpansionKind.ResultsView,
Resources.ResultsView,
......@@ -259,7 +263,11 @@ private ResultsViewExpansion(DkmClrValue proxyValue, Expansion proxyMembers)
{
formatSpecifiers = Formatter.AddFormatSpecifier(formatSpecifiers, ResultsFormatSpecifier);
}
var childFullNamePrefix = fullNameProvider.GetClrObjectCreationExpression(inspectionContext, _proxyValue.Type, customTypeInfo: null, arguments: fullName);
var childFullNamePrefix = fullNameProvider.GetClrObjectCreationExpression(
inspectionContext,
_proxyValue.Type,
customTypeInfo: null,
arguments: new[] { fullName });
return new EvalResult(
ExpansionKind.Default,
name,
......
......@@ -99,7 +99,12 @@ private TupleExpansion(TypeAndCustomInfo typeAndInfo, int cardinality, bool useR
var parentRuntimeType = parent.Value.Type;
if (!parent.DeclaredTypeAndInfo.Type.Equals(parentRuntimeType.GetLmrType()))
{
parentFullName = fullNameProvider.GetClrCastExpression(inspectionContext, parentFullName, parentRuntimeType, customTypeInfo: null, parenthesizeArgument: false, parenthesizeEntireExpression: true);
parentFullName = fullNameProvider.GetClrCastExpression(
inspectionContext,
parentFullName,
parentRuntimeType,
customTypeInfo: null,
castExpressionOptions: DkmClrCastExpressionOptions.ParenthesizeEntireExpression);
}
}
......@@ -192,11 +197,11 @@ private TupleExpansion(TypeAndCustomInfo typeAndInfo, int cardinality, bool useR
fullNameProvider.GetClrMemberName(
inspectionContext,
parentFullName,
declaringType: field.DeclaringTypeAndInfo.ClrType,
declaringTypeInfo: null,
clrType: field.DeclaringTypeAndInfo.ClrType,
customTypeInfo: null,
memberName: fieldName,
memberAccessRequiresExplicitCast: false,
memberIsStatic: false);
requiresExplicitCast: false,
isStatic: false);
return value.GetFieldValue(fieldName, inspectionContext);
}
......
......@@ -409,15 +409,15 @@ private static string IncludeObjectId(DkmClrValue value, string valueStr, GetVal
internal abstract string GetArrayDisplayString(DkmClrAppDomain appDomain, Type lmrType, ReadOnlyCollection<int> sizes, ReadOnlyCollection<int> lowerBounds, ObjectDisplayOptions options);
internal abstract string GetArrayIndexExpression(int[] indices);
internal abstract string GetArrayIndexExpression(string[] indices);
internal abstract string GetCastExpression(string argument, string type, bool parenthesizeArgument, bool parenthesizeEntireExpression);
internal abstract string GetCastExpression(string argument, string type, DkmClrCastExpressionOptions options);
internal abstract string GetNamesForFlagsEnumValue(ArrayBuilder<EnumField> fields, object value, ulong underlyingValue, ObjectDisplayOptions options, Type typeToDisplayOpt);
internal abstract string GetNameForEnumValue(ArrayBuilder<EnumField> fields, object value, ulong underlyingValue, ObjectDisplayOptions options, Type typeToDisplayOpt);
internal abstract string GetObjectCreationExpression(string type, string arguments);
internal abstract string GetObjectCreationExpression(string type, string[] arguments);
internal abstract string GetTupleExpression(string[] values);
......
......@@ -21,11 +21,13 @@ internal abstract partial class Formatter : IDkmClrFormatter, IDkmClrFormatter2,
{
private readonly string _defaultFormat;
private readonly string _nullString;
private readonly string _thisString;
internal Formatter(string defaultFormat, string nullString)
internal Formatter(string defaultFormat, string nullString, string thisString)
{
_defaultFormat = defaultFormat;
_nullString = nullString;
_thisString = thisString;
}
string IDkmClrFormatter.GetValueString(DkmClrValue value, DkmInspectionContext inspectionContext, ReadOnlyCollection<string> formatSpecifiers)
......@@ -71,12 +73,12 @@ string IDkmClrFullNameProvider.GetClrTypeName(DkmInspectionContext inspectionCon
return sawInvalidIdentifier ? null : name;
}
string IDkmClrFullNameProvider.GetClrArrayIndexExpression(DkmInspectionContext inspectionContext, int[] indices)
string IDkmClrFullNameProvider.GetClrArrayIndexExpression(DkmInspectionContext inspectionContext, string[] indices)
{
return GetArrayIndexExpression(indices);
}
string IDkmClrFullNameProvider.GetClrCastExpression(DkmInspectionContext inspectionContext, string argument, DkmClrType type, DkmClrCustomTypeInfo customTypeInfo, bool parenthesizeArgument, bool parenthesizeEntireExpression)
string IDkmClrFullNameProvider.GetClrCastExpression(DkmInspectionContext inspectionContext, string argument, DkmClrType type, DkmClrCustomTypeInfo customTypeInfo, DkmClrCastExpressionOptions castExpressionOptions)
{
bool sawInvalidIdentifier;
var name = GetTypeName(new TypeAndCustomInfo(type, customTypeInfo), escapeKeywordIdentifiers: true, sawInvalidIdentifier: out sawInvalidIdentifier);
......@@ -84,10 +86,10 @@ string IDkmClrFullNameProvider.GetClrCastExpression(DkmInspectionContext inspect
{
return null;
}
return GetCastExpression(argument, name, parenthesizeArgument, parenthesizeEntireExpression);
return GetCastExpression(argument, name, castExpressionOptions);
}
string IDkmClrFullNameProvider.GetClrObjectCreationExpression(DkmInspectionContext inspectionContext, DkmClrType type, DkmClrCustomTypeInfo customTypeInfo, string arguments)
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);
......@@ -146,11 +148,7 @@ bool IDkmClrFullNameProvider.ClrExpressionMayRequireParentheses(DkmInspectionCon
{
return null; // FullName wouldn't be parseable.
}
qualifier = GetCastExpression(
parentFullName,
typeName,
parenthesizeArgument: false,
parenthesizeEntireExpression: true);
qualifier = GetCastExpression(parentFullName, typeName, DkmClrCastExpressionOptions.ParenthesizeEntireExpression);
}
else
{
......@@ -159,6 +157,16 @@ bool IDkmClrFullNameProvider.ClrExpressionMayRequireParentheses(DkmInspectionCon
return $"{qualifier}.{memberName}";
}
string IDkmClrFullNameProvider.GetClrExpressionForNull(DkmInspectionContext inspectionContext)
{
return _nullString;
}
string IDkmClrFullNameProvider.GetClrExpressionForThis(DkmInspectionContext inspectionContext)
{
return _thisString;
}
// CONSIDER: If the number or complexity of the "language-specific syntax helpers" grows (or if
// we make this a public API, it would be good to consider abstracting them into a separate object
// that can be passed to the ResultProvider on construction (a "LanguageSyntax" service of sorts).
......
// 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 Microsoft.CodeAnalysis.Collections;
using Microsoft.VisualStudio.Debugger.Evaluation;
using Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation;
using System.Diagnostics;
using System.Text;
namespace Microsoft.CodeAnalysis.ExpressionEvaluator
{
......@@ -43,5 +45,33 @@ internal static string Parenthesize(this string expr)
{
return $"({expr})";
}
internal static string ToCommaSeparatedString(this string[] values, char openParen, char closeParen)
{
Debug.Assert(values != null);
var pooled = PooledStringBuilder.GetInstance();
var builder = pooled.Builder;
builder.Append(openParen);
builder.AppendCommaSeparatedList(values);
builder.Append(closeParen);
return pooled.ToStringAndFree();
}
internal static void AppendCommaSeparatedList(this StringBuilder builder, string[] values)
{
bool any = false;
foreach (var value in values)
{
if (any)
{
builder.Append(", ");
}
builder.Append(value);
any = true;
}
}
}
}
// 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.Collections.ObjectModel;
using Microsoft.VisualStudio.Debugger.Clr;
using Microsoft.VisualStudio.Debugger.Evaluation;
using Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation;
namespace Microsoft.VisualStudio.Debugger.ComponentInterfaces
{
internal interface IDkmClrFullNameProvider
{
/// <summary>
/// Return the type name in a form valid in the language (e.g.: escaping keywords)
/// or null if the name cannot be represented as valid syntax.
/// </summary>
string GetClrTypeName(DkmInspectionContext inspectionContext, DkmClrType type, DkmClrCustomTypeInfo customTypeInfo);
/// <summary>
/// Return an array index expression. Should not return null.
/// </summary>
string GetClrArrayIndexExpression(DkmInspectionContext inspectionContext, int[] indices);
/// <summary>
/// Return a cast expression or null if the type name would be invalid syntax.
/// </summary>
string GetClrCastExpression(DkmInspectionContext inspectionContext, string argument, DkmClrType type, DkmClrCustomTypeInfo customTypeInfo, bool parenthesizeArgument, bool parenthesizeEntireExpression);
/// <summary>
/// Return an object creation expression or null if the type name would be invalid syntax.
/// </summary>
string GetClrObjectCreationExpression(DkmInspectionContext inspectionContext, DkmClrType type, DkmClrCustomTypeInfo customTypeInfo, string arguments);
/// <summary>
/// Return the identifier in a form valid in the language (e.g.: escaping keywords)
/// or null if the identifier cannot be represented as a valid identifier.
/// </summary>
string GetClrValidIdentifier(DkmInspectionContext inspectionContext, string identifier);
/// <summary>
/// Return a member access expression or null if the expression cannot be
/// represented as valid syntax.
/// </summary>
string GetClrMemberName(
DkmInspectionContext inspectionContext,
string parentFullName,
DkmClrType declaringType,
DkmClrCustomTypeInfo declaringTypeInfo,
string memberName,
bool memberAccessRequiresExplicitCast,
bool memberIsStatic);
/// <summary>
/// Return true if the expression may require parentheses when used
/// as a sub-expression in the language.
/// </summary>
bool ClrExpressionMayRequireParentheses(DkmInspectionContext inspectionContext, string expression);
/// <summary>
/// Split the string into the expression and format specifier parts.
/// Returns the expression without format specifiers.
/// </summary>
string GetClrExpressionAndFormatSpecifiers(DkmInspectionContext inspectionContext, string expression, out ReadOnlyCollection<string> formatSpecifiers);
}
}
{
"dependencies": {
"Microsoft.NetFX20": "1.0.3",
"Microsoft.VisualStudio.Debugger.Engine": "14.3.25422",
"Microsoft.VisualStudio.Debugger.Metadata": "14.3.25421"
"Microsoft.VisualStudio.Debugger.Engine": "15.0.25824-RC",
"Microsoft.VisualStudio.Debugger.Metadata": "15.0.25824-RC"
},
"frameworks": {
"net20": { }
......
{
"dependencies": {
"Microsoft.VisualStudio.Debugger.Engine": "14.3.25422",
"Microsoft.VisualStudio.Debugger.Metadata": "14.3.25421"
"Microsoft.VisualStudio.Debugger.Engine": "15.0.25824-RC",
"Microsoft.VisualStudio.Debugger.Metadata": "15.0.25824-RC"
},
"frameworks": {
".NETPortable,Version=v4.5,Profile=Profile7": { }
......
......@@ -19,8 +19,6 @@
<Compile Include="$(MSBuildThisFileDirectory)Helpers\TypeWalker.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Helpers\AttributeHelpers.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Helpers\CustomTypeInfoTypeArgumentMap.cs" />
<Compile Include="$(MSBuildThisFileDirectory)IDkmClrFormatter2.cs" />
<Compile Include="$(MSBuildThisFileDirectory)IDkmClrFullNameProvider.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ResultProvider.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Expansion\AggregateExpansion.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Expansion\ArrayExpansion.cs" />
......
{
"dependencies": {
"Microsoft.VisualStudio.Debugger.Engine": "14.3.25422",
"Microsoft.VisualStudio.Debugger.Engine": "15.0.25824-RC",
"Microsoft.DiaSymReader": "1.1.0",
"xunit": "2.2.0-beta4-build3444",
"xunit.runner.console": "2.2.0-beta4-build3444",
......
{
"dependencies": {
"Microsoft.VisualStudio.Debugger.Engine": "14.3.25422",
"Microsoft.VisualStudio.Debugger.Engine": "15.0.25824-RC",
"xunit": "2.2.0-beta4-build3444",
"xunit.runner.console": "2.2.0-beta4-build3444",
"xunit.runner.visualstudio": "2.2.0-beta4-build1194"
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#region Assembly Microsoft.VisualStudio.Debugger.Engine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// References\Debugger\v2.0\Microsoft.VisualStudio.Debugger.Engine.dll
#endregion
namespace Microsoft.VisualStudio.Debugger.Clr
{
public enum DkmClrCastExpressionOptions
{
None = 0,
ConditionalCast = 1,
ParenthesizeArgument = 2,
ParenthesizeEntireExpression = 4
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#region Assembly Microsoft.VisualStudio.Debugger.Engine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// References\Debugger\v2.0\Microsoft.VisualStudio.Debugger.Engine.dll
#endregion
using System.Collections.ObjectModel;
using Microsoft.VisualStudio.Debugger.Evaluation;
using Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation;
namespace Microsoft.VisualStudio.Debugger.ComponentInterfaces
{
internal interface IDkmClrFormatter2
public interface IDkmClrFormatter2
{
string GetValueString(DkmClrValue clrValue, DkmClrCustomTypeInfo customTypeInfo, DkmInspectionContext inspectionContext, ReadOnlyCollection<string> formatSpecifiers);
string GetEditableValueString(DkmClrValue value, DkmInspectionContext inspectionContext, DkmClrCustomTypeInfo customTypeInfo);
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#region Assembly Microsoft.VisualStudio.Debugger.Engine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// References\Debugger\v2.0\Microsoft.VisualStudio.Debugger.Engine.dll
#endregion
using System.Collections.ObjectModel;
using Microsoft.VisualStudio.Debugger.Clr;
using Microsoft.VisualStudio.Debugger.Evaluation;
using Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation;
namespace Microsoft.VisualStudio.Debugger.ComponentInterfaces
{
public interface IDkmClrFullNameProvider
{
string GetClrTypeName(
DkmInspectionContext inspectionContext,
DkmClrType clrType,
DkmClrCustomTypeInfo customTypeInfo);
string GetClrArrayIndexExpression(
DkmInspectionContext inspectionContext,
string[] indices);
string GetClrCastExpression(
DkmInspectionContext inspectionContext,
string argument,
DkmClrType clrType,
DkmClrCustomTypeInfo customTypeInfo,
DkmClrCastExpressionOptions castExpressionOptions);
string GetClrObjectCreationExpression(
DkmInspectionContext inspectionContext,
DkmClrType clrType,
DkmClrCustomTypeInfo customTypeInfo,
string[] arguments);
string GetClrValidIdentifier(
DkmInspectionContext inspectionContext,
string identifier);
string GetClrMemberName(
DkmInspectionContext inspectionContext,
string parentFullName,
DkmClrType clrType,
DkmClrCustomTypeInfo customTypeInfo,
string memberName,
bool requiresExplicitCast,
bool isStatic);
bool ClrExpressionMayRequireParentheses(
DkmInspectionContext inspectionContext,
string expression);
string GetClrExpressionAndFormatSpecifiers(
DkmInspectionContext inspectionContext,
string expression,
out ReadOnlyCollection<string> formatSpecifiers);
string GetClrExpressionForNull(DkmInspectionContext inspectionContext);
string GetClrExpressionForThis(DkmInspectionContext inspectionContext);
}
}
......@@ -92,6 +92,7 @@
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="Debugger\Engine\DkmClrCastExpressionOptions.cs" />
<Compile Include="Debugger\Engine\DkmClrCustomTypeInfo.cs" />
<Compile Include="Debugger\Engine\DkmCompilerId.cs" />
<Compile Include="Debugger\Engine\DkmContinueCorruptingException.cs" />
......@@ -137,6 +138,8 @@
<Compile Include="Debugger\Engine\DkmVendorId.cs" />
<Compile Include="Debugger\Engine\DkmWorkList.cs" />
<Compile Include="Debugger\Engine\IDkmClrFormatter.cs" />
<Compile Include="Debugger\Engine\IDkmClrFormatter2.cs" />
<Compile Include="Debugger\Engine\IDkmClrFullNameProvider.cs" />
<Compile Include="Debugger\Engine\IDkmClrResultProvider.cs" />
<Compile Include="Debugger\MemberInfo\AssemblyImpl.cs" />
<Compile Include="Debugger\MemberInfo\ConstructorInfoImpl.cs" />
......
{
"dependencies": {
"System.Collections.Immutable": "1.3.1",
"Microsoft.VisualStudio.Debugger.Metadata": "14.3.25421",
"Microsoft.VisualStudio.Debugger.Metadata": "15.0.25824-RC",
"xunit": "2.2.0-beta4-build3444",
"xunit.runner.console": "2.2.0-beta4-build3444",
"xunit.runner.visualstudio": "2.2.0-beta4-build1194"
......
{
"dependencies": {
"Microsoft.VisualStudio.Debugger.Engine": "14.3.25422"
"Microsoft.VisualStudio.Debugger.Engine": "15.0.25824-RC"
},
"frameworks": {
"netstandard1.3": {
......
{
"dependencies": {
"Microsoft.VisualStudio.Debugger.Engine": "14.3.25422",
"Microsoft.VisualStudio.Debugger.Metadata": "14.3.25421"
"Microsoft.VisualStudio.Debugger.Engine": "15.0.25824-RC",
"Microsoft.VisualStudio.Debugger.Metadata": "15.0.25824-RC"
},
"frameworks": {
".NETPortable,Version=v4.5,Profile=Profile7": { }
......
......@@ -3,6 +3,7 @@
Imports System.Collections.ObjectModel
Imports System.Text
Imports Microsoft.CodeAnalysis.Collections
Imports Microsoft.CodeAnalysis.ExpressionEvaluator
Imports Microsoft.VisualStudio.Debugger.Clr
Imports Roslyn.Utilities
Imports Type = Microsoft.VisualStudio.Debugger.Metadata.Type
......@@ -64,34 +65,27 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Return pooled.ToStringAndFree()
End Function
Friend Overrides Function GetArrayIndexExpression(indices() As Integer) As String
Debug.Assert(indices IsNot Nothing)
Dim pooled = PooledStringBuilder.GetInstance()
Dim builder = pooled.Builder
builder.Append("("c)
Dim any As Boolean = False
For Each index In indices
If any Then
builder.Append(", ")
End If
builder.Append(index)
any = True
Next
builder.Append(")"c)
Return pooled.ToStringAndFree()
Friend Overrides Function GetArrayIndexExpression(indices() As String) As String
Return indices.ToCommaSeparatedString("("c, ")"c)
End Function
Friend Overrides Function GetCastExpression(argument As String, type As String, parenthesizeArgument As Boolean, parenthesizeEntireExpression As Boolean) As String
Friend Overrides Function GetCastExpression(argument As String, type As String, options As DkmClrCastExpressionOptions) As String
Debug.Assert(Not String.IsNullOrEmpty(argument))
Debug.Assert(Not String.IsNullOrEmpty(type))
Dim pooled = PooledStringBuilder.GetInstance()
Dim builder = pooled.Builder
builder.Append("DirectCast(")
If (options And DkmClrCastExpressionOptions.ParenthesizeArgument) <> 0 Then
argument = $"({argument})"
End If
If (options And DkmClrCastExpressionOptions.ConditionalCast) <> 0 Then
builder.Append("TryCast(")
Else
builder.Append("DirectCast(")
End If
builder.Append(argument)
builder.Append(", ")
builder.Append(type)
......@@ -101,23 +95,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
End Function
Friend Overrides Function GetTupleExpression(values() As String) As String
Debug.Assert(values IsNot Nothing)
Dim pooled = PooledStringBuilder.GetInstance()
Dim builder = pooled.Builder
builder.Append("("c)
Dim any As Boolean = False
For Each value In values
If any Then
builder.Append(", ")
End If
builder.Append(value)
any = True
Next
builder.Append(")"c)
Return pooled.ToStringAndFree()
Return values.ToCommaSeparatedString("("c, ")"c)
End Function
Friend Overrides Function GetNamesForFlagsEnumValue(fields As ArrayBuilder(Of EnumField), value As Object, underlyingValue As ULong, options As ObjectDisplayOptions, typeToDisplayOpt As Type) As String
......@@ -167,7 +145,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Return Nothing
End Function
Friend Overrides Function GetObjectCreationExpression(type As String, arguments As String) As String
Friend Overrides Function GetObjectCreationExpression(type As String, arguments As String()) As String
Debug.Assert(Not String.IsNullOrEmpty(type))
Dim pooled = PooledStringBuilder.GetInstance()
......@@ -176,7 +154,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
builder.Append("New ")
builder.Append(type)
builder.Append("("c)
builder.Append(arguments)
builder.AppendCommaSeparatedList(arguments)
builder.Append(")"c)
Return pooled.ToStringAndFree()
......
......@@ -20,7 +20,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Friend Shared ReadOnly Instance As VisualBasicFormatter = New VisualBasicFormatter()
Public Sub New()
MyBase.New(defaultFormat:="{{{0}}}", nullString:="Nothing")
MyBase.New(defaultFormat:="{{{0}}}", nullString:="Nothing", thisString:="Me")
End Sub
Friend Overrides Function IsValidIdentifier(name As String) As Boolean
......
{
"dependencies": {
"Microsoft.VisualStudio.Debugger.Engine": "14.3.25422",
"Microsoft.VisualStudio.Debugger.Engine": "15.0.25824-RC",
"Microsoft.DiaSymReader": "1.1.0",
"xunit": "2.2.0-beta4-build3444",
"xunit.runner.console": "2.2.0-beta4-build3444",
......
......@@ -3,6 +3,8 @@
Imports System.Collections.Immutable
Imports Microsoft.CodeAnalysis.ExpressionEvaluator
Imports Microsoft.CodeAnalysis.VisualBasic.UnitTests
Imports Microsoft.VisualStudio.Debugger.Clr
Imports Microsoft.VisualStudio.Debugger.ComponentInterfaces
Imports Microsoft.VisualStudio.Debugger.Evaluation
Imports Roslyn.Test.Utilities
Imports Xunit
......@@ -11,6 +13,60 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator.UnitTests
Public Class FullNameTests : Inherits VisualBasicResultProviderTestBase
<Fact>
Public Sub Null()
Dim fullNameProvider As IDkmClrFullNameProvider = New VisualBasicFormatter()
Dim inspectionContext = CreateDkmInspectionContext()
Assert.Equal("Nothing", fullNameProvider.GetClrExpressionForNull(inspectionContext))
End Sub
<Fact>
Public Sub This()
Dim fullNameProvider As IDkmClrFullNameProvider = New VisualBasicFormatter()
Dim inspectionContext = CreateDkmInspectionContext()
Assert.Equal("Me", fullNameProvider.GetClrExpressionForThis(inspectionContext))
End Sub
<Fact>
Public Sub ArrayIndex()
Dim fullNameProvider As IDkmClrFullNameProvider = New VisualBasicFormatter()
Dim inspectionContext = CreateDkmInspectionContext()
Assert.Equal("()", fullNameProvider.GetClrArrayIndexExpression(inspectionContext, {}))
Assert.Equal("()", fullNameProvider.GetClrArrayIndexExpression(inspectionContext, {""}))
Assert.Equal("( )", fullNameProvider.GetClrArrayIndexExpression(inspectionContext, {" "}))
Assert.Equal("(1)", fullNameProvider.GetClrArrayIndexExpression(inspectionContext, {"1"}))
Assert.Equal("((), 2, 3)", fullNameProvider.GetClrArrayIndexExpression(inspectionContext, {"()", "2", "3"}))
Assert.Equal("(, , )", fullNameProvider.GetClrArrayIndexExpression(inspectionContext, {"", "", ""}))
End Sub
<Fact>
Public Sub Cast()
Const source =
"Class C
End Class"
Dim runtime = New DkmClrRuntimeInstance(ReflectionUtilities.GetMscorlibAndSystemCore(GetAssembly(source)))
Using runtime.Load()
Dim fullNameProvider As IDkmClrFullNameProvider = New VisualBasicFormatter()
Dim inspectionContext = CreateDkmInspectionContext()
Dim type = runtime.GetType("C")
Assert.Equal("DirectCast(o, C)", fullNameProvider.GetClrCastExpression(inspectionContext, "o", type, Nothing, DkmClrCastExpressionOptions.None))
Assert.Equal("TryCast(o, C)", fullNameProvider.GetClrCastExpression(inspectionContext, "o", type, Nothing, DkmClrCastExpressionOptions.ConditionalCast))
Assert.Equal("DirectCast((o), C)", fullNameProvider.GetClrCastExpression(inspectionContext, "o", type, Nothing, DkmClrCastExpressionOptions.ParenthesizeArgument))
Assert.Equal("TryCast((o), C)", fullNameProvider.GetClrCastExpression(inspectionContext, "o", type, Nothing, DkmClrCastExpressionOptions.ParenthesizeArgument Or DkmClrCastExpressionOptions.ConditionalCast))
Assert.Equal("DirectCast(o, C)", fullNameProvider.GetClrCastExpression(inspectionContext, "o", type, Nothing, DkmClrCastExpressionOptions.ParenthesizeEntireExpression))
Assert.Equal("TryCast(o, C)", fullNameProvider.GetClrCastExpression(inspectionContext, "o", type, Nothing, DkmClrCastExpressionOptions.ParenthesizeEntireExpression Or DkmClrCastExpressionOptions.ConditionalCast))
Assert.Equal("DirectCast((o), C)", fullNameProvider.GetClrCastExpression(inspectionContext, "o", type, Nothing, DkmClrCastExpressionOptions.ParenthesizeEntireExpression Or DkmClrCastExpressionOptions.ParenthesizeArgument))
Assert.Equal("TryCast((o), C)", fullNameProvider.GetClrCastExpression(inspectionContext, "o", type, Nothing, DkmClrCastExpressionOptions.ParenthesizeEntireExpression Or DkmClrCastExpressionOptions.ParenthesizeArgument Or DkmClrCastExpressionOptions.ConditionalCast))
' Some of the same tests with "..." as the expression ("..." is used
' by the debugger when the expression cannot be determined).
Assert.Equal("DirectCast(..., C)", fullNameProvider.GetClrCastExpression(inspectionContext, "...", type, Nothing, DkmClrCastExpressionOptions.None))
Assert.Equal("TryCast(..., C)", fullNameProvider.GetClrCastExpression(inspectionContext, "...", type, Nothing, DkmClrCastExpressionOptions.ConditionalCast))
Assert.Equal("TryCast(..., C)", fullNameProvider.GetClrCastExpression(inspectionContext, "...", type, Nothing, DkmClrCastExpressionOptions.ParenthesizeEntireExpression Or DkmClrCastExpressionOptions.ConditionalCast))
End Using
End Sub
<Fact>
Public Sub RootComment()
Dim source = "
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册