How do I parse C# conditional compilation statement using Roslyn.
In the following code, I want Roslyn to give the Conditional compilation statement node.
public abstract class TestClass
{
public int Get()
{
#if DEBUG
return 1;
#else
return 2;
#endif
}
}
I don't get conditional compilation node in SyntaxTree and neither it is part of LeadingTrivia of }
or TrailingTrivia of {
What I get in LeadingTrivia of }
is "\t\t#endif\r\n\t\t"
and TrailingTrivia of {
is "\r\n"
which is not complete conditional compilation statement.
Can someone point me to the right direction?
If you parse the nodes via visitor (CSharpSyntaxRewriter\Walker) you need to override:
public override SyntaxNode VisitIfDirectiveTrivia(IfDirectiveTriviaSyntax node)
{
}
public override SyntaxNode VisitElseDirectiveTrivia(ElseDirectiveTriviaSyntax node)
{
}
public override SyntaxNode VisitEndIfDirectiveTrivia(EndIfDirectiveTriviaSyntax node)
{
}
If you want to get this not via visitors, you can do this:
node.DescendantNodesAndSelf().OfType<ConditionalDirectiveTriviaSyntax>();
You can take a look here to see what Roslyn generating for your conditional.
Update
I checked it, and indeed its kind of complicated here, because its not Node
of course. The node is just return 2
or if you write #define DEBUG
its return 1
.
So, in case you have that conditional directive inside method you can do something like this:
// First get the relevant method (or any other parent block depending in the case)
var method = root.DescendantNodes().OfType<MethodDeclarationSyntax>().First();
// Then, you can write method similar to this
static SyntaxTrivia GetConditionalDirectiveTrivia(SyntaxNode node, SyntaxKind kind)
{
foreach (SyntaxNode syntaxNode in node.DescendantNodes())
{
var trivia = syntaxNode.GetLeadingTrivia().FirstOrDefault(t => t.Kind() == kind);
if (trivia != default(SyntaxTrivia))
return trivia;
GetConditionalDirectiveTrivia(syntaxNode, kind);
}
return default(SyntaxTrivia);
}
And call it like this:
GetConditionalDirectiveTrivia(method, SyntaxKind.IfDirectiveTrivia);
You can find it in more ways without the Kind but I think its good enough.
Note, that its just an example. I return here only the first trivia.
In your real code, you can write more elegant solution (maybe even an extension method) to get for example AllTriviaOfKind
or something else that fit your requirements.
Also, you can return the token trivia or the parent node, if the trivia itself is useless for you, whatever you want\need.
I hope its help.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With