diff options
Diffstat (limited to 'vendor/pest_meta/src/validator.rs')
-rw-r--r-- | vendor/pest_meta/src/validator.rs | 222 |
1 files changed, 88 insertions, 134 deletions
diff --git a/vendor/pest_meta/src/validator.rs b/vendor/pest_meta/src/validator.rs index a358dbeec..5448c3bcd 100644 --- a/vendor/pest_meta/src/validator.rs +++ b/vendor/pest_meta/src/validator.rs @@ -7,105 +7,67 @@ // option. All files in the project carrying such notice may not be copied, // modified, or distributed except according to those terms. +use once_cell::sync::Lazy; use std::collections::{HashMap, HashSet}; use pest::error::{Error, ErrorVariant, InputLocation}; use pest::iterators::Pairs; use pest::Span; -use parser::{ParserExpr, ParserNode, ParserRule, Rule}; -use UNICODE_PROPERTY_NAMES; - -#[allow(clippy::needless_pass_by_value)] -pub fn validate_pairs<'i>(pairs: Pairs<'i, Rule>) -> Result<Vec<&'i str>, Vec<Error<Rule>>> { - let mut rust_keywords = HashSet::new(); - rust_keywords.insert("abstract"); - rust_keywords.insert("alignof"); - rust_keywords.insert("as"); - rust_keywords.insert("become"); - rust_keywords.insert("box"); - rust_keywords.insert("break"); - rust_keywords.insert("const"); - rust_keywords.insert("continue"); - rust_keywords.insert("crate"); - rust_keywords.insert("do"); - rust_keywords.insert("else"); - rust_keywords.insert("enum"); - rust_keywords.insert("extern"); - rust_keywords.insert("false"); - rust_keywords.insert("final"); - rust_keywords.insert("fn"); - rust_keywords.insert("for"); - rust_keywords.insert("if"); - rust_keywords.insert("impl"); - rust_keywords.insert("in"); - rust_keywords.insert("let"); - rust_keywords.insert("loop"); - rust_keywords.insert("macro"); - rust_keywords.insert("match"); - rust_keywords.insert("mod"); - rust_keywords.insert("move"); - rust_keywords.insert("mut"); - rust_keywords.insert("offsetof"); - rust_keywords.insert("override"); - rust_keywords.insert("priv"); - rust_keywords.insert("proc"); - rust_keywords.insert("pure"); - rust_keywords.insert("pub"); - rust_keywords.insert("ref"); - rust_keywords.insert("return"); - rust_keywords.insert("Self"); - rust_keywords.insert("self"); - rust_keywords.insert("sizeof"); - rust_keywords.insert("static"); - rust_keywords.insert("struct"); - rust_keywords.insert("super"); - rust_keywords.insert("trait"); - rust_keywords.insert("true"); - rust_keywords.insert("type"); - rust_keywords.insert("typeof"); - rust_keywords.insert("unsafe"); - rust_keywords.insert("unsized"); - rust_keywords.insert("use"); - rust_keywords.insert("virtual"); - rust_keywords.insert("where"); - rust_keywords.insert("while"); - rust_keywords.insert("yield"); - - let mut pest_keywords = HashSet::new(); - pest_keywords.insert("_"); - pest_keywords.insert("ANY"); - pest_keywords.insert("DROP"); - pest_keywords.insert("EOI"); - pest_keywords.insert("PEEK"); - pest_keywords.insert("PEEK_ALL"); - pest_keywords.insert("POP"); - pest_keywords.insert("POP_ALL"); - pest_keywords.insert("PUSH"); - pest_keywords.insert("SOI"); - - let mut builtins = HashSet::new(); - builtins.insert("ANY"); - builtins.insert("DROP"); - builtins.insert("EOI"); - builtins.insert("PEEK"); - builtins.insert("PEEK_ALL"); - builtins.insert("POP"); - builtins.insert("POP_ALL"); - builtins.insert("SOI"); - builtins.insert("ASCII_DIGIT"); - builtins.insert("ASCII_NONZERO_DIGIT"); - builtins.insert("ASCII_BIN_DIGIT"); - builtins.insert("ASCII_OCT_DIGIT"); - builtins.insert("ASCII_HEX_DIGIT"); - builtins.insert("ASCII_ALPHA_LOWER"); - builtins.insert("ASCII_ALPHA_UPPER"); - builtins.insert("ASCII_ALPHA"); - builtins.insert("ASCII_ALPHANUMERIC"); - builtins.insert("ASCII"); - builtins.insert("NEWLINE"); - builtins.extend(UNICODE_PROPERTY_NAMES); - +use crate::parser::{ParserExpr, ParserNode, ParserRule, Rule}; +use crate::UNICODE_PROPERTY_NAMES; + +static RUST_KEYWORDS: Lazy<HashSet<&'static str>> = Lazy::new(|| { + [ + "abstract", "alignof", "as", "become", "box", "break", "const", "continue", "crate", "do", + "else", "enum", "extern", "false", "final", "fn", "for", "if", "impl", "in", "let", "loop", + "macro", "match", "mod", "move", "mut", "offsetof", "override", "priv", "proc", "pure", + "pub", "ref", "return", "Self", "self", "sizeof", "static", "struct", "super", "trait", + "true", "type", "typeof", "unsafe", "unsized", "use", "virtual", "where", "while", "yield", + ] + .iter() + .cloned() + .collect() +}); + +static PEST_KEYWORDS: Lazy<HashSet<&'static str>> = Lazy::new(|| { + [ + "_", "ANY", "DROP", "EOI", "PEEK", "PEEK_ALL", "POP", "POP_ALL", "PUSH", "SOI", + ] + .iter() + .cloned() + .collect() +}); + +static BUILTINS: Lazy<HashSet<&'static str>> = Lazy::new(|| { + [ + "ANY", + "DROP", + "EOI", + "PEEK", + "PEEK_ALL", + "POP", + "POP_ALL", + "SOI", + "ASCII_DIGIT", + "ASCII_NONZERO_DIGIT", + "ASCII_BIN_DIGIT", + "ASCII_OCT_DIGIT", + "ASCII_HEX_DIGIT", + "ASCII_ALPHA_LOWER", + "ASCII_ALPHA_UPPER", + "ASCII_ALPHA", + "ASCII_ALPHANUMERIC", + "ASCII", + "NEWLINE", + ] + .iter() + .cloned() + .chain(UNICODE_PROPERTY_NAMES.iter().cloned()) + .collect::<HashSet<&str>>() +}); + +pub fn validate_pairs(pairs: Pairs<Rule>) -> Result<Vec<&str>, Vec<Error<Rule>>> { let definitions: Vec<_> = pairs .clone() .filter(|pair| pair.as_rule() == Rule::grammar_rule) @@ -125,10 +87,10 @@ pub fn validate_pairs<'i>(pairs: Pairs<'i, Rule>) -> Result<Vec<&'i str>, Vec<Er let mut errors = vec![]; - errors.extend(validate_rust_keywords(&definitions, &rust_keywords)); - errors.extend(validate_pest_keywords(&definitions, &pest_keywords)); + errors.extend(validate_rust_keywords(&definitions)); + errors.extend(validate_pest_keywords(&definitions)); errors.extend(validate_already_defined(&definitions)); - errors.extend(validate_undefined(&definitions, &called_rules, &builtins)); + errors.extend(validate_undefined(&definitions, &called_rules)); if !errors.is_empty() { return Err(errors); @@ -142,22 +104,19 @@ pub fn validate_pairs<'i>(pairs: Pairs<'i, Rule>) -> Result<Vec<&'i str>, Vec<Er Ok(defaults.cloned().collect()) } -#[allow(clippy::implicit_hasher, clippy::ptr_arg)] -pub fn validate_rust_keywords<'i>( - definitions: &Vec<Span<'i>>, - rust_keywords: &HashSet<&str>, -) -> Vec<Error<Rule>> { +#[allow(clippy::ptr_arg)] +pub fn validate_rust_keywords(definitions: &Vec<Span>) -> Vec<Error<Rule>> { let mut errors = vec![]; for definition in definitions { let name = definition.as_str(); - if rust_keywords.contains(name) { + if RUST_KEYWORDS.contains(name) { errors.push(Error::new_from_span( ErrorVariant::CustomError { message: format!("{} is a rust keyword", name), }, - definition.clone(), + *definition, )) } } @@ -165,22 +124,19 @@ pub fn validate_rust_keywords<'i>( errors } -#[allow(clippy::implicit_hasher, clippy::ptr_arg)] -pub fn validate_pest_keywords<'i>( - definitions: &Vec<Span<'i>>, - pest_keywords: &HashSet<&str>, -) -> Vec<Error<Rule>> { +#[allow(clippy::ptr_arg)] +pub fn validate_pest_keywords(definitions: &Vec<Span>) -> Vec<Error<Rule>> { let mut errors = vec![]; for definition in definitions { let name = definition.as_str(); - if pest_keywords.contains(name) { + if PEST_KEYWORDS.contains(name) { errors.push(Error::new_from_span( ErrorVariant::CustomError { message: format!("{} is a pest keyword", name), }, - definition.clone(), + *definition, )) } } @@ -189,7 +145,7 @@ pub fn validate_pest_keywords<'i>( } #[allow(clippy::ptr_arg)] -pub fn validate_already_defined<'i>(definitions: &Vec<Span<'i>>) -> Vec<Error<Rule>> { +pub fn validate_already_defined(definitions: &Vec<Span>) -> Vec<Error<Rule>> { let mut errors = vec![]; let mut defined = HashSet::new(); @@ -201,7 +157,7 @@ pub fn validate_already_defined<'i>(definitions: &Vec<Span<'i>>) -> Vec<Error<Ru ErrorVariant::CustomError { message: format!("rule {} already defined", name), }, - definition.clone(), + *definition, )) } else { defined.insert(name); @@ -211,11 +167,10 @@ pub fn validate_already_defined<'i>(definitions: &Vec<Span<'i>>) -> Vec<Error<Ru errors } -#[allow(clippy::implicit_hasher, clippy::ptr_arg)] +#[allow(clippy::ptr_arg)] pub fn validate_undefined<'i>( definitions: &Vec<Span<'i>>, called_rules: &Vec<Span<'i>>, - builtins: &HashSet<&str>, ) -> Vec<Error<Rule>> { let mut errors = vec![]; let definitions: HashSet<_> = definitions.iter().map(|span| span.as_str()).collect(); @@ -223,12 +178,12 @@ pub fn validate_undefined<'i>( for rule in called_rules { let name = rule.as_str(); - if !definitions.contains(name) && !builtins.contains(name) { + if !definitions.contains(name) && !BUILTINS.contains(name) { errors.push(Error::new_from_span( ErrorVariant::CustomError { message: format!("rule {} is undefined", name), }, - rule.clone(), + *rule, )) } } @@ -259,7 +214,7 @@ fn is_non_progressing<'i>( trace: &mut Vec<String>, ) -> bool { match *expr { - ParserExpr::Str(ref string) => string == "", + ParserExpr::Str(ref string) => string.is_empty(), ParserExpr::Ident(ref ident) => { if ident == "soi" || ident == "eoi" { return true; @@ -297,7 +252,7 @@ fn is_non_failing<'i>( trace: &mut Vec<String>, ) -> bool { match *expr { - ParserExpr::Str(ref string) => string == "", + ParserExpr::Str(ref string) => string.is_empty(), ParserExpr::Ident(ref ident) => { if !trace.contains(ident) { if let Some(node) = rules.get(ident) { @@ -342,7 +297,7 @@ fn validate_repetition<'a, 'i: 'a>(rules: &'a [ParserRule<'i>]) -> Vec<Error<Rul infinitely" .to_owned() }, - node.span.clone() + node.span )) } else if is_non_progressing(&other.expr, &map, &mut vec![]) { Some(Error::new_from_span( @@ -352,7 +307,7 @@ fn validate_repetition<'a, 'i: 'a>(rules: &'a [ParserRule<'i>]) -> Vec<Error<Rul infinitely" .to_owned(), }, - node.span.clone() + node.span )) } else { None @@ -389,7 +344,7 @@ fn validate_choices<'a, 'i: 'a>(rules: &'a [ParserRule<'i>]) -> Vec<Error<Rule>> "expression cannot fail; following choices cannot be reached" .to_owned(), }, - node.span.clone(), + node.span, )) } else { None @@ -419,7 +374,7 @@ fn validate_whitespace_comment<'a, 'i: 'a>(rules: &'a [ParserRule<'i>]) -> Vec<E &rule.name ), }, - rule.node.span.clone(), + rule.node.span, )) } else if is_non_progressing(&rule.node.expr, &map, &mut vec![]) { Some(Error::new_from_span( @@ -429,7 +384,7 @@ fn validate_whitespace_comment<'a, 'i: 'a>(rules: &'a [ParserRule<'i>]) -> Vec<E &rule.name ), }, - rule.node.span.clone(), + rule.node.span, )) } else { None @@ -449,7 +404,6 @@ fn to_hash_map<'a, 'i: 'a>(rules: &'a [ParserRule<'i>]) -> HashMap<String, &'a P rules.iter().map(|r| (r.name.clone(), &r.node)).collect() } -#[allow(clippy::needless_pass_by_value)] fn left_recursion<'a, 'i: 'a>(rules: HashMap<String, &'a ParserNode<'i>>) -> Vec<Error<Rule>> { fn check_expr<'a, 'i: 'a>( node: &'a ParserNode<'i>, @@ -475,7 +429,7 @@ fn left_recursion<'a, 'i: 'a>(rules: HashMap<String, &'a ParserNode<'i>>) -> Vec chain ) }, - node.span.clone() + node.span )); } @@ -499,22 +453,22 @@ fn left_recursion<'a, 'i: 'a>(rules: HashMap<String, &'a ParserNode<'i>>) -> Vec } } ParserExpr::Choice(ref lhs, ref rhs) => { - check_expr(&lhs, rules, trace).or_else(|| check_expr(&rhs, rules, trace)) + check_expr(lhs, rules, trace).or_else(|| check_expr(rhs, rules, trace)) } - ParserExpr::Rep(ref node) => check_expr(&node, rules, trace), - ParserExpr::RepOnce(ref node) => check_expr(&node, rules, trace), - ParserExpr::Opt(ref node) => check_expr(&node, rules, trace), - ParserExpr::PosPred(ref node) => check_expr(&node, rules, trace), - ParserExpr::NegPred(ref node) => check_expr(&node, rules, trace), - ParserExpr::Push(ref node) => check_expr(&node, rules, trace), + ParserExpr::Rep(ref node) => check_expr(node, rules, trace), + ParserExpr::RepOnce(ref node) => check_expr(node, rules, trace), + ParserExpr::Opt(ref node) => check_expr(node, rules, trace), + ParserExpr::PosPred(ref node) => check_expr(node, rules, trace), + ParserExpr::NegPred(ref node) => check_expr(node, rules, trace), + ParserExpr::Push(ref node) => check_expr(node, rules, trace), _ => None, } } let mut errors = vec![]; - for (ref name, ref node) in &rules { - let name = (*name).clone(); + for (name, node) in &rules { + let name = name.clone(); if let Some(error) = check_expr(node, &rules, &mut vec![name]) { errors.push(error); |