From 5e1a86b57d08ceacdff43760d7616cae1d6789df Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Mon, 13 Mar 2017 12:32:36 -0400 Subject: [PATCH] [class-parse] Use InvariantCulture to format floating-point values Fixes: https://github.com/xamarin/java.interop/issues/129 The System.Double/Single ["Round-trip Format Specifier"][0] varies by culture, so cultures which use `,` as the decimal separator character use `,` within e.g. `42.0.ToString("r")`. For example, the Java declaration: class E { public static final double V = 42.5; } on french systems would result in `class-parse` emitting: which, when run through `generator`, emits: public const double V = (double) 42,5; ...which promptly fails with a CS1001. Oops. Fix our `double` and `float` serialization in `XmlClassDeclarationBuilder` so that `CultureInfo.InvariantCulture` is used, which ensures that `.` is the decimal separator character, ensuring that `class-parse` and `generator` output is as expected. [0]: https://msdn.microsoft.com/en-us/library/dwhawy9k(v=vs.110).aspx#RFormatString --- .../XmlClassDeclarationBuilder.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Xamarin.Android.Tools.Bytecode/XmlClassDeclarationBuilder.cs b/src/Xamarin.Android.Tools.Bytecode/XmlClassDeclarationBuilder.cs index f69be9e5b..6dd0d653e 100644 --- a/src/Xamarin.Android.Tools.Bytecode/XmlClassDeclarationBuilder.cs +++ b/src/Xamarin.Android.Tools.Bytecode/XmlClassDeclarationBuilder.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Globalization; using System.Linq; using System.Xml.Linq; using System.Text; @@ -443,9 +444,19 @@ static XAttribute GetValue (FieldInfo field) else if (Double.IsPositiveInfinity (doubleItem.Value)) value = "(1.0 / 0.0)"; else - value = doubleItem.Value.ToString ("R"); + value = doubleItem.Value.ToString ("R", CultureInfo.InvariantCulture); + break; + case ConstantPoolItemType.Float: + var floatItem = (ConstantPoolFloatItem) constant; + if (Double.IsNaN (floatItem.Value)) + value = "(0.0f / 0.0f)"; + else if (Double.IsNegativeInfinity (floatItem.Value)) + value = "(-1.0f / 0.0f)"; + else if (Double.IsPositiveInfinity (floatItem.Value)) + value = "(1.0f / 0.0f)"; + else + value = floatItem.Value.ToString ("R", CultureInfo.InvariantCulture); break; - case ConstantPoolItemType.Float: value = ((ConstantPoolFloatItem)constant).Value.ToString ("R"); break; case ConstantPoolItemType.Long: value = ((ConstantPoolLongItem) constant).Value.ToString (); break; case ConstantPoolItemType.Integer: if (field.Descriptor == "Z")