mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-07 20:58:39 +00:00
Remove dependence on rustc/rustc_driver, use syntex
Instead just parse manually with the `syntex_syntax` crate which is a clone of libsyntax on crates.io which builds on stable Rust.
This commit is contained in:
parent
36abfe5dc2
commit
579fb34417
24
Cargo.lock
generated
24
Cargo.lock
generated
@ -8,6 +8,7 @@ dependencies = [
|
|||||||
"regex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"strings 0.0.1 (git+https://github.com/nrc/strings.rs.git)",
|
"strings 0.0.1 (git+https://github.com/nrc/strings.rs.git)",
|
||||||
|
"syntex_syntax 0.18.0 (git+https://github.com/serde-rs/syntex)",
|
||||||
"term 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"term 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"toml 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
"toml 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"unicode-segmentation 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-segmentation 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -21,6 +22,11 @@ dependencies = [
|
|||||||
"memchr 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"memchr 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "diff"
|
name = "diff"
|
||||||
version = "0.1.7"
|
version = "0.1.7"
|
||||||
@ -93,6 +99,19 @@ dependencies = [
|
|||||||
"log 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syntex_syntax"
|
||||||
|
version = "0.18.0"
|
||||||
|
source = "git+https://github.com/serde-rs/syntex#176ca5d8add606fac8d503b10c89ddb82f02d92b"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"term 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "term"
|
name = "term"
|
||||||
version = "0.2.12"
|
version = "0.2.12"
|
||||||
@ -115,6 +134,11 @@ name = "unicode-segmentation"
|
|||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-xid"
|
||||||
|
version = "0.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.2.4"
|
version = "0.2.4"
|
||||||
|
@ -16,6 +16,7 @@ regex = "0.1.41"
|
|||||||
term = "0.2.11"
|
term = "0.2.11"
|
||||||
strings = { version = "0.0.1", git = "https://github.com/nrc/strings.rs.git" }
|
strings = { version = "0.0.1", git = "https://github.com/nrc/strings.rs.git" }
|
||||||
diff = { git = "https://github.com/utkarshkukreti/diff.rs.git" }
|
diff = { git = "https://github.com/utkarshkukreti/diff.rs.git" }
|
||||||
|
syntex_syntax = { git = "https://github.com/serde-rs/syntex" }
|
||||||
log = "0.3.2"
|
log = "0.3.2"
|
||||||
env_logger = "0.3.1"
|
env_logger = "0.3.1"
|
||||||
|
|
||||||
|
71
src/lib.rs
71
src/lib.rs
@ -15,10 +15,7 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
extern crate getopts;
|
extern crate syntex_syntax as syntax;
|
||||||
extern crate rustc;
|
|
||||||
extern crate rustc_driver;
|
|
||||||
extern crate syntax;
|
|
||||||
extern crate rustc_serialize;
|
extern crate rustc_serialize;
|
||||||
|
|
||||||
extern crate strings;
|
extern crate strings;
|
||||||
@ -28,22 +25,15 @@ extern crate regex;
|
|||||||
extern crate diff;
|
extern crate diff;
|
||||||
extern crate term;
|
extern crate term;
|
||||||
|
|
||||||
use rustc::session::Session;
|
|
||||||
use rustc::session::config as rustc_config;
|
|
||||||
use rustc::session::config::Input;
|
|
||||||
use rustc_driver::{driver, CompilerCalls, Compilation};
|
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::codemap::{CodeMap, Span};
|
use syntax::codemap::{CodeMap, Span};
|
||||||
use syntax::diagnostics;
|
use syntax::parse::{self, ParseSess};
|
||||||
|
|
||||||
use std::ops::{Add, Sub};
|
use std::ops::{Add, Sub};
|
||||||
use std::path::PathBuf;
|
use std::path::Path;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::rc::Rc;
|
|
||||||
use std::cell::RefCell;
|
|
||||||
|
|
||||||
use issues::{BadIssueSeeker, Issue};
|
use issues::{BadIssueSeeker, Issue};
|
||||||
use filemap::FileMap;
|
use filemap::FileMap;
|
||||||
@ -380,65 +370,24 @@ pub fn fmt_lines(file_map: &mut FileMap, config: &Config) -> FormatReport {
|
|||||||
report
|
report
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RustFmtCalls {
|
pub fn format(file: &Path, config: &Config) -> FileMap {
|
||||||
config: Rc<Config>,
|
let parse_session = ParseSess::new();
|
||||||
result: Rc<RefCell<Option<FileMap>>>,
|
let krate = parse::parse_crate_from_file(file, Vec::new(), &parse_session);
|
||||||
}
|
let mut file_map = fmt_ast(&krate, parse_session.codemap(), config);
|
||||||
|
|
||||||
impl<'a> CompilerCalls<'a> for RustFmtCalls {
|
|
||||||
fn no_input(&mut self,
|
|
||||||
_: &getopts::Matches,
|
|
||||||
_: &rustc_config::Options,
|
|
||||||
_: &Option<PathBuf>,
|
|
||||||
_: &Option<PathBuf>,
|
|
||||||
_: &diagnostics::registry::Registry)
|
|
||||||
-> Option<(Input, Option<PathBuf>)> {
|
|
||||||
panic!("No input supplied to RustFmt");
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_controller(&mut self, _: &Session) -> driver::CompileController<'a> {
|
|
||||||
let result = self.result.clone();
|
|
||||||
let config = self.config.clone();
|
|
||||||
|
|
||||||
let mut control = driver::CompileController::basic();
|
|
||||||
control.after_parse.stop = Compilation::Stop;
|
|
||||||
control.after_parse.callback = Box::new(move |state| {
|
|
||||||
let krate = state.krate.unwrap();
|
|
||||||
let codemap = state.session.codemap();
|
|
||||||
let mut file_map = fmt_ast(krate, codemap, &*config);
|
|
||||||
// For some reason, the codemap does not include terminating
|
// For some reason, the codemap does not include terminating
|
||||||
// newlines so we must add one on for each file. This is sad.
|
// newlines so we must add one on for each file. This is sad.
|
||||||
filemap::append_newlines(&mut file_map);
|
filemap::append_newlines(&mut file_map);
|
||||||
|
|
||||||
*result.borrow_mut() = Some(file_map);
|
return file_map;
|
||||||
});
|
|
||||||
|
|
||||||
control
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn format(args: Vec<String>, config: &Config) -> FileMap {
|
|
||||||
let result = Rc::new(RefCell::new(None));
|
|
||||||
|
|
||||||
{
|
|
||||||
let config = Rc::new(config.clone());
|
|
||||||
let mut call_ctxt = RustFmtCalls {
|
|
||||||
config: config,
|
|
||||||
result: result.clone(),
|
|
||||||
};
|
|
||||||
rustc_driver::run_compiler(&args, &mut call_ctxt);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Peel the union.
|
|
||||||
Rc::try_unwrap(result).ok().unwrap().into_inner().unwrap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// args are the arguments passed on the command line, generally passed through
|
// args are the arguments passed on the command line, generally passed through
|
||||||
// to the compiler.
|
// to the compiler.
|
||||||
// write_mode determines what happens to the result of running rustfmt, see
|
// write_mode determines what happens to the result of running rustfmt, see
|
||||||
// WriteMode.
|
// WriteMode.
|
||||||
pub fn run(args: Vec<String>, write_mode: WriteMode, config: &Config) {
|
pub fn run(file: &Path, write_mode: WriteMode, config: &Config) {
|
||||||
let mut result = format(args, config);
|
let mut result = format(file, config);
|
||||||
|
|
||||||
println!("{}", fmt_lines(&mut result, config));
|
println!("{}", fmt_lines(&mut result, config));
|
||||||
|
|
||||||
|
@ -19,15 +19,10 @@
|
|||||||
// List-like invocations with parentheses will be formatted as function calls,
|
// List-like invocations with parentheses will be formatted as function calls,
|
||||||
// and those with brackets will be formatted as array literals.
|
// and those with brackets will be formatted as array literals.
|
||||||
|
|
||||||
use std::thread;
|
|
||||||
use std::collections::hash_map::{HashMap, Entry};
|
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::parse::token::{Eof, Comma, Token};
|
use syntax::parse::token::{Eof, Comma, Token};
|
||||||
use syntax::parse::{ParseSess, tts_to_parser};
|
use syntax::parse::{ParseSess, tts_to_parser};
|
||||||
use syntax::codemap::{mk_sp, BytePos};
|
use syntax::codemap::{mk_sp, BytePos};
|
||||||
use syntax::parse::token;
|
|
||||||
use syntax::util::interner::StrInterner;
|
|
||||||
|
|
||||||
use Indent;
|
use Indent;
|
||||||
use rewrite::RewriteContext;
|
use rewrite::RewriteContext;
|
||||||
@ -37,12 +32,6 @@ use utils::{wrap_str, span_after};
|
|||||||
|
|
||||||
static FORCED_BRACKET_MACROS: &'static [&'static str] = &["vec!"];
|
static FORCED_BRACKET_MACROS: &'static [&'static str] = &["vec!"];
|
||||||
|
|
||||||
// We need to pass `TokenTree`s to our expression parsing thread, but they are
|
|
||||||
// not `Send`. We wrap them in a `Send` container to force our will.
|
|
||||||
// FIXME: this is a pretty terrible hack. Any other solution would be preferred.
|
|
||||||
struct ForceSend<T>(pub T);
|
|
||||||
unsafe impl<T> Send for ForceSend<T> {}
|
|
||||||
|
|
||||||
// FIXME: use the enum from libsyntax?
|
// FIXME: use the enum from libsyntax?
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
enum MacroStyle {
|
enum MacroStyle {
|
||||||
@ -84,25 +73,20 @@ pub fn rewrite_macro(mac: &ast::Mac,
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let wrapped_tt_vec = ForceSend(mac.node.tts.clone());
|
|
||||||
let my_interner = ForceSend(clone_interner());
|
|
||||||
|
|
||||||
// Wrap expression parsing logic in a thread since the libsyntax parser
|
|
||||||
// panics on failure, which we do not want to propagate.
|
|
||||||
// The expression vector is wrapped in an Option inside a Result.
|
|
||||||
let expr_vec_result = thread::spawn(move || {
|
|
||||||
let parse_session = ParseSess::new();
|
let parse_session = ParseSess::new();
|
||||||
let mut parser = tts_to_parser(&parse_session, wrapped_tt_vec.0, vec![]);
|
let mut parser = tts_to_parser(&parse_session, mac.node.tts.clone(), Vec::new());
|
||||||
let mut expr_vec = vec![];
|
let mut expr_vec = Vec::new();
|
||||||
token::get_ident_interner().reset(my_interner.0);
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
expr_vec.push(parser.parse_expr());
|
expr_vec.push(match parser.parse_expr_nopanic() {
|
||||||
|
Ok(expr) => expr,
|
||||||
|
Err(..) => return None,
|
||||||
|
});
|
||||||
|
|
||||||
match parser.token {
|
match parser.token {
|
||||||
Token::Eof => break,
|
Token::Eof => break,
|
||||||
Token::Comma => (),
|
Token::Comma => (),
|
||||||
_ => panic!("Macro not list-like, skiping..."),
|
_ => return None,
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = parser.bump();
|
let _ = parser.bump();
|
||||||
@ -112,11 +96,6 @@ pub fn rewrite_macro(mac: &ast::Mac,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(ForceSend((expr_vec, clone_interner())))
|
|
||||||
});
|
|
||||||
let (expr_vec, interner) = try_opt!(try_opt!(expr_vec_result.join().ok())).0;
|
|
||||||
token::get_ident_interner().reset(interner);
|
|
||||||
|
|
||||||
match style {
|
match style {
|
||||||
MacroStyle::Parens => {
|
MacroStyle::Parens => {
|
||||||
// Format macro invocation as function call.
|
// Format macro invocation as function call.
|
||||||
@ -146,23 +125,6 @@ pub fn rewrite_macro(mac: &ast::Mac,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clone_interner() -> StrInterner {
|
|
||||||
let old = token::get_ident_interner();
|
|
||||||
let new = StrInterner::new();
|
|
||||||
let mut map = HashMap::new();
|
|
||||||
for name in (0..old.len()).map(|i| i as u32).map(ast::Name) {
|
|
||||||
match map.entry(old.get(name)) {
|
|
||||||
Entry::Occupied(e) => {
|
|
||||||
new.gensym_copy(*e.get());
|
|
||||||
}
|
|
||||||
Entry::Vacant(e) => {
|
|
||||||
e.insert(new.intern(&old.get(name)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new
|
|
||||||
}
|
|
||||||
|
|
||||||
fn macro_style(mac: &ast::Mac, context: &RewriteContext) -> MacroStyle {
|
fn macro_style(mac: &ast::Mac, context: &RewriteContext) -> MacroStyle {
|
||||||
let snippet = context.snippet(mac.span);
|
let snippet = context.snippet(mac.span);
|
||||||
let paren_pos = snippet.find_uncommented("(").unwrap_or(usize::max_value());
|
let paren_pos = snippet.find_uncommented("(").unwrap_or(usize::max_value());
|
||||||
|
@ -135,7 +135,6 @@ fn print_mismatches(result: HashMap<String, Vec<Mismatch>>) {
|
|||||||
pub fn idempotent_check(filename: String) -> Result<FormatReport, HashMap<String, Vec<Mismatch>>> {
|
pub fn idempotent_check(filename: String) -> Result<FormatReport, HashMap<String, Vec<Mismatch>>> {
|
||||||
let sig_comments = read_significant_comments(&filename);
|
let sig_comments = read_significant_comments(&filename);
|
||||||
let mut config = get_config(sig_comments.get("config").map(|x| &(*x)[..]));
|
let mut config = get_config(sig_comments.get("config").map(|x| &(*x)[..]));
|
||||||
let args = vec!["rustfmt".to_owned(), filename];
|
|
||||||
|
|
||||||
for (key, val) in &sig_comments {
|
for (key, val) in &sig_comments {
|
||||||
if key != "target" && key != "config" {
|
if key != "target" && key != "config" {
|
||||||
@ -146,7 +145,7 @@ pub fn idempotent_check(filename: String) -> Result<FormatReport, HashMap<String
|
|||||||
// Don't generate warnings for to-do items.
|
// Don't generate warnings for to-do items.
|
||||||
config.report_todo = ReportTactic::Never;
|
config.report_todo = ReportTactic::Never;
|
||||||
|
|
||||||
let mut file_map = format(args, &config);
|
let mut file_map = format(Path::new(&filename), &config);
|
||||||
let format_report = fmt_lines(&mut file_map, &config);
|
let format_report = fmt_lines(&mut file_map, &config);
|
||||||
|
|
||||||
// Won't panic, as we're not doing any IO.
|
// Won't panic, as we're not doing any IO.
|
||||||
|
Loading…
Reference in New Issue
Block a user