diff --git a/src/Java.Interop.Tools.JavaSource/Java.Interop.Tools.JavaSource/JavaStubParser.cs b/src/Java.Interop.Tools.JavaSource/Java.Interop.Tools.JavaSource/JavaStubParser.cs index 5defff6a5..00182bfb1 100644 --- a/src/Java.Interop.Tools.JavaSource/Java.Interop.Tools.JavaSource/JavaStubParser.cs +++ b/src/Java.Interop.Tools.JavaSource/Java.Interop.Tools.JavaSource/JavaStubParser.cs @@ -315,7 +315,12 @@ public JavaStubGrammar () identifier.AstConfig.NodeCreator = (ctx, node) => node.AstNode = node.Token.ValueString; compile_unit.AstConfig.NodeCreator = (ctx, node) => { ProcessChildren (ctx, node); - node.AstNode = new JavaPackage (null) { Name = (string)node.ChildNodes [0].AstNode, Types = ((IEnumerable)node.ChildNodes [2].AstNode).ToList () }; + var pkg = new JavaPackage (null) { Name = (string) node.ChildNodes [0].AstNode }; + + foreach (var t in (IEnumerable) node.ChildNodes [2].AstNode) + pkg.AddType (t); + + node.AstNode = pkg; }; opt_package_decl.AstConfig.NodeCreator = SelectSingleChild; package_decl.AstConfig.NodeCreator = SelectChildValueAt (1); @@ -637,9 +642,13 @@ public JavaStubParser () void FlattenNestedTypes (JavaPackage package) { var results = new List (); - foreach (var t in package.Types) + foreach (var t in package.AllTypes) Flatten (results, t); - package.Types = results.ToList (); + + package.ClearTypes (); + + foreach (var t in results) + package.AddType (t); void Flatten (List list, JavaType t) { diff --git a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApi.XmlModel.cs b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApi.XmlModel.cs index e93e64c50..d19d8174e 100644 --- a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApi.XmlModel.cs +++ b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApi.XmlModel.cs @@ -10,29 +10,77 @@ public partial class JavaApi { public JavaApi () { - Packages = new List (); + Packages = new Dictionary (); } public string? ExtendedApiSource { get; set; } public string? Platform { get; set; } - public IList Packages { get; set; } + public IDictionary Packages { get; } + + public ICollection AllPackages => Packages.Values; } public partial class JavaPackage { + private Dictionary> types = new Dictionary> (); + public JavaPackage (JavaApi? parent) { Parent = parent; - - Types = new List (); } public JavaApi? Parent { get; private set; } public string? Name { get; set; } public string? JniName { get; set; } - public IList Types { get; set; } - + + // Yes, there can be multiple types with the same *Java* name. + // For example: + // - MyInterface + // - MyInterfaceConsts + // It's debatable whether we handle this "properly", as most callers just + // do `First ()`, but it's been working for years so I'm not changing it. + // Exposes an IReadOnlyDictionary so caller cannot bypass our AddType/RemoveType code. + public IReadOnlyDictionary> Types => types; + + // Use this for a flat list of *all* types + public IEnumerable AllTypes => Types.Values.SelectMany (v => v); + + public void AddType (JavaType type) + { + // If this is a duplicate key, add it to existing list + if (Types.TryGetValue (type.Name!, out var list)) { + list.Add (type); + return; + } + + // Add to a new list + var new_list = new List (); + new_list.Add (type); + + types.Add (type.Name!, new_list); + } + + public void RemoveType (JavaType type) + { + if (!Types.TryGetValue (type.Name!, out var list)) + return; + + // Remove 1 type from list if it contains multiple types + if (list.Count > 1) { + list.Remove (type); + return; + } + + // Remove the whole dictionary entry + types.Remove (type.Name!); + } + + public void ClearTypes () + { + types.Clear (); + } + // Content of this value is not stable. public override string ToString () { @@ -123,14 +171,14 @@ static ManagedType () dummy_system_package = new JavaPackage (null) { Name = "System" }; system_object = new ManagedType (dummy_system_package) { Name = "Object" }; system_exception = new ManagedType (dummy_system_package) { Name = "Exception" }; - dummy_system_package.Types.Add (system_object); - dummy_system_package.Types.Add (system_exception); + dummy_system_package.AddType (system_object); + dummy_system_package.AddType (system_exception); dummy_system_io_package = new JavaPackage (null) { Name = "System.IO" }; system_io_stream = new ManagedType (dummy_system_io_package) { Name = "Stream" }; - dummy_system_io_package.Types.Add (system_io_stream); + dummy_system_io_package.AddType (system_io_stream); dummy_system_xml_package = new JavaPackage (null) { Name = "System.Xml" }; system_xml_xmlreader = new ManagedType (dummy_system_xml_package) { Name = "XmlReader" }; - dummy_system_io_package.Types.Add (system_xml_xmlreader); + dummy_system_io_package.AddType (system_xml_xmlreader); } public static IEnumerable DummyManagedPackages { diff --git a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiDefectFinderExtensions.cs b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiDefectFinderExtensions.cs index 949a41c83..0136d86a4 100644 --- a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiDefectFinderExtensions.cs +++ b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiDefectFinderExtensions.cs @@ -7,7 +7,7 @@ public static class JavaApiDefectFinderExtensions { public static void FindDefects (this JavaApi api) { - foreach (var type in api.Packages.SelectMany (p => p.Types).Where (t => !t.IsReferenceOnly)) + foreach (var type in api.AllPackages.SelectMany (p => p.AllTypes).Where (t => !t.IsReferenceOnly)) type.FindDefects (); } diff --git a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiGenericInheritanceMapperExtensions.cs b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiGenericInheritanceMapperExtensions.cs index 7ef0768ba..73b93e16f 100644 --- a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiGenericInheritanceMapperExtensions.cs +++ b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiGenericInheritanceMapperExtensions.cs @@ -8,7 +8,7 @@ public static class JavaApiGenericInheritanceMapperExtensions { public static void CreateGenericInheritanceMapping (this JavaApi api) { - foreach (var kls in api.Packages.SelectMany (p => p.Types).OfType ()) + foreach (var kls in api.AllPackages.SelectMany (p => p.AllTypes).OfType ()) kls.PrepareGenericInheritanceMapping (); } diff --git a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiNonBindableStripper.cs b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiNonBindableStripper.cs index c6d289795..0caf70953 100644 --- a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiNonBindableStripper.cs +++ b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiNonBindableStripper.cs @@ -9,7 +9,7 @@ public static class JavaApiNonBindableStripper public static void StripNonBindables (this JavaApi api) { var invalids = new List (); - foreach (var member in api.Packages.SelectMany (p => p.Types) + foreach (var member in api.AllPackages.SelectMany (p => p.AllTypes) .SelectMany (t => t.Members).Where (m => m.Name != null && m.Name.Contains ('$'))) invalids.Add (member); foreach (var invalid in invalids) diff --git a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiOverrideMarkerExtensions.cs b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiOverrideMarkerExtensions.cs index c626a732d..3e1aa50a1 100644 --- a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiOverrideMarkerExtensions.cs +++ b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiOverrideMarkerExtensions.cs @@ -14,7 +14,7 @@ public static void MarkOverrides (this JavaApi api) public static void MarkOverrides (this JavaApi api, HashSet doneList) { - foreach (var kls in api.Packages.SelectMany (p => p.Types).OfType ()) + foreach (var kls in api.AllPackages.SelectMany (p => p.AllTypes).OfType ()) kls.MarkOverrides (doneList); } diff --git a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiTypeResolverExtensions.cs b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiTypeResolverExtensions.cs index 15c84994c..36fa3f624 100644 --- a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiTypeResolverExtensions.cs +++ b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiTypeResolverExtensions.cs @@ -39,13 +39,31 @@ static JavaTypeReference JavaTypeNameToReference (this JavaApi api, JavaTypeName public static JavaType FindNonGenericType (this JavaApi api, string? name) { - var ret = FindPackages (api, name ?? "") - .SelectMany (p => p.Types) - .FirstOrDefault (t => name == (t.Parent?.Name != null ? t.Parent.Name + "." : "") + t.Name); - if (ret == null) - ret = ManagedType.DummyManagedPackages - .SelectMany (p => p.Types) - .FirstOrDefault (t => t.FullName == name); + // Given a type name like 'android.graphics.BitmapFactory.Options' + // We're going to search for: + // - Pkg: android.graphics.BitmapFactory Type: Options + // - Pkg: android.graphics Type: BitmapFactory.Options + // - Pkg: android Type: graphics.BitmapFactory.Options + // etc. We will short-circuit as soon as we find a match + var index = name?.LastIndexOf ('.') ?? -1; + + while (index > 0) { + var ns = name!.Substring (0, index); + var type_name = name.Substring (index + 1); + + if (api.Packages.TryGetValue (ns, out var pkg)) { + if (pkg.Types.TryGetValue (type_name, out var type)) + return type.First (); + } + + index = name.LastIndexOf ('.', index - 1); + } + + // See if it's purely a C# type + var ret = ManagedType.DummyManagedPackages + .SelectMany (p => p.AllTypes) + .FirstOrDefault (t => t.FullName == name); + if (ret == null) { // We moved this type to "mono.android.app.IntentService" which makes this // type resolution fail if a user tries to reference it in Java. @@ -58,43 +76,26 @@ public static JavaType FindNonGenericType (this JavaApi api, string? name) return ret; } - static IEnumerable FindPackages (JavaApi api, string name) - { - // Given a type name like "java.lang.Object", return packages that could - // possibly contain the type so we don't search all packages, ie: - // - java.lang - // - java - var package_names = new List (); - int index; - - while ((index = name.LastIndexOf ('.')) >= 0) { - name = name.Substring (0, index); - package_names.Add (name); - } - - return api.Packages.Where (p => package_names.Contains (p.Name, StringComparer.Ordinal)).ToList (); - } - public static void Resolve (this JavaApi api) { while (true) { bool errors = false; - foreach (var t in api.Packages.SelectMany (p => p.Types).OfType ().ToArray ()) + foreach (var t in api.AllPackages.SelectMany (p => p.AllTypes).OfType ().ToArray ()) try { t.Resolve (); } catch (JavaTypeResolutionException ex) { Log.LogError ("Error while processing type '{0}': {1}", t, ex.Message); errors = true; - t.Parent?.Types.Remove (t); + t.Parent?.RemoveType (t); } - foreach (var t in api.Packages.SelectMany (p => p.Types).OfType ().ToArray ()) + foreach (var t in api.AllPackages.SelectMany (p => p.AllTypes).OfType ().ToArray ()) try { t.Resolve (); } catch (JavaTypeResolutionException ex) { Log.LogError ("Error while processing type '{0}': {1}", t, ex.Message); errors = true; - t.Parent?.Types.Remove (t); + t.Parent?.RemoveType (t); } if (!errors) break; diff --git a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiXmlGeneratorExtensions.cs b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiXmlGeneratorExtensions.cs index a76352405..53c85325f 100644 --- a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiXmlGeneratorExtensions.cs +++ b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiXmlGeneratorExtensions.cs @@ -24,15 +24,15 @@ public static void Save (this JavaApi api, XmlWriter writer) if (api.Platform != null) writer.WriteAttributeString ("platform", api.Platform); - foreach (var pkg in api.Packages) { - if (!pkg.Types.Any (t => !t.IsReferenceOnly)) + foreach (var pkg in api.AllPackages) { + if (!pkg.AllTypes.Any (t => !t.IsReferenceOnly)) continue; writer.WriteStartElement ("package"); writer.WriteAttributeString ("name", pkg.Name); if (!string.IsNullOrEmpty (pkg.JniName)) { writer.WriteAttributeString ("jni-name", pkg.JniName); } - foreach (var type in pkg.Types) { + foreach (var type in pkg.AllTypes) { if (type.IsReferenceOnly) continue; // skip reference only types if (type is JavaClass) diff --git a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiXmlLoaderExtensions.cs b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiXmlLoaderExtensions.cs index 218488f3c..b08ad4374 100644 --- a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiXmlLoaderExtensions.cs +++ b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiXmlLoaderExtensions.cs @@ -32,11 +32,14 @@ public static void Load (this JavaApi api, XmlReader reader, bool isReferenceOnl break; // if (reader.NodeType != XmlNodeType.Element || reader.LocalName != "package") throw XmlUtil.UnexpectedElementOrContent ("api", reader, "package"); - var pkg = api.Packages.FirstOrDefault (p => p.Name == reader.GetAttribute ("name")); - if (pkg == null) { + + var name = reader.GetAttribute ("name"); + + if (!api.Packages.TryGetValue (name, out var pkg)) { pkg = new JavaPackage (api); - api.Packages.Add (pkg); + api.Packages.Add (name, pkg); } + pkg.Load (reader, isReferenceOnly); } while (true); @@ -67,11 +70,11 @@ public static void Load (this JavaPackage package, XmlReader reader, bool isRefe if (reader.LocalName == "class") { var kls = new JavaClass (package) { IsReferenceOnly = isReferenceOnly }; kls.Load (reader); - package.Types.Add (kls); + package.AddType (kls); } else if (reader.LocalName == "interface") { var iface = new JavaInterface (package) { IsReferenceOnly = isReferenceOnly }; iface.Load (reader); - package.Types.Add (iface); + package.AddType (iface); } else throw XmlUtil.UnexpectedElementOrContent ("package", reader, "class", "interface"); } while (true); diff --git a/tests/Java.Interop.Tools.JavaSource-Tests/JavaStubParserTests.cs b/tests/Java.Interop.Tools.JavaSource-Tests/JavaStubParserTests.cs index 6e1cc78c2..92ea2b779 100644 --- a/tests/Java.Interop.Tools.JavaSource-Tests/JavaStubParserTests.cs +++ b/tests/Java.Interop.Tools.JavaSource-Tests/JavaStubParserTests.cs @@ -35,7 +35,7 @@ public static void m (String text) { Assert.AreEqual (null, package.Name); Assert.AreEqual (1, package.Types.Count); - var Example_Type = package.Types [0]; + var Example_Type = package.AllTypes.First (); Assert.AreEqual ("Example", Example_Type.FullName); Assert.AreEqual (1, Example_Type.Members.Count); diff --git a/tests/Xamarin.Android.Tools.ApiXmlAdjuster-Tests/JavaApiTest.cs b/tests/Xamarin.Android.Tools.ApiXmlAdjuster-Tests/JavaApiTest.cs index ff56486d2..727bffe62 100644 --- a/tests/Xamarin.Android.Tools.ApiXmlAdjuster-Tests/JavaApiTest.cs +++ b/tests/Xamarin.Android.Tools.ApiXmlAdjuster-Tests/JavaApiTest.cs @@ -19,9 +19,9 @@ public void SetupFixture () [Test] public void TestToString () { - var pkg = api.Packages.First (p => p.Name == "android.database"); + var pkg = api.AllPackages.First (p => p.Name == "android.database"); Assert.AreEqual ("[Package] android.database", pkg.ToString ()); - var kls = pkg.Types.First (t => t.FullName == "android.database.ContentObservable"); + var kls = pkg.AllTypes.First (t => t.FullName == "android.database.ContentObservable"); Assert.AreEqual ("[Class] android.database.ContentObservable", kls.ToString ()); } diff --git a/tests/Xamarin.Android.Tools.ApiXmlAdjuster-Tests/OverrideMarkerTest.cs b/tests/Xamarin.Android.Tools.ApiXmlAdjuster-Tests/OverrideMarkerTest.cs index 0605e254b..085d0ddbe 100644 --- a/tests/Xamarin.Android.Tools.ApiXmlAdjuster-Tests/OverrideMarkerTest.cs +++ b/tests/Xamarin.Android.Tools.ApiXmlAdjuster-Tests/OverrideMarkerTest.cs @@ -53,7 +53,7 @@ public void AncestralOverrides () xapi.Resolve (); xapi.CreateGenericInheritanceMapping (); xapi.MarkOverrides (); - var t = xapi.Packages.First (_ => _.Name == "XXX").Types.First (_ => _.Name == "SherlockExpandableListActivity"); + var t = xapi.AllPackages.First (_ => _.Name == "XXX").AllTypes.First (_ => _.Name == "SherlockExpandableListActivity"); var m = t.Members.OfType ().First (_ => _.Name == "addContentView"); Assert.IsNotNull (m.BaseMethod, "base method not found"); } @@ -88,7 +88,7 @@ public void GenericConstructors () xapi = new JavaApi (); using (var xr = XmlReader.Create (new StringReader (sw.ToString ()))) xapi.Load (xr, true); - var t = xapi.Packages.First (_ => _.Name == "XXX").Types.First (_ => _.Name == "GenericConstructors"); + var t = xapi.AllPackages.First (_ => _.Name == "XXX").AllTypes.First (_ => _.Name == "GenericConstructors"); var m = t.Members.OfType ().FirstOrDefault (); Assert.IsNotNull (m.TypeParameters, "constructor not found"); } diff --git a/tests/Xamarin.Android.Tools.ApiXmlAdjuster-Tests/TypeResolverTest.cs b/tests/Xamarin.Android.Tools.ApiXmlAdjuster-Tests/TypeResolverTest.cs index 8e07226db..479d29c9e 100644 --- a/tests/Xamarin.Android.Tools.ApiXmlAdjuster-Tests/TypeResolverTest.cs +++ b/tests/Xamarin.Android.Tools.ApiXmlAdjuster-Tests/TypeResolverTest.cs @@ -76,20 +76,20 @@ public void IntentServiceHack () var api = JavaApiTestHelper.GetLoadedApi (); // Create "mono.android.app" package - var mono_android_app = new JavaPackage (api) { Name = "mono.android.app", JniName = "mono/android/app", Types = new List () }; - api.Packages.Add (mono_android_app); + var mono_android_app = new JavaPackage (api) { Name = "mono.android.app", JniName = "mono/android/app" }; + api.Packages.Add (mono_android_app.Name, mono_android_app); // Remove "android.app.IntentService" type - var android_app = api.Packages.Single (p => p.Name == "android.app"); - var intent_service = android_app.Types.Single (t => t.Name == "IntentService"); - android_app.Types.Remove (intent_service); + var android_app = api.AllPackages.Single (p => p.Name == "android.app"); + var intent_service = android_app.AllTypes.Single (t => t.Name == "IntentService"); + android_app.RemoveType (intent_service); // Create new "mono.android.app.IntentService" type var new_intent_service = new JavaClass (mono_android_app) { Name = intent_service.Name, }; - mono_android_app.Types.Add (new_intent_service); + mono_android_app.AddType (new_intent_service); api.Resolve (); diff --git a/tools/generator/Extensions/JavaApiDllLoaderExtensions.cs b/tools/generator/Extensions/JavaApiDllLoaderExtensions.cs index b735320fd..58e3b7cbf 100644 --- a/tools/generator/Extensions/JavaApiDllLoaderExtensions.cs +++ b/tools/generator/Extensions/JavaApiDllLoaderExtensions.cs @@ -12,19 +12,21 @@ public static void LoadReferences (this JavaApi api, CodeGenerationOptions opt, { JavaPackage pkg = null; foreach (var gen in gens.Where (_ => _.IsAcw)) { - pkg = api.Packages.FirstOrDefault (_ => _.Name == gen.PackageName); - if (pkg == null) { + if (!api.Packages.TryGetValue (gen.PackageName, out pkg)) { pkg = new JavaPackage (api) { Name = gen.PackageName }; - api.Packages.Add (pkg); + api.Packages.Add (pkg.Name, pkg); } - if (gen is InterfaceGen) { + + if (gen is InterfaceGen iface_gen) { var iface = new JavaInterface (pkg); - pkg.Types.Add (iface); - iface.Load ((InterfaceGen) gen); - } else if (gen is ClassGen c) { + iface.Load (iface_gen); + + pkg.AddType (iface); + } else if (gen is ClassGen class_gen) { var kls = new JavaClass (pkg); - pkg.Types.Add (kls); - kls.Load (opt, c); + kls.Load (opt, class_gen); + + pkg.AddType (kls); } else throw new InvalidOperationException (); diff --git a/tools/param-name-importer/DroidDocImporter.cs b/tools/param-name-importer/DroidDocImporter.cs index 8e4a92953..dabc30399 100644 --- a/tools/param-name-importer/DroidDocImporter.cs +++ b/tools/param-name-importer/DroidDocImporter.cs @@ -97,15 +97,15 @@ public void Import (ImporterOptions options) bool isClass = apiSignatureTokens.Contains ("class"); options.DiagnosticWriter.WriteLine (apiSignatureTokens); - var javaPackage = api.Packages.FirstOrDefault (p => p.Name == packageName); + var javaPackage = api.AllPackages.FirstOrDefault (p => p.Name == packageName); if (javaPackage == null) { javaPackage = new JavaPackage (api) { Name = packageName }; - api.Packages.Add (javaPackage); + api.Packages.Add (packageName, javaPackage); } var javaType = isClass ? (JavaType)new JavaClass (javaPackage) : new JavaInterface (javaPackage); javaType.Name = apiSignatureTokens.Substring (apiSignatureTokens.LastIndexOf (' ') + 1); - javaPackage.Types.Add (javaType); + javaPackage.AddType (javaType); string sectionType = null; var sep = new string [] { ", " }; @@ -166,9 +166,6 @@ public void Import (ImporterOptions options) .OrderBy (m => m.Name + "(" + string.Join (",", m.Parameters.Select (p => p.Type)) + ")") .ToArray (); } - foreach (var pkg in api.Packages) - pkg.Types = pkg.Types.OrderBy (t => t.Name).ToArray (); - api.Packages = api.Packages.OrderBy (p => p.Name).ToArray (); if (options.OutputTextFile != null) api.WriteParameterNamesText (options.OutputTextFile); diff --git a/tools/param-name-importer/JavaApiParameterNamesExporter.cs b/tools/param-name-importer/JavaApiParameterNamesExporter.cs index b20d7f574..2dd5947e9 100644 --- a/tools/param-name-importer/JavaApiParameterNamesExporter.cs +++ b/tools/param-name-importer/JavaApiParameterNamesExporter.cs @@ -31,11 +31,11 @@ public static void WriteParameterNamesXml (this JavaApi api, XmlWriter writer) } }; - foreach (var package in api.Packages) { + foreach (var package in api.AllPackages.OrderBy (p => p.Name)) { writer.WriteStartElement ("package"); writer.WriteAttributeString ("name", package.Name); - foreach (var type in package.Types) { + foreach (var type in package.AllTypes.OrderBy (t => t.Name)) { if (!type.Members.OfType ().Any (m => m.Parameters.Any ())) continue; // we care only about types that has any methods that have parameters. @@ -115,12 +115,12 @@ public static void WriteParameterNamesText (this JavaApi api, TextWriter writer) writer.Write ($"{indent}<{string.Join (",", tps.TypeParameters.Select (p => p.Name))}>"); }; - foreach (var package in api.Packages) { + foreach (var package in api.AllPackages.OrderBy (p => p.Name)) { writer.WriteLine (); writer.WriteLine ($"package {package.Name}"); writer.WriteLine (";---------------------------------------"); - foreach (var type in package.Types) { + foreach (var type in package.AllTypes.OrderBy (t => t.Name)) { if (!type.Members.OfType ().Any (m => m.Parameters.Any ())) continue; // we care only about types that has any methods that have parameters. writer.Write (type is JavaClass ? " class " : " interface "); diff --git a/tools/param-name-importer/JavaStubSourceImporter.cs b/tools/param-name-importer/JavaStubSourceImporter.cs index ef2dcf946..80c609828 100644 --- a/tools/param-name-importer/JavaStubSourceImporter.cs +++ b/tools/param-name-importer/JavaStubSourceImporter.cs @@ -28,8 +28,8 @@ public void Import (ImporterOptions options) break; } } - foreach (var pkg in api.Packages) { - foreach (var t in pkg.Types) { + foreach (var pkg in api.AllPackages) { + foreach (var t in pkg.AllTypes.OrderBy (t => t.Name)) { // Our API definitions don't contain non-public members, so remove those (but it does contain non-public types). t.Members = t.Members.Where (m => m != null && m.Visibility != "").ToList (); // Constructor "type" is the full name of the class. @@ -56,9 +56,7 @@ public void Import (ImporterOptions options) .OrderBy (m => m.Name + "(" + string.Join (",", m.Parameters.Select (p => p.Type)) + ")") .ToArray (); } - pkg.Types = pkg.Types.OrderBy (t => t.Name).ToArray (); } - api.Packages = api.Packages.OrderBy (p => p.Name).ToArray (); if (options.OutputTextFile != null) api.WriteParameterNamesText (options.OutputTextFile); @@ -78,14 +76,14 @@ bool ParseJava (string javaSourceText) if (parsedPackage == null) { return false; } - var pkg = api.Packages.FirstOrDefault (p => p.Name == parsedPackage.Name); + var pkg = api.AllPackages.FirstOrDefault (p => p.Name == parsedPackage.Name); if (pkg == null) { - api.Packages.Add (parsedPackage); + api.AllPackages.Add (parsedPackage); pkg = parsedPackage; } else - foreach (var t in parsedPackage.Types) - pkg.Types.Add (t); - pkg.Types = pkg.Types.OrderBy (t => t.Name).ToList (); + foreach (var t in parsedPackage.AllTypes) + pkg.AddType (t); + return true; } }