4

I'm doing code analysis with Roslyn in order to validate that even though I have the following signature

public void MyMethod(object anObject, MyCustomObject customObject);

I only want to receive, as parameters, a string (1st) and a child from MyCustomObject (2nd). I have no power over the signature, it cannot be changed.

Here's what I did to evaluate my method (Here's a snippet)

    public void OnMethodInvocation(SyntaxNodeAnalysisContext context)
    {
        var invocation= context.Node as InvocationExpressionSyntax;
        var symbol = context.SemanticModel.GetSymbolInfo(invocation).Symbol as IMethodSymbol;

        if (symbol?.Name.ToString()== "MyMethod")
        {
            var parameterList = invocation.Parameters;
        }

As of now, I can manipulate my IParameterSymbol objects from the property Parameters (symbol.Parameters). What I don't get is the following : I've gone through my result IEnumerable containing both my parameters, but because of the method signature, it expects to receive an object and a MyCustomObject instances. I'm not in a position (at the moment) to be certain that the first parameter is indeed an object and not a string (merely an example, could have been anything else) and that when I'm expecting a child of MyCustomObject, if I give it a null, I want to know it's a null parameter.

I'll be grateful to anyone who can un-stuck me from this sticky situation !

UPDATES

Here's what kind of information is given to me when I get into an ArgumentSyntax object :

ArgumentSyntax Argument exception
    ContainsAnnotations: false
    ContainsDiagnostics: false
    ContainsDirectives: false
    ContainsSkippedText: false
    Expression: IdentifierNameSyntax IdentifierName exception
    FullSpan: {[550..559)}
    HasLeadingTrivia: false
    HasStructuredTrivia: false
    HasTrailingTrivia: false
    IsMissing: false
    IsStructuredTrivia: false
    KindText: "Argument"
    Language: "C#"
    NameColon: null
    Parent (Microsoft.CodeAnalysis.SyntaxNode): ArgumentListSyntax ArgumentList (exception,exception)
    ParentTrivia: SyntaxTrivia None 
    RawKind: 8638
    RefOrOutKeyword: SyntaxToken None 
    Span: {[550..559)}
    SpanStart: 550
7
  • It's quite confusing, as you've got parameterList referring to an argument list, not a parameter list... Commented Mar 24, 2015 at 19:18
  • And I'm really not sure what you mean by "I've gone through my result IEnumerable containing both my parameters". It's hard to tell what you're trying to achieve. Are you trying to check that the compile-time type of the first argument is string? Commented Mar 24, 2015 at 19:19
  • 1
    Then it sounds like you do want the argument list, not the parameter list. After all, the argument list says what's actually going to be passed - the parameter list will be the same each time... Commented Mar 24, 2015 at 19:27
  • 1
    Take this as a genuine question (since I don't really know how a c# compiler works), but how can one be sure that the passed object is a string at compile time? Commented Mar 25, 2015 at 7:21
  • 2
    @Jcl: The compiler knows the compile-time type of every expression, and the Roslyn semantic model will happily give it to you. (at runtime, it may be a subtype of the compile-time type) Commented Mar 25, 2015 at 14:52

1 Answer 1

5

What you should be doing is getting the arguments (not parameters -- they are different things!) and calling SemanticModel.GetTypeInfo() on the ArgumentSyntax. That'll give you the type of the expression being passed. From there you can do whatever checks you need.

Sign up to request clarification or add additional context in comments.

3 Comments

I've tried your solution. I find that it only works when a type was explicitly declared/initialize. When using implicit variable types, the result of TypeInfo then becomes null. Don't get me wrong, I'm glad because it help me for some situation, but the solution is not perfect for every scenarios.
Im sorry Jason, i think I made a typo or something but my analyzer does work now. Thanks for the help! @JasonMalinowski
Works great, though calling GetTypeInfo() on the ArgumentSyntax gave me null in my case, but when I called GetTypeInfo(argument.Expression) with the ExpressionSyntax I got the correct result.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.