Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ namespace Java.Interop.Tools.Cecil {

public static class TypeDefinitionRocks {

public static TypeDefinition ResolveCached (this TypeReference type, IMetadataResolver? resolver) =>
resolver != null ? resolver.Resolve (type) : type.Resolve ();

[Obsolete ("Use the TypeDefinitionCache overload for better performance.")]
public static TypeDefinition? GetBaseType (this TypeDefinition type) =>
GetBaseType (type, resolver: null);
Expand All @@ -19,9 +22,7 @@ public static class TypeDefinitionRocks {
var bt = type.BaseType;
if (bt == null)
return null;
if (resolver != null)
return resolver.Resolve (bt);
return bt.Resolve ();
return bt.ResolveCached (resolver);
}

[Obsolete ("Use the TypeDefinitionCache overload for better performance.")]
Expand Down Expand Up @@ -68,7 +69,7 @@ public static bool IsAssignableFrom (this TypeReference type, TypeReference c, I
{
if (type.FullName == c.FullName)
return true;
var d = (resolver?.Resolve (c)) ?? c.Resolve ();
var d = c.ResolveCached (resolver);
if (d == null)
return false;
foreach (var t in d.GetTypeAndBaseTypes (resolver)) {
Expand Down Expand Up @@ -127,7 +128,7 @@ public static string GetPartialAssemblyName (this TypeReference type, TypeDefini

public static string GetPartialAssemblyName (this TypeReference type, IMetadataResolver? resolver)
{
TypeDefinition? def = (resolver?.Resolve (type)) ?? type.Resolve ();
TypeDefinition? def = type.ResolveCached (resolver);
return (def ?? type).Module.Assembly.Name.Name;
}

Expand Down Expand Up @@ -156,7 +157,7 @@ public static string GetAssemblyQualifiedName (this TypeReference type, TypeDefi

public static string GetAssemblyQualifiedName (this TypeReference type, IMetadataResolver? resolver)
{
TypeDefinition? def = (resolver?.Resolve (type)) ?? type.Resolve ();
TypeDefinition? def = type.ResolveCached(resolver);
return string.Format ("{0}, {1}",
// Cecil likes to use '/' as the nested type separator, while
// Reflection uses '+' as the nested type separator. Use Reflection.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public JavaFieldInfo (MethodDefinition method, string fieldName, IMetadataResolv
?? throw new ArgumentException ($"Could not get JNI signature for method `{method.Name}`", nameof (method));
IsStatic = method.IsStatic;
Access = method.Attributes & MethodAttributes.MemberAccessMask;
Annotations = GetAnnotationsString ("\t", method.CustomAttributes);
Annotations = GetAnnotationsString ("\t", method.CustomAttributes, resolver);
}

public MethodAttributes Access { get; private set; }
Expand Down Expand Up @@ -175,20 +175,23 @@ void AddNestedTypes (TypeDefinition type)
}
}

foreach (MethodDefinition imethod in type.Interfaces.Select (ifaceInfo => ifaceInfo.InterfaceType)
.Select (r => {
var d = r.Resolve ();
if (d == null)
Diagnostic.Error (4204,
LookupSource (type),
Localization.Resources.JavaCallableWrappers_XA4204,
r.FullName);
return d;
})
.Where (d => d != null && GetTypeRegistrationAttributes (d).Any ())
.SelectMany (d => d!.Methods)
.Where (m => !m.IsStatic)) {
AddMethod (imethod, imethod);
foreach (InterfaceImplementation ifaceInfo in type.Interfaces) {
var typeReference = ifaceInfo.InterfaceType;
var typeDefinition = typeReference.ResolveCached (resolver);
if (typeDefinition == null) {
Diagnostic.Error (4204,
LookupSource (type),
Localization.Resources.JavaCallableWrappers_XA4204,
typeReference.FullName);
continue;
}
if (!GetTypeRegistrationAttributes (typeDefinition).Any ())
continue;
foreach (MethodDefinition imethod in typeDefinition.Methods) {
if (imethod.IsStatic)
continue;
AddMethod (imethod, imethod);
}
}

var ctorTypes = new List<TypeDefinition> () {
Expand Down Expand Up @@ -303,7 +306,7 @@ void AddConstructor (MethodDefinition ctor, TypeDefinition type, string? outerTy
if (rattr != null) {
if (ctors.Any (c => c.JniSignature == rattr.Signature))
return;
ctors.Add (new Signature (ctor, rattr, managedParameters, outerType));
ctors.Add (new Signature (ctor, rattr, managedParameters, outerType, cache));
curCtors.Add (ctor);
return;
}
Expand Down Expand Up @@ -473,7 +476,7 @@ void AddMethod (MethodDefinition? registeredMethod, MethodDefinition implemented
Diagnostic.Error (4217, LookupSource (implementedMethod), Localization.Resources.JavaCallableWrappers_XA4217, attr.Name);

bool shouldBeDynamicallyRegistered = methodClassifier?.ShouldBeDynamicallyRegistered (type, registeredMethod, implementedMethod, attr.OriginAttribute) ?? true;
var msig = new Signature (implementedMethod, attr, shouldBeDynamicallyRegistered);
var msig = new Signature (implementedMethod, attr, cache, shouldBeDynamicallyRegistered);
if (!registeredMethod.IsConstructor && !methods.Any (m => m.Name == msig.Name && m.Params == msig.Params))
methods.Add (msig);
}
Expand Down Expand Up @@ -601,17 +604,17 @@ public void Generate (string outputPath)
}
}

static string GetAnnotationsString (string indent, IEnumerable<CustomAttribute> atts)
static string GetAnnotationsString (string indent, IEnumerable<CustomAttribute> atts, IMetadataResolver? resolver)
{
var sw = new StringWriter ();
WriteAnnotations (indent, sw, atts);
WriteAnnotations (indent, sw, atts, resolver);
return sw.ToString ();
}

static void WriteAnnotations (string indent, TextWriter sw, IEnumerable<CustomAttribute> atts)
static void WriteAnnotations (string indent, TextWriter sw, IEnumerable<CustomAttribute> atts, IMetadataResolver? resolver)
{
foreach (var ca in atts) {
var catype = ca.AttributeType.Resolve ();
var catype = ca.AttributeType.ResolveCached (resolver);
var tca = catype.CustomAttributes.FirstOrDefault (a => a.AttributeType.FullName == "Android.Runtime.AnnotationAttribute");
if (tca != null) {
sw.Write (indent);
Expand Down Expand Up @@ -655,7 +658,7 @@ void GenerateHeader (TextWriter sw)
sw.WriteLine ();

// class annotations.
WriteAnnotations ("", sw, type.CustomAttributes);
WriteAnnotations ("", sw, type.CustomAttributes, cache);

sw.WriteLine ("public " + (type.IsAbstract ? "abstract " : "") + "class " + name);

Expand All @@ -673,15 +676,13 @@ void GenerateHeader (TextWriter sw)
sw.Write ("mono.android.IGCUserPeer");
break;
}
IEnumerable<TypeDefinition> ifaces = type.Interfaces.Select (ifaceInfo => ifaceInfo.InterfaceType)
.Select (r => r.Resolve ())
.Where (d => GetTypeRegistrationAttributes (d).Any ());
if (ifaces.Any ()) {
foreach (TypeDefinition iface in ifaces) {
sw.WriteLine (",");
sw.Write ("\t\t");
sw.Write (GetJavaTypeName (iface, cache));
}
foreach (var ifaceInfo in type.Interfaces) {
var iface = ifaceInfo.InterfaceType.ResolveCached (cache);
if (!GetTypeRegistrationAttributes (iface).Any ())
continue;
sw.WriteLine (",");
sw.Write ("\t\t");
sw.Write (GetJavaTypeName (iface, cache));
}
sw.WriteLine ();
sw.WriteLine ("{");
Expand Down Expand Up @@ -811,7 +812,7 @@ static string GetJavaAccess (MethodAttributes access)

static string GetJavaTypeName (TypeReference r, IMetadataResolver cache)
{
TypeDefinition d = r.Resolve ();
TypeDefinition d = cache.Resolve (r);
string? jniName = JavaNativeTypeManager.ToJniName (d, cache);
if (jniName == null) {
Diagnostic.Error (4201, Localization.Resources.JavaCallableWrappers_XA4201, r.FullName);
Expand All @@ -827,12 +828,12 @@ bool CannotRegisterInStaticConstructor (TypeDefinition type)

class Signature {

public Signature (MethodDefinition method, RegisterAttribute register, bool shouldBeDynamicallyRegistered = true) : this (method, register, null, null, shouldBeDynamicallyRegistered) {}
public Signature (MethodDefinition method, RegisterAttribute register, IMetadataResolver cache, bool shouldBeDynamicallyRegistered = true) : this (method, register, null, null, cache, shouldBeDynamicallyRegistered) {}

public Signature (MethodDefinition method, RegisterAttribute register, string? managedParameters, string? outerType, bool shouldBeDynamicallyRegistered = true)
public Signature (MethodDefinition method, RegisterAttribute register, string? managedParameters, string? outerType, IMetadataResolver cache, bool shouldBeDynamicallyRegistered = true)
: this (register.Name, register.Signature, register.Connector, managedParameters, outerType, null)
{
Annotations = JavaCallableWrapperGenerator.GetAnnotationsString ("\t", method.CustomAttributes);
Annotations = JavaCallableWrapperGenerator.GetAnnotationsString ("\t", method.CustomAttributes, cache);
IsDynamicallyRegistered = shouldBeDynamicallyRegistered;
}

Expand All @@ -844,10 +845,10 @@ public Signature (MethodDefinition method, ExportAttribute export, IMetadataReso
JavaAccess = JavaCallableWrapperGenerator.GetJavaAccess (method.Attributes & MethodAttributes.MemberAccessMask);
ThrownTypeNames = export.ThrownNames;
JavaNameOverride = export.Name;
Annotations = JavaCallableWrapperGenerator.GetAnnotationsString ("\t", method.CustomAttributes);
Annotations = JavaCallableWrapperGenerator.GetAnnotationsString ("\t", method.CustomAttributes, cache);
}

public Signature (MethodDefinition method, ExportFieldAttribute exportField, IMetadataResolver? cache)
public Signature (MethodDefinition method, ExportFieldAttribute exportField, IMetadataResolver cache)
: this (method.Name, GetJniSignature (method, cache), "__export__", null, null, null)
{
if (method.HasParameters)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ public static bool IsInstrumentation (TypeDefinition type, IMetadataResolver? re

internal static string? GetJniTypeName (TypeReference typeRef, ExportParameterKind exportKind, IMetadataResolver? cache)
{
return GetJniTypeName<TypeReference, TypeDefinition> (typeRef, exportKind, t => t.Resolve (), t => {
return GetJniTypeName<TypeReference, TypeDefinition> (typeRef, exportKind, t => t.ResolveCached (cache), t => {
TypeReference etype;
int rank = GetArrayInfo (typeRef, out etype);
return new KeyValuePair<int,TypeReference> (rank,etype);
Expand Down Expand Up @@ -525,7 +525,7 @@ public static string ToJniName (TypeDefinition type, IMetadataResolver? resolver
throw new ArgumentNullException ("type");

if (type.IsValueType)
return GetPrimitiveClass (type);
return GetPrimitiveClass (type, cache);

if (type.FullName == "System.String")
return "java/lang/String";
Expand Down Expand Up @@ -554,7 +554,7 @@ public static string ToJniName (TypeDefinition type, IMetadataResolver? resolver
static string? ToJniNameFromAttributesForInterop (TypeDefinition type, IMetadataResolver? resolver)
{
var attr = type.CustomAttributes.FirstOrDefault (a =>
Resolve (resolver, a.AttributeType)
a.AttributeType.ResolveCached (resolver)
.FullName == "Java.Interop.JniTypeSignatureAttribute");
if (attr == null) {
return null;
Expand Down Expand Up @@ -604,17 +604,12 @@ static bool IsIJniNameProviderAttribute (CustomAttribute attr, IMetadataResolver
return true;

// Slow path resolves the type, looking for IJniNameProviderAttribute
var attributeType = Resolve (resolver, attr.AttributeType);
var attributeType = attr.AttributeType.ResolveCached (resolver);
if (!attributeType.HasInterfaces)
return false;
return attributeType.Interfaces.Any (it => it.InterfaceType.FullName == typeof (IJniNameProviderAttribute).FullName);
}

static TypeDefinition Resolve (IMetadataResolver? resolver, TypeReference typeReference) =>
resolver?.Resolve (typeReference) ??
typeReference.Resolve () ??
throw new InvalidOperationException ();

public static int GetArrayInfo (Mono.Cecil.TypeReference type, out Mono.Cecil.TypeReference elementType)
{
elementType = type;
Expand All @@ -626,10 +621,10 @@ public static int GetArrayInfo (Mono.Cecil.TypeReference type, out Mono.Cecil.Ty
return rank;
}

static string? GetPrimitiveClass (Mono.Cecil.TypeDefinition type)
static string? GetPrimitiveClass (Mono.Cecil.TypeDefinition type, IMetadataResolver? cache)
{
if (type.IsEnum)
return GetPrimitiveClass (type.Fields.First (f => f.IsSpecialName).FieldType.Resolve ());
return GetPrimitiveClass (type.Fields.First (f => f.IsSpecialName).FieldType.ResolveCached (cache), cache);
if (type.FullName == "System.Byte")
return "B";
if (type.FullName == "System.Char")
Expand Down