0

What I'd like to achieve

I'd like to write a code analyzer that picks up on any ObjectCreationExpression such as:

FruitMix fm = new FruitMix();

and allow me to find out what interfaces that type implements, performing an action if a particular interface is found.

What I've tried

I've intercepted the analysis through registering the SyntaxNodeAction via:

public override void Initialize(AnalysisContext context)
{
    context.RegisterSyntaxNodeAction(c=> AnalyzeObjectCreation(c), SyntaxKind.ObjectCreationExpression);         
}

in order to get the interfaces ITypeSymbol seems to be the way to go which I'm attempting to obtain in the registered method:

private static void AnalyzeObjectCreation(SyntaxNodeAnalysisContext context)
{
    ObjectCreationExpressionSyntax objectCreation = (ObjectCreationExpressionSyntax) context.Node;

    //How do I get an INamedTypeSymbol here?

    //INamedTypeSymbol typeSyntax = (INamedTypeSymbol)objectCreation.Type;
    //ISymbol test = typeSyntax.AssociatedSymbol;    
    //ISymbol test = context.SemanticModel.GetDeclaredSymbol(context.Node);
    //SymbolInfo symbolInfo = context.SemanticModel.GetDeclaredSymbol()
}

As you can see I've tried everything I can find online to no avail. Perhaps I shouldn't be looking for an INamedTypeSymbol at all - if so what do I need?

Could you point me in the right direction?

svick
  • 236,525
  • 50
  • 385
  • 514
m.edmondson
  • 30,382
  • 27
  • 123
  • 206

1 Answers1

4

You'll want to use the SemanticModel.GetSymbolInfo() on the ObjectCreationSyntax.

(In your example you can use the SemanticModel on context, this is just a self-contained sample)

var tree = CSharpSyntaxTree.ParseText(@"
using System;
public class MyClass
{
    public MyClass()
    {
    }
}
public class Program
{
    public static void Main()
    {
        var x = new MyClass();  
    }   
}");

var mscorlib = MetadataReference.CreateFromFile(typeof(object).Assembly.Location);
var compilation = CSharpCompilation.Create("MyCompilation",
    syntaxTrees: new[] { tree }, references: new[] { mscorlib });

var model = compilation.GetSemanticModel(tree);
var objectCreationSyntax = tree.GetRoot().DescendantNodes().OfType<ObjectCreationExpressionSyntax>().Single();

var namedTypeSymbol = model.GetSymbolInfo(objectCreationSyntax).Symbol;

It looks like you were playing around with GetDeclaredSymbol() which was probably returning null. The rule I like to use is:

  • Use GetDeclaredSymbol() for any syntax with the name DeclarationSyntax in its name
  • Use GetSymbolInfo() for all other syntax.
JoshVarty
  • 9,066
  • 4
  • 52
  • 80
  • Thanks - GetSymbolInfo has returned what I need. My problem now is when registering the location I can't get hold of the location where the object is being created (not where the class is defined). Do you have any ideas? – m.edmondson Mar 17 '16 at 23:16
  • That will be on your original `ObjectDeclarationSyntax`. You can use `.GetLocation()` on it. – JoshVarty Mar 18 '16 at 17:51
  • Thanks `.GetLocation()' gave what I want – m.edmondson Mar 21 '16 at 09:47