From 6ce5e770d2b456fd44dce50703afd980ffe2ff33 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 19 Apr 2016 11:24:41 -0400 Subject: move json.rs file --- src/compiletest/json.rs | 194 -------------------------------------- src/tools/compiletest/src/json.rs | 194 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 194 insertions(+), 194 deletions(-) delete mode 100644 src/compiletest/json.rs create mode 100644 src/tools/compiletest/src/json.rs diff --git a/src/compiletest/json.rs b/src/compiletest/json.rs deleted file mode 100644 index bbe038509e3..00000000000 --- a/src/compiletest/json.rs +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright 2012-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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use errors::{Error, ErrorKind}; -use rustc_serialize::json; -use std::str::FromStr; - -// These structs are a subset of the ones found in -// `syntax::errors::json`. - -#[derive(RustcEncodable, RustcDecodable)] -struct Diagnostic { - message: String, - code: Option, - level: String, - spans: Vec, - children: Vec, - rendered: Option, -} - -#[derive(RustcEncodable, RustcDecodable, Clone)] -struct DiagnosticSpan { - file_name: String, - line_start: usize, - line_end: usize, - column_start: usize, - column_end: usize, - expansion: Option>, -} - -#[derive(RustcEncodable, RustcDecodable, Clone)] -struct DiagnosticSpanMacroExpansion { - /// span where macro was applied to generate this code - span: DiagnosticSpan, - - /// name of macro that was applied (e.g., "foo!" or "#[derive(Eq)]") - macro_decl_name: String, -} - -#[derive(RustcEncodable, RustcDecodable, Clone)] -struct DiagnosticCode { - /// The code itself. - code: String, - /// An explanation for the code. - explanation: Option, -} - -pub fn parse_output(file_name: &str, output: &str) -> Vec { - output.lines() - .flat_map(|line| parse_line(file_name, line)) - .collect() -} - -fn parse_line(file_name: &str, line: &str) -> Vec { - // The compiler sometimes intermingles non-JSON stuff into the - // output. This hack just skips over such lines. Yuck. - if line.chars().next() == Some('{') { - match json::decode::(line) { - Ok(diagnostic) => { - let mut expected_errors = vec![]; - push_expected_errors(&mut expected_errors, &diagnostic, file_name); - expected_errors - } - Err(error) => { - panic!("failed to decode compiler output as json: `{}`", error); - } - } - } else { - vec![] - } -} - -fn push_expected_errors(expected_errors: &mut Vec, - diagnostic: &Diagnostic, - file_name: &str) { - // We only consider messages pertaining to the current file. - let matching_spans = || { - diagnostic.spans.iter().filter(|span| span.file_name == file_name) - }; - - // We break the output into multiple lines, and then append the - // [E123] to every line in the output. This may be overkill. The - // intention was to match existing tests that do things like "//| - // found `i32` [E123]" and expect to match that somewhere, and yet - // also ensure that `//~ ERROR E123` *always* works. The - // assumption is that these multi-line error messages are on their - // way out anyhow. - let with_code = |span: &DiagnosticSpan, text: &str| { - match diagnostic.code { - Some(ref code) => - // FIXME(#33000) -- it'd be better to use a dedicated - // UI harness than to include the line/col number like - // this, but some current tests rely on it. - // - // Note: Do NOT include the filename. These can easily - // cause false matches where the expected message - // appears in the filename, and hence the message - // changes but the test still passes. - format!("{}:{}: {}:{}: {} [{}]", - span.line_start, span.column_start, - span.line_end, span.column_end, - text, code.code.clone()), - None => - // FIXME(#33000) -- it'd be better to use a dedicated UI harness - format!("{}:{}: {}:{}: {}", - span.line_start, span.column_start, - span.line_end, span.column_end, - text), - } - }; - - // Convert multi-line messages into multiple expected - // errors. We expect to replace these with something - // more structured shortly anyhow. - let mut message_lines = diagnostic.message.lines(); - if let Some(first_line) = message_lines.next() { - for span in matching_spans() { - let msg = with_code(span, first_line); - let kind = ErrorKind::from_str(&diagnostic.level).ok(); - expected_errors.push( - Error { - line_num: span.line_start, - kind: kind, - msg: msg, - } - ); - } - } - for next_line in message_lines { - for span in matching_spans() { - expected_errors.push( - Error { - line_num: span.line_start, - kind: None, - msg: with_code(span, next_line), - } - ); - } - } - - // If the message has a suggestion, register that. - if let Some(ref rendered) = diagnostic.rendered { - let start_line = matching_spans().map(|s| s.line_start).min().expect("\ - every suggestion should have at least one span"); - for (index, line) in rendered.lines().enumerate() { - expected_errors.push( - Error { - line_num: start_line + index, - kind: Some(ErrorKind::Suggestion), - msg: line.to_string() - } - ); - } - } - - // Add notes for the backtrace - for span in matching_spans() { - for frame in &span.expansion { - push_backtrace(expected_errors, - frame, - file_name); - } - } - - // Flatten out the children. - for child in &diagnostic.children { - push_expected_errors(expected_errors, child, file_name); - } -} - -fn push_backtrace(expected_errors: &mut Vec, - expansion: &DiagnosticSpanMacroExpansion, - file_name: &str) { - if expansion.span.file_name == file_name { - expected_errors.push( - Error { - line_num: expansion.span.line_start, - kind: Some(ErrorKind::Note), - msg: format!("in this expansion of {}", expansion.macro_decl_name), - } - ); - } - - for previous_expansion in &expansion.span.expansion { - push_backtrace(expected_errors, previous_expansion, file_name); - } -} diff --git a/src/tools/compiletest/src/json.rs b/src/tools/compiletest/src/json.rs new file mode 100644 index 00000000000..bbe038509e3 --- /dev/null +++ b/src/tools/compiletest/src/json.rs @@ -0,0 +1,194 @@ +// Copyright 2012-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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use errors::{Error, ErrorKind}; +use rustc_serialize::json; +use std::str::FromStr; + +// These structs are a subset of the ones found in +// `syntax::errors::json`. + +#[derive(RustcEncodable, RustcDecodable)] +struct Diagnostic { + message: String, + code: Option, + level: String, + spans: Vec, + children: Vec, + rendered: Option, +} + +#[derive(RustcEncodable, RustcDecodable, Clone)] +struct DiagnosticSpan { + file_name: String, + line_start: usize, + line_end: usize, + column_start: usize, + column_end: usize, + expansion: Option>, +} + +#[derive(RustcEncodable, RustcDecodable, Clone)] +struct DiagnosticSpanMacroExpansion { + /// span where macro was applied to generate this code + span: DiagnosticSpan, + + /// name of macro that was applied (e.g., "foo!" or "#[derive(Eq)]") + macro_decl_name: String, +} + +#[derive(RustcEncodable, RustcDecodable, Clone)] +struct DiagnosticCode { + /// The code itself. + code: String, + /// An explanation for the code. + explanation: Option, +} + +pub fn parse_output(file_name: &str, output: &str) -> Vec { + output.lines() + .flat_map(|line| parse_line(file_name, line)) + .collect() +} + +fn parse_line(file_name: &str, line: &str) -> Vec { + // The compiler sometimes intermingles non-JSON stuff into the + // output. This hack just skips over such lines. Yuck. + if line.chars().next() == Some('{') { + match json::decode::(line) { + Ok(diagnostic) => { + let mut expected_errors = vec![]; + push_expected_errors(&mut expected_errors, &diagnostic, file_name); + expected_errors + } + Err(error) => { + panic!("failed to decode compiler output as json: `{}`", error); + } + } + } else { + vec![] + } +} + +fn push_expected_errors(expected_errors: &mut Vec, + diagnostic: &Diagnostic, + file_name: &str) { + // We only consider messages pertaining to the current file. + let matching_spans = || { + diagnostic.spans.iter().filter(|span| span.file_name == file_name) + }; + + // We break the output into multiple lines, and then append the + // [E123] to every line in the output. This may be overkill. The + // intention was to match existing tests that do things like "//| + // found `i32` [E123]" and expect to match that somewhere, and yet + // also ensure that `//~ ERROR E123` *always* works. The + // assumption is that these multi-line error messages are on their + // way out anyhow. + let with_code = |span: &DiagnosticSpan, text: &str| { + match diagnostic.code { + Some(ref code) => + // FIXME(#33000) -- it'd be better to use a dedicated + // UI harness than to include the line/col number like + // this, but some current tests rely on it. + // + // Note: Do NOT include the filename. These can easily + // cause false matches where the expected message + // appears in the filename, and hence the message + // changes but the test still passes. + format!("{}:{}: {}:{}: {} [{}]", + span.line_start, span.column_start, + span.line_end, span.column_end, + text, code.code.clone()), + None => + // FIXME(#33000) -- it'd be better to use a dedicated UI harness + format!("{}:{}: {}:{}: {}", + span.line_start, span.column_start, + span.line_end, span.column_end, + text), + } + }; + + // Convert multi-line messages into multiple expected + // errors. We expect to replace these with something + // more structured shortly anyhow. + let mut message_lines = diagnostic.message.lines(); + if let Some(first_line) = message_lines.next() { + for span in matching_spans() { + let msg = with_code(span, first_line); + let kind = ErrorKind::from_str(&diagnostic.level).ok(); + expected_errors.push( + Error { + line_num: span.line_start, + kind: kind, + msg: msg, + } + ); + } + } + for next_line in message_lines { + for span in matching_spans() { + expected_errors.push( + Error { + line_num: span.line_start, + kind: None, + msg: with_code(span, next_line), + } + ); + } + } + + // If the message has a suggestion, register that. + if let Some(ref rendered) = diagnostic.rendered { + let start_line = matching_spans().map(|s| s.line_start).min().expect("\ + every suggestion should have at least one span"); + for (index, line) in rendered.lines().enumerate() { + expected_errors.push( + Error { + line_num: start_line + index, + kind: Some(ErrorKind::Suggestion), + msg: line.to_string() + } + ); + } + } + + // Add notes for the backtrace + for span in matching_spans() { + for frame in &span.expansion { + push_backtrace(expected_errors, + frame, + file_name); + } + } + + // Flatten out the children. + for child in &diagnostic.children { + push_expected_errors(expected_errors, child, file_name); + } +} + +fn push_backtrace(expected_errors: &mut Vec, + expansion: &DiagnosticSpanMacroExpansion, + file_name: &str) { + if expansion.span.file_name == file_name { + expected_errors.push( + Error { + line_num: expansion.span.line_start, + kind: Some(ErrorKind::Note), + msg: format!("in this expansion of {}", expansion.macro_decl_name), + } + ); + } + + for previous_expansion in &expansion.span.expansion { + push_backtrace(expected_errors, previous_expansion, file_name); + } +} -- cgit 1.4.1-3-g733a5