From 9b7edbcd70b87df97d4a0f7890e86182dd3cb309 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Thu, 17 Mar 2022 15:28:38 -0400 Subject: [PATCH] [Java.Base, generator] Bind all of package java.lang MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Context: bc5bcf4f0ef07aab898f2643d2a25f66512d98ed Bind all classes and interfaces in the `java.lang` package. Alter Java array binding, so that instead of `IList`, we get "direct" Java arrays, e.g. namespace Java.Lang { partial class Character { // Previous/Xamarin.Android-like public static int CodePointAt (IList? a, int index); // New/Desktop public static int CodePointAt (JavaCharArray? a, int index); } } Rationale: it *allows* for more efficient JVM :: .NET array copying, by making copies explicit (to the dev), not implicit. We can add an implicit conversion from e.g. `IEnumerable` to `JavaCharArray` in the future, if deemed useful. This also impacts method return types, properties, and fields. Bind the `java.lang.module` package in the namespace `Java.Lang.Modules`. This is to avoid a type/namespace conflict with `java.lang.Module`, bound as `Java.Lang.Module`. Continue updating `generator` to remove "Android-isms". Update `Java.Base.csproj` to ignore [warning CS0108][0]: Java.Lang.Reflect.IAnnotatedArrayType.cs(15,45): warning CS0108: 'IAnnotatedArrayType.AnnotatedOwnerType' hides inherited member 'IAnnotatedType.AnnotatedOwnerType'. Use the new keyword if hiding was intended. The problem here is that we have: public partial interface IAnnotatedType { // Contains default interface method virtual unsafe IAnnotatedType? AnnotatedOwnerType => …; } public partial interface IAnnotatedArrayType : IAnnotatedType { // Contains *no* method body; re-abstracted IAnnotatedType? AnnotatedOwnerType {get;} } TODO: figure out how to properly fix this. `managedOverride` metadata (5a0e37e0) doesn't seem useful to "re-abstract" a default interface member. Update `Java.Base.targets` to use `generator --global`. This is so that `java.lang.System` can be bound as `Java.Lang.System` without causing various C# compilation errors due to type lookup. (Compare to Xamarin.Android's `Java.Lang.JavaSystem`, which got a `Java*` prefix to avoid these compilation errors.) Update `JavaInteropCodeGeneratorTests.CreateOptions()` so that C# features such as default interface methods and nested interface types are enabled within the unit tests. TODO: * When `generator --codegen-target=JavaInterop1` is used, all the language features should also be enabled by default. * Certain Java Annotation-related types aren't bound in JavaInterop1, vs. XAJavaInterop1. Revisit this. * "Revisit" use of `JNIEnv.ToLocalJniHandle()` in Xamarin.Android bindings, and it's outright removal in JavaInterop1 bindings. @jonpryor *thinks* the `JNIENv.ToLocalJniHandle(v)` was introduced "in case" `v` would be collected by the GC "during" a JNI call. Use of `GC.KeepAlive()` (1f21f38c, da73d6a5), would be a better solution, but also requires auditing `generator` output. * Bind the rest of `java.base.jmod` (bc5bcf4f). [0]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/cs0108 --- src/Java.Base/Java.Base.csproj | 3 +- src/Java.Base/Java.Base.targets | 2 +- src/Java.Base/Java.Lang/ICharSequence.cs | 20 +++ src/Java.Base/Java.Lang/String.cs | 9 ++ src/Java.Base/Java.Lang/StringBuffer.cs | 8 + src/Java.Base/Java.Lang/StringBuilder.cs | 8 + src/Java.Base/Transforms/Metadata.xml | 28 ++-- .../Integration-Tests/Arrays.cs | 2 - .../Integration-Tests/Compiler.cs | 2 +- .../JavaInterop1/WriteClass.txt | 8 +- .../WriteDuplicateInterfaceEventArgs.txt | 4 +- .../JavaInterop1/WriteInterface.txt | 69 ++++---- .../JavaInterop1/WriteInterfaceEventArgs.txt | 2 +- .../WriteInterfaceEventArgsWithParamArray.txt | 6 +- .../WriteInterfaceEventHandlerImpl.txt | 81 +++++----- .../WriteInterfaceEventHandlerImplContent.txt | 4 +- ...iteKotlinUnsignedArrayTypeMethodsClass.txt | 16 +- ...KotlinUnsignedArrayTypePropertiesClass.txt | 16 +- .../WritePropertyAbstractDeclaration.txt | 8 +- .../JavaInterop1/WritePropertyCallbacks.txt | 8 +- .../JavaInterop1/WritePropertyInvoker.txt | 49 +++--- .../WritePropertyStringVariant.txt | 2 +- .../Unit-Tests/CodeGeneratorTestBase.cs | 30 +++- .../Unit-Tests/CodeGeneratorTests.cs | 151 ++++++++++-------- .../Unit-Tests/SupportTypes.cs | 11 +- .../Arrays/Xamarin.Test.SomeObject.cs | 70 ++++---- .../Streams/Java.IO.FilterOutputStream.cs | 19 +++ .../Streams/Java.IO.InputStream.cs | 8 +- .../Streams/Java.IO.OutputStream.cs | 8 +- ....ME.GenericStringPropertyImplementation.cs | 2 +- .../AccessModifiers/Mono.Android.projitems | 20 +++ .../expected/Adapters/Mono.Android.projitems | 19 +++ .../Mono.Android.projitems | 15 ++ .../expected/Arrays/Mono.Android.projitems | 15 ++ .../CSharpKeywords/Mono.Android.projitems | 16 ++ .../Constructors/Mono.Android.projitems | 16 ++ .../Core_ClassParse/Mono.Android.projitems | 18 +++ .../Core_Jar2Xml/Mono.Android.projitems | 21 +++ .../EnumerationFixup/Mono.Android.projitems | 19 +++ .../GenericArguments/Mono.Android.projitems | 18 +++ .../Mono.Android.projitems | 18 +++ .../NestedTypes/Mono.Android.projitems | 15 ++ .../NonStaticFields/Mono.Android.projitems | 15 ++ .../NormalMethods/Mono.Android.projitems | 20 +++ .../NormalProperties/Mono.Android.projitems | 15 ++ .../ParameterXPath/Mono.Android.projitems | 16 ++ .../StaticFields/Mono.Android.projitems | 15 ++ .../StaticMethods/Mono.Android.projitems | 15 ++ .../StaticProperties/Mono.Android.projitems | 15 ++ .../expected/Streams/Mono.Android.projitems | 19 +++ .../TestInterface/Mono.Android.projitems | 25 +++ ....ME.GenericStringPropertyImplementation.cs | 2 +- .../java.lang.Enum/Mono.Android.projitems | 17 ++ .../java.lang.Object/Mono.Android.projitems | 14 ++ .../java.util.List/Mono.Android.projitems | 15 ++ tools/generator/CodeGenerationOptions.cs | 7 + .../ClassGen.cs | 9 +- .../GenBase.cs | 3 + .../InterfaceGen.cs | 3 + .../Parameter.cs | 7 +- .../ReturnValue.cs | 12 ++ .../Symbols/ArraySymbol.cs | 34 +--- .../Symbols/CharSequenceSymbol.cs | 22 +++ .../Symbols/GenericTypeParameter.cs | 13 +- .../Symbols/SymbolTable.cs | 11 +- .../SourceWriters/BoundFieldAsProperty.cs | 61 +++++-- .../generator/SourceWriters/BoundInterface.cs | 4 +- .../BoundPropertyStringVariant.cs | 7 +- .../CharSequenceEnumeratorMethod.cs | 6 +- .../Extensions/SourceWriterExtensions.cs | 4 +- 70 files changed, 954 insertions(+), 316 deletions(-) create mode 100644 src/Java.Base/Java.Lang/ICharSequence.cs create mode 100644 src/Java.Base/Java.Lang/String.cs create mode 100644 src/Java.Base/Java.Lang/StringBuffer.cs create mode 100644 src/Java.Base/Java.Lang/StringBuilder.cs create mode 100644 tests/generator-Tests/expected/AccessModifiers/Mono.Android.projitems create mode 100644 tests/generator-Tests/expected/Adapters/Mono.Android.projitems create mode 100644 tests/generator-Tests/expected/Android.Graphics.Color/Mono.Android.projitems create mode 100644 tests/generator-Tests/expected/Arrays/Mono.Android.projitems create mode 100644 tests/generator-Tests/expected/CSharpKeywords/Mono.Android.projitems create mode 100644 tests/generator-Tests/expected/Constructors/Mono.Android.projitems create mode 100644 tests/generator-Tests/expected/Core_ClassParse/Mono.Android.projitems create mode 100644 tests/generator-Tests/expected/Core_Jar2Xml/Mono.Android.projitems create mode 100644 tests/generator-Tests/expected/EnumerationFixup/Mono.Android.projitems create mode 100644 tests/generator-Tests/expected/GenericArguments/Mono.Android.projitems create mode 100644 tests/generator-Tests/expected/InterfaceMethodsConflict/Mono.Android.projitems create mode 100644 tests/generator-Tests/expected/NestedTypes/Mono.Android.projitems create mode 100644 tests/generator-Tests/expected/NonStaticFields/Mono.Android.projitems create mode 100644 tests/generator-Tests/expected/NormalMethods/Mono.Android.projitems create mode 100644 tests/generator-Tests/expected/NormalProperties/Mono.Android.projitems create mode 100644 tests/generator-Tests/expected/ParameterXPath/Mono.Android.projitems create mode 100644 tests/generator-Tests/expected/StaticFields/Mono.Android.projitems create mode 100644 tests/generator-Tests/expected/StaticMethods/Mono.Android.projitems create mode 100644 tests/generator-Tests/expected/StaticProperties/Mono.Android.projitems create mode 100644 tests/generator-Tests/expected/Streams/Mono.Android.projitems create mode 100644 tests/generator-Tests/expected/TestInterface/Mono.Android.projitems create mode 100644 tests/generator-Tests/expected/java.lang.Enum/Mono.Android.projitems create mode 100644 tests/generator-Tests/expected/java.lang.Object/Mono.Android.projitems create mode 100644 tests/generator-Tests/expected/java.util.List/Mono.Android.projitems diff --git a/src/Java.Base/Java.Base.csproj b/src/Java.Base/Java.Base.csproj index 81bd6cc7d..7351b3997 100644 --- a/src/Java.Base/Java.Base.csproj +++ b/src/Java.Base/Java.Base.csproj @@ -4,7 +4,8 @@ net6.0 true enable - $(NoWarn);8764 + + $(NoWarn);8764;CS0108 $(JICoreLibVersion) diff --git a/src/Java.Base/Java.Base.targets b/src/Java.Base/Java.Base.targets index bf23f6dde..8ce72f869 100644 --- a/src/Java.Base/Java.Base.targets +++ b/src/Java.Base/Java.Base.targets @@ -44,7 +44,7 @@ "$(GeneratorPath)" - <_GenFlags>--public + <_GenFlags>--public --global <_Out>-o "$(IntermediateOutputPath)mcw" <_Codegen>--codegen-target=JavaInterop1 <_Fixup>--fixup=Transforms/Metadata.xml diff --git a/src/Java.Base/Java.Lang/ICharSequence.cs b/src/Java.Base/Java.Lang/ICharSequence.cs new file mode 100644 index 000000000..678e0e67a --- /dev/null +++ b/src/Java.Base/Java.Lang/ICharSequence.cs @@ -0,0 +1,20 @@ +namespace Java.Lang { + + public static partial class ICharSequenceExtensions { + + public static ICharSequence[]? ToCharSequenceArray (this string?[]? values) + { + if (values == null) { + return null; + } + var array = new ICharSequence [values.Length]; + for (int i = 0; i < values.Length; ++i) { + if (values [i] == null) { + continue; + } + array [i] = new Java.Lang.String (values [i]); + } + return array; + } + } +} diff --git a/src/Java.Base/Java.Lang/String.cs b/src/Java.Base/Java.Lang/String.cs new file mode 100644 index 000000000..bc580cfb4 --- /dev/null +++ b/src/Java.Base/Java.Lang/String.cs @@ -0,0 +1,9 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using Java.Interop; + +namespace Java.Lang { + public partial class String : IEnumerable, IEnumerable { + } +} diff --git a/src/Java.Base/Java.Lang/StringBuffer.cs b/src/Java.Base/Java.Lang/StringBuffer.cs new file mode 100644 index 000000000..13a798613 --- /dev/null +++ b/src/Java.Base/Java.Lang/StringBuffer.cs @@ -0,0 +1,8 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Java.Lang { + partial class StringBuffer : IEnumerable, IEnumerable { + } +} diff --git a/src/Java.Base/Java.Lang/StringBuilder.cs b/src/Java.Base/Java.Lang/StringBuilder.cs new file mode 100644 index 000000000..0eecdaa24 --- /dev/null +++ b/src/Java.Base/Java.Lang/StringBuilder.cs @@ -0,0 +1,8 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Java.Lang { + partial class StringBuilder : IEnumerable, IEnumerable { + } +} diff --git a/src/Java.Base/Transforms/Metadata.xml b/src/Java.Base/Transforms/Metadata.xml index 7ab4ca6f5..29fc1fedc 100644 --- a/src/Java.Base/Transforms/Metadata.xml +++ b/src/Java.Base/Transforms/Metadata.xml @@ -2,16 +2,22 @@ - - - + + - JavaFinalize + + JavaFinalize + + deprecated + + + + + java.lang.Object + + + + java.lang.Object + + diff --git a/tests/generator-Tests/Integration-Tests/Arrays.cs b/tests/generator-Tests/Integration-Tests/Arrays.cs index ecdc48e52..73e30baa3 100644 --- a/tests/generator-Tests/Integration-Tests/Arrays.cs +++ b/tests/generator-Tests/Integration-Tests/Arrays.cs @@ -6,8 +6,6 @@ namespace generatortests [TestFixture] public class Arrays : BaseGeneratorTest { - protected override bool TryJavaInterop1 => false; - [Test] public void GeneratedOK () { diff --git a/tests/generator-Tests/Integration-Tests/Compiler.cs b/tests/generator-Tests/Integration-Tests/Compiler.cs index b0386cf9a..15bfc0265 100644 --- a/tests/generator-Tests/Integration-Tests/Compiler.cs +++ b/tests/generator-Tests/Integration-Tests/Compiler.cs @@ -71,7 +71,7 @@ public static Assembly Compile (Xamarin.Android.Binder.CodeGeneratorOptions opti var references = referencePaths.Select (p => MetadataReference.CreateFromFile (p)).ToArray (); string testCommandLine = - $"csc \"-out:{Path.GetFileName (assemblyFileName)}\" " + + $"csc -noconfig -nostdlib \"-out:{Path.GetFileName (assemblyFileName)}\" " + $"-unsafe -t:library " + string.Join (" ", preprocessorSymbols.Select (p => $"\"-define:{p}\"")) + " " + string.Join (" ", referencePaths.Select (p => $"\"-r:{p}\"")) + " " + diff --git a/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteClass.txt b/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteClass.txt index 68a8448d9..09e6e4837 100644 --- a/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteClass.txt +++ b/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteClass.txt @@ -24,7 +24,7 @@ public partial class MyClass { } // Metadata.xml XPath constructor reference: path="/api/package[@name='java.code']/class[@name='MyClass']/constructor[@name='MyClass' and count(parameter)=1 and parameter[1][@type='java.lang.String']]" - unsafe MyClass (string p0) : base (ref *InvalidJniObjectReference, JniObjectReferenceOptions.None) + unsafe MyClass (string? p0) : base (ref *InvalidJniObjectReference, JniObjectReferenceOptions.None) { const string __id = "(Ljava/lang/String;)V"; @@ -65,7 +65,7 @@ public partial class MyClass { } } - public virtual unsafe string Key { + public virtual unsafe string? Key { // Metadata.xml XPath method reference: path="/api/package[@name='java.code']/class[@name='MyClass']/method[@name='get_Key' and count(parameter)=0]" get { const string __id = "get_Key.()Ljava/lang/String;"; @@ -120,7 +120,7 @@ public partial class MyClass { } // Metadata.xml XPath method reference: path="/api/package[@name='java.code']/class[@name='MyClass']/method[@name='GetCountForKey' and count(parameter)=1 and parameter[1][@type='java.lang.String']]" - public virtual unsafe int GetCountForKey (string key) + public virtual unsafe int GetCountForKey (string? key) { const string __id = "GetCountForKey.(Ljava/lang/String;)I"; var native_key = global::Java.Interop.JniEnvironment.Strings.NewString (key); @@ -135,7 +135,7 @@ public partial class MyClass { } // Metadata.xml XPath method reference: path="/api/package[@name='java.code']/class[@name='MyClass']/method[@name='Key' and count(parameter)=0]" - public virtual unsafe string Key () + public virtual unsafe string? Key () { const string __id = "Key.()Ljava/lang/String;"; try { diff --git a/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteDuplicateInterfaceEventArgs.txt b/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteDuplicateInterfaceEventArgs.txt index ab1cf6160..2fbd55975 100644 --- a/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteDuplicateInterfaceEventArgs.txt +++ b/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteDuplicateInterfaceEventArgs.txt @@ -57,7 +57,7 @@ internal sealed partial class AnimatorListenerImplementor : global::Java.Lang.Ob } #pragma warning disable 0649 - public EventHandler OnAnimationEndHandler; + public EventHandler? OnAnimationEndHandler; #pragma warning restore 0649 public bool OnAnimationEnd (int param1) @@ -71,7 +71,7 @@ internal sealed partial class AnimatorListenerImplementor : global::Java.Lang.Ob } #pragma warning disable 0649 - public EventHandler OnAnimationEndHandler; + public EventHandler? OnAnimationEndHandler; #pragma warning restore 0649 public bool OnAnimationEnd (int param1, int param2) diff --git a/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteInterface.txt b/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteInterface.txt index 5e4f2d46d..79c6ea479 100644 --- a/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteInterface.txt +++ b/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteInterface.txt @@ -1,35 +1,8 @@ -[Register ("java/code/IMyInterface", DoNotGenerateAcw=true)] -public abstract class MyInterface : Java.Lang.Object { - internal MyInterface () - { - } - - // Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/method[@name='StaticMethod' and count(parameter)=0]" - public static unsafe void StaticMethod () - { - const string __id = "StaticMethod.()V"; - try { - _members.StaticMethods.InvokeVoidMethod (__id, null); - } finally { - } - } - - static readonly JniPeerMembers _members = new JniPeerMembers ("java/code/IMyInterface", typeof (MyInterface)); - -} - -[Register ("java/code/IMyInterface", DoNotGenerateAcw=true)] -[global::System.Obsolete ("Use the 'MyInterface' type. This type will be removed in a future release.", error: true)] -public abstract class MyInterfaceConsts : MyInterface { - private MyInterfaceConsts () - { - } - -} - // Metadata.xml XPath interface reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']" [global::Java.Interop.JniTypeSignature ("java/code/IMyInterface", GenerateJavaPeer=false)] public partial interface IMyInterface : IJavaPeerable { + private static readonly JniPeerMembers _members = new JniPeerMembers ("java/code/IMyInterface", typeof (IMyInterface), isInterface: true); + int Count { // Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/method[@name='get_Count' and count(parameter)=0]" get; @@ -38,7 +11,7 @@ public partial interface IMyInterface : IJavaPeerable { set; } - string Key { + string? Key { // Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/method[@name='get_Key' and count(parameter)=0]" get; @@ -54,13 +27,45 @@ public partial interface IMyInterface : IJavaPeerable { set; } + static unsafe int StaticCount { + // Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/method[@name='get_StaticCount' and count(parameter)=0]" + get { + const string __id = "get_StaticCount.()I"; + try { + var __rm = _members.StaticMethods.InvokeInt32Method (__id, null); + return __rm; + } finally { + } + } + // Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/method[@name='set_StaticCount' and count(parameter)=1 and parameter[1][@type='int']]" + set { + const string __id = "set_StaticCount.(I)V"; + try { + JniArgumentValue* __args = stackalloc JniArgumentValue [1]; + __args [0] = new JniArgumentValue (value); + _members.StaticMethods.InvokeVoidMethod (__id, __args); + } finally { + } + } + } + // Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/method[@name='GetCountForKey' and count(parameter)=1 and parameter[1][@type='java.lang.String']]" - int GetCountForKey (string key); + int GetCountForKey (string? key); // Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/method[@name='Key' and count(parameter)=0]" - string Key (); + string? Key (); // Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/method[@name='AbstractMethod' and count(parameter)=0]" void AbstractMethod (); + // Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/method[@name='StaticMethod' and count(parameter)=0]" + public static unsafe void StaticMethod () + { + const string __id = "StaticMethod.()V"; + try { + _members.StaticMethods.InvokeVoidMethod (__id, null); + } finally { + } + } + } diff --git a/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteInterfaceEventArgs.txt b/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteInterfaceEventArgs.txt index 135abf81e..b184c765c 100644 --- a/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteInterfaceEventArgs.txt +++ b/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteInterfaceEventArgs.txt @@ -1,2 +1,2 @@ -public delegate int MyIGetCountForKeyHandler (string key); +public delegate int MyIGetCountForKeyHandler (string? key); diff --git a/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteInterfaceEventArgsWithParamArray.txt b/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteInterfaceEventArgsWithParamArray.txt index c937a0439..66e970b19 100644 --- a/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteInterfaceEventArgsWithParamArray.txt +++ b/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteInterfaceEventArgsWithParamArray.txt @@ -1,13 +1,13 @@ // event args for com.xamarin.android.MyListener.onDoSomething public partial class MyEventArgs : global::System.EventArgs { - public MyEventArgs (params Java.Lang.Object[] args) + public MyEventArgs (params Java.Lang.Object[]? args) { this.args = args; } - Java.Lang.Object[] args; - public Java.Lang.Object[] Args { + Java.Lang.Object[]? args; + public Java.Lang.Object[]? Args { get { return args; } } } diff --git a/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteInterfaceEventHandlerImpl.txt b/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteInterfaceEventHandlerImpl.txt index 20b467783..e89b39878 100644 --- a/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteInterfaceEventHandlerImpl.txt +++ b/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteInterfaceEventHandlerImpl.txt @@ -1,58 +1,59 @@ [global::Android.Runtime.Register ("mono/java/code/IMyInterfaceImplementor")] internal sealed partial class IMyInterfaceImplementor : global::Java.Lang.Object, IMyInterface { - object sender; + object sender; - public IMyInterfaceImplementor (object sender) - : base ( - global::Android.Runtime.JNIEnv.StartCreateInstance ("mono/java/code/IMyInterfaceImplementor", "()V"), - JniHandleOwnership.TransferLocalRef) - { - global::Android.Runtime.JNIEnv.FinishCreateInstance (this.PeerReference, "()V"); - this.sender = sender; - } + public IMyInterfaceImplementor (object sender) + : base ( + global::Android.Runtime.JNIEnv.StartCreateInstance ("mono/java/code/IMyInterfaceImplementor", "()V"), + JniHandleOwnership.TransferLocalRef) + { + global::Android.Runtime.JNIEnv.FinishCreateInstance (this.PeerReference, "()V"); + this.sender = sender; + } #pragma warning disable 0649 - public MyIGetCountForKeyHandler GetCountForKeyHandler; + public MyIGetCountForKeyHandler? GetCountForKeyHandler; #pragma warning restore 0649 - public int GetCountForKey (string key) - { - var __h = GetCountForKeyHandler; - return __h != null ? __h (key) : default (int); - } + public int GetCountForKey (string? key) + { + var __h = GetCountForKeyHandler; + return __h != null ? __h (key) : default (int); + } #pragma warning disable 0649 - public MyIKeyHandler KeyHandler; + public MyIKeyHandler? KeyHandler; #pragma warning restore 0649 - public string Key () - { - var __h = KeyHandler; - return __h != null ? __h () : default (string); - } + public string? Key () + { + var __h = KeyHandler; + return __h != null ? __h () : default (string?); + } #pragma warning disable 0649 - public EventHandler StaticMethodHandler; + public EventHandler? StaticMethodHandler; #pragma warning restore 0649 - public void StaticMethod () - { - var __h = StaticMethodHandler; - if (__h != null) - __h (sender, new EventArgs ()); - } + public void StaticMethod () + { + var __h = StaticMethodHandler; + if (__h != null) + __h (sender, new EventArgs ()); + } #pragma warning disable 0649 - public EventHandler AbstractMethodHandler; + public EventHandler? AbstractMethodHandler; #pragma warning restore 0649 - public void AbstractMethod () - { - var __h = AbstractMethodHandler; - if (__h != null) - __h (sender, new EventArgs ()); - } - - internal static bool __IsEmpty (IMyInterfaceImplementor value) - { - return value.GetCountForKeyHandler == null && value.KeyHandler == null && value.StaticMethodHandler == null && value.AbstractMethodHandler == null; - } + public void AbstractMethod () + { + var __h = AbstractMethodHandler; + if (__h != null) + __h (sender, new EventArgs ()); + } + + internal static bool __IsEmpty (IMyInterfaceImplementor value) + { + return value.GetCountForKeyHandler == null && value.KeyHandler == null && value.StaticMethodHandler == null && value.AbstractMethodHandler == null; + } } + diff --git a/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteInterfaceEventHandlerImplContent.txt b/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteInterfaceEventHandlerImplContent.txt index a190fc776..e6011b413 100644 --- a/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteInterfaceEventHandlerImplContent.txt +++ b/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteInterfaceEventHandlerImplContent.txt @@ -1,8 +1,8 @@ #pragma warning disable 0649 - public MyIGetCountForKeyHandler GetCountForKeyHandler; + public MyIGetCountForKeyHandler? GetCountForKeyHandler; #pragma warning restore 0649 - public int GetCountForKey (string key) + public int GetCountForKey (string? key) { var __h = GetCountForKeyHandler; return __h != null ? __h (key) : default (int); diff --git a/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteKotlinUnsignedArrayTypeMethodsClass.txt b/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteKotlinUnsignedArrayTypeMethodsClass.txt index 802050719..b2f007f96 100644 --- a/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteKotlinUnsignedArrayTypeMethodsClass.txt +++ b/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteKotlinUnsignedArrayTypeMethodsClass.txt @@ -8,7 +8,7 @@ public partial class MyClass { } // Metadata.xml XPath method reference: path="/api/package[@name='java.code']/class[@name='MyClass']/method[@name='Echo' and count(parameter)=1 and parameter[1][@type='uint[]']]" - public unsafe System.Collections.Generic.IList Echo (uint[] value) + public unsafe Java.Interop.JavaInt32Array? Echo (uint[]? value) { const string __id = "Echo.([I)[I"; var native_value = global::Java.Interop.JniEnvironment.Arrays.CreateMarshalInt32Array (value); @@ -18,7 +18,7 @@ public partial class MyClass { var __rm = _members.InstanceMethods.InvokeAbstractObjectMethod (__id, this, __args); return global::Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue(ref __rm, JniObjectReferenceOptions.CopyAndDispose); } finally { - if (value != null) { + if (native_value != null) { native_value.DisposeUnlessReferenced (); } global::System.GC.KeepAlive (value); @@ -26,7 +26,7 @@ public partial class MyClass { } // Metadata.xml XPath method reference: path="/api/package[@name='java.code']/class[@name='MyClass']/method[@name='Echo' and count(parameter)=1 and parameter[1][@type='ushort[]']]" - public unsafe System.Collections.Generic.IList Echo (ushort[] value) + public unsafe Java.Interop.JavaInt16Array? Echo (ushort[]? value) { const string __id = "Echo.([S)[S"; var native_value = global::Java.Interop.JniEnvironment.Arrays.CreateMarshalInt16Array (value); @@ -36,7 +36,7 @@ public partial class MyClass { var __rm = _members.InstanceMethods.InvokeAbstractObjectMethod (__id, this, __args); return global::Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue(ref __rm, JniObjectReferenceOptions.CopyAndDispose); } finally { - if (value != null) { + if (native_value != null) { native_value.DisposeUnlessReferenced (); } global::System.GC.KeepAlive (value); @@ -44,7 +44,7 @@ public partial class MyClass { } // Metadata.xml XPath method reference: path="/api/package[@name='java.code']/class[@name='MyClass']/method[@name='Echo' and count(parameter)=1 and parameter[1][@type='ulong[]']]" - public unsafe System.Collections.Generic.IList Echo (ulong[] value) + public unsafe Java.Interop.JavaInt64Array? Echo (ulong[]? value) { const string __id = "Echo.([J)[J"; var native_value = global::Java.Interop.JniEnvironment.Arrays.CreateMarshalInt64Array (value); @@ -54,7 +54,7 @@ public partial class MyClass { var __rm = _members.InstanceMethods.InvokeAbstractObjectMethod (__id, this, __args); return global::Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue(ref __rm, JniObjectReferenceOptions.CopyAndDispose); } finally { - if (value != null) { + if (native_value != null) { native_value.DisposeUnlessReferenced (); } global::System.GC.KeepAlive (value); @@ -62,7 +62,7 @@ public partial class MyClass { } // Metadata.xml XPath method reference: path="/api/package[@name='java.code']/class[@name='MyClass']/method[@name='Echo' and count(parameter)=1 and parameter[1][@type='ubyte[]']]" - public unsafe System.Collections.Generic.IList Echo (byte[] value) + public unsafe Java.Interop.JavaSByteArray? Echo (byte[]? value) { const string __id = "Echo.([B)[B"; var native_value = global::Java.Interop.JniEnvironment.Arrays.CreateMarshalSByteArray (value); @@ -72,7 +72,7 @@ public partial class MyClass { var __rm = _members.InstanceMethods.InvokeAbstractObjectMethod (__id, this, __args); return global::Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue(ref __rm, JniObjectReferenceOptions.CopyAndDispose); } finally { - if (value != null) { + if (native_value != null) { native_value.DisposeUnlessReferenced (); } global::System.GC.KeepAlive (value); diff --git a/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteKotlinUnsignedArrayTypePropertiesClass.txt b/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteKotlinUnsignedArrayTypePropertiesClass.txt index bac18d103..67df154c8 100644 --- a/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteKotlinUnsignedArrayTypePropertiesClass.txt +++ b/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteKotlinUnsignedArrayTypePropertiesClass.txt @@ -7,7 +7,7 @@ public partial class MyClass { { } - public unsafe System.Collections.Generic.IList UIntProp { + public unsafe Java.Interop.JavaInt32Array? UIntProp { // Metadata.xml XPath method reference: path="/api/package[@name='java.code']/class[@name='MyClass']/method[@name='get_UIntProp' and count(parameter)=0]" get { const string __id = "get_UIntProp.()[I"; @@ -26,7 +26,7 @@ public partial class MyClass { __args [0] = new JniArgumentValue (native_value); _members.InstanceMethods.InvokeAbstractVoidMethod (__id, this, __args); } finally { - if (value != null) { + if (native_value != null) { native_value.DisposeUnlessReferenced (); } global::System.GC.KeepAlive (value); @@ -34,7 +34,7 @@ public partial class MyClass { } } - public unsafe System.Collections.Generic.IList UShortProp { + public unsafe Java.Interop.JavaInt16Array? UShortProp { // Metadata.xml XPath method reference: path="/api/package[@name='java.code']/class[@name='MyClass']/method[@name='get_UShortProp' and count(parameter)=0]" get { const string __id = "get_UShortProp.()[S"; @@ -53,7 +53,7 @@ public partial class MyClass { __args [0] = new JniArgumentValue (native_value); _members.InstanceMethods.InvokeAbstractVoidMethod (__id, this, __args); } finally { - if (value != null) { + if (native_value != null) { native_value.DisposeUnlessReferenced (); } global::System.GC.KeepAlive (value); @@ -61,7 +61,7 @@ public partial class MyClass { } } - public unsafe System.Collections.Generic.IList ULongProp { + public unsafe Java.Interop.JavaInt64Array? ULongProp { // Metadata.xml XPath method reference: path="/api/package[@name='java.code']/class[@name='MyClass']/method[@name='get_ULongProp' and count(parameter)=0]" get { const string __id = "get_ULongProp.()[J"; @@ -80,7 +80,7 @@ public partial class MyClass { __args [0] = new JniArgumentValue (native_value); _members.InstanceMethods.InvokeAbstractVoidMethod (__id, this, __args); } finally { - if (value != null) { + if (native_value != null) { native_value.DisposeUnlessReferenced (); } global::System.GC.KeepAlive (value); @@ -88,7 +88,7 @@ public partial class MyClass { } } - public unsafe System.Collections.Generic.IList UByteProp { + public unsafe Java.Interop.JavaSByteArray? UByteProp { // Metadata.xml XPath method reference: path="/api/package[@name='java.code']/class[@name='MyClass']/method[@name='get_UByteProp' and count(parameter)=0]" get { const string __id = "get_UByteProp.()[B"; @@ -107,7 +107,7 @@ public partial class MyClass { __args [0] = new JniArgumentValue (native_value); _members.InstanceMethods.InvokeAbstractVoidMethod (__id, this, __args); } finally { - if (value != null) { + if (native_value != null) { native_value.DisposeUnlessReferenced (); } global::System.GC.KeepAlive (value); diff --git a/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WritePropertyAbstractDeclaration.txt b/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WritePropertyAbstractDeclaration.txt index ba0d8f006..b04f48c67 100644 --- a/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WritePropertyAbstractDeclaration.txt +++ b/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WritePropertyAbstractDeclaration.txt @@ -1,4 +1,4 @@ -static Delegate cb_get_MyProperty; +static Delegate? cb_get_MyProperty; #pragma warning disable 0169 static Delegate Getget_MyPropertyHandler () { @@ -9,12 +9,12 @@ static Delegate Getget_MyPropertyHandler () static int n_get_MyProperty (IntPtr jnienv, IntPtr native__this) { - var __this = global::Java.Lang.Object.GetObject (jnienv, native__this, JniHandleOwnership.DoNotTransfer); + var __this = global::Java.Lang.Object.GetObject (jnienv, native__this, JniHandleOwnership.DoNotTransfer)!; return __this.MyProperty; } #pragma warning restore 0169 -static Delegate cb_set_MyProperty_I; +static Delegate? cb_set_MyProperty_I; #pragma warning disable 0169 static Delegate Getset_MyProperty_IHandler () { @@ -25,7 +25,7 @@ static Delegate Getset_MyProperty_IHandler () static void n_set_MyProperty_I (IntPtr jnienv, IntPtr native__this, int value) { - var __this = global::Java.Lang.Object.GetObject (jnienv, native__this, JniHandleOwnership.DoNotTransfer); + var __this = global::Java.Lang.Object.GetObject (jnienv, native__this, JniHandleOwnership.DoNotTransfer)!; __this.MyProperty = value; } #pragma warning restore 0169 diff --git a/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WritePropertyCallbacks.txt b/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WritePropertyCallbacks.txt index 3ee57d568..fc4f51432 100644 --- a/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WritePropertyCallbacks.txt +++ b/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WritePropertyCallbacks.txt @@ -1,4 +1,4 @@ -static Delegate cb_get_MyProperty; +static Delegate? cb_get_MyProperty; #pragma warning disable 0169 static Delegate Getget_MyPropertyHandler () { @@ -9,12 +9,12 @@ static Delegate Getget_MyPropertyHandler () static int n_get_MyProperty (IntPtr jnienv, IntPtr native__this) { - var __this = global::Java.Lang.Object.GetObject (jnienv, native__this, JniHandleOwnership.DoNotTransfer); + var __this = global::Java.Lang.Object.GetObject (jnienv, native__this, JniHandleOwnership.DoNotTransfer)!; return __this.MyProperty; } #pragma warning restore 0169 -static Delegate cb_set_MyProperty_I; +static Delegate? cb_set_MyProperty_I; #pragma warning disable 0169 static Delegate Getset_MyProperty_IHandler () { @@ -25,7 +25,7 @@ static Delegate Getset_MyProperty_IHandler () static void n_set_MyProperty_I (IntPtr jnienv, IntPtr native__this, int value) { - var __this = global::Java.Lang.Object.GetObject (jnienv, native__this, JniHandleOwnership.DoNotTransfer); + var __this = global::Java.Lang.Object.GetObject (jnienv, native__this, JniHandleOwnership.DoNotTransfer)!; __this.MyProperty = value; } #pragma warning restore 0169 diff --git a/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WritePropertyInvoker.txt b/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WritePropertyInvoker.txt index d199cb12d..115683b9d 100644 --- a/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WritePropertyInvoker.txt +++ b/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WritePropertyInvoker.txt @@ -1,48 +1,49 @@ -static Delegate cb_get_MyProperty; +static Delegate? cb_get_MyProperty; #pragma warning disable 0169 static Delegate Getget_MyPropertyHandler () { - if (cb_get_MyProperty == null) - cb_get_MyProperty = JNINativeWrapper.CreateDelegate ((_JniMarshal_PP_I) n_get_MyProperty); - return cb_get_MyProperty; + if (cb_get_MyProperty == null) + cb_get_MyProperty = JNINativeWrapper.CreateDelegate ((_JniMarshal_PP_I) n_get_MyProperty); + return cb_get_MyProperty; } static int n_get_MyProperty (IntPtr jnienv, IntPtr native__this) { - var __this = global::Java.Lang.Object.GetObject (jnienv, native__this, JniHandleOwnership.DoNotTransfer); - return __this.MyProperty; + var __this = global::Java.Lang.Object.GetObject (jnienv, native__this, JniHandleOwnership.DoNotTransfer)!; + return __this.MyProperty; } #pragma warning restore 0169 -static Delegate cb_set_MyProperty_I; +static Delegate? cb_set_MyProperty_I; #pragma warning disable 0169 static Delegate Getset_MyProperty_IHandler () { - if (cb_set_MyProperty_I == null) - cb_set_MyProperty_I = JNINativeWrapper.CreateDelegate ((_JniMarshal_PPI_V) n_set_MyProperty_I); - return cb_set_MyProperty_I; + if (cb_set_MyProperty_I == null) + cb_set_MyProperty_I = JNINativeWrapper.CreateDelegate ((_JniMarshal_PPI_V) n_set_MyProperty_I); + return cb_set_MyProperty_I; } static void n_set_MyProperty_I (IntPtr jnienv, IntPtr native__this, int value) { - var __this = global::Java.Lang.Object.GetObject (jnienv, native__this, JniHandleOwnership.DoNotTransfer); - __this.MyProperty = value; + var __this = global::Java.Lang.Object.GetObject (jnienv, native__this, JniHandleOwnership.DoNotTransfer)!; + __this.MyProperty = value; } #pragma warning restore 0169 IntPtr id_get_MyProperty; IntPtr id_set_MyProperty_I; public unsafe int MyProperty { - get { - if (id_get_MyProperty == IntPtr.Zero) - id_get_MyProperty = JNIEnv.GetMethodID (class_ref, "get_MyProperty", "()I"); - return JNIEnv.CallIntMethod (this.PeerReference, id_get_MyProperty); - } - set { - if (id_set_MyProperty_I == IntPtr.Zero) - id_set_MyProperty_I = JNIEnv.GetMethodID (class_ref, "set_MyProperty", "(I)V"); - JValue* __args = stackalloc JValue [1]; - __args [0] = new JValue (value); - JNIEnv.CallVoidMethod (this.PeerReference, id_set_MyProperty_I, __args); - } + get { + if (id_get_MyProperty == IntPtr.Zero) + id_get_MyProperty = JNIEnv.GetMethodID (class_ref, "get_MyProperty", "()I"); + return JNIEnv.CallIntMethod (this.PeerReference, id_get_MyProperty); + } + set { + if (id_set_MyProperty_I == IntPtr.Zero) + id_set_MyProperty_I = JNIEnv.GetMethodID (class_ref, "set_MyProperty", "(I)V"); + JValue* __args = stackalloc JValue [1]; + __args [0] = new JValue (value); + JNIEnv.CallVoidMethod (this.PeerReference, id_set_MyProperty_I, __args); + } } + diff --git a/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WritePropertyStringVariant.txt b/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WritePropertyStringVariant.txt index 639a5fc22..72025a88f 100644 --- a/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WritePropertyStringVariant.txt +++ b/tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WritePropertyStringVariant.txt @@ -1,4 +1,4 @@ -public string MyProperty { +public string? MyProperty { get { return MyProperty == null ? null : MyProperty.ToString (); } set { var jls = value == null ? null : new global::Java.Lang.String (value); diff --git a/tests/generator-Tests/Unit-Tests/CodeGeneratorTestBase.cs b/tests/generator-Tests/Unit-Tests/CodeGeneratorTestBase.cs index 07faad14f..e39403f9f 100644 --- a/tests/generator-Tests/Unit-Tests/CodeGeneratorTestBase.cs +++ b/tests/generator-Tests/Unit-Tests/CodeGeneratorTestBase.cs @@ -83,16 +83,40 @@ protected List ParseApiDefinition (string xml) return gens; } - protected void AssertExpected (string testName, string actual) + protected void AssertTargetedExpected (string testName, string actual) { + WriteActualContents (testName, actual); + + var expected = GetTargetedExpected (testName); + Assert.AreEqual (expected, actual.NormalizeLineEndings ()); + } + + protected void AssertOriginalExpected (string testName, string actual) + { + WriteActualContents (testName, actual); + var expected = GetOriginalExpected (testName); Assert.AreEqual (expected.NormalizeLineEndings (), actual.NormalizeLineEndings (), GetAssertionMessage ($"Test `{testName}` failed.", expected, actual)); } - protected void AssertTargetExpected (string testName, string actual) + protected void WriteActualContents (string testName, string contents) { - var expected = GetOriginalTargetExpected (testName); + var t = this.TargetedDirectoryOverride; + if (string.IsNullOrEmpty (t)) + t = this.CommonDirectoryOverride; + if (string.IsNullOrEmpty (t)) + t = GetType ().Name; + var dir = Path.Combine ("__jonp", t); + Directory.CreateDirectory (dir); + File.WriteAllText (Path.Combine (dir, testName + ".txt"), contents); + } + + protected void AssertOriginalTargetExpected (string testName, string actual) + { + WriteActualContents (testName, actual); + + var expected = GetOriginalTargetExpected (testName); Assert.AreEqual (expected.NormalizeLineEndings (), actual.NormalizeLineEndings (), GetAssertionMessage ($"Test `{testName}` failed.", expected, actual)); } diff --git a/tests/generator-Tests/Unit-Tests/CodeGeneratorTests.cs b/tests/generator-Tests/Unit-Tests/CodeGeneratorTests.cs index fe03bd4b8..560f6b850 100644 --- a/tests/generator-Tests/Unit-Tests/CodeGeneratorTests.cs +++ b/tests/generator-Tests/Unit-Tests/CodeGeneratorTests.cs @@ -29,7 +29,7 @@ public void WriteKotlinUnsignedTypeMethodsClass () generator.WriteType (@class, string.Empty, new GenerationInfo ("", "", "MyAssembly")); generator.Context.ContextTypes.Pop (); - AssertTargetExpected (nameof (WriteKotlinUnsignedTypeMethodsClass), writer.ToString ()); + AssertOriginalTargetExpected (nameof (WriteKotlinUnsignedTypeMethodsClass), writer.ToString ()); } [Test] @@ -52,7 +52,7 @@ public void WriteKotlinUnsignedTypePropertiesClass () generator.WriteType (@class, string.Empty, new GenerationInfo ("", "", "MyAssembly")); generator.Context.ContextTypes.Pop (); - AssertTargetExpected (nameof (WriteKotlinUnsignedTypePropertiesClass), writer.ToString ()); + AssertOriginalTargetExpected (nameof (WriteKotlinUnsignedTypePropertiesClass), writer.ToString ()); } [Test] @@ -73,7 +73,7 @@ public void WriteKotlinUnsignedArrayTypeMethodsClass () generator.WriteType (@class, string.Empty, new GenerationInfo ("", "", "MyAssembly")); generator.Context.ContextTypes.Pop (); - AssertTargetExpected (nameof (WriteKotlinUnsignedArrayTypeMethodsClass), writer.ToString ()); + AssertOriginalTargetExpected (nameof (WriteKotlinUnsignedArrayTypeMethodsClass), writer.ToString ()); } [Test] @@ -96,7 +96,7 @@ public void WriteKotlinUnsignedArrayTypePropertiesClass () generator.WriteType (@class, string.Empty, new GenerationInfo ("", "", "MyAssembly")); generator.Context.ContextTypes.Pop (); - AssertTargetExpected (nameof (WriteKotlinUnsignedArrayTypePropertiesClass), writer.ToString ()); + AssertOriginalTargetExpected (nameof (WriteKotlinUnsignedArrayTypePropertiesClass), writer.ToString ()); } [Test] @@ -212,7 +212,7 @@ public void WriteDuplicateInterfaceEventArgs () generator.WriteType (iface, string.Empty, new GenerationInfo ("", "", "MyAssembly")); generator.Context.ContextTypes.Pop (); - AssertExpected (nameof (WriteDuplicateInterfaceEventArgs), writer.ToString ()); + AssertOriginalExpected (nameof (WriteDuplicateInterfaceEventArgs), writer.ToString ()); } [Test] @@ -259,6 +259,18 @@ class JavaInteropCodeGeneratorTests : AnyJavaInteropCodeGeneratorTests { protected override CodeGenerationTarget Target => CodeGenerationTarget.JavaInterop1; protected override string CommonDirectoryOverride => "JavaInterop1"; + + protected override CodeGenerationOptions CreateOptions () + { + var options = new CodeGenerationOptions { + CodeGenerationTarget = Target, + SupportDefaultInterfaceMethods = true, + SupportInterfaceConstants = true, + SupportNestedInterfaceTypes = true, + SupportNullableReferenceTypes = true, + }; + return options; + } } [TestFixture] @@ -341,7 +353,7 @@ public void WriteClassConstructors () generator.WriteClassConstructors (@class, string.Empty); generator.Context.ContextTypes.Pop (); - Assert.AreEqual (GetTargetedExpected (nameof (WriteClassConstructors)), writer.ToString ().NormalizeLineEndings ()); + AssertTargetedExpected (nameof (WriteClassConstructors), writer.ToString ()); } [Test] @@ -351,7 +363,7 @@ public void WriteClassHandle () generator.WriteClassHandle (@class, string.Empty, false); - Assert.AreEqual (GetTargetedExpected (nameof (WriteClassHandle)), writer.ToString ().NormalizeLineEndings ()); + AssertTargetedExpected (nameof (WriteClassHandle), writer.ToString ()); } [Test] @@ -363,7 +375,7 @@ public void WriteClassInvoker () generator.WriteClassInvoker (@class, string.Empty); generator.Context.ContextTypes.Pop (); - Assert.AreEqual (GetTargetedExpected (nameof (WriteClassInvoker)), writer.ToString ().NormalizeLineEndings ()); + AssertTargetedExpected (nameof (WriteClassInvoker), writer.ToString ()); } [Test] @@ -373,7 +385,7 @@ public void WriteClassInvokerHandle () generator.WriteClassInvokerHandle (@class, string.Empty, "Com.MyPackage.Foo"); - Assert.AreEqual (GetTargetedExpected (nameof (WriteClassInvokerHandle)), writer.ToString ().NormalizeLineEndings ()); + AssertTargetedExpected (nameof (WriteClassInvokerHandle), writer.ToString ()); } [Test] @@ -387,7 +399,7 @@ public void WriteClassInvokerMembers () generator.WriteClassInvokerMembers (@class, string.Empty, members); generator.Context.ContextTypes.Pop (); - Assert.AreEqual (GetTargetedExpected (nameof (WriteClassInvokerMembers)), writer.ToString ().NormalizeLineEndings ()); + AssertTargetedExpected (nameof (WriteClassInvokerMembers), writer.ToString ()); } [Test] @@ -401,7 +413,7 @@ public void WriteClassMethodInvokers () generator.WriteClassMethodInvokers (@class, @class.Methods, string.Empty, members, null); generator.Context.ContextTypes.Pop (); - Assert.AreEqual (GetTargetedExpected (nameof (WriteClassMethodInvokers)), writer.ToString ().NormalizeLineEndings ()); + AssertTargetedExpected (nameof (WriteClassMethodInvokers), writer.ToString ()); } [Test] @@ -415,7 +427,7 @@ public void WriteClassMethodInvokersWithSkips () generator.WriteClassMethodInvokers (@class, @class.Methods, string.Empty, members, null); generator.Context.ContextTypes.Pop (); - Assert.AreEqual (GetTargetedExpected (nameof (WriteClassMethodInvokersWithSkips)), writer.ToString ().NormalizeLineEndings ()); + AssertTargetedExpected (nameof (WriteClassMethodInvokersWithSkips), writer.ToString ()); } [Test] @@ -427,7 +439,7 @@ public void WriteClassMethods () generator.WriteClassMethods (@class, string.Empty); generator.Context.ContextTypes.Pop (); - Assert.AreEqual (GetTargetedExpected (nameof (WriteClassMethods)), writer.ToString ().NormalizeLineEndings ()); + AssertTargetedExpected (nameof (WriteClassMethods), writer.ToString ()); } [Test] @@ -439,7 +451,7 @@ public void WriteClassProperties () generator.WriteImplementedProperties (@class.Properties, string.Empty, @class.IsFinal, @class); generator.Context.ContextTypes.Pop (); - Assert.AreEqual (GetTargetedExpected (nameof (WriteClassProperties)), writer.ToString ().NormalizeLineEndings ()); + AssertTargetedExpected (nameof (WriteClassProperties), writer.ToString ()); } [Test] @@ -453,7 +465,7 @@ public void WriteClassPropertyInvokers () generator.WriteClassPropertyInvokers (@class, @class.Properties, string.Empty, members); generator.Context.ContextTypes.Pop (); - Assert.AreEqual (GetTargetedExpected (nameof (WriteClassPropertyInvokers)), writer.ToString ().NormalizeLineEndings ()); + AssertTargetedExpected (nameof (WriteClassPropertyInvokers), writer.ToString ()); } [Test] @@ -467,7 +479,7 @@ public void WriteClassPropertyInvokersWithSkips () generator.WriteClassPropertyInvokers (@class, @class.Properties, string.Empty, members); generator.Context.ContextTypes.Pop (); - Assert.AreEqual (GetTargetedExpected (nameof (WriteClassPropertyInvokersWithSkips)), writer.ToString ().NormalizeLineEndings ()); + AssertTargetedExpected (nameof (WriteClassPropertyInvokersWithSkips), writer.ToString ()); } [Test] @@ -480,7 +492,7 @@ public void WriteCtor () generator.WriteConstructor (ctor, string.Empty, true, @class); generator.Context.ContextTypes.Pop (); - Assert.AreEqual (GetTargetedExpected (nameof (WriteCtor)), writer.ToString ().NormalizeLineEndings ()); + AssertTargetedExpected (nameof (WriteCtor), writer.ToString ()); } [Test] @@ -496,7 +508,7 @@ public void WriteCtorDeprecated () generator.WriteConstructor (ctor, string.Empty, true, @class); generator.Context.ContextTypes.Pop (); - Assert.AreEqual (GetTargetedExpected (nameof (WriteCtorDeprecated)), writer.ToString ().NormalizeLineEndings ()); + AssertTargetedExpected (nameof (WriteCtorDeprecated), writer.ToString ()); } [Test] @@ -512,7 +524,7 @@ public void WriteCtorWithStringOverload () generator.WriteConstructor (ctor, string.Empty, true, @class); generator.Context.ContextTypes.Pop (); - Assert.AreEqual (GetTargetedExpected (nameof (WriteCtorWithStringOverload)), writer.ToString ().NormalizeLineEndings ()); + AssertTargetedExpected (nameof (WriteCtorWithStringOverload), writer.ToString ()); } [Test] @@ -558,7 +570,7 @@ public void WriteFieldConstant () Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList (), new CodeGeneratorContext ()), "field.Validate failed!"); generator.WriteField (field, string.Empty, @class); - Assert.AreEqual (GetTargetedExpected (nameof (WriteFieldConstant)), writer.ToString ().NormalizeLineEndings ()); + AssertTargetedExpected (nameof (WriteFieldConstant), writer.ToString ()); } [Test] @@ -570,7 +582,7 @@ public void WriteFieldConstantWithIntValue () Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList (), new CodeGeneratorContext ()), "field.Validate failed!"); generator.WriteField (field, string.Empty, @class); - Assert.AreEqual (GetTargetedExpected (nameof (WriteFieldConstantWithIntValue)), writer.ToString ().NormalizeLineEndings ()); + AssertTargetedExpected (nameof (WriteFieldConstantWithIntValue), writer.ToString ()); } [Test] @@ -582,7 +594,7 @@ public void WriteFieldConstantWithStringValue () Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList (), new CodeGeneratorContext ()), "field.Validate failed!"); generator.WriteField (field, string.Empty, @class); - Assert.AreEqual (GetTargetedExpected (nameof (WriteFieldConstantWithStringValue)), writer.ToString ().NormalizeLineEndings ()); + AssertTargetedExpected (nameof (WriteFieldConstantWithStringValue), writer.ToString ()); } [Test] @@ -594,7 +606,7 @@ public void WriteFieldGetBody () Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList (), new CodeGeneratorContext ()), "field.Validate failed!"); generator.WriteFieldGetBody (field, string.Empty, @class); - Assert.AreEqual (GetTargetedExpected (nameof (WriteFieldGetBody)), writer.ToString ().NormalizeLineEndings ()); + AssertTargetedExpected (nameof (WriteFieldGetBody), writer.ToString ()); } [Test] @@ -604,7 +616,7 @@ public void WriteFieldIdField () generator.WriteFieldIdField (field, string.Empty); - Assert.AreEqual (GetTargetedExpected (nameof (WriteFieldIdField)), writer.ToString ().NormalizeLineEndings ()); + AssertTargetedExpected (nameof (WriteFieldIdField), writer.ToString ()); } [Test] @@ -616,7 +628,7 @@ public void WriteFieldInt () Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList (), new CodeGeneratorContext ()), "field.Validate failed!"); generator.WriteField (field, string.Empty, @class); - Assert.AreEqual (GetTargetedExpected (nameof (WriteFieldInt)), writer.ToString ().NormalizeLineEndings ()); + AssertTargetedExpected (nameof (WriteFieldInt), writer.ToString ()); } [Test] @@ -628,7 +640,7 @@ public void WriteFieldSetBody () Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList (), new CodeGeneratorContext ()), "field.Validate failed!"); generator.WriteFieldSetBody (field, string.Empty, @class); - Assert.AreEqual (GetTargetedExpected (nameof (WriteFieldSetBody)), writer.ToString ().NormalizeLineEndings ()); + AssertTargetedExpected (nameof (WriteFieldSetBody), writer.ToString ()); } [Test] @@ -640,7 +652,7 @@ public void WriteFieldString () Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList (), new CodeGeneratorContext ()), "field.Validate failed!"); generator.WriteField (field, string.Empty, @class); - Assert.AreEqual (GetTargetedExpected (nameof (WriteFieldString)), writer.ToString ().NormalizeLineEndings ()); + AssertTargetedExpected (nameof (WriteFieldString), writer.ToString ()); } [Test] @@ -686,7 +698,7 @@ public void WriteInterfaceInvoker () generator.WriteInterfaceInvoker (iface, string.Empty); generator.Context.ContextTypes.Pop (); - AssertTargetExpected (nameof (WriteInterfaceInvoker), writer.ToString ()); + AssertTargetedExpected (nameof (WriteInterfaceInvoker), writer.ToString ()); } [Test] @@ -698,7 +710,7 @@ public void WriteInterfaceListenerEvent () generator.WriteInterfaceListenerEvent (iface, string.Empty, "MyName", "MyNameSpec", "MyMethodName", "MyFullDelegateName", true, "MyWrefSuffix", "Add", "Remove"); generator.Context.ContextTypes.Pop (); - AssertExpected (nameof (WriteInterfaceListenerEvent), writer.ToString ()); + AssertOriginalExpected (nameof (WriteInterfaceListenerEvent), writer.ToString ()); } [Test] @@ -710,7 +722,7 @@ public void WriteInterfaceListenerEventWithHandlerArgument () generator.WriteInterfaceListenerEvent (iface, string.Empty, "MyName", "MyNameSpec", "MyMethodName", "MyFullDelegateName", true, "MyWrefSuffix", "AddMyName", "RemoveMyName", true); generator.Context.ContextTypes.Pop (); - AssertExpected (nameof (WriteInterfaceListenerEventWithHandlerArgument), writer.ToString ()); + AssertOriginalExpected (nameof (WriteInterfaceListenerEventWithHandlerArgument), writer.ToString ()); } [Test] @@ -722,7 +734,7 @@ public void WriteInterfaceListenerProperty () generator.WriteInterfaceListenerProperty (iface, string.Empty, "MyName", "MyNameSpec", "MyMethodName", "MyConnectorFmt", "MyFullDelegateName"); generator.Context.ContextTypes.Pop (); - AssertExpected (nameof (WriteInterfaceListenerProperty), writer.ToString ()); + AssertOriginalExpected (nameof (WriteInterfaceListenerProperty), writer.ToString ()); } [Test] @@ -736,7 +748,7 @@ public void WriteInterfaceMethodInvokers () generator.WriteInterfaceMethodInvokers (iface, iface.Methods, string.Empty, members); generator.Context.ContextTypes.Pop (); - AssertExpected (nameof (WriteInterfaceMethodInvokers), writer.ToString ()); + AssertOriginalExpected (nameof (WriteInterfaceMethodInvokers), writer.ToString ()); } [Test] @@ -750,7 +762,7 @@ public void WriteInterfaceMethodInvokersWithSkips () generator.WriteInterfaceMethodInvokers (iface, iface.Methods, string.Empty, members); generator.Context.ContextTypes.Pop (); - AssertExpected (nameof (WriteInterfaceMethodInvokersWithSkips), writer.ToString ()); + AssertOriginalExpected (nameof (WriteInterfaceMethodInvokersWithSkips), writer.ToString ()); } [Test] @@ -762,7 +774,7 @@ public void WriteInterfaceMethods () generator.WriteInterfaceMethods (iface, string.Empty); generator.Context.ContextTypes.Pop (); - AssertExpected (nameof (WriteInterfaceMethods), writer.ToString ()); + AssertOriginalExpected (nameof (WriteInterfaceMethods), writer.ToString ()); } [Test] @@ -774,7 +786,7 @@ public void WriteInterfaceProperties () generator.WriteInterfaceProperties (iface, string.Empty); generator.Context.ContextTypes.Pop (); - AssertExpected (nameof (WriteInterfaceProperties), writer.ToString ()); + AssertOriginalExpected (nameof (WriteInterfaceProperties), writer.ToString ()); } [Test] @@ -788,7 +800,7 @@ public void WriteInterfacePropertyInvokers () generator.WriteInterfacePropertyInvokers (iface, iface.Properties, string.Empty, members); generator.Context.ContextTypes.Pop (); - AssertExpected (nameof (WriteInterfacePropertyInvokers), writer.ToString ()); + AssertOriginalExpected (nameof (WriteInterfacePropertyInvokers), writer.ToString ()); } [Test] @@ -802,7 +814,7 @@ public void WriteInterfacePropertyInvokersWithSkips () generator.WriteInterfacePropertyInvokers (iface, iface.Properties, string.Empty, members); generator.Context.ContextTypes.Pop (); - AssertExpected (nameof (WriteInterfacePropertyInvokersWithSkips), writer.ToString ()); + AssertOriginalExpected (nameof (WriteInterfacePropertyInvokersWithSkips), writer.ToString ()); } [Test] @@ -814,7 +826,7 @@ public void WriteMethodAbstractWithVoidReturn () Assert.IsTrue (method.Validate (options, new GenericParameterDefinitionList (), new CodeGeneratorContext ()), "method.Validate failed!"); generator.WriteMethod (method, string.Empty, @class, true); - AssertTargetExpected (nameof (WriteMethodAbstractWithVoidReturn), writer.ToString ()); + AssertTargetedExpected (nameof (WriteMethodAbstractWithVoidReturn), writer.ToString ()); } [Test] @@ -826,7 +838,7 @@ public void WriteMethodAsyncifiedWithIntReturn () Assert.IsTrue (method.Validate (options, new GenericParameterDefinitionList (), new CodeGeneratorContext ()), "method.Validate failed!"); generator.WriteMethod (method, string.Empty, @class, true); - AssertTargetExpected (nameof (WriteMethodAsyncifiedWithIntReturn), writer.ToString ()); + AssertTargetedExpected (nameof (WriteMethodAsyncifiedWithIntReturn), writer.ToString ()); } [Test] @@ -838,7 +850,7 @@ public void WriteMethodAsyncifiedWithVoidReturn () Assert.IsTrue (method.Validate (options, new GenericParameterDefinitionList (), new CodeGeneratorContext ()), "method.Validate failed!"); generator.WriteMethod (method, string.Empty, @class, true); - AssertTargetExpected (nameof (WriteMethodAsyncifiedWithVoidReturn), writer.ToString ()); + AssertTargetedExpected (nameof (WriteMethodAsyncifiedWithVoidReturn), writer.ToString ()); } [Test] @@ -850,7 +862,7 @@ public void WriteMethodBody () Assert.IsTrue (method.Validate (options, new GenericParameterDefinitionList (), new CodeGeneratorContext ()), "method.Validate failed!"); generator.WriteMethodBody (method, string.Empty, @class); - AssertTargetExpected (nameof (WriteMethodBody), writer.ToString ()); + AssertTargetedExpected (nameof (WriteMethodBody), writer.ToString ()); } [Test] @@ -862,7 +874,7 @@ public void WriteMethodFinalWithVoidReturn () Assert.IsTrue (method.Validate (options, new GenericParameterDefinitionList (), new CodeGeneratorContext ()), "method.Validate failed!"); generator.WriteMethod (method, string.Empty, @class, true); - AssertTargetExpected (nameof (WriteMethodFinalWithVoidReturn), writer.ToString ()); + AssertTargetedExpected (nameof (WriteMethodFinalWithVoidReturn), writer.ToString ()); } [Test] @@ -873,7 +885,7 @@ public void WriteMethodIdField () generator.WriteMethodIdField (method, string.Empty); - AssertTargetExpected (nameof (WriteMethodIdField), writer.ToString ()); + AssertTargetedExpected (nameof (WriteMethodIdField), writer.ToString ()); } [Test] @@ -885,7 +897,7 @@ public void WriteMethodProtected () Assert.IsTrue (method.Validate (options, new GenericParameterDefinitionList (), new CodeGeneratorContext ()), "method.Validate failed!"); generator.WriteMethod (method, string.Empty, @class, true); - AssertTargetExpected (nameof (WriteMethodProtected), writer.ToString ()); + AssertTargetedExpected (nameof (WriteMethodProtected), writer.ToString ()); } [Test] @@ -897,7 +909,7 @@ public void WriteMethodStaticWithVoidReturn () Assert.IsTrue (method.Validate (options, new GenericParameterDefinitionList (), new CodeGeneratorContext ()), "method.Validate failed!"); generator.WriteMethod (method, string.Empty, @class, true); - AssertTargetExpected (nameof (WriteMethodStaticWithVoidReturn), writer.ToString ()); + AssertTargetedExpected (nameof (WriteMethodStaticWithVoidReturn), writer.ToString ()); } [Test] @@ -909,7 +921,7 @@ public void WriteMethodWithIntReturn () Assert.IsTrue (method.Validate (options, new GenericParameterDefinitionList (), new CodeGeneratorContext ()), "method.Validate failed!"); generator.WriteMethod (method, string.Empty, @class, true); - AssertTargetExpected (nameof (WriteMethodWithIntReturn), writer.ToString ()); + AssertTargetedExpected (nameof (WriteMethodWithIntReturn), writer.ToString ()); } [Test] @@ -921,7 +933,7 @@ public void WriteMethodWithStringReturn () Assert.IsTrue (method.Validate (options, new GenericParameterDefinitionList (), new CodeGeneratorContext ()), "method.Validate failed!"); generator.WriteMethod (method, string.Empty, @class, true); - AssertTargetExpected (nameof (WriteMethodWithStringReturn), writer.ToString ()); + AssertTargetedExpected (nameof (WriteMethodWithStringReturn), writer.ToString ()); } [Test] @@ -933,7 +945,7 @@ public void WriteMethodWithVoidReturn () Assert.IsTrue (method.Validate (options, new GenericParameterDefinitionList (), new CodeGeneratorContext ()), "method.Validate failed!"); generator.WriteMethod (method, string.Empty, @class, true); - Assert.AreEqual (GetTargetedExpected (nameof (WriteMethodWithVoidReturn)), writer.ToString ().NormalizeLineEndings ()); + AssertTargetedExpected (nameof (WriteMethodWithVoidReturn), writer.ToString ()); } [Test] @@ -992,7 +1004,7 @@ public void WriteInterfaceDeclaration () generator.WriteInterfaceDeclaration (iface, string.Empty, new GenerationInfo (null, null, null)); generator.Context.ContextTypes.Pop (); - Assert.AreEqual (GetTargetedExpected (nameof (WriteInterfaceDeclaration)), writer.ToString ().NormalizeLineEndings ()); + AssertTargetedExpected (nameof (WriteInterfaceDeclaration), writer.ToString ()); } [Test] @@ -1002,7 +1014,7 @@ public void WriteProperty () generator.WriteProperty (@class.Properties.First (), @class, string.Empty); - Assert.AreEqual (GetTargetedExpected (nameof (WriteProperty)), writer.ToString ().NormalizeLineEndings ()); + AssertTargetedExpected (nameof (WriteProperty), writer.ToString ()); } } @@ -1025,7 +1037,7 @@ public void WriteClass () generator.WriteType (@class, string.Empty, new GenerationInfo ("", "", "MyAssembly")); generator.Context.ContextTypes.Pop (); - AssertTargetExpected (nameof (WriteClass), writer.ToString ()); + AssertTargetedExpected (nameof (WriteClass), writer.ToString ()); } [Test] @@ -1050,7 +1062,7 @@ public void WriteInterface () generator.WriteType (iface, string.Empty, gen_info); generator.Context.ContextTypes.Pop (); - AssertTargetExpected (nameof (WriteInterface), writer.ToString ()); + AssertTargetedExpected (nameof (WriteInterface), writer.ToString ()); } [Test] @@ -1074,6 +1086,8 @@ public void WriteInterfaceEventArgs () generator.WriteInterfaceEventArgs (iface, iface.Methods [0], string.Empty); generator.Context.ContextTypes.Pop (); + WriteActualContents (nameof (WriteInterfaceEventArgs), writer.ToString ()); + Assert.AreEqual (GetExpected (nameof (WriteInterfaceEventArgs)), writer.ToString ().NormalizeLineEndings ()); } @@ -1100,6 +1114,8 @@ public void WriteInterfaceEventArgsWithParamArray () generator.WriteInterfaceEventArgs (iface as InterfaceGen, iface.Methods [0], string.Empty); generator.Context.ContextTypes.Pop (); + WriteActualContents (nameof (WriteInterfaceEventArgsWithParamArray), writer.ToString ()); + Assert.AreEqual (GetExpected (nameof (WriteInterfaceEventArgsWithParamArray)), writer.ToString ().NormalizeLineEndings ()); } @@ -1112,7 +1128,7 @@ public void WriteInterfaceEventHandler () generator.WriteInterfaceEventHandler (iface, string.Empty); generator.Context.ContextTypes.Pop (); - AssertExpected (nameof (WriteInterfaceEventHandler), writer.ToString ()); + AssertOriginalExpected (nameof (WriteInterfaceEventHandler), writer.ToString ()); } [Test] @@ -1124,7 +1140,7 @@ public void WriteInterfaceEventHandlerImpl () generator.WriteInterfaceEventHandlerImpl (iface, string.Empty); generator.Context.ContextTypes.Pop (); - AssertExpected (nameof (WriteInterfaceEventHandlerImpl), writer.ToString ()); + AssertOriginalExpected (nameof (WriteInterfaceEventHandlerImpl), writer.ToString ()); } [Test] @@ -1139,7 +1155,7 @@ public void WriteInterfaceEventHandlerImplContent () Assert.AreEqual (1, handlers.Count); Assert.AreEqual ("GetCountForKey", handlers [0]); - AssertExpected (nameof (WriteInterfaceEventHandlerImplContent), writer.ToString ()); + AssertOriginalExpected (nameof (WriteInterfaceEventHandlerImplContent), writer.ToString ()); } [Test] @@ -1149,7 +1165,7 @@ public void WriteParameterListCallArgs () generator.WriteParameterListCallArgs (list, string.Empty, false); - AssertTargetExpected (nameof (WriteParameterListCallArgs), writer.ToString ()); + AssertTargetedExpected (nameof (WriteParameterListCallArgs), writer.ToString ()); } [Test] @@ -1159,7 +1175,7 @@ public void WriteParameterListCallArgsForInvoker () generator.WriteParameterListCallArgs (list, string.Empty, true); - AssertTargetExpected (nameof (WriteParameterListCallArgsForInvoker), writer.ToString ()); + AssertTargetedExpected (nameof (WriteParameterListCallArgsForInvoker), writer.ToString ()); } [Test] @@ -1169,7 +1185,7 @@ public void WritePropertyAbstractDeclaration () generator.WritePropertyAbstractDeclaration (@class.Properties.First (), string.Empty, @class); - AssertExpected (nameof (WritePropertyAbstractDeclaration), writer.ToString ()); + AssertOriginalExpected (nameof (WritePropertyAbstractDeclaration), writer.ToString ()); } [Test] @@ -1179,7 +1195,7 @@ public void WritePropertyCallbacks () generator.WritePropertyCallbacks (@class.Properties.First (), string.Empty, @class); - AssertExpected (nameof (WritePropertyCallbacks), writer.ToString ()); + AssertOriginalExpected (nameof (WritePropertyCallbacks), writer.ToString ()); } [Test] @@ -1189,7 +1205,7 @@ public void WritePropertyDeclaration () generator.WritePropertyDeclaration (@class.Properties.First (), string.Empty, @class, "ObjectAdapter"); - AssertExpected (nameof (WritePropertyDeclaration), writer.ToString ()); + AssertOriginalExpected (nameof (WritePropertyDeclaration), writer.ToString ()); } [Test] @@ -1199,7 +1215,7 @@ public void WritePropertyStringVariant () generator.WritePropertyStringVariant (@class.Properties.First (), string.Empty); - AssertExpected (nameof (WritePropertyStringVariant), writer.ToString ()); + AssertOriginalExpected (nameof (WritePropertyStringVariant), writer.ToString ()); } [Test] @@ -1211,7 +1227,7 @@ public void WritePropertyInvoker () generator.WritePropertyInvoker (@class.Properties.First (), string.Empty, @class); generator.Context.ContextTypes.Pop (); - AssertExpected (nameof (WritePropertyInvoker), writer.ToString ()); + AssertOriginalExpected (nameof (WritePropertyInvoker), writer.ToString ()); } [Test] @@ -1296,7 +1312,9 @@ public void WriteBoundMethodAbstractDeclarationWithGenericReturn () "); var declIface = gens.OfType ().Single (c => c.Name == "IFlowIterator"); - var declClass = declIface.NestedTypes.OfType ().Single (c => c.Name == "FlowIteratorRangeIterator"); + var declClass = options.SupportNestedInterfaceTypes + ? declIface.NestedTypes.OfType ().Single (c => c.Name == "RangeIterator") + : declIface.NestedTypes.OfType ().Single (c => c.Name == "FlowIteratorRangeIterator"); var method = declClass.Methods.Single (); var bmad = new BoundMethodAbstractDeclaration (declClass, method, options, null); @@ -1304,7 +1322,12 @@ public void WriteBoundMethodAbstractDeclarationWithGenericReturn () bmad.Write (source_writer); - var expected = @"Java.Lang.Object Com.Example.FlowIteratorRangeIterator.Next () + var expected = options.SupportNestedInterfaceTypes + ? @"Java.Lang.Object Com.Example.IFlowIterator.RangeIterator.Next () + { + throw new NotImplementedException (); + }" + : @"Java.Lang.Object Com.Example.FlowIteratorRangeIterator.Next () { throw new NotImplementedException (); }"; diff --git a/tests/generator-Tests/Unit-Tests/SupportTypes.cs b/tests/generator-Tests/Unit-Tests/SupportTypes.cs index ec1253182..f774e942d 100644 --- a/tests/generator-Tests/Unit-Tests/SupportTypes.cs +++ b/tests/generator-Tests/Unit-Tests/SupportTypes.cs @@ -221,14 +221,16 @@ public static TestClass CreateClass (string className, CodeGenerationOptions opt var ctor_name = className.Contains ('.') ? className.Substring (className.LastIndexOf ('.') + 1) : className; @class.Ctors.Add (CreateConstructor (@class, ctor_name, options)); - @class.Ctors.Add (CreateConstructor (@class, ctor_name, options, new Parameter ("p0", "java.lang.String", "string", false))); + @class.Ctors.Add (CreateConstructor (@class, ctor_name, options, + new Parameter ("p0", "java.lang.String", options.SymbolTable.Lookup ("java.lang.String", null).FullName, false))); @class.Properties.Add (CreateProperty (@class, "Count", "int", options)); @class.Properties.Add (CreateProperty (@class, "Key", "java.lang.String", options)); @class.Properties.Add (CreateProperty (@class, "StaticCount", "int", options, true)); @class.Properties.Add (CreateProperty (@class, "AbstractCount", "int", options, false, true)); - @class.Methods.Add (CreateMethod (@class, "GetCountForKey", options, "int", false, parameters: new Parameter ("key", "java.lang.String", "string", false))); + @class.Methods.Add (CreateMethod (@class, "GetCountForKey", options, "int", false, + parameters: new Parameter ("key", "java.lang.String", options.SymbolTable.Lookup ("java.lang.String", null).FullName, false))); @class.Methods.Add (CreateMethod (@class, "Key", options, "java.lang.String")); @class.Methods.Add (CreateMethod (@class, "StaticMethod", options, "void", true)); @class.Methods.Add (CreateMethod (@class, "AbstractMethod", options, "void", false, true)); @@ -273,7 +275,8 @@ public static TestInterface CreateInterface (string interfaceName, CodeGeneratio iface.Properties.Add (CreateProperty (iface, "StaticCount", "int", options, true)); iface.Properties.Add (CreateProperty (iface, "AbstractCount", "int", options, false, true)); - iface.Methods.Add (CreateMethod (iface, "GetCountForKey", options, "int", false, parameters: new Parameter ("key", "java.lang.String", "string", false))); + iface.Methods.Add (CreateMethod (iface, "GetCountForKey", options, "int", false, + parameters: new Parameter ("key", "java.lang.String", options.SymbolTable.Lookup ("java.lang.String", null).FullName, false))); iface.Methods.Add (CreateMethod (iface, "Key", options, "java.lang.String")); iface.Methods.Add (CreateMethod (iface, "StaticMethod", options, "void", true)); iface.Methods.Add (CreateMethod (iface, "AbstractMethod", options, "void", false, true)); @@ -313,7 +316,7 @@ public static ParameterList CreateParameterList (CodeGenerationOptions options) { var list = new ParameterList { new Parameter ("value", "int", "int", false), - new Parameter ("str", "java.lang.String", "string", false), + new Parameter ("str", "java.lang.String", options.SymbolTable.Lookup ("java.lang.String", null).FullName, false), new Parameter ("flag", "int", "OptionTypes", true) }; diff --git a/tests/generator-Tests/expected.ji/Arrays/Xamarin.Test.SomeObject.cs b/tests/generator-Tests/expected.ji/Arrays/Xamarin.Test.SomeObject.cs index a2c81f637..c3c4e3c64 100644 --- a/tests/generator-Tests/expected.ji/Arrays/Xamarin.Test.SomeObject.cs +++ b/tests/generator-Tests/expected.ji/Arrays/Xamarin.Test.SomeObject.cs @@ -9,147 +9,147 @@ namespace Xamarin.Test { public partial class SomeObject : global::Java.Lang.Object { // Metadata.xml XPath field reference: path="/api/package[@name='xamarin.test']/class[@name='SomeObject']/field[@name='myStrings']" - public IList MyStrings { + public global::Java.Interop.JavaObjectArray MyStrings { get { const string __id = "myStrings.[Ljava/lang/String;"; var __v = _members.InstanceFields.GetObjectValue (__id, this); - return global::Android.Runtime.JavaArray.FromJniHandle (__v.Handle, JniHandleOwnership.TransferLocalRef); + return global::Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue >(ref __v, JniObjectReferenceOptions.Copy); } set { const string __id = "myStrings.[Ljava/lang/String;"; - IntPtr native_value = global::Android.Runtime.JavaArray.ToLocalJniHandle (value); try { - _members.InstanceFields.SetValue (__id, this, new JniObjectReference (native_value)); + _members.InstanceFields.SetValue (__id, this, value?.PeerReference ?? default); + } finally { - global::Android.Runtime.JNIEnv.DeleteLocalRef (native_value); + GC.KeepAlive (value); } } } // Metadata.xml XPath field reference: path="/api/package[@name='xamarin.test']/class[@name='SomeObject']/field[@name='myInts']" - public IList MyInts { + public global::Java.Interop.JavaInt32Array MyInts { get { const string __id = "myInts.[I"; var __v = _members.InstanceFields.GetObjectValue (__id, this); - return global::Android.Runtime.JavaArray.FromJniHandle (__v.Handle, JniHandleOwnership.TransferLocalRef); + return global::Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue(ref __v, JniObjectReferenceOptions.Copy); } set { const string __id = "myInts.[I"; - IntPtr native_value = global::Android.Runtime.JavaArray.ToLocalJniHandle (value); try { - _members.InstanceFields.SetValue (__id, this, new JniObjectReference (native_value)); + _members.InstanceFields.SetValue (__id, this, value?.PeerReference ?? default); + } finally { - global::Android.Runtime.JNIEnv.DeleteLocalRef (native_value); + GC.KeepAlive (value); } } } // Metadata.xml XPath field reference: path="/api/package[@name='xamarin.test']/class[@name='SomeObject']/field[@name='mybools']" - public IList Mybools { + public global::Java.Interop.JavaBooleanArray Mybools { get { const string __id = "mybools.[Z"; var __v = _members.InstanceFields.GetObjectValue (__id, this); - return global::Android.Runtime.JavaArray.FromJniHandle (__v.Handle, JniHandleOwnership.TransferLocalRef); + return global::Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue(ref __v, JniObjectReferenceOptions.Copy); } set { const string __id = "mybools.[Z"; - IntPtr native_value = global::Android.Runtime.JavaArray.ToLocalJniHandle (value); try { - _members.InstanceFields.SetValue (__id, this, new JniObjectReference (native_value)); + _members.InstanceFields.SetValue (__id, this, value?.PeerReference ?? default); + } finally { - global::Android.Runtime.JNIEnv.DeleteLocalRef (native_value); + GC.KeepAlive (value); } } } // Metadata.xml XPath field reference: path="/api/package[@name='xamarin.test']/class[@name='SomeObject']/field[@name='myObjects']" - public IList MyObjects { + public global::Java.Interop.JavaObjectArray MyObjects { get { const string __id = "myObjects.[Ljava/lang/Object;"; var __v = _members.InstanceFields.GetObjectValue (__id, this); - return global::Android.Runtime.JavaArray.FromJniHandle (__v.Handle, JniHandleOwnership.TransferLocalRef); + return global::Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue >(ref __v, JniObjectReferenceOptions.Copy); } set { const string __id = "myObjects.[Ljava/lang/Object;"; - IntPtr native_value = global::Android.Runtime.JavaArray.ToLocalJniHandle (value); try { - _members.InstanceFields.SetValue (__id, this, new JniObjectReference (native_value)); + _members.InstanceFields.SetValue (__id, this, value?.PeerReference ?? default); + } finally { - global::Android.Runtime.JNIEnv.DeleteLocalRef (native_value); + GC.KeepAlive (value); } } } // Metadata.xml XPath field reference: path="/api/package[@name='xamarin.test']/class[@name='SomeObject']/field[@name='myfloats']" - public IList Myfloats { + public global::Java.Interop.JavaSingleArray Myfloats { get { const string __id = "myfloats.[F"; var __v = _members.InstanceFields.GetObjectValue (__id, this); - return global::Android.Runtime.JavaArray.FromJniHandle (__v.Handle, JniHandleOwnership.TransferLocalRef); + return global::Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue(ref __v, JniObjectReferenceOptions.Copy); } set { const string __id = "myfloats.[F"; - IntPtr native_value = global::Android.Runtime.JavaArray.ToLocalJniHandle (value); try { - _members.InstanceFields.SetValue (__id, this, new JniObjectReference (native_value)); + _members.InstanceFields.SetValue (__id, this, value?.PeerReference ?? default); + } finally { - global::Android.Runtime.JNIEnv.DeleteLocalRef (native_value); + GC.KeepAlive (value); } } } // Metadata.xml XPath field reference: path="/api/package[@name='xamarin.test']/class[@name='SomeObject']/field[@name='mydoubles']" - public IList Mydoubles { + public global::Java.Interop.JavaDoubleArray Mydoubles { get { const string __id = "mydoubles.[D"; var __v = _members.InstanceFields.GetObjectValue (__id, this); - return global::Android.Runtime.JavaArray.FromJniHandle (__v.Handle, JniHandleOwnership.TransferLocalRef); + return global::Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue(ref __v, JniObjectReferenceOptions.Copy); } set { const string __id = "mydoubles.[D"; - IntPtr native_value = global::Android.Runtime.JavaArray.ToLocalJniHandle (value); try { - _members.InstanceFields.SetValue (__id, this, new JniObjectReference (native_value)); + _members.InstanceFields.SetValue (__id, this, value?.PeerReference ?? default); + } finally { - global::Android.Runtime.JNIEnv.DeleteLocalRef (native_value); + GC.KeepAlive (value); } } } // Metadata.xml XPath field reference: path="/api/package[@name='xamarin.test']/class[@name='SomeObject']/field[@name='mylongs']" - public IList Mylongs { + public global::Java.Interop.JavaInt64Array Mylongs { get { const string __id = "mylongs.[J"; var __v = _members.InstanceFields.GetObjectValue (__id, this); - return global::Android.Runtime.JavaArray.FromJniHandle (__v.Handle, JniHandleOwnership.TransferLocalRef); + return global::Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue(ref __v, JniObjectReferenceOptions.Copy); } set { const string __id = "mylongs.[J"; - IntPtr native_value = global::Android.Runtime.JavaArray.ToLocalJniHandle (value); try { - _members.InstanceFields.SetValue (__id, this, new JniObjectReference (native_value)); + _members.InstanceFields.SetValue (__id, this, value?.PeerReference ?? default); + } finally { - global::Android.Runtime.JNIEnv.DeleteLocalRef (native_value); + GC.KeepAlive (value); } } } diff --git a/tests/generator-Tests/expected.ji/Streams/Java.IO.FilterOutputStream.cs b/tests/generator-Tests/expected.ji/Streams/Java.IO.FilterOutputStream.cs index 38056067c..91e4ebd60 100644 --- a/tests/generator-Tests/expected.ji/Streams/Java.IO.FilterOutputStream.cs +++ b/tests/generator-Tests/expected.ji/Streams/Java.IO.FilterOutputStream.cs @@ -19,6 +19,25 @@ protected FilterOutputStream (ref JniObjectReference reference, JniObjectReferen { } + // Metadata.xml XPath constructor reference: path="/api/package[@name='java.io']/class[@name='FilterOutputStream']/constructor[@name='FilterOutputStream' and count(parameter)=1 and parameter[1][@type='java.io.OutputStream']]" + public unsafe FilterOutputStream (global::Java.IO.OutputStream @out) : base (ref *InvalidJniObjectReference, JniObjectReferenceOptions.None) + { + const string __id = "(Ljava/io/OutputStream;)V"; + + if (PeerReference.IsValid) + return; + + try { + JniArgumentValue* __args = stackalloc JniArgumentValue [1]; + __args [0] = new JniArgumentValue (@out); + var __r = _members.InstanceMethods.StartCreateInstance (__id, ((object) this).GetType (), __args); + Construct (ref __r, JniObjectReferenceOptions.CopyAndDispose); + _members.InstanceMethods.FinishCreateInstance (__id, this, __args); + } finally { + global::System.GC.KeepAlive (@out); + } + } + // Metadata.xml XPath method reference: path="/api/package[@name='java.io']/class[@name='FilterOutputStream']/method[@name='write' and count(parameter)=1 and parameter[1][@type='int']]" public override unsafe void Write (int oneByte) { diff --git a/tests/generator-Tests/expected.ji/Streams/Java.IO.InputStream.cs b/tests/generator-Tests/expected.ji/Streams/Java.IO.InputStream.cs index 7a8c3ba4c..7fca6aac1 100644 --- a/tests/generator-Tests/expected.ji/Streams/Java.IO.InputStream.cs +++ b/tests/generator-Tests/expected.ji/Streams/Java.IO.InputStream.cs @@ -83,7 +83,7 @@ public virtual unsafe bool MarkSupported () public abstract int Read (); // Metadata.xml XPath method reference: path="/api/package[@name='java.io']/class[@name='InputStream']/method[@name='read' and count(parameter)=1 and parameter[1][@type='byte[]']]" - public virtual unsafe int Read (global::System.Collections.Generic.IList buffer) + public virtual unsafe int Read (global::Java.Interop.JavaSByteArray buffer) { const string __id = "read.([B)I"; var native_buffer = global::Java.Interop.JniEnvironment.Arrays.CreateMarshalSByteArray (buffer); @@ -93,7 +93,7 @@ public virtual unsafe int Read (global::System.Collections.Generic.IList var __rm = _members.InstanceMethods.InvokeVirtualInt32Method (__id, this, __args); return __rm; } finally { - if (buffer != null) { + if (native_buffer != null) { native_buffer.DisposeUnlessReferenced (); } global::System.GC.KeepAlive (buffer); @@ -101,7 +101,7 @@ public virtual unsafe int Read (global::System.Collections.Generic.IList } // Metadata.xml XPath method reference: path="/api/package[@name='java.io']/class[@name='InputStream']/method[@name='read' and count(parameter)=3 and parameter[1][@type='byte[]'] and parameter[2][@type='int'] and parameter[3][@type='int']]" - public virtual unsafe int Read (global::System.Collections.Generic.IList buffer, int byteOffset, int byteCount) + public virtual unsafe int Read (global::Java.Interop.JavaSByteArray buffer, int byteOffset, int byteCount) { const string __id = "read.([BII)I"; var native_buffer = global::Java.Interop.JniEnvironment.Arrays.CreateMarshalSByteArray (buffer); @@ -113,7 +113,7 @@ public virtual unsafe int Read (global::System.Collections.Generic.IList var __rm = _members.InstanceMethods.InvokeVirtualInt32Method (__id, this, __args); return __rm; } finally { - if (buffer != null) { + if (native_buffer != null) { native_buffer.DisposeUnlessReferenced (); } global::System.GC.KeepAlive (buffer); diff --git a/tests/generator-Tests/expected.ji/Streams/Java.IO.OutputStream.cs b/tests/generator-Tests/expected.ji/Streams/Java.IO.OutputStream.cs index 0bbf6d2cc..e5b645b4a 100644 --- a/tests/generator-Tests/expected.ji/Streams/Java.IO.OutputStream.cs +++ b/tests/generator-Tests/expected.ji/Streams/Java.IO.OutputStream.cs @@ -56,7 +56,7 @@ public virtual unsafe void Flush () } // Metadata.xml XPath method reference: path="/api/package[@name='java.io']/class[@name='OutputStream']/method[@name='write' and count(parameter)=1 and parameter[1][@type='byte[]']]" - public virtual unsafe void Write (global::System.Collections.Generic.IList buffer) + public virtual unsafe void Write (global::Java.Interop.JavaSByteArray buffer) { const string __id = "write.([B)V"; var native_buffer = global::Java.Interop.JniEnvironment.Arrays.CreateMarshalSByteArray (buffer); @@ -65,7 +65,7 @@ public virtual unsafe void Write (global::System.Collections.Generic.IList buffer, int offset, int count) + public virtual unsafe void Write (global::Java.Interop.JavaSByteArray buffer, int offset, int count) { const string __id = "write.([BII)V"; var native_buffer = global::Java.Interop.JniEnvironment.Arrays.CreateMarshalSByteArray (buffer); @@ -84,7 +84,7 @@ public virtual unsafe void Write (global::System.Collections.Generic.IList + + + $(DefineConstants);ANDROID_1;ANDROID_2;ANDROID_3;ANDROID_4 + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/generator-Tests/expected/Adapters/Mono.Android.projitems b/tests/generator-Tests/expected/Adapters/Mono.Android.projitems new file mode 100644 index 000000000..4e6987503 --- /dev/null +++ b/tests/generator-Tests/expected/Adapters/Mono.Android.projitems @@ -0,0 +1,19 @@ + + + + $(DefineConstants);ANDROID_1;ANDROID_2;ANDROID_3;ANDROID_4 + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/generator-Tests/expected/Android.Graphics.Color/Mono.Android.projitems b/tests/generator-Tests/expected/Android.Graphics.Color/Mono.Android.projitems new file mode 100644 index 000000000..066be1dd1 --- /dev/null +++ b/tests/generator-Tests/expected/Android.Graphics.Color/Mono.Android.projitems @@ -0,0 +1,15 @@ + + + + $(DefineConstants);ANDROID_1;ANDROID_2;ANDROID_3;ANDROID_4 + + + + + + + + + + + \ No newline at end of file diff --git a/tests/generator-Tests/expected/Arrays/Mono.Android.projitems b/tests/generator-Tests/expected/Arrays/Mono.Android.projitems new file mode 100644 index 000000000..066be1dd1 --- /dev/null +++ b/tests/generator-Tests/expected/Arrays/Mono.Android.projitems @@ -0,0 +1,15 @@ + + + + $(DefineConstants);ANDROID_1;ANDROID_2;ANDROID_3;ANDROID_4 + + + + + + + + + + + \ No newline at end of file diff --git a/tests/generator-Tests/expected/CSharpKeywords/Mono.Android.projitems b/tests/generator-Tests/expected/CSharpKeywords/Mono.Android.projitems new file mode 100644 index 000000000..1e80d027f --- /dev/null +++ b/tests/generator-Tests/expected/CSharpKeywords/Mono.Android.projitems @@ -0,0 +1,16 @@ + + + + $(DefineConstants);ANDROID_1;ANDROID_2;ANDROID_3;ANDROID_4 + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/generator-Tests/expected/Constructors/Mono.Android.projitems b/tests/generator-Tests/expected/Constructors/Mono.Android.projitems new file mode 100644 index 000000000..82192a590 --- /dev/null +++ b/tests/generator-Tests/expected/Constructors/Mono.Android.projitems @@ -0,0 +1,16 @@ + + + + $(DefineConstants);ANDROID_1;ANDROID_2;ANDROID_3;ANDROID_4 + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/generator-Tests/expected/Core_ClassParse/Mono.Android.projitems b/tests/generator-Tests/expected/Core_ClassParse/Mono.Android.projitems new file mode 100644 index 000000000..5a1d5a97e --- /dev/null +++ b/tests/generator-Tests/expected/Core_ClassParse/Mono.Android.projitems @@ -0,0 +1,18 @@ + + + + $(DefineConstants);ANDROID_1;ANDROID_2;ANDROID_3;ANDROID_4 + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/generator-Tests/expected/Core_Jar2Xml/Mono.Android.projitems b/tests/generator-Tests/expected/Core_Jar2Xml/Mono.Android.projitems new file mode 100644 index 000000000..0b239b193 --- /dev/null +++ b/tests/generator-Tests/expected/Core_Jar2Xml/Mono.Android.projitems @@ -0,0 +1,21 @@ + + + + $(DefineConstants);ANDROID_1;ANDROID_2;ANDROID_3;ANDROID_4 + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/generator-Tests/expected/EnumerationFixup/Mono.Android.projitems b/tests/generator-Tests/expected/EnumerationFixup/Mono.Android.projitems new file mode 100644 index 000000000..439ba2d49 --- /dev/null +++ b/tests/generator-Tests/expected/EnumerationFixup/Mono.Android.projitems @@ -0,0 +1,19 @@ + + + + $(DefineConstants);ANDROID_1;ANDROID_2;ANDROID_3;ANDROID_4 + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/generator-Tests/expected/GenericArguments/Mono.Android.projitems b/tests/generator-Tests/expected/GenericArguments/Mono.Android.projitems new file mode 100644 index 000000000..ce2c2b1c9 --- /dev/null +++ b/tests/generator-Tests/expected/GenericArguments/Mono.Android.projitems @@ -0,0 +1,18 @@ + + + + $(DefineConstants);ANDROID_1;ANDROID_2;ANDROID_3;ANDROID_4 + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/generator-Tests/expected/InterfaceMethodsConflict/Mono.Android.projitems b/tests/generator-Tests/expected/InterfaceMethodsConflict/Mono.Android.projitems new file mode 100644 index 000000000..03c426cd6 --- /dev/null +++ b/tests/generator-Tests/expected/InterfaceMethodsConflict/Mono.Android.projitems @@ -0,0 +1,18 @@ + + + + $(DefineConstants);ANDROID_1;ANDROID_2;ANDROID_3;ANDROID_4 + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/generator-Tests/expected/NestedTypes/Mono.Android.projitems b/tests/generator-Tests/expected/NestedTypes/Mono.Android.projitems new file mode 100644 index 000000000..5e66c0f7f --- /dev/null +++ b/tests/generator-Tests/expected/NestedTypes/Mono.Android.projitems @@ -0,0 +1,15 @@ + + + + $(DefineConstants);ANDROID_1;ANDROID_2;ANDROID_3;ANDROID_4 + + + + + + + + + + + \ No newline at end of file diff --git a/tests/generator-Tests/expected/NonStaticFields/Mono.Android.projitems b/tests/generator-Tests/expected/NonStaticFields/Mono.Android.projitems new file mode 100644 index 000000000..066be1dd1 --- /dev/null +++ b/tests/generator-Tests/expected/NonStaticFields/Mono.Android.projitems @@ -0,0 +1,15 @@ + + + + $(DefineConstants);ANDROID_1;ANDROID_2;ANDROID_3;ANDROID_4 + + + + + + + + + + + \ No newline at end of file diff --git a/tests/generator-Tests/expected/NormalMethods/Mono.Android.projitems b/tests/generator-Tests/expected/NormalMethods/Mono.Android.projitems new file mode 100644 index 000000000..98ca90f0d --- /dev/null +++ b/tests/generator-Tests/expected/NormalMethods/Mono.Android.projitems @@ -0,0 +1,20 @@ + + + + $(DefineConstants);ANDROID_1;ANDROID_2;ANDROID_3;ANDROID_4 + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/generator-Tests/expected/NormalProperties/Mono.Android.projitems b/tests/generator-Tests/expected/NormalProperties/Mono.Android.projitems new file mode 100644 index 000000000..066be1dd1 --- /dev/null +++ b/tests/generator-Tests/expected/NormalProperties/Mono.Android.projitems @@ -0,0 +1,15 @@ + + + + $(DefineConstants);ANDROID_1;ANDROID_2;ANDROID_3;ANDROID_4 + + + + + + + + + + + \ No newline at end of file diff --git a/tests/generator-Tests/expected/ParameterXPath/Mono.Android.projitems b/tests/generator-Tests/expected/ParameterXPath/Mono.Android.projitems new file mode 100644 index 000000000..e6f21d31f --- /dev/null +++ b/tests/generator-Tests/expected/ParameterXPath/Mono.Android.projitems @@ -0,0 +1,16 @@ + + + + $(DefineConstants);ANDROID_1;ANDROID_2;ANDROID_3;ANDROID_4 + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/generator-Tests/expected/StaticFields/Mono.Android.projitems b/tests/generator-Tests/expected/StaticFields/Mono.Android.projitems new file mode 100644 index 000000000..066be1dd1 --- /dev/null +++ b/tests/generator-Tests/expected/StaticFields/Mono.Android.projitems @@ -0,0 +1,15 @@ + + + + $(DefineConstants);ANDROID_1;ANDROID_2;ANDROID_3;ANDROID_4 + + + + + + + + + + + \ No newline at end of file diff --git a/tests/generator-Tests/expected/StaticMethods/Mono.Android.projitems b/tests/generator-Tests/expected/StaticMethods/Mono.Android.projitems new file mode 100644 index 000000000..066be1dd1 --- /dev/null +++ b/tests/generator-Tests/expected/StaticMethods/Mono.Android.projitems @@ -0,0 +1,15 @@ + + + + $(DefineConstants);ANDROID_1;ANDROID_2;ANDROID_3;ANDROID_4 + + + + + + + + + + + \ No newline at end of file diff --git a/tests/generator-Tests/expected/StaticProperties/Mono.Android.projitems b/tests/generator-Tests/expected/StaticProperties/Mono.Android.projitems new file mode 100644 index 000000000..066be1dd1 --- /dev/null +++ b/tests/generator-Tests/expected/StaticProperties/Mono.Android.projitems @@ -0,0 +1,15 @@ + + + + $(DefineConstants);ANDROID_1;ANDROID_2;ANDROID_3;ANDROID_4 + + + + + + + + + + + \ No newline at end of file diff --git a/tests/generator-Tests/expected/Streams/Mono.Android.projitems b/tests/generator-Tests/expected/Streams/Mono.Android.projitems new file mode 100644 index 000000000..3d19ddac3 --- /dev/null +++ b/tests/generator-Tests/expected/Streams/Mono.Android.projitems @@ -0,0 +1,19 @@ + + + + $(DefineConstants);ANDROID_1;ANDROID_2;ANDROID_3;ANDROID_4 + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/generator-Tests/expected/TestInterface/Mono.Android.projitems b/tests/generator-Tests/expected/TestInterface/Mono.Android.projitems new file mode 100644 index 000000000..5a3e90231 --- /dev/null +++ b/tests/generator-Tests/expected/TestInterface/Mono.Android.projitems @@ -0,0 +1,25 @@ + + + + $(DefineConstants);ANDROID_1;ANDROID_2;ANDROID_3;ANDROID_4 + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/generator-Tests/expected/TestInterface/Test.ME.GenericStringPropertyImplementation.cs b/tests/generator-Tests/expected/TestInterface/Test.ME.GenericStringPropertyImplementation.cs index 401becb8e..aa34c27e3 100644 --- a/tests/generator-Tests/expected/TestInterface/Test.ME.GenericStringPropertyImplementation.cs +++ b/tests/generator-Tests/expected/TestInterface/Test.ME.GenericStringPropertyImplementation.cs @@ -131,7 +131,7 @@ public virtual unsafe string Object { } // Metadata.xml XPath method reference: path="/api/package[@name='test.me']/interface[@name='GenericPropertyInterface']/method[@name='setObject' and count(parameter)=1 and parameter[1][@type='T']]" [Register ("setObject", "(Ljava/lang/Object;)V", "GetSetObject_Ljava_lang_Object_Handler:Test.ME.IGenericPropertyInterfaceInvoker, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null")] set { - Object = value.ToString (); + Object = value?.ToString (); } } diff --git a/tests/generator-Tests/expected/java.lang.Enum/Mono.Android.projitems b/tests/generator-Tests/expected/java.lang.Enum/Mono.Android.projitems new file mode 100644 index 000000000..fa2e06041 --- /dev/null +++ b/tests/generator-Tests/expected/java.lang.Enum/Mono.Android.projitems @@ -0,0 +1,17 @@ + + + + $(DefineConstants);ANDROID_1;ANDROID_2;ANDROID_3;ANDROID_4 + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/generator-Tests/expected/java.lang.Object/Mono.Android.projitems b/tests/generator-Tests/expected/java.lang.Object/Mono.Android.projitems new file mode 100644 index 000000000..d140c8de1 --- /dev/null +++ b/tests/generator-Tests/expected/java.lang.Object/Mono.Android.projitems @@ -0,0 +1,14 @@ + + + + $(DefineConstants);ANDROID_1;ANDROID_2;ANDROID_3;ANDROID_4 + + + + + + + + + + \ No newline at end of file diff --git a/tests/generator-Tests/expected/java.util.List/Mono.Android.projitems b/tests/generator-Tests/expected/java.util.List/Mono.Android.projitems new file mode 100644 index 000000000..066be1dd1 --- /dev/null +++ b/tests/generator-Tests/expected/java.util.List/Mono.Android.projitems @@ -0,0 +1,15 @@ + + + + $(DefineConstants);ANDROID_1;ANDROID_2;ANDROID_3;ANDROID_4 + + + + + + + + + + + \ No newline at end of file diff --git a/tools/generator/CodeGenerationOptions.cs b/tools/generator/CodeGenerationOptions.cs index 7e4eb9398..564941bb1 100644 --- a/tools/generator/CodeGenerationOptions.cs +++ b/tools/generator/CodeGenerationOptions.cs @@ -302,6 +302,13 @@ public string GetTransformedNamespace (string value) return value; } + + public string GetStringArrayToCharSequenceArrayMethodName () + { + return CodeGenerationTarget == CodeGenerationTarget.JavaInterop1 + ? "ICharSequenceExtensions.ToCharSequenceArray" + : "CharSequence.ArrayFromStringArray"; + } } } diff --git a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/ClassGen.cs b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/ClassGen.cs index 57e76c0be..30ce30b9e 100644 --- a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/ClassGen.cs +++ b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/ClassGen.cs @@ -339,8 +339,13 @@ public override void ResetValidation () base.ResetValidation (); } - public override string ToNative (CodeGenerationOptions opt, string varname, Dictionary mappings = null) => - $"JNIEnv.ToLocalJniHandle ({varname})"; + public override string ToNative (CodeGenerationOptions opt, string varname, Dictionary mappings = null) + { + if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1) { + return $"({varname}.?PeerReference ?? default)"; + } + return $"JNIEnv.ToLocalJniHandle ({varname})"; + } public override void UpdateEnumsInInterfaceImplementation () { diff --git a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/GenBase.cs b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/GenBase.cs index 1322ea41f..6d55000fc 100644 --- a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/GenBase.cs +++ b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/GenBase.cs @@ -355,6 +355,9 @@ public string FullName { protected void GenerateAnnotationAttribute (CodeGenerationOptions opt, GenerationInfo gen_info) { + if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1) { + return; + } if (ShouldGenerateAnnotationAttribute) { var baseName = Namespace.Length > 0 ? FullName.Substring (Namespace.Length + 1) : FullName; var attrClassNameBase = baseName.Substring (TypeNamePrefix.Length) + "Attribute"; diff --git a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/InterfaceGen.cs b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/InterfaceGen.cs index 8b17fe928..4b111554b 100644 --- a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/InterfaceGen.cs +++ b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/InterfaceGen.cs @@ -243,6 +243,9 @@ public override void ResetValidation () public override string ToNative (CodeGenerationOptions opt, string varname, Dictionary mappings = null) { + if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1) { + return $"({varname}.?PeerReference ?? default)"; + } return string.Format ("JNIEnv.ToLocalJniHandle ({0})", varname); /* if (String.IsNullOrEmpty (Marshaler)) diff --git a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/Parameter.cs b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/Parameter.cs index a32c49abc..4a7c6e35c 100644 --- a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/Parameter.cs +++ b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/Parameter.cs @@ -256,11 +256,16 @@ public string GetGenericCall (CodeGenerationOptions opt, Dictionary ()", name, targetType.Replace ("[]","")); } var rgm = opt.SymbolTable.Lookup (targetType) as IRequireGenericMarshal; + if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1) { + return "global::Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue<" + + opt.GetOutputName (rgm != null ? (rgm.GetGenericJavaObjectTypeOverride () ?? targetType) : targetType) + + $">(({name}?.PeerReference ?? default).Handle)"; + } return string.Format ("global::Java.Interop.JavaObjectExtensions.JavaCast<{0}>({1}){2}", opt.GetOutputName (rgm != null ? (rgm.GetGenericJavaObjectTypeOverride () ?? targetType) : targetType), name, diff --git a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/ReturnValue.cs b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/ReturnValue.cs index 9a2cc73a9..1fe885d78 100644 --- a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/ReturnValue.cs +++ b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/ReturnValue.cs @@ -4,6 +4,7 @@ using System.Xml; using Java.Interop.Tools.Generator; using MonoDroid.Utils; +using Xamarin.Android.Binder; namespace MonoDroid.Generation { @@ -107,6 +108,12 @@ public string FromNative (CodeGenerationOptions opt, string var_name, bool owned public string ToNative (CodeGenerationOptions opt, string var_name) { + if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1) { + if ((sym is GenericTypeParameter) || (sym is GenericSymbol)) { + return $"({var_name}.?PeerReference ?? default)"; + } + return sym.ToNative (opt, var_name); + } return ((sym is GenericTypeParameter) || (sym is GenericSymbol)) ? String.Format ("JNIEnv.ToLocalJniHandle ({0})", var_name) : sym.ToNative (opt, var_name); } @@ -118,6 +125,11 @@ public string GetGenericReturn (CodeGenerationOptions opt, string name, Dictiona if (targetType == "string") return string.Format ("{0}?.ToString ()", name); var rgm = opt.SymbolTable.Lookup (targetType) as IRequireGenericMarshal; + if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1) { + return "global::Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue<" + + (rgm != null ? (rgm.GetGenericJavaObjectTypeOverride () ?? sym.FullName) : sym.FullName) + + $">(({opt.GetSafeIdentifier (rgm != null ? rgm.ToInteroperableJavaObject (name) : name)}?.PeerReference ?? default).Handle)"; + } return string.Format ("global::Java.Interop.JavaObjectExtensions.JavaCast<{0}>({1}){2}", rgm != null ? (rgm.GetGenericJavaObjectTypeOverride () ?? sym.FullName) : sym.FullName, opt.GetSafeIdentifier (rgm != null ? rgm.ToInteroperableJavaObject (name) : name), diff --git a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/Symbols/ArraySymbol.cs b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/Symbols/ArraySymbol.cs index 6a5d984fb..800360f60 100644 --- a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/Symbols/ArraySymbol.cs +++ b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/Symbols/ArraySymbol.cs @@ -38,7 +38,7 @@ public string ElementType { public string FullName { get { if (!is_params && target == CodeGenerationTarget.JavaInterop1) { - return GetJavaInterop1ParameterType (); + return GetJavaInterop1MarshalType (); } return (is_params ? "params " : String.Empty) + ElementType + "[]"; } @@ -135,14 +135,14 @@ public string[] PostCall (CodeGenerationOptions opt, string var_name) if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1) { if (IsParams) { return new[]{ - $"if ({managed_name} != null) {{", - $"\t{native_name}.CopyTo ({managed_name}, 0);", + $"if ({native_name} != null) {{", + $"\t{native_name}.CopyTo ({managed_name}!, 0);", $"\t{native_name}.Dispose ();", $"}}", }; } return new[]{ - $"if ({managed_name} != null) {{", + $"if ({native_name} != null) {{", $"\t{native_name}.DisposeUnlessReferenced ();", $"}}", }; @@ -174,26 +174,6 @@ public string[] PreCall (CodeGenerationOptions opt, string var_name) public bool NeedsPrep { get { return true; } } - string GetJavaInterop1ParameterType () - { - var typeParam = ElementType switch { - "string" => "string", - _ => $"global::{ElementType}", - }; - return sym.JniName switch { - "B" => "System.Collections.Generic.IList", - "C" => "System.Collections.Generic.IList", - "D" => "System.Collections.Generic.IList", - "F" => "System.Collections.Generic.IList", - "I" => "System.Collections.Generic.IList", - "J" => "System.Collections.Generic.IList", - "S" => "System.Collections.Generic.IList", - "V" => throw new InvalidOperationException ("`void` cannot be used as an array type."), - "Z" => "System.Collections.Generic.IList", - _ => $"System.Collections.Generic.IList<{typeParam}>", - }; - } - string GetJavaInterop1MarshalMethod() { var typeParam = ElementType switch { @@ -216,10 +196,6 @@ string GetJavaInterop1MarshalMethod() string GetJavaInterop1MarshalType () { - var typeParam = ElementType switch { - "string" => "string", - _ => $"global::{ElementType}", - }; return sym.JniName switch { "B" => "Java.Interop.JavaSByteArray", "C" => "Java.Interop.JavaCharArray", @@ -230,7 +206,7 @@ string GetJavaInterop1MarshalType () "S" => "Java.Interop.JavaInt16Array", "V" => throw new InvalidOperationException ("`void` cannot be used as an array type."), "Z" => "Java.Interop.JavaBooleanArray", - _ => $"Java.Interop.JavaObjectArray<{typeParam}>", + _ => $"Java.Interop.JavaObjectArray<{ElementType}>", }; } } diff --git a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/Symbols/CharSequenceSymbol.cs b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/Symbols/CharSequenceSymbol.cs index 750fd84b0..3b3a2e5c0 100644 --- a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/Symbols/CharSequenceSymbol.cs +++ b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/Symbols/CharSequenceSymbol.cs @@ -59,11 +59,18 @@ public string GetGenericType (Dictionary mappings) public string FromNative (CodeGenerationOptions opt, string var_name, bool owned) { + if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1) { + return "global::Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue(" + + $"ref {var_name}, JniObjectReferenceOptions.{(owned ? "CopyAndDispose" : "Copy")})"; + } return String.Format ("global::Java.Lang.Object.GetObject ({0}, {1})", var_name, owned ? "JniHandleOwnership.TransferLocalRef" : "JniHandleOwnership.DoNotTransfer"); } public string ToNative (CodeGenerationOptions opt, string var_name, Dictionary mappings = null) { + if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1) { + return $"({var_name}?.PeerReference ?? default)"; + } return String.Format ("CharSequence.ToLocalJniHandle ({0})", var_name); } @@ -74,6 +81,9 @@ public bool Validate (CodeGenerationOptions opt, GenericParameterDefinitionList public string Call (CodeGenerationOptions opt, string var_name) { + if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1) { + return var_name; + } return opt.GetSafeIdentifier (TypeNameUtilities.GetNativeName (var_name)); } @@ -84,6 +94,9 @@ public string[] PostCallback (CodeGenerationOptions opt, string var_name) public string[] PostCall (CodeGenerationOptions opt, string var_name) { + if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1) { + return Array.Empty(); + } return new string[]{ string.Format ("JNIEnv.DeleteLocalRef ({0});", opt.GetSafeIdentifier (TypeNameUtilities.GetNativeName (var_name))), }; @@ -91,11 +104,20 @@ public string[] PostCall (CodeGenerationOptions opt, string var_name) public string[] PreCallback (CodeGenerationOptions opt, string var_name, bool owned) { + if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1) { + return new[]{ + $"var {var_name} = global::Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue(" + + $"ref {TypeNameUtilities.GetNativeName (var_name)}, JniObjectReferenceOptions.Copy)", + }; + } return new string[] { String.Format ("var {0} = global::Java.Lang.Object.GetObject ({1}, JniHandleOwnership.DoNotTransfer);", var_name, TypeNameUtilities.GetNativeName (var_name)) }; } public string[] PreCall (CodeGenerationOptions opt, string var_name) { + if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1) { + return Array.Empty (); + } return new string[] { String.Format ("IntPtr {0} = CharSequence.ToLocalJniHandle ({1});", opt.GetSafeIdentifier (TypeNameUtilities.GetNativeName (var_name)), opt.GetSafeIdentifier (var_name)) }; } diff --git a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/Symbols/GenericTypeParameter.cs b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/Symbols/GenericTypeParameter.cs index 5d2b5f3db..db11a3dd9 100644 --- a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/Symbols/GenericTypeParameter.cs +++ b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/Symbols/GenericTypeParameter.cs @@ -120,9 +120,16 @@ public string[] PostCallback (CodeGenerationOptions opt, string var_name) public string[] PreCall (CodeGenerationOptions opt, string var_name) { + var native_name = opt.GetSafeIdentifier (TypeNameUtilities.GetNativeName (var_name)); + var name = opt.GetSafeIdentifier (var_name); + if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1) { + return new[]{ + $"var {native_name} = ({name}?.PeerReference ?? default);", + }; + } return new string[] { string.Format ("IntPtr {0} = JNIEnv.ToLocalJniHandle ({1});", - opt.GetSafeIdentifier (TypeNameUtilities.GetNativeName (var_name)), opt.GetSafeIdentifier (var_name)), + native_name, name), }; } @@ -133,6 +140,10 @@ public string Call (CodeGenerationOptions opt, string var_name) public string[] PostCall (CodeGenerationOptions opt, string var_name) { + if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1) { + return new string[]{ + }; + } return new string[]{ string.Format ("JNIEnv.DeleteLocalRef ({0});", opt.GetSafeIdentifier (TypeNameUtilities.GetNativeName (var_name))), diff --git a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/Symbols/SymbolTable.cs b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/Symbols/SymbolTable.cs index e90f62710..259e8c0f1 100644 --- a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/Symbols/SymbolTable.cs +++ b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/Symbols/SymbolTable.cs @@ -197,7 +197,16 @@ public ISymbol Lookup (string java_type, GenericParameterDefinitionList in_param } key = TypeNameUtilities.FilterPrimitiveFullName (key) ?? key; - switch (key) { + if (target == CodeGenerationTarget.JavaInterop1) { + if (key == "java.lang.CharSequence") { + return CreateArray (char_seq, arrayRank, has_ellipsis); + } + if (key == "java.lang.String") { + return CreateArray (string_sym, arrayRank, has_ellipsis); + } + } + + switch (this.target != CodeGenerationTarget.JavaInterop1 ? key : null) { case "android.content.res.XmlResourceParser": return CreateArray (xmlresourceparser_sym, arrayRank, has_ellipsis); case "org.xmlpull.v1.XmlPullParser": diff --git a/tools/generator/SourceWriters/BoundFieldAsProperty.cs b/tools/generator/SourceWriters/BoundFieldAsProperty.cs index fdcc2e4f8..2e3740a63 100644 --- a/tools/generator/SourceWriters/BoundFieldAsProperty.cs +++ b/tools/generator/SourceWriters/BoundFieldAsProperty.cs @@ -24,7 +24,15 @@ public BoundFieldAsProperty (GenBase type, Field field, CodeGenerationOptions op Name = field.Name; - var fieldType = field.Symbol.IsArray ? "IList<" + field.Symbol.ElementType + ">" + opt.NullableOperator : opt.GetTypeReferenceName (field); + string fieldType; + if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1) { + fieldType = opt.GetTypeReferenceName (field); + } else { + fieldType = field.Symbol.IsArray + ? "IList<" + field.Symbol.ElementType + ">" + opt.NullableOperator + : opt.GetTypeReferenceName (field); + } + PropertyType = new TypeReferenceWriter (fieldType); field.JavadocInfo?.AddJavadocs (Comments); @@ -85,6 +93,18 @@ protected override void WriteGetterBody (CodeWriter writer) writer.WriteLine ($"var __v = {field.Symbol.ReturnCast}_members.{indirect}.{invoke} (__id{(field.IsStatic ? "" : ", this")});"); + if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1) { + if (field.Symbol.NativeType == field.Symbol.FullName) { + writer.WriteLine ("return __v;"); + return; + } + writer.Write ("return global::Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue<"); + PropertyType.WriteTypeReference (writer); + writer.Write (">(ref __v, JniObjectReferenceOptions.Copy)"); + writer.WriteLine (";"); + return; + } + if (field.Symbol.IsArray) { writer.WriteLine ($"return global::Android.Runtime.JavaArray<{opt.GetOutputName (field.Symbol.ElementType)}>.FromJniHandle (__v.Handle, JniHandleOwnership.TransferLocalRef);"); } else if (field.Symbol.NativeType != field.Symbol.FullName) { @@ -102,12 +122,17 @@ protected override void WriteSetterBody (CodeWriter writer) var invokeType = SourceWriterExtensions.GetInvokeType (field.GetMethodPrefix); var indirect = field.IsStatic ? "StaticFields" : "InstanceFields"; + string native_arg = opt.GetSafeIdentifier (TypeNameUtilities.GetNativeName ("value")); string arg; bool have_prep = false; if (field.Symbol.IsArray) { - arg = opt.GetSafeIdentifier (TypeNameUtilities.GetNativeName ("value")); - writer.WriteLine ($"IntPtr {arg} = global::Android.Runtime.JavaArray<{opt.GetOutputName (field.Symbol.ElementType)}>.ToLocalJniHandle (value);"); + if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1) { + arg = "value"; + } else { + arg = native_arg; + writer.WriteLine ($"IntPtr {native_arg} = global::Android.Runtime.JavaArray<{opt.GetOutputName (field.Symbol.ElementType)}>.ToLocalJniHandle (value);"); + } } else { foreach (var prep in field.SetParameters.GetCallPrep (opt)) { have_prep = true; @@ -116,29 +141,47 @@ protected override void WriteSetterBody (CodeWriter writer) arg = field.SetParameters [0].ToNative (opt); - if (field.SetParameters.HasCleanup && !have_prep) { - arg = opt.GetSafeIdentifier (TypeNameUtilities.GetNativeName ("value")); - writer.WriteLine ($"IntPtr {arg} = global::Android.Runtime.JNIEnv.ToLocalJniHandle (value);"); + if (opt.CodeGenerationTarget != CodeGenerationTarget.JavaInterop1 && + field.SetParameters.HasCleanup && + !have_prep) { + writer.WriteLine ($"IntPtr {native_arg} = global::Android.Runtime.JNIEnv.ToLocalJniHandle (value);"); } } writer.WriteLine ("try {"); + writer.Write ($"\t_members.{indirect}.SetValue (__id{(field.IsStatic ? "" : ", this")}, "); - writer.WriteLine ($"\t_members.{indirect}.SetValue (__id{(field.IsStatic ? "" : ", this")}, {(invokeType != "Object" ? arg : "new JniObjectReference (" + arg + ")")});"); + if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1) { + writer.WriteLine ($"{(invokeType != "Object" ? arg : $"{arg}?.PeerReference ?? default")});"); + } else { + writer.WriteLine ($"{(invokeType != "Object" ? arg : "new JniObjectReference (" + arg + ")")});"); + } + writer.WriteLine (); writer.WriteLine ("} finally {"); writer.Indent (); if (field.Symbol.IsArray) { - writer.WriteLine ($"global::Android.Runtime.JNIEnv.DeleteLocalRef ({arg});"); + if (opt.CodeGenerationTarget != CodeGenerationTarget.JavaInterop1) { + writer.WriteLine ($"global::Android.Runtime.JNIEnv.DeleteLocalRef ({arg});"); + } } else { foreach (var cleanup in field.SetParameters.GetCallCleanup (opt)) writer.WriteLine (cleanup); if (field.SetParameters.HasCleanup && !have_prep) { - writer.WriteLine ($"global::Android.Runtime.JNIEnv.DeleteLocalRef ({arg});"); + if (opt.CodeGenerationTarget != CodeGenerationTarget.JavaInterop1) { + writer.WriteLine ($"global::Android.Runtime.JNIEnv.DeleteLocalRef ({arg});"); + } } } + if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1 && + field.Symbol.JniName != null && + field.Symbol.JniName.Length > 1 && + (field.Symbol.JniName[0] == 'L' || field.Symbol.JniName[0] == '[')) { + writer.WriteLine ($"GC.KeepAlive (value);"); + } + writer.Unindent (); writer.WriteLine ("}"); } diff --git a/tools/generator/SourceWriters/BoundInterface.cs b/tools/generator/SourceWriters/BoundInterface.cs index 09524b4cf..334985608 100644 --- a/tools/generator/SourceWriters/BoundInterface.cs +++ b/tools/generator/SourceWriters/BoundInterface.cs @@ -104,8 +104,10 @@ void AddAlternativesClass (InterfaceGen iface, CodeGenerationOptions opt, CodeGe var staticMethods = iface.Methods.Where (m => m.IsStatic); - if (iface.Fields.Any () || staticMethods.Any ()) + if (opt.CodeGenerationTarget != CodeGenerationTarget.JavaInterop1 && + (iface.Fields.Any () || staticMethods.Any ())) { pre_sibling_types.Add (new InterfaceMemberAlternativeClass (iface, opt, context)); + } } void AddInterfaceEventHandler (InterfaceGen iface, CodeGenerationOptions opt, CodeGeneratorContext context) diff --git a/tools/generator/SourceWriters/BoundPropertyStringVariant.cs b/tools/generator/SourceWriters/BoundPropertyStringVariant.cs index 26dd3f77f..05a083d5d 100644 --- a/tools/generator/SourceWriters/BoundPropertyStringVariant.cs +++ b/tools/generator/SourceWriters/BoundPropertyStringVariant.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using MonoDroid.Generation; using Xamarin.SourceWriter; +using Xamarin.Android.Binder; namespace generator.SourceWriters { @@ -26,10 +27,12 @@ public BoundPropertyStringVariant (Property property, CodeGenerationOptions opt) SourceWriterExtensions.AddSupportedOSPlatform (Attributes, property.Getter, opt); + string arrayConvertMethod = opt.GetStringArrayToCharSequenceArrayMethodName (); + HasGet = true; if (is_array) - GetBody.Add ($"return CharSequence.ArrayToStringArray ({property.AdjustedName});"); + GetBody.Add ($"return {arrayConvertMethod} ({property.AdjustedName});"); else GetBody.Add ($"return {property.AdjustedName} == null ? null : {property.AdjustedName}.ToString ();"); @@ -39,7 +42,7 @@ public BoundPropertyStringVariant (Property property, CodeGenerationOptions opt) HasSet = true; if (is_array) { - SetBody.Add ($"global::Java.Lang.ICharSequence[] jlsa = CharSequence.ArrayFromStringArray (value);"); + SetBody.Add ($"global::Java.Lang.ICharSequence[] jlsa = {arrayConvertMethod} (value);"); SetBody.Add ($"{property.AdjustedName} = jlsa;"); SetBody.Add ($"foreach (var jls in jlsa) if (jls != null) jls.Dispose ();"); } else { diff --git a/tools/generator/SourceWriters/CharSequenceEnumeratorMethod.cs b/tools/generator/SourceWriters/CharSequenceEnumeratorMethod.cs index 11554454b..79c4b1f6d 100644 --- a/tools/generator/SourceWriters/CharSequenceEnumeratorMethod.cs +++ b/tools/generator/SourceWriters/CharSequenceEnumeratorMethod.cs @@ -15,8 +15,8 @@ public class CharSequenceEnumeratorMethod : MethodWriter // } public CharSequenceEnumeratorMethod () { - Name = "System.Collections.IEnumerable.GetEnumerator"; - ReturnType = new TypeReferenceWriter ("System.Collections.IEnumerator"); + Name = "global::System.Collections.IEnumerable.GetEnumerator"; + ReturnType = new TypeReferenceWriter ("global::System.Collections.IEnumerator"); Body.Add ("return GetEnumerator ();"); } @@ -32,7 +32,7 @@ public class CharSequenceGenericEnumeratorMethod : MethodWriter public CharSequenceGenericEnumeratorMethod () { Name = "GetEnumerator"; - ReturnType = new TypeReferenceWriter ("System.Collections.Generic.IEnumerator"); + ReturnType = new TypeReferenceWriter ("global::System.Collections.Generic.IEnumerator"); IsPublic = true; diff --git a/tools/generator/SourceWriters/Extensions/SourceWriterExtensions.cs b/tools/generator/SourceWriters/Extensions/SourceWriterExtensions.cs index 88bd55689..a7b215fb6 100644 --- a/tools/generator/SourceWriters/Extensions/SourceWriterExtensions.cs +++ b/tools/generator/SourceWriters/Extensions/SourceWriterExtensions.cs @@ -352,7 +352,7 @@ public static void WriteMethodStringOverloadBody (CodeWriter writer, Method meth writer.WriteLine ($"var {pname} = {p.Name} == null ? null : new global::Java.Lang.String ({p.Name});"); } else if (p.Type == "Java.Lang.ICharSequence[]" || p.Type == "params Java.Lang.ICharSequence[]") { pname = p.GetName ("jlca_"); - writer.WriteLine ($"var {pname} = CharSequence.ArrayFromStringArray({p.Name});"); + writer.WriteLine ($"var {pname} = {opt.GetStringArrayToCharSequenceArrayMethodName ()} ({p.Name});"); } if (call.Length > 0) @@ -367,7 +367,7 @@ public static void WriteMethodStringOverloadBody (CodeWriter writer, Method meth case "void": break; case "Java.Lang.ICharSequence[]": - writer.WriteLine ("var __rsval = CharSequence.ArrayToStringArray (__result);"); + writer.WriteLine ($"var __rsval = {opt.GetStringArrayToCharSequenceArrayMethodName ()} (__result);"); break; case "Java.Lang.ICharSequence": writer.WriteLine ("var __rsval = __result?.ToString ();");