-
Notifications
You must be signed in to change notification settings - Fork 928
Add infrastructure for formatting specific line ranges #1007
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
7f0d87c
Derive Debug for the Input enum
kamalmarhubi 80c56a0
visitor: Add debug log for FmtVisitor::visit_stmt()
kamalmarhubi bd10af1
utils: Move codemap related utilities to a dedicated module
kamalmarhubi ed27b47
codemap: Add utilities for looking up line ranges of spans
kamalmarhubi c311b30
Add type to represent collection of lines in files
kamalmarhubi 9fa5a91
visitor: Handle specified line ranges in visit_stmt
kamalmarhubi bef5d09
rustfmt: Add option to specify line ranges for formatting
kamalmarhubi a83f1a1
Add copyright notices to added files
kamalmarhubi 8775fe4
codemap: Add module description
kamalmarhubi 6648301
Explain that FileLines cannot be given in rustfmt.toml
kamalmarhubi e252100
README: Explain that --file-lines ranges are 1-based
kamalmarhubi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,3 +26,4 @@ log = "0.3" | |
env_logger = "0.3" | ||
getopts = "0.2" | ||
itertools = "0.4.15" | ||
multimap = "0.3" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
// Copyright 2016 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. | ||
|
||
//! This module contains utilities that work with the `CodeMap` from libsyntax / syntex_syntax. | ||
//! This includes extension traits and methods for looking up spans and line ranges for AST nodes. | ||
|
||
use std::rc::Rc; | ||
|
||
use syntax::codemap::{BytePos, CodeMap, FileMap, Span}; | ||
|
||
use comment::FindUncommented; | ||
|
||
/// A range of lines in a file, inclusive of both ends. | ||
pub struct LineRange { | ||
pub file: Rc<FileMap>, | ||
pub lo: usize, | ||
pub hi: usize, | ||
} | ||
|
||
impl LineRange { | ||
pub fn file_name(&self) -> &str { | ||
self.file.as_ref().name.as_str() | ||
} | ||
} | ||
|
||
pub trait SpanUtils { | ||
fn span_after(&self, original: Span, needle: &str) -> BytePos; | ||
fn span_after_last(&self, original: Span, needle: &str) -> BytePos; | ||
fn span_before(&self, original: Span, needle: &str) -> BytePos; | ||
} | ||
|
||
pub trait LineRangeUtils { | ||
/// Returns the `LineRange` that corresponds to `span` in `self`. | ||
/// | ||
/// # Panics | ||
/// | ||
/// Panics if `span` crosses a file boundary, which shouldn't happen. | ||
fn lookup_line_range(&self, span: Span) -> LineRange; | ||
} | ||
|
||
impl SpanUtils for CodeMap { | ||
#[inline] | ||
fn span_after(&self, original: Span, needle: &str) -> BytePos { | ||
let snippet = self.span_to_snippet(original).unwrap(); | ||
let offset = snippet.find_uncommented(needle).unwrap() + needle.len(); | ||
|
||
original.lo + BytePos(offset as u32) | ||
} | ||
|
||
#[inline] | ||
fn span_after_last(&self, original: Span, needle: &str) -> BytePos { | ||
let snippet = self.span_to_snippet(original).unwrap(); | ||
let mut offset = 0; | ||
|
||
while let Some(additional_offset) = snippet[offset..].find_uncommented(needle) { | ||
offset += additional_offset + needle.len(); | ||
} | ||
|
||
original.lo + BytePos(offset as u32) | ||
} | ||
|
||
#[inline] | ||
fn span_before(&self, original: Span, needle: &str) -> BytePos { | ||
let snippet = self.span_to_snippet(original).unwrap(); | ||
let offset = snippet.find_uncommented(needle).unwrap(); | ||
|
||
original.lo + BytePos(offset as u32) | ||
} | ||
} | ||
|
||
impl LineRangeUtils for CodeMap { | ||
fn lookup_line_range(&self, span: Span) -> LineRange { | ||
let lo = self.lookup_char_pos(span.lo); | ||
let hi = self.lookup_char_pos(span.hi); | ||
|
||
assert!(lo.file.name == hi.file.name, | ||
"span crossed file boundary: lo: {:?}, hi: {:?}", | ||
lo, | ||
hi); | ||
|
||
LineRange { | ||
file: lo.file.clone(), | ||
lo: lo.line, | ||
hi: hi.line, | ||
} | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do this? Seems like we could apply --file-lines to stdin if we wanted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason here is that
rustfmt --file-lines='[{"file":"blah.rs", range:[1,15]}]'
with no free arguments should formatblah.rs
not stdin. I could change it so that a string like<stdin>
is accepted in thefile
part of JSON and treated specially. This might require some validation that we're not mixing<stdin>
and file names to avoid confusing behaviour. Thoughts?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On this note, I'm tempted to make
--file-lines
mutually exclusive with specifying file names on the command line, since it's redundant and in the worst case results in unnecessary parsing. I'd leave that to a later PR though.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Accepting
file: <stdin>
sounds good. I would allow --file-lines and a file specified on the command line, as long as the names match up - seems silly to do, but no reason to error out. You can leave all of this till later though.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 for leaving this until a later PR. I want to get the basic idea merged in so that I can build on it in various ways.