public static IMethodSymbol GetMethodSymbol([NotNull] this ArgumentSyntax argument, [NotNull] SemanticModel semanticModel) { Requires.NotNull(argument, nameof(argument)); Requires.NotNull(semanticModel, nameof(semanticModel)); var methodCallExpression = argument.GetInvocationExpression(); return(methodCallExpression.GetReferencedSymbol <IMethodSymbol>(semanticModel)); }
public static IParameterSymbol GetParameterSymbol([NotNull] this ArgumentSyntax argument, [NotNull] SemanticModel semanticModel) { Requires.NotNull(argument, nameof(argument)); Requires.NotNull(semanticModel, nameof(semanticModel)); var invocation = argument.GetInvocationExpression(); Requires.That(!(invocation as InvocationExpressionSyntax)?.IsNameOfOperator(semanticModel) ?? true, "Cannot get parameter symbol for nameof operator."); var methodSymbol = invocation.GetReferencedSymbol(semanticModel) as IMethodSymbol; var propertySymbol = invocation.GetReferencedSymbol(semanticModel) as IPropertySymbol; var parameterSymbols = methodSymbol?.Parameters ?? propertySymbol.Parameters; // If this is a named argument, simply look up the parameter symbol by name. if (argument.NameColon != null) { return(parameterSymbols.Single(parameter => parameter.Name == argument.NameColon.Name.Identifier.ValueText)); } // Otherwise, get the corresponding invocation or object creation expression and match the argument. var arguments = default(SeparatedSyntaxList <ArgumentSyntax>); var invocationExpression = invocation as InvocationExpressionSyntax; var objectCreationExpression = invocation as ObjectCreationExpressionSyntax; var constructorInitializer = invocation as ConstructorInitializerSyntax; var elementAccessExpression = invocation as ElementAccessExpressionSyntax; var implicitElementAccessExpression = invocation as ImplicitElementAccessSyntax; if (invocationExpression != null) { arguments = invocationExpression.ArgumentList.Arguments; } else if (objectCreationExpression != null) { arguments = objectCreationExpression.ArgumentList.Arguments; } else if (constructorInitializer != null) { arguments = constructorInitializer.ArgumentList.Arguments; } else if (elementAccessExpression != null) { arguments = elementAccessExpression.ArgumentList.Arguments; } else if (implicitElementAccessExpression != null) { arguments = implicitElementAccessExpression.ArgumentList.Arguments; } else { Assert.NotReached("Expected an invocation expression or an object creation expression."); } for (var i = 0; i < arguments.Count; ++i) { // If this is a method with a params parameter at the end, we might have more arguments than parameters. In that case, // return the parameter symbol for the params parameter if the argument exceeds the parameter count. if (i >= parameterSymbols.Length) { var lastParameter = parameterSymbols[methodSymbol.Parameters.Length - 1]; if (lastParameter.IsParams) { return(lastParameter); } Assert.NotReached("There are more arguments than parameters."); } if (arguments[i] == argument) { return(parameterSymbols[i]); } } Assert.NotReached($"Unable to determine parameter symbol for argument '{argument}'."); return(null); }