public static bool TryGetFormattingParameters(CSharpInvocationResolveResult invocationResolveResult, InvocationExpression invocationExpression, out Expression formatArgument, out TextLocation formatStart, out IList<Expression> arguments, Func<IParameter, Expression, bool> argumentFilter) { if (argumentFilter == null) argumentFilter = (p, e) => true; formatArgument = null; formatStart = default(TextLocation); arguments = new List<Expression>(); var argumentToParameterMap = invocationResolveResult.GetArgumentToParameterMap(); var resolvedParameters = invocationResolveResult.Member.Parameters; var allArguments = invocationExpression.Arguments.ToArray(); for (int i = 0; i < allArguments.Length; i++) { var parameterIndex = argumentToParameterMap[i]; if (parameterIndex < 0 || parameterIndex >= resolvedParameters.Count) { // No valid mapping for this parameter, skip it continue; } var parameter = resolvedParameters[parameterIndex]; var argument = allArguments[i]; if (parameter.Type.IsKnownType(KnownTypeCode.String) && parameterNames.Contains(parameter.Name)) { formatArgument = argument; formatStart = argument.StartLocation; } else if ((formatArgument != null || parameter.IsParams) && argumentFilter(parameter, argument)) { arguments.Add(argument); } } return formatArgument != null; }
AstNode ToStaticMethodInvocation(InvocationExpression invocation, MemberReferenceExpression memberReference, CSharpInvocationResolveResult invocationRR) { var newArgumentList = invocation.Arguments.Select(arg => arg.Clone()).ToList(); newArgumentList.Insert(0, memberReference.Target.Clone()); var newTarget = memberReference.Clone() as MemberReferenceExpression; newTarget.Target = new IdentifierExpression(invocationRR.Member.DeclaringType.Name); return new InvocationExpression(newTarget, newArgumentList); }
void CheckFormattingCall(InvocationExpression invocationExpression, CSharpInvocationResolveResult invocationResolveResult) { Expression formatArgument; IList<Expression> formatArguments; TextLocation formatStart; // Only check parameters that are of type object: String means it is neccessary, others // means that there is another problem (ie no matching overload of the method). Func<IParameter, Expression, bool> predicate = (parameter, argument) => { var type = parameter.Type; if (type is TypeWithElementType && parameter.IsParams) { type = ((TypeWithElementType)type).ElementType; } var typeDefinition = type.GetDefinition(); if (typeDefinition == null) return false; return typeDefinition.IsKnownType(KnownTypeCode.Object); }; if (FormatStringHelper.TryGetFormattingParameters(invocationResolveResult, invocationExpression, out formatArgument, out formatStart, out formatArguments, predicate)) { foreach (var argument in formatArguments) { CheckExpressionInAutoCallContext(argument); } } }