diff --git a/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs b/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs index 994c16f3f..27e42e795 100644 --- a/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs @@ -16,6 +16,7 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +using System; using System.CodeDom.Compiler; using System.IO; using System.Linq; @@ -254,7 +255,7 @@ namespace ICSharpCode.Decompiler.Tests try { outputFile = Tester.CompileCSharp(Path.Combine(TestCasePath, testFileName), options, outputFileName: Path.Combine(TestCasePath, testOutputFileName)); - string decompiledCodeFile = Tester.DecompileCSharp(outputFile.PathToAssembly); + string decompiledCodeFile = Tester.DecompileCSharp(outputFile.PathToAssembly, GetSettings(options)); decompiledOutputFile = Tester.CompileCSharp(decompiledCodeFile, options); Tester.RunAndCompareOutput(testFileName, outputFile.PathToAssembly, decompiledOutputFile.PathToAssembly, decompiledCodeFile); @@ -268,7 +269,7 @@ namespace ICSharpCode.Decompiler.Tests decompiledOutputFile.TempFiles.Delete(); } } - + void RunIL(string testFileName, CompilerOptions options = CompilerOptions.UseDebug, AssemblerOptions asmOptions = AssemblerOptions.None) { string outputFile = null; @@ -276,7 +277,7 @@ namespace ICSharpCode.Decompiler.Tests try { outputFile = Tester.AssembleIL(Path.Combine(TestCasePath, testFileName), asmOptions); - string decompiledCodeFile = Tester.DecompileCSharp(outputFile); + string decompiledCodeFile = Tester.DecompileCSharp(outputFile, GetSettings(options)); decompiledOutputFile = Tester.CompileCSharp(decompiledCodeFile, options); Tester.RunAndCompareOutput(testFileName, outputFile, decompiledOutputFile.PathToAssembly, decompiledCodeFile); @@ -288,5 +289,15 @@ namespace ICSharpCode.Decompiler.Tests decompiledOutputFile.TempFiles.Delete(); } } + + DecompilerSettings GetSettings(CompilerOptions options) + { + if (!options.HasFlag(CompilerOptions.UseRoslyn)) { + return new DecompilerSettings { + StringInterpolation = false + }; + } + return new DecompilerSettings(); + } } } diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CS6_StringInterpolation.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CS6_StringInterpolation.cs index ed4146640..104417efd 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CS6_StringInterpolation.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CS6_StringInterpolation.cs @@ -38,6 +38,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty Console.WriteLine(string.Format("{}", args.Length)); Console.WriteLine(string.Format("{0:}", args.Length)); Console.WriteLine(string.Format("{0{a}0}", args.Length)); + Console.WriteLine(string.Format("test: {0}", string.Join(",", args))); } } } diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CS6_StringInterpolation.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CS6_StringInterpolation.opt.roslyn.il index 9f6074b2e..34f13e90b 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CS6_StringInterpolation.opt.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CS6_StringInterpolation.opt.roslyn.il @@ -25,14 +25,14 @@ .ver 0:0:0:0 } .module CS6_StringInterpolation.dll -// MVID: {12BAF781-868E-4161-A197-F81DC457D96B} +// MVID: {F5FD4CCF-66AB-4E03-8E45-96F42947A65D} .custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) .imagebase 0x10000000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x03620000 +// Image base: 0x03070000 // =============== CLASS MEMBERS DECLARATION =================== @@ -115,8 +115,8 @@ .method public hidebysig static void Invalid(string[] args) cil managed { - // Code size 530 (0x212) - .maxstack 2 + // Code size 556 (0x22c) + .maxstack 3 IL_0000: ldstr "" IL_0005: ldarg.0 IL_0006: ldlen @@ -301,7 +301,15 @@ IL_0207: call string [mscorlib]System.String::Format(string, object) IL_020c: call void [mscorlib]System.Console::WriteLine(string) - IL_0211: ret + IL_0211: ldstr "test: {0}" + IL_0216: ldstr "," + IL_021b: ldarg.0 + IL_021c: call string [mscorlib]System.String::Join(string, + string[]) + IL_0221: call string [mscorlib]System.String::Format(string, + object) + IL_0226: call void [mscorlib]System.Console::WriteLine(string) + IL_022b: ret } // end of method CS6_StringInterpolation::Invalid .method public hidebysig specialname rtspecialname diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CS6_StringInterpolation.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CS6_StringInterpolation.roslyn.il index b3113cf9d..e355bdd8d 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CS6_StringInterpolation.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CS6_StringInterpolation.roslyn.il @@ -25,14 +25,14 @@ .ver 0:0:0:0 } .module CS6_StringInterpolation.dll -// MVID: {97DDF3A3-A5BD-433E-B982-F6DD427CE8FF} +// MVID: {FE9286DD-8C20-4FC8-8786-543E572641EA} .custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) .imagebase 0x10000000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x03970000 +// Image base: 0x03840000 // =============== CLASS MEMBERS DECLARATION =================== @@ -121,8 +121,8 @@ .method public hidebysig static void Invalid(string[] args) cil managed { - // Code size 554 (0x22a) - .maxstack 2 + // Code size 581 (0x245) + .maxstack 3 IL_0000: nop IL_0001: ldstr "" IL_0006: ldarg.0 @@ -331,7 +331,16 @@ object) IL_0223: call void [mscorlib]System.Console::WriteLine(string) IL_0228: nop - IL_0229: ret + IL_0229: ldstr "test: {0}" + IL_022e: ldstr "," + IL_0233: ldarg.0 + IL_0234: call string [mscorlib]System.String::Join(string, + string[]) + IL_0239: call string [mscorlib]System.String::Format(string, + object) + IL_023e: call void [mscorlib]System.Console::WriteLine(string) + IL_0243: nop + IL_0244: ret } // end of method CS6_StringInterpolation::Invalid .method public hidebysig specialname rtspecialname diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/ReplaceMethodCallsWithOperators.cs b/ICSharpCode.Decompiler/CSharp/Transforms/ReplaceMethodCallsWithOperators.cs index 848196335..aaede07e4 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/ReplaceMethodCallsWithOperators.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/ReplaceMethodCallsWithOperators.cs @@ -110,7 +110,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms break; case "System.String.Format": if (context.Settings.StringInterpolation && arguments.Length > 1 - && arguments[0] is PrimitiveExpression stringExpression && stringExpression.Value is string) + && arguments[0] is PrimitiveExpression stringExpression && stringExpression.Value is string + && arguments.Skip(1).All(a => !a.DescendantsAndSelf.OfType().Any(p => p.Value is string))) { var tokens = new List<(TokenKind, int, string)>(); int i = 0;