我正在尝试从GotoStatementSyntax获取Symbol的标签,下面的代码适用于带标签的语句,但不适用于案例标签:
public override void VisitGotoStatement(GotoStatementSyntax node)
{
var symbol = Model.GetSymbolInfo(node.Expression).Symbol;
}
我发现2012年不支持here。它仍然是这种情况还是有办法从goto case语句中获取符号?
答案 0 :(得分:1)
实际上有两种获取标签声明的方法。
您可以使用SemanticModel.LookupLabels
方法获取相关的标签符号。找出正确的名称参数有点棘手:
var name = node.CaseOrDefaultKeyword.ValueText != null
? string.Join(" ", new[] { node.CaseOrDefaultKeyword.Text, node.Expression?.ToString() }.Where(x => x != null)) + ":"
: node.Expression.ToString();
var label = Model.LookupLabels(node.SpanStart, name).OfType<ILabelSymbol>().SingleOrDefault();
GotoStatementSyntax
解析为IBranchStatement
操作,其中包含对目标标签符号的引用:
var label = ((IBranchStatement)Model.GetOperation(node)).Target;
两个代码段都为您提供相同的ILabelSymbol
。
这是我用来重复问题的LinqPad脚本:
async Task Test()
{
var ws = new AdhocWorkspace();
var proj = ws.AddProject("test", "C#");
var tree = SyntaxFactory.ParseSyntaxTree(@"
public class Program
{
public static void Main()
{
var i = System.Environment.GetCommandLineArgs().Length;
switch (i)
{
case 1: goto case 2;
case 2: goto default;
case 3: goto wat;
default: break;
}
wat:
return;
}
}");
var root = tree.GetRoot();
var doc = proj.AddDocument("file1.cs", root);
proj = doc.Project.AddMetadataReference(MetadataReference.CreateFromFile(typeof(object).Assembly.Location));
var compilation = await proj.GetCompilationAsync();
var model = compilation.GetSemanticModel(tree);
var walker = new Walker { Model = model };
walker.Visit(root);
}
class Walker : CSharpSyntaxWalker
{
public SemanticModel Model { get; set; }
public override void VisitGotoStatement(GotoStatementSyntax node)
{
var name = node.CaseOrDefaultKeyword.ValueText != null
? string.Join(" ", new[] { node.CaseOrDefaultKeyword.Text, node.Expression?.ToString() }.Where(x => x != null)) + ":"
: node.Expression.ToString();
var label = Model.LookupLabels(node.SpanStart, name).OfType<ILabelSymbol>().SingleOrDefault();
var label2 = ((IBranchStatement)Model.GetOperation(node)).Target;
// (label == label2).Dump();
base.VisitGotoStatement(node);
}
}