public override void VisitMethodDeclaration(MethodDeclaration methodDeclaration) { 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) || 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)) && !FilterOut(variable.Type, type) select type).ToList(); if (validTypes.Any()) { 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) || !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), string.Format(ctx.TranslateString("Parameter can be {0}"), foundType.Name), script => script.Replace(parameter.Type, CreateShortType(ctx, foundType, parameter))); }
void ProcessParameter(ParameterDeclaration parameter, AstNode rootResolutionNode, TypeCriteriaCollector collector) { var localResolveResult = ctx.Resolve(parameter) as LocalResolveResult; 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) orderby GetInheritanceDepth(type) ascending select type).ToList(); if (validTypes.Any()) { AddIssue(parameter, ctx.TranslateString("Parameter can be demoted to base class"), GetActions(parameter, validTypes)); MembersWithIssues++; } }
public override void VisitMethodDeclaration(MethodDeclaration methodDeclaration) { 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); } }