public static DirectiveSpan BuildConditionalDirectiveTree(CompilationUnitSyntax compilationUnit) { var root = new DirectiveSpan(0) { End = compilationUnit.Span.End }; var directiveStack = new Stack<DirectiveSpan>(); directiveStack.Push(root); for (var directiveTrivia = compilationUnit.GetFirstDirective(); directiveTrivia != null; directiveTrivia = directiveTrivia.GetNextDirective()) { DirectiveSpan previousDirectiveSpan; DirectiveSpan newDirectiveSpan; switch (directiveTrivia.Kind()) { case SyntaxKind.IfDirectiveTrivia: newDirectiveSpan = directiveStack.Peek().AddChild(directiveTrivia.SpanStart); directiveStack.Push(newDirectiveSpan); break; case SyntaxKind.ElifDirectiveTrivia: case SyntaxKind.ElseDirectiveTrivia: previousDirectiveSpan = directiveStack.Pop(); previousDirectiveSpan.End = directiveTrivia.SpanStart; newDirectiveSpan = directiveStack.Peek().AddChild(directiveTrivia.SpanStart); directiveStack.Push(newDirectiveSpan); break; case SyntaxKind.EndIfDirectiveTrivia: previousDirectiveSpan = directiveStack.Pop(); previousDirectiveSpan.End = directiveTrivia.SpanStart; break; default: // ignore all other directive trivia break; } } // cleanup the stack if for some reason the tree of directives has not reached closure. while (directiveStack.Count > 1) { var directiveSpan = directiveStack.Pop(); directiveSpan.End = compilationUnit.Span.End; } return root; }