[gh-88] Implemented exception flow for try/catch+when.
This commit is contained in:
Родитель
5707a9eb22
Коммит
33e77cc9cd
|
@ -27,7 +27,7 @@ namespace SharpLab.Runtime.Internal {
|
|||
_lines[_lines.Count - 1] = line;
|
||||
}
|
||||
|
||||
public static void ReportException(Exception exception) {
|
||||
public static void ReportException(object exception) {
|
||||
var line = _lines[_lines.Count - 1];
|
||||
line.Exception = exception;
|
||||
_lines[_lines.Count - 1] = line;
|
||||
|
@ -94,7 +94,7 @@ namespace SharpLab.Runtime.Internal {
|
|||
}
|
||||
|
||||
public int Number { get; }
|
||||
public Exception Exception { get; internal set; }
|
||||
public object Exception { get; internal set; }
|
||||
|
||||
public bool HasNotes => _notes != null;
|
||||
public StringBuilder Notes {
|
||||
|
|
|
@ -80,18 +80,27 @@ namespace SharpLab.Server.Execution.Internal {
|
|||
|
||||
var handlers = il.Body.ExceptionHandlers;
|
||||
for (var i = 0; i < handlers.Count; i++) {
|
||||
if (handlers[i].HandlerType == ExceptionHandlerType.Catch) {
|
||||
var start = handlers[i].HandlerStart;
|
||||
InsertBefore(il, start, il.Create(OpCodes.Dup));
|
||||
InsertBefore(il, start, il.Create(OpCodes.Call, flow.ReportException));
|
||||
continue;
|
||||
}
|
||||
switch (handlers[i].HandlerType) {
|
||||
case ExceptionHandlerType.Catch:
|
||||
RewriteCatch(handlers[i].HandlerStart, il, flow);
|
||||
break;
|
||||
|
||||
if (handlers[i].HandlerType == ExceptionHandlerType.Finally)
|
||||
RewriteFinally(handlers[i], ref i, il, flow);
|
||||
case ExceptionHandlerType.Filter:
|
||||
RewriteCatch(handlers[i].FilterStart, il, flow);
|
||||
break;
|
||||
|
||||
case ExceptionHandlerType.Finally:
|
||||
RewriteFinally(handlers[i], ref i, il, flow);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RewriteCatch(Instruction start, ILProcessor il, ReportMethods flow) {
|
||||
InsertBefore(il, start, il.Create(OpCodes.Dup));
|
||||
InsertBefore(il, start, il.Create(OpCodes.Call, flow.ReportException));
|
||||
}
|
||||
|
||||
private void RewriteFinally(ExceptionHandler handler, ref int index, ILProcessor il, ReportMethods flow) {
|
||||
var oldTryLeave = handler.TryEnd.Previous;
|
||||
|
||||
|
@ -136,6 +145,8 @@ namespace SharpLab.Server.Execution.Internal {
|
|||
handler.TryStart = instruction;
|
||||
if (handler.TryEnd == target)
|
||||
handler.TryEnd = instruction;
|
||||
if (handler.FilterStart == target)
|
||||
handler.FilterStart = instruction;
|
||||
if (handler.HandlerStart == target)
|
||||
handler.HandlerStart = instruction;
|
||||
if (handler.HandlerEnd == target)
|
||||
|
|
|
@ -17,6 +17,8 @@ namespace SharpLab.Tests {
|
|||
[Theory]
|
||||
[InlineData("Exceptions.DivideByZero.cs", 4, "DivideByZeroException")]
|
||||
[InlineData("Exceptions.DivideByZero.Catch.cs", 5, "DivideByZeroException")]
|
||||
[InlineData("Exceptions.DivideByZero.Catch.When.True.cs", 5, "DivideByZeroException")]
|
||||
[InlineData("Exceptions.DivideByZero.Catch.When.False.cs", 5, "DivideByZeroException")]
|
||||
[InlineData("Exceptions.DivideByZero.Finally.cs", 5, "DivideByZeroException")]
|
||||
public async Task SlowUpdate_ReportsExceptionInFlow(string resourceName, int expectedLineNumber, string expectedExceptionTypeName) {
|
||||
var driver = await NewTestDriverAsync(LoadCodeFromResource(resourceName));
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
public class C {
|
||||
public void M() {
|
||||
try {
|
||||
var x = 0;
|
||||
var y = x / 0;
|
||||
}
|
||||
catch when (false) {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
public class C {
|
||||
public void M() {
|
||||
try {
|
||||
var x = 0;
|
||||
var y = x / 0;
|
||||
}
|
||||
catch when (true) {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,71 +9,9 @@
|
|||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'" />
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="TestCode\Execution\Exceptions.DivideByZero.Catch.cs" />
|
||||
<Compile Remove="TestCode\Execution\Exceptions.DivideByZero.cs" />
|
||||
<Compile Remove="TestCode\Execution\Exceptions.DivideByZero.Finally.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="TestCode\Ast\EmptyClass.cs2ast" />
|
||||
<None Remove="TestCode\Ast\StructuredTrivia.cs2ast" />
|
||||
<None Remove="TestCode\Constructor.BaseCall.cs2cs" />
|
||||
<None Remove="TestCode\FSharp\EmptyType.fs2il" />
|
||||
<None Remove="TestCode\FSharp\NotNull.fs2cs" />
|
||||
<None Remove="TestCode\FSharp\SimpleMethod.fs2cs" />
|
||||
<None Remove="TestCode\Goto.TryWhile.cs2cs" />
|
||||
<None Remove="TestCode\JitAsm\ArrayElement.cs2asm" />
|
||||
<None Remove="TestCode\JitAsm\AsyncRegression.cs2asm" />
|
||||
<None Remove="TestCode\JitAsm\ConsoleWrite.cs2asm" />
|
||||
<None Remove="TestCode\JitAsm\MultipleReturns.cs2asm" />
|
||||
<None Remove="TestCode\JitAsm\Simple.cs2asm" />
|
||||
<None Remove="TestCode\Lambda.CallInArray.cs2cs" />
|
||||
<None Remove="TestCode\Module.vb2vb" />
|
||||
<None Remove="TestCode\NullPropagation.ToTernary.cs2cs" />
|
||||
<None Remove="TestCode\Simple.cs2il" />
|
||||
<None Remove="TestCode\Simple.vb2vb" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="TestCode\Execution\Exceptions.DivideByZero.Finally.cs" />
|
||||
<EmbeddedResource Include="TestCode\Execution\Exceptions.DivideByZero.cs" />
|
||||
<EmbeddedResource Include="TestCode\Execution\Exceptions.DivideByZero.Catch.cs" />
|
||||
<EmbeddedResource Include="TestCode\Variable.FromArgumentToCall.cs2cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="TestCode\Condition.SimpleSwitch.cs2cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="TestCode\Cast.ExplicitOperatorOnNull.cs2cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="TestCode\Ast\EmptyType.fs2ast" />
|
||||
<EmbeddedResource Include="TestCode\Ast\LiteralTokens.fs2ast" />
|
||||
<EmbeddedResource Include="TestCode\Ast\LiteralTokens.cs2ast" />
|
||||
<EmbeddedResource Include="TestCode\Ast\EmptyClass.cs2ast" />
|
||||
<EmbeddedResource Include="TestCode\Ast\StructuredTrivia.cs2ast" />
|
||||
<EmbeddedResource Include="TestCode\Constructor.BaseCall.cs2cs" />
|
||||
<EmbeddedResource Include="TestCode\FSharp\EmptyType.fs2il" />
|
||||
<EmbeddedResource Include="TestCode\FSharp\NotNull.fs2cs" />
|
||||
<EmbeddedResource Include="TestCode\FSharp\SimpleMethod.fs2cs" />
|
||||
<EmbeddedResource Include="TestCode\Goto.TryWhile.cs2cs" />
|
||||
<EmbeddedResource Include="TestCode\JitAsm\GenericMethodWithAttribute.fs2asm" />
|
||||
<EmbeddedResource Include="TestCode\JitAsm\OpenGenerics.cs2asm" />
|
||||
<EmbeddedResource Include="TestCode\JitAsm\GenericMethodWithAttribute.cs2asm" />
|
||||
<EmbeddedResource Include="TestCode\JitAsm\GenericClassWithAttribute.cs2asm" />
|
||||
<EmbeddedResource Include="TestCode\JitAsm\ArrayElement.cs2asm" />
|
||||
<EmbeddedResource Include="TestCode\JitAsm\AsyncRegression.cs2asm" />
|
||||
<EmbeddedResource Include="TestCode\JitAsm\ConsoleWrite.cs2asm" />
|
||||
<EmbeddedResource Include="TestCode\JitAsm\MultipleReturns.cs2asm" />
|
||||
<EmbeddedResource Include="TestCode\JitAsm\Simple.cs2asm" />
|
||||
<EmbeddedResource Include="TestCode\Lambda.CallInArray.cs2cs" />
|
||||
<EmbeddedResource Include="TestCode\Module.vb2vb" />
|
||||
<EmbeddedResource Include="TestCode\NullPropagation.ToTernary.cs2cs" />
|
||||
<EmbeddedResource Include="TestCode\Simple.cs2il" />
|
||||
<EmbeddedResource Include="TestCode\Simple.vb2vb" />
|
||||
<Compile Remove="TestCode\**\*.cs" />
|
||||
<None Remove="TestCode\**\*.*" />
|
||||
<EmbeddedResource Include="TestCode\**\*.*" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
Загрузка…
Ссылка в новой задаче