2014-12-03 1 views
3

Я пытаюсь собрать константы метки секции переключателя от SwitchStatement с Roslyn. Но пока я вижу в синтаксисе Visualizer, что CaseSwitchLabelSyntax имеет свойство Value с соответствующей константой, а объявленный символ (SourceLabelSymbol) имеет свойство SwitchCaseLabelConstant, я не могу получить эту информацию из того, что у меня есть в своем коде.Получите идентификатор метки корпуса в Roslyn

// 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 
    } 
} 

Я мог бы, вероятно, искать ли SwitchLabelSyntax является CaseSwitchLabelSyntax или DefaultSwitchLabelSyntax и брось соответственно. SourceLabelSymbol фактически является внутренним, поэтому я не могу получить доступ к его свойствам. model.GetConstantValue(label)null.

Но, учитывая, что Рослин всегда передает интерфейсы, я верю, что есть причина для этого, и дико кастинг вокруг меня немного взломал. Есть ли лучший вариант?

Примечание: Я делаю это для перевода синтаксиса C# на другой язык. Технически, сначала в отдельный АСТ, который затем снова преобразуется в текст. Выше код находится в пределах CSharpSyntaxWalker, и я мог бы, вероятно, просто сохранить мое частично преобразованное заявление switch, продолжить посещение его потомков и создать его кусочно.

Но это означает, что у вас больше состояний, выражений здания в полдюжины различных местоположений, что приводит к трудно читаемому и -следующему коду. Я бы предпочел избежать этого здесь, если это возможно.

ответ

3

Ближайший из API является semanticModel.GetConstantValue метод, но все же вам нужно передать узел Value к нему, как это:

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

Как вы можете видеть, отфильтровывая CaseSwitchLabelSyntax требуется в любом случае.