使用 Roslyn,如何枚举 Visual Basic 文档中的成员(命名空间、类 等)详细信息?
Using Roslyn, how to enumerate members (Namespaces, classes etc) details in Visual Basic Document?
使用 Roslyn,确定 Visual Basic 文档成员的唯一机制似乎是:
var members = SyntaxTree.GetRoot().DescendantNodes().Where(node =>
node is ClassStatementSyntax ||
node is FunctionAggregationSyntax ||
node is IncompleteMemberSyntax ||
node is MethodBaseSyntax ||
node is ModuleStatementSyntax ||
node is NamespaceStatementSyntax ||
node is PropertyStatementSyntax ||
node is SubNewStatementSyntax
);
如何获取每个成员的成员name
、StarLineNumber
和EndLineNumber
?
不仅存在获得它的一种方法:
1)当你尝试时:我不会为所有善良的成员展示这种方式(他们数量庞大,逻辑相似),但只有其中一个,例如ClassStatementSyntax
:
- 要获得它的名字,只需
ClassStatementSyntax.Identifier.ValueText
- 要获取起始行,您可以使用
Location
作为其中一种方法:
var location = Location.Create(SyntaxTree, ClassStatementSyntax.Identifier.Span);
var startLine = location.GetLineSpan().StartLinePosition.Line;
- 检索结束行的逻辑看起来像接收开始行的逻辑,但它依赖于相应的结束语句(某种结束语句或自身)
2) 更有用的方法——使用SemanticModel
来获取你想要的数据:
通过这种方式,您将只需要接收 ClassStatementSyntax
、ModuleStatementSyntxt
和 NamespaceStatementSyntax
的语义信息,并且只需调用 GetMembers()
:[=23= 即可接收到它们的所有成员]
...
SemanticModel semanticModel = // usually it is received from the corresponding compilation
var typeSyntax = // ClassStatementSyntax, ModuleStatementSyntxt or NamespaceStatementSyntax
string name = null;
int startLine;
int endLine;
var info = semanticModel.GetSymbolInfo(typeSyntax);
if (info.Symbol is INamespaceOrTypeSymbol typeSymbol)
{
name = typeSymbol.Name; // retrieve Name
startLine = semanticModel.SyntaxTree.GetLineSpan(typeSymbol.DeclaringSyntaxReferences[0].Span).StartLinePosition.Line; //retrieve start line
endLine = semanticModel.SyntaxTree.GetLineSpan(typeSymbol.DeclaringSyntaxReferences[0].Span).EndLinePosition.Line; //retrieve end line
foreach (var item in typeSymbol.GetMembers())
{
// do the same logic for retrieving name and lines for all others members without calling GetMembers()
}
}
else if (semanticModel.GetDeclaredSymbol(typeSyntax) is INamespaceOrTypeSymbol typeSymbol2)
{
name = typeSymbol2.Name; // retrieve Name
startLine = semanticModel.SyntaxTree.GetLineSpan(typeSymbol2.DeclaringSyntaxReferences[0].Span).StartLinePosition.Line; //retrieve start line
endLine = semanticModel.SyntaxTree.GetLineSpan(typeSymbol2.DeclaringSyntaxReferences[0].Span).EndLinePosition.Line; //retrieve end line
foreach (var item in typeSymbol2.GetMembers())
{
// do the same logic for retrieving name and lines for all others members without calling GetMembers()
}
}
但是请注意,当您有部分声明时,您的 DeclaringSyntaxReferences
将有几个项目,因此您需要根据当前的 SyntaxTree
过滤 SyntaxReference
使用 Roslyn,确定 Visual Basic 文档成员的唯一机制似乎是:
var members = SyntaxTree.GetRoot().DescendantNodes().Where(node =>
node is ClassStatementSyntax ||
node is FunctionAggregationSyntax ||
node is IncompleteMemberSyntax ||
node is MethodBaseSyntax ||
node is ModuleStatementSyntax ||
node is NamespaceStatementSyntax ||
node is PropertyStatementSyntax ||
node is SubNewStatementSyntax
);
如何获取每个成员的成员name
、StarLineNumber
和EndLineNumber
?
不仅存在获得它的一种方法:
1)当你尝试时:我不会为所有善良的成员展示这种方式(他们数量庞大,逻辑相似),但只有其中一个,例如ClassStatementSyntax
:
- 要获得它的名字,只需
ClassStatementSyntax.Identifier.ValueText
- 要获取起始行,您可以使用
Location
作为其中一种方法:
var location = Location.Create(SyntaxTree, ClassStatementSyntax.Identifier.Span);
var startLine = location.GetLineSpan().StartLinePosition.Line;
- 检索结束行的逻辑看起来像接收开始行的逻辑,但它依赖于相应的结束语句(某种结束语句或自身)
2) 更有用的方法——使用SemanticModel
来获取你想要的数据:
通过这种方式,您将只需要接收 ClassStatementSyntax
、ModuleStatementSyntxt
和 NamespaceStatementSyntax
的语义信息,并且只需调用 GetMembers()
:[=23= 即可接收到它们的所有成员]
...
SemanticModel semanticModel = // usually it is received from the corresponding compilation
var typeSyntax = // ClassStatementSyntax, ModuleStatementSyntxt or NamespaceStatementSyntax
string name = null;
int startLine;
int endLine;
var info = semanticModel.GetSymbolInfo(typeSyntax);
if (info.Symbol is INamespaceOrTypeSymbol typeSymbol)
{
name = typeSymbol.Name; // retrieve Name
startLine = semanticModel.SyntaxTree.GetLineSpan(typeSymbol.DeclaringSyntaxReferences[0].Span).StartLinePosition.Line; //retrieve start line
endLine = semanticModel.SyntaxTree.GetLineSpan(typeSymbol.DeclaringSyntaxReferences[0].Span).EndLinePosition.Line; //retrieve end line
foreach (var item in typeSymbol.GetMembers())
{
// do the same logic for retrieving name and lines for all others members without calling GetMembers()
}
}
else if (semanticModel.GetDeclaredSymbol(typeSyntax) is INamespaceOrTypeSymbol typeSymbol2)
{
name = typeSymbol2.Name; // retrieve Name
startLine = semanticModel.SyntaxTree.GetLineSpan(typeSymbol2.DeclaringSyntaxReferences[0].Span).StartLinePosition.Line; //retrieve start line
endLine = semanticModel.SyntaxTree.GetLineSpan(typeSymbol2.DeclaringSyntaxReferences[0].Span).EndLinePosition.Line; //retrieve end line
foreach (var item in typeSymbol2.GetMembers())
{
// do the same logic for retrieving name and lines for all others members without calling GetMembers()
}
}
但是请注意,当您有部分声明时,您的 DeclaringSyntaxReferences
将有几个项目,因此您需要根据当前的 SyntaxTree
SyntaxReference