提交 1bab5665 编写于 作者: P Petr Onderka 提交者: Tomáš Matoušek

Fix formatting of ref/out parameters in Scripting (#11296)

* Fix formatting of ref/out parameters in Scripting

This is used when displaying exceptions in csi.

Previously, ref/out parameters in stacktraces were shown incorrectly,
and even threw NRE when the type of the ref/out parameter was a type parameter.

Fixes the fixable part of #11284
上级 a6a51c25
......@@ -18,13 +18,6 @@ internal CSharpObjectFormatterImpl()
Filter = new CSharpMemberFilter();
}
protected override string FormatRefKind(ParameterInfo parameter)
{
return parameter.IsOut
? parameter.IsIn
? "ref"
: "out"
: "";
}
protected override string FormatRefKind(ParameterInfo parameter) => parameter.IsOut ? "out" : "ref";
}
}
......@@ -938,6 +938,67 @@ public void StackTrace_Dynamic()
+ System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid1<T0>(System.Runtime.CompilerServices.CallSite, T0)
+ Microsoft.CodeAnalysis.CSharp.Scripting.Hosting.UnitTests.ObjectFormatterTests.Fixture2.MethodDynamic(){string.Format(ScriptingResources.AtFileLine, filePath, 10123)}
+ Microsoft.CodeAnalysis.CSharp.Scripting.Hosting.UnitTests.ObjectFormatterTests.StackTrace_Dynamic(){string.Format(ScriptingResources.AtFileLine, filePath, 10132)}
";
var actual = s_formatter.FormatException(e);
Assert.Equal(expected, actual);
}
}
private static class ParametersFixture
{
[MethodImpl(MethodImplOptions.NoInlining)]
public static void Method(ref char c, out DateTime d)
{
throw new Exception();
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static void Method<U>(ref U u)
{
throw new Exception();
}
}
[Fact]
public void StackTrace_RefOutParameters()
{
try
{
char c = ' ';
DateTime date;
ParametersFixture.Method(ref c, out date);
}
catch (Exception e)
{
const string filePath = @"z:\Fixture.cs";
var expected =
$@"Exception of type 'System.Exception' was thrown.
+ Microsoft.CodeAnalysis.CSharp.Scripting.Hosting.UnitTests.ObjectFormatterTests.ParametersFixture.Method(ref char, out System.DateTime){string.Format(ScriptingResources.AtFileLine, filePath, 10155)}
+ Microsoft.CodeAnalysis.CSharp.Scripting.Hosting.UnitTests.ObjectFormatterTests.StackTrace_RefOutParameters(){string.Format(ScriptingResources.AtFileLine, filePath, 10172)}
";
var actual = s_formatter.FormatException(e);
Assert.Equal(expected, actual);
}
}
[Fact]
public void StackTrace_GenericRefParameter()
{
try
{
char c = ' ';
ParametersFixture.Method<char>(ref c);
}
catch (Exception e)
{
const string filePath = @"z:\Fixture.cs";
// TODO (DevDiv #173210): Should show ParametersFixture.Method<char>(ref char)
var expected =
$@"Exception of type 'System.Exception' was thrown.
+ Microsoft.CodeAnalysis.CSharp.Scripting.Hosting.UnitTests.ObjectFormatterTests.ParametersFixture.Method<U>(ref U){string.Format(ScriptingResources.AtFileLine, filePath, 10161)}
+ Microsoft.CodeAnalysis.CSharp.Scripting.Hosting.UnitTests.ObjectFormatterTests.StackTrace_GenericRefParameter(){string.Format(ScriptingResources.AtFileLine, filePath, 10194)}
";
var actual = s_formatter.FormatException(e);
Assert.Equal(expected, actual);
......
......@@ -131,8 +131,16 @@ protected internal virtual string FormatMethodSignature(MethodBase method)
builder.Append(", ");
}
builder.Append(FormatRefKind(parameter));
builder.Append(TypeNameFormatter.FormatTypeName(parameter.ParameterType, options));
if (parameter.ParameterType.IsByRef)
{
builder.Append(FormatRefKind(parameter));
builder.Append(' ');
builder.Append(TypeNameFormatter.FormatTypeName(parameter.ParameterType.GetElementType(), options));
}
else
{
builder.Append(TypeNameFormatter.FormatTypeName(parameter.ParameterType, options));
}
}
builder.Append(')');
......
......@@ -19,7 +19,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Scripting.Hosting
End Sub
Protected Overrides Function FormatRefKind(parameter As ParameterInfo) As String
Return If(parameter.IsOut, "ByRef", "")
Return If(parameter.IsOut, "<Out> ByRef", "ByRef")
End Function
End Class
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册