Browse Source

Fix output of float/double literals that are infinite or NaN.

newNRvisualizers
Daniel Grunwald 15 years ago
parent
commit
0c9dec1b9a
  1. 97
      ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs

97
ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs

@ -784,52 +784,75 @@ namespace ICSharpCode.NRefactory.CSharp
public object VisitPrimitiveExpression(PrimitiveExpression primitiveExpression, object data) public object VisitPrimitiveExpression(PrimitiveExpression primitiveExpression, object data)
{ {
StartNode(primitiveExpression); StartNode(primitiveExpression);
formatter.WriteToken(ToCSharpString(primitiveExpression)); WritePrimitiveValue(primitiveExpression.Value);
lastWritten = LastWritten.Other;
return EndNode(primitiveExpression); return EndNode(primitiveExpression);
} }
internal static string ToCSharpString(PrimitiveExpression primitiveExpression) void WritePrimitiveValue(object val)
{ {
if (primitiveExpression.Value == null) { if (val == null) {
return "null"; // usually NullReferenceExpression should be used for this, but we'll handle it anyways
WriteKeyword("null");
return;
} }
object val = primitiveExpression.Value;
if (val is bool) { if (val is bool) {
if ((bool)val) { if ((bool)val) {
return "true"; WriteKeyword("true");
} else { } else {
return "false"; WriteKeyword("false");
} }
return;
} }
if (val is string) { if (val is string) {
return "\"" + ConvertString(val.ToString()) + "\""; formatter.WriteToken("\"" + ConvertString(val.ToString()) + "\"");
} lastWritten = LastWritten.Other;
} else if (val is char) {
if (val is char) { formatter.WriteToken("'" + ConvertCharLiteral((char)val) + "'");
return "'" + ConvertCharLiteral((char)val) + "'"; lastWritten = LastWritten.Other;
} } else if (val is decimal) {
formatter.WriteToken(((decimal)val).ToString(NumberFormatInfo.InvariantInfo) + "m");
if (val is decimal) { lastWritten = LastWritten.Other;
return ((decimal)val).ToString(NumberFormatInfo.InvariantInfo) + "m"; } else if (val is float) {
} float f = (float)val;
if (float.IsInfinity(f) || float.IsNaN(f)) {
if (val is float) { // Strictly speaking, these aren't PrimitiveExpressions;
return ((float)val).ToString(NumberFormatInfo.InvariantInfo) + "f"; // but we still support writing these to make life easier for code generators.
} WriteKeyword("float");
WriteToken(".", AstNode.Roles.Dot);
if (val is double) { if (float.IsPositiveInfinity(f))
string text = ((double)val).ToString(NumberFormatInfo.InvariantInfo); WriteIdentifier("PositiveInfinity");
if (text.IndexOf('.') < 0 && text.IndexOf('E') < 0) else if (float.IsNegativeInfinity(f))
return text + ".0"; WriteIdentifier("NegativeInfinity");
else else
return text; WriteIdentifier("NaN");
} return;
}
if (val is IFormattable) { formatter.WriteToken(f.ToString("R", NumberFormatInfo.InvariantInfo) + "f");
lastWritten = LastWritten.Other;
} else if (val is double) {
double f = (double)val;
if (double.IsInfinity(f) || double.IsNaN(f)) {
// Strictly speaking, these aren't PrimitiveExpressions;
// but we still support writing these to make life easier for code generators.
WriteKeyword("double");
WriteToken(".", AstNode.Roles.Dot);
if (double.IsPositiveInfinity(f))
WriteIdentifier("PositiveInfinity");
else if (double.IsNegativeInfinity(f))
WriteIdentifier("NegativeInfinity");
else
WriteIdentifier("NaN");
return;
}
string number = f.ToString("R", NumberFormatInfo.InvariantInfo);
if (number.IndexOf('.') < 0 && number.IndexOf('E') < 0)
number += ".0";
formatter.WriteToken(number);
// needs space if identifier follows number; this avoids mistaking the following identifier as type suffix
lastWritten = LastWritten.KeywordOrIdentifier;
} else if (val is IFormattable) {
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
// if (primitiveExpression.LiteralFormat == LiteralFormat.HexadecimalNumber) { // if (primitiveExpression.LiteralFormat == LiteralFormat.HexadecimalNumber) {
// b.Append("0x"); // b.Append("0x");
@ -843,13 +866,15 @@ namespace ICSharpCode.NRefactory.CSharp
if (val is long || val is ulong) { if (val is long || val is ulong) {
b.Append("L"); b.Append("L");
} }
return b.ToString(); formatter.WriteToken(b.ToString());
// needs space if identifier follows number; this avoids mistaking the following identifier as type suffix
lastWritten = LastWritten.KeywordOrIdentifier;
} else { } else {
return val.ToString(); formatter.WriteToken(val.ToString());
lastWritten = LastWritten.Other;
} }
} }
static string ConvertCharLiteral(char ch) static string ConvertCharLiteral(char ch)
{ {
if (ch == '\'') return "\\'"; if (ch == '\'') return "\\'";

Loading…
Cancel
Save