diff --git a/src/Java.Interop.Tools.JavaTypeSystem/Adapters/JavaXmlApiExporter.cs b/src/Java.Interop.Tools.JavaTypeSystem/Adapters/JavaXmlApiExporter.cs index 694f84cbe..990c7abcb 100644 --- a/src/Java.Interop.Tools.JavaTypeSystem/Adapters/JavaXmlApiExporter.cs +++ b/src/Java.Interop.Tools.JavaTypeSystem/Adapters/JavaXmlApiExporter.cs @@ -58,15 +58,15 @@ public static void Save (JavaTypeCollection types, XmlWriter writer) static void SaveType (JavaTypeModel type, XmlWriter writer) { if (type is JavaClassModel cls) - SaveType (type, writer, "class", XmlConvert.ToString (cls.IsAbstract), cls.BaseType, cls.BaseTypeGeneric, cls.BaseTypeJni); + SaveType (type, writer, "class", XmlConvert.ToString (cls.IsAbstract), cls.BaseType, cls.BaseTypeGeneric, cls.BaseTypeJni, cls.AnnotatedVisibility); else - SaveType (type, writer, "interface", "true", null, null, null); + SaveType (type, writer, "interface", "true", null, null, null, type.AnnotatedVisibility); foreach (var nested in type.NestedTypes) SaveType (nested, writer); } - static void SaveType (JavaTypeModel cls, XmlWriter writer, string elementName, string abs, string? ext, string? extgen, string? jniExt) + static void SaveType (JavaTypeModel cls, XmlWriter writer, string elementName, string abs, string? ext, string? extgen, string? jniExt, string annotatedVisibility) { writer.WriteStartElement (elementName); @@ -80,6 +80,7 @@ static void SaveType (JavaTypeModel cls, XmlWriter writer, string elementName, s writer.WriteAttributeString ("static", XmlConvert.ToString (cls.IsStatic)); writer.WriteAttributeString ("visibility", cls.Visibility); writer.WriteAttributeStringIfValue ("jni-signature", cls.ExtendedJniSignature); + writer.WriteAttributeStringIfValue ("annotated-visibility", annotatedVisibility); if (cls.PropertyBag.TryGetValue ("merge.SourceFile", out var source)) writer.WriteAttributeString ("merge.SourceFile", source); diff --git a/src/Java.Interop.Tools.JavaTypeSystem/Adapters/JavaXmlApiImporter.cs b/src/Java.Interop.Tools.JavaTypeSystem/Adapters/JavaXmlApiImporter.cs index 77c8bfd7a..514d011d3 100644 --- a/src/Java.Interop.Tools.JavaTypeSystem/Adapters/JavaXmlApiImporter.cs +++ b/src/Java.Interop.Tools.JavaTypeSystem/Adapters/JavaXmlApiImporter.cs @@ -113,7 +113,8 @@ public static JavaClassModel ParseClass (JavaPackage package, XElement element) javaDeprecated: element.XGetAttribute ("deprecated"), javaStatic: element.XGetAttributeAsBool ("static"), jniSignature: element.XGetAttribute ("jni-signature"), - baseTypeJni: element.XGetAttribute ("jni-extends") + baseTypeJni: element.XGetAttribute ("jni-extends"), + annotatedVisibility: element.XGetAttribute ("annotated-visibility") ); if (element.XGetAttribute ("merge.SourceFile") is string source && source.HasValue ()) @@ -151,8 +152,9 @@ public static JavaInterfaceModel ParseInterface (JavaPackage package, XElement e var deprecated = element.XGetAttribute ("deprecated"); var is_static = element.XGetAttribute ("static") == "true"; var jni_signature = element.XGetAttribute ("jni-signature"); + var annotated_visibility = element.XGetAttribute ("annotated-visibility"); - var model = new JavaInterfaceModel (package, nested_name, visibility, deprecated, is_static, jni_signature); + var model = new JavaInterfaceModel (package, nested_name, visibility, deprecated, is_static, jni_signature, annotated_visibility); if (element.XGetAttribute ("merge.SourceFile") is string source && source.HasValue ()) model.PropertyBag.Add ("merge.SourceFile", source); diff --git a/src/Java.Interop.Tools.JavaTypeSystem/Adapters/ManagedApiImporter.cs b/src/Java.Interop.Tools.JavaTypeSystem/Adapters/ManagedApiImporter.cs index c1a6b4d7a..9326743e1 100644 --- a/src/Java.Interop.Tools.JavaTypeSystem/Adapters/ManagedApiImporter.cs +++ b/src/Java.Interop.Tools.JavaTypeSystem/Adapters/ManagedApiImporter.cs @@ -114,7 +114,8 @@ static bool ShouldImport (TypeDefinition td) javaDeprecated: obs_attr != null ? "deprecated" : "not-deprecated", javaStatic: false, jniSignature: FormatJniSignature (package, nested_name), - baseTypeJni: base_jni.HasValue () ? $"L{base_jni};" : string.Empty + baseTypeJni: base_jni.HasValue () ? $"L{base_jni};" : string.Empty, + annotatedVisibility: string.Empty ); ; ParseImplementedInterfaces (type, model); @@ -144,7 +145,8 @@ static bool ShouldImport (TypeDefinition td) javaVisibility: type.IsPublic || type.IsNestedPublic ? "public" : "protected internal", javaDeprecated: obs_attr != null ? "deprecated" : "not-deprecated", javaStatic: false, - jniSignature: FormatJniSignature (package, nested_name) + jniSignature: FormatJniSignature (package, nested_name), + annotatedVisibility: "" ); ParseImplementedInterfaces (type, model); diff --git a/src/Java.Interop.Tools.JavaTypeSystem/JavaModels/JavaBuiltInType.cs b/src/Java.Interop.Tools.JavaTypeSystem/JavaModels/JavaBuiltInType.cs index a7e63e65f..30656a64e 100644 --- a/src/Java.Interop.Tools.JavaTypeSystem/JavaModels/JavaBuiltInType.cs +++ b/src/Java.Interop.Tools.JavaTypeSystem/JavaModels/JavaBuiltInType.cs @@ -6,7 +6,7 @@ namespace Java.Interop.Tools.JavaTypeSystem.Models // Represents a Java built-in type like 'int' or 'float' public class JavaBuiltInType : JavaTypeModel { - public JavaBuiltInType (string name) : base (new JavaPackage ("", "", null), name, "public", false, true, "not deprecated", false, "") { } + public JavaBuiltInType (string name) : base (new JavaPackage ("", "", null), name, "public", false, true, "not deprecated", false, "", "") { } public override void Resolve (JavaTypeCollection types, ICollection unresolvables) { diff --git a/src/Java.Interop.Tools.JavaTypeSystem/JavaModels/JavaClassModel.cs b/src/Java.Interop.Tools.JavaTypeSystem/JavaModels/JavaClassModel.cs index 38a7090f7..35ef3996f 100644 --- a/src/Java.Interop.Tools.JavaTypeSystem/JavaModels/JavaClassModel.cs +++ b/src/Java.Interop.Tools.JavaTypeSystem/JavaModels/JavaClassModel.cs @@ -15,8 +15,8 @@ public class JavaClassModel : JavaTypeModel public JavaTypeReference? BaseTypeReference { get; private set; } public List Constructors { get; } = new List (); - public JavaClassModel (JavaPackage javaPackage, string javaNestedName, string javaVisibility, bool javaAbstract, bool javaFinal, string javaBaseType, string javaBaseTypeGeneric, string javaDeprecated, bool javaStatic, string jniSignature, string baseTypeJni) : - base (javaPackage, javaNestedName, javaVisibility, javaAbstract, javaFinal, javaDeprecated, javaStatic, jniSignature) + public JavaClassModel (JavaPackage javaPackage, string javaNestedName, string javaVisibility, bool javaAbstract, bool javaFinal, string javaBaseType, string javaBaseTypeGeneric, string javaDeprecated, bool javaStatic, string jniSignature, string baseTypeJni, string annotatedVisibility) : + base (javaPackage, javaNestedName, javaVisibility, javaAbstract, javaFinal, javaDeprecated, javaStatic, jniSignature, annotatedVisibility) { BaseType = javaBaseType; BaseTypeGeneric = javaBaseTypeGeneric; diff --git a/src/Java.Interop.Tools.JavaTypeSystem/JavaModels/JavaInterfaceModel.cs b/src/Java.Interop.Tools.JavaTypeSystem/JavaModels/JavaInterfaceModel.cs index 1823f3d18..2ce22c435 100644 --- a/src/Java.Interop.Tools.JavaTypeSystem/JavaModels/JavaInterfaceModel.cs +++ b/src/Java.Interop.Tools.JavaTypeSystem/JavaModels/JavaInterfaceModel.cs @@ -4,8 +4,8 @@ namespace Java.Interop.Tools.JavaTypeSystem.Models { public class JavaInterfaceModel : JavaTypeModel { - public JavaInterfaceModel (JavaPackage javaPackage, string javaNestedName, string javaVisibility, string javaDeprecated, bool javaStatic, string jniSignature) : - base (javaPackage, javaNestedName, javaVisibility, false, false, javaDeprecated, javaStatic, jniSignature) + public JavaInterfaceModel (JavaPackage javaPackage, string javaNestedName, string javaVisibility, string javaDeprecated, bool javaStatic, string jniSignature, string annotatedVisibility) : + base (javaPackage, javaNestedName, javaVisibility, false, false, javaDeprecated, javaStatic, jniSignature, annotatedVisibility) { } diff --git a/src/Java.Interop.Tools.JavaTypeSystem/JavaModels/JavaTypeModel.cs b/src/Java.Interop.Tools.JavaTypeSystem/JavaModels/JavaTypeModel.cs index 2049742c2..f1c65249f 100644 --- a/src/Java.Interop.Tools.JavaTypeSystem/JavaModels/JavaTypeModel.cs +++ b/src/Java.Interop.Tools.JavaTypeSystem/JavaModels/JavaTypeModel.cs @@ -17,6 +17,7 @@ public abstract class JavaTypeModel : IJavaResolvable public string NestedName { get; set; } public string Visibility { get; } + public string AnnotatedVisibility { get; } public bool IsAbstract { get; } public bool IsFinal { get; } public string Deprecated { get; } @@ -36,12 +37,13 @@ public abstract class JavaTypeModel : IJavaResolvable public Dictionary PropertyBag { get; } = new Dictionary (); - protected JavaTypeModel (JavaPackage javaPackage, string javaNestedName, string javaVisibility, bool javaAbstract, bool javaFinal, string deprecated, bool javaStatic, string jniSignature) + protected JavaTypeModel (JavaPackage javaPackage, string javaNestedName, string javaVisibility, bool javaAbstract, bool javaFinal, string deprecated, bool javaStatic, string jniSignature, string annotatedVisibility) { Package = javaPackage; NestedName = javaNestedName.Replace ('$', '.'); Name = NestedName.LastSubset ('.'); Visibility = javaVisibility; + AnnotatedVisibility = annotatedVisibility; IsAbstract = javaAbstract; IsFinal = javaFinal; Deprecated = deprecated; diff --git a/tests/Java.Interop.Tools.JavaTypeSystem-Tests/Java.Interop.Tools.JavaTypeSystem-Tests.csproj b/tests/Java.Interop.Tools.JavaTypeSystem-Tests/Java.Interop.Tools.JavaTypeSystem-Tests.csproj index f1f14b19d..a0fb695ce 100644 --- a/tests/Java.Interop.Tools.JavaTypeSystem-Tests/Java.Interop.Tools.JavaTypeSystem-Tests.csproj +++ b/tests/Java.Interop.Tools.JavaTypeSystem-Tests/Java.Interop.Tools.JavaTypeSystem-Tests.csproj @@ -4,6 +4,7 @@ net472;$(DotNetTargetFramework) false Java.Interop.Tools.JavaTypeSystem.Tests + 8.0 diff --git a/tests/Java.Interop.Tools.JavaTypeSystem-Tests/JavaApiTestHelper.cs b/tests/Java.Interop.Tools.JavaTypeSystem-Tests/JavaApiTestHelper.cs index 5534af80a..182b40d8d 100644 --- a/tests/Java.Interop.Tools.JavaTypeSystem-Tests/JavaApiTestHelper.cs +++ b/tests/Java.Interop.Tools.JavaTypeSystem-Tests/JavaApiTestHelper.cs @@ -14,7 +14,7 @@ public static JavaTypeCollection GetLoadedApi () return JavaXmlApiImporter.Parse (ApiPath); } - public static JavaClassModel CreateClass (JavaPackage javaPackage, string javaNestedName, string javaVisibility = "public", bool javaAbstract = false, bool javaFinal = false, string javaBaseType = "java.lang.Object", string javaBaseTypeGeneric = "java.lang.Object", string javaDeprecated = "not deprecated", bool javaStatic = false, string jniSignature = "", string baseTypeJni = "java/lang/Object") + public static JavaClassModel CreateClass (JavaPackage javaPackage, string javaNestedName, string javaVisibility = "public", bool javaAbstract = false, bool javaFinal = false, string javaBaseType = "java.lang.Object", string javaBaseTypeGeneric = "java.lang.Object", string javaDeprecated = "not deprecated", bool javaStatic = false, string jniSignature = "", string baseTypeJni = "java/lang/Object", string annotatedVisibility = "") { if (string.IsNullOrWhiteSpace (jniSignature)) jniSignature = $"{(!string.IsNullOrWhiteSpace (javaPackage.Name) ? javaPackage.Name + "." : "")}{javaNestedName}".Replace ('.', '/'); @@ -30,7 +30,8 @@ public static JavaClassModel CreateClass (JavaPackage javaPackage, string javaNe javaDeprecated: javaDeprecated, javaStatic: javaStatic, jniSignature: jniSignature, - baseTypeJni: baseTypeJni + baseTypeJni: baseTypeJni, + annotatedVisibility: annotatedVisibility ); return klass; diff --git a/tests/Java.Interop.Tools.JavaTypeSystem-Tests/JavaTypeModelsTests.cs b/tests/Java.Interop.Tools.JavaTypeSystem-Tests/JavaTypeModelsTests.cs index a69c401a3..1ee28de00 100644 --- a/tests/Java.Interop.Tools.JavaTypeSystem-Tests/JavaTypeModelsTests.cs +++ b/tests/Java.Interop.Tools.JavaTypeSystem-Tests/JavaTypeModelsTests.cs @@ -1,5 +1,7 @@ using System; +using System.IO; using System.Linq; +using System.Xml; using Java.Interop.Tools.JavaTypeSystem.Models; using NUnit.Framework; @@ -25,5 +27,35 @@ public void TestToString () var kls = pkg.Types.First (t => t.FullName == "android.database.ContentObservable"); Assert.AreEqual ("[Class] android.database.ContentObservable", kls.ToString ()); } + + [Test] + public void AnnotatedVisibility () + { + // Ensure the 'annotated-visibility' attribute gets passed through + using var sw = new StringWriter (); + + using (var xml = XmlWriter.Create (sw)) + JavaXmlApiExporter.Save (api, xml); + + var doc = new XmlDocument { XmlResolver = null }; + using var sreader = new StringReader (sw.ToString ()); + using var reader = XmlReader.Create (sreader, new XmlReaderSettings { XmlResolver = null }); + doc.Load (reader); + + var annotated_class = doc.SelectSingleNode ("/api/package/class[@name='StateListAnimator']"); + Assert.AreEqual ("TESTS", annotated_class.Attributes ["annotated-visibility"].InnerText); + + var annotated_ctor = annotated_class ["constructor"]; + Assert.AreEqual ("TESTS", annotated_ctor.Attributes ["annotated-visibility"].InnerText); + + var annotated_method = annotated_class ["method"]; + Assert.AreEqual ("TESTS", annotated_method.Attributes ["annotated-visibility"].InnerText); + + var annotated_interface = doc.SelectSingleNode ("/api/package/interface[@name='DrmStore.ConstraintsColumns']"); + Assert.AreEqual ("TESTS", annotated_interface.Attributes ["annotated-visibility"].InnerText); + + var annotated_field = annotated_interface ["field"]; + Assert.AreEqual ("TESTS", annotated_field.Attributes ["annotated-visibility"].InnerText); + } } } diff --git a/tests/Java.Interop.Tools.JavaTypeSystem-Tests/api-24.xml.in b/tests/Java.Interop.Tools.JavaTypeSystem-Tests/api-24.xml.in index 2a7f4bab5..48f408a4b 100644 --- a/tests/Java.Interop.Tools.JavaTypeSystem-Tests/api-24.xml.in +++ b/tests/Java.Interop.Tools.JavaTypeSystem-Tests/api-24.xml.in @@ -43190,7 +43190,8 @@ name="StateListAnimator" jni-signature="Landroid/animation/StateListAnimator;" static="false" - visibility="public"> + visibility="public" + annotated-visibility="TESTS"> + jni-signature="()V" + annotated-visibility="TESTS" /> + jni-signature="([ILandroid/animation/Animator;)V" + annotated-visibility="TESTS"> + visibility="public" + annotated-visibility="TESTS"> + volatile="false" + annotated-visibility="TESTS" />