diff --git a/nukebuild/RefAssemblyGenerator.cs b/nukebuild/RefAssemblyGenerator.cs index 912f74cdf9..5c5324ac8f 100644 --- a/nukebuild/RefAssemblyGenerator.cs +++ b/nukebuild/RefAssemblyGenerator.cs @@ -18,31 +18,39 @@ public class RefAssemblyGenerator var def = AssemblyDef.Load(new MemoryStream(File.ReadAllBytes(file))); + var obsoleteAttribute = new TypeRefUser(def.ManifestModule, "System", "ObsoleteAttribute", def.ManifestModule.CorLibTypes.AssemblyRef); + var obsoleteCtor = def.ManifestModule.Import(new MemberRefUser(def.ManifestModule, ".ctor", + new MethodSig(CallingConvention.Default, 0, def.ManifestModule.CorLibTypes.Void, new TypeSig[] + { + def.ManifestModule.CorLibTypes.String + }), obsoleteAttribute)); + foreach(var t in def.ManifestModule.Types) - ProcessType(t); + ProcessType(t, obsoleteCtor); def.Write(file, new ModuleWriterOptions(def.ManifestModule) { StrongNameKey = new StrongNameKey(snk), }); } - static void ProcessType(TypeDef type) + static void ProcessType(TypeDef type, MemberRef obsoleteCtor) { foreach (var nested in type.NestedTypes) - ProcessType(nested); + ProcessType(nested, obsoleteCtor); if (type.IsInterface) { var hideMethods = type.Name.EndsWith("Impl"); var injectMethod = hideMethods || type.CustomAttributes.Any(a => a.AttributeType.FullName.EndsWith("NotClientImplementableAttribute")); - + if (hideMethods) { foreach (var m in type.Methods) { - m.Attributes |= MethodAttributes.Public | MethodAttributes.Assembly; - m.Attributes ^= MethodAttributes.Public; + var dflags = MethodAttributes.Public | MethodAttributes.Family | MethodAttributes.FamORAssem | + MethodAttributes.FamANDAssem | MethodAttributes.Assembly; + m.Attributes = ((m.Attributes | dflags) ^ dflags) | MethodAttributes.Assembly; } } @@ -55,8 +63,37 @@ public class RefAssemblyGenerator | MethodAttributes.NewSlot | MethodAttributes.HideBySig)); } + + var forceUnstable = type.CustomAttributes.Any(a => + a.AttributeType.FullName.EndsWith("UnstableAttribute")); + + foreach (var m in type.Methods) + MarkAsUnstable(m, obsoleteCtor, forceUnstable); + foreach (var m in type.Properties) + MarkAsUnstable(m, obsoleteCtor, forceUnstable); + foreach (var m in type.Events) + MarkAsUnstable(m, obsoleteCtor, forceUnstable); + } } + + static void MarkAsUnstable(IMemberDef def, MemberRef obsoleteCtor, bool force) + { + if (!force + || def.HasCustomAttributes == false + || !def.CustomAttributes.Any(a => + a.AttributeType.FullName.EndsWith("UnstableAttribute"))) + return; + + if (def.CustomAttributes.Any(a => a.TypeFullName.EndsWith("ObsoleteAttribute"))) + return; + + def.CustomAttributes.Add(new CustomAttribute(obsoleteCtor, new CAArgument[] + { + new(def.Module.CorLibTypes.String, + "This is a part of unstable API and can be changed in minor releases. You have been warned") + })); + } public static void GenerateRefAsmsInPackage(string packagePath) {