private static void BuildDirectiveTriviaMaps(CompilationUnitSyntax compilationUnit, out TreeTextSpan conditionalRoot, out TreeTextSpan regionRoot, out TreeTextSpan pragmaWarningRoot) { var conditionalStack = new Stack <TreeTextSpan.Builder>(); var regionStack = new Stack <TreeTextSpan.Builder>(); var pragmaWarningList = new List <DirectiveTriviaSyntax>(); var conditionalBuilder = SetupBuilder(compilationUnit, conditionalStack); var regionBuilder = SetupBuilder(compilationUnit, regionStack); for (var directiveTrivia = compilationUnit.GetFirstDirective(); directiveTrivia != null; directiveTrivia = directiveTrivia.GetNextDirective()) { switch (directiveTrivia.Kind()) { case SyntaxKind.IfDirectiveTrivia: AddNewDirectiveTriviaSpan(conditionalBuilder, conditionalStack, directiveTrivia); break; case SyntaxKind.ElifDirectiveTrivia: case SyntaxKind.ElseDirectiveTrivia: var previousSpan = conditionalStack.Pop(); previousSpan.SetEnd(directiveTrivia.FullSpan.Start); AddNewDirectiveTriviaSpan(conditionalBuilder, conditionalStack, directiveTrivia); break; case SyntaxKind.EndIfDirectiveTrivia: CloseDirectiveTriviaSpan(conditionalBuilder, conditionalStack, directiveTrivia); break; case SyntaxKind.RegionDirectiveTrivia: AddNewDirectiveTriviaSpan(regionBuilder, regionStack, directiveTrivia); break; case SyntaxKind.EndRegionDirectiveTrivia: CloseDirectiveTriviaSpan(regionBuilder, regionStack, directiveTrivia); break; case SyntaxKind.PragmaWarningDirectiveTrivia: pragmaWarningList.Add(directiveTrivia); break; default: // ignore all other directive trivia break; } } conditionalRoot = FinalizeBuilder(conditionalBuilder, conditionalStack, compilationUnit.Span.End); regionRoot = FinalizeBuilder(regionBuilder, regionStack, compilationUnit.Span.End); pragmaWarningRoot = BuildPragmaWarningSpans(pragmaWarningList, compilationUnit); }
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); }