Skip to content

[Java.Interop.Tools.Cecil] Unroll TypeDefinitionRocks iterators. #1244

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
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
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>8.0</LangVersion>
<LangVersion>9.0</LangVersion>
<Nullable>enable</Nullable>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\..\product.snk</AssemblyOriginatorKeyFile>
Original file line number Diff line number Diff line change
@@ -20,7 +20,9 @@ public static MethodDefinition GetBaseDefinition (this MethodDefinition method,
if (method.IsStatic || method.IsNewSlot || !method.IsVirtual)
return method;

foreach (var baseType in method.DeclaringType.GetBaseTypes (resolver)) {
TypeDefinition? baseType = method.DeclaringType;

while ((baseType = baseType.GetBaseType (resolver)) != null) {
foreach (var m in baseType.Methods) {
if (!m.IsConstructor &&
m.Name == method.Name &&
Original file line number Diff line number Diff line change
@@ -65,14 +65,19 @@ public static bool IsAssignableFrom (this TypeReference type, TypeReference c, I
var d = resolver.Resolve (c);
if (d == null)
return false;
foreach (var t in d.GetTypeAndBaseTypes (resolver)) {

TypeDefinition? t = d;

while (t is not null) {
if (type.FullName == t.FullName)
return true;
foreach (var ifaceImpl in t.Interfaces) {
var i = ifaceImpl.InterfaceType;
if (IsAssignableFrom (type, i, resolver))
return true;
}

t = t.GetBaseType (resolver);
}
return false;
}
@@ -84,20 +89,44 @@ public static bool IsSubclassOf (this TypeDefinition type, string typeName, Type
IsSubclassOf (type, typeName, (IMetadataResolver) cache);
public static bool IsSubclassOf (this TypeDefinition type, string typeName, IMetadataResolver resolver)
{
foreach (var t in type.GetTypeAndBaseTypes (resolver)) {
TypeDefinition? t = type;

while (t is not null) {
if (t.FullName == typeName) {
return true;
}

t = t.GetBaseType (resolver);
}
return false;
}

public static bool IsSubclassOfAny (this TypeDefinition type, IList<string> typeNames, IMetadataResolver resolver, out string? subclassType)
{
subclassType = null;

TypeDefinition? t = type;

while (t is not null) {
if (typeNames.Contains (t.FullName)) {
subclassType = t.FullName;
return true;
}

t = t.GetBaseType (resolver);
}

return false;
}

public static bool HasJavaPeer (this TypeDefinition type, IMetadataResolver resolver)
{
if (type.IsInterface && type.ImplementsInterface ("Java.Interop.IJavaPeerable", resolver))
return true;
if (type.IsInterface)
return type.ImplementsInterface ("Java.Interop.IJavaPeerable", resolver);

foreach (var t in type.GetTypeAndBaseTypes (resolver)) {
TypeDefinition? t = type;

while (t is not null) {
switch (t.FullName) {
case "Java.Lang.Object":
case "Java.Lang.Throwable":
@@ -107,6 +136,8 @@ public static bool HasJavaPeer (this TypeDefinition type, IMetadataResolver reso
default:
break;
}

t = t.GetBaseType (resolver);
}
return false;
}
@@ -119,13 +150,36 @@ public static bool ImplementsInterface (this TypeDefinition type, string interfa

public static bool ImplementsInterface (this TypeDefinition type, string interfaceName, IMetadataResolver resolver)
{
foreach (var t in type.GetTypeAndBaseTypes (resolver)) {
TypeDefinition? t = type;

while (t is not null) {
foreach (var i in t.Interfaces) {
if (i.InterfaceType.FullName == interfaceName) {
return true;
}
}

t = t.GetBaseType (resolver);
}
return false;
}

public static bool ImplementsAnyInterface (this TypeDefinition type, IList<string> interfaceNames, IMetadataResolver resolver, out string? implementedInterface)
{
implementedInterface = null;
TypeDefinition? t = type;

while (t is not null) {
foreach (var i in t.Interfaces) {
if (interfaceNames.Contains (i.InterfaceType.FullName)) {
implementedInterface = i.InterfaceType.FullName;
return true;
}
}

t = t.GetBaseType (resolver);
}

return false;
}

Original file line number Diff line number Diff line change
@@ -14,6 +14,8 @@ namespace Java.Interop.Tools.JavaCallableWrappers.Adapters;

public class CecilImporter
{
static IList<string> android_manifest_types = ["Android.App.Activity", "Android.App.Application", "Android.App.Service", "Android.Content.BroadcastReceiver", "Android.Content.ContentProvider"];

// Don't expose internal "outerType" parameter to the public API
public static CallableWrapperType CreateType (TypeDefinition type, IMetadataResolver resolver, CallableWrapperReaderOptions? options = null)
=> CreateType (type, resolver, options, null);
@@ -38,11 +40,7 @@ static CallableWrapperType CreateType (TypeDefinition type, IMetadataResolver re
options ??= new CallableWrapperReaderOptions ();

if (string.IsNullOrEmpty (package) &&
(type.IsSubclassOf ("Android.App.Activity", resolver) ||
type.IsSubclassOf ("Android.App.Application", resolver) ||
type.IsSubclassOf ("Android.App.Service", resolver) ||
type.IsSubclassOf ("Android.Content.BroadcastReceiver", resolver) ||
type.IsSubclassOf ("Android.Content.ContentProvider", resolver)))
(type.IsSubclassOfAny (android_manifest_types, resolver, out var _)))
Diagnostic.Error (4203, CecilExtensions.LookupSource (type), Localization.Resources.JavaCallableWrappers_XA4203, jniName);

var cwt = new CallableWrapperType (name, package, type.GetPartialAssemblyQualifiedName (resolver)) {
@@ -124,7 +122,9 @@ static CallableWrapperType CreateType (TypeDefinition type, IMetadataResolver re
type,
};

foreach (var bt in type.GetBaseTypes (resolver)) {
TypeDefinition? bt = type;

while ((bt = bt.GetBaseType (resolver)) != null) {
ctorTypes.Add (bt);
var rattr = CecilExtensions.GetTypeRegistrationAttributes (bt).FirstOrDefault ();

Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>11.0</LangVersion>
<LangVersion>12.0</LangVersion>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<SignAssembly>true</SignAssembly>
Original file line number Diff line number Diff line change
@@ -438,7 +438,7 @@ public static bool IsApplication (TypeDefinition type, TypeDefinitionCache cache

public static bool IsApplication (TypeDefinition type, IMetadataResolver resolver)
{
return type.GetBaseTypes (resolver).Any (b => b.FullName == "Android.App.Application");
return type.IsSubclassOf ("Android.App.Application", resolver);
}

[Obsolete ("Use the TypeDefinitionCache overload for better performance.", error: true)]
@@ -449,7 +449,7 @@ public static bool IsInstrumentation (TypeDefinition type, TypeDefinitionCache c

public static bool IsInstrumentation (TypeDefinition type, IMetadataResolver resolver)
{
return type.GetBaseTypes (resolver).Any (b => b.FullName == "Android.App.Instrumentation");
return type.IsSubclassOf ("Android.App.Instrumentation", resolver);
}

// moved from JavaTypeInfo
@@ -529,6 +529,8 @@ public static string ToJniName (TypeDefinition type, IMetadataResolver resolver)
return x;
}

static IList<string> java_interface_types = ["Android.Runtime.IJavaObject", "Java.Interop.IJavaPeerable"];

static string? ToJniName (TypeDefinition type, ExportParameterKind exportKind, IMetadataResolver cache)
{
if (type == null)
@@ -540,8 +542,7 @@ public static string ToJniName (TypeDefinition type, IMetadataResolver resolver)
if (type.FullName == "System.String")
return "java/lang/String";

if (!type.ImplementsInterface ("Android.Runtime.IJavaObject", cache) &&
!type.ImplementsInterface ("Java.Interop.IJavaPeerable", cache)) {
if (!type.ImplementsAnyInterface (java_interface_types, cache, out var _)) {
return GetSpecialExportJniType (type.FullName, exportKind);
}

@@ -734,9 +735,10 @@ internal static bool IsNonStaticInnerClass (TypeDefinition? type, IMetadataResol
if (!type.DeclaringType.HasJavaPeer (cache))
return false;

foreach (var baseType in type.GetBaseTypes (cache)) {
if (baseType == null)
continue;
TypeDefinition? baseType = type;

while ((baseType = baseType.GetBaseType (cache)) != null) {

if (!baseType.AnyCustomAttributes (typeof (RegisterAttribute)))
continue;