Skip to content

Commit

Permalink
#1922: Refactor PrimitiveExpression to store the literal format in th…
Browse files Browse the repository at this point in the history
…e AST
  • Loading branch information
dgrunwald committed Feb 14, 2020
1 parent 8d780cc commit a7446cf
Show file tree
Hide file tree
Showing 10 changed files with 77 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -992,7 +992,7 @@ public virtual void VisitPointerReferenceExpression(PointerReferenceExpression p
public virtual void VisitPrimitiveExpression(PrimitiveExpression primitiveExpression)
{
StartNode(primitiveExpression);
writer.WritePrimitiveValue(primitiveExpression.Value, primitiveExpression.UnsafeLiteralValue);
writer.WritePrimitiveValue(primitiveExpression.Value, primitiveExpression.Format);
isAfterSpace = false;
EndNode(primitiveExpression);
}
Expand All @@ -1019,7 +1019,7 @@ public virtual void VisitInterpolation(Interpolation interpolation)
interpolation.Expression.AcceptVisitor(this);
if (interpolation.Suffix != null) {
writer.WriteToken(Roles.Colon, ":");
writer.WritePrimitiveValue("", interpolation.Suffix);
writer.WriteInterpolatedText(interpolation.Suffix);
}
writer.WriteToken(Interpolation.RBrace, "}");

Expand All @@ -1029,7 +1029,7 @@ public virtual void VisitInterpolation(Interpolation interpolation)
public virtual void VisitInterpolatedStringText(InterpolatedStringText interpolatedStringText)
{
StartNode(interpolatedStringText);
writer.WritePrimitiveValue("", TextWriterTokenWriter.ConvertString(interpolatedStringText.Text));
writer.WriteInterpolatedText(interpolatedStringText.Text);
EndNode(interpolatedStringText);
}
#endregion
Expand Down
16 changes: 13 additions & 3 deletions ICSharpCode.Decompiler/CSharp/OutputVisitor/ITokenWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,15 @@ public abstract class TokenWriter
/// <summary>
/// Writes a primitive/literal value
/// </summary>
public abstract void WritePrimitiveValue(object value, string literalValue = null);
public abstract void WritePrimitiveValue(object value, LiteralFormat format = LiteralFormat.None);

public abstract void WritePrimitiveType(string type);

/// <summary>
/// Write a piece of text in an interpolated string literal.
/// </summary>
public abstract void WriteInterpolatedText(string text);

public abstract void Space();
public abstract void Indent();
public abstract void Unindent();
Expand Down Expand Up @@ -123,16 +128,21 @@ public override void WriteToken(Role role, string token)
decoratedWriter.WriteToken(role, token);
}

public override void WritePrimitiveValue(object value, string literalValue = null)
public override void WritePrimitiveValue(object value, LiteralFormat format = LiteralFormat.None)
{
decoratedWriter.WritePrimitiveValue(value, literalValue);
decoratedWriter.WritePrimitiveValue(value, format);
}

public override void WritePrimitiveType(string type)
{
decoratedWriter.WritePrimitiveType(type);
}

public override void WriteInterpolatedText(string text)
{
decoratedWriter.WriteInterpolatedText(text);
}

public override void Space()
{
decoratedWriter.Space();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,19 +116,19 @@ public override void WriteIdentifier(Identifier identifier)
base.WriteIdentifier(identifier);
}

public override void WritePrimitiveValue(object value, string literalValue = null)
public override void WritePrimitiveValue(object value, LiteralFormat format = LiteralFormat.None)
{
Expression node = nodes.Peek().LastOrDefault() as Expression;
var startLocation = locationProvider.Location;
base.WritePrimitiveValue(value, literalValue);
base.WritePrimitiveValue(value, format);
if (node is PrimitiveExpression) {
((PrimitiveExpression)node).SetLocation(startLocation, locationProvider.Location);
}
if (node is NullReferenceExpression) {
((NullReferenceExpression)node).SetStartLocation(startLocation);
}
}

public override void WritePrimitiveType(string type)
{
PrimitiveType node = nodes.Peek().LastOrDefault() as PrimitiveType;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,12 @@ public override void WritePreProcessorDirective(PreProcessorDirectiveType type,
lastWritten = LastWritten.Whitespace;
}

public override void WritePrimitiveValue(object value, string literalValue = null)
public override void WritePrimitiveValue(object value, LiteralFormat format = LiteralFormat.None)
{
if (lastWritten == LastWritten.KeywordOrIdentifier) {
Space();
}
base.WritePrimitiveValue(value, literalValue);
base.WritePrimitiveValue(value, format);
if (value == null || value is bool)
return;
if (value is string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,16 +224,9 @@ public static string PrintPrimitiveValue(object value)
tokenWriter.WritePrimitiveValue(value);
return writer.ToString();
}

public override void WritePrimitiveValue(object value, string literalValue = null)
public override void WritePrimitiveValue(object value, LiteralFormat format = LiteralFormat.None)
{
if (literalValue != null) {
textWriter.Write(literalValue);
column += literalValue.Length;
Length += literalValue.Length;
return;
}

if (value == null) {
// usually NullReferenceExpression should be used for this, but we'll handle it anyways
textWriter.Write("null");
Expand Down Expand Up @@ -346,12 +339,12 @@ public override void WritePrimitiveValue(object value, string literalValue = nul
Length += number.Length;
} else if (value is IFormattable) {
StringBuilder b = new StringBuilder();
// if (primitiveExpression.LiteralFormat == LiteralFormat.HexadecimalNumber) {
// b.Append("0x");
// b.Append(((IFormattable)val).ToString("x", NumberFormatInfo.InvariantInfo));
// } else {
b.Append(((IFormattable)value).ToString(null, NumberFormatInfo.InvariantInfo));
// }
if (format == LiteralFormat.HexadecimalNumber) {
b.Append("0x");
b.Append(((IFormattable)value).ToString("X", NumberFormatInfo.InvariantInfo));
} else {
b.Append(((IFormattable)value).ToString(null, NumberFormatInfo.InvariantInfo));
}
if (value is uint || value is ulong) {
b.Append("u");
}
Expand All @@ -369,6 +362,11 @@ public override void WritePrimitiveValue(object value, string literalValue = nul
}
}

public override void WriteInterpolatedText(string text)
{
textWriter.Write(ConvertString(text));
}

/// <summary>
/// Gets the escape sequence for the specified character within a char literal.
/// Does not include the single quotes surrounding the char literal.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,20 @@

namespace ICSharpCode.Decompiler.CSharp.Syntax
{
/// <summary>
/// Form of a C# literal.
/// </summary>
public enum LiteralFormat : byte
{
None,
DecimalNumber,
HexadecimalNumber,
BinaryNumber,
StringLiteral,
VerbatimStringLiteral,
CharLiteral,
}

/// <summary>
/// Represents a literal value.
/// </summary>
Expand Down Expand Up @@ -63,26 +77,16 @@ public override TextLocation EndLocation {
}

object value;

LiteralFormat format;

public object Value {
get { return this.value; }
set {
ThrowIfFrozen();
this.value = value;
literalValue = null;
}
}

/// <remarks>Never returns null.</remarks>
public string LiteralValue {
get { return literalValue ?? ""; }
}

/// <remarks>Can be null.</remarks>
public string UnsafeLiteralValue {
get { return literalValue; }
}

public void SetValue(object value, string literalValue)
{
if (value == null)
Expand All @@ -91,24 +95,24 @@ public void SetValue(object value, string literalValue)
this.value = value;
this.literalValue = literalValue;
}

public PrimitiveExpression (object value)
{
this.Value = value;
this.literalValue = null;

public LiteralFormat Format {
get { return format;}
set {
ThrowIfFrozen();
format = value;
}
}
public PrimitiveExpression (object value, string literalValue)

public PrimitiveExpression (object value)
{
this.Value = value;
this.literalValue = literalValue;
}

public PrimitiveExpression (object value, TextLocation startLocation, string literalValue)
public PrimitiveExpression (object value, LiteralFormat format)
{
this.Value = value;
this.startLocation = startLocation;
this.literalValue = literalValue;
this.format = format;
}

public override void AcceptVisitor (IAstVisitor visitor)
Expand Down
12 changes: 3 additions & 9 deletions ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -784,17 +784,11 @@ public Expression ConvertConstantValue(IType expectedType, IType type, object co
constantValue = CSharpPrimitiveCast.Cast(TypeCode.Int32, constantValue, false);
literalType = type.GetDefinition().Compilation.FindType(KnownTypeCode.Int32);
}
string literalValue = null;
LiteralFormat format = LiteralFormat.None;
if (PrintIntegralValuesAsHex) {
literalValue = $"0x{constantValue:X}";
if (constantValue is uint || constantValue is ulong) {
literalValue += "u";
}
if (constantValue is long || constantValue is ulong) {
literalValue += "L";
}
format = LiteralFormat.HexadecimalNumber;
}
expr = new PrimitiveExpression(constantValue, literalValue);
expr = new PrimitiveExpression(constantValue, format);
if (AddResolveResultAnnotations)
expr.AddAnnotation(new ConstantResolveResult(literalType, constantValue));
if (smallInteger && !type.Equals(expectedType)) {
Expand Down
11 changes: 8 additions & 3 deletions ICSharpCode.Decompiler/Output/TextTokenWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -322,11 +322,16 @@ public override void WritePreProcessorDirective(PreProcessorDirectiveType type,
output.WriteLine();
}

public override void WritePrimitiveValue(object value, string literalValue = null)
public override void WritePrimitiveValue(object value, LiteralFormat format = LiteralFormat.None)
{
new TextWriterTokenWriter(new TextOutputWriter(output)).WritePrimitiveValue(value, literalValue);
new TextWriterTokenWriter(new TextOutputWriter(output)).WritePrimitiveValue(value, format);
}


public override void WriteInterpolatedText(string text)
{
output.Write(TextWriterTokenWriter.ConvertString(text));
}

public override void WritePrimitiveType(string type)
{
switch (type) {
Expand Down
4 changes: 2 additions & 2 deletions ILSpy/Languages/CSharpHighlightingTokenWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ public override void WriteIdentifier(Identifier identifier)
}
}

public override void WritePrimitiveValue(object value, string literalValue = null)
public override void WritePrimitiveValue(object value, Decompiler.CSharp.Syntax.LiteralFormat format)
{
HighlightingColor color = null;
if (value is null) {
Expand All @@ -404,7 +404,7 @@ public override void WritePrimitiveValue(object value, string literalValue = nul
if (color != null) {
BeginSpan(color);
}
base.WritePrimitiveValue(value, literalValue);
base.WritePrimitiveValue(value, format);
if (color != null) {
EndSpan();
}
Expand Down
6 changes: 3 additions & 3 deletions ILSpy/Languages/CSharpLexer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

namespace ICSharpCode.ILSpy
{
public class LATextReader : TextReader
class LATextReader : TextReader
{
List<int> buffer;
TextReader reader;
Expand Down Expand Up @@ -52,7 +52,7 @@ protected override void Dispose(bool disposing)
}
}

public enum LiteralFormat : byte
enum LiteralFormat : byte
{
None,
DecimalNumber,
Expand All @@ -64,7 +64,7 @@ public enum LiteralFormat : byte
DateTimeLiteral
}

public class Literal
class Literal
{
internal readonly LiteralFormat literalFormat;
internal readonly object literalValue;
Expand Down

0 comments on commit a7446cf

Please sign in to comment.