Permalink
Browse files

Fix bug in string interpolation handling.

  • Loading branch information...
siegfriedpammer committed Nov 4, 2018
1 parent c9b7486 commit ee584f3260317a26aaacd6e2c541c2778d1d63fd
@@ -21,6 +21,12 @@ public static void General(string[] args)
Console.WriteLine($"\ta{$"a{args.Length}" == args[0]}");
}
public static void ArrayExpansionSpecialCases(object[] args)
{
Console.WriteLine($"args: {args}");
Console.WriteLine(string.Format("args: {0}", args));
}
public static void InvalidFormatString(string[] args)
{
Console.WriteLine(string.Format("", args.Length));
@@ -169,6 +169,23 @@
IL_0115: ret
} // end of method CS6_StringInterpolation::General
.method public hidebysig static void ArrayExpansionSpecialCases(object[] args) cil managed
{
// Code size 33 (0x21)
.maxstack 8
IL_0000: ldstr "args: {0}"
IL_0005: ldarg.0
IL_0006: call string [mscorlib]System.String::Format(string,
object)
IL_000b: call void [mscorlib]System.Console::WriteLine(string)
IL_0010: ldstr "args: {0}"
IL_0015: ldarg.0
IL_0016: call string [mscorlib]System.String::Format(string,
object[])
IL_001b: call void [mscorlib]System.Console::WriteLine(string)
IL_0020: ret
} // end of method CS6_StringInterpolation::ArrayExpansionSpecialCases
.method public hidebysig static void InvalidFormatString(string[] args) cil managed
{
// Code size 556 (0x22c)
@@ -180,6 +180,26 @@
IL_011f: ret
} // end of method CS6_StringInterpolation::General
.method public hidebysig static void ArrayExpansionSpecialCases(object[] args) cil managed
{
// Code size 36 (0x24)
.maxstack 8
IL_0000: nop
IL_0001: ldstr "args: {0}"
IL_0006: ldarg.0
IL_0007: call string [mscorlib]System.String::Format(string,
object)
IL_000c: call void [mscorlib]System.Console::WriteLine(string)
IL_0011: nop
IL_0012: ldstr "args: {0}"
IL_0017: ldarg.0
IL_0018: call string [mscorlib]System.String::Format(string,
object[])
IL_001d: call void [mscorlib]System.Console::WriteLine(string)
IL_0022: nop
IL_0023: ret
} // end of method CS6_StringInterpolation::ArrayExpansionSpecialCases
.method public hidebysig static void InvalidFormatString(string[] args) cil managed
{
// Code size 581 (0x245)
@@ -235,22 +235,41 @@ public TranslatedExpression Build(CallInstruction inst)
argumentList.GetArgumentResolveResults().ToList(), isExpandedForm: argumentList.IsExpandedForm));
}
if (settings.StringInterpolation && IsInterpolatedStringCreation(method) &&
if (settings.StringInterpolation && IsInterpolatedStringCreation(method, argumentList) &&
TryGetStringInterpolationTokens(argumentList, out string format, out var tokens))
{
var arguments = argumentList.Arguments;
var content = new List<InterpolatedStringContent>();
bool unpackSingleElementArray = !argumentList.IsExpandedForm && argumentList.Length == 2
&& argumentList.Arguments[1].Expression is ArrayCreateExpression ace
&& ace.Initializer?.Elements.Count == 1;
void UnpackSingleElementArray(ref TranslatedExpression argument)
{
if (!unpackSingleElementArray) return;
var arrayCreation = (ArrayCreateExpression)argumentList.Arguments[1].Expression;
var arrayCreationRR = (ArrayCreateResolveResult)argumentList.Arguments[1].ResolveResult;
var element = arrayCreation.Initializer.Elements.First().Detach();
argument = new TranslatedExpression(element, arrayCreationRR.InitializerElements.First());
}
if (tokens.Count > 0) {
foreach (var (kind, index, text) in tokens) {
TranslatedExpression argument;
switch (kind) {
case TokenKind.String:
content.Add(new InterpolatedStringText(text));
break;
case TokenKind.Argument:
content.Add(new Interpolation(arguments[index + 1]));
argument = arguments[index + 1];
UnpackSingleElementArray(ref argument);
content.Add(new Interpolation(argument));
break;
case TokenKind.ArgumentWithFormat:
content.Add(new Interpolation(arguments[index + 1], text));
argument = arguments[index + 1];
UnpackSingleElementArray(ref argument);
content.Add(new Interpolation(argument, text));
break;
}
}
@@ -405,12 +424,18 @@ public TranslatedExpression Build(CallInstruction inst)
return new ExpressionWithResolveResult(((AssignmentExpression)assignment).Left.Detach());
}
private static bool IsInterpolatedStringCreation(IMethod method)
private static bool IsInterpolatedStringCreation(IMethod method, ArgumentList argumentList)
{
return method.IsStatic && (
(method.DeclaringType.IsKnownType(KnownTypeCode.String) && method.Name == "Format") ||
(method.Name == "Create" && method.DeclaringType.Name == "FormattableStringFactory" &&
method.DeclaringType.Namespace == "System.Runtime.CompilerServices")
)
&& argumentList.ArgumentNames == null // Argument names are not allowed
&& (
argumentList.IsExpandedForm // Must be expanded form
|| !method.Parameters.Last().IsParams // -or- not a params overload
|| (argumentList.Length == 2 && argumentList.Arguments[1].Expression is ArrayCreateExpression) // -or- an array literal
);
}

0 comments on commit ee584f3

Please sign in to comment.