5 // Jb Evain (jbevain@gmail.com)
8 // (C) 2007 Novell, Inc.
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System.Collections;
37 namespace Mono.Linker.Steps {
39 public class MarkStep : IStep {
41 protected LinkContext _context;
42 protected Queue _methods;
43 protected ArrayList _virtual_methods;
45 public AnnotationStore Annotations {
46 get { return _context.Annotations; }
51 _methods = new Queue ();
52 _virtual_methods = new ArrayList ();
55 public virtual void Process (LinkContext context)
65 foreach (AssemblyDefinition assembly in _context.GetAssemblies ())
66 InitializeAssembly (assembly);
69 protected virtual void InitializeAssembly (AssemblyDefinition assembly)
71 MarkAssembly (assembly);
72 foreach (TypeDefinition type in assembly.MainModule.Types) {
73 if (!Annotations.IsMarked (type))
76 InitializeType (type);
80 void InitializeType (TypeDefinition type)
85 InitializeFields (type);
87 InitializeMethods (type.Methods);
89 if (type.HasNestedTypes) {
90 foreach (var nested in type.NestedTypes) {
91 if (Annotations.IsMarked (nested))
92 InitializeType (nested);
97 void InitializeFields (TypeDefinition type)
99 foreach (FieldDefinition field in type.Fields)
100 if (Annotations.IsMarked (field))
104 void InitializeMethods (ICollection methods)
106 foreach (MethodDefinition method in methods)
107 if (Annotations.IsMarked (method))
108 EnqueueMethod (method);
114 throw new InvalidOperationException ("No entry methods");
116 while (!QueueIsEmpty ()) {
118 ProcessVirtualMethods ();
124 while (!QueueIsEmpty ()) {
125 MethodDefinition method = (MethodDefinition) _methods.Dequeue ();
126 Annotations.Push (method);
127 ProcessMethod (method);
134 return _methods.Count == 0;
137 protected virtual void EnqueueMethod (MethodDefinition method)
139 _methods.Enqueue (method);
142 void ProcessVirtualMethods ()
144 foreach (MethodDefinition method in _virtual_methods)
145 ProcessVirtualMethod (method);
148 void ProcessVirtualMethod (MethodDefinition method)
150 IList overrides = Annotations.GetOverrides (method);
151 if (overrides == null)
154 foreach (MethodDefinition @override in overrides)
155 ProcessOverride (@override);
158 void ProcessOverride (MethodDefinition method)
160 if (!Annotations.IsMarked (method.DeclaringType))
163 if (Annotations.IsProcessed (method))
166 if (Annotations.IsMarked (method))
170 ProcessVirtualMethod (method);
173 void MarkMarshalSpec (IMarshalInfoProvider spec)
175 if (!spec.HasMarshalInfo)
178 var marshaler = spec.MarshalInfo as CustomMarshalInfo;
179 if (marshaler == null)
182 MarkType (marshaler.ManagedType);
185 void MarkCustomAttributes (ICustomAttributeProvider provider)
187 if (!provider.HasCustomAttributes)
190 foreach (CustomAttribute ca in provider.CustomAttributes)
191 MarkCustomAttribute (ca);
194 protected virtual void MarkCustomAttribute (CustomAttribute ca)
196 MarkMethod (ca.Constructor);
198 MarkCustomAttributeArguments (ca);
200 TypeReference constructor_type = ca.Constructor.DeclaringType;
201 TypeDefinition type = constructor_type.Resolve ();
203 throw new ResolutionException (constructor_type);
205 MarkCustomAttributeProperties (ca, type);
206 MarkCustomAttributeFields (ca, type);
209 protected void MarkSecurityDeclarations (ISecurityDeclarationProvider provider)
211 // most security declarations are removed (if linked) but user code might still have some
212 // and if the attribtues references types then they need to be marked too
213 if ((provider == null) || !provider.HasSecurityDeclarations)
216 foreach (var sd in provider.SecurityDeclarations)
217 MarkSecurityDeclaration (sd);
220 protected virtual void MarkSecurityDeclaration (SecurityDeclaration sd)
222 if (!sd.HasSecurityAttributes)
225 foreach (var sa in sd.SecurityAttributes)
226 MarkSecurityAttribute (sa);
229 protected virtual void MarkSecurityAttribute (SecurityAttribute sa)
231 TypeReference security_type = sa.AttributeType;
232 TypeDefinition type = security_type.Resolve ();
234 throw new ResolutionException (security_type);
236 MarkType (security_type);
237 MarkSecurityAttributeProperties (sa, type);
238 MarkSecurityAttributeFields (sa, type);
241 protected void MarkSecurityAttributeProperties (SecurityAttribute sa, TypeDefinition attribute)
243 if (!sa.HasProperties)
246 foreach (var named_argument in sa.Properties)
247 MarkCustomAttributeProperty (named_argument, attribute);
250 protected void MarkSecurityAttributeFields (SecurityAttribute sa, TypeDefinition attribute)
255 foreach (var named_argument in sa.Fields)
256 MarkCustomAttributeField (named_argument, attribute);
259 protected void MarkCustomAttributeProperties (CustomAttribute ca, TypeDefinition attribute)
261 if (!ca.HasProperties)
264 foreach (var named_argument in ca.Properties)
265 MarkCustomAttributeProperty (named_argument, attribute);
268 protected void MarkCustomAttributeProperty (CustomAttributeNamedArgument namedArgument, TypeDefinition attribute)
270 PropertyDefinition property = GetProperty (attribute, namedArgument.Name);
271 if (property != null)
272 MarkMethod (property.SetMethod);
274 MarkIfType (namedArgument.Argument);
277 PropertyDefinition GetProperty (TypeDefinition type, string propertyname)
279 while (type != null) {
280 PropertyDefinition property = type.Properties.FirstOrDefault (p => p.Name == propertyname);
281 if (property != null)
284 type = type.BaseType != null ? ResolveTypeDefinition (type.BaseType) : null;
290 protected void MarkCustomAttributeFields (CustomAttribute ca, TypeDefinition attribute)
295 foreach (var named_argument in ca.Fields)
296 MarkCustomAttributeField (named_argument, attribute);
299 protected void MarkCustomAttributeField (CustomAttributeNamedArgument namedArgument, TypeDefinition attribute)
301 FieldDefinition field = GetField (attribute, namedArgument.Name);
305 MarkIfType (namedArgument.Argument);
308 FieldDefinition GetField (TypeDefinition type, string fieldname)
310 while (type != null) {
311 FieldDefinition field = type.Fields.FirstOrDefault (f => f.Name == fieldname);
315 type = type.BaseType != null ? ResolveTypeDefinition (type.BaseType) : null;
321 void MarkCustomAttributeArguments (CustomAttribute ca)
323 if (!ca.HasConstructorArguments)
326 foreach (var argument in ca.ConstructorArguments)
327 MarkIfType (argument);
330 void MarkIfType (CustomAttributeArgument argument)
332 var at = argument.Type;
334 var et = at.GetElementType ();
335 if (et.Namespace != "System" || et.Name != "Type")
339 foreach (var cac in (CustomAttributeArgument[]) argument.Value)
340 MarkWithResolvedScope ((TypeReference) cac.Value);
341 } else if (at.Namespace == "System" && at.Name == "Type") {
342 MarkType (argument.Type);
343 MarkWithResolvedScope ((TypeReference) argument.Value);
347 // custom attributes encoding means it's possible to have a scope that will point into a PCL facade
348 // even if we (just before saving) will resolve all type references (bug #26752)
349 void MarkWithResolvedScope (TypeReference type)
354 // a GenericInstanceType can could contains generic arguments with scope that
355 // needs to be updated out of the PCL facade (bug #28823)
356 var git = (type as GenericInstanceType);
357 if ((git != null) && git.HasGenericArguments) {
358 foreach (var ga in git.GenericArguments)
359 MarkWithResolvedScope (ga);
361 // we cannot set the Scope of a TypeSpecification but it's element type can be set
362 // e.g. System.String[] -> System.String
363 var ts = (type as TypeSpecification);
365 MarkWithResolvedScope (ts.GetElementType ());
369 var td = type.Resolve ();
371 type.Scope = td.Scope;
375 protected bool CheckProcessed (IMetadataTokenProvider provider)
377 if (Annotations.IsProcessed (provider))
380 Annotations.Processed (provider);
384 protected void MarkAssembly (AssemblyDefinition assembly)
386 if (CheckProcessed (assembly))
389 ProcessModule (assembly);
391 MarkCustomAttributes (assembly);
392 MarkSecurityDeclarations (assembly);
394 foreach (ModuleDefinition module in assembly.Modules)
395 MarkCustomAttributes (module);
398 void ProcessModule (AssemblyDefinition assembly)
400 // Pre-mark <Module> if there is any methods as they need to be executed
401 // at assembly load time
402 foreach (TypeDefinition type in assembly.MainModule.Types)
404 if (type.Name == "<Module>" && type.HasMethods)
412 protected void MarkField (FieldReference reference)
414 // if (IgnoreScope (reference.DeclaringType.Scope))
417 if (reference.DeclaringType is GenericInstanceType)
418 MarkType (reference.DeclaringType);
420 FieldDefinition field = ResolveFieldDefinition (reference);
423 throw new ResolutionException (reference);
425 if (CheckProcessed (field))
428 MarkType (field.DeclaringType);
429 MarkType (field.FieldType);
430 MarkCustomAttributes (field);
431 MarkMarshalSpec (field);
433 Annotations.Mark (field);
436 protected virtual bool IgnoreScope (IMetadataScope scope)
438 AssemblyDefinition assembly = ResolveAssembly (scope);
439 return Annotations.GetAction (assembly) != AssemblyAction.Link;
442 FieldDefinition ResolveFieldDefinition (FieldReference field)
444 FieldDefinition fd = field as FieldDefinition;
446 fd = field.Resolve ();
451 void MarkScope (IMetadataScope scope)
453 var provider = scope as IMetadataTokenProvider;
454 if (provider == null)
457 Annotations.Mark (provider);
460 protected virtual void MarkSerializable (TypeDefinition type)
462 MarkDefaultConstructor (type);
463 MarkMethodsIf (type.Methods, IsSpecialSerializationConstructorPredicate);
466 protected virtual TypeDefinition MarkType (TypeReference reference)
468 if (reference == null)
471 reference = GetOriginalType (reference);
473 if (reference is GenericParameter)
476 // if (IgnoreScope (reference.Scope))
479 TypeDefinition type = ResolveTypeDefinition (reference);
482 throw new ResolutionException (reference);
484 if (CheckProcessed (type))
487 Annotations.Push (type);
489 MarkScope (type.Scope);
490 MarkType (type.BaseType);
491 MarkType (type.DeclaringType);
492 MarkCustomAttributes (type);
493 MarkSecurityDeclarations (type);
495 if (IsMulticastDelegate (type)) {
496 MarkMethodCollection (type.Methods);
499 if (IsSerializable (type))
500 MarkSerializable (type);
502 MarkTypeSpecialCustomAttributes (type);
504 MarkGenericParameterProvider (type);
506 // keep fields for value-types and for classes with LayoutKind.Sequential or Explicit
507 if (type.IsValueType || !type.IsAutoLayout)
508 MarkFields (type, type.IsEnum);
510 if (type.HasInterfaces) {
511 foreach (TypeReference iface in type.Interfaces)
515 if (type.HasMethods) {
516 MarkMethodsIf (type.Methods, IsVirtualAndHasPreservedParent);
517 MarkMethodsIf (type.Methods, IsStaticConstructorPredicate);
520 DoAdditionalTypeProcessing (type);
524 Annotations.Mark (type);
526 ApplyPreserveInfo (type);
531 // Allow subclassers to mark additional things when marking a method
532 protected virtual void DoAdditionalTypeProcessing (TypeDefinition method)
536 void MarkTypeSpecialCustomAttributes (TypeDefinition type)
538 if (!type.HasCustomAttributes)
541 foreach (CustomAttribute attribute in type.CustomAttributes) {
542 switch (attribute.Constructor.DeclaringType.FullName) {
543 case "System.Xml.Serialization.XmlSchemaProviderAttribute":
544 MarkXmlSchemaProvider (type, attribute);
550 void MarkMethodSpecialCustomAttributes (MethodDefinition method)
552 if (!method.HasCustomAttributes)
555 foreach (CustomAttribute attribute in method.CustomAttributes) {
556 switch (attribute.Constructor.DeclaringType.FullName) {
557 case "System.Web.Services.Protocols.SoapHeaderAttribute":
558 MarkSoapHeader (method, attribute);
564 void MarkXmlSchemaProvider (TypeDefinition type, CustomAttribute attribute)
567 if (!TryGetStringArgument (attribute, out method_name))
570 MarkNamedMethod (type, method_name);
573 static bool TryGetStringArgument (CustomAttribute attribute, out string argument)
577 if (attribute.ConstructorArguments.Count < 1)
580 argument = attribute.ConstructorArguments [0].Value as string;
582 return argument != null;
585 protected int MarkNamedMethod (TypeDefinition type, string method_name)
587 if (!type.HasMethods)
591 foreach (MethodDefinition method in type.Methods) {
592 if (method.Name != method_name)
602 void MarkSoapHeader (MethodDefinition method, CustomAttribute attribute)
605 if (!TryGetStringArgument (attribute, out member_name))
608 MarkNamedField (method.DeclaringType, member_name);
609 MarkNamedProperty (method.DeclaringType, member_name);
612 void MarkNamedField (TypeDefinition type, string field_name)
617 foreach (FieldDefinition field in type.Fields) {
618 if (field.Name != field_name)
625 void MarkNamedProperty (TypeDefinition type, string property_name)
627 if (!type.HasProperties)
630 foreach (PropertyDefinition property in type.Properties) {
631 if (property.Name != property_name)
634 MarkMethod (property.GetMethod);
635 MarkMethod (property.SetMethod);
639 void MarkGenericParameterProvider (IGenericParameterProvider provider)
641 if (!provider.HasGenericParameters)
644 foreach (GenericParameter parameter in provider.GenericParameters)
645 MarkGenericParameter (parameter);
648 void MarkGenericParameter (GenericParameter parameter)
650 MarkCustomAttributes (parameter);
651 foreach (TypeReference constraint in parameter.Constraints)
652 MarkType (constraint);
655 bool IsVirtualAndHasPreservedParent (MethodDefinition method)
657 if (!method.IsVirtual)
660 var base_list = Annotations.GetBaseMethods (method);
661 if (base_list == null)
664 foreach (MethodDefinition @base in base_list) {
665 if (IgnoreScope (@base.DeclaringType.Scope))
668 if (IsVirtualAndHasPreservedParent (@base))
675 static MethodPredicate IsSpecialSerializationConstructorPredicate = new MethodPredicate (IsSpecialSerializationConstructor);
677 static bool IsSpecialSerializationConstructor (MethodDefinition method)
679 if (!IsConstructor (method))
682 var parameters = method.Parameters;
683 if (parameters.Count != 2)
686 return parameters [0].ParameterType.Name == "SerializationInfo" &&
687 parameters [1].ParameterType.Name == "StreamingContext";
690 delegate bool MethodPredicate (MethodDefinition method);
692 void MarkMethodsIf (ICollection methods, MethodPredicate predicate)
694 foreach (MethodDefinition method in methods)
695 if (predicate (method))
699 static MethodPredicate IsDefaultConstructorPredicate = new MethodPredicate (IsDefaultConstructor);
701 static bool IsDefaultConstructor (MethodDefinition method)
703 return IsConstructor (method) && !method.HasParameters;
706 static bool IsConstructor (MethodDefinition method)
708 return method.IsConstructor && !method.IsStatic;
711 protected void MarkDefaultConstructor (TypeDefinition type)
713 if ((type == null) || !type.HasMethods)
716 MarkMethodsIf (type.Methods, IsDefaultConstructorPredicate);
719 static MethodPredicate IsStaticConstructorPredicate = new MethodPredicate (IsStaticConstructor);
721 static bool IsStaticConstructor (MethodDefinition method)
723 return method.IsConstructor && method.IsStatic;
726 static bool IsSerializable (TypeDefinition td)
728 return (td.Attributes & TypeAttributes.Serializable) != 0;
731 static bool IsMulticastDelegate (TypeDefinition td)
733 return td.BaseType != null && td.BaseType.FullName == "System.MulticastDelegate";
736 protected TypeDefinition ResolveTypeDefinition (TypeReference type)
738 TypeDefinition td = type as TypeDefinition;
740 td = type.Resolve ();
745 protected TypeReference GetOriginalType (TypeReference type)
747 while (type is TypeSpecification) {
748 GenericInstanceType git = type as GenericInstanceType;
750 MarkGenericArguments (git);
752 var mod = type as IModifierType;
754 MarkModifierType (mod);
756 type = ((TypeSpecification) type).ElementType;
762 void MarkModifierType (IModifierType mod)
764 MarkType (mod.ModifierType);
767 void MarkGenericArguments (IGenericInstance instance)
769 foreach (TypeReference argument in instance.GenericArguments)
772 MarkGenericArgumentConstructors (instance);
775 void MarkGenericArgumentConstructors (IGenericInstance instance)
777 var arguments = instance.GenericArguments;
779 var generic_element = GetGenericProviderFromInstance (instance);
780 if (generic_element == null)
783 var parameters = generic_element.GenericParameters;
785 if (arguments.Count != parameters.Count)
788 for (int i = 0; i < arguments.Count; i++) {
789 var argument = arguments [i];
790 var parameter = parameters [i];
792 if (!parameter.HasDefaultConstructorConstraint)
795 var argument_definition = ResolveTypeDefinition (argument);
796 if (argument_definition == null)
799 MarkMethodsIf (argument_definition.Methods, ctor => !ctor.IsStatic && !ctor.HasParameters);
803 IGenericParameterProvider GetGenericProviderFromInstance (IGenericInstance instance)
805 var method = instance as GenericInstanceMethod;
807 return ResolveMethodDefinition (method.ElementMethod);
809 var type = instance as GenericInstanceType;
811 return ResolveTypeDefinition (type.ElementType);
816 void ApplyPreserveInfo (TypeDefinition type)
818 ApplyPreserveMethods (type);
820 if (!Annotations.IsPreserved (type))
823 switch (Annotations.GetPreserve (type)) {
824 case TypePreserve.All:
825 MarkFields (type, true);
828 case TypePreserve.Fields:
829 MarkFields (type, true);
831 case TypePreserve.Methods:
837 void ApplyPreserveMethods (TypeDefinition type)
839 var list = Annotations.GetPreservedMethods (type);
843 MarkMethodCollection (list);
846 void ApplyPreserveMethods (MethodDefinition method)
848 var list = Annotations.GetPreservedMethods (method);
852 MarkMethodCollection (list);
855 protected void MarkFields (TypeDefinition type, bool includeStatic)
860 foreach (FieldDefinition field in type.Fields) {
861 if (!includeStatic && field.IsStatic)
867 protected virtual void MarkMethods (TypeDefinition type)
870 MarkMethodCollection (type.Methods);
873 void MarkMethodCollection (IEnumerable methods)
875 foreach (MethodDefinition method in methods)
879 protected virtual MethodDefinition MarkMethod (MethodReference reference)
881 reference = GetOriginalMethod (reference);
883 if (reference.DeclaringType is ArrayType)
886 Annotations.Push (reference);
887 if (reference.DeclaringType is GenericInstanceType)
888 MarkType (reference.DeclaringType);
890 // if (IgnoreScope (reference.DeclaringType.Scope))
893 MethodDefinition method = ResolveMethodDefinition (reference);
895 if (method == null) {
897 throw new ResolutionException (reference);
900 if (Annotations.GetAction (method) == MethodAction.Nothing)
901 Annotations.SetAction (method, MethodAction.Parse);
903 EnqueueMethod (method);
910 AssemblyDefinition ResolveAssembly (IMetadataScope scope)
912 AssemblyDefinition assembly = _context.Resolve (scope);
913 MarkAssembly (assembly);
917 protected MethodReference GetOriginalMethod (MethodReference method)
919 while (method is MethodSpecification) {
920 GenericInstanceMethod gim = method as GenericInstanceMethod;
922 MarkGenericArguments (gim);
924 method = ((MethodSpecification) method).ElementMethod;
930 MethodDefinition ResolveMethodDefinition (MethodReference method)
932 MethodDefinition md = method as MethodDefinition;
934 md = method.Resolve ();
939 protected virtual void ProcessMethod (MethodDefinition method)
941 if (CheckProcessed (method))
944 MarkType (method.DeclaringType);
945 MarkCustomAttributes (method);
946 MarkSecurityDeclarations (method);
948 MarkGenericParameterProvider (method);
950 if (IsPropertyMethod (method))
951 MarkProperty (GetProperty (method));
952 else if (IsEventMethod (method))
953 MarkEvent (GetEvent (method));
955 if (method.HasParameters) {
956 foreach (ParameterDefinition pd in method.Parameters) {
957 MarkType (pd.ParameterType);
958 MarkCustomAttributes (pd);
959 MarkMarshalSpec (pd);
963 if (method.HasOverrides) {
964 foreach (MethodReference ov in method.Overrides)
968 MarkMethodSpecialCustomAttributes (method);
970 if (method.IsVirtual)
971 _virtual_methods.Add (method);
973 MarkBaseMethods (method);
975 MarkType (method.ReturnType);
976 MarkCustomAttributes (method.MethodReturnType);
977 MarkMarshalSpec (method.MethodReturnType);
979 if (ShouldParseMethodBody (method))
980 MarkMethodBody (method.Body);
982 DoAdditionalMethodProcessing (method);
984 Annotations.Mark (method);
986 ApplyPreserveMethods (method);
989 // Allow subclassers to mark additional things when marking a method
990 protected virtual void DoAdditionalMethodProcessing (MethodDefinition method)
994 void MarkBaseMethods (MethodDefinition method)
996 IList base_methods = Annotations.GetBaseMethods (method);
997 if (base_methods == null)
1000 foreach (MethodDefinition base_method in base_methods) {
1001 if (base_method.DeclaringType.IsInterface && !method.DeclaringType.IsInterface)
1004 MarkMethod (base_method);
1005 MarkBaseMethods (base_method);
1009 bool ShouldParseMethodBody (MethodDefinition method)
1011 if (!method.HasBody)
1014 AssemblyDefinition assembly = ResolveAssembly (method.DeclaringType.Scope);
1015 return (Annotations.GetAction (method) == MethodAction.ForceParse ||
1016 (Annotations.GetAction (assembly) == AssemblyAction.Link && Annotations.GetAction (method) == MethodAction.Parse));
1019 static internal bool IsPropertyMethod (MethodDefinition md)
1021 return (md.SemanticsAttributes & MethodSemanticsAttributes.Getter) != 0 ||
1022 (md.SemanticsAttributes & MethodSemanticsAttributes.Setter) != 0;
1025 static bool IsEventMethod (MethodDefinition md)
1027 return (md.SemanticsAttributes & MethodSemanticsAttributes.AddOn) != 0 ||
1028 (md.SemanticsAttributes & MethodSemanticsAttributes.Fire) != 0 ||
1029 (md.SemanticsAttributes & MethodSemanticsAttributes.RemoveOn) != 0;
1032 static internal PropertyDefinition GetProperty (MethodDefinition md)
1034 TypeDefinition declaringType = (TypeDefinition) md.DeclaringType;
1035 foreach (PropertyDefinition prop in declaringType.Properties)
1036 if (prop.GetMethod == md || prop.SetMethod == md)
1042 static EventDefinition GetEvent (MethodDefinition md)
1044 TypeDefinition declaringType = (TypeDefinition) md.DeclaringType;
1045 foreach (EventDefinition evt in declaringType.Events)
1046 if (evt.AddMethod == md || evt.InvokeMethod == md || evt.RemoveMethod == md)
1052 protected void MarkProperty (PropertyDefinition prop)
1054 MarkCustomAttributes (prop);
1057 protected void MarkEvent (EventDefinition evt)
1059 MarkCustomAttributes (evt);
1060 MarkMethodIfNotNull (evt.AddMethod);
1061 MarkMethodIfNotNull (evt.InvokeMethod);
1062 MarkMethodIfNotNull (evt.RemoveMethod);
1065 void MarkMethodIfNotNull (MethodReference method)
1070 MarkMethod (method);
1073 protected virtual void MarkMethodBody (MethodBody body)
1075 foreach (VariableDefinition var in body.Variables)
1076 MarkType (var.VariableType);
1078 foreach (ExceptionHandler eh in body.ExceptionHandlers)
1079 if (eh.HandlerType == ExceptionHandlerType.Catch)
1080 MarkType (eh.CatchType);
1082 foreach (Instruction instruction in body.Instructions)
1083 MarkInstruction (instruction);
1086 protected virtual void MarkInstruction (Instruction instruction)
1088 switch (instruction.OpCode.OperandType) {
1089 case OperandType.InlineField:
1090 MarkField ((FieldReference) instruction.Operand);
1092 case OperandType.InlineMethod:
1093 MarkMethod ((MethodReference) instruction.Operand);
1095 case OperandType.InlineTok:
1096 object token = instruction.Operand;
1097 if (token is TypeReference)
1098 MarkType ((TypeReference) token);
1099 else if (token is MethodReference)
1100 MarkMethod ((MethodReference) token);
1102 MarkField ((FieldReference) token);
1104 case OperandType.InlineType:
1105 MarkType ((TypeReference) instruction.Operand);