protected TextLine?GetPreviousNonBlankOrPreprocessorLine() { if (Tree == null) { throw new ArgumentNullException(nameof(Tree)); } if (LineToBeIndented.LineNumber <= 0) { return(null); } var sourceText = this.LineToBeIndented.Text; var lineNumber = this.LineToBeIndented.LineNumber - 1; while (lineNumber >= 0) { var actualLine = sourceText.Lines[lineNumber]; // Empty line, no indentation to match. if (string.IsNullOrWhiteSpace(actualLine.ToString())) { lineNumber--; continue; } // No preprocessors in the entire tree, so this // line definitely doesn't have one var root = Tree.GetRoot(CancellationToken); if (!root.ContainsDirectives) { return(sourceText.Lines[lineNumber]); } // This line is inside an inactive region. Examine the // first preceding line not in an inactive region. var disabledSpan = _syntaxFacts.GetInactiveRegionSpanAroundPosition(this.Tree, actualLine.Span.Start, CancellationToken); if (disabledSpan != default(TextSpan)) { var targetLine = sourceText.Lines.GetLineFromPosition(disabledSpan.Start).LineNumber; lineNumber = targetLine - 1; continue; } // A preprocessor directive starts on this line. if (HasPreprocessorCharacter(actualLine) && root.DescendantTokens(actualLine.Span, tk => tk.FullWidth() > 0).Any(s_tokenHasDirective)) { lineNumber--; continue; } return(sourceText.Lines[lineNumber]); } return(null); }