首页 文章

Roslyn:如何将多个项目的编译合并为一个单一的编译?

提问于
浏览
0

是否可以将每个项目的所有编译合并为1个编译?我目前正在研究静态代码分析器,因此,当例如一个方法调用来自同一解决方案中的另一个项目的另一个方法时,当我尝试使用 compilation.GetSemanticModel(SyntaxTree) 获取语义模型时,将会出现错误,如传递进入当前项目 Compilation 的另一个项目类的 SyntaxTree 将破坏我的代码 .

编辑:我想到获取每个项目的引用和syntaxtrees并将它们组合起来,然后根据它创建一个编译 .

List<MetadataReference> refs = new List<MetadataReference>();
        List<SyntaxTree> syntaxtrees = new List<SyntaxTree>();
        foreach (var project in projectToAnalyze)
        {
            Compilation compilation = project.GetCompilationAsync().Result;

            var references = compilation.References;
            refs.AddRange(references);
            var trees = compilation.SyntaxTrees;
            syntaxtrees.AddRange(trees);
            //analysis(project, config, compilation);
        }


        var mycompilation = CSharpCompilation.Create("test").AddReferences(refs).AddSyntaxTrees(syntaxtrees);

但是,尽管我没有因此而出错,但某些操作现在似乎无法正常工作 . 例如,当我现在使用 SymbolFinder.FindImplementationsAsync 时,它不再返回我的实现 .

Edit2:例如MyAnalyzer:

class MyAnalyzer {

    private Compilation compilation;
    private SemanticModel model;
    private SyntaxTree tree;

    public MyAnalyzer(SyntaxTree tree, Compilation compilation) {
        this.compilation = compilation;
        this.tree = tree;
        this.model = compilation.GetSemanticModel(tree);

    //Various override Visit functions for analysis
    public override void VisitInvocationExpression(node) {
         //
         //lets say i just pass the syntaxtree belonging to ClassB
         //into a new instance of MyAnalyzer
         MyAnalyzer newAnalysis = new MyAnalyzer(classB's syntaxtree, this.compilation)
    }
}

要分析的代码:

class A {

ClassB B = new ClassB();
B.method();
}

我通过传递树和编译从我 Main.cs 运行我的分析,如果假设 ClassB 同一个解决方案中来自另一个项目,那么如果当我尝试创建 VisitInvocationExpression 分析的新实例会出现一个错误 compilation.GetSemanticModel(tree) 不会我在这里工作,因为我将当前实例编译 this.compilation 传递给新实例,并且由于 ClassBSyntaxTree 来自另一个项目 . 因此,我想出了将编译组合成单个编译的想法 .

1 回答

  • 0

    我有我的问题的解决方案是,代替汇编合并成1名单编辑,我做了一个try-catch块周围的声明 compilation.GetSemanticModel(tree) ,如果我传递给类编译不包含 tree ,该 catch 块将环通过 IEnumerable<Project> 的全局变量,我存储 Solution 的项目,我正在分析并循环每个项目的编译,以查找包含树的编译 .

相关问题