Browse Source

StringInterpolation: basic implementation in AST

pull/1012/head
Siegfried Pammer 8 years ago
parent
commit
bcb9cca39b
  1. 38
      ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs
  2. 51
      ICSharpCode.Decompiler/CSharp/Syntax/DepthFirstAstVisitor.cs
  3. 169
      ICSharpCode.Decompiler/CSharp/Syntax/Expressions/InterpolatedStringExpression.cs
  4. 16
      ICSharpCode.Decompiler/CSharp/Syntax/IAstVisitor.cs
  5. 15
      ICSharpCode.Decompiler/DecompilerSettings.cs
  6. 1
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

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

@ -980,8 +980,44 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -980,8 +980,44 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
isAfterSpace = false;
EndNode(primitiveExpression);
}
public virtual void VisitInterpolatedStringExpression(InterpolatedStringExpression interpolatedStringExpression)
{
StartNode(interpolatedStringExpression);
writer.WriteToken(Roles.Error, "$\"");
foreach (var element in interpolatedStringExpression.Content) {
element.AcceptVisitor(this);
}
writer.WriteToken(Roles.Error, "\"");
isAfterSpace = false;
EndNode(interpolatedStringExpression);
}
public virtual void VisitInterpolation(Interpolation interpolation)
{
StartNode(interpolation);
writer.WriteToken(Roles.LBrace, "{");
interpolation.Expression.AcceptVisitor(this);
if (interpolation.Suffix != null) {
writer.WriteToken(Roles.Colon, ":");
writer.WritePrimitiveValue("", interpolation.Suffix);
}
writer.WriteToken(Roles.RBrace, "}");
EndNode(interpolation);
}
public virtual void VisitInterpolatedStringText(InterpolatedStringText interpolatedStringText)
{
StartNode(interpolatedStringText);
writer.WritePrimitiveValue("", TextWriterTokenWriter.ConvertString(interpolatedStringText.Text));
EndNode(interpolatedStringText);
}
#endregion
public virtual void VisitSizeOfExpression(SizeOfExpression sizeOfExpression)
{
StartNode(sizeOfExpression);

51
ICSharpCode.Decompiler/CSharp/Syntax/DepthFirstAstVisitor.cs

@ -445,7 +445,22 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -445,7 +445,22 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
{
VisitChildren (indexerExpression);
}
public virtual void VisitInterpolatedStringExpression(InterpolatedStringExpression interpolatedStringExpression)
{
VisitChildren(interpolatedStringExpression);
}
public virtual void VisitInterpolation(Interpolation interpolation)
{
VisitChildren(interpolation);
}
public virtual void VisitInterpolatedStringText(InterpolatedStringText interpolatedStringText)
{
VisitChildren(interpolatedStringText);
}
public virtual void VisitInvocationExpression (InvocationExpression invocationExpression)
{
VisitChildren (invocationExpression);
@ -1062,7 +1077,22 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1062,7 +1077,22 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
{
return VisitChildren (indexerExpression);
}
public virtual T VisitInterpolatedStringExpression(InterpolatedStringExpression interpolatedStringExpression)
{
return VisitChildren(interpolatedStringExpression);
}
public virtual T VisitInterpolation(Interpolation interpolation)
{
return VisitChildren(interpolation);
}
public virtual T VisitInterpolatedStringText(InterpolatedStringText interpolatedStringText)
{
return VisitChildren(interpolatedStringText);
}
public virtual T VisitInvocationExpression (InvocationExpression invocationExpression)
{
return VisitChildren (invocationExpression);
@ -1679,7 +1709,22 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1679,7 +1709,22 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
{
return VisitChildren (indexerExpression, data);
}
public virtual S VisitInterpolatedStringExpression(InterpolatedStringExpression interpolatedStringExpression, T data)
{
return VisitChildren(interpolatedStringExpression, data);
}
public virtual S VisitInterpolation(Interpolation interpolation, T data)
{
return VisitChildren(interpolation, data);
}
public virtual S VisitInterpolatedStringText(InterpolatedStringText interpolatedStringText, T data)
{
return VisitChildren(interpolatedStringText, data);
}
public virtual S VisitInvocationExpression (InvocationExpression invocationExpression, T data)
{
return VisitChildren (invocationExpression, data);

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

@ -0,0 +1,169 @@ @@ -0,0 +1,169 @@
using System;
using System.Collections.Generic;
using System.Text;
using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;
namespace ICSharpCode.Decompiler.CSharp.Syntax
{
public class InterpolatedStringExpression : Expression
{
public AstNodeCollection<InterpolatedStringContent> Content {
get { return GetChildrenByRole(InterpolatedStringContent.Role); }
}
public InterpolatedStringExpression()
{
}
public override void AcceptVisitor(IAstVisitor visitor)
{
visitor.VisitInterpolatedStringExpression(this);
}
public override T AcceptVisitor<T>(IAstVisitor<T> visitor)
{
return visitor.VisitInterpolatedStringExpression(this);
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitInterpolatedStringExpression(this, data);
}
protected internal override bool DoMatch(AstNode other, Match match)
{
InterpolatedStringExpression o = other as InterpolatedStringExpression;
return o != null && !o.IsNull && this.Content.DoMatch(o.Content, match);
}
}
public abstract class InterpolatedStringContent : AstNode
{
#region Null
public new static readonly InterpolatedStringContent Null = new NullInterpolatedStringContent();
sealed class NullInterpolatedStringContent : InterpolatedStringContent
{
public override bool IsNull {
get {
return true;
}
}
public override void AcceptVisitor(IAstVisitor visitor)
{
visitor.VisitNullNode(this);
}
public override T AcceptVisitor<T>(IAstVisitor<T> visitor)
{
return visitor.VisitNullNode(this);
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitNullNode(this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return other == null || other.IsNull;
}
}
#endregion
public new static readonly Role<InterpolatedStringContent> Role = new Role<InterpolatedStringContent>("InterpolatedStringContent", Syntax.InterpolatedStringContent.Null);
public override NodeType NodeType => NodeType.Unknown;
}
/// <summary>
/// { Expression }
/// </summary>
public class Interpolation : InterpolatedStringContent
{
public CSharpTokenNode LBraceToken {
get { return GetChildByRole(Roles.LBrace); }
}
public Expression Expression {
get { return GetChildByRole(Roles.Expression); }
set { SetChildByRole(Roles.Expression, value); }
}
public string Suffix { get; }
public CSharpTokenNode RBraceToken {
get { return GetChildByRole(Roles.RBrace); }
}
public Interpolation()
{
}
public Interpolation(Expression expression, string suffix = null)
{
Expression = expression;
Suffix = suffix;
}
public override void AcceptVisitor(IAstVisitor visitor)
{
visitor.VisitInterpolation(this);
}
public override T AcceptVisitor<T>(IAstVisitor<T> visitor)
{
return visitor.VisitInterpolation(this);
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitInterpolation(this, data);
}
protected internal override bool DoMatch(AstNode other, Match match)
{
Interpolation o = other as Interpolation;
return o != null && this.Expression.DoMatch(o.Expression, match);
}
}
public class InterpolatedStringText : InterpolatedStringContent
{
public string Text { get; set; }
public InterpolatedStringText()
{
}
public InterpolatedStringText(string text)
{
Text = text;
}
public override void AcceptVisitor(IAstVisitor visitor)
{
visitor.VisitInterpolatedStringText(this);
}
public override T AcceptVisitor<T>(IAstVisitor<T> visitor)
{
return visitor.VisitInterpolatedStringText(this);
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitInterpolatedStringText(this, data);
}
protected internal override bool DoMatch(AstNode other, Match match)
{
InterpolatedStringText o = other as InterpolatedStringText;
return o != null && o.Text == this.Text;
}
}
}

16
ICSharpCode.Decompiler/CSharp/Syntax/IAstVisitor.cs

@ -39,6 +39,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -39,6 +39,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
void VisitDirectionExpression(DirectionExpression directionExpression);
void VisitIdentifierExpression(IdentifierExpression identifierExpression);
void VisitIndexerExpression(IndexerExpression indexerExpression);
void VisitInterpolatedStringExpression(InterpolatedStringExpression interpolatedStringExpression);
void VisitInvocationExpression(InvocationExpression invocationExpression);
void VisitIsExpression(IsExpression isExpression);
void VisitLambdaExpression(LambdaExpression lambdaExpression);
@ -147,6 +148,9 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -147,6 +148,9 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
void VisitConstraint(Constraint constraint);
void VisitCSharpTokenNode(CSharpTokenNode cSharpTokenNode);
void VisitIdentifier(Identifier identifier);
void VisitInterpolation(Interpolation interpolation);
void VisitInterpolatedStringText(InterpolatedStringText interpolatedStringText);
void VisitNullNode(AstNode nullNode);
void VisitErrorNode(AstNode errorNode);
@ -173,6 +177,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -173,6 +177,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
S VisitDirectionExpression(DirectionExpression directionExpression);
S VisitIdentifierExpression(IdentifierExpression identifierExpression);
S VisitIndexerExpression(IndexerExpression indexerExpression);
S VisitInterpolatedStringExpression(InterpolatedStringExpression interpolatedStringExpression);
S VisitInvocationExpression(InvocationExpression invocationExpression);
S VisitIsExpression(IsExpression isExpression);
S VisitLambdaExpression(LambdaExpression lambdaExpression);
@ -281,7 +286,10 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -281,7 +286,10 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
S VisitConstraint(Constraint constraint);
S VisitCSharpTokenNode(CSharpTokenNode cSharpTokenNode);
S VisitIdentifier(Identifier identifier);
S VisitInterpolation(Interpolation interpolation);
S VisitInterpolatedStringText(InterpolatedStringText interpolatedStringText);
S VisitNullNode(AstNode nullNode);
S VisitErrorNode(AstNode errorNode);
S VisitPatternPlaceholder(AstNode placeholder, PatternMatching.Pattern pattern);
@ -307,6 +315,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -307,6 +315,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
S VisitDirectionExpression(DirectionExpression directionExpression, T data);
S VisitIdentifierExpression(IdentifierExpression identifierExpression, T data);
S VisitIndexerExpression(IndexerExpression indexerExpression, T data);
S VisitInterpolatedStringExpression(InterpolatedStringExpression interpolatedStringExpression, T data);
S VisitInvocationExpression(InvocationExpression invocationExpression, T data);
S VisitIsExpression(IsExpression isExpression, T data);
S VisitLambdaExpression(LambdaExpression lambdaExpression, T data);
@ -415,7 +424,10 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -415,7 +424,10 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
S VisitConstraint(Constraint constraint, T data);
S VisitCSharpTokenNode(CSharpTokenNode cSharpTokenNode, T data);
S VisitIdentifier(Identifier identifier, T data);
S VisitInterpolation(Interpolation interpolation, T data);
S VisitInterpolatedStringText(InterpolatedStringText interpolatedStringText, T data);
S VisitNullNode(AstNode nullNode, T data);
S VisitErrorNode(AstNode errorNode, T data);
S VisitPatternPlaceholder(AstNode placeholder, PatternMatching.Pattern pattern, T data);

15
ICSharpCode.Decompiler/DecompilerSettings.cs

@ -318,6 +318,21 @@ namespace ICSharpCode.Decompiler @@ -318,6 +318,21 @@ namespace ICSharpCode.Decompiler
}
}
bool stringInterpolation = true;
/// <summary>
/// Gets/Sets whether to use C# 6.0 string interpolation
/// </summary>
public bool StringInterpolation {
get { return stringInterpolation; }
set {
if (stringInterpolation != value) {
stringInterpolation = value;
OnPropertyChanged();
}
}
}
bool showXmlDocumentation = true;
/// <summary>

1
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -88,6 +88,7 @@ @@ -88,6 +88,7 @@
<Compile Include="CSharp\Syntax\Expressions\Expression.cs" />
<Compile Include="CSharp\Syntax\Expressions\IdentifierExpression.cs" />
<Compile Include="CSharp\Syntax\Expressions\IndexerExpression.cs" />
<Compile Include="CSharp\Syntax\Expressions\InterpolatedStringExpression.cs" />
<Compile Include="CSharp\Syntax\Expressions\InvocationExpression.cs" />
<Compile Include="CSharp\Syntax\Expressions\IsExpression.cs" />
<Compile Include="CSharp\Syntax\Expressions\LambdaExpression.cs" />

Loading…
Cancel
Save