瀏覽代碼

More patches

Nikita Tsukanov 2 年之前
父節點
當前提交
f9955f0c79
共有 1 個文件被更改,包括 43 次插入6 次删除
  1. 43 6
      nukebuild/RefAssemblyGenerator.cs

+ 43 - 6
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)
     {