From cb88706b7ccfa6e53b6f8c162f7d1693074449b3 Mon Sep 17 00:00:00 2001 From: Atsushi Eno Date: Mon, 30 Jan 2017 16:47:50 +0900 Subject: [PATCH] [generator] less aggressive obfuscation marking. This is a fixup for c51469e, as well as bugfix for: https://bugzilla.xamarin.com/show_bug.cgi?id=51337 What's happening behind bug #51337 was this: BINDINGSGENERATOR: warning BG8800: Unknown parameter type org.osmdroid.ResourceProxy.bitmap in method GetBitmap in managed type OsmDroid.DefaultResourceProxyImpl. This was, because, "bitmap" is all lowercased and was marked as obfuscated (because, WHY NAME A CLASS ALL IN LOWERCASE!?). Such classes should not exist, or should be marked as "obfuscated='false'". However what bug #51337 implies is that people are not going to make this additional markup for generator improvements. What this generator change does is then - a hack. A hack to mark "classes with very short names" as obfuscated, instead of "all lowercase or number". As commented on c51469e, there isn't good way to check API element siblings (it can check sibling names every time at all expensive calculation). So we just count the sibling nodes and if name length is short enough to fit within the number of classes, we mark as obfucated. As some post-first-commit thought, the name check is done only for very short names i.e. only those within 3 letters. Also, the new proguard in Gradle task seems to obfuscates the names as "zzXXXXX" . They should be marked as obfuscated too. --- tools/generator/GenBaseSupport.cs | 13 +++++++++++-- tools/generator/Tests-Core/api-cp.xml | 8 ++++++++ .../expected.cp/GeneratedFiles.projitems | 2 ++ .../Java.Interop.__TypeRegistrations.cs | 14 ++++++++++++++ .../Tests-Core/expected.cp/Java.Lang.String.cs | 14 ++++++++++++++ .../expected.cp/Xamarin.Test.Invalidnames.In.cs | 14 ++++++++++++++ 6 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 tools/generator/Tests-Core/expected.cp/Java.Lang.String.cs create mode 100644 tools/generator/Tests-Core/expected.cp/Xamarin.Test.Invalidnames.In.cs diff --git a/tools/generator/GenBaseSupport.cs b/tools/generator/GenBaseSupport.cs index ed91ebc12..481d9f978 100644 --- a/tools/generator/GenBaseSupport.cs +++ b/tools/generator/GenBaseSupport.cs @@ -204,7 +204,7 @@ public XmlGenBaseSupport (XmlElement pkg, XmlElement elem) full_name = String.Format ("{0}.{1}{2}", ns, idx > 0 ? StringRocks.TypeToPascalCase (java_name.Substring (0, idx + 1)) : String.Empty, name); } - obfuscated = IsObfuscatedName (java_name) && elem.XGetAttribute ("obfuscated") != "false"; + obfuscated = IsObfuscatedName (pkg.ChildNodes.Count, java_name) && elem.XGetAttribute ("obfuscated") != "false"; } public override bool IsAcw { @@ -302,12 +302,21 @@ public override bool ValidateNamespace () return true; } - bool IsObfuscatedName (String name) + bool IsObfuscatedName (int threshold, string name) { if (name.StartsWith ("R.", StringComparison.Ordinal)) return false; int idx = name.LastIndexOf ('.'); string last = idx < 0 ? name : name.Substring (idx + 1); + // probably new proguard within Gradle tasks, used in recent GooglePlayServices in 2016 or later. + if (last.StartsWith ("zz", StringComparison.Ordinal)) + return true; + // do not expect any name with more than 3 letters is an 'obfuscated' one. + if (last.Length > 3) + return false; + // Only short ones ('a', 'b', 'c' ... 'aa', 'ab', ... 'zzz') are the targets. + if (!(last.Length == 3 && threshold > 26*26 || last.Length == 2 && threshold > 26 || last.Length == 1)) + return false; if (last.Any (c => (c < 'a' || 'z' < c) && (c < '0' || '9' < c))) return false; return true; diff --git a/tools/generator/Tests-Core/api-cp.xml b/tools/generator/Tests-Core/api-cp.xml index c20b00f98..41015a890 100644 --- a/tools/generator/Tests-Core/api-cp.xml +++ b/tools/generator/Tests-Core/api-cp.xml @@ -3,6 +3,8 @@ + + @@ -13,6 +15,12 @@ + + + + + + diff --git a/tools/generator/Tests-Core/expected.cp/GeneratedFiles.projitems b/tools/generator/Tests-Core/expected.cp/GeneratedFiles.projitems index 864450984..7e5723e9e 100644 --- a/tools/generator/Tests-Core/expected.cp/GeneratedFiles.projitems +++ b/tools/generator/Tests-Core/expected.cp/GeneratedFiles.projitems @@ -7,6 +7,8 @@ + + diff --git a/tools/generator/Tests-Core/expected.cp/Java.Interop.__TypeRegistrations.cs b/tools/generator/Tests-Core/expected.cp/Java.Interop.__TypeRegistrations.cs index 6008ae6da..210cb8258 100644 --- a/tools/generator/Tests-Core/expected.cp/Java.Interop.__TypeRegistrations.cs +++ b/tools/generator/Tests-Core/expected.cp/Java.Interop.__TypeRegistrations.cs @@ -14,8 +14,10 @@ public static void RegisterPackages () #endif // def MONODROID_TIMING Java.Interop.TypeManager.RegisterPackages ( new string[]{ + "xamarin/test/invalidnames", }, new Converter[]{ + lookup_xamarin_test_invalidnames_package, }); #if MONODROID_TIMING var end = DateTime.Now; @@ -30,5 +32,17 @@ static Type Lookup (string[] mappings, string javaType) return null; return Type.GetType (managedType); } + + static string[] package_xamarin_test_invalidnames_mappings; + static Type lookup_xamarin_test_invalidnames_package (string klass) + { + if (package_xamarin_test_invalidnames_mappings == null) { + package_xamarin_test_invalidnames_mappings = new string[]{ + "xamarin/test/invalidnames/in:Xamarin.Test.Invalidnames.In", + }; + } + + return Lookup (package_xamarin_test_invalidnames_mappings, klass); + } } } diff --git a/tools/generator/Tests-Core/expected.cp/Java.Lang.String.cs b/tools/generator/Tests-Core/expected.cp/Java.Lang.String.cs new file mode 100644 index 000000000..88051e79a --- /dev/null +++ b/tools/generator/Tests-Core/expected.cp/Java.Lang.String.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using Android.Runtime; + +namespace Java.Lang { + + // Metadata.xml XPath class reference: path="/api/package[@name='java.lang']/class[@name='String']" + [global::Android.Runtime.Register ("java/lang/String", DoNotGenerateAcw=true)] + public partial class String : Java.Lang.Object { + + protected String (IntPtr javaReference, JniHandleOwnership transfer) : base (javaReference, transfer) {} + + } +} diff --git a/tools/generator/Tests-Core/expected.cp/Xamarin.Test.Invalidnames.In.cs b/tools/generator/Tests-Core/expected.cp/Xamarin.Test.Invalidnames.In.cs new file mode 100644 index 000000000..1de9800a2 --- /dev/null +++ b/tools/generator/Tests-Core/expected.cp/Xamarin.Test.Invalidnames.In.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using Android.Runtime; + +namespace Xamarin.Test.Invalidnames { + + // Metadata.xml XPath class reference: path="/api/package[@name='xamarin.test.invalidnames']/class[@name='in']" + [global::Android.Runtime.Register ("xamarin/test/invalidnames/in", DoNotGenerateAcw=true)] + public partial class In : Java.Lang.Object { + + protected In (IntPtr javaReference, JniHandleOwnership transfer) : base (javaReference, transfer) {} + + } +}