private static bool ContainsInterleavedDirective( TextSpan textSpan, SyntaxTrivia trivia, ref SimpleIntervalTree <TextSpan> ifEndIfSpans, CancellationToken cancellationToken) { if (trivia.HasStructure) { var parentSpan = trivia.GetStructure().Span; if (trivia.GetStructure().IsKind(SyntaxKind.RegionDirectiveTrivia) || trivia.GetStructure().IsKind(SyntaxKind.EndRegionDirectiveTrivia) || trivia.GetStructure().IsKind(SyntaxKind.IfDirectiveTrivia) || trivia.GetStructure().IsKind(SyntaxKind.EndIfDirectiveTrivia)) { var match = ((DirectiveTriviaSyntax)trivia.GetStructure()).GetMatchingDirective(cancellationToken); if (match != null) { var matchSpan = match.Span; if (!textSpan.Contains(matchSpan.Start)) { // The match for this pp directive is outside // this node. return(true); } if (trivia.GetStructure().IsKind(SyntaxKind.IfDirectiveTrivia) || trivia.GetStructure().IsKind(SyntaxKind.EndIfDirectiveTrivia)) { var ppSpan = TextSpan.FromBounds( Math.Min(parentSpan.Start, matchSpan.Start), Math.Max(parentSpan.End, matchSpan.End)); ifEndIfSpans = ifEndIfSpans.AddInterval(ppSpan); } } } else if ( trivia.GetStructure().IsKind(SyntaxKind.ElseDirectiveTrivia) || trivia.GetStructure().IsKind(SyntaxKind.ElifDirectiveTrivia)) { if (!ifEndIfSpans.IntersectsWith(parentSpan.Start)) { // This else/elif belongs to a pp span that isn't // entirely within this node. return(true); } } } return(false); }
private void Validate(TextSpan textSpan) { #if DEBUG if (nonOverlappingSpans == null) { nonOverlappingSpans = SimpleIntervalTree.Create(TextSpanIntervalIntrospector.Instance); } // new span should not overlap with any span that we already have. Contract.Requires(!nonOverlappingSpans.GetOverlappingIntervals(textSpan.Start, textSpan.Length).Any()); nonOverlappingSpans = nonOverlappingSpans.AddInterval(textSpan); #endif }