<commit_before>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::borrow::Cow;
use std::iter::repeat;

use syntax::codemap::{BytePos, Pos, Span};

use comment::{rewrite_comment, CodeCharKind, CommentCodeSlices};
use config::WriteMode;
use shape::{Indent, Shape};
use utils::{count_newlines, mk_sp};
use visitor::FmtVisitor;

impl<'a> FmtVisitor<'a> {
    fn output_at_start(&self) -> bool {
        self.buffer.len == 0
    }

    // TODO these format_missing methods are ugly. Refactor and add unit tests
    // for the central whitespace stripping loop.
    pub fn format_missing(&mut self, end: BytePos) {
        self.format_missing_inner(end, |this, last_snippet, _| {
            this.buffer.push_str(last_snippet)
        })
    }

    pub fn format_missing_with_indent(&mut self, end: BytePos) {
        let config = self.config;
        self.format_missing_inner(end, |this, last_snippet, snippet| {
            this.buffer.push_str(last_snippet.trim_right());
            if last_snippet == snippet && !this.output_at_start() {
                // No new lines in the snippet.
                this.buffer.push_str("\n");
            }
            let indent = this.block_indent.to_string(config);
            this.buffer.push_str(&indent);
        })
    }

    pub fn format_missing_no_indent(&mut self, end: BytePos) {
        self.format_missing_inner(end, |this, last_snippet, _| {
            this.buffer.push_str(last_snippet.trim_right());
        })
    }

    fn format_missing_inner<F: Fn(&mut FmtVisitor, &str, &str)>(
        &mut self,
        end: BytePos,
        process_last_snippet: F,
    ) {
        let start = self.last_pos;

        if start == end {
            // Do nothing if this is the beginning of the file.
            if !self.output_at_start() {
                process_last_snippet(self, "", "");
            }
            return;
        }

        assert!(
            start < end,
            "Request to format inverted span: {:?} to {:?}",
            self.codemap.lookup_char_pos(start),
            self.codemap.lookup_char_pos(end)
        );

        self.last_pos = end;
        let span = mk_sp(start, end);
        let snippet = self.snippet(span);
        if snippet.trim().is_empty() {
            // Keep vertical spaces within range.
            self.push_vertical_spaces(count_newlines(&snippet));<commit_msg>Process blank lines if only they're within file lines range<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::borrow::Cow;
use std::iter::repeat;

use syntax::codemap::{BytePos, Pos, Span};

use codemap::LineRangeUtils;
use comment::{rewrite_comment, CodeCharKind, CommentCodeSlices};
use config::WriteMode;
use shape::{Indent, Shape};
use utils::{count_newlines, mk_sp};
use visitor::FmtVisitor;

impl<'a> FmtVisitor<'a> {
    fn output_at_start(&self) -> bool {
        self.buffer.len == 0
    }

    // TODO these format_missing methods are ugly. Refactor and add unit tests
    // for the central whitespace stripping loop.
    pub fn format_missing(&mut self, end: BytePos) {
        self.format_missing_inner(end, |this, last_snippet, _| {
            this.buffer.push_str(last_snippet)
        })
    }

    pub fn format_missing_with_indent(&mut self, end: BytePos) {
        let config = self.config;
        self.format_missing_inner(end, |this, last_snippet, snippet| {
            this.buffer.push_str(last_snippet.trim_right());
            if last_snippet == snippet && !this.output_at_start() {
                // No new lines in the snippet.
                this.buffer.push_str("\n");
            }
            let indent = this.block_indent.to_string(config);
            this.buffer.push_str(&indent);
        })
    }

    pub fn format_missing_no_indent(&mut self, end: BytePos) {
        self.format_missing_inner(end, |this, last_snippet, _| {
            this.buffer.push_str(last_snippet.trim_right());
        })
    }

    fn format_missing_inner<F: Fn(&mut FmtVisitor, &str, &str)>(
        &mut self,
        end: BytePos,
        process_last_snippet: F,
    ) {
        let start = self.last_pos;

        if start == end {
            // Do nothing if this is the beginning of the file.
            if !self.output_at_start() {
                process_last_snippet(self, "", "");
            }
            return;
        }

        assert!(
            start < end,
            "Request to format inverted span: {:?} to {:?}",
            self.codemap.lookup_char_pos(start),
            self.codemap.lookup_char_pos(end)
        );

        self.last_pos = end;
        let span = mk_sp(start, end);
        let snippet = self.snippet(span);
        if snippet.trim().is_empty() && !out_of_file_lines_range!(self, span) {
            // Keep vertical spaces within range.
            self.push_vertical_spaces(count_newlines(&snippet));
{'fraction_non_alphanumeric': 0.11938990182328191, 'fraction_numerical': 0.003155680224403927, 'mean_word_length': 2.410041841004184, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4359786', 'n_tokens_mistral': 1758, 'n_tokens_neox': 1718, 'n_words': 432}