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 || ParameterCanBeDeclaredWithBaseTypeIssue.TypeChangeResolvesCorrectly(ctx, parameter, rootResolutionNode, type) select type).ToList(); if (!validTypes.Any()) { return; } var foundType = validTypes.FirstOrDefault(); if (foundType == null) { return; } AddDiagnosticAnalyzer(new CodeIssue(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)))); }