public RuleResult CheckType (TypeDefinition type)
		{
			// rule does not apply to interface (since [Serializable] is not applicable to interfaces)
			// nor does it apply to delegates
			if (type.IsInterface || type.IsDelegate ())
				return RuleResult.DoesNotApply;

			// rule does not apply if the type does not implements ISerializable 
			if (!type.Implements ("System.Runtime.Serialization", "ISerializable"))
				return RuleResult.DoesNotApply;

			// rule applies only if base type is serializable
			if (!type.BaseType.IsNamed ("System", "Object")) {
				TypeDefinition base_type = type.BaseType.Resolve ();
				// in doubt don't report
				if ((base_type == null) || !base_type.IsSerializable)
					return RuleResult.DoesNotApply;
			}

			// rule applies, only Success or Failure from the point on

			// ok if the type has the [Serializable] pseudo-attribute
			if (type.IsSerializable)
				return RuleResult.Success;

			Runner.Report (type, Severity.Critical, Confidence.Total);
			return RuleResult.Failure;
		}
Esempio n. 2
0
 /// <summary>
 /// Create a type builder for the given type.
 /// </summary>
 internal static IClassBuilder[] Create(ReachableContext context, AssemblyCompiler compiler, TypeDefinition typeDef)
 {
     if (typeDef.FullName == "<Module>")
         return new IClassBuilder[] { new SkipClassBuilder() };
     if (typeDef.IsDelegate())
         return new IClassBuilder[] {new DelegateClassBuilder(context, compiler, typeDef) };
     if (typeDef.IsAttribute()) 
         return new IClassBuilder[]  {new AttributeClassBuilder(context, compiler, typeDef) };
     if (typeDef.IsAnnotation())
         return new IClassBuilder[] {new AnnotationClassBuilder(context, compiler, typeDef) };
     if (typeDef.HasDexImportAttribute())
         return new IClassBuilder[] {new DexImportClassBuilder(context, compiler, typeDef) };
     if (typeDef.HasJavaImportAttribute())
         return new IClassBuilder[] {CreateJavaImportBuilder(context, compiler, typeDef)};
     if (typeDef.IsEnum)
     {
         if (typeDef.UsedInNullableT)
         {
             var nullableBaseClassBuilder = new NullableEnumBaseClassBuilder(context, compiler, typeDef);
             IClassBuilder builder = new EnumClassBuilder(context, compiler, typeDef, nullableBaseClassBuilder);
             return new[] { builder, nullableBaseClassBuilder };
         }
         return new IClassBuilder[] { new EnumClassBuilder(context, compiler, typeDef, null) };
     }
     else
     {
         IClassBuilder builder = new StandardClassBuilder(context, compiler, typeDef);
         if (typeDef.UsedInNullableT)
             return new[] { builder, new NullableBaseClassBuilder(context, compiler, typeDef) };
         return new[] { builder };
     }
 }
        public RuleResult CheckType(TypeDefinition type)
        {
            // rule applies only to types and interfaces
            if (type.IsEnum || type.IsDelegate() || type.IsGeneratedCode() ||
                type.IsValueType || type.IsInterface)
                return RuleResult.DoesNotApply;

            // rule only applies to type that implements IDisposable
            if (!type.Implements("System", "IDisposable"))
                return RuleResult.DoesNotApply;

            // rule only applies to type that doesn't derive from class that implements IDisposable
            if (type.BaseType.Implements("System", "IDisposable"))
                return RuleResult.DoesNotApply;

            // rule only applies if type has a Dispose(bool) method
            if (!type.HasMethod(Dispose))
                return RuleResult.DoesNotApply;

            // no problem if a finalizer is found
            if (type.HasMethod(MethodSignatures.Finalize))
                return RuleResult.Success;

            Runner.Report(type, Severity.Medium, Confidence.High);
            return RuleResult.Failure;
        }
		public RuleResult CheckType (TypeDefinition type)
		{
			// rule applies only to types, interfaces and structures (value types)
			if (type.IsEnum || type.IsDelegate () || type.IsGeneratedCode ())
				return RuleResult.DoesNotApply;

			// rule onyly applies to type that implements IDisposable
			if (!type.Implements ("System.IDisposable"))
				return RuleResult.DoesNotApply;

			// no problem is a finalizer is found
			if (type.HasMethod (MethodSignatures.Finalize))
				return RuleResult.Success;

			// otherwise check for native types
			foreach (FieldDefinition field in type.Fields) {
				// we can't dispose static fields in IDisposable
				if (field.IsStatic)
					continue;
				if (!field.FieldType.GetElementType ().IsNative ())
					continue;
				Runner.Report (field, Severity.High, Confidence.High);
			}

			// special case: a struct cannot define a finalizer so it's a
			// bad candidate to hold references to unmanaged resources
			if (type.IsValueType && (Runner.CurrentRuleResult == RuleResult.Failure))
				Runner.Report (type, Severity.High, Confidence.High, Struct);

			return Runner.CurrentRuleResult;
		}
		public RuleResult CheckType (TypeDefinition type)
		{
			// rule only apply to (non generated) delegates
			if (!type.IsDelegate () || type.IsGeneratedCode ())
				return RuleResult.DoesNotApply;

			MethodDefinition invoke = type.GetMethod ("Invoke");
			// this happens for System.MulticastDelegate
			if (invoke == null)
				return RuleResult.DoesNotApply;

			if (!invoke.ReturnType.IsNamed ("System", "Void"))
				return RuleResult.Success;

			if (!invoke.HasParameters)
				return RuleResult.Success;

			IList<ParameterDefinition> pdc = invoke.Parameters;
			if (pdc.Count != 2)
				return RuleResult.Success;
			if (!pdc [0].ParameterType.IsNamed ("System", "Object"))
				return RuleResult.Success;
			if (!pdc [1].ParameterType.Inherits ("System", "EventArgs"))
				return RuleResult.Success;

			Runner.Report (type, Severity.Medium, Confidence.High);
			return RuleResult.Failure;
		}
		public RuleResult CheckType (TypeDefinition type)
		{
			if (type.IsInterface || type.IsValueType || type.IsDelegate ())
				return RuleResult.DoesNotApply;

			int depth = 0;
			while (type.BaseType != null) {
				type = type.BaseType.Resolve ();
				if (type == null)
					break;
				if (countExternalDepth || Runner.Assemblies.Contains (type.Module.Assembly))
					depth++;
			}

			if (depth <= MaximumDepth)
				return RuleResult.Success;

			// Confidence is total unless we count outside the current assembly,
			// where it's possible we can't resolve up to System.Object
			Confidence confidence = countExternalDepth ? Confidence.High : Confidence.Total;
			// Severity is based on the depth
			string msg = String.Format (CultureInfo.CurrentCulture, "Inheritance tree depth : {0}.", depth);
			Runner.Report (type, GetSeverity (depth), confidence, msg);
			return RuleResult.Failure;
		}
		public RuleResult CheckType (TypeDefinition type)
		{
			//does rule apply?
			if (type.IsEnum || type.IsInterface || type.IsAbstract || type.IsDelegate () || type.IsGeneratedCode ())
				return RuleResult.DoesNotApply;

			if (!type.HasFields || (type.Fields.Count < MinimumFieldCount))
				return RuleResult.DoesNotApply;
			if (!type.HasMethods || (type.Methods.Count < MinimumMethodCount))
				return RuleResult.DoesNotApply;

			//yay! rule do apply!
			double coh = GetCohesivenessForType (type);
			if (coh >= SuccessLowerLimit)
				return RuleResult.Success;
			if (0 == coh)
				return RuleResult.DoesNotApply;

			//how's severity?
			Severity sev = GetCohesivenessSeverity(coh);

			string msg = String.Format (CultureInfo.CurrentCulture, "Type cohesiveness : {0}%", (int) (coh * 100));
			Runner.Report (type, sev, Confidence.Normal, msg);
			return RuleResult.Failure;
		}
		public RuleResult CheckType (TypeDefinition type)
		{
			// rule doesn't apply on enums, interfaces, delegates or to compiler/tools-generated code
			// e.g. CSC compiles anonymous methods as an inner type that expose public fields
			if (type.IsEnum || type.IsInterface || !type.HasFields || type.IsDelegate () || type.IsGeneratedCode ())
				return RuleResult.DoesNotApply;
			
			// rule doesn't apply to type non (externally) visible
			if (!type.IsVisible ())
				return RuleResult.DoesNotApply;

			foreach (FieldDefinition fd in type.Fields) {
				if (!fd.IsVisible () || fd.IsSpecialName || fd.HasConstant || fd.IsInitOnly)
					continue;

				string name = fd.Name;
				if (fd.FieldType.IsArray) {
					string s = String.Format (CultureInfo.InvariantCulture, 
						"Consider changing the field '{0}' to a private or internal field and add a 'Set{1}{2}' method.",
						name, Char.ToUpper (name [0], CultureInfo.InvariantCulture).ToString (CultureInfo.InvariantCulture), name.Substring (1));
					Runner.Report (fd, Severity.Medium, Confidence.Total, s);
				} else {
					string s = String.Format (CultureInfo.InvariantCulture, 
						"Field '{0}' should be private or internal and its value accessed through a property.", name);
					Runner.Report (fd, Severity.Medium, Confidence.Total, s);
				}
			}
			return Runner.CurrentRuleResult;
		}
		public RuleResult CheckType (TypeDefinition type)
		{
			if (type.IsEnum || type.IsInterface || type.IsDelegate ())
				return RuleResult.DoesNotApply;

			MethodDefinition equality = type.GetMethod (MethodSignatures.op_Equality);
			if ((equality == null) || type.HasMethod (MethodSignatures.Equals))
				return RuleResult.Success;
			
			Runner.Report (equality, Severity.High, Confidence.High);
			return RuleResult.Failure;
		}
		public RuleResult CheckType (TypeDefinition type)
		{
			// rule does not apply to interface and enumerations
			if (type.IsInterface || type.IsEnum || !type.HasFields || type.IsDelegate ())
				return RuleResult.DoesNotApply;

			foreach (FieldDefinition field in type.Fields) {
				if (field.IsStatic && field.IsVisible () && !field.IsInitOnly && !field.IsLiteral) {
					Runner.Report (field, Severity.Medium, Confidence.High);
				}
			}

			return Runner.CurrentRuleResult;
		}
		public RuleResult CheckType (TypeDefinition type)
		{
			// rule does not apply to interface and enumerations
			if (type.IsInterface || type.IsEnum || !type.HasFields || type.IsDelegate ())
				return RuleResult.DoesNotApply;

			foreach (FieldDefinition field in type.Fields) {
				if (field.IsStatic && field.IsVisible () && !field.IsInitOnly && !field.IsLiteral) {
					Runner.Report (field, Severity.Medium, Confidence.High, String.Format("Change the field \"{0}\" to read-only, or mark it [ThreadStatic], or make it non visible outside the assembly.", field.Name));
				}
			}

			return Runner.CurrentRuleResult;
		}
		public RuleResult CheckType (TypeDefinition type)
		{
			// rule does not apply to interface, enumerations and delegates or to types without fields
			if (type.IsInterface || type.IsEnum || !type.HasFields || type.IsDelegate ())
				return RuleResult.DoesNotApply;

			foreach (FieldDefinition field in type.Fields) {
				//IsInitOnly == readonly
				if (field.IsInitOnly && field.IsVisible () && field.FieldType.IsArray) {
					// Medium = this will work as long as no code starts "playing" with the array values
					Runner.Report (field, Severity.Medium, Confidence.Total);
				}
			}

			return Runner.CurrentRuleResult;
		}
		public RuleResult CheckType (TypeDefinition type)
		{
			// rule applies only to sealed types, but not to enum, value types and delegate (sealed)
			if (!type.IsSealed || type.IsEnum || type.IsValueType || type.IsDelegate ())
				return RuleResult.DoesNotApply;

			foreach (MethodDefinition method in type.Methods) {
				// method is virtual and not final (sealed)
				if (method.IsVirtual && !method.IsFinal) {
					// so just make sure it's not an override of an ancestor
					if (!method.IsOverride ())
						Runner.Report (method, Severity.Low, Confidence.Total);
				}
			}

			return Runner.CurrentRuleResult;
		}
		public RuleResult CheckType (TypeDefinition type)
		{
			if (type.IsEnum || type.IsInterface || type.IsDelegate ())
				return RuleResult.DoesNotApply;

			// get the static constructor
			MethodDefinition cctor = type.Methods.FirstOrDefault (m => m.IsConstructor && m.IsStatic);
			if (cctor == null)
				return RuleResult.DoesNotApply;

			// check if we store things into static fields
			if (!OpCodeEngine.GetBitmask (cctor).Get (Code.Stsfld))
				return RuleResult.DoesNotApply;

			// verify each store we do in a static field
			foreach (Instruction ins in cctor.Body.Instructions) {
				if (ins.OpCode.Code != Code.Stsfld)
					continue;

				// make sure we assign to this type (and not another one)
				FieldReference fr = (ins.Operand as FieldReference);
				if (fr.DeclaringType != type)
					continue;
				// if it's this one then we have a FieldDefinition available
				FieldDefinition field = (fr as FieldDefinition);
				// check for static (we already know with Stsfld) and readonly
				if (!field.IsInitOnly)
					continue;

				// look at what is being assigned
				Instruction previous = ins.Previous;
				// while skipping conversions
				if (Convert.Get (previous.OpCode.Code))
					previous = previous.Previous;
				// and report constant stuff
				if (Constant.Get (previous.OpCode.Code)) {
					// adjust severity based on the field visibility and it's type
					Severity s = (field.FieldType.IsNamed ("System", "String") || !field.IsVisible ()) ?
						Severity.High : Severity.Medium;
					Runner.Report (field, s, Confidence.Normal);
				}
			}

			return Runner.CurrentRuleResult;
		}
        public RuleResult CheckType(TypeDefinition type)
        {
            // rule does not apply to interface, enumerations and delegates or to types without fields
            if (type.IsInterface || type.IsEnum || !type.HasFields || type.IsDelegate ())
                return RuleResult.DoesNotApply;

            foreach (FieldDefinition field in type.Fields) {
                if (!field.IsVisible ())
                    continue;

                //not readonly native fields or arrays of native fields
                if ((field.FieldType.IsNative () && !field.IsInitOnly) ||
                    (field.FieldType.IsArray && field.FieldType.GetElementType ().IsNative ())) {

                    Runner.Report (field, Severity.Medium, Confidence.Total);
                }
            }

            return Runner.CurrentRuleResult;
        }
		public RuleResult CheckType (TypeDefinition type)
		{
			// rule does not apply to interface, enumerations or delegates
			if (type.IsInterface || type.IsEnum || !type.HasMethods || type.IsDelegate ())
				return RuleResult.DoesNotApply;

			MethodDefinition private_static_ctor = null;
			foreach (MethodDefinition method in type.Methods) {
				if (method.IsStatic && !method.IsPrivate && method.IsConstructor) {
					private_static_ctor = method;
					break; // there cannot be two .cctor's so we can stop looking
				}
			}

			if (private_static_ctor == null)
				return RuleResult.Success;

			Runner.Report (private_static_ctor, Severity.Critical, Confidence.Total);
			return RuleResult.Failure;
		}
		public RuleResult CheckType (TypeDefinition type)
		{
			// rule does not apply to enumerations and delegates
			if (type.IsEnum || type.IsDelegate ())
				return RuleResult.DoesNotApply;

			// quick out if there are no events
			if (!type.HasEvents)
				return RuleResult.Success;

			foreach (EventDefinition evnt in type.Events) {
				string name = evnt.Name;
				if (name.StartsWith ("After", StringComparison.Ordinal) || 
					name.StartsWith ("Before", StringComparison.Ordinal)) {
					Runner.Report (evnt, Severity.Medium, Confidence.Total);
				}
			}

			return Runner.CurrentRuleResult;
		}
		public RuleResult CheckType (TypeDefinition type)
		{
			if (type.IsEnum || type.IsInterface || type.IsDelegate ())
				return RuleResult.DoesNotApply;

			foreach (var kv in AlternativeMethodNames) {
				MethodDefinition op = type.GetMethod (kv.Key);
				if (op == null)
					continue;
				bool alternativeDefined = false;
				foreach (MethodDefinition alternative in type.Methods) {
					if (kv.Value.Matches (alternative)) {
						alternativeDefined = true;
						break;
					}
				}

				if (!alternativeDefined) {
					string s = String.Format ("This type implements the '{0}' operator. Some languages do not support overloaded operators so an alternative '{1}' method should be provided.",
						kv.Key.Name, kv.Value.Name);
					Runner.Report (op, Severity.Medium, Confidence.High, s);
				}
			}

			return Runner.CurrentRuleResult;
		}
		public RuleResult CheckType (TypeDefinition type)
		{
			if (type.IsEnum || type.IsDelegate ())
				return RuleResult.DoesNotApply;

			// we look for a Parse method defined in the type
			bool has_parse = false;
			foreach (MethodDefinition method in type.Methods) {
				if (method.IsConstructor)
					continue;
				if (MethodSignatures.Parse.Matches (method)) {
					// the type provides a "<type> <type>::Parse(string)" method
					has_parse = true;
					break;
				}
			}

			// if no Parse method is found; or
			// if a Parse method is found along with a TryParse method
			if (!has_parse || HasTryParseMethod (type))
				return RuleResult.Success;

			// otherwise we report a defect to add a TryParse alternative
			Runner.Report (type, Severity.Medium, Confidence.High);
			return RuleResult.Failure;
		}
		public RuleResult CheckType (TypeDefinition type)
		{
			// rule does not apply to enums, delegates and to generated code
			if (type.IsEnum || type.IsDelegate () || type.IsGeneratedCode ())
				return RuleResult.DoesNotApply;

			// rule applies only if the type overrides Equals(object)
			if (!type.HasMethod (MethodSignatures.Equals))
				return RuleResult.DoesNotApply;

			// if so then the type should also implement Equals(type) since this avoid a cast 
			// operation (for reference types) and also boxing (for value types).

			// we suggest to implement IEquatable<T> if
			// * the assembly targets the 2.0 (or later) runtime
			// * and it does not already implement it
			if (type.Module.Runtime >= TargetRuntime.Net_2_0) {
				if (!type.Implements ("System", "IEquatable`1")) {
					Runner.Report (type, Severity.Medium, Confidence.Total, "Implement System.IEquatable<T>");
				}
				return Runner.CurrentRuleResult;
			}

			parameters [0] = type.GetFullName ();
			if (type.GetMethod (MethodAttributes.Public, "Equals", "System.Boolean", parameters) != null)
				return RuleResult.Success;

			// we consider this a step more severe for value types since it will need 
			// boxing/unboxing with Equals(object)
			Severity severity = type.IsValueType ? Severity.Medium : Severity.Low;
			string msg = String.Format (CultureInfo.InvariantCulture, "Implement 'bool Equals({0})'", type.Name);
			Runner.Report (type, severity, Confidence.High, msg);
			return RuleResult.Failure;
		}
		public RuleResult CheckType (TypeDefinition type)
		{
			// we don't control, nor report, p/invoke declarations - sometimes the poor C 
			// guys don't have a choice to make long parameter lists ;-)
			if (OnlyContainsExternalMethods (type))
				return RuleResult.DoesNotApply;
			
			if (type.IsDelegate ())
				return CheckDelegate (type);

			if (type.HasMethods) {
				CheckConstructor (GetSmallestConstructorFrom (type));

				foreach (MethodDefinition method in GetSmallestOverloaded (type)) 
					CheckMethod (method);
			}

			return Runner.CurrentRuleResult;
		}
		public RuleResult CheckType (TypeDefinition type)
		{
			// rule doesn't apply to enums, interfaces, structs, delegates or generated code
			if (type.IsEnum || type.IsInterface || type.IsValueType || type.IsDelegate () || type.IsGeneratedCode ())
				return RuleResult.DoesNotApply;

			MethodDefinition explicitDisposeMethod = null;
			MethodDefinition implicitDisposeMethod = null;

			bool abstractWarning = false;

			if (type.Implements ("System.IDisposable")) {
				implicitDisposeMethod = type.GetMethod (MethodSignatures.Dispose);
				explicitDisposeMethod = type.GetMethod (MethodSignatures.DisposeExplicit);

				if (IsAbstract (implicitDisposeMethod) || IsAbstract (explicitDisposeMethod)) {
					abstractWarning = true;
				} else {
					return RuleResult.Success;
				}
			}

			foreach (FieldDefinition field in type.Fields) {
				// we can't dispose static fields in IDisposable
				if (field.IsStatic)
					continue;
				TypeDefinition fieldType = field.FieldType.GetElementType ().Resolve ();
				if (fieldType == null)
					continue;
				// enums and primitives don't implement IDisposable
				if (fieldType.IsEnum || fieldType.IsPrimitive)
					continue;
				if (fieldType.Implements ("System.IDisposable")) {
					Runner.Report (field, Severity.High, Confidence.High,
						abstractWarning ? AbstractTypeMessage : TypeMessage);
				}
			}

			// Warn about possible confusion if the Dispose methods are abstract
			if (IsAbstract (implicitDisposeMethod))
				Runner.Report (implicitDisposeMethod, Severity.Medium, Confidence.High, AbstractDisposeMessage);

			return Runner.CurrentRuleResult;
		}
		public RuleResult CheckType (TypeDefinition type)
		{
			if (type.IsInterface || type.IsEnum || type.IsDelegate ())
				return RuleResult.DoesNotApply;

			foreach (var kv in SymmetricOperators_Warning)
				CheckOperatorPair (kv, type, Severity.Medium);
			foreach (var kv in SymmetricOperators_Error)
				CheckOperatorPair (kv, type, Severity.High);

			return Runner.CurrentRuleResult;
		}
		public RuleResult CheckType (TypeDefinition type)
		{
			// rule does not apply to enums, interfaces and delegates
			// or types and structures without fields
			// nor does it apply to generated code (quite common for anonymous types)
			if (type.IsEnum || type.IsInterface || !type.HasFields || type.IsDelegate () || type.IsGeneratedCode ())
				return RuleResult.DoesNotApply;

			// copy all fields into an hashset
			fields.Clear ();
			foreach (FieldDefinition field in type.Fields) {
				if (!field.IsPrivate || field.IsLiteral)
					continue;

				fields.Add (field);
			}

			// scan all methods, including constructors, to find if the field is used
			foreach (MethodDefinition method in type.Methods) {
				if (!method.HasBody)
					continue;

				// don't check the method if it does not access any field
				if (!OpCodeEngine.GetBitmask (method).Intersect (LoadStoreFields))
					continue;

				foreach (Instruction ins in method.Body.Instructions) {
					FieldDefinition fd = ins.GetField ();
					if (fd == null)
						continue;

					fields.Remove (fd);
				}
			}

			// check remaining (private) fields in the set
			foreach (FieldDefinition field in fields) {
				Runner.Report (field, Severity.Medium, Confidence.Normal);
			}
			return Runner.CurrentRuleResult;
		}
		public RuleResult CheckType (TypeDefinition type)
		{
			// rule doesn't apply to interfaces and enums
			if (type.IsInterface || type.IsEnum || type.IsDelegate ())
				return RuleResult.DoesNotApply;

			bool equals = type.HasMethod (MethodSignatures.Equals);
			bool getHashCode = type.HasMethod (MethodSignatures.GetHashCode);

			// if we have Equals but no GetHashCode method
			if (equals && !getHashCode) {
				string text = String.Format (Message, MethodSignatures.Equals, MethodSignatures.GetHashCode);
				Runner.Report (type, Severity.Critical, Confidence.High, text);
			}

			// if we have GetHashCode but no Equals method
			if (!equals && getHashCode) {
				string text = String.Format (Message, MethodSignatures.GetHashCode, MethodSignatures.Equals);
				Runner.Report (type, Severity.Medium, Confidence.High, text);
			}

			// we either have both Equals and GetHashCode or none (both fine)
			return Runner.CurrentRuleResult;
		}
		public RuleResult CheckType (TypeDefinition type)
		{
			// rule applies only if the type isn't: an enum, an interface, a struct, a delegate or compiler generated
			if (type.IsEnum || type.IsInterface || type.IsValueType || type.IsDelegate () || type.IsGeneratedCode ())
				return RuleResult.DoesNotApply;

			// it also does not apply if the type is static (2.0+ only)
			if (type.IsStatic ())
				return RuleResult.DoesNotApply;

			if (!IsAllStatic (type))
				return RuleResult.Success;

			// rule applies!

			foreach (MethodDefinition ctor in type.Methods) {
				if (ctor.IsConstructor && !ctor.IsStatic && ctor.IsVisible ()) {
					Runner.Report (ctor, Severity.Low, Confidence.High);
				}
			}

			return Runner.CurrentRuleResult;
		}
		public RuleResult CheckType (TypeDefinition type)
		{
			if (!type.IsClass || type.IsEnum || type.IsInterface || type.IsDelegate ())
				return RuleResult.DoesNotApply;

			if (type.HasFields) {
				foreach (var field in type.Fields)
					CheckField (field);
			}
			if (type.HasProperties) {
				foreach (var property in type.Properties)
					CheckProperty (property);
			}
			if (type.HasMethods) {
				foreach (var method in type.Methods)
					CheckMethod (method);
			}

			return Runner.CurrentRuleResult;
		}
        protected virtual void WriteTypeInternal(TypeDefinition type, Action<IMemberDefinition> writeMember, bool showCompilerGeneratedMembers)
        {
            string typeName = string.Empty;

            membersStack.Push(type);
            if (type.IsDelegate())
            {
                WriteDelegate(type);
                return;
            }
            typeName = WriteTypeDeclaration(type);

            int startIndex = this.formatter.CurrentPosition;

            this.formatter.WriteStartBlock();

            WriteBeginBlock();

            WriteTypeOpeningBlock(type);

            WriteTypeMembers(type, writeMember, showCompilerGeneratedMembers);

            WriteLine();
            Outdent();

            WriteEndBlock(typeName);
            membersStack.Pop();

            this.currentWritingInfo.MemberDefinitionToFoldingPositionMap[type] = new OffsetSpan(startIndex, formatter.CurrentPosition - 1);

            this.formatter.WriteEndBlock();
        }
        public void WriteTypeDeclaration(TypeDefinition type, IWriterContextService writerContextService, bool showCompilerGeneratedMembers = false)
        {
            this.writerContextService = writerContextService;
            this.writerContext = writerContextService.GetWriterContext(type, Language);
            this.currentWritingInfo = new WritingInfo(type);

            WriteAttributes(type, new string[] { "System.Reflection.DefaultMemberAttribute" });

            membersStack.Push(type);
            if (type.IsDelegate())
            {
                WriteDelegate(type);
                WriteLine();
                membersStack.Pop();
                return;
            }

            WriteTypeDeclaration(type);
            WriteLine();

            membersStack.Pop();
        }
		public RuleResult CheckType (TypeDefinition type)
		{
			// rule only apply to (non generated) delegates
			if (!type.IsDelegate () || type.IsGeneratedCode ())
				return RuleResult.DoesNotApply;

			MethodDefinition invoke = type.GetMethod ("Invoke");
			// this happens for System.MulticastDelegate
			if (invoke == null)
				return RuleResult.DoesNotApply;

			int n = 0;
			Severity severity = Severity.Medium;
			bool use_structure = false;
			// check parameters for 'ref', 'out', 'params'
			if (invoke.HasParameters) {
				IList<ParameterDefinition> pdc = invoke.Parameters;
				n = pdc.Count;
				// too many parameters to directly use Action/Func
				// so we lower severity and suggest grouping them
				if (n > ((type.Module.Runtime >= TargetRuntime.Net_4_0) ? 16 : 4)) {
					severity = Severity.Low;
					n = 1;
					use_structure = true;
				}

				// special cases not directly usable with Action/Func
				foreach (ParameterDefinition pd in pdc) {
					if (pd.IsOut || pd.ParameterType.IsByReference || pd.IsParams ())
						return RuleResult.Success;
				}
			}

			string msg = invoke.ReturnType.IsNamed ("System", "Void") ? ActionMessage [n] : FuncMessage [n];
			if (use_structure)
				msg += " and use a structure to hold all your parameters into <T>.";
			Runner.Report (type, severity, Confidence.High, msg);
			return Runner.CurrentRuleResult;
		}