Skip to content

Commit de64e7b

Browse files
atsushienojonpryor
authored andcommitted
[generator][api-xml-adjuster] Fix managed type resolution in API adjuster. (#86)
Until now, ApiXmlAdjuster was trying to resolve types using ClassGen.BaseGen property which is in fact assigned only after Validate() step in generator. API XML analyzer work is done way before that step, and therefore it failed to resolve types from managed code (DLL references). Missing type hierarchy in Java type model from managed code means that any bindings that references Mono.Android (which wouldn't?) had to rely on insufficient hierarchy. Especially, it failed to resolve method overrides when the target Java library types overrode methods in android.jar indirectly. SherlockExpandableListActivity.addContentView() was such a method. And it had appeared as a regression from our MSBuild tests[*1]. Fixes: - removed dependency on BaseGen in ApiXmlAdjuster. Use BaseType instead, which doesn't depend on validation step. - Though this change uncovered an issue that Ctor and Parameter needed to hold Java type information. So, made some changes to them. - Now that ApiXmlAdjuster is getting valid managed type hierarchy, it had uncovered another kind of issues: managed objects need to exist to not cause some null crashes. Hence there is ManagedType class now. - Type resolution now premises this ManagedType in type resolver code. - Fixed incorrect Load() invocation for ClassGen and InterfaceGen (that had caused missing BaseType information). - Added (almost irrelevant) ApiXmlAdjuster test to make sure override resolution is done for overrides from indirect inheritance. [*1] that needs to be OSS-ed...
1 parent 40b75e9 commit de64e7b

File tree

8 files changed

+79
-15
lines changed

8 files changed

+79
-15
lines changed

src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApi.XmlModel.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,37 @@ public override string ToString ()
108108
}
109109
}
110110

111+
112+
class ManagedType : JavaType
113+
{
114+
static JavaPackage dummy_system_package, dummy_system_io_package;
115+
static JavaType system_object, system_exception, system_io_stream;
116+
117+
static ManagedType ()
118+
{
119+
dummy_system_package = new JavaPackage (null) { Name = "System" };
120+
system_object = new ManagedType (dummy_system_package) { Name = "Object" };
121+
system_exception = new ManagedType (dummy_system_package) { Name = "Exception" };
122+
dummy_system_package.Types.Add (system_object);
123+
dummy_system_package.Types.Add (system_exception);
124+
dummy_system_io_package = new JavaPackage (null) { Name = "System.IO" };
125+
system_io_stream = new ManagedType (dummy_system_package) { Name = "Stream" };
126+
dummy_system_io_package.Types.Add (system_io_stream);
127+
}
128+
129+
public static IEnumerable<JavaPackage> DummyManagedPackages {
130+
get {
131+
yield return dummy_system_package;
132+
yield return dummy_system_io_package;
133+
}
134+
}
135+
136+
public ManagedType (JavaPackage package) : base (package)
137+
{
138+
}
139+
}
140+
141+
111142
public partial class JavaImplements
112143
{
113144
public string Name { get; set; }

src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiOverrideMarkerExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ static void MarkBaseMethod (this JavaClass cls, JavaMethod method)
3636
{
3737
JavaClass k = cls;
3838
while (true) {
39-
k = k.ResolvedExtends != null ? (JavaClass) k.ResolvedExtends.ReferencedType : null;
39+
k = k.ResolvedExtends != null ? k.ResolvedExtends.ReferencedType as JavaClass : null;
4040
if (k == null)
4141
break;
4242

src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiTypeResolverExtensions.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,12 @@ public static JavaType FindNonGenericType (this JavaApi api, string name)
3838
var ret = api.Packages
3939
.SelectMany (p => p.Types)
4040
.FirstOrDefault (t => name.StartsWith (t.Parent.Name, StringComparison.Ordinal) && name == t.Parent.Name + '.' + t.Name);
41+
if (ret == null)
42+
ret = ManagedType.DummyManagedPackages
43+
.SelectMany (p => p.Types)
44+
.FirstOrDefault (t => t.FullName == name);
4145
if (ret == null)
4246
throw new JavaTypeResolutionException (string.Format ("Type '{0}' was not found.", name));
43-
4447
return ret;
4548
}
4649

src/Xamarin.Android.Tools.ApiXmlAdjuster/Tests/OverrideMarkerTest.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System;
2+
using System.IO;
23
using System.Linq;
4+
using System.Xml;
35
using NUnit.Framework;
46

57
namespace Xamarin.Android.Tools.ApiXmlAdjuster.Tests
@@ -29,6 +31,32 @@ public void InstantiatedGenericArgumentName ()
2931
Assert.AreEqual (method.Parameters.First (), method.Parameters.Last (), "There should be only one parameter.");
3032
Assert.AreEqual ("T", para.InstantiatedGenericArgumentName, "InstantiatedGenericArgumentName mismatch");
3133
}
34+
35+
[Test]
36+
public void AncestralOverrides ()
37+
{
38+
string xml = @"<api>
39+
<package name='XXX'>
40+
<class abstract='true' deprecated='not deprecated' extends='android.app.ExpandableListActivity' extends-generic-aware='android.app.ExpandableListActivity' final='false' name='SherlockExpandableListActivity' static='false' visibility='public'>
41+
<method abstract='false' deprecated='not deprecated' final='false' name='addContentView' native='false' return='void' static='false' synchronized='false' visibility='public'>
42+
<parameter name = 'view' type='android.view.View'>
43+
</parameter>
44+
<parameter name = 'params' type='android.view.ViewGroup.LayoutParams'>
45+
</parameter>
46+
</method>
47+
</class>
48+
</package>
49+
</api>";
50+
var xapi = JavaApiTestHelper.GetLoadedApi ();
51+
using (var xr = XmlReader.Create (new StringReader (xml)))
52+
xapi.Load (xr, false);
53+
xapi.Resolve ();
54+
xapi.CreateGenericInheritanceMapping ();
55+
xapi.MarkOverrides ();
56+
var t = xapi.Packages.First (_ => _.Name == "XXX").Types.First (_ => _.Name == "SherlockExpandableListActivity");
57+
var m = t.Members.OfType<JavaMethod> ().First (_ => _.Name == "addContentView");
58+
Assert.IsNotNull (m.BaseMethod, "base method not found");
59+
}
3260
}
3361
}
3462

tools/generator/Ctor.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ public ManagedCtor (GenBase declaringType, MethodDefinition m)
2727
// the type of the containing class must be inserted as the first
2828
// argument
2929
if (IsNonStaticNestedType)
30-
Parameters.AddFirst (Parameter.FromManagedType (m.DeclaringType.DeclaringType));
31-
30+
Parameters.AddFirst (Parameter.FromManagedType (m.DeclaringType.DeclaringType, DeclaringType.JavaName));
3231
var regatt = m.CustomAttributes.FirstOrDefault (a => a.AttributeType.FullName == "Android.Runtime.RegisterAttribute");
3332
is_acw = regatt != null;
3433
foreach (var p in support.GetParameters (regatt))

tools/generator/Field.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public override string Visibility {
7676

7777
protected override Parameter SetterParameter {
7878
get {
79-
var p = Parameter.FromManagedType (f.FieldType.Resolve ());
79+
var p = Parameter.FromManagedType (f.FieldType.Resolve (), null);
8080
p.Name = "value";
8181
return p;
8282
}

tools/generator/JavaApiDllLoaderExtensions.cs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ public static void LoadReferences (this JavaApi api, GenBase [] gens)
1919
if (gen is InterfaceGen) {
2020
var iface = new JavaInterface (pkg);
2121
pkg.Types.Add (iface);
22-
iface.Load (gen);
22+
iface.Load ((InterfaceGen) gen);
2323
} else if (gen is ClassGen) {
2424
var kls = new JavaClass (pkg);
2525
pkg.Types.Add (kls);
26-
kls.Load (gen);
26+
kls.Load ((ClassGen) gen);
2727
}
2828
else
2929
throw new InvalidOperationException ();
@@ -75,11 +75,11 @@ static void Load (this JavaInterface iface, InterfaceGen gen)
7575
((JavaType) iface).Load (gen);
7676
}
7777

78-
static string ExpandTypeParameters (GenericParameterDefinitionList tps)
78+
static string ExpandTypeParameters (ISymbol [] tps)
7979
{
8080
if (tps == null)
8181
return null;
82-
return '<' + string.Join (", ", tps.Select (_ => _.Name)) + '>';
82+
return '<' + string.Join (", ", tps.Select (_ => _.JavaName)) + '>';
8383
}
8484

8585
static void Load (this JavaClass kls, ClassGen gen)
@@ -88,10 +88,13 @@ static void Load (this JavaClass kls, ClassGen gen)
8888

8989
kls.Abstract = gen.IsAbstract;
9090
kls.Final = gen.IsFinal;
91-
if (gen.BaseGen != null) {
92-
kls.Extends = gen.BaseGen.JavaSimpleName;
93-
kls.ExtendsGeneric = gen.BaseGen.JavaSimpleName + ExpandTypeParameters (gen.BaseGen.TypeParameters);
94-
kls.ExtendedJniExtends = gen.BaseGen.JniName;
91+
var baseGen = gen.BaseType != null ? SymbolTable.Lookup (gen.BaseType) : null;
92+
93+
if (baseGen != null) {
94+
kls.Extends = baseGen.JavaName;
95+
var gs = baseGen as GenericSymbol;
96+
kls.ExtendsGeneric = gs != null ? gs.JavaName + ExpandTypeParameters (gs.TypeParams) : baseGen.JavaName;
97+
kls.ExtendedJniExtends = baseGen.JniName;
9598
}
9699
foreach (var c in gen.Ctors) {
97100
var ctor = new JavaConstructor (kls);

tools/generator/Parameter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,9 +291,9 @@ public static Parameter FromManagedParameter (ParameterDefinition p, string jnit
291291
return new Parameter (SymbolTable.MangleName (p.Name), jnitype ?? p.ParameterType.FullNameCorrected (), null, isEnumType, rawtype);
292292
}
293293

294-
public static Parameter FromManagedType (TypeDefinition t)
294+
public static Parameter FromManagedType (TypeDefinition t, string javaType)
295295
{
296-
return new Parameter ("__self", t.FullName, null, false);
296+
return new Parameter ("__self", javaType ?? t.FullName, t.FullName, false);
297297
}
298298
#endif
299299
}

0 commit comments

Comments
 (0)