Răspuns Get more info about target symbol

  • 2 martie 2012 23:52
     
      Are cod

    Idea of code issue plugin is to analyze only poperties of classes that are decorated with precise attribute which is known to code issue plugin.

    Properties that are decorated with specific attribute needs to be virtual because those are used by interception engine to mock around during runtime. Other classes does not need to be inspected.

    Currently I ended up with the code as following:

    var localDeclaration = (PropertyDeclarationSyntax)node;
    var semanticModel = document.GetSemanticModel();
    var classDeclaration = localDeclaration.Parent as ClassDeclarationSyntax;

    then I'm trying to investigate whether class is decorated with particular attribute:

    var classSymbol = semanticModel.GetDeclaredSymbol(classDeclaration);
    var isDecoratedWithAtribute = HasTypeAttribute(classSymbol, typeof(MyAttribute));

    With HasTypeAttribute() method I ended-up in the following way:

    foreach (var attributeData in symbol.GetAttributes())
    {
        var attributeClassName = attributeData.AttributeClass.ToString();
        var t = TryGetType(attributeClassName, attributeData);
        if (t == null)
        {
            continue;
        }
    
        if (t.IsAssignableFrom(targetType))
        {
            result = true;
        }
    }
    

    So TryGetType() just tries to load the type from the assembly and looks if that is of atribute type code issue is looking for:

    assembly = Assembly.Load(attributeData.AttributeClass.ContainingAssembly.AssemblyName);

    This all workd great if class is directly decorated with that atribute - therefore code issue plugin can load the type. Problem may come up when class is decorated indirectly (with child attribute class, etc).

    So question is - is there some mechanisms how plugin could retrieve more info about target type symbol, like retrieving CLR type (if it's avalable, I suppose that could be only if module is compiled), getting also information about inheritance hierarchy, etc.


    Valdis Iljuconoks (C# MVP) Latvian Microsoft .NET User Group

Toate mesajele

  • 3 martie 2012 01:56
    Proprietar
     
     

    Hi Valdis - You should be able to get information about inheritance hierarchy for any TypeSymbol by looking at the TypeSymbol.BaseType property. In fact all the information about the TypeSymbol that you may require from a compiler point of view should be available via the various methods and properties present on TypeSymbol - you shouldn't need to retrieve the CLR type (i.e. the System.Type).

    Using TypeSymbol, you should be able to answer questions like
    - what is the name of the type (TypeSymbol.Name for simple name / TypeSymbol.ToDisplayString() for fully qualified name etc.)
    - is this a generic type (TypeSymbol.IsGenericType)
    - what are the generic type arguments (TypeSymbol.TypeArguments)
    - what is the base type (TypeSymbol.BaseType)
    - what interfaces does this type implement (TypeSymbol.Interfaces)?
    - is this type convertible to this other type (Compilation.ClassifyConversion())?

    Are you finding that some information you need is not available via TypeSymbol?


    Shyam Namboodiripad | Software Development Engineer in Test | Roslyn Compilers Team

  • 2 aprilie 2012 13:54
     
     
    Hi, Seems like everything I do need to check type for decorated attribute is present within the TypeSymbol. But what I wanted to do is not to check types by name but types by its type (strongly typed).

    Valdis Iljuconoks (C# MVP)/Latvian Microsoft .NET User Group

  • 6 aprilie 2012 22:22
    Proprietar
     
     Răspuns

    Hi Valdis - Isn't that the same thing as checking that the TypeSymbols returned for two occurances of the same type are 'equal' OR checking the fully qualified name of the type using the TypeSymbol? TypeSymbols for specific types can be compared (so long as the symbols come from the same Compilation). You can use TypeSymbol.Equals() for this / implement your own notion of symbol equality. You may want to take a look at the following earlier threads around this topic - here and here.

    Currently, as far as I am aware there is no direct way to get the CLR type (System.Type) corresponding to a TypeSymbol in Roslyn. To do this, the compiler would itself need to reference the assemblies that contain the definition of the type. And if the type is defined in source, the compiler would probably need to emit it to metadata before it can return the corresponding System.Type...

    However, for types that come from metadata, you could construct an instance of System.Type from the TypeSymbol by passing the (assembly) qualified name of the type to System.Type.GetType(). I think qualified name (which is essentially a format recognized by reflection) can be constructed using the info present in TypeSymbol and AssemblySymbol (although I haven't tried this myself yet). This should be easy to do for simple types - but may require additional work for more complex types (for example, the qualified name for generic types would need to include "`1", "`2" etc. suffix to indicate the number of type parameters - so you would need to translate the type name info returned from a TypeSymbol to this format). We are considering exposing a TypeSymbol.MetadataName property that would probably help for this (i.e. this property would return the name in the format recognized by reflection).

    But this wouldn't work for symbols that come from source i.e. the type needs to be present in metadata before one can construct a System.Type for it...

    Hope this helps!


    Shyam Namboodiripad | Software Development Engineer in Test | Roslyn Compilers Team

  • 9 aprilie 2012 07:43
     
     
    Thanks for the answer!

    Valdis Iljuconoks (C# MVP)/Latvian Microsoft .NET User Group