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);
73 foreach (TypeDefinition type in assembly.MainModule.Types)
74 InitializeType (type);
77 void InitializeType (TypeDefinition type)
79 if (type.HasNestedTypes) {
80 foreach (var nested in type.NestedTypes)
81 InitializeType (nested);
84 if (!Annotations.IsMarked (type))
90 InitializeFields (type);
92 InitializeMethods (type.Methods);
94 if (type.HasNestedTypes) {
95 foreach (var nested in type.NestedTypes) {
96 if (Annotations.IsMarked (nested))
97 InitializeType (nested);
102 void InitializeFields (TypeDefinition type)
104 foreach (FieldDefinition field in type.Fields)
105 if (Annotations.IsMarked (field))
109 void InitializeMethods (ICollection methods)
111 foreach (MethodDefinition method in methods)
112 if (Annotations.IsMarked (method))
113 EnqueueMethod (method);
119 throw new InvalidOperationException ("No entry methods");
121 while (!QueueIsEmpty ()) {
123 ProcessVirtualMethods ();
129 while (!QueueIsEmpty ()) {
130 MethodDefinition method = (MethodDefinition) _methods.Dequeue ();
131 Annotations.Push (method);
132 ProcessMethod (method);
139 return _methods.Count == 0;
142 protected virtual void EnqueueMethod (MethodDefinition method)
144 _methods.Enqueue (method);
147 void ProcessVirtualMethods ()
149 foreach (MethodDefinition method in _virtual_methods) {
150 Annotations.Push (method);
151 ProcessVirtualMethod (method);
156 void ProcessVirtualMethod (MethodDefinition method)
158 IList overrides = Annotations.GetOverrides (method);
159 if (overrides == null)
162 foreach (MethodDefinition @override in overrides)
163 ProcessOverride (@override);
166 void ProcessOverride (MethodDefinition method)
168 if (!Annotations.IsMarked (method.DeclaringType))
171 if (Annotations.IsProcessed (method))
174 if (Annotations.IsMarked (method))
178 ProcessVirtualMethod (method);
181 void MarkMarshalSpec (IMarshalInfoProvider spec)
183 if (!spec.HasMarshalInfo)
186 var marshaler = spec.MarshalInfo as CustomMarshalInfo;
187 if (marshaler == null)
190 MarkType (marshaler.ManagedType);
193 void MarkCustomAttributes (ICustomAttributeProvider provider)
195 if (!provider.HasCustomAttributes)
198 foreach (CustomAttribute ca in provider.CustomAttributes)
199 MarkCustomAttribute (ca);
202 protected virtual void MarkCustomAttribute (CustomAttribute ca)
204 Annotations.Push (ca);
205 MarkMethod (ca.Constructor);
207 MarkCustomAttributeArguments (ca);
209 TypeReference constructor_type = ca.Constructor.DeclaringType;
210 TypeDefinition type = constructor_type.Resolve ();
213 throw new ResolutionException (constructor_type);
216 MarkCustomAttributeProperties (ca, type);
217 MarkCustomAttributeFields (ca, type);
221 protected void MarkSecurityDeclarations (ISecurityDeclarationProvider provider)
223 // most security declarations are removed (if linked) but user code might still have some
224 // and if the attribtues references types then they need to be marked too
225 if ((provider == null) || !provider.HasSecurityDeclarations)
228 foreach (var sd in provider.SecurityDeclarations)
229 MarkSecurityDeclaration (sd);
232 protected virtual void MarkSecurityDeclaration (SecurityDeclaration sd)
234 if (!sd.HasSecurityAttributes)
237 foreach (var sa in sd.SecurityAttributes)
238 MarkSecurityAttribute (sa);
241 protected virtual void MarkSecurityAttribute (SecurityAttribute sa)
243 TypeReference security_type = sa.AttributeType;
244 TypeDefinition type = security_type.Resolve ();
246 throw new ResolutionException (security_type);
248 MarkType (security_type);
249 MarkSecurityAttributeProperties (sa, type);
250 MarkSecurityAttributeFields (sa, type);
253 protected void MarkSecurityAttributeProperties (SecurityAttribute sa, TypeDefinition attribute)
255 if (!sa.HasProperties)
258 foreach (var named_argument in sa.Properties)
259 MarkCustomAttributeProperty (named_argument, attribute);
262 protected void MarkSecurityAttributeFields (SecurityAttribute sa, TypeDefinition attribute)
267 foreach (var named_argument in sa.Fields)
268 MarkCustomAttributeField (named_argument, attribute);
271 protected void MarkCustomAttributeProperties (CustomAttribute ca, TypeDefinition attribute)
273 if (!ca.HasProperties)
276 foreach (var named_argument in ca.Properties)
277 MarkCustomAttributeProperty (named_argument, attribute);
280 protected void MarkCustomAttributeProperty (CustomAttributeNamedArgument namedArgument, TypeDefinition attribute)
282 PropertyDefinition property = GetProperty (attribute, namedArgument.Name);
283 Annotations.Push (property);
284 if (property != null)
285 MarkMethod (property.SetMethod);
287 MarkIfType (namedArgument.Argument);
291 PropertyDefinition GetProperty (TypeDefinition type, string propertyname)
293 while (type != null) {
294 PropertyDefinition property = type.Properties.FirstOrDefault (p => p.Name == propertyname);
295 if (property != null)
298 type = type.BaseType != null ? ResolveTypeDefinition (type.BaseType) : null;
304 protected void MarkCustomAttributeFields (CustomAttribute ca, TypeDefinition attribute)
309 foreach (var named_argument in ca.Fields)
310 MarkCustomAttributeField (named_argument, attribute);
313 protected void MarkCustomAttributeField (CustomAttributeNamedArgument namedArgument, TypeDefinition attribute)
315 FieldDefinition field = GetField (attribute, namedArgument.Name);
319 MarkIfType (namedArgument.Argument);
322 FieldDefinition GetField (TypeDefinition type, string fieldname)
324 while (type != null) {
325 FieldDefinition field = type.Fields.FirstOrDefault (f => f.Name == fieldname);
329 type = type.BaseType != null ? ResolveTypeDefinition (type.BaseType) : null;
335 void MarkCustomAttributeArguments (CustomAttribute ca)
337 if (!ca.HasConstructorArguments)
340 foreach (var argument in ca.ConstructorArguments)
341 MarkIfType (argument);
344 void MarkIfType (CustomAttributeArgument argument)
346 var at = argument.Type;
348 var et = at.GetElementType ();
349 if (et.Namespace != "System" || et.Name != "Type")
353 if (argument.Value == null)
356 foreach (var cac in (CustomAttributeArgument[]) argument.Value)
357 MarkWithResolvedScope ((TypeReference) cac.Value);
358 } else if (at.Namespace == "System" && at.Name == "Type") {
359 MarkType (argument.Type);
360 MarkWithResolvedScope ((TypeReference) argument.Value);
364 // custom attributes encoding means it's possible to have a scope that will point into a PCL facade
365 // even if we (just before saving) will resolve all type references (bug #26752)
366 void MarkWithResolvedScope (TypeReference type)
371 // a GenericInstanceType can could contains generic arguments with scope that
372 // needs to be updated out of the PCL facade (bug #28823)
373 var git = (type as GenericInstanceType);
374 if ((git != null) && git.HasGenericArguments) {
375 foreach (var ga in git.GenericArguments)
376 MarkWithResolvedScope (ga);
378 // we cannot set the Scope of a TypeSpecification but it's element type can be set
379 // e.g. System.String[] -> System.String
380 var ts = (type as TypeSpecification);
382 MarkWithResolvedScope (ts.GetElementType ());
386 var td = type.Resolve ();
388 type.Scope = td.Scope;
392 protected bool CheckProcessed (IMetadataTokenProvider provider)
394 if (Annotations.IsProcessed (provider))
397 Annotations.Processed (provider);
401 protected void MarkAssembly (AssemblyDefinition assembly)
403 if (CheckProcessed (assembly))
406 ProcessModule (assembly);
408 MarkCustomAttributes (assembly);
409 MarkSecurityDeclarations (assembly);
411 foreach (ModuleDefinition module in assembly.Modules)
412 MarkCustomAttributes (module);
415 void ProcessModule (AssemblyDefinition assembly)
417 // Pre-mark <Module> if there is any methods as they need to be executed
418 // at assembly load time
419 foreach (TypeDefinition type in assembly.MainModule.Types)
421 if (type.Name == "<Module>" && type.HasMethods)
429 protected void MarkField (FieldReference reference)
431 // if (IgnoreScope (reference.DeclaringType.Scope))
434 if (reference.DeclaringType is GenericInstanceType)
435 MarkType (reference.DeclaringType);
437 FieldDefinition field = ResolveFieldDefinition (reference);
440 throw new ResolutionException (reference);
442 if (CheckProcessed (field))
445 MarkType (field.DeclaringType);
446 MarkType (field.FieldType);
447 MarkCustomAttributes (field);
448 MarkMarshalSpec (field);
450 Annotations.Mark (field);
453 protected virtual bool IgnoreScope (IMetadataScope scope)
455 AssemblyDefinition assembly = ResolveAssembly (scope);
456 return Annotations.GetAction (assembly) != AssemblyAction.Link;
459 FieldDefinition ResolveFieldDefinition (FieldReference field)
461 FieldDefinition fd = field as FieldDefinition;
463 fd = field.Resolve ();
468 void MarkScope (IMetadataScope scope)
470 var provider = scope as IMetadataTokenProvider;
471 if (provider == null)
474 Annotations.Mark (provider);
477 protected virtual void MarkSerializable (TypeDefinition type)
479 MarkDefaultConstructor (type);
480 MarkMethodsIf (type.Methods, IsSpecialSerializationConstructorPredicate);
483 protected virtual TypeDefinition MarkType (TypeReference reference)
485 if (reference == null)
488 reference = GetOriginalType (reference);
490 if (reference is GenericParameter)
493 // if (IgnoreScope (reference.Scope))
496 TypeDefinition type = ResolveTypeDefinition (reference);
499 throw new ResolutionException (reference);
501 if (CheckProcessed (type))
504 Annotations.Push (type);
506 MarkScope (type.Scope);
507 MarkType (type.BaseType);
508 MarkType (type.DeclaringType);
509 MarkCustomAttributes (type);
510 MarkSecurityDeclarations (type);
512 if (IsMulticastDelegate (type)) {
513 MarkMethodCollection (type.Methods);
516 if (IsSerializable (type))
517 MarkSerializable (type);
519 MarkTypeSpecialCustomAttributes (type);
521 MarkGenericParameterProvider (type);
523 // keep fields for value-types and for classes with LayoutKind.Sequential or Explicit
524 if (type.IsValueType || !type.IsAutoLayout)
525 MarkFields (type, type.IsEnum);
527 if (type.HasInterfaces) {
528 foreach (var iface in type.Interfaces)
529 MarkType (iface.InterfaceType);
532 if (type.HasMethods) {
533 MarkMethodsIf (type.Methods, IsVirtualAndHasPreservedParent);
534 MarkMethodsIf (type.Methods, IsStaticConstructorPredicate);
535 MarkMethodsIf (type.Methods, HasSerializationAttribute);
538 DoAdditionalTypeProcessing (type);
542 Annotations.Mark (type);
544 ApplyPreserveInfo (type);
549 // Allow subclassers to mark additional things when marking a method
550 protected virtual void DoAdditionalTypeProcessing (TypeDefinition method)
554 void MarkTypeSpecialCustomAttributes (TypeDefinition type)
556 if (!type.HasCustomAttributes)
559 foreach (CustomAttribute attribute in type.CustomAttributes) {
560 switch (attribute.Constructor.DeclaringType.FullName) {
561 case "System.Xml.Serialization.XmlSchemaProviderAttribute":
562 MarkXmlSchemaProvider (type, attribute);
568 void MarkMethodSpecialCustomAttributes (MethodDefinition method)
570 if (!method.HasCustomAttributes)
573 foreach (CustomAttribute attribute in method.CustomAttributes) {
574 switch (attribute.Constructor.DeclaringType.FullName) {
575 case "System.Web.Services.Protocols.SoapHeaderAttribute":
576 MarkSoapHeader (method, attribute);
582 void MarkXmlSchemaProvider (TypeDefinition type, CustomAttribute attribute)
585 if (!TryGetStringArgument (attribute, out method_name))
588 MarkNamedMethod (type, method_name);
591 static bool TryGetStringArgument (CustomAttribute attribute, out string argument)
595 if (attribute.ConstructorArguments.Count < 1)
598 argument = attribute.ConstructorArguments [0].Value as string;
600 return argument != null;
603 protected int MarkNamedMethod (TypeDefinition type, string method_name)
605 if (!type.HasMethods)
609 foreach (MethodDefinition method in type.Methods) {
610 if (method.Name != method_name)
620 void MarkSoapHeader (MethodDefinition method, CustomAttribute attribute)
623 if (!TryGetStringArgument (attribute, out member_name))
626 MarkNamedField (method.DeclaringType, member_name);
627 MarkNamedProperty (method.DeclaringType, member_name);
630 void MarkNamedField (TypeDefinition type, string field_name)
635 foreach (FieldDefinition field in type.Fields) {
636 if (field.Name != field_name)
643 void MarkNamedProperty (TypeDefinition type, string property_name)
645 if (!type.HasProperties)
648 foreach (PropertyDefinition property in type.Properties) {
649 if (property.Name != property_name)
652 Annotations.Push (property);
653 MarkMethod (property.GetMethod);
654 MarkMethod (property.SetMethod);
659 void MarkGenericParameterProvider (IGenericParameterProvider provider)
661 if (!provider.HasGenericParameters)
664 foreach (GenericParameter parameter in provider.GenericParameters)
665 MarkGenericParameter (parameter);
668 void MarkGenericParameter (GenericParameter parameter)
670 MarkCustomAttributes (parameter);
671 foreach (TypeReference constraint in parameter.Constraints)
672 MarkType (constraint);
675 bool IsVirtualAndHasPreservedParent (MethodDefinition method)
677 if (!method.IsVirtual)
680 var base_list = Annotations.GetBaseMethods (method);
681 if (base_list == null)
684 foreach (MethodDefinition @base in base_list) {
685 if (IgnoreScope (@base.DeclaringType.Scope))
688 if (IsVirtualAndHasPreservedParent (@base))
695 static MethodPredicate IsSpecialSerializationConstructorPredicate = new MethodPredicate (IsSpecialSerializationConstructor);
697 static bool IsSpecialSerializationConstructor (MethodDefinition method)
699 if (!IsConstructor (method))
702 var parameters = method.Parameters;
703 if (parameters.Count != 2)
706 return parameters [0].ParameterType.Name == "SerializationInfo" &&
707 parameters [1].ParameterType.Name == "StreamingContext";
710 delegate bool MethodPredicate (MethodDefinition method);
712 void MarkMethodsIf (ICollection methods, MethodPredicate predicate)
714 foreach (MethodDefinition method in methods)
715 if (predicate (method)) {
716 Annotations.Push (predicate);
722 static MethodPredicate IsDefaultConstructorPredicate = new MethodPredicate (IsDefaultConstructor);
724 static bool IsDefaultConstructor (MethodDefinition method)
726 return IsConstructor (method) && !method.HasParameters;
729 static bool IsConstructor (MethodDefinition method)
731 return method.IsConstructor && !method.IsStatic;
734 protected void MarkDefaultConstructor (TypeDefinition type)
736 if ((type == null) || !type.HasMethods)
739 MarkMethodsIf (type.Methods, IsDefaultConstructorPredicate);
742 static MethodPredicate IsStaticConstructorPredicate = new MethodPredicate (IsStaticConstructor);
744 static bool IsStaticConstructor (MethodDefinition method)
746 return method.IsConstructor && method.IsStatic;
749 static bool HasSerializationAttribute (MethodDefinition method)
751 if (!method.HasCustomAttributes)
753 foreach (var ca in method.CustomAttributes) {
754 var cat = ca.AttributeType;
755 if (cat.Namespace != "System.Runtime.Serialization")
758 case "OnDeserializedAttribute":
759 case "OnDeserializingAttribute":
760 case "OnSerializedAttribute":
761 case "OnSerializingAttribute":
768 static bool IsSerializable (TypeDefinition td)
770 return (td.Attributes & TypeAttributes.Serializable) != 0;
773 static bool IsMulticastDelegate (TypeDefinition td)
775 return td.BaseType != null && td.BaseType.FullName == "System.MulticastDelegate";
778 protected TypeDefinition ResolveTypeDefinition (TypeReference type)
780 TypeDefinition td = type as TypeDefinition;
782 td = type.Resolve ();
787 protected TypeReference GetOriginalType (TypeReference type)
789 while (type is TypeSpecification) {
790 GenericInstanceType git = type as GenericInstanceType;
792 MarkGenericArguments (git);
794 var mod = type as IModifierType;
796 MarkModifierType (mod);
798 type = ((TypeSpecification) type).ElementType;
804 void MarkModifierType (IModifierType mod)
806 MarkType (mod.ModifierType);
809 void MarkGenericArguments (IGenericInstance instance)
811 foreach (TypeReference argument in instance.GenericArguments)
814 MarkGenericArgumentConstructors (instance);
817 void MarkGenericArgumentConstructors (IGenericInstance instance)
819 var arguments = instance.GenericArguments;
821 var generic_element = GetGenericProviderFromInstance (instance);
822 if (generic_element == null)
825 var parameters = generic_element.GenericParameters;
827 if (arguments.Count != parameters.Count)
830 for (int i = 0; i < arguments.Count; i++) {
831 var argument = arguments [i];
832 var parameter = parameters [i];
834 if (!parameter.HasDefaultConstructorConstraint)
837 var argument_definition = ResolveTypeDefinition (argument);
838 if (argument_definition == null)
841 MarkMethodsIf (argument_definition.Methods, ctor => !ctor.IsStatic && !ctor.HasParameters);
845 IGenericParameterProvider GetGenericProviderFromInstance (IGenericInstance instance)
847 var method = instance as GenericInstanceMethod;
849 return ResolveMethodDefinition (method.ElementMethod);
851 var type = instance as GenericInstanceType;
853 return ResolveTypeDefinition (type.ElementType);
858 void ApplyPreserveInfo (TypeDefinition type)
860 ApplyPreserveMethods (type);
862 if (!Annotations.IsPreserved (type))
865 switch (Annotations.GetPreserve (type)) {
866 case TypePreserve.All:
867 MarkFields (type, true);
870 case TypePreserve.Fields:
871 MarkFields (type, true);
873 case TypePreserve.Methods:
879 void ApplyPreserveMethods (TypeDefinition type)
881 var list = Annotations.GetPreservedMethods (type);
885 MarkMethodCollection (list);
888 void ApplyPreserveMethods (MethodDefinition method)
890 var list = Annotations.GetPreservedMethods (method);
894 MarkMethodCollection (list);
897 protected void MarkFields (TypeDefinition type, bool includeStatic)
902 foreach (FieldDefinition field in type.Fields) {
903 if (!includeStatic && field.IsStatic)
909 protected virtual void MarkMethods (TypeDefinition type)
912 MarkMethodCollection (type.Methods);
915 void MarkMethodCollection (IEnumerable methods)
917 foreach (MethodDefinition method in methods)
921 protected virtual MethodDefinition MarkMethod (MethodReference reference)
923 reference = GetOriginalMethod (reference);
925 if (reference.DeclaringType is ArrayType)
928 Annotations.Push (reference);
929 if (reference.DeclaringType is GenericInstanceType)
930 MarkType (reference.DeclaringType);
932 // if (IgnoreScope (reference.DeclaringType.Scope))
935 MethodDefinition method = ResolveMethodDefinition (reference);
937 if (method == null) {
939 throw new ResolutionException (reference);
942 if (Annotations.GetAction (method) == MethodAction.Nothing)
943 Annotations.SetAction (method, MethodAction.Parse);
945 EnqueueMethod (method);
948 Annotations.AddDependency (method);
953 AssemblyDefinition ResolveAssembly (IMetadataScope scope)
955 AssemblyDefinition assembly = _context.Resolve (scope);
956 MarkAssembly (assembly);
960 protected MethodReference GetOriginalMethod (MethodReference method)
962 while (method is MethodSpecification) {
963 GenericInstanceMethod gim = method as GenericInstanceMethod;
965 MarkGenericArguments (gim);
967 method = ((MethodSpecification) method).ElementMethod;
973 MethodDefinition ResolveMethodDefinition (MethodReference method)
975 MethodDefinition md = method as MethodDefinition;
977 md = method.Resolve ();
982 protected virtual void ProcessMethod (MethodDefinition method)
984 if (CheckProcessed (method))
987 Annotations.Push (method);
988 MarkType (method.DeclaringType);
989 MarkCustomAttributes (method);
990 MarkSecurityDeclarations (method);
992 MarkGenericParameterProvider (method);
994 if (IsPropertyMethod (method))
995 MarkProperty (GetProperty (method));
996 else if (IsEventMethod (method))
997 MarkEvent (GetEvent (method));
999 if (method.HasParameters) {
1000 foreach (ParameterDefinition pd in method.Parameters) {
1001 MarkType (pd.ParameterType);
1002 MarkCustomAttributes (pd);
1003 MarkMarshalSpec (pd);
1007 if (method.HasOverrides) {
1008 foreach (MethodReference ov in method.Overrides)
1012 MarkMethodSpecialCustomAttributes (method);
1014 if (method.IsVirtual)
1015 _virtual_methods.Add (method);
1017 MarkBaseMethods (method);
1019 MarkType (method.ReturnType);
1020 MarkCustomAttributes (method.MethodReturnType);
1021 MarkMarshalSpec (method.MethodReturnType);
1023 if (ShouldParseMethodBody (method))
1024 MarkMethodBody (method.Body);
1026 DoAdditionalMethodProcessing (method);
1028 Annotations.Mark (method);
1030 ApplyPreserveMethods (method);
1034 // Allow subclassers to mark additional things when marking a method
1035 protected virtual void DoAdditionalMethodProcessing (MethodDefinition method)
1039 void MarkBaseMethods (MethodDefinition method)
1041 IList base_methods = Annotations.GetBaseMethods (method);
1042 if (base_methods == null)
1045 foreach (MethodDefinition base_method in base_methods) {
1046 if (base_method.DeclaringType.IsInterface && !method.DeclaringType.IsInterface)
1049 MarkMethod (base_method);
1050 MarkBaseMethods (base_method);
1054 bool ShouldParseMethodBody (MethodDefinition method)
1056 if (!method.HasBody)
1059 AssemblyDefinition assembly = ResolveAssembly (method.DeclaringType.Scope);
1060 return (Annotations.GetAction (method) == MethodAction.ForceParse ||
1061 (Annotations.GetAction (assembly) == AssemblyAction.Link && Annotations.GetAction (method) == MethodAction.Parse));
1064 static internal bool IsPropertyMethod (MethodDefinition md)
1066 return (md.SemanticsAttributes & MethodSemanticsAttributes.Getter) != 0 ||
1067 (md.SemanticsAttributes & MethodSemanticsAttributes.Setter) != 0;
1070 static bool IsEventMethod (MethodDefinition md)
1072 return (md.SemanticsAttributes & MethodSemanticsAttributes.AddOn) != 0 ||
1073 (md.SemanticsAttributes & MethodSemanticsAttributes.Fire) != 0 ||
1074 (md.SemanticsAttributes & MethodSemanticsAttributes.RemoveOn) != 0;
1077 static internal PropertyDefinition GetProperty (MethodDefinition md)
1079 TypeDefinition declaringType = (TypeDefinition) md.DeclaringType;
1080 foreach (PropertyDefinition prop in declaringType.Properties)
1081 if (prop.GetMethod == md || prop.SetMethod == md)
1087 static EventDefinition GetEvent (MethodDefinition md)
1089 TypeDefinition declaringType = (TypeDefinition) md.DeclaringType;
1090 foreach (EventDefinition evt in declaringType.Events)
1091 if (evt.AddMethod == md || evt.InvokeMethod == md || evt.RemoveMethod == md)
1097 protected void MarkProperty (PropertyDefinition prop)
1099 MarkCustomAttributes (prop);
1102 protected void MarkEvent (EventDefinition evt)
1104 MarkCustomAttributes (evt);
1105 MarkMethodIfNotNull (evt.AddMethod);
1106 MarkMethodIfNotNull (evt.InvokeMethod);
1107 MarkMethodIfNotNull (evt.RemoveMethod);
1110 void MarkMethodIfNotNull (MethodReference method)
1115 MarkMethod (method);
1118 protected virtual void MarkMethodBody (MethodBody body)
1120 foreach (VariableDefinition var in body.Variables)
1121 MarkType (var.VariableType);
1123 foreach (ExceptionHandler eh in body.ExceptionHandlers)
1124 if (eh.HandlerType == ExceptionHandlerType.Catch)
1125 MarkType (eh.CatchType);
1127 foreach (Instruction instruction in body.Instructions)
1128 MarkInstruction (instruction);
1131 protected virtual void MarkInstruction (Instruction instruction)
1133 switch (instruction.OpCode.OperandType) {
1134 case OperandType.InlineField:
1135 MarkField ((FieldReference) instruction.Operand);
1137 case OperandType.InlineMethod:
1138 MarkMethod ((MethodReference) instruction.Operand);
1140 case OperandType.InlineTok:
1141 object token = instruction.Operand;
1142 if (token is TypeReference)
1143 MarkType ((TypeReference) token);
1144 else if (token is MethodReference)
1145 MarkMethod ((MethodReference) token);
1147 MarkField ((FieldReference) token);
1149 case OperandType.InlineType:
1150 MarkType ((TypeReference) instruction.Operand);