Skip to content

Commit 2f72421

Browse files
committed
[Java.Interop.Tools.Cecil] TypeDefinitionRocks performance tweaks.
1 parent 51b784a commit 2f72421

File tree

6 files changed

+80
-22
lines changed

6 files changed

+80
-22
lines changed

src/Java.Interop.Tools.Cecil/Java.Interop.Tools.Cecil.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFramework>netstandard2.0</TargetFramework>
5-
<LangVersion>8.0</LangVersion>
5+
<LangVersion>9.0</LangVersion>
66
<Nullable>enable</Nullable>
77
<SignAssembly>true</SignAssembly>
88
<AssemblyOriginatorKeyFile>..\..\product.snk</AssemblyOriginatorKeyFile>

src/Java.Interop.Tools.Cecil/Java.Interop.Tools.Cecil/MethodDefinitionRocks.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ public static MethodDefinition GetBaseDefinition (this MethodDefinition method,
2020
if (method.IsStatic || method.IsNewSlot || !method.IsVirtual)
2121
return method;
2222

23-
foreach (var baseType in method.DeclaringType.GetBaseTypes (resolver)) {
23+
TypeDefinition? baseType = method.DeclaringType;
24+
25+
while ((baseType = baseType.GetBaseType (resolver)) != null) {
2426
foreach (var m in baseType.Methods) {
2527
if (!m.IsConstructor &&
2628
m.Name == method.Name &&

src/Java.Interop.Tools.Cecil/Java.Interop.Tools.Cecil/TypeDefinitionRocks.cs

+60-6
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,19 @@ public static bool IsAssignableFrom (this TypeReference type, TypeReference c, I
6565
var d = resolver.Resolve (c);
6666
if (d == null)
6767
return false;
68-
foreach (var t in d.GetTypeAndBaseTypes (resolver)) {
68+
69+
TypeDefinition? t = d;
70+
71+
while (t is not null) {
6972
if (type.FullName == t.FullName)
7073
return true;
7174
foreach (var ifaceImpl in t.Interfaces) {
7275
var i = ifaceImpl.InterfaceType;
7376
if (IsAssignableFrom (type, i, resolver))
7477
return true;
7578
}
79+
80+
t = t.GetBaseType (resolver);
7681
}
7782
return false;
7883
}
@@ -84,20 +89,44 @@ public static bool IsSubclassOf (this TypeDefinition type, string typeName, Type
8489
IsSubclassOf (type, typeName, (IMetadataResolver) cache);
8590
public static bool IsSubclassOf (this TypeDefinition type, string typeName, IMetadataResolver resolver)
8691
{
87-
foreach (var t in type.GetTypeAndBaseTypes (resolver)) {
92+
TypeDefinition? t = type;
93+
94+
while (t is not null) {
8895
if (t.FullName == typeName) {
8996
return true;
9097
}
98+
99+
t = t.GetBaseType (resolver);
100+
}
101+
return false;
102+
}
103+
104+
public static bool IsSubclassOfAny (this TypeDefinition type, IList<string> typeNames, IMetadataResolver resolver, out string? subclassType)
105+
{
106+
subclassType = null;
107+
108+
TypeDefinition? t = type;
109+
110+
while (t is not null) {
111+
if (typeNames.Contains (t.FullName)) {
112+
subclassType = t.FullName;
113+
return true;
114+
}
115+
116+
t = t.GetBaseType (resolver);
91117
}
118+
92119
return false;
93120
}
94121

95122
public static bool HasJavaPeer (this TypeDefinition type, IMetadataResolver resolver)
96123
{
97-
if (type.IsInterface && type.ImplementsInterface ("Java.Interop.IJavaPeerable", resolver))
98-
return true;
124+
if (type.IsInterface)
125+
return type.ImplementsInterface ("Java.Interop.IJavaPeerable", resolver);
99126

100-
foreach (var t in type.GetTypeAndBaseTypes (resolver)) {
127+
TypeDefinition? t = type;
128+
129+
while (t is not null) {
101130
switch (t.FullName) {
102131
case "Java.Lang.Object":
103132
case "Java.Lang.Throwable":
@@ -107,6 +136,8 @@ public static bool HasJavaPeer (this TypeDefinition type, IMetadataResolver reso
107136
default:
108137
break;
109138
}
139+
140+
t = t.GetBaseType (resolver);
110141
}
111142
return false;
112143
}
@@ -119,13 +150,36 @@ public static bool ImplementsInterface (this TypeDefinition type, string interfa
119150

120151
public static bool ImplementsInterface (this TypeDefinition type, string interfaceName, IMetadataResolver resolver)
121152
{
122-
foreach (var t in type.GetTypeAndBaseTypes (resolver)) {
153+
TypeDefinition? t = type;
154+
155+
while (t is not null) {
123156
foreach (var i in t.Interfaces) {
124157
if (i.InterfaceType.FullName == interfaceName) {
125158
return true;
126159
}
127160
}
161+
162+
t = t.GetBaseType (resolver);
163+
}
164+
return false;
165+
}
166+
167+
public static bool ImplementsAnyInterface (this TypeDefinition type, IList<string> interfaceNames, IMetadataResolver resolver, out string? implementedInterface)
168+
{
169+
implementedInterface = null;
170+
TypeDefinition? t = type;
171+
172+
while (t is not null) {
173+
foreach (var i in t.Interfaces) {
174+
if (interfaceNames.Contains (i.InterfaceType.FullName)) {
175+
implementedInterface = i.InterfaceType.FullName;
176+
return true;
177+
}
178+
}
179+
180+
t = t.GetBaseType (resolver);
128181
}
182+
129183
return false;
130184
}
131185

src/Java.Interop.Tools.JavaCallableWrappers/Java.Interop.Tools.JavaCallableWrappers.Adapters/CecilImporter.cs

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

1515
public class CecilImporter
1616
{
17+
static IList<string> android_manifest_types = ["Android.App.Activity", "Android.App.Application", "Android.App.Service", "Android.Content.BroadcastReceiver", "Android.Content.ContentProvider"];
18+
1719
// Don't expose internal "outerType" parameter to the public API
1820
public static CallableWrapperType CreateType (TypeDefinition type, IMetadataResolver resolver, CallableWrapperReaderOptions? options = null)
1921
=> CreateType (type, resolver, options, null);
@@ -38,11 +40,7 @@ static CallableWrapperType CreateType (TypeDefinition type, IMetadataResolver re
3840
options ??= new CallableWrapperReaderOptions ();
3941

4042
if (string.IsNullOrEmpty (package) &&
41-
(type.IsSubclassOf ("Android.App.Activity", resolver) ||
42-
type.IsSubclassOf ("Android.App.Application", resolver) ||
43-
type.IsSubclassOf ("Android.App.Service", resolver) ||
44-
type.IsSubclassOf ("Android.Content.BroadcastReceiver", resolver) ||
45-
type.IsSubclassOf ("Android.Content.ContentProvider", resolver)))
43+
(type.IsSubclassOfAny (android_manifest_types, resolver, out var _)))
4644
Diagnostic.Error (4203, CecilExtensions.LookupSource (type), Localization.Resources.JavaCallableWrappers_XA4203, jniName);
4745

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

127-
foreach (var bt in type.GetBaseTypes (resolver)) {
125+
TypeDefinition? bt = type;
126+
127+
while ((bt = bt.GetBaseType (resolver)) != null) {
128128
ctorTypes.Add (bt);
129129
var rattr = CecilExtensions.GetTypeRegistrationAttributes (bt).FirstOrDefault ();
130130

src/Java.Interop.Tools.JavaCallableWrappers/Java.Interop.Tools.JavaCallableWrappers.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFramework>netstandard2.0</TargetFramework>
5-
<LangVersion>11.0</LangVersion>
5+
<LangVersion>12.0</LangVersion>
66
<Nullable>enable</Nullable>
77
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
88
<SignAssembly>true</SignAssembly>

src/Java.Interop.Tools.TypeNameMappings/Java.Interop.Tools.TypeNameMappings/JavaNativeTypeManager.cs

+9-7
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ public static bool IsApplication (TypeDefinition type, TypeDefinitionCache cache
438438

439439
public static bool IsApplication (TypeDefinition type, IMetadataResolver resolver)
440440
{
441-
return type.GetBaseTypes (resolver).Any (b => b.FullName == "Android.App.Application");
441+
return type.IsSubclassOf ("Android.App.Application", resolver);
442442
}
443443

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

450450
public static bool IsInstrumentation (TypeDefinition type, IMetadataResolver resolver)
451451
{
452-
return type.GetBaseTypes (resolver).Any (b => b.FullName == "Android.App.Instrumentation");
452+
return type.IsSubclassOf ("Android.App.Instrumentation", resolver);
453453
}
454454

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

532+
static IList<string> java_interface_types = ["Android.Runtime.IJavaObject", "Java.Interop.IJavaPeerable"];
533+
532534
static string? ToJniName (TypeDefinition type, ExportParameterKind exportKind, IMetadataResolver cache)
533535
{
534536
if (type == null)
@@ -540,8 +542,7 @@ public static string ToJniName (TypeDefinition type, IMetadataResolver resolver)
540542
if (type.FullName == "System.String")
541543
return "java/lang/String";
542544

543-
if (!type.ImplementsInterface ("Android.Runtime.IJavaObject", cache) &&
544-
!type.ImplementsInterface ("Java.Interop.IJavaPeerable", cache)) {
545+
if (!type.ImplementsAnyInterface (java_interface_types, cache, out var _)) {
545546
return GetSpecialExportJniType (type.FullName, exportKind);
546547
}
547548

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

737-
foreach (var baseType in type.GetBaseTypes (cache)) {
738-
if (baseType == null)
739-
continue;
738+
TypeDefinition? baseType = type;
739+
740+
while ((baseType = baseType.GetBaseType (cache)) != null) {
741+
740742
if (!baseType.AnyCustomAttributes (typeof (RegisterAttribute)))
741743
continue;
742744

0 commit comments

Comments
 (0)