diff --git a/src/Xamarin.SourceWriter/Models/MethodWriter.cs b/src/Xamarin.SourceWriter/Models/MethodWriter.cs index f826b919b..0d8135c2c 100644 --- a/src/Xamarin.SourceWriter/Models/MethodWriter.cs +++ b/src/Xamarin.SourceWriter/Models/MethodWriter.cs @@ -19,6 +19,7 @@ public class MethodWriter : ISourceWriter, ITakeParameters public List Body { get; set; } = new List (); public bool IsSealed { get; set; } public bool IsStatic { get; set; } + public bool IsPartial { get; set; } public bool IsPrivate { get => visibility == Visibility.Private; set => visibility = value ? Visibility.Private : Visibility.Default; } public bool IsProtected { get => visibility == Visibility.Protected; set => visibility = value ? Visibility.Protected : Visibility.Default; } public bool IsOverride { get; set; } @@ -103,6 +104,9 @@ public virtual void WriteSignature (CodeWriter writer) if (IsUnsafe) writer.Write ("unsafe "); + if (IsPartial) + writer.Write ("partial "); + WriteReturnType (writer); if (ExplicitInterfaceImplementation.HasValue ()) diff --git a/tests/generator-Tests/Unit-Tests/CodeGeneratorTests.cs b/tests/generator-Tests/Unit-Tests/CodeGeneratorTests.cs index ff3c7945a..21e11258f 100644 --- a/tests/generator-Tests/Unit-Tests/CodeGeneratorTests.cs +++ b/tests/generator-Tests/Unit-Tests/CodeGeneratorTests.cs @@ -376,6 +376,34 @@ public void CompatVirtualMethod_Class () Assert.True (writer.ToString ().NormalizeLineEndings ().Contains ("catch (Java.Lang.NoSuchMethodError) { throw new Java.Lang.AbstractMethodError (__id); }".NormalizeLineEndings ()), $"was: `{writer}`"); } + [Test] + public void PeerConstructorPartialMethod_Class () + { + var xml = @" + + + + + + + + "; + + var gens = ParseApiDefinition (xml); + var klass = gens.Single (g => g.Name == "MyClass"); + + generator.Context.ContextTypes.Push (klass); + generator.WriteType (klass, string.Empty, new GenerationInfo ("", "", "MyAssembly")); + generator.Context.ContextTypes.Pop (); + + Assert.True (writer.ToString ().NormalizeLineEndings ().Contains ("partial void _OnMyClassCreated ();".NormalizeLineEndings ()), $"was: `{writer}`"); + Assert.True (writer.ToString ().NormalizeLineEndings ().Contains ("{ _OnMyClassCreated (); }".NormalizeLineEndings ()), $"was: `{writer}`"); + } [Test] public void WriteDuplicateInterfaceEventArgs () { diff --git a/tools/generator/Java.Interop.Tools.Generator.Importers/XmlApiImporter.cs b/tools/generator/Java.Interop.Tools.Generator.Importers/XmlApiImporter.cs index 3eaab2bd6..51a8239fe 100644 --- a/tools/generator/Java.Interop.Tools.Generator.Importers/XmlApiImporter.cs +++ b/tools/generator/Java.Interop.Tools.Generator.Importers/XmlApiImporter.cs @@ -110,6 +110,7 @@ public static ClassGen CreateClass (XElement pkg, XElement elem, CodeGenerationO FromXml = true, IsAbstract = elem.XGetAttribute ("abstract") == "true", IsFinal = elem.XGetAttribute ("final") == "true", + PeerConstructorPartialMethod = elem.XGetAttribute ("peerConstructorPartialMethod"), // Only use an explicitly set XML attribute Unnest = elem.XGetAttribute ("unnest") == "true" ? true : elem.XGetAttribute ("unnest") == "false" ? false : diff --git a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/ClassGen.cs b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/ClassGen.cs index ffb419a6d..ccdcd174d 100644 --- a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/ClassGen.cs +++ b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/ClassGen.cs @@ -302,6 +302,8 @@ public bool IsExplicitlyImplementedMethod (string sig) public bool NeedsNew { get; set; } + public string PeerConstructorPartialMethod { get; set; } + protected override bool OnValidate (CodeGenerationOptions opt, GenericParameterDefinitionList type_params, CodeGeneratorContext context) { if (validated) diff --git a/tools/generator/SourceWriters/BoundClass.cs b/tools/generator/SourceWriters/BoundClass.cs index 76ca86db8..3acb86c85 100644 --- a/tools/generator/SourceWriters/BoundClass.cs +++ b/tools/generator/SourceWriters/BoundClass.cs @@ -126,8 +126,12 @@ void AddBindingInfrastructure (ClassGen klass, CodeGenerationOptions opt) void AddConstructors (ClassGen klass, CodeGenerationOptions opt, CodeGeneratorContext context) { // Add required constructor for all JLO inheriting classes - if (klass.FullName != "Java.Lang.Object" && klass.InheritsObject) - Constructors.Add (new JavaLangObjectConstructor (klass, opt)); + if (klass.FullName != "Java.Lang.Object" && klass.InheritsObject) { + if (!string.IsNullOrWhiteSpace (klass.PeerConstructorPartialMethod)) { + Methods.Add (new ConstructorPartialMethod (klass.PeerConstructorPartialMethod)); + } + Constructors.Add (new JavaLangObjectConstructor (klass, opt, klass.PeerConstructorPartialMethod)); + } foreach (var ctor in klass.Ctors) { // Don't bind final or protected constructors diff --git a/tools/generator/SourceWriters/ConstructorPartialMethod.cs b/tools/generator/SourceWriters/ConstructorPartialMethod.cs new file mode 100644 index 000000000..af0c4c4b8 --- /dev/null +++ b/tools/generator/SourceWriters/ConstructorPartialMethod.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MonoDroid.Generation; +using Xamarin.Android.Binder; +using Xamarin.SourceWriter; + +namespace generator.SourceWriters +{ + public class ConstructorPartialMethod : MethodWriter + { + public ConstructorPartialMethod (string partialMethodName) + { + Name = partialMethodName; + IsPartial = true; + IsDeclaration = true; + ReturnType = new TypeReferenceWriter ("void"); + } + } +} diff --git a/tools/generator/SourceWriters/JavaLangObjectConstructor.cs b/tools/generator/SourceWriters/JavaLangObjectConstructor.cs index a36bb69c5..7c6381e14 100644 --- a/tools/generator/SourceWriters/JavaLangObjectConstructor.cs +++ b/tools/generator/SourceWriters/JavaLangObjectConstructor.cs @@ -11,7 +11,7 @@ namespace generator.SourceWriters { public class JavaLangObjectConstructor : ConstructorWriter { - public JavaLangObjectConstructor (ClassGen klass, CodeGenerationOptions opt) + public JavaLangObjectConstructor (ClassGen klass, CodeGenerationOptions opt, string callPartialMethod) { Name = klass.Name; @@ -31,6 +31,9 @@ public JavaLangObjectConstructor (ClassGen klass, CodeGenerationOptions opt) BaseCall = "base (javaReference, transfer)"; } + if (!string.IsNullOrWhiteSpace (callPartialMethod)) { + Body.Add ($"{callPartialMethod} ();"); + } } } }