5 // Jb Evain (jbevain@gmail.com)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 using System
.Collections
;
33 namespace Mono
.Linker
.Steps
{
35 public class CleanStep
: BaseStep
{
37 protected override void ProcessAssembly (AssemblyDefinition assembly
)
39 if (Annotations
.GetAction (assembly
) == AssemblyAction
.Link
)
40 CleanAssembly (assembly
);
43 static void CleanAssembly (AssemblyDefinition asm
)
45 CleanMemberReferences (asm
.MainModule
);
46 foreach (TypeDefinition type
in asm
.MainModule
.Types
)
50 static void CleanMemberReferences (ModuleDefinition module
)
52 foreach (MemberReference reference
in new ArrayList (module
.MemberReferences
)) {
53 GenericInstanceType git
= reference
.DeclaringType
as GenericInstanceType
;
57 foreach (TypeReference arg
in git
.GenericArguments
)
58 if (!CheckType (module
, arg
))
59 module
.MemberReferences
.Remove (reference
);
63 static bool CheckType (ModuleDefinition module
, TypeReference reference
)
65 TypeSpecification spec
= reference
as TypeSpecification
;
67 return CheckType (module
, spec
.ElementType
);
69 TypeDefinition type
= reference
as TypeDefinition
;
73 return module
.Types
.Contains (type
);
76 static void CleanType (TypeDefinition type
)
78 CleanNestedTypes (type
);
79 CleanProperties (type
);
83 static void CleanNestedTypes (TypeDefinition type
)
85 foreach (TypeDefinition nested
in new ArrayList (type
.NestedTypes
))
86 if (!type
.Module
.Types
.Contains (nested
))
87 type
.NestedTypes
.Remove (nested
);
90 static MethodDefinition
CheckMethod (TypeDefinition type
, MethodDefinition method
)
95 return type
.Methods
.Contains (method
) ? method
: null;
98 static void CleanEvents (TypeDefinition type
)
100 foreach (EventDefinition evt
in new ArrayList (type
.Events
)) {
101 evt
.AddMethod
= CheckMethod (type
, evt
.AddMethod
);
102 evt
.InvokeMethod
= CheckMethod (type
, evt
.InvokeMethod
);
103 evt
.RemoveMethod
= CheckMethod (type
, evt
.RemoveMethod
);
105 if (!IsEventUsed (evt
))
106 type
.Events
.Remove (evt
);
110 static bool IsEventUsed (EventDefinition evt
)
112 return evt
.AddMethod
!= null || evt
.InvokeMethod
!= null || evt
.RemoveMethod
!= null;
115 static void CleanProperties (TypeDefinition type
)
117 foreach (PropertyDefinition prop
in new ArrayList (type
.Properties
)) {
118 prop
.GetMethod
= CheckMethod (type
, prop
.GetMethod
);
119 prop
.SetMethod
= CheckMethod (type
, prop
.SetMethod
);
121 if (!IsPropertyUsed (prop
))
122 type
.Properties
.Remove (prop
);
126 static bool IsPropertyUsed (PropertyDefinition prop
)
128 return prop
.GetMethod
!= null || prop
.SetMethod
!= null;