public override void VisitMethodDeclaration(MethodDeclaration methodDeclaration)
            {
                methodDeclaration.Attributes.AcceptVisitor(this);
                if (HasEntryPointSignature(methodDeclaration))
                {
                    return;
                }
                var eligibleParameters = methodDeclaration.Parameters
                                         .Where(p => p.ParameterModifier != ParameterModifier.Out && p.ParameterModifier != ParameterModifier.Ref)
                                         .ToList();

                if (eligibleParameters.Count == 0)
                {
                    return;
                }
                var declarationResolveResult = ctx.Resolve(methodDeclaration) as MemberResolveResult;

                if (declarationResolveResult == null)
                {
                    return;
                }
                var member = declarationResolveResult.Member;

                if (member.IsOverride || member.IsOverridable || member.ImplementedInterfaceMembers.Any())
                {
                    return;
                }

                var collector = new TypeCriteriaCollector(ctx);

                methodDeclaration.AcceptVisitor(collector);

                foreach (var parameter in eligibleParameters)
                {
                    ProcessParameter(parameter, methodDeclaration.Body, collector);
                }
            }
            void ProcessParameter(ParameterDeclaration parameter, AstNode rootResolutionNode, TypeCriteriaCollector collector)
            {
                var localResolveResult = ctx.Resolve(parameter) as LocalResolveResult;

                if (localResolveResult == null)
                {
                    return;
                }
                var variable = localResolveResult.Variable;
                var typeKind = variable.Type.Kind;

                if (!(typeKind == TypeKind.Class ||
                      typeKind == TypeKind.Struct ||
                      typeKind == TypeKind.Interface ||
                      typeKind == TypeKind.Array) ||
                    !collector.UsedVariables.Contains(variable))
                {
                    return;
                }

                var candidateTypes = localResolveResult.Type.GetAllBaseTypes()
                                     .Where(t => t.IsParameterized)
                                     .ToList();

                var validTypes =
                    (from type in candidateTypes
                     where !tryResolve || ParameterCanBeDemotedIssue.TypeChangeResolvesCorrectly(ctx, parameter, rootResolutionNode, type)
                     select type).ToList();

                if (!validTypes.Any())
                {
                    return;
                }

                var foundType = validTypes.FirstOrDefault();

                if (foundType == null)
                {
                    return;
                }

                AddIssue(parameter.NameToken, string.Format(ctx.TranslateString("Parameter can be {0}"),
                                                            foundType.Name),
                         script => script.Replace(parameter.Type, CreateShortType(ctx, foundType, parameter)));
            }
			public override void VisitMethodDeclaration(MethodDeclaration methodDeclaration)
			{
				if (HasEntryPointSignature(methodDeclaration))
					return;
				var eligibleParameters = methodDeclaration.Parameters
					.Where(p => p.ParameterModifier != ParameterModifier.Out && p.ParameterModifier != ParameterModifier.Ref)
					.ToList();
				if (eligibleParameters.Count == 0)
					return;
				var declarationResolveResult = ctx.Resolve(methodDeclaration) as MemberResolveResult;
				if (declarationResolveResult == null)
					return;
				var member = declarationResolveResult.Member;
				if (member.IsOverride || member.IsOverridable || member.ImplementedInterfaceMembers.Any())
					return;

				var collector = new TypeCriteriaCollector(ctx);
				methodDeclaration.AcceptVisitor(collector);
				
				foreach (var parameter in eligibleParameters) {
					ProcessParameter(parameter, methodDeclaration.Body, collector);
				}
			}
Example #4
0
            void ProcessParameter(ParameterDeclaration parameter, AstNode rootResolutionNode, TypeCriteriaCollector collector)
            {
                var localResolveResult = ctx.Resolve(parameter) as LocalResolveResult;

                if (localResolveResult == null)
                {
                    return;
                }
                var variable = localResolveResult.Variable;
                var typeKind = variable.Type.Kind;

                if (!(typeKind == TypeKind.Class ||
                      typeKind == TypeKind.Struct ||
                      typeKind == TypeKind.Interface ||
                      typeKind == TypeKind.Array) ||
                    parameter.Type is PrimitiveType ||
                    !collector.UsedVariables.Contains(variable))
                {
                    return;
                }

                var candidateTypes = localResolveResult.Type.GetAllBaseTypes().ToList();

                TypesChecked += candidateTypes.Count;
                var criterion = collector.GetCriterion(variable);

                var possibleTypes =
                    (from type in candidateTypes
                     where !type.Equals(localResolveResult.Type) && criterion.SatisfiedBy(type)
                     select type).ToList();

                TypeResolveCount += possibleTypes.Count;
                var validTypes =
                    (from type in possibleTypes
                     where !tryResolve || TypeChangeResolvesCorrectly(ctx, parameter, rootResolutionNode, type)
                     select type).ToList();

                if (validTypes.Any())
                {
                    // don't demote an array to IList
                    if (variable.Type.Kind == TypeKind.Array && validTypes.Any(t => t.Namespace == "System.Collections" && t.Name == "IList"))
                    {
                        return;
                    }
                    AddIssue(parameter, ctx.TranslateString("Parameter can be demoted to base class"), GetActions(parameter, validTypes));
                    MembersWithIssues++;
                }
            }
			void ProcessParameter(ParameterDeclaration parameter, AstNode rootResolutionNode, TypeCriteriaCollector collector)
			{
				var localResolveResult = ctx.Resolve(parameter) as LocalResolveResult;
				if (localResolveResult == null)
					return;
				var variable = localResolveResult.Variable;
				var typeKind = variable.Type.Kind;
				if (!(typeKind == TypeKind.Class ||
					  typeKind == TypeKind.Struct ||
					  typeKind == TypeKind.Interface ||
					  typeKind == TypeKind.Array) ||
				    parameter.Type is PrimitiveType ||
					!collector.UsedVariables.Contains(variable)) {
					return;
				}

				var candidateTypes = localResolveResult.Type.GetAllBaseTypes().ToList();
				TypesChecked += candidateTypes.Count;
				var criterion = collector.GetCriterion(variable);

				var possibleTypes = 
					(from type in candidateTypes
					 where !type.Equals(localResolveResult.Type) && criterion.SatisfiedBy(type)
					 select type).ToList();

				TypeResolveCount += possibleTypes.Count;
				var validTypes = 
					(from type in possibleTypes
					 where !tryResolve || TypeChangeResolvesCorrectly(parameter, rootResolutionNode, type)
					 select type).ToList();
				if (validTypes.Any()) {
					// don't demote an array to IList
					if (variable.Type.Kind == TypeKind.Array && validTypes.Any (t => t.Namespace == "System.Collections" && t.Name == "IList")) {
						return;
					}
					AddIssue(parameter, ctx.TranslateString("Parameter can be demoted to base class"), GetActions(parameter, validTypes));
					MembersWithIssues++;
				}
			}