diff --git a/Configurations.md b/Configurations.md index edb2d1f7575..8c84614352c 100644 --- a/Configurations.md +++ b/Configurations.md @@ -1473,26 +1473,6 @@ use core::slice; #[cfg(feature = "alloc")] use core::slice; ``` -## `license_template_path` - -Check whether beginnings of files match a license template. - -- **Default value**: `""` -- **Possible values**: path to a license template file -- **Stable**: No (tracking issue: [#3352](https://github.com/rust-lang/rustfmt/issues/3352)) - -A license template is a plain text file which is matched literally against the -beginning of each source file, except for `{}`-delimited blocks, which are -matched as regular expressions. The following license template therefore -matches strings like `// Copyright 2017 The Rust Project Developers.`, `// -Copyright 2018 The Rust Project Developers.`, etc.: - -``` -// Copyright {\d+} The Rust Project Developers. -``` - -`\{`, `\}` and `\\` match literal braces / backslashes. - ## `match_arm_blocks` Controls whether arm bodies are wrapped in cases where the first line of the body cannot fit on the same line as the `=>` operator. diff --git a/src/config/config_type.rs b/src/config/config_type.rs index 7fc4486ddcd..e37ed798cb5 100644 --- a/src/config/config_type.rs +++ b/src/config/config_type.rs @@ -61,9 +61,6 @@ macro_rules! create_config { #[derive(Clone)] #[allow(unreachable_pub)] pub struct Config { - // if a license_template_path has been specified, successfully read, parsed and compiled - // into a regex, it will be stored here - pub license_template: Option, // For each config item, we store a bool indicating whether it has // been accessed and the value, and a bool whether the option was // manually initialised, or taken from the default, @@ -104,7 +101,6 @@ macro_rules! create_config { | "struct_variant_width" | "array_width" | "chain_width" => self.0.set_heuristics(), - "license_template_path" => self.0.set_license_template(), "merge_imports" => self.0.set_merge_imports(), &_ => (), } @@ -163,7 +159,6 @@ macro_rules! create_config { } )+ self.set_heuristics(); - self.set_license_template(); self.set_ignore(dir); self.set_merge_imports(); self @@ -247,7 +242,6 @@ macro_rules! create_config { | "struct_variant_width" | "array_width" | "chain_width" => self.set_heuristics(), - "license_template_path" => self.set_license_template(), "merge_imports" => self.set_merge_imports(), &_ => (), } @@ -386,21 +380,6 @@ macro_rules! create_config { }; } - fn set_license_template(&mut self) { - if self.was_set().license_template_path() { - let lt_path = self.license_template_path(); - if lt_path.len() > 0 { - match license::load_and_compile_template(<_path) { - Ok(re) => self.license_template = Some(re), - Err(msg) => eprintln!("Warning for license template file {:?}: {}", - lt_path, msg), - } - } else { - self.license_template = None; - } - } - } - fn set_ignore(&mut self, dir: &Path) { self.ignore.2.add_prefix(dir); } @@ -437,7 +416,6 @@ macro_rules! create_config { impl Default for Config { fn default() -> Config { Config { - license_template: None, $( $i: (Cell::new(false), false, $def, $stb), )+ diff --git a/src/config/license.rs b/src/config/license.rs deleted file mode 100644 index c7feb502ea9..00000000000 --- a/src/config/license.rs +++ /dev/null @@ -1,265 +0,0 @@ -use std::fmt; -use std::fs::File; -use std::io; -use std::io::Read; - -use regex::Regex; - -#[derive(Debug)] -pub(crate) enum LicenseError { - IO(io::Error), - Regex(regex::Error), - Parse(String), -} - -impl fmt::Display for LicenseError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { - LicenseError::IO(ref err) => err.fmt(f), - LicenseError::Regex(ref err) => err.fmt(f), - LicenseError::Parse(ref err) => write!(f, "parsing failed, {}", err), - } - } -} - -impl From for LicenseError { - fn from(err: io::Error) -> LicenseError { - LicenseError::IO(err) - } -} - -impl From for LicenseError { - fn from(err: regex::Error) -> LicenseError { - LicenseError::Regex(err) - } -} - -// the template is parsed using a state machine -enum ParsingState { - Lit, - LitEsc, - // the u32 keeps track of brace nesting - Re(u32), - ReEsc(u32), - Abort(String), -} - -use self::ParsingState::*; - -pub(crate) struct TemplateParser { - parsed: String, - buffer: String, - state: ParsingState, - linum: u32, - open_brace_line: u32, -} - -impl TemplateParser { - fn new() -> Self { - Self { - parsed: "^".to_owned(), - buffer: String::new(), - state: Lit, - linum: 1, - // keeps track of last line on which a regex placeholder was started - open_brace_line: 0, - } - } - - /// Converts a license template into a string which can be turned into a regex. - /// - /// The license template could use regex syntax directly, but that would require a lot of manual - /// escaping, which is inconvenient. It is therefore literal by default, with optional regex - /// subparts delimited by `{` and `}`. Additionally: - /// - /// - to insert literal `{`, `}` or `\`, escape it with `\` - /// - an empty regex placeholder (`{}`) is shorthand for `{.*?}` - /// - /// This function parses this input format and builds a properly escaped *string* representation - /// of the equivalent regular expression. It **does not** however guarantee that the returned - /// string is a syntactically valid regular expression. - /// - /// # Examples - /// - /// ```text - /// assert_eq!( - /// TemplateParser::parse( - /// r" - /// // Copyright {\d+} The \} Rust \\ Project \{ Developers. See the {([A-Z]+)} - /// // file at the top-level directory of this distribution and at - /// // {}. - /// // - /// // 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. - /// " - /// ).unwrap(), - /// r"^ - /// // Copyright \d+ The \} Rust \\ Project \{ Developers\. See the ([A-Z]+) - /// // file at the top\-level directory of this distribution and at - /// // .*?\. - /// // - /// // 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\. - /// " - /// ); - /// ``` - pub(crate) fn parse(template: &str) -> Result { - let mut parser = Self::new(); - for chr in template.chars() { - if chr == '\n' { - parser.linum += 1; - } - parser.state = match parser.state { - Lit => parser.trans_from_lit(chr), - LitEsc => parser.trans_from_litesc(chr), - Re(brace_nesting) => parser.trans_from_re(chr, brace_nesting), - ReEsc(brace_nesting) => parser.trans_from_reesc(chr, brace_nesting), - Abort(msg) => return Err(LicenseError::Parse(msg)), - }; - } - // check if we've ended parsing in a valid state - match parser.state { - Abort(msg) => return Err(LicenseError::Parse(msg)), - Re(_) | ReEsc(_) => { - return Err(LicenseError::Parse(format!( - "escape or balance opening brace on l. {}", - parser.open_brace_line - ))); - } - LitEsc => { - return Err(LicenseError::Parse(format!( - "incomplete escape sequence on l. {}", - parser.linum - ))); - } - _ => (), - } - parser.parsed.push_str(®ex::escape(&parser.buffer)); - - Ok(parser.parsed) - } - - fn trans_from_lit(&mut self, chr: char) -> ParsingState { - match chr { - '{' => { - self.parsed.push_str(®ex::escape(&self.buffer)); - self.buffer.clear(); - self.open_brace_line = self.linum; - Re(1) - } - '}' => Abort(format!( - "escape or balance closing brace on l. {}", - self.linum - )), - '\\' => LitEsc, - _ => { - self.buffer.push(chr); - Lit - } - } - } - - fn trans_from_litesc(&mut self, chr: char) -> ParsingState { - self.buffer.push(chr); - Lit - } - - fn trans_from_re(&mut self, chr: char, brace_nesting: u32) -> ParsingState { - match chr { - '{' => { - self.buffer.push(chr); - Re(brace_nesting + 1) - } - '}' => { - match brace_nesting { - 1 => { - // default regex for empty placeholder {} - if self.buffer.is_empty() { - self.parsed.push_str(".*?"); - } else { - self.parsed.push_str(&self.buffer); - } - self.buffer.clear(); - Lit - } - _ => { - self.buffer.push(chr); - Re(brace_nesting - 1) - } - } - } - '\\' => { - self.buffer.push(chr); - ReEsc(brace_nesting) - } - _ => { - self.buffer.push(chr); - Re(brace_nesting) - } - } - } - - fn trans_from_reesc(&mut self, chr: char, brace_nesting: u32) -> ParsingState { - self.buffer.push(chr); - Re(brace_nesting) - } -} - -pub(crate) fn load_and_compile_template(path: &str) -> Result { - let mut lt_file = File::open(&path)?; - let mut lt_str = String::new(); - lt_file.read_to_string(&mut lt_str)?; - let lt_parsed = TemplateParser::parse(<_str)?; - Ok(Regex::new(<_parsed)?) -} - -#[cfg(test)] -mod test { - use super::TemplateParser; - - #[test] - fn test_parse_license_template() { - assert_eq!( - TemplateParser::parse("literal (.*)").unwrap(), - r"^literal \(\.\*\)" - ); - assert_eq!( - TemplateParser::parse(r"escaping \}").unwrap(), - r"^escaping \}" - ); - assert!(TemplateParser::parse("unbalanced } without escape").is_err()); - assert_eq!( - TemplateParser::parse(r"{\d+} place{-?}holder{s?}").unwrap(), - r"^\d+ place-?holders?" - ); - assert_eq!(TemplateParser::parse("default {}").unwrap(), "^default .*?"); - assert_eq!( - TemplateParser::parse(r"unbalanced nested braces {\{{3}}").unwrap(), - r"^unbalanced nested braces \{{3}" - ); - assert_eq!( - &TemplateParser::parse("parsing error }") - .unwrap_err() - .to_string(), - "parsing failed, escape or balance closing brace on l. 1" - ); - assert_eq!( - &TemplateParser::parse("parsing error {\nsecond line") - .unwrap_err() - .to_string(), - "parsing failed, escape or balance opening brace on l. 1" - ); - assert_eq!( - &TemplateParser::parse(r"parsing error \") - .unwrap_err() - .to_string(), - "parsing failed, incomplete escape sequence on l. 1" - ); - } -} diff --git a/src/config/mod.rs b/src/config/mod.rs index fc724beae60..a5169528187 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -5,7 +5,6 @@ use std::io::{Error, ErrorKind, Read}; use std::path::{Path, PathBuf}; use std::{env, fs}; -use regex::Regex; use thiserror::Error; use crate::config::config_type::ConfigType; @@ -22,7 +21,6 @@ pub(crate) mod config_type; pub(crate) mod options; pub(crate) mod file_lines; -pub(crate) mod license; pub(crate) mod lists; // This macro defines configuration options used in rustfmt. Each option @@ -63,8 +61,6 @@ create_config! { "Maximum length of comments. No effect unless wrap_comments = true"; normalize_comments: bool, false, false, "Convert /* */ comments to // comments where possible"; normalize_doc_attributes: bool, false, false, "Normalize doc attributes as doc comments"; - license_template_path: String, String::default(), false, - "Beginning of file must match license template"; format_strings: bool, false, false, "Format string literals where necessary"; format_macro_matchers: bool, false, false, "Format the metavariable matching patterns in macros"; @@ -414,8 +410,6 @@ mod test { create_config! { // Options that are used by the generated functions max_width: usize, 100, true, "Maximum width of each line"; - license_template_path: String, String::default(), false, - "Beginning of file must match license template"; required_version: String, env!("CARGO_PKG_VERSION").to_owned(), false, "Require a specific version of rustfmt."; ignore: IgnoreList, IgnoreList::default(), false, @@ -520,31 +514,6 @@ mod test { assert_eq!(s.contains("(unstable)"), true); } - #[test] - fn test_empty_string_license_template_path() { - let toml = r#"license_template_path = """#; - let config = Config::from_toml(toml, Path::new("")).unwrap(); - assert!(config.license_template.is_none()); - } - - #[nightly_only_test] - #[test] - fn test_valid_license_template_path() { - let toml = r#"license_template_path = "tests/license-template/lt.txt""#; - let config = Config::from_toml(toml, Path::new("")).unwrap(); - assert!(config.license_template.is_some()); - } - - #[nightly_only_test] - #[test] - fn test_override_existing_license_with_no_license() { - let toml = r#"license_template_path = "tests/license-template/lt.txt""#; - let mut config = Config::from_toml(toml, Path::new("")).unwrap(); - assert!(config.license_template.is_some()); - config.override_value("license_template_path", ""); - assert!(config.license_template.is_none()); - } - #[test] fn test_dump_default_config() { let default_config = format!( @@ -566,7 +535,6 @@ format_code_in_doc_comments = false comment_width = 80 normalize_comments = false normalize_doc_attributes = false -license_template_path = "" format_strings = false format_macro_matchers = false format_macro_bodies = true diff --git a/src/format_report_formatter.rs b/src/format_report_formatter.rs index 9809f72f5ae..fd536d4df41 100644 --- a/src/format_report_formatter.rs +++ b/src/format_report_formatter.rs @@ -142,7 +142,6 @@ fn error_kind_to_snippet_annotation_type(error_kind: &ErrorKind) -> AnnotationTy | ErrorKind::ModuleResolutionError(_) | ErrorKind::ParseError | ErrorKind::LostComment - | ErrorKind::LicenseCheck | ErrorKind::BadAttr | ErrorKind::InvalidGlobPattern(_) | ErrorKind::VersionMismatch => AnnotationType::Error, diff --git a/src/formatting.rs b/src/formatting.rs index 869c6db647d..e6995210a94 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -332,8 +332,7 @@ impl FormattingError { ErrorKind::TrailingWhitespace | ErrorKind::DeprecatedAttr | ErrorKind::BadAttr - | ErrorKind::LostComment - | ErrorKind::LicenseCheck => { + | ErrorKind::LostComment => { let trailing_ws_start = self .line_buffer .rfind(|c: char| !c.is_whitespace()) @@ -365,7 +364,7 @@ pub(crate) struct ReportedErrors { // Code contains macro call that was unable to format. pub(crate) has_macro_format_failure: bool, - // Failed a check, such as the license check or other opt-in checking. + // Failed an opt-in checking. pub(crate) has_check_errors: bool, /// Formatted code differs from existing code (--check only). @@ -461,7 +460,6 @@ fn format_lines( report: &FormatReport, ) { let mut formatter = FormatLines::new(name, skipped_range, config); - formatter.check_license(text); formatter.iterate(text); if formatter.newline_count > 1 { @@ -508,20 +506,6 @@ impl<'a> FormatLines<'a> { } } - fn check_license(&mut self, text: &mut String) { - if let Some(ref license_template) = self.config.license_template { - if !license_template.is_match(text) { - self.errors.push(FormattingError { - line: self.cur_line, - kind: ErrorKind::LicenseCheck, - is_comment: false, - is_string: false, - line_buffer: String::new(), - }); - } - } - } - // Iterate over the chars in the file map. fn iterate(&mut self, text: &mut String) { for (kind, c) in CharClasses::new(text.chars()) { diff --git a/src/lib.rs b/src/lib.rs index f46a6914dd8..495010a297d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -108,9 +108,6 @@ pub enum ErrorKind { /// Line ends in whitespace. #[error("left behind trailing whitespace")] TrailingWhitespace, - /// License check has failed. - #[error("license check failed")] - LicenseCheck, /// Used deprecated skip attribute. #[error("`rustfmt_skip` is deprecated; use `rustfmt::skip`")] DeprecatedAttr, @@ -231,10 +228,7 @@ impl FormatReport { ErrorKind::LostComment => { errs.has_unformatted_code_errors = true; } - ErrorKind::LicenseCheck - | ErrorKind::DeprecatedAttr - | ErrorKind::BadAttr - | ErrorKind::VersionMismatch => { + ErrorKind::DeprecatedAttr | ErrorKind::BadAttr | ErrorKind::VersionMismatch => { errs.has_check_errors = true; } _ => {} diff --git a/tests/config/issue-3802.toml b/tests/config/issue-3802.toml deleted file mode 100644 index 74ee8b010dd..00000000000 --- a/tests/config/issue-3802.toml +++ /dev/null @@ -1,2 +0,0 @@ -unstable_features = true -license_template_path = "" diff --git a/tests/license-template/lt.txt b/tests/license-template/lt.txt deleted file mode 100644 index ea4390371a0..00000000000 --- a/tests/license-template/lt.txt +++ /dev/null @@ -1,2 +0,0 @@ -// rustfmt-license_template_path: tests/license-template/lt.txt -// Copyright {\d+} The rustfmt developers. diff --git a/tests/source/license-templates/empty_license_path.rs b/tests/source/license-templates/empty_license_path.rs deleted file mode 100644 index d3a91e4231d..00000000000 --- a/tests/source/license-templates/empty_license_path.rs +++ /dev/null @@ -1,5 +0,0 @@ -// rustfmt-config: issue-3802.toml - -fn main() { -println!("Hello world!"); -} diff --git a/tests/source/license-templates/license.rs b/tests/source/license-templates/license.rs deleted file mode 100644 index 6816011c60d..00000000000 --- a/tests/source/license-templates/license.rs +++ /dev/null @@ -1,6 +0,0 @@ -// rustfmt-license_template_path: tests/license-template/lt.txt -// Copyright 2019 The rustfmt developers. - -fn main() { -println!("Hello world!"); -} diff --git a/tests/target/license-templates/empty_license_path.rs b/tests/target/license-templates/empty_license_path.rs deleted file mode 100644 index 950f103ed39..00000000000 --- a/tests/target/license-templates/empty_license_path.rs +++ /dev/null @@ -1,5 +0,0 @@ -// rustfmt-config: issue-3802.toml - -fn main() { - println!("Hello world!"); -} diff --git a/tests/target/license-templates/license.rs b/tests/target/license-templates/license.rs deleted file mode 100644 index 7169c7b2576..00000000000 --- a/tests/target/license-templates/license.rs +++ /dev/null @@ -1,6 +0,0 @@ -// rustfmt-license_template_path: tests/license-template/lt.txt -// Copyright 2019 The rustfmt developers. - -fn main() { - println!("Hello world!"); -}