编译 CompilationUnitSyntax 的正确方法
Proper way to compile CompilationUnitSyntax
我有以下代码片段
var compilationUnit = SyntaxFactory.CompilationUnit()
.AddUsings(SyntaxFactory.UsingDirective(SyntaxFactory.ParseName("System")))
.AddMembers(
SyntaxFactory.NamespaceDeclaration(SyntaxFactory.IdentifierName("MyNamespace"))
.AddMembers(SyntaxFactory.ClassDeclaration("MyClass").AddMembers(
SyntaxFactory.MethodDeclaration(SyntaxFactory.ParseTypeName("void"), "Main")
.WithBody(SyntaxFactory.Block())))).NormalizeWhitespace();
但是,当我直接从编译单元使用 SyntaxTree 时,似乎无法使用 Roslyn 编译它 - 就像那样
CSharpCompilation compilation = CSharpCompilation.Create(
assemblyName: "MyAssembly",
syntaxTrees: new [] { compilationUnit.SyntaxTree },
references: references,
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
);
我找不到比使用
重新创建 SyntaxTree 更好的方法了
CSharpSyntaxTree.ParseText(compilationUnit.ToFullString())
并将其传递给 CSharpCompilation.Create 方法。有没有更好的编译 CompilationUnitSyntax 的方法?
您正在寻找 CSharpSyntaxTree.Create(compilationUnit)
从语法树创建编译的方式没有任何问题。问题在于您创建语法树的方式,特别是 void
关键字(如错误所示)。
如果你写这段代码:
SyntaxFactory.ParseTypeName("void").GetDiagnostics()
那么已经报错了
您可以手动为 void
类型创建一个 TypeName
对象,而不是 ParseTypeName
:
SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.VoidKeyword))
适合我的完整代码(从您的代码中简化以删除不必要的语法节点):
var compilationUnit = SyntaxFactory.CompilationUnit()
.AddMembers(SyntaxFactory.ClassDeclaration("MyClass").AddMembers(
SyntaxFactory.MethodDeclaration(
SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.VoidKeyword)),
"Main")
.WithBody(SyntaxFactory.Block())))
.NormalizeWhitespace();
CSharpCompilation compilation = CSharpCompilation.Create(
assemblyName: "MyAssembly",
syntaxTrees: new[] { compilationUnit.SyntaxTree },
references: references,
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
);
我有以下代码片段
var compilationUnit = SyntaxFactory.CompilationUnit()
.AddUsings(SyntaxFactory.UsingDirective(SyntaxFactory.ParseName("System")))
.AddMembers(
SyntaxFactory.NamespaceDeclaration(SyntaxFactory.IdentifierName("MyNamespace"))
.AddMembers(SyntaxFactory.ClassDeclaration("MyClass").AddMembers(
SyntaxFactory.MethodDeclaration(SyntaxFactory.ParseTypeName("void"), "Main")
.WithBody(SyntaxFactory.Block())))).NormalizeWhitespace();
但是,当我直接从编译单元使用 SyntaxTree 时,似乎无法使用 Roslyn 编译它 - 就像那样
CSharpCompilation compilation = CSharpCompilation.Create(
assemblyName: "MyAssembly",
syntaxTrees: new [] { compilationUnit.SyntaxTree },
references: references,
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
);
我找不到比使用
重新创建 SyntaxTree 更好的方法了CSharpSyntaxTree.ParseText(compilationUnit.ToFullString())
并将其传递给 CSharpCompilation.Create 方法。有没有更好的编译 CompilationUnitSyntax 的方法?
您正在寻找 CSharpSyntaxTree.Create(compilationUnit)
从语法树创建编译的方式没有任何问题。问题在于您创建语法树的方式,特别是 void
关键字(如错误所示)。
如果你写这段代码:
SyntaxFactory.ParseTypeName("void").GetDiagnostics()
那么已经报错了
您可以手动为 void
类型创建一个 TypeName
对象,而不是 ParseTypeName
:
SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.VoidKeyword))
适合我的完整代码(从您的代码中简化以删除不必要的语法节点):
var compilationUnit = SyntaxFactory.CompilationUnit()
.AddMembers(SyntaxFactory.ClassDeclaration("MyClass").AddMembers(
SyntaxFactory.MethodDeclaration(
SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.VoidKeyword)),
"Main")
.WithBody(SyntaxFactory.Block())))
.NormalizeWhitespace();
CSharpCompilation compilation = CSharpCompilation.Create(
assemblyName: "MyAssembly",
syntaxTrees: new[] { compilationUnit.SyntaxTree },
references: references,
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
);