Browse Source

#1922: Refactor PrimitiveExpression to store the literal format in the AST

pull/1930/head
Daniel Grunwald 6 years ago
parent
commit
a7446cfddf
  1. 6
      ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs
  2. 16
      ICSharpCode.Decompiler/CSharp/OutputVisitor/ITokenWriter.cs
  3. 6
      ICSharpCode.Decompiler/CSharp/OutputVisitor/InsertMissingTokensDecorator.cs
  4. 4
      ICSharpCode.Decompiler/CSharp/OutputVisitor/InsertRequiredSpacesDecorator.cs
  5. 28
      ICSharpCode.Decompiler/CSharp/OutputVisitor/TextWriterTokenWriter.cs
  6. 50
      ICSharpCode.Decompiler/CSharp/Syntax/Expressions/PrimitiveExpression.cs
  7. 12
      ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
  8. 11
      ICSharpCode.Decompiler/Output/TextTokenWriter.cs
  9. 4
      ILSpy/Languages/CSharpHighlightingTokenWriter.cs
  10. 6
      ILSpy/Languages/CSharpLexer.cs

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

@ -992,7 +992,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -992,7 +992,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
public virtual void VisitPrimitiveExpression(PrimitiveExpression primitiveExpression)
{
StartNode(primitiveExpression);
writer.WritePrimitiveValue(primitiveExpression.Value, primitiveExpression.UnsafeLiteralValue);
writer.WritePrimitiveValue(primitiveExpression.Value, primitiveExpression.Format);
isAfterSpace = false;
EndNode(primitiveExpression);
}
@ -1019,7 +1019,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -1019,7 +1019,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
interpolation.Expression.AcceptVisitor(this);
if (interpolation.Suffix != null) {
writer.WriteToken(Roles.Colon, ":");
writer.WritePrimitiveValue("", interpolation.Suffix);
writer.WriteInterpolatedText(interpolation.Suffix);
}
writer.WriteToken(Interpolation.RBrace, "}");
@ -1029,7 +1029,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -1029,7 +1029,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
public virtual void VisitInterpolatedStringText(InterpolatedStringText interpolatedStringText)
{
StartNode(interpolatedStringText);
writer.WritePrimitiveValue("", TextWriterTokenWriter.ConvertString(interpolatedStringText.Text));
writer.WriteInterpolatedText(interpolatedStringText.Text);
EndNode(interpolatedStringText);
}
#endregion

16
ICSharpCode.Decompiler/CSharp/OutputVisitor/ITokenWriter.cs

@ -45,10 +45,15 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -45,10 +45,15 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
/// <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();
@ -123,9 +128,9 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -123,9 +128,9 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
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)
@ -133,6 +138,11 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -133,6 +138,11 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
decoratedWriter.WritePrimitiveType(type);
}
public override void WriteInterpolatedText(string text)
{
decoratedWriter.WriteInterpolatedText(text);
}
public override void Space()
{
decoratedWriter.Space();

6
ICSharpCode.Decompiler/CSharp/OutputVisitor/InsertMissingTokensDecorator.cs

@ -116,11 +116,11 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -116,11 +116,11 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
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);
}
@ -128,7 +128,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -128,7 +128,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
((NullReferenceExpression)node).SetStartLocation(startLocation);
}
}
public override void WritePrimitiveType(string type)
{
PrimitiveType node = nodes.Peek().LastOrDefault() as PrimitiveType;

4
ICSharpCode.Decompiler/CSharp/OutputVisitor/InsertRequiredSpacesDecorator.cs

@ -129,12 +129,12 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -129,12 +129,12 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
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) {

28
ICSharpCode.Decompiler/CSharp/OutputVisitor/TextWriterTokenWriter.cs

@ -224,16 +224,9 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -224,16 +224,9 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
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");
@ -346,12 +339,12 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -346,12 +339,12 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
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");
}
@ -369,6 +362,11 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -369,6 +362,11 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
}
}
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.

50
ICSharpCode.Decompiler/CSharp/Syntax/Expressions/PrimitiveExpression.cs

@ -29,6 +29,20 @@ using ICSharpCode.Decompiler.Util; @@ -29,6 +29,20 @@ using ICSharpCode.Decompiler.Util;
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>
@ -63,26 +77,16 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -63,26 +77,16 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
}
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)
@ -91,24 +95,24 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -91,24 +95,24 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
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)

12
ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs

@ -784,17 +784,11 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -784,17 +784,11 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
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)) {

11
ICSharpCode.Decompiler/Output/TextTokenWriter.cs

@ -322,11 +322,16 @@ namespace ICSharpCode.Decompiler @@ -322,11 +322,16 @@ namespace ICSharpCode.Decompiler
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) {

4
ILSpy/Languages/CSharpHighlightingTokenWriter.cs

@ -392,7 +392,7 @@ namespace ICSharpCode.ILSpy @@ -392,7 +392,7 @@ namespace ICSharpCode.ILSpy
}
}
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) {
@ -404,7 +404,7 @@ namespace ICSharpCode.ILSpy @@ -404,7 +404,7 @@ namespace ICSharpCode.ILSpy
if (color != null) {
BeginSpan(color);
}
base.WritePrimitiveValue(value, literalValue);
base.WritePrimitiveValue(value, format);
if (color != null) {
EndSpan();
}

6
ILSpy/Languages/CSharpLexer.cs

@ -9,7 +9,7 @@ using System.Text; @@ -9,7 +9,7 @@ using System.Text;
namespace ICSharpCode.ILSpy
{
public class LATextReader : TextReader
class LATextReader : TextReader
{
List<int> buffer;
TextReader reader;
@ -52,7 +52,7 @@ namespace ICSharpCode.ILSpy @@ -52,7 +52,7 @@ namespace ICSharpCode.ILSpy
}
}
public enum LiteralFormat : byte
enum LiteralFormat : byte
{
None,
DecimalNumber,
@ -64,7 +64,7 @@ namespace ICSharpCode.ILSpy @@ -64,7 +64,7 @@ namespace ICSharpCode.ILSpy
DateTimeLiteral
}
public class Literal
class Literal
{
internal readonly LiteralFormat literalFormat;
internal readonly object literalValue;

Loading…
Cancel
Save