예제 #1
0
        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));
        }
예제 #2
0
        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);
        }