mirror of https://github.com/rwf2/Rocket.git
Add emoji in errors
This commit is contained in:
parent
6be902162d
commit
314c776f4f
|
@ -13,7 +13,7 @@ use syntax_ext::deriving::generic::MethodDef;
|
|||
use syntax_ext::deriving::generic::{StaticStruct, Substructure, TraitDef, ty};
|
||||
use syntax_ext::deriving::generic::combine_substructure as c_s;
|
||||
|
||||
use utils::strip_ty_lifetimes;
|
||||
use utils::*;
|
||||
|
||||
static ONLY_STRUCTS_ERR: &'static str = "`FromForm` can only be derived for \
|
||||
structures with named fields.";
|
||||
|
@ -37,15 +37,15 @@ fn get_struct_lifetime(ecx: &mut ExtCtxt, item: &Annotatable, span: Span)
|
|||
Some(lifetime_name)
|
||||
}
|
||||
_ => {
|
||||
ecx.span_err(item.span, "cannot have more than one \
|
||||
span_err(ecx, item.span, "cannot have more than one \
|
||||
lifetime parameter when deriving `FromForm`.");
|
||||
None
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => ecx.span_fatal(span, ONLY_STRUCTS_ERR)
|
||||
_ => span_fatal(ecx, span, ONLY_STRUCTS_ERR)
|
||||
},
|
||||
_ => ecx.span_fatal(span, ONLY_STRUCTS_ERR)
|
||||
_ => span_fatal(ecx, span, ONLY_STRUCTS_ERR)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ impl ErrorGenerateExt for ErrorParams {
|
|||
let input_args = &self.annotated_fn.decl().inputs;
|
||||
if input_args.len() > 2 {
|
||||
let sp = self.annotated_fn.span();
|
||||
ecx.struct_span_err(sp, "error handlers can have at most 2 arguments")
|
||||
struct_span_err(ecx, sp, "error handlers can have at most 2 arguments")
|
||||
.help(arg_help).emit()
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ impl ErrorGenerateExt for ErrorParams {
|
|||
TyKind::Rptr(..) => Some(req),
|
||||
TyKind::Path(..) => Some(err),
|
||||
_ => {
|
||||
ecx.struct_span_err(ty.span, "unexpected error handler argument")
|
||||
struct_span_err(ecx, ty.span, "unexpected error handler argument")
|
||||
.help(arg_help).emit();
|
||||
None
|
||||
}
|
||||
|
|
|
@ -52,8 +52,8 @@ impl RouteGenerateExt for RouteParams {
|
|||
fn missing_declared_err<T: Display>(&self, ecx: &ExtCtxt, arg: &Spanned<T>) {
|
||||
let fn_span = self.annotated_fn.span();
|
||||
let msg = format!("'{}' is declared as an argument...", arg.node);
|
||||
ecx.span_err(arg.span, &msg);
|
||||
ecx.span_err(fn_span, "...but isn't in the function signature.");
|
||||
span_err(ecx, arg.span, &msg);
|
||||
span_err(ecx, fn_span, "...but isn't in the function signature.");
|
||||
}
|
||||
|
||||
fn gen_form(&self,
|
||||
|
@ -181,7 +181,7 @@ impl RouteGenerateExt for RouteParams {
|
|||
!a.named(&p.node.name)
|
||||
})
|
||||
} else {
|
||||
ecx.span_err(a.pat.span, "route argument names must be identifiers");
|
||||
span_err(ecx, a.pat.span, "route argument names must be identifiers");
|
||||
false
|
||||
}
|
||||
};
|
||||
|
|
|
@ -121,6 +121,7 @@
|
|||
extern crate syntax;
|
||||
extern crate syntax_ext;
|
||||
extern crate syntax_pos;
|
||||
extern crate rustc_errors;
|
||||
extern crate rustc_plugin;
|
||||
extern crate rocket;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ use syntax::codemap::{Span, Spanned, dummy_spanned};
|
|||
|
||||
use rocket::http::Status;
|
||||
|
||||
use utils::{span, MetaItemExt};
|
||||
use utils::*;
|
||||
use super::Function;
|
||||
|
||||
/// This structure represents the parsed `error` attribute.
|
||||
|
@ -23,21 +23,21 @@ impl ErrorParams {
|
|||
annotated: &Annotatable)
|
||||
-> ErrorParams {
|
||||
let function = Function::from(annotated).unwrap_or_else(|item_sp| {
|
||||
ecx.span_err(sp, "this attribute can only be used on functions...");
|
||||
ecx.span_fatal(item_sp, "...but was applied to the item above.");
|
||||
span_err(ecx, sp, "this attribute can only be used on functions...");
|
||||
span_fatal(ecx, item_sp, "...but was applied to the item above.");
|
||||
});
|
||||
|
||||
let meta_items = meta_item.meta_item_list().unwrap_or_else(|| {
|
||||
ecx.struct_span_fatal(sp, "incorrect use of attribute")
|
||||
struct_span_fatal(ecx, sp, "incorrect use of attribute")
|
||||
.help("attributes in Rocket must have the form: #[name(...)]")
|
||||
.emit();
|
||||
ecx.span_fatal(sp, "malformed attribute");
|
||||
span_fatal(ecx, sp, "malformed attribute");
|
||||
});
|
||||
|
||||
if meta_items.len() < 1 {
|
||||
ecx.span_fatal(sp, "attribute requires the `code` parameter");
|
||||
span_fatal(ecx, sp, "attribute requires the `code` parameter");
|
||||
} else if meta_items.len() > 1 {
|
||||
ecx.span_fatal(sp, "attribute can only have one `code` parameter");
|
||||
span_fatal(ecx, sp, "attribute can only have one `code` parameter");
|
||||
}
|
||||
|
||||
ErrorParams {
|
||||
|
@ -50,7 +50,7 @@ impl ErrorParams {
|
|||
fn parse_code(ecx: &ExtCtxt, meta_item: &NestedMetaItem) -> Spanned<u16> {
|
||||
let code_from_u128 = |n: Spanned<u128>| {
|
||||
if n.node < 400 || n.node > 599 {
|
||||
ecx.span_err(n.span, "code must be >= 400 and <= 599.");
|
||||
span_err(ecx, n.span, "code must be >= 400 and <= 599.");
|
||||
span(0, n.span)
|
||||
} else if Status::from_code(n.node as u16).is_none() {
|
||||
ecx.span_warn(n.span, "status code is unknown.");
|
||||
|
@ -63,16 +63,16 @@ fn parse_code(ecx: &ExtCtxt, meta_item: &NestedMetaItem) -> Spanned<u16> {
|
|||
let sp = meta_item.span();
|
||||
if let Some((name, lit)) = meta_item.name_value() {
|
||||
if name != &"code" {
|
||||
ecx.span_err(sp, "the first key, if any, must be 'code'");
|
||||
span_err(ecx, sp, "the first key, if any, must be 'code'");
|
||||
} else if let LitKind::Int(n, _) = lit.node {
|
||||
return code_from_u128(span(n, lit.span))
|
||||
} else {
|
||||
ecx.span_err(lit.span, "`code` value must be an integer")
|
||||
span_err(ecx, lit.span, "`code` value must be an integer")
|
||||
}
|
||||
} else if let Some(n) = meta_item.int_lit() {
|
||||
return code_from_u128(span(n, sp))
|
||||
} else {
|
||||
ecx.struct_span_err(sp, r#"expected `code = int` or an integer literal"#)
|
||||
struct_span_err(ecx, sp, r#"expected `code = int` or an integer literal"#)
|
||||
.help(r#"you can specify the code directly as an integer,
|
||||
e.g: #[error(404)], or as a key-value pair,
|
||||
e.g: $[error(code = 404)]"#)
|
||||
|
|
|
@ -2,7 +2,7 @@ use syntax::ast::Ident;
|
|||
use syntax::ext::base::ExtCtxt;
|
||||
use syntax::codemap::{Span, Spanned, BytePos};
|
||||
|
||||
use utils::span;
|
||||
use utils::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Param {
|
||||
|
@ -41,7 +41,7 @@ impl<'s, 'a, 'c> Iterator for ParamIter<'s, 'a, 'c> {
|
|||
|
||||
fn next(&mut self) -> Option<Param> {
|
||||
let err = |ecx: &ExtCtxt, sp: Span, msg: &str| {
|
||||
ecx.span_err(sp, msg);
|
||||
span_err(ecx, sp, msg);
|
||||
None
|
||||
};
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ use syntax::ast::*;
|
|||
use syntax::ext::base::{ExtCtxt, Annotatable};
|
||||
use syntax::codemap::{Span, Spanned, dummy_spanned};
|
||||
|
||||
use utils::{span, MetaItemExt, SpanExt, is_valid_ident};
|
||||
use utils::*;
|
||||
use super::{Function, ParamIter};
|
||||
use super::keyvalue::KVSpanned;
|
||||
use super::uri::validate_uri;
|
||||
|
@ -40,19 +40,19 @@ impl RouteParams {
|
|||
annotated: &Annotatable)
|
||||
-> RouteParams {
|
||||
let function = Function::from(annotated).unwrap_or_else(|item_sp| {
|
||||
ecx.span_err(sp, "this attribute can only be used on functions...");
|
||||
ecx.span_fatal(item_sp, "...but was applied to the item above.");
|
||||
span_err(ecx, sp, "this attribute can only be used on functions...");
|
||||
span_fatal(ecx, item_sp, "...but was applied to the item above.");
|
||||
});
|
||||
|
||||
let meta_items = meta_item.meta_item_list().unwrap_or_else(|| {
|
||||
ecx.struct_span_err(sp, "incorrect use of attribute")
|
||||
struct_span_err(ecx, sp, "incorrect use of attribute")
|
||||
.help("attributes in Rocket must have the form: #[name(...)]")
|
||||
.emit();
|
||||
ecx.span_fatal(sp, "malformed attribute");
|
||||
span_fatal(ecx, sp, "malformed attribute");
|
||||
});
|
||||
|
||||
if meta_items.len() < 1 {
|
||||
ecx.span_fatal(sp, "attribute requires at least 1 parameter");
|
||||
span_fatal(ecx, sp, "attribute requires at least 1 parameter");
|
||||
}
|
||||
|
||||
// Figure out the method. If it is known (i.e, because we're parsing a
|
||||
|
@ -64,10 +64,10 @@ impl RouteParams {
|
|||
};
|
||||
|
||||
if attr_params.len() < 1 {
|
||||
ecx.struct_span_err(sp, "attribute requires at least a path")
|
||||
struct_span_err(ecx, sp, "attribute requires at least a path")
|
||||
.help(r#"example: #[get("/my/path")] or #[get(path = "/hi")]"#)
|
||||
.emit();
|
||||
ecx.span_fatal(sp, "malformed attribute");
|
||||
span_fatal(ecx, sp, "malformed attribute");
|
||||
}
|
||||
|
||||
// Parse the required path and optional query parameters.
|
||||
|
@ -79,7 +79,7 @@ impl RouteParams {
|
|||
for param in &attr_params[1..] {
|
||||
let kv_opt = kv_from_nested(param);
|
||||
if kv_opt.is_none() {
|
||||
ecx.span_err(param.span(), "expected key = value");
|
||||
span_err(ecx, param.span(), "expected key = value");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,7 @@ impl RouteParams {
|
|||
"format" => format = parse_opt(ecx, &kv, parse_format),
|
||||
_ => {
|
||||
let msg = format!("'{}' is not a known parameter", kv.key());
|
||||
ecx.span_err(kv.span, &msg);
|
||||
span_err(ecx, kv.span, &msg);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ impl RouteParams {
|
|||
// Sanity check: `data` should only be used with payload methods.
|
||||
if let Some(ref data_param) = data {
|
||||
if !method.node.supports_payload() {
|
||||
ecx.struct_span_err(data_param.span, "`data` route parameters \
|
||||
struct_span_err(ecx, data_param.span, "`data` route parameters \
|
||||
can only be used with payload supporting methods")
|
||||
.note(&format!("'{}' does not support payloads", method.node))
|
||||
.emit();
|
||||
|
@ -160,9 +160,9 @@ pub fn param_to_ident(ecx: &ExtCtxt, s: Spanned<&str>) -> Option<Spanned<Ident>>
|
|||
return Some(span(Ident::from_str(param), s.span.trim(1)));
|
||||
}
|
||||
|
||||
ecx.span_err(s.span, "parameter name must be alphanumeric");
|
||||
span_err(ecx, s.span, "parameter name must be alphanumeric");
|
||||
} else {
|
||||
ecx.span_err(s.span, "parameters must start with '<' and end with '>'");
|
||||
span_err(ecx, s.span, "parameters must start with '<' and end with '>'");
|
||||
}
|
||||
|
||||
None
|
||||
|
@ -176,12 +176,12 @@ fn parse_method(ecx: &ExtCtxt, meta_item: &NestedMetaItem) -> Spanned<Method> {
|
|||
}
|
||||
} else {
|
||||
let msg = format!("'{}' is not a valid HTTP method.", word.name());
|
||||
ecx.span_err(word.span(), &msg);
|
||||
span_err(ecx, word.span(), &msg);
|
||||
}
|
||||
}
|
||||
|
||||
// Fallthrough. Return default method.
|
||||
ecx.struct_span_err(meta_item.span, "expected a valid HTTP method")
|
||||
struct_span_err(ecx, meta_item.span, "expected a valid HTTP method")
|
||||
.help("valid methods are: GET, PUT, POST, DELETE, PATCH")
|
||||
.emit();
|
||||
|
||||
|
@ -194,16 +194,16 @@ fn parse_path(ecx: &ExtCtxt,
|
|||
let sp = meta_item.span();
|
||||
if let Some((name, lit)) = meta_item.name_value() {
|
||||
if name != &"path" {
|
||||
ecx.span_err(sp, "the first key, if any, must be 'path'");
|
||||
span_err(ecx, sp, "the first key, if any, must be 'path'");
|
||||
} else if let LitKind::Str(ref s, _) = lit.node {
|
||||
return validate_uri(ecx, &s.as_str(), lit.span);
|
||||
} else {
|
||||
ecx.span_err(lit.span, "`path` value must be a string")
|
||||
span_err(ecx, lit.span, "`path` value must be a string")
|
||||
}
|
||||
} else if let Some(s) = meta_item.str_lit() {
|
||||
return validate_uri(ecx, &s.as_str(), sp);
|
||||
} else {
|
||||
ecx.struct_span_err(sp, r#"expected `path = string` or a path string"#)
|
||||
struct_span_err(ecx, sp, r#"expected `path = string` or a path string"#)
|
||||
.help(r#"you can specify the path directly as a string, \
|
||||
e.g: "/hello/world", or as a key-value pair, \
|
||||
e.g: path = "/hello/world" "#)
|
||||
|
@ -229,7 +229,7 @@ fn parse_data(ecx: &ExtCtxt, kv: &KVSpanned<LitKind>) -> Ident {
|
|||
}
|
||||
|
||||
let err_string = r#"`data` value must be a parameter, e.g: "<name>"`"#;
|
||||
ecx.struct_span_fatal(kv.span, err_string)
|
||||
struct_span_fatal(ecx, kv.span, err_string)
|
||||
.help(r#"data, if specified, must be a key-value pair where
|
||||
the key is `data` and the value is a string with a single
|
||||
parameter inside '<' '>'. e.g: data = "<user_form>""#)
|
||||
|
@ -245,10 +245,10 @@ fn parse_rank(ecx: &ExtCtxt, kv: &KVSpanned<LitKind>) -> isize {
|
|||
return n as isize;
|
||||
} else {
|
||||
let msg = format!("rank must be less than or equal to {}", max);
|
||||
ecx.span_err(kv.value.span, msg.as_str());
|
||||
span_err(ecx, kv.value.span, msg.as_str());
|
||||
}
|
||||
} else {
|
||||
ecx.struct_span_err(kv.span, r#"`rank` value must be an int"#)
|
||||
struct_span_err(ecx, kv.span, r#"`rank` value must be an int"#)
|
||||
.help(r#"the rank, if specified, must be a key-value pair where
|
||||
the key is `rank` and the value is an integer.
|
||||
e.g: rank = 1, or e.g: rank = 10"#)
|
||||
|
@ -268,11 +268,11 @@ fn parse_format(ecx: &ExtCtxt, kv: &KVSpanned<LitKind>) -> ContentType {
|
|||
|
||||
return ct;
|
||||
} else {
|
||||
ecx.span_err(kv.value.span, "malformed content-type");
|
||||
span_err(ecx, kv.value.span, "malformed content-type");
|
||||
}
|
||||
}
|
||||
|
||||
ecx.struct_span_err(kv.span, r#"`format` must be a "content/type""#)
|
||||
struct_span_err(ecx, kv.span, r#"`format` must be a "content/type""#)
|
||||
.help(r#"format, if specified, must be a key-value pair where
|
||||
the key is `format` and the value is a string representing the
|
||||
content-type accepted. e.g: format = "application/json""#)
|
||||
|
|
|
@ -4,7 +4,7 @@ use syntax::ext::base::ExtCtxt;
|
|||
|
||||
use rocket::http::uri::URI;
|
||||
use super::route::param_to_ident;
|
||||
use utils::{span, SpanExt, is_valid_ident};
|
||||
use utils::*;
|
||||
|
||||
// We somewhat arbitrarily enforce absolute paths. This is mostly because we
|
||||
// want the initial "/" to represent the mount point. Empty segments are
|
||||
|
@ -14,11 +14,11 @@ use utils::{span, SpanExt, is_valid_ident};
|
|||
fn valid_path(ecx: &ExtCtxt, uri: &URI, sp: Span) -> bool {
|
||||
let cleaned = uri.to_string();
|
||||
if !uri.as_str().starts_with('/') {
|
||||
ecx.struct_span_err(sp, "route paths must be absolute")
|
||||
struct_span_err(ecx, sp, "route paths must be absolute")
|
||||
.note(&format!("expected {:?}, found {:?}", cleaned, uri.as_str()))
|
||||
.emit()
|
||||
} else if cleaned != uri.as_str() {
|
||||
ecx.struct_span_err(sp, "paths cannot contain empty segments")
|
||||
struct_span_err(ecx, sp, "paths cannot contain empty segments")
|
||||
.note(&format!("expected {:?}, found {:?}", cleaned, uri.as_str()))
|
||||
.emit()
|
||||
} else {
|
||||
|
@ -39,7 +39,7 @@ fn valid_segments(ecx: &ExtCtxt, uri: &URI, sp: Span) -> bool {
|
|||
// If we're iterating after a '..' param, that's a hard error.
|
||||
if let Some(span) = segments_span {
|
||||
let rem_sp = sp.trim_left(index).trim_right(1);
|
||||
ecx.struct_span_err(rem_sp, "text after a trailing '..' param")
|
||||
struct_span_err(ecx, rem_sp, "text after a trailing '..' param")
|
||||
.help("a segments param must be the final text in a path")
|
||||
.span_note(span, "trailing param is here")
|
||||
.emit();
|
||||
|
@ -55,13 +55,13 @@ fn valid_segments(ecx: &ExtCtxt, uri: &URI, sp: Span) -> bool {
|
|||
}
|
||||
|
||||
if param.is_empty() {
|
||||
ecx.span_err(span, "parameters cannot be empty");
|
||||
span_err(ecx, span, "parameters cannot be empty");
|
||||
} else if !is_valid_ident(param) {
|
||||
ecx.struct_span_err(span, "parameter names must be valid identifiers")
|
||||
struct_span_err(ecx, span, "parameter names must be valid identifiers")
|
||||
.note(&format!("{:?} is not a valid identifier", param))
|
||||
.emit();
|
||||
} else if param.starts_with('_') {
|
||||
ecx.struct_span_err(span, "parameters cannot be ignored")
|
||||
struct_span_err(ecx, span, "parameters cannot be ignored")
|
||||
.note(&format!("{:?} is being ignored", param))
|
||||
.emit();
|
||||
} else {
|
||||
|
@ -71,11 +71,11 @@ fn valid_segments(ecx: &ExtCtxt, uri: &URI, sp: Span) -> bool {
|
|||
validated = false;
|
||||
} else if segment.starts_with("<") {
|
||||
if segment[1..].contains("<") || segment.contains(">") {
|
||||
ecx.struct_span_err(span, "malformed parameter")
|
||||
struct_span_err(ecx, span, "malformed parameter")
|
||||
.help("parameters must be of the form '<param>'")
|
||||
.emit();
|
||||
} else {
|
||||
ecx.struct_span_err(span, "parameter is missing a closing bracket")
|
||||
struct_span_err(ecx, span, "parameter is missing a closing bracket")
|
||||
.help(&format!("perhaps you meant '{}>'?", segment))
|
||||
.emit();
|
||||
}
|
||||
|
@ -83,11 +83,11 @@ fn valid_segments(ecx: &ExtCtxt, uri: &URI, sp: Span) -> bool {
|
|||
validated = false;
|
||||
} else if URI::percent_encode(segment) != segment {
|
||||
if segment.contains("<") || segment.contains(">") {
|
||||
ecx.struct_span_err(span, "malformed parameter")
|
||||
struct_span_err(ecx, span, "malformed parameter")
|
||||
.help("parameters must be of the form '<param>'")
|
||||
.emit();
|
||||
} else {
|
||||
ecx.span_err(span, "segment contains invalid characters");
|
||||
span_err(ecx, span, "segment contains invalid characters");
|
||||
}
|
||||
|
||||
validated = false;
|
||||
|
|
|
@ -10,6 +10,8 @@ pub use self::parser_ext::ParserExt;
|
|||
pub use self::ident_ext::IdentExt;
|
||||
pub use self::span_ext::SpanExt;
|
||||
|
||||
use rustc_errors::DiagnosticBuilder;
|
||||
|
||||
use std::convert::AsRef;
|
||||
|
||||
use syntax;
|
||||
|
@ -43,6 +45,22 @@ pub fn sep_by_tok<T>(ecx: &ExtCtxt, things: &[T], token: Token) -> Vec<TokenTree
|
|||
output
|
||||
}
|
||||
|
||||
pub fn struct_span_err<'cx>(cx: &'cx ExtCtxt, sp: Span, error: &str) -> DiagnosticBuilder<'cx> {
|
||||
cx.struct_span_err(sp, &format!("😭 {}", error))
|
||||
}
|
||||
|
||||
pub fn struct_span_fatal<'cx>(cx: &'cx ExtCtxt, sp: Span, error: &str) -> DiagnosticBuilder<'cx> {
|
||||
cx.struct_span_err(sp, &format!("💀 {}", error))
|
||||
}
|
||||
|
||||
pub fn span_err(cx: &ExtCtxt, sp: Span, error: &str) {
|
||||
cx.span_err(sp, &format!("😭 {}", error))
|
||||
}
|
||||
|
||||
pub fn span_fatal(cx: &ExtCtxt, sp: Span, error: &str) -> ! {
|
||||
cx.span_fatal(sp, &format!("💀 {}", error))
|
||||
}
|
||||
|
||||
pub fn option_as_expr<T: ToTokens>(ecx: &ExtCtxt, opt: &Option<T>) -> P<Expr> {
|
||||
match *opt {
|
||||
Some(ref item) => quote_expr!(ecx, Some($item)),
|
||||
|
|
Loading…
Reference in New Issue