How to access project code meta data?

后端 未结 1 1391
花落未央
花落未央 2021-01-28 23:08

In my VSPackage I need to replace reference to a property in code with its actual value. For example

public static void Main(string[] args) {
    Console.WriteLi         


        
相关标签:
1条回答
  • 2021-01-28 23:22

    There is no straight forward way to do this that I know of. Reliably getting an AST out of Visual Studio (and changes to it) has always been a big problem. Part of the goal of the Rosalyn project is to create an unified way of doing this, because many tool windows had their own way of doing this sort of stuff.

    There are four ways to do this:

    1. Symbols
    2. FileCodeModel + CodeDOM
    3. Rosalyn AST
    4. Unexplored Method

    Symbols

    I believe most tool windows such as the CodeView and things like Code Element Search use the symbols created from a compiled build. This is not ideal as it is a little more heavy weight and hard to keep in sync. You'd have to cache symbols to make this not slow. Using reflector, you can see how CodeView implements this.

    This approach uses private assemblies. The code for getting the symbols would look something like this:

    var compilerHost = new IDECompilerHost();
    
    var typeEnumerator = (from compiler in compilerHost.Compilers.Cast<IDECompiler>()
                                              from type in compiler.GetCompilation().MainAssembly.Types
                                              select new Tuple<IDECompiler, CSharpType>(compiler, type));
    
    foreach (var typeTuple in typeEnumerator)
    {
        Trace.WriteLine(typeTuple.Item2.Name);
        var csType = typeTuple.Item2;
        foreach (var loc in csType.SourceLocations)
        {
           var file = loc.FileName.Value;
           var line = loc.Position.Line;
           var charPos = loc.Position.Character;
        }
    }
    

    FileCodeModel + CodeDOM

    You could try using the EnvDTE service to get the FileCodeModel associated with a Code Document. This will let you get classes and methods. But it does not support getting the method body. You're messing with buggy COM. This ugly because an COM object reference to a CodeFunction or CodeClass can get invalided without you knowing it, meaning you'd have to keep your own mirror.

    Rosalyn AST

    This allows provides the same capabilities as both FileCodeModel and Symbols. I've been playing with this and it's actually not too bad.

    Unexplored Method

    You could try getting the underlying LanguageServiceProvider that is associated with the Code Document. But this is really difficult to pull off, and leaves you with many issues.

    0 讨论(0)
提交回复
热议问题