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);
362 // we cannot set the Scope of a TypeSpecification but it's element type can be set
363 // e.g. System.String[] -> System.String
364 var ts = (type as TypeSpecification);
366 MarkWithResolvedScope (ts.GetElementType ());
370 var td = type.Resolve ();
372 type.Scope = td.Scope;
376 protected bool CheckProcessed (IMetadataTokenProvider provider)
378 if (Annotations.IsProcessed (provider))
381 Annotations.Processed (provider);
385 protected void MarkAssembly (AssemblyDefinition assembly)
387 if (CheckProcessed (assembly))
390 ProcessModule (assembly);
392 MarkCustomAttributes (assembly);
393 MarkSecurityDeclarations (assembly);
395 foreach (ModuleDefinition module in assembly.Modules)
396 MarkCustomAttributes (module);
399 void ProcessModule (AssemblyDefinition assembly)
401 // Pre-mark <Module> if there is any methods as they need to be executed
402 // at assembly load time
403 foreach (TypeDefinition type in assembly.MainModule.Types)
405 if (type.Name == "<Module>" && type.HasMethods)
413 protected void MarkField (FieldReference reference)
415 // if (IgnoreScope (reference.DeclaringType.Scope))
418 if (reference.DeclaringType is GenericInstanceType)
419 MarkType (reference.DeclaringType);
421 FieldDefinition field = ResolveFieldDefinition (reference);
424 throw new ResolutionException (reference);
426 if (CheckProcessed (field))
429 MarkType (field.DeclaringType);
430 MarkType (field.FieldType);
431 MarkCustomAttributes (field);
432 MarkMarshalSpec (field);
434 Annotations.Mark (field);
437 protected virtual bool IgnoreScope (IMetadataScope scope)
439 AssemblyDefinition assembly = ResolveAssembly (scope);
440 return Annotations.GetAction (assembly) != AssemblyAction.Link;
443 FieldDefinition ResolveFieldDefinition (FieldReference field)
445 FieldDefinition fd = field as FieldDefinition;
447 fd = field.Resolve ();
452 void MarkScope (IMetadataScope scope)
454 var provider = scope as IMetadataTokenProvider;
455 if (provider == null)
458 Annotations.Mark (provider);
461 protected virtual void MarkSerializable (TypeDefinition type)
463 MarkDefaultConstructor (type);
464 MarkMethodsIf (type.Methods, IsSpecialSerializationConstructorPredicate);
467 protected virtual TypeDefinition MarkType (TypeReference reference)
469 if (reference == null)
472 reference = GetOriginalType (reference);
474 if (reference is GenericParameter)
477 // if (IgnoreScope (reference.Scope))
480 TypeDefinition type = ResolveTypeDefinition (reference);
483 throw new ResolutionException (reference);
485 if (CheckProcessed (type))
488 Annotations.Push (type);
490 MarkScope (type.Scope);
491 MarkType (type.BaseType);
492 MarkType (type.DeclaringType);
493 MarkCustomAttributes (type);
494 MarkSecurityDeclarations (type);
496 if (IsMulticastDelegate (type)) {
497 MarkMethodCollection (type.Methods);
500 if (IsSerializable (type))
501 MarkSerializable (type);
503 MarkTypeSpecialCustomAttributes (type);
505 MarkGenericParameterProvider (type);
507 // keep fields for value-types and for classes with LayoutKind.Sequential or Explicit
508 if (type.IsValueType || !type.IsAutoLayout)
509 MarkFields (type, type.IsEnum);
511 if (type.HasInterfaces) {
512 foreach (TypeReference iface in type.Interfaces)
516 if (type.HasMethods) {
517 MarkMethodsIf (type.Methods, IsVirtualAndHasPreservedParent);
518 MarkMethodsIf (type.Methods, IsStaticConstructorPredicate);
521 DoAdditionalTypeProcessing (type);
525 Annotations.Mark (type);
527 ApplyPreserveInfo (type);
532 // Allow subclassers to mark additional things when marking a method
533 protected virtual void DoAdditionalTypeProcessing (TypeDefinition method)
537 void MarkTypeSpecialCustomAttributes (TypeDefinition type)
539 if (!type.HasCustomAttributes)
542 foreach (CustomAttribute attribute in type.CustomAttributes) {
543 switch (attribute.Constructor.DeclaringType.FullName) {
544 case "System.Xml.Serialization.XmlSchemaProviderAttribute":
545 MarkXmlSchemaProvider (type, attribute);
551 void MarkMethodSpecialCustomAttributes (MethodDefinition method)
553 if (!method.HasCustomAttributes)
556 foreach (CustomAttribute attribute in method.CustomAttributes) {
557 switch (attribute.Constructor.DeclaringType.FullName) {
558 case "System.Web.Services.Protocols.SoapHeaderAttribute":
559 MarkSoapHeader (method, attribute);
565 void MarkXmlSchemaProvider (TypeDefinition type, CustomAttribute attribute)
568 if (!TryGetStringArgument (attribute, out method_name))
571 MarkNamedMethod (type, method_name);
574 static bool TryGetStringArgument (CustomAttribute attribute, out string argument)
578 if (attribute.ConstructorArguments.Count < 1)
581 argument = attribute.ConstructorArguments [0].Value as string;
583 return argument != null;
586 protected int MarkNamedMethod (TypeDefinition type, string method_name)
588 if (!type.HasMethods)
592 foreach (MethodDefinition method in type.Methods) {
593 if (method.Name != method_name)
603 void MarkSoapHeader (MethodDefinition method, CustomAttribute attribute)
606 if (!TryGetStringArgument (attribute, out member_name))
609 MarkNamedField (method.DeclaringType, member_name);
610 MarkNamedProperty (method.DeclaringType, member_name);
613 void MarkNamedField (TypeDefinition type, string field_name)
618 foreach (FieldDefinition field in type.Fields) {
619 if (field.Name != field_name)
626 void MarkNamedProperty (TypeDefinition type, string property_name)
628 if (!type.HasProperties)
631 foreach (PropertyDefinition property in type.Properties) {
632 if (property.Name != property_name)
635 MarkMethod (property.GetMethod);
636 MarkMethod (property.SetMethod);
640 void MarkGenericParameterProvider (IGenericParameterProvider provider)
642 if (!provider.HasGenericParameters)
645 foreach (GenericParameter parameter in provider.GenericParameters)
646 MarkGenericParameter (parameter);
649 void MarkGenericParameter (GenericParameter parameter)
651 MarkCustomAttributes (parameter);
652 foreach (TypeReference constraint in parameter.Constraints)
653 MarkType (constraint);
656 bool IsVirtualAndHasPreservedParent (MethodDefinition method)
658 if (!method.IsVirtual)
661 var base_list = Annotations.GetBaseMethods (method);
662 if (base_list == null)
665 foreach (MethodDefinition @base in base_list) {
666 if (IgnoreScope (@base.DeclaringType.Scope))
669 if (IsVirtualAndHasPreservedParent (@base))
676 static MethodPredicate IsSpecialSerializationConstructorPredicate = new MethodPredicate (IsSpecialSerializationConstructor);
678 static bool IsSpecialSerializationConstructor (MethodDefinition method)
680 if (!IsConstructor (method))
683 var parameters = method.Parameters;
684 if (parameters.Count != 2)
687 return parameters [0].ParameterType.Name == "SerializationInfo" &&
688 parameters [1].ParameterType.Name == "StreamingContext";
691 delegate bool MethodPredicate (MethodDefinition method);
693 void MarkMethodsIf (ICollection methods, MethodPredicate predicate)
695 foreach (MethodDefinition method in methods)
696 if (predicate (method))
700 static MethodPredicate IsDefaultConstructorPredicate = new MethodPredicate (IsDefaultConstructor);
702 static bool IsDefaultConstructor (MethodDefinition method)
704 return IsConstructor (method) && !method.HasParameters;
707 static bool IsConstructor (MethodDefinition method)
709 return method.IsConstructor && !method.IsStatic;
712 protected void MarkDefaultConstructor (TypeDefinition type)
714 if ((type == null) || !type.HasMethods)
717 MarkMethodsIf (type.Methods, IsDefaultConstructorPredicate);
720 static MethodPredicate IsStaticConstructorPredicate = new MethodPredicate (IsStaticConstructor);
722 static bool IsStaticConstructor (MethodDefinition method)
724 return method.IsConstructor && method.IsStatic;
727 static bool IsSerializable (TypeDefinition td)
729 return (td.Attributes & TypeAttributes.Serializable) != 0;
732 static bool IsMulticastDelegate (TypeDefinition td)
734 return td.BaseType != null && td.BaseType.FullName == "System.MulticastDelegate";
737 protected TypeDefinition ResolveTypeDefinition (TypeReference type)
739 TypeDefinition td = type as TypeDefinition;
741 td = type.Resolve ();
746 protected TypeReference GetOriginalType (TypeReference type)
748 while (type is TypeSpecification) {
749 GenericInstanceType git = type as GenericInstanceType;
751 MarkGenericArguments (git);
753 var mod = type as IModifierType;
755 MarkModifierType (mod);
757 type = ((TypeSpecification) type).ElementType;
763 void MarkModifierType (IModifierType mod)
765 MarkType (mod.ModifierType);
768 void MarkGenericArguments (IGenericInstance instance)
770 foreach (TypeReference argument in instance.GenericArguments)
773 MarkGenericArgumentConstructors (instance);
776 void MarkGenericArgumentConstructors (IGenericInstance instance)
778 var arguments = instance.GenericArguments;
780 var generic_element = GetGenericProviderFromInstance (instance);
781 if (generic_element == null)
784 var parameters = generic_element.GenericParameters;
786 if (arguments.Count != parameters.Count)
789 for (int i = 0; i < arguments.Count; i++) {
790 var argument = arguments [i];
791 var parameter = parameters [i];
793 if (!parameter.HasDefaultConstructorConstraint)
796 var argument_definition = ResolveTypeDefinition (argument);
797 if (argument_definition == null)
800 MarkMethodsIf (argument_definition.Methods, ctor => !ctor.IsStatic && !ctor.HasParameters);
804 IGenericParameterProvider GetGenericProviderFromInstance (IGenericInstance instance)
806 var method = instance as GenericInstanceMethod;
808 return ResolveMethodDefinition (method.ElementMethod);
810 var type = instance as GenericInstanceType;
812 return ResolveTypeDefinition (type.ElementType);
817 void ApplyPreserveInfo (TypeDefinition type)
819 ApplyPreserveMethods (type);
821 if (!Annotations.IsPreserved (type))
824 switch (Annotations.GetPreserve (type)) {
825 case TypePreserve.All:
826 MarkFields (type, true);
829 case TypePreserve.Fields:
830 MarkFields (type, true);
832 case TypePreserve.Methods:
838 void ApplyPreserveMethods (TypeDefinition type)
840 var list = Annotations.GetPreservedMethods (type);
844 MarkMethodCollection (list);
847 void ApplyPreserveMethods (MethodDefinition method)
849 var list = Annotations.GetPreservedMethods (method);
853 MarkMethodCollection (list);
856 protected void MarkFields (TypeDefinition type, bool includeStatic)
861 foreach (FieldDefinition field in type.Fields) {
862 if (!includeStatic && field.IsStatic)
868 protected virtual void MarkMethods (TypeDefinition type)
871 MarkMethodCollection (type.Methods);
874 void MarkMethodCollection (IEnumerable methods)
876 foreach (MethodDefinition method in methods)
880 protected virtual MethodDefinition MarkMethod (MethodReference reference)
882 reference = GetOriginalMethod (reference);
884 if (reference.DeclaringType is ArrayType)
887 Annotations.Push (reference);
888 if (reference.DeclaringType is GenericInstanceType)
889 MarkType (reference.DeclaringType);
891 // if (IgnoreScope (reference.DeclaringType.Scope))
894 MethodDefinition method = ResolveMethodDefinition (reference);
896 if (method == null) {
898 throw new ResolutionException (reference);
901 if (Annotations.GetAction (method) == MethodAction.Nothing)
902 Annotations.SetAction (method, MethodAction.Parse);
904 EnqueueMethod (method);
911 AssemblyDefinition ResolveAssembly (IMetadataScope scope)
913 AssemblyDefinition assembly = _context.Resolve (scope);
914 MarkAssembly (assembly);
918 protected MethodReference GetOriginalMethod (MethodReference method)
920 while (method is MethodSpecification) {
921 GenericInstanceMethod gim = method as GenericInstanceMethod;
923 MarkGenericArguments (gim);
925 method = ((MethodSpecification) method).ElementMethod;
931 MethodDefinition ResolveMethodDefinition (MethodReference method)
933 MethodDefinition md = method as MethodDefinition;
935 md = method.Resolve ();
940 protected virtual void ProcessMethod (MethodDefinition method)
942 if (CheckProcessed (method))
945 MarkType (method.DeclaringType);
946 MarkCustomAttributes (method);
947 MarkSecurityDeclarations (method);
949 MarkGenericParameterProvider (method);
951 if (IsPropertyMethod (method))
952 MarkProperty (GetProperty (method));
953 else if (IsEventMethod (method))
954 MarkEvent (GetEvent (method));
956 if (method.HasParameters) {
957 foreach (ParameterDefinition pd in method.Parameters) {
958 MarkType (pd.ParameterType);
959 MarkCustomAttributes (pd);
960 MarkMarshalSpec (pd);
964 if (method.HasOverrides) {
965 foreach (MethodReference ov in method.Overrides)
969 MarkMethodSpecialCustomAttributes (method);
971 if (method.IsVirtual)
972 _virtual_methods.Add (method);
974 MarkBaseMethods (method);
976 MarkType (method.ReturnType);
977 MarkCustomAttributes (method.MethodReturnType);
978 MarkMarshalSpec (method.MethodReturnType);
980 if (ShouldParseMethodBody (method))
981 MarkMethodBody (method.Body);
983 DoAdditionalMethodProcessing (method);
985 Annotations.Mark (method);
987 ApplyPreserveMethods (method);
990 // Allow subclassers to mark additional things when marking a method
991 protected virtual void DoAdditionalMethodProcessing (MethodDefinition method)
995 void MarkBaseMethods (MethodDefinition method)
997 IList base_methods = Annotations.GetBaseMethods (method);
998 if (base_methods == null)
1001 foreach (MethodDefinition base_method in base_methods) {
1002 if (base_method.DeclaringType.IsInterface && !method.DeclaringType.IsInterface)
1005 MarkMethod (base_method);
1006 MarkBaseMethods (base_method);
1010 bool ShouldParseMethodBody (MethodDefinition method)
1012 if (!method.HasBody)
1015 AssemblyDefinition assembly = ResolveAssembly (method.DeclaringType.Scope);
1016 return (Annotations.GetAction (method) == MethodAction.ForceParse ||
1017 (Annotations.GetAction (assembly) == AssemblyAction.Link && Annotations.GetAction (method) == MethodAction.Parse));
1020 static internal bool IsPropertyMethod (MethodDefinition md)
1022 return (md.SemanticsAttributes & MethodSemanticsAttributes.Getter) != 0 ||
1023 (md.SemanticsAttributes & MethodSemanticsAttributes.Setter) != 0;
1026 static bool IsEventMethod (MethodDefinition md)
1028 return (md.SemanticsAttributes & MethodSemanticsAttributes.AddOn) != 0 ||
1029 (md.SemanticsAttributes & MethodSemanticsAttributes.Fire) != 0 ||
1030 (md.SemanticsAttributes & MethodSemanticsAttributes.RemoveOn) != 0;
1033 static internal PropertyDefinition GetProperty (MethodDefinition md)
1035 TypeDefinition declaringType = (TypeDefinition) md.DeclaringType;
1036 foreach (PropertyDefinition prop in declaringType.Properties)
1037 if (prop.GetMethod == md || prop.SetMethod == md)
1043 static EventDefinition GetEvent (MethodDefinition md)
1045 TypeDefinition declaringType = (TypeDefinition) md.DeclaringType;
1046 foreach (EventDefinition evt in declaringType.Events)
1047 if (evt.AddMethod == md || evt.InvokeMethod == md || evt.RemoveMethod == md)
1053 protected void MarkProperty (PropertyDefinition prop)
1055 MarkCustomAttributes (prop);
1058 protected void MarkEvent (EventDefinition evt)
1060 MarkCustomAttributes (evt);
1061 MarkMethodIfNotNull (evt.AddMethod);
1062 MarkMethodIfNotNull (evt.InvokeMethod);
1063 MarkMethodIfNotNull (evt.RemoveMethod);
1066 void MarkMethodIfNotNull (MethodReference method)
1071 MarkMethod (method);
1074 protected virtual void MarkMethodBody (MethodBody body)
1076 foreach (VariableDefinition var in body.Variables)
1077 MarkType (var.VariableType);
1079 foreach (ExceptionHandler eh in body.ExceptionHandlers)
1080 if (eh.HandlerType == ExceptionHandlerType.Catch)
1081 MarkType (eh.CatchType);
1083 foreach (Instruction instruction in body.Instructions)
1084 MarkInstruction (instruction);
1087 protected virtual void MarkInstruction (Instruction instruction)
1089 switch (instruction.OpCode.OperandType) {
1090 case OperandType.InlineField:
1091 MarkField ((FieldReference) instruction.Operand);
1093 case OperandType.InlineMethod:
1094 MarkMethod ((MethodReference) instruction.Operand);
1096 case OperandType.InlineTok:
1097 object token = instruction.Operand;
1098 if (token is TypeReference)
1099 MarkType ((TypeReference) token);
1100 else if (token is MethodReference)
1101 MarkMethod ((MethodReference) token);
1103 MarkField ((FieldReference) token);
1105 case OperandType.InlineType:
1106 MarkType ((TypeReference) instruction.Operand);