Browse Source

Add support for string format alignment.

pull/2743/head
Siegfried Pammer 4 years ago
parent
commit
5078796b17
  1. 2
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/StringInterpolation.cs
  2. 64
      ICSharpCode.Decompiler/CSharp/CallBuilder.cs
  3. 5
      ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs
  4. 12
      ICSharpCode.Decompiler/CSharp/Syntax/Expressions/InterpolatedStringExpression.cs

2
ICSharpCode.Decompiler.Tests/TestCases/Pretty/StringInterpolation.cs

@ -20,6 +20,8 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -20,6 +20,8 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
Console.WriteLine($"\ta{args[0][0] == 'a'}");
Console.WriteLine($"\ta{$"a{args.Length}" == args[0]}");
Console.WriteLine($"\ta{args.Length}}}");
Console.WriteLine($"{args.Length,5:x}");
Console.WriteLine($"{args.Length,5}");
}
public static void ArrayExpansionSpecialCases(object[] args)

64
ICSharpCode.Decompiler/CSharp/CallBuilder.cs

@ -357,7 +357,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -357,7 +357,7 @@ namespace ICSharpCode.Decompiler.CSharp
if (tokens.Count > 0)
{
foreach (var (kind, index, text) in tokens)
foreach (var (kind, index, alignment, text) in tokens)
{
TranslatedExpression argument;
switch (kind)
@ -373,7 +373,17 @@ namespace ICSharpCode.Decompiler.CSharp @@ -373,7 +373,17 @@ namespace ICSharpCode.Decompiler.CSharp
case TokenKind.ArgumentWithFormat:
argument = arguments[index + 1];
UnpackSingleElementArray(ref argument);
content.Add(new Interpolation(argument, text));
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;
}
}
@ -566,7 +576,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -566,7 +576,7 @@ namespace ICSharpCode.Decompiler.CSharp
);
}
private bool TryGetStringInterpolationTokens(ArgumentList argumentList, out string format, out List<(TokenKind, int, string)> tokens)
private bool TryGetStringInterpolationTokens(ArgumentList argumentList, out string format, out List<(TokenKind Kind, int Index, int Alignment, string Format)> tokens)
{
tokens = null;
format = null;
@ -577,33 +587,56 @@ namespace ICSharpCode.Decompiler.CSharp @@ -577,33 +587,56 @@ namespace ICSharpCode.Decompiler.CSharp
return false;
if (!arguments.Skip(1).All(a => !a.Expression.DescendantsAndSelf.OfType<PrimitiveExpression>().Any(p => p.Value is string)))
return false;
tokens = new List<(TokenKind, int, string)>();
tokens = new List<(TokenKind Kind, int Index, int Alignment, string Format)>();
int i = 0;
format = (string)crr.ConstantValue;
foreach (var (kind, data) in TokenizeFormatString(format))
{
int index;
string[] arg;
switch (kind)
{
case TokenKind.Error:
return false;
case TokenKind.String:
tokens.Add((kind, -1, data));
tokens.Add((kind, -1, 0, data));
break;
case TokenKind.Argument:
if (!int.TryParse(data, out index) || index != i)
return false;
i++;
tokens.Add((kind, index, null));
tokens.Add((kind, index, 0, null));
break;
case TokenKind.ArgumentWithFormat:
string[] arg = data.Split(new[] { ':' }, 2);
arg = data.Split(new[] { ':' }, 2);
if (arg.Length != 2 || arg[1].Length == 0)
return false;
if (!int.TryParse(arg[0], out index) || index != i)
return false;
i++;
tokens.Add((kind, index, arg[1]));
tokens.Add((kind, index, 0, arg[1]));
break;
case TokenKind.ArgumentWithAlignment:
arg = data.Split(new[] { ',' }, 2);
if (arg.Length != 2 || arg[1].Length == 0)
return false;
if (!int.TryParse(arg[0], out index) || index != i)
return false;
if (!int.TryParse(arg[1], out int alignment))
return false;
i++;
tokens.Add((kind, index, alignment, null));
break;
case TokenKind.ArgumentWithAlignmentAndFormat:
arg = data.Split(new[] { ',', ':' }, 3);
if (arg.Length != 3 || arg[1].Length == 0 || arg[2].Length == 0)
return false;
if (!int.TryParse(arg[0], out index) || index != i)
return false;
if (!int.TryParse(arg[1], out alignment))
return false;
i++;
tokens.Add((kind, index, alignment, arg[2]));
break;
default:
return false;
@ -617,7 +650,9 @@ namespace ICSharpCode.Decompiler.CSharp @@ -617,7 +650,9 @@ namespace ICSharpCode.Decompiler.CSharp
Error,
String,
Argument,
ArgumentWithFormat
ArgumentWithFormat,
ArgumentWithAlignment,
ArgumentWithAlignmentAndFormat,
}
private IEnumerable<(TokenKind, string)> TokenizeFormatString(string value)
@ -685,8 +720,19 @@ namespace ICSharpCode.Decompiler.CSharp @@ -685,8 +720,19 @@ namespace ICSharpCode.Decompiler.CSharp
{
kind = TokenKind.ArgumentWithFormat;
}
else if (kind == TokenKind.ArgumentWithAlignment)
{
kind = TokenKind.ArgumentWithAlignmentAndFormat;
}
sb.Append(':');
break;
case ',':
if (kind == TokenKind.Argument)
{
kind = TokenKind.ArgumentWithAlignment;
}
sb.Append(',');
break;
default:
sb.Append((char)next);
break;

5
ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs

@ -1168,6 +1168,11 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -1168,6 +1168,11 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
writer.WriteToken(Interpolation.LBrace, "{");
interpolation.Expression.AcceptVisitor(this);
if (interpolation.Alignment != 0)
{
writer.WriteToken(Roles.Comma, ",");
writer.WritePrimitiveValue(interpolation.Alignment);
}
if (interpolation.Suffix != null)
{
writer.WriteToken(Roles.Colon, ":");

12
ICSharpCode.Decompiler/CSharp/Syntax/Expressions/InterpolatedStringExpression.cs

@ -20,6 +20,11 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -20,6 +20,11 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
}
public InterpolatedStringExpression(IList<InterpolatedStringContent> content)
{
Content.AddRange(content);
}
public override void AcceptVisitor(IAstVisitor visitor)
{
visitor.VisitInterpolatedStringExpression(this);
@ -83,7 +88,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -83,7 +88,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
}
/// <summary>
/// { Expression }
/// { Expression , Alignment : Suffix }
/// </summary>
public class Interpolation : InterpolatedStringContent
{
@ -99,6 +104,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -99,6 +104,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
set { SetChildByRole(Roles.Expression, value); }
}
public int Alignment { get; }
public string Suffix { get; }
public CSharpTokenNode RBraceToken {
@ -110,9 +117,10 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -110,9 +117,10 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
}
public Interpolation(Expression expression, string suffix = null)
public Interpolation(Expression expression, int alignment = 0, string suffix = null)
{
Expression = expression;
Alignment = alignment;
Suffix = suffix;
}

Loading…
Cancel
Save