From 2b7dc07d20fc06344d7f164af8934f5e755572c2 Mon Sep 17 00:00:00 2001 From: Sebastien Pouliot Date: Tue, 23 Mar 2021 20:05:49 -0400 Subject: [PATCH] [generate-type-forwarders] Fix issues with properties stubs (#10941) Examples * Fix visibility, e.g. `protected` ```diff - public virtual System.IntPtr RawJointLandmarks { + protected virtual System.IntPtr RawJointLandmarks { ``` * Remove non-visible properties, e.g. `internal` ```diff - public virtual System.IntPtr _AddressBook { - get { throw new global::System.PlatformNotSupportedException (global::Constants.UnavailableOnMacCatalyst); } - set { throw new global::System.PlatformNotSupportedException (global::Constants.UnavailableOnMacCatalyst); } - } ``` * Fix `abstract` members ```diff -public abstract ARSession Session { get; } +public virtual ARSession Session { get; } ``` --- src/generate-type-forwarders/Program.cs | 79 ++++++++++++++++++++----- 1 file changed, 63 insertions(+), 16 deletions(-) diff --git a/src/generate-type-forwarders/Program.cs b/src/generate-type-forwarders/Program.cs index f9b180c2e255..f9f8a65c948b 100644 --- a/src/generate-type-forwarders/Program.cs +++ b/src/generate-type-forwarders/Program.cs @@ -18,7 +18,7 @@ */ namespace GenerateTypeForwarders { - class MainClass { + static class MainClass { public static int Main (string [] args) { var forwardFrom = args [0]; @@ -27,6 +27,30 @@ public static int Main (string [] args) return Fix (forwardFrom, forwardTo, output); } + static bool IsVisible (this TypeDefinition type) + { + if (!type.IsNested) + return true; + return type.IsNestedPublic || type.IsNestedFamily; + } + + static bool IsVisible (this MethodDefinition method) + { + if (method is null) + return false; + return method.IsPublic || method.IsFamily; + } + + static bool IsVisible (this PropertyDefinition property) + { + return property.GetMethod.IsVisible () || property.SetMethod.IsVisible (); + } + + static bool IsVisible (this FieldDefinition field) + { + return field.IsPublic || field.IsFamily; + } + static void EmitTypeName (StringBuilder sb, TypeReference type) { if (type.FullName == "System.Void") { @@ -357,10 +381,14 @@ static bool HasPropertyInTypeHierarchy (TypeDefinition type, MethodDefinition ac static void EmitProperty (StringBuilder sb, PropertyDefinition pd, int indent) { - var strIndent = new string ('\t', indent); - sb.Append (strIndent); - sb.Append ("public "); - var m = pd.GetMethod ?? pd.SetMethod; + sb.Append ('\t', indent); + var gm = pd.GetMethod; + var sm = pd.SetMethod; + var m = gm ?? sm; + if (m.IsPublic) + sb.Append ("public "); + else + sb.Append ("protected "); if (m.IsStatic) { sb.Append ("static "); if (HasPropertyInTypeHierarchy (pd.DeclaringType, m, out var _)) @@ -373,20 +401,32 @@ static void EmitProperty (StringBuilder sb, PropertyDefinition pd, int indent) sb.Append ("new "); } } else if (!pd.DeclaringType.IsSealed) { - sb.Append ("virtual "); + if (m.IsAbstract) + sb.Append ("abstract "); + else + sb.Append ("virtual "); } } EmitTypeName (sb, pd.PropertyType); sb.Append (' '); sb.Append (pd.Name); sb.AppendLine (" {"); - if (pd.GetMethod != null) { - sb.AppendLine ($"{strIndent}\tget {{ throw new global::System.PlatformNotSupportedException (global::Constants.UnavailableOnMacCatalyst); }}"); + if (gm.IsVisible ()) { + sb.Append ('\t', indent + 1); + if (gm.IsAbstract) + sb.AppendLine ("get;"); + else + sb.AppendLine ("get { throw new global::System.PlatformNotSupportedException (global::Constants.UnavailableOnMacCatalyst); }"); } - if (pd.SetMethod != null) { - sb.AppendLine ($"{strIndent}\tset {{ throw new global::System.PlatformNotSupportedException (global::Constants.UnavailableOnMacCatalyst); }}"); + if (pd.SetMethod.IsVisible ()) { + sb.Append ('\t', indent + 1); + if (sm.IsAbstract) + sb.AppendLine ("set;"); + else + sb.AppendLine ("set { throw new global::System.PlatformNotSupportedException (global::Constants.UnavailableOnMacCatalyst); }"); } - sb.AppendLine ($"{strIndent}}}"); + sb.Append ('\t', indent); + sb.AppendLine ("}"); } static void EmitEvent (StringBuilder sb, EventDefinition ed, int indent) @@ -425,7 +465,12 @@ static void EmitPNSE (StringBuilder sb, TypeDefinition type, int indent) EmitParameters (sb, invoke.Parameters); sb.AppendLine (");"); } else { - sb.Append ($"{strIndent}public "); + sb.Append (strIndent); + // other are filtered not to generate stubs + if (type.IsNestedFamily) + sb.Append ("protected "); + else + sb.Append ("public "); if (type.IsInterface) { sb.Append ("interface "); } else if (type.IsEnum) { @@ -484,7 +529,7 @@ static void EmitPNSE (StringBuilder sb, TypeDefinition type, int indent) sb.Append (" {"); sb.AppendLine (); foreach (var nestedType in type.NestedTypes) { - if (nestedType.IsNestedPrivate) + if (!nestedType.IsVisible ()) continue; EmitPNSE (sb, nestedType, indent + 1); } @@ -498,18 +543,20 @@ static void EmitPNSE (StringBuilder sb, TypeDefinition type, int indent) bt = bt.BaseType?.Resolve (); } foreach (var method in type.Methods) { + // need .ctor(IntPtr) for chaining + if (!method.IsVisible () && !method.IsConstructor) + continue; EmitPNSE (sb, method, indent + 1, nsobject); } foreach (var field in type.Fields) { - if (field.IsPrivate) + if (!field.IsVisible ()) continue; - EmitField (sb, field, indent + 1); } foreach (var prop in type.Properties) { - if (prop.GetMethod?.IsPrivate != false && prop.SetMethod?.IsPrivate != false) + if (!prop.IsVisible ()) continue; EmitProperty (sb, prop, indent + 1); }