mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-22 12:43:36 +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)",
|
||||
"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)",
|
||||
"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)",
|
||||
"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)",
|
||||
@ -21,6 +22,11 @@ dependencies = [
|
||||
"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]]
|
||||
name = "diff"
|
||||
version = "0.1.7"
|
||||
@ -93,6 +99,19 @@ dependencies = [
|
||||
"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]]
|
||||
name = "term"
|
||||
version = "0.2.12"
|
||||
@ -115,6 +134,11 @@ name = "unicode-segmentation"
|
||||
version = "0.1.2"
|
||||
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]]
|
||||
name = "winapi"
|
||||
version = "0.2.4"
|
||||
|
@ -16,6 +16,7 @@ regex = "0.1.41"
|
||||
term = "0.2.11"
|
||||
strings = { version = "0.0.1", git = "https://github.com/nrc/strings.rs.git" }
|
||||
diff = { git = "https://github.com/utkarshkukreti/diff.rs.git" }
|
||||
syntex_syntax = { git = "https://github.com/serde-rs/syntex" }
|
||||
log = "0.3.2"
|
||||
env_logger = "0.3.1"
|
||||
|
||||
|
77
src/lib.rs
77
src/lib.rs
@ -15,10 +15,7 @@
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
extern crate getopts;
|
||||
extern crate rustc;
|
||||
extern crate rustc_driver;
|
||||
extern crate syntax;
|
||||
extern crate syntex_syntax as syntax;
|
||||
extern crate rustc_serialize;
|
||||
|
||||
extern crate strings;
|
||||
@ -28,22 +25,15 @@ extern crate regex;
|
||||
extern crate diff;
|
||||
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::codemap::{CodeMap, Span};
|
||||
use syntax::diagnostics;
|
||||
use syntax::parse::{self, ParseSess};
|
||||
|
||||
use std::ops::{Add, Sub};
|
||||
use std::path::PathBuf;
|
||||
use std::path::Path;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
|
||||
use issues::{BadIssueSeeker, Issue};
|
||||
use filemap::FileMap;
|
||||
@ -380,65 +370,24 @@ pub fn fmt_lines(file_map: &mut FileMap, config: &Config) -> FormatReport {
|
||||
report
|
||||
}
|
||||
|
||||
struct RustFmtCalls {
|
||||
config: Rc<Config>,
|
||||
result: Rc<RefCell<Option<FileMap>>>,
|
||||
}
|
||||
pub fn format(file: &Path, config: &Config) -> FileMap {
|
||||
let parse_session = ParseSess::new();
|
||||
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");
|
||||
}
|
||||
// For some reason, the codemap does not include terminating
|
||||
// newlines so we must add one on for each file. This is sad.
|
||||
filemap::append_newlines(&mut file_map);
|
||||
|
||||
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
|
||||
// newlines so we must add one on for each file. This is sad.
|
||||
filemap::append_newlines(&mut file_map);
|
||||
|
||||
*result.borrow_mut() = Some(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()
|
||||
return file_map;
|
||||
}
|
||||
|
||||
// args are the arguments passed on the command line, generally passed through
|
||||
// to the compiler.
|
||||
// write_mode determines what happens to the result of running rustfmt, see
|
||||
// WriteMode.
|
||||
pub fn run(args: Vec<String>, write_mode: WriteMode, config: &Config) {
|
||||
let mut result = format(args, config);
|
||||
pub fn run(file: &Path, write_mode: WriteMode, config: &Config) {
|
||||
let mut result = format(file, config);
|
||||
|
||||
println!("{}", fmt_lines(&mut result, config));
|
||||
|
||||
|
@ -19,15 +19,10 @@
|
||||
// List-like invocations with parentheses will be formatted as function calls,
|
||||
// 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::parse::token::{Eof, Comma, Token};
|
||||
use syntax::parse::{ParseSess, tts_to_parser};
|
||||
use syntax::codemap::{mk_sp, BytePos};
|
||||
use syntax::parse::token;
|
||||
use syntax::util::interner::StrInterner;
|
||||
|
||||
use Indent;
|
||||
use rewrite::RewriteContext;
|
||||
@ -37,12 +32,6 @@ use utils::{wrap_str, span_after};
|
||||
|
||||
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?
|
||||
#[derive(Clone, Copy)]
|
||||
enum MacroStyle {
|
||||
@ -84,38 +73,28 @@ pub fn rewrite_macro(mac: &ast::Mac,
|
||||
};
|
||||
}
|
||||
|
||||
let wrapped_tt_vec = ForceSend(mac.node.tts.clone());
|
||||
let my_interner = ForceSend(clone_interner());
|
||||
let parse_session = ParseSess::new();
|
||||
let mut parser = tts_to_parser(&parse_session, mac.node.tts.clone(), Vec::new());
|
||||
let mut expr_vec = Vec::new();
|
||||
|
||||
// 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 mut parser = tts_to_parser(&parse_session, wrapped_tt_vec.0, vec![]);
|
||||
let mut expr_vec = vec![];
|
||||
token::get_ident_interner().reset(my_interner.0);
|
||||
loop {
|
||||
expr_vec.push(match parser.parse_expr_nopanic() {
|
||||
Ok(expr) => expr,
|
||||
Err(..) => return None,
|
||||
});
|
||||
|
||||
loop {
|
||||
expr_vec.push(parser.parse_expr());
|
||||
|
||||
match parser.token {
|
||||
Token::Eof => break,
|
||||
Token::Comma => (),
|
||||
_ => panic!("Macro not list-like, skiping..."),
|
||||
}
|
||||
|
||||
let _ = parser.bump();
|
||||
|
||||
if parser.token == Token::Eof {
|
||||
return None;
|
||||
}
|
||||
match parser.token {
|
||||
Token::Eof => break,
|
||||
Token::Comma => (),
|
||||
_ => return None,
|
||||
}
|
||||
|
||||
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);
|
||||
let _ = parser.bump();
|
||||
|
||||
if parser.token == Token::Eof {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
match style {
|
||||
MacroStyle::Parens => {
|
||||
@ -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 {
|
||||
let snippet = context.snippet(mac.span);
|
||||
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>>> {
|
||||
let sig_comments = read_significant_comments(&filename);
|
||||
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 {
|
||||
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.
|
||||
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);
|
||||
|
||||
// Won't panic, as we're not doing any IO.
|
||||
|
Loading…
Reference in New Issue
Block a user