Browse Source

Fix bug in StringInterpolation transform: do not transform if arguments use string literals, nested string literals are not allowed.

pull/1012/head
Siegfried Pammer 8 years ago
parent
commit
f59504bbce
  1. 17
      ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs
  2. 1
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/CS6_StringInterpolation.cs
  3. 18
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/CS6_StringInterpolation.opt.roslyn.il
  4. 19
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/CS6_StringInterpolation.roslyn.il
  5. 3
      ICSharpCode.Decompiler/CSharp/Transforms/ReplaceMethodCallsWithOperators.cs

17
ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs

@ -16,6 +16,7 @@ @@ -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 @@ -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 @@ -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 @@ -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 @@ -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();
}
}
}

1
ICSharpCode.Decompiler.Tests/TestCases/Pretty/CS6_StringInterpolation.cs

@ -38,6 +38,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -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)));
}
}
}

18
ICSharpCode.Decompiler.Tests/TestCases/Pretty/CS6_StringInterpolation.opt.roslyn.il

@ -25,14 +25,14 @@ @@ -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 @@ @@ -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 @@ @@ -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

19
ICSharpCode.Decompiler.Tests/TestCases/Pretty/CS6_StringInterpolation.roslyn.il

@ -25,14 +25,14 @@ @@ -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 @@ @@ -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 @@ @@ -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

3
ICSharpCode.Decompiler/CSharp/Transforms/ReplaceMethodCallsWithOperators.cs

@ -110,7 +110,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -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<PrimitiveExpression>().Any(p => p.Value is string)))
{
var tokens = new List<(TokenKind, int, string)>();
int i = 0;

Loading…
Cancel
Save