在 Roslyn 中从类型 string/ITypeSymbol 创建语法树
Creating a syntax tree from a type string/ITypeSymbol in Roslyn
Roslyn 是否提供了为任意有效类型字符串或 ITypeSymbol 生成语法树的方法?
例如System.Threading.Task
解析为
的树
QualifiedName(
QualifiedName(
IdentifierName("System"),
IdentifierName("Threading")),
IdentifierName("Task"))
而 System.Threading.Task<int>
解析为
的树
QualifiedName(
QualifiedName(
IdentifierName("System"),
IdentifierName("Threading")),
GenericName(
Identifier("Task"))
.WithTypeArgumentList(
TypeArgumentList(
SingletonSeparatedList<TypeSyntax>(
PredefinedType(
Token(SyntaxKind.IntKeyword))))))
最后System.Threading.Task<,>
解析为
的树
QualifiedName(
QualifiedName(
IdentifierName("System"),
IdentifierName("Threading")),
GenericName(
Identifier("Task"))
.WithTypeArgumentList(
TypeArgumentList(
SeparatedList<TypeSyntax>(
new SyntaxNodeOrToken[]{
OmittedTypeArgument(),
Token(SyntaxKind.CommaToken),
OmittedTypeArgument()}))))
虽然我正在为此用例编写轻量级词法分析器,但我想知道 Roslyn 是否已经提供了它。
更新 #1:
基于 Tamas 描述的方法最小化解析的最终变体:
public static async Task<TypeSyntax> CreateTypeSyntax(string typeName)
{
var options = new CSharpParseOptions(kind: SourceCodeKind.Script);
var parsedTree = CSharpSyntaxTree.ParseText($"typeof({typeName})", options);
var treeRoot = await parsedTree.GetRootAsync();
var typeNameNode = treeRoot.DescendantNodes().OfType<TypeSyntax>().FirstOrDefault();
return typeNameNode;
}
您可以使用 CSharpSyntaxTree.ParseText
从任何输入生成树。如果你给它一个你可以控制的输入,那么你就可以找到你感兴趣的子树。例如,现在你想要一个类型的语法。您可以将输入放在一起:
@"class MyClass
{
TYPE_THAT_INTERESTS_ME field;
}"
然后获取它的树,导航到该字段,并从其 VariableDeclarationSyntax
中获取 TypeSyntax
。
Roslyn 是否提供了为任意有效类型字符串或 ITypeSymbol 生成语法树的方法?
例如System.Threading.Task
解析为
QualifiedName(
QualifiedName(
IdentifierName("System"),
IdentifierName("Threading")),
IdentifierName("Task"))
而 System.Threading.Task<int>
解析为
QualifiedName(
QualifiedName(
IdentifierName("System"),
IdentifierName("Threading")),
GenericName(
Identifier("Task"))
.WithTypeArgumentList(
TypeArgumentList(
SingletonSeparatedList<TypeSyntax>(
PredefinedType(
Token(SyntaxKind.IntKeyword))))))
最后System.Threading.Task<,>
解析为
QualifiedName(
QualifiedName(
IdentifierName("System"),
IdentifierName("Threading")),
GenericName(
Identifier("Task"))
.WithTypeArgumentList(
TypeArgumentList(
SeparatedList<TypeSyntax>(
new SyntaxNodeOrToken[]{
OmittedTypeArgument(),
Token(SyntaxKind.CommaToken),
OmittedTypeArgument()}))))
虽然我正在为此用例编写轻量级词法分析器,但我想知道 Roslyn 是否已经提供了它。
更新 #1: 基于 Tamas 描述的方法最小化解析的最终变体:
public static async Task<TypeSyntax> CreateTypeSyntax(string typeName)
{
var options = new CSharpParseOptions(kind: SourceCodeKind.Script);
var parsedTree = CSharpSyntaxTree.ParseText($"typeof({typeName})", options);
var treeRoot = await parsedTree.GetRootAsync();
var typeNameNode = treeRoot.DescendantNodes().OfType<TypeSyntax>().FirstOrDefault();
return typeNameNode;
}
您可以使用 CSharpSyntaxTree.ParseText
从任何输入生成树。如果你给它一个你可以控制的输入,那么你就可以找到你感兴趣的子树。例如,现在你想要一个类型的语法。您可以将输入放在一起:
@"class MyClass
{
TYPE_THAT_INTERESTS_ME field;
}"
然后获取它的树,导航到该字段,并从其 VariableDeclarationSyntax
中获取 TypeSyntax
。