Skip to content

Commit e176e65

Browse files
[generator] covariant return type fixes need to happen later on
When testing generator upstream in xamarin-android, I was getting NREs generating `Mono.Android.dll`. It appears that `OnValidate` was a bit too early to do the work for fixing covariant return types. It seems that `OnValidate` needs to happen on all base classes and interfaces, which *can* work if your types happen to be in the right order. So I followed the pattern for some of the other fixups in generator: - Add a `FixupCovariantReturnTypes` method to `GenBase` - Call this as a “pass” that happens first, before `FillProperties` - Make sure to call `FixupCovariantReturnTypes` recursively on nested types Also: - Made the variable declarations for `foreach` loops in `CodeGenerator` all match
1 parent d9e0953 commit e176e65

File tree

2 files changed

+26
-16
lines changed

2 files changed

+26
-16
lines changed

tools/generator/CodeGenerator.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -323,16 +323,19 @@ static void Run (CodeGeneratorOptions options, DirectoryAssemblyResolver resolve
323323
if (api_versions_xml != null)
324324
ApiVersionsSupport.AssignApiLevels (gens, api_versions_xml);
325325

326-
foreach (GenBase gen in gens)
326+
foreach (var gen in gens)
327+
gen.FixupCovariantReturnTypes ();
328+
329+
foreach (var gen in gens)
327330
gen.FillProperties ();
328331

329332
foreach (var gen in gens)
330333
gen.UpdateEnums (opt);
331334

332-
foreach (GenBase gen in gens)
335+
foreach (var gen in gens)
333336
gen.FixupMethodOverrides ();
334337

335-
foreach (GenBase gen in gens)
338+
foreach (var gen in gens)
336339
gen.FixupExplicitImplementation ();
337340

338341
GenerateAnnotationAttributes (gens, annotations_zips);

tools/generator/GenBase.cs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -415,19 +415,6 @@ bool ValidateMethod (CodeGenerationOptions opt, Method m)
415415
if (!m.Validate (opt, TypeParameters)) {
416416
return false;
417417
}
418-
419-
//Fix up Java covariant return types, C# return type must match the base return type
420-
var baseCovariantMethod = BaseGen?.methods.FirstOrDefault (bm => bm.IsCovariantOverride (m));
421-
if (baseCovariantMethod == null) {
422-
baseCovariantMethod = ifaces.OfType<InterfaceGen> ()
423-
.SelectMany (i => i.methods)
424-
.FirstOrDefault (im => im.IsCovariantOverride (m));
425-
}
426-
if (baseCovariantMethod != null && m.ManagedReturn == null) {
427-
m.RetVal.FullName = baseCovariantMethod.ReturnType;
428-
m.RetVal.ToNativeOverride = baseCovariantMethod.RetVal.ToNative;
429-
}
430-
431418
return true;
432419
}
433420

@@ -740,6 +727,26 @@ public void StripNonBindables ()
740727
n.StripNonBindables ();
741728
}
742729

730+
public void FixupCovariantReturnTypes()
731+
{
732+
//Fix up Java covariant return types, C# return type must match the base return type
733+
foreach (Method m in methods) {
734+
var baseCovariantMethod = BaseGen?.methods.FirstOrDefault (bm => bm.IsCovariantOverride (m));
735+
if (baseCovariantMethod == null) {
736+
baseCovariantMethod = ifaces.OfType<InterfaceGen> ()
737+
.SelectMany (i => i.methods)
738+
.FirstOrDefault (im => im.IsCovariantOverride (m));
739+
}
740+
if (baseCovariantMethod != null && m.ManagedReturn == null) {
741+
m.RetVal.FullName = baseCovariantMethod.ReturnType;
742+
m.RetVal.ToNativeOverride = baseCovariantMethod.RetVal.ToNative;
743+
}
744+
}
745+
746+
foreach (var nt in NestedTypes)
747+
nt.FixupCovariantReturnTypes ();
748+
}
749+
743750
public void FillProperties ()
744751
{
745752
if (property_filled)

0 commit comments

Comments
 (0)