1bb6d6fb0e14801a6f750a69ab49737510b7e652
[mono.git] / mcs / tools / tuner / Mono.Tuner / CustomizeActions.cs
1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.IO;
5 using System.Linq;
6
7 using Mono.Linker;
8 using Mono.Linker.Steps;
9
10 using Mono.Cecil;
11 using Mono.Cecil.Cil;
12
13 namespace Mono.Tuner {
14
15         public class CustomizeActions : BaseStep {
16
17                 readonly bool link_sdk_only;
18                 readonly HashSet<string> skipped_assemblies;
19
20                 public CustomizeActions (bool link_sdk_only, IEnumerable<string> skipped_assemblies)
21                 {
22                         this.link_sdk_only = link_sdk_only;
23                         this.skipped_assemblies = new HashSet<string> (skipped_assemblies);
24                 }
25
26                 protected override void ProcessAssembly (AssemblyDefinition assembly)
27                 {
28                         if (!IsSkipped (assembly) && IsLinked (assembly)) {
29                                 if (!Annotations.HasAction (assembly)) // stray assembly not picked up when resolving references
30                                         Annotations.SetAction (assembly, AssemblyAction.Link);
31                                 return;
32                         }
33                         ProcessUserAssembly (assembly);
34                 }
35
36                 protected virtual bool IsPreservedAttribute (CustomAttribute attribute)
37                 {
38                         // [assembly: Preserve (type)] does not preserve all the code in the assembly, in fact it might
39                         // not preserve anything in _this_ assembly, but something in a separate assembly (reference)
40                         if (attribute.HasConstructorArguments)
41                                 return false;
42                         return (attribute.AttributeType.Name == "PreserveAttribute");
43                 }
44
45                 protected virtual bool IsLinkerSafeAttribute (CustomAttribute attribute)
46                 {
47                         return (attribute.AttributeType.Name == "LinkerSafeAttribute");
48                 }
49
50                 const ModuleAttributes Supported = ModuleAttributes.ILOnly | ModuleAttributes.Required32Bit | 
51                         ModuleAttributes.Preferred32Bit | ModuleAttributes.StrongNameSigned;
52
53                 protected virtual bool IsSkipped (AssemblyDefinition assembly)
54                 {
55                         // Cecil can't save back mixed-mode assemblies - so we can't link them
56                         if ((assembly.MainModule.Attributes & ~Supported) != 0)
57                                 return true;
58
59                         if (assembly.HasCustomAttributes) {
60                                 foreach (var ca in assembly.CustomAttributes) {
61                                         if (IsPreservedAttribute (ca))
62                                                 return true;
63                                 }
64                         }
65                         return skipped_assemblies.Contains (assembly.Name.Name);
66                 }
67
68                 protected virtual bool IsLinked (AssemblyDefinition assembly)
69                 {
70                         // LinkAll
71                         if (!link_sdk_only)
72                                 return true;
73                         // Link SDK : applies to BCL/SDK and product assembly (e.g. monotouch.dll)
74                         if (Profile.IsSdkAssembly (assembly))
75                                 return true;
76                         if (Profile.IsProductAssembly (assembly))
77                             return true;
78                         // the assembly can be marked with [LinkAssembly]
79                         if (assembly.HasCustomAttributes) {
80                                 foreach (var ca in assembly.CustomAttributes) {
81                                         if (IsLinkerSafeAttribute (ca))
82                                                 return true;
83                                 }
84                         }
85                         return false;
86                 }
87
88                 protected void ProcessUserAssembly (AssemblyDefinition assembly)
89                 {
90                         ResolveFromAssemblyStep.ProcessLibrary (Context, assembly);
91                 }
92         }
93 }