Skip to content

Commit

Permalink
CallBuilder: Extract handling of interpolated string pattern into sep…
Browse files Browse the repository at this point in the history
…arate method.
  • Loading branch information
siegfriedpammer committed Jul 20, 2024
1 parent fe87986 commit cf5f100
Showing 1 changed file with 73 additions and 62 deletions.
135 changes: 73 additions & 62 deletions ICSharpCode.Decompiler/CSharp/CallBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -345,69 +345,11 @@ public ExpressionWithResolveResult Build(OpCode callOpCode, IMethod method,
argumentList.GetArgumentResolveResults(), isExpandedForm: argumentList.IsExpandedForm, isDelegateInvocation: true));
}

if (settings.StringInterpolation && IsInterpolatedStringCreation(method, argumentList) &&
TryGetStringInterpolationTokens(argumentList, out string format, out var tokens))
if (settings.StringInterpolation && IsInterpolatedStringCreation(method, argumentList))
{
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, alignment, text) in tokens)
{
TranslatedExpression argument;
switch (kind)
{
case TokenKind.String:
content.Add(new InterpolatedStringText(text));
break;
case TokenKind.Argument:
argument = arguments[index + 1];
UnpackSingleElementArray(ref argument);
content.Add(new Interpolation(argument));
break;
case TokenKind.ArgumentWithFormat:
argument = arguments[index + 1];
UnpackSingleElementArray(ref argument);
content.Add(new Interpolation(argument, suffix: text));
break;
case TokenKind.ArgumentWithAlignment:
argument = arguments[index + 1];
UnpackSingleElementArray(ref argument);
content.Add(new Interpolation(argument, alignment));
break;
case TokenKind.ArgumentWithAlignmentAndFormat:
argument = arguments[index + 1];
UnpackSingleElementArray(ref argument);
content.Add(new Interpolation(argument, alignment, text));
break;
}
}
var formattableStringType = expressionBuilder.compilation.FindType(KnownTypeCode.FormattableString);
var isrr = new InterpolatedStringResolveResult(expressionBuilder.compilation.FindType(KnownTypeCode.String),
format, argumentList.GetArgumentResolveResults(1).ToArray());
var expr = new InterpolatedStringExpression();
expr.Content.AddRange(content);
if (method.Name == "Format")
return expr.WithRR(isrr);
return new CastExpression(expressionBuilder.ConvertType(formattableStringType),
expr.WithRR(isrr))
.WithRR(new ConversionResolveResult(formattableStringType, isrr, Conversion.ImplicitInterpolatedStringConversion));
}
var result = HandleStringInterpolation(method, argumentList);
if (result.Expression != null)
return result;
}

int allowedParamCount = (method.ReturnType.IsKnownType(KnownTypeCode.Void) ? 1 : 0);
Expand Down Expand Up @@ -482,6 +424,75 @@ void UnpackSingleElementArray(ref TranslatedExpression argument)
argumentList.GetArgumentResolveResultsDirect(), isExpandedForm: argumentList.IsExpandedForm));
}

private ExpressionWithResolveResult HandleStringInterpolation(IMethod method, ArgumentList argumentList)
{
if (!TryGetStringInterpolationTokens(argumentList, out string format, out var tokens))
return default;

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)
{
return default;
}

foreach (var (kind, index, alignment, text) in tokens)
{
TranslatedExpression argument;
switch (kind)
{
case TokenKind.String:
content.Add(new InterpolatedStringText(text));
break;
case TokenKind.Argument:
argument = arguments[index + 1];
UnpackSingleElementArray(ref argument);
content.Add(new Interpolation(argument));
break;
case TokenKind.ArgumentWithFormat:
argument = arguments[index + 1];
UnpackSingleElementArray(ref argument);
content.Add(new Interpolation(argument, suffix: text));
break;
case TokenKind.ArgumentWithAlignment:
argument = arguments[index + 1];
UnpackSingleElementArray(ref argument);
content.Add(new Interpolation(argument, alignment));
break;
case TokenKind.ArgumentWithAlignmentAndFormat:
argument = arguments[index + 1];
UnpackSingleElementArray(ref argument);
content.Add(new Interpolation(argument, alignment, text));
break;
}
}
var formattableStringType = expressionBuilder.compilation.FindType(KnownTypeCode.FormattableString);
var isrr = new InterpolatedStringResolveResult(expressionBuilder.compilation.FindType(KnownTypeCode.String),
format, argumentList.GetArgumentResolveResults(1).ToArray());
var expr = new InterpolatedStringExpression();
expr.Content.AddRange(content);
if (method.Name == "Format")
return expr.WithRR(isrr);
return new CastExpression(expressionBuilder.ConvertType(formattableStringType),
expr.WithRR(isrr))
.WithRR(new ConversionResolveResult(formattableStringType, isrr, Conversion.ImplicitInterpolatedStringConversion));
}

/// <summary>
/// Converts a call to an Add method to a collection initializer expression.
/// </summary>
Expand Down

0 comments on commit cf5f100

Please sign in to comment.