我正在编写一个需要生成AST的解决方案,然后应该解析这个AST,以便生成一个有语义的有效编译单元。
SyntaxFactory
类生成的。Compilation
。SemanticModel
的引用。我为生成AST而运行的代码类似于:
var classNode = SyntaxFactory.ClassDeclaration("MyCLass");
classNode = classNode.AddMembers(
SyntaxFactory.MethodDeclaration(SyntaxFactory.ParseTypeName("string"), "DoIt")
.WithBody(...));
...
第一部分是正常的,你可以看到。我可以得到我的AST。但现在我需要将其转换为代码? 如何在AST上调用编译器?:
Compiler Compilation.GetSemanticModel(AST)
| |
+-----+ v +-----------------+ v +---------------+
+----> AST +-----> CompilationUnit +-----> SemanticModel |
^ +-----+ +-----------------+ +---------------+
| ^ ^
| |-----------------|
Factories ???
请注意,相对于获取SemanticModel
的部分,我需要使用Compilation
对象并通过传递GetSemanticModel
来调用CSharpSyntaxTree
。 / p>
如果你想知道为什么会这样,那是因为我正在写一个测试工具。无论使用什么,这种情况应该是可能的。怎么样?
答案 0 :(得分:0)
要在Roslyn中创建Compilation
,您需要一个有效的语法树,以获得一个有效的语法树,您只需解析文本:
var tree = CSharpSyntaxTree.ParseText(@"using System;
namespace HelloWorld
{
public class MyType{public void MyMethod(){} public void MySecondMethod(){}}
}"));
或者你可以像你写的那样使用SyntaxFactory
(或SyntaxGenerator
)。 (只需添加usings
和namespace
除非您撰写CSharpScript
,但必须添加SyntaxTree
,您还可以查看RoslynQuoter以获得有效的SyntaxTree
)
如果您拥有有效的Compilation
,则可以将其写为SemanticModel
和 var options = new CSharpCompilationOptions(kind);
var root = (CompilationUnitSyntax)tree.GetRoot();
var compilation = CSharpCompilation.Create("HelloWorld", options: options).
AddReferences(MetadataReference.CreateFromFile(typeof(object).Assembly.Location)).
AddSyntaxTrees(tree);
var model = compilation.GetSemanticModel(tree);
public Boolean isFooHere(final Foo foo) {
Criteria criteria = createCriteria();
criteria.add(Restrictions.eq("foo.id", foo.getId()));
if(criteria.uniqueResult() != null)
return true;
return false;
}