Get case label constant in Roslyn

I am trying to collect switch section label constants from SwitchStatement

with Roslyn. But although in the syntax renderer I can see that it CaseSwitchLabelSyntax

has a property Value

with a matching constant and the declared symbol ( SourceLabelSymbol

) has a property SwitchCaseLabelConstant

, I cannot get that information from what I am in my code.

// SwitchStatementSyntax node;
// SemanticModel model;

foreach (var section in node.Sections) {
  foreach (var label in section.Labels) {
    var labelSymbol = model.GetDeclaredSymbol(label);
    // Here I'm stuck
  }
}

      

I could probably see if SwitchLabelSyntax

CaseSwitchLabelSyntax

or DefaultSwitchLabelSyntax

and execute appropriately. SourceLabelSymbol

is actually internal, so I cannot access its properties. model.GetConstantValue(label)

returns null

.

But given that Roslyn is always handing out interfaces, I find the reason for this and the wildly casting seems a little hacky to me. Is there a better option?

Note. I am doing this to translate C # syntax to another language. Technically, first into a separate AST, which is then converted back to text. The above is the code from within CSharpSyntaxWalker

, and I could just keep my partially transformed statement switch

, continue visiting its descendants, and create it piecewise.

But that means more state, creating statements in half a dozen different locations, resulting in hard to read and non-sequential code. I would rather avoid this here if possible.

+3


source to share


1 answer


The closest API is a semanticModel.GetConstantValue

method, but you still need to pass the node value like this:

section.Labels
       .OfType<CaseSwitchLabelSyntax>()
       .Select(l => semanticModel.GetConstantValue(l.Value))
       .ToArray()

      



As you can see, filtering is required anyway CaseSwitchLabelSyntax

.

+3


source







All Articles