2015-06-05 68 views
26

我有以下編譯:如何用新的語法樹部分更新編譯?

Solution solutionToAnalyze = workspace.OpenSolutionAsync(pathToSolution).Result; 
var projects = solutionToAnalyze.Projects; 
Compilation compilation = projects.First().GetCompilationAsync().Result; 
var syntaxTrees = compilation.SyntaxTrees.First(); 
var semanticModel = compilation.GetSemanticModel(syntaxTree, true); 
SyntaxNode newSource = semanticModel.SyntaxTree.GetRoot(); 
var methodRefactoringVisitor = new MethodRefactoringVisitor(); 

我已經修改的方法

public override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax method) 
{ 
    var newBody = method.Body; 
    //modify newBody 
    var updatedMethod = method.ReplaceNode(method.Body, newBody); 
    return updatedMethod; 
} 

newSource = methodRefactoringVisitor.Visit(newSource); 

的主體後,我所做的更改的方法,我想更新編輯使得例如我可以查詢一個節點的類型:

var typeInfo = semanticModel.GetTypeInfo(node).Type; 

目前我做的:

var oldSyntaxTree = semanticModel.SyntaxTree; 
var newSyntaxTree = newSource.SyntaxTree; 
var newCompilation = compilation.ReplaceSyntaxTree(oldSyntaxTree, newSyntaxTree); 
var newSemanticModel = newCompilation.GetSemanticModel(newSyntaxTree); 

我想修改正文後更新編譯權限,以便我可以看到更改,如果我從修改方法的父類調用訪問者。

是否可以部分更新編譯而不編譯整個項目/類?

更新

如果我理解正確的,我不認爲這是可能的。 在Roslyn github上的FAQ頁面上,它說:

我可以在編譯器管道中重寫源代碼嗎?

羅斯林不提供一個插件架構整個編譯器的管道,這樣在每一個階段,你可以影響句法分析,語義分析,優化算法,代碼排放,等等。[...]你可以使用Roslyn解析代碼並進行語義分析,然後重寫樹,更改引用等。然後將結果編譯爲新的編譯。

+0

'SyntaxTree.GetRoot()。SyntaxTree'與'SyntaxTree'相同 – SLaks

+1

我不清楚你想要做什麼。你可以擴展你的問題嗎? –

+0

@JeroenVannevel我已經擴展了這個問題。我希望現在更清楚。感謝您的建議。 –

回答

1

是否可以部分更新編譯而不編譯整個項目/類?

     沒有,SyntaxTree實現爲ImmutableArray。因此,您實際上正在創建一個新的SyntaxTree,而不是修改舊的SyntaxTree,並且同樣需要將新的SyntaxTree編譯爲新的編譯。
      0123你可以用新的覆蓋Compilation或SemanticModel對象,如果這使得代碼更容易推理,但是在每次你替換一個節點或者什麼時候你正在創建一個語法樹的新實例有你,所以你目前的做法似乎是適當的。
     沒什麼大不了的,我不會讓它打擾你太多。你是否只關心表現或最好的方法或...?