I am writing a solution which requires an AST to be generated and then this AST should be parsed in order to generate a valid compilation unit with semantics available.
SyntaxFactory
class.Compilation
somehow.SemanticModel
from the compilation unit.The code I run for generating the AST is something like:
var classNode = SyntaxFactory.ClassDeclaration("MyCLass");
classNode = classNode.AddMembers(
SyntaxFactory.MethodDeclaration(SyntaxFactory.ParseTypeName("string"), "DoIt")
.WithBody(...));
...
The first part is ok as you can see. I can get my AST. But now I need to convert it into code? How to invoke the compiler on the AST?:
Compiler Compilation.GetSemanticModel(AST)
| |
+-----+ v +-----------------+ v +---------------+
+----> AST +-----> CompilationUnit +-----> SemanticModel |
^ +-----+ +-----------------+ +---------------+
| ^ ^
| |-----------------|
Factories ???
Note that the part relative to getting the SemanticModel
is covered as I simly need to use the Compilation
object and call GetSemanticModel
on that by passing the CSharpSyntaxTree
.
If you are wondering why this, it is because of a testing tool I am writing. Regardless of the use, this scenario should be possible. How?
To create Compilation
in Roslyn, you need a valid syntax tree, to get a valid syntax tree you can just parse text like:
var tree = CSharpSyntaxTree.ParseText(@"using System;
namespace HelloWorld
{
public class MyType{public void MyMethod(){} public void MySecondMethod(){}}
}"));
Or you can use SyntaxFactory
(or SyntaxGenerator
) like you wrote. (just add usings
and namespace
unless you writing a CSharpScript
, its required, You can also check RoslynQuoter to get a valid SyntaxTree
)
When you have a valid SyntaxTree
you can write this to get a Compilation
and 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);