Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 63 additions & 7 deletions samples/Hello-NativeAOTFromAndroid/NativeAotTypeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace Java.Interop.Samples.NativeAotFromAndroid;

partial class NativeAotTypeManager : JniRuntime.JniTypeManager {

internal const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
internal const DynamicallyAccessedMemberTypes Methods = DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods;
internal const DynamicallyAccessedMemberTypes MethodsAndPrivateNested = Methods | DynamicallyAccessedMemberTypes.NonPublicNestedTypes;

Expand All @@ -26,9 +27,27 @@ public override void RegisterNativeMembers (
ReadOnlySpan<char> methods)
{
Console.WriteLine ($"# jonp: RegisterNativeMembers: nativeClass={nativeClass} type=`{type}`");
base.RegisterNativeMembers (nativeClass, type, methods);
if (!methods.IsEmpty)
throw new NotSupportedException ($"Could not register native members for type '{type.FullName}'.");
}

public override void RegisterNativeMembers (
JniType nativeClass,
[DynamicallyAccessedMembers (MethodsAndPrivateNested)]
Type type,
string? methods)
{
RegisterNativeMembers (nativeClass, type, methods.AsSpan ());
}

protected override string? GetSimpleReference (Type type)
{
foreach (var e in typeMappings) {
if (e.Value == type)
return e.Key;
}
return null;
}

protected override IEnumerable<Type> GetTypesForSimpleReference (string jniSimpleReference)
{
Expand All @@ -37,16 +56,18 @@ protected override IEnumerable<Type> GetTypesForSimpleReference (string jniSimpl
Console.WriteLine ($"# jonp: GetTypesForSimpleReference: jniSimpleReference=`{jniSimpleReference}` -> `{target}`");
yield return target;
}
foreach (var t in base.GetTypesForSimpleReference (jniSimpleReference)) {
Console.WriteLine ($"# jonp: GetTypesForSimpleReference: jniSimpleReference=`{jniSimpleReference}` -> `{t}`");
yield return t;
}
}

protected override Type? GetTypeForSimpleReference (string jniSimpleReference)
{
if (typeMappings.TryGetValue (jniSimpleReference, out var target))
return target;
return null;
}

protected override IEnumerable<string> GetSimpleReferences (Type type)
{
return base.GetSimpleReferences (type)
.Concat (CreateSimpleReferencesEnumerator (type));
return CreateSimpleReferencesEnumerator (type);
}

IEnumerable<string> CreateSimpleReferencesEnumerator (Type type)
Expand All @@ -58,4 +79,39 @@ IEnumerable<string> CreateSimpleReferencesEnumerator (Type type)
yield return e.Key;
}
}

public override IEnumerable<Type> GetTypes (JniTypeSignature typeSignature)
{
if (!typeSignature.IsValid || typeSignature.ArrayRank != 0 || typeSignature.SimpleReference == null)
return [];
return GetTypesForSimpleReference (typeSignature.SimpleReference);
}

public override IEnumerable<ReflectionConstructibleType> GetReflectionConstructibleTypes (JniTypeSignature typeSignature)
{
foreach (var type in GetTypes (typeSignature)) {
yield return new ReflectionConstructibleType (type);
}
}

protected override Type? GetInvokerTypeCore ([DynamicallyAccessedMembers (Constructors)] Type type) => null;

protected override JniTypeSignature GetTypeSignatureCore (Type type)
{
var simpleReference = GetSimpleReference (type);
return simpleReference == null ? default : new JniTypeSignature (simpleReference, 0, false);
}

protected override IEnumerable<JniTypeSignature> GetTypeSignaturesCore (Type type)
{
var signature = GetTypeSignatureCore (type);
if (signature.IsValid)
yield return signature;
}

protected override IReadOnlyList<string>? GetStaticMethodFallbackTypesCore (string jniSimpleReference) => null;

protected override string? GetReplacementTypeCore (string jniSimpleReference) => null;

protected override JniRuntime.ReplacementMethodInfo? GetReplacementMethodInfoCore (string jniSimpleReference, string jniMethodName, string jniMethodSignature) => null;
}
2 changes: 1 addition & 1 deletion samples/Hello-NativeAOTFromJNI/ManagedType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ static IntPtr n_GetString (IntPtr jnienv, IntPtr n_self)
}

[JniAddNativeMethodRegistration]
static void RegisterNativeMembers (JniNativeMethodRegistrationArguments args)
internal static void RegisterNativeMembers (JniNativeMethodRegistrationArguments args)
{
args.AddRegistrations (new [] {
new JniNativeMethodRegistration ("n_GetString", "()Ljava/lang/String;", new _JniMarshal_PP_L (n_GetString)),
Expand Down
89 changes: 85 additions & 4 deletions samples/Hello-NativeAOTFromJNI/NativeAotTypeManager.cs
Original file line number Diff line number Diff line change
@@ -1,28 +1,47 @@
using Java.Interop;
using System.Diagnostics.CodeAnalysis;

namespace Hello_NativeAOTFromJNI;

class NativeAotTypeManager : JniRuntime.JniTypeManager {
internal const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
internal const DynamicallyAccessedMemberTypes Methods = DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods;
internal const DynamicallyAccessedMemberTypes MethodsAndPrivateNested = Methods | DynamicallyAccessedMemberTypes.NonPublicNestedTypes;

#pragma warning disable IL2026
Dictionary<string, Type> typeMappings = new () {
[Example.ManagedType.JniTypeName] = typeof (Example.ManagedType),
[Java.Lang.Object.JniTypeName] = typeof (Java.Lang.Object),
[Java.Lang.String.JniTypeName] = typeof (Java.Lang.String),
};
#pragma warning restore IL2026

protected override string? GetSimpleReference (Type type)
{
foreach (var e in typeMappings) {
if (e.Value == type)
return e.Key;
}
return null;
}


protected override IEnumerable<Type> GetTypesForSimpleReference (string jniSimpleReference)
{
if (typeMappings.TryGetValue (jniSimpleReference, out var target))
yield return target;
foreach (var t in base.GetTypesForSimpleReference (jniSimpleReference))
yield return t;
}

protected override Type? GetTypeForSimpleReference (string jniSimpleReference)
{
if (typeMappings.TryGetValue (jniSimpleReference, out var target))
return target;
return null;
}

protected override IEnumerable<string> GetSimpleReferences (Type type)
{
return base.GetSimpleReferences (type)
.Concat (CreateSimpleReferencesEnumerator (type));
return CreateSimpleReferencesEnumerator (type);
}

IEnumerable<string> CreateSimpleReferencesEnumerator (Type type)
Expand All @@ -34,4 +53,66 @@ IEnumerable<string> CreateSimpleReferencesEnumerator (Type type)
yield return e.Key;
}
}

public override IEnumerable<Type> GetTypes (JniTypeSignature typeSignature)
{
if (!typeSignature.IsValid || typeSignature.ArrayRank != 0 || typeSignature.SimpleReference == null)
return [];
return GetTypesForSimpleReference (typeSignature.SimpleReference);
}

public override IEnumerable<ReflectionConstructibleType> GetReflectionConstructibleTypes (JniTypeSignature typeSignature)
{
foreach (var type in GetTypes (typeSignature)) {
yield return new ReflectionConstructibleType (type);
}
}

protected override Type? GetInvokerTypeCore ([DynamicallyAccessedMembers (Constructors)] Type type) => null;

protected override JniTypeSignature GetTypeSignatureCore (Type type)
{
var simpleReference = GetSimpleReference (type);
return simpleReference == null ? default : new JniTypeSignature (simpleReference, 0, false);
}

protected override IEnumerable<JniTypeSignature> GetTypeSignaturesCore (Type type)
{
var signature = GetTypeSignatureCore (type);
if (signature.IsValid)
yield return signature;
}

protected override IReadOnlyList<string>? GetStaticMethodFallbackTypesCore (string jniSimpleReference) => null;

protected override string? GetReplacementTypeCore (string jniSimpleReference) => null;

protected override JniRuntime.ReplacementMethodInfo? GetReplacementMethodInfoCore (string jniSimpleReference, string jniMethodName, string jniMethodSignature) => null;

public override void RegisterNativeMembers (
JniType nativeClass,
[DynamicallyAccessedMembers (MethodsAndPrivateNested)]
Type type,
ReadOnlySpan<char> methods)
{
if (type != typeof (Example.ManagedType)) {
if (!methods.IsEmpty)
throw new NotSupportedException ($"Could not register native members for type '{type.FullName}'.");
return;
}

var registrations = new List<JniNativeMethodRegistration> ();
Example.ManagedType.RegisterNativeMembers (new JniNativeMethodRegistrationArguments (registrations, null));
if (registrations.Count > 0)
nativeClass.RegisterNativeMethods (registrations.ToArray ());
}

public override void RegisterNativeMembers (
JniType nativeClass,
[DynamicallyAccessedMembers (MethodsAndPrivateNested)]
Type type,
string? methods)
{
RegisterNativeMembers (nativeClass, type, methods.AsSpan ());
}
}
1 change: 1 addition & 0 deletions src/Java.Interop/GlobalSuppressions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
[assembly: SuppressMessage ("Design", "CA1034:Nested types should not be visible", Justification = "Deliberate choice to 'hide' these types from code completion for `Java.Interop.`.", Scope = "type", Target = "~T:Java.Interop.JniRuntime.JniValueManager")]
[assembly: SuppressMessage ("Design", "CA1034:Nested types should not be visible", Justification = "Deliberate choice to 'hide' these types from code completion for `Java.Interop.`.", Scope = "type", Target = "~T:Java.Interop.JniEnvironment.References")]
[assembly: SuppressMessage ("Design", "CA1034:Nested types should not be visible", Justification = "Deliberate choice to 'hide' these types from code completion for `Java.Interop.`.", Scope = "type", Target = "~T:Java.Interop.JniRuntime.JniTypeManager")]
[assembly: SuppressMessage ("Design", "CA1034:Nested types should not be visible", Justification = "Deliberate choice to 'hide' these types from code completion for `Java.Interop.`.", Scope = "type", Target = "~T:Java.Interop.JniRuntime.DynamicJniTypeManager")]
[assembly: SuppressMessage ("Design", "CA1034:Nested types should not be visible", Justification = "Deliberate choice to 'hide' these types from code completion for `Java.Interop.`.", Scope = "type", Target = "~T:Java.Interop.JniPeerMembers.JniInstanceMethods")]
[assembly: SuppressMessage ("Design", "CA1034:Nested types should not be visible", Justification = "Deliberate choice to 'hide' these types from code completion for `Java.Interop.`.", Scope = "type", Target = "~T:Java.Interop.JniPeerMembers.JniInstanceFields")]
[assembly: SuppressMessage ("Design", "CA1034:Nested types should not be visible", Justification = "Deliberate choice to 'hide' these types from code completion for `Java.Interop.`.", Scope = "type", Target = "~T:Java.Interop.JniRuntime.CreationOptions")]
Expand Down
3 changes: 1 addition & 2 deletions src/Java.Interop/Java.Interop/JavaPrimitiveArrays.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ namespace Java.Interop {

partial class JniRuntime {

partial class JniTypeManager {

partial class DynamicJniTypeManager {
readonly struct JniPrimitiveArrayInfo {
public readonly JniTypeSignature JniTypeSignature;
public readonly Type PrimitiveType;
Expand Down
2 changes: 1 addition & 1 deletion src/Java.Interop/Java.Interop/JavaPrimitiveArrays.tt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ namespace Java.Interop {
#>
partial class JniRuntime {

partial class JniTypeManager {
partial class DynamicJniTypeManager {

readonly struct JniPrimitiveArrayInfo {
public readonly JniTypeSignature JniTypeSignature;
Expand Down
Loading