From 4388c14afd131046cce1371f734fe80802741d8b Mon Sep 17 00:00:00 2001 From: Andrey Shchekin Date: Sun, 25 Jun 2017 17:18:17 +1200 Subject: [PATCH] [closes gh-25] Fixed incorrect negation in string comparisons. --- .../DecompiledPseudoCSharpOutputVisitor.cs | 24 -------------- source/Tests/DecompilationTests.cs | 22 +++++++++++-- ...s2cs => Cast.ExplicitOperatorOnNull.cs2cs} | 0 .../TestCode/Condition.SimpleSwitch.cs2cs | 32 +++++++++++++++++++ source/Tests/Tests.csproj | 6 +++- 5 files changed, 56 insertions(+), 28 deletions(-) rename source/Tests/TestCode/{Casts.ExplicitOperatorOnNull.cs2cs => Cast.ExplicitOperatorOnNull.cs2cs} (100%) create mode 100644 source/Tests/TestCode/Condition.SimpleSwitch.cs2cs diff --git a/source/Server/Decompilation/Internal/DecompiledPseudoCSharpOutputVisitor.cs b/source/Server/Decompilation/Internal/DecompiledPseudoCSharpOutputVisitor.cs index 30003ac..5204b0b 100644 --- a/source/Server/Decompilation/Internal/DecompiledPseudoCSharpOutputVisitor.cs +++ b/source/Server/Decompilation/Internal/DecompiledPseudoCSharpOutputVisitor.cs @@ -15,30 +15,6 @@ namespace SharpLab.Server.Decompilation.Internal { public DecompiledPseudoCSharpOutputVisitor(TokenWriter tokenWriter, CSharpFormattingOptions formattingPolicy) : base(tokenWriter, formattingPolicy) { } - // fixes bug https://github.com/ashmind/SharpLab/issues/7 - // todo: report this to the decompiler guys -- but does not seem like they are reading their queue - public override void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression) { - StartNode(memberReferenceExpression); - - var useParentheses = RequiresParenthesesWhenTargetOfMemberReference(memberReferenceExpression.Target); - if (useParentheses) - LPar(); - memberReferenceExpression.Target.AcceptVisitor(this); - if (useParentheses) - RPar(); - - WriteToken(Roles.Dot); - WriteIdentifier(memberReferenceExpression.MemberName); - WriteTypeArguments(memberReferenceExpression.TypeArguments); - EndNode(memberReferenceExpression); - } - - private bool RequiresParenthesesWhenTargetOfMemberReference(Expression expression) { - return (expression is ConditionalExpression) - || (expression is BinaryOperatorExpression) - || (expression is UnaryOperatorExpression); - } - public override void VisitExpressionStatement(ExpressionStatement expressionStatement) { StartNode(expressionStatement); expressionStatement.Expression.AcceptVisitor(this); diff --git a/source/Tests/DecompilationTests.cs b/source/Tests/DecompilationTests.cs index ae62882..50a39cf 100644 --- a/source/Tests/DecompilationTests.cs +++ b/source/Tests/DecompilationTests.cs @@ -32,7 +32,7 @@ namespace SharpLab.Tests { // https://github.com/ashmind/SharpLab/issues/9 [InlineData("Lambda.CallInArray.cs2cs")] // https://github.com/ashmind/SharpLab/issues/20 - [InlineData("Casts.ExplicitOperatorOnNull.cs2cs")] + [InlineData("Cast.ExplicitOperatorOnNull.cs2cs")] public async Task SlowUpdate_ReturnsExpectedDecompiledCode(string resourceName) { var data = TestData.FromResource(resourceName); var driver = await NewTestDriverAsync(data); @@ -46,6 +46,22 @@ namespace SharpLab.Tests { Assert.Equal(data.Expected, decompiledText); } + [Theory] + // https://github.com/ashmind/SharpLab/issues/25 + [InlineData("Condition.SimpleSwitch.cs2cs")] + public async Task SlowUpdate_ReturnsExpectedDecompiledCode_InDebug(string resourceName) { + var data = TestData.FromResource(resourceName); + var driver = await NewTestDriverAsync(data, OptimizationLevel.Debug); + + var result = await driver.SendSlowUpdateAsync(); + var errors = result.JoinErrors(); + + var decompiledText = result.ExtensionResult?.Trim(); + _output.WriteLine(decompiledText); + Assert.True(errors.IsNullOrEmpty(), errors); + Assert.Equal(data.Expected, decompiledText); + } + [Theory] [InlineData("FSharp.EmptyType.fs2il")] [InlineData("FSharp.SimpleMethod.fs2cs")] @@ -113,11 +129,11 @@ namespace SharpLab.Tests { ); } - private static async Task NewTestDriverAsync(TestData data) { + private static async Task NewTestDriverAsync(TestData data, OptimizationLevel optimizationLevel = OptimizationLevel.Release) { var driver = MirrorSharpTestDriver.New(MirrorSharpOptions); await driver.SendSetOptionsAsync(new Dictionary { {"language", data.SourceLanguageName}, - {"optimize", nameof(OptimizationLevel.Release).ToLowerInvariant()}, + {"optimize", optimizationLevel.ToString().ToLowerInvariant()}, {"x-target", data.TargetLanguageName} }); driver.SetText(data.Original); diff --git a/source/Tests/TestCode/Casts.ExplicitOperatorOnNull.cs2cs b/source/Tests/TestCode/Cast.ExplicitOperatorOnNull.cs2cs similarity index 100% rename from source/Tests/TestCode/Casts.ExplicitOperatorOnNull.cs2cs rename to source/Tests/TestCode/Cast.ExplicitOperatorOnNull.cs2cs diff --git a/source/Tests/TestCode/Condition.SimpleSwitch.cs2cs b/source/Tests/TestCode/Condition.SimpleSwitch.cs2cs new file mode 100644 index 0000000..4a66d97 --- /dev/null +++ b/source/Tests/TestCode/Condition.SimpleSwitch.cs2cs @@ -0,0 +1,32 @@ +public class C { + public void M(string n) { + switch(n) { + case "foo": break; + } + } +} + +#=> + +using System; +using System.Diagnostics; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Security; +using System.Security.Permissions; + +[assembly: AssemblyVersion("0.0.0.0")] +[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] +[assembly: CompilationRelaxations(8)] +[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] +[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] +[module: UnverifiableCode] +public class C +{ + public void M(string n) + { + if (n != "foo") + { + } + } +} \ No newline at end of file diff --git a/source/Tests/Tests.csproj b/source/Tests/Tests.csproj index 16e9304..cae5885 100644 --- a/source/Tests/Tests.csproj +++ b/source/Tests/Tests.csproj @@ -27,7 +27,11 @@ - + + + + +