44
55use lazy_static:: lazy_static;
66use rustc_span:: source_map;
7- use std :: default :: Default ;
8- use std:: io :: Read ;
7+ use source_map :: Span ;
8+ use std:: path :: { Path , PathBuf } ;
99use std:: sync:: Mutex ;
10- use std:: { env, fmt, fs, io, path } ;
11- use syntax:: ast;
10+ use std:: { env, fmt, fs, io} ;
11+ use syntax:: ast:: { LitKind , MetaItemKind , NestedMetaItem } ;
1212
1313/// Gets the configuration file from arguments.
14- pub fn file_from_args ( args : & [ ast :: NestedMetaItem ] ) -> Result < Option < path :: PathBuf > , ( & ' static str , source_map :: Span ) > {
15- for arg in args. iter ( ) . filter_map ( syntax :: ast :: NestedMetaItem :: meta_item) {
14+ pub fn file_from_args ( args : & [ NestedMetaItem ] ) -> Result < Option < PathBuf > , ( & ' static str , Span ) > {
15+ for arg in args. iter ( ) . filter_map ( NestedMetaItem :: meta_item) {
1616 if arg. check_name ( sym ! ( conf_file) ) {
1717 return match arg. kind {
18- ast:: MetaItemKind :: Word | ast:: MetaItemKind :: List ( _) => {
19- Err ( ( "`conf_file` must be a named value" , arg. span ) )
20- } ,
21- ast:: MetaItemKind :: NameValue ( ref value) => {
22- if let ast:: LitKind :: Str ( ref file, _) = value. kind {
18+ MetaItemKind :: Word | MetaItemKind :: List ( _) => Err ( ( "`conf_file` must be a named value" , arg. span ) ) ,
19+ MetaItemKind :: NameValue ( ref value) => {
20+ if let LitKind :: Str ( ref file, _) = value. kind {
2321 Ok ( Some ( file. to_string ( ) . into ( ) ) )
2422 } else {
2523 Err ( ( "`conf_file` value must be a string" , value. span ) )
@@ -37,15 +35,15 @@ pub fn file_from_args(args: &[ast::NestedMetaItem]) -> Result<Option<path::PathB
3735pub enum Error {
3836 /// An I/O error.
3937 Io ( io:: Error ) ,
40- /// Not valid toml or doesn't fit the expected conf format
38+ /// Not valid toml or doesn't fit the expected config format
4139 Toml ( String ) ,
4240}
4341
4442impl fmt:: Display for Error {
45- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> Result < ( ) , fmt:: Error > {
46- match * self {
47- Self :: Io ( ref err) => err. fmt ( f) ,
48- Self :: Toml ( ref err) => err. fmt ( f) ,
43+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
44+ match self {
45+ Self :: Io ( err) => err. fmt ( f) ,
46+ Self :: Toml ( err) => err. fmt ( f) ,
4947 }
5048 }
5149}
@@ -61,59 +59,61 @@ lazy_static! {
6159}
6260
6361macro_rules! define_Conf {
64- ( $( #[ $doc: meta] ( $rust_name: ident, $rust_name_str: expr, $default: expr => $( $ty: tt) +) , ) +) => {
65- pub use self :: helpers:: Conf ;
62+ ( $( #[ $doc: meta] ( $config: ident, $config_str: literal: $Ty: ty, $default: expr) , ) +) => {
6663 mod helpers {
6764 use serde:: Deserialize ;
6865 /// Type used to store lint configuration.
6966 #[ derive( Deserialize ) ]
70- #[ serde( rename_all= "kebab-case" , deny_unknown_fields) ]
67+ #[ serde( rename_all = "kebab-case" , deny_unknown_fields) ]
7168 pub struct Conf {
72- $( #[ $doc] #[ serde( default =$rust_name_str) ] #[ serde( with=$rust_name_str) ]
73- pub $rust_name: define_Conf!( TY $( $ty) +) , ) +
69+ $(
70+ #[ $doc]
71+ #[ serde( default = $config_str) ]
72+ #[ serde( with = $config_str) ]
73+ pub $config: $Ty,
74+ ) +
7475 #[ allow( dead_code) ]
7576 #[ serde( default ) ]
7677 third_party: Option <:: toml:: Value >,
7778 }
79+
7880 $(
79- mod $rust_name {
81+ mod $config {
8082 use serde:: Deserialize ;
81- crate fn deserialize<' de, D : serde:: Deserializer <' de>>( deserializer: D )
82- -> Result <define_Conf!( TY $( $ty) +) , D :: Error > {
83- type T = define_Conf!( TY $( $ty) +) ;
84- Ok ( T :: deserialize( deserializer) . unwrap_or_else( |e| {
85- crate :: utils:: conf:: ERRORS . lock( ) . expect( "no threading here" )
86- . push( crate :: utils:: conf:: Error :: Toml ( e. to_string( ) ) ) ;
87- super :: $rust_name( )
88- } ) )
83+ crate fn deserialize<' de, D : serde:: Deserializer <' de>>( deserializer: D ) -> Result <$Ty, D :: Error > {
84+ use super :: super :: { ERRORS , Error } ;
85+ Ok (
86+ <$Ty>:: deserialize( deserializer) . unwrap_or_else( |e| {
87+ ERRORS
88+ . lock( )
89+ . expect( "no threading here" )
90+ . push( Error :: Toml ( e. to_string( ) ) ) ;
91+ super :: $config( )
92+ } )
93+ )
8994 }
9095 }
9196
9297 #[ must_use]
93- fn $rust_name( ) -> define_Conf!( TY $( $ty) +) {
94- define_Conf!( DEFAULT $( $ty) +, $default)
98+ fn $config( ) -> $Ty {
99+ let x = $default;
100+ x
95101 }
96102 ) +
97103 }
98104 } ;
99-
100- // hack to convert tts
101- ( TY $ty: ty) => { $ty } ;
102-
103- // provide a nicer syntax to declare the default value of `Vec<String>` variables
104- ( DEFAULT Vec <String >, $e: expr) => { $e. iter( ) . map( |& e| e. to_owned( ) ) . collect( ) } ;
105- ( DEFAULT $ty: ty, $e: expr) => { $e } ;
106105}
107106
107+ pub use self :: helpers:: Conf ;
108108define_Conf ! {
109109 /// Lint: BLACKLISTED_NAME. The list of blacklisted names to lint about
110- ( blacklisted_names, "blacklisted_names" , [ "foo" , "bar" , "baz" , "quux" ] => Vec < String > ) ,
110+ ( blacklisted_names, "blacklisted_names" : Vec < String > , [ "foo" , "bar" , "baz" , "quux" ] . iter ( ) . map ( ToString :: to_string ) . collect ( ) ) ,
111111 /// Lint: COGNITIVE_COMPLEXITY. The maximum cognitive complexity a function can have
112- ( cognitive_complexity_threshold, "cognitive_complexity_threshold" , 25 => u64 ) ,
112+ ( cognitive_complexity_threshold, "cognitive_complexity_threshold" : u64 , 25 ) ,
113113 /// DEPRECATED LINT: CYCLOMATIC_COMPLEXITY. Use the Cognitive Complexity lint instead.
114- ( cyclomatic_complexity_threshold, "cyclomatic_complexity_threshold" , None => Option <u64 >) ,
114+ ( cyclomatic_complexity_threshold, "cyclomatic_complexity_threshold" : Option <u64 >, None ) ,
115115 /// Lint: DOC_MARKDOWN. The list of words this lint should not consider as identifiers needing ticks
116- ( doc_valid_idents, "doc_valid_idents" , [
116+ ( doc_valid_idents, "doc_valid_idents" : Vec < String > , [
117117 "KiB" , "MiB" , "GiB" , "TiB" , "PiB" , "EiB" ,
118118 "DirectX" ,
119119 "ECMAScript" ,
@@ -129,31 +129,31 @@ define_Conf! {
129129 "TeX" , "LaTeX" , "BibTeX" , "BibLaTeX" ,
130130 "MinGW" ,
131131 "CamelCase" ,
132- ] => Vec < String > ) ,
132+ ] . iter ( ) . map ( ToString :: to_string ) . collect ( ) ) ,
133133 /// Lint: TOO_MANY_ARGUMENTS. The maximum number of argument a function or method can have
134- ( too_many_arguments_threshold, "too_many_arguments_threshold" , 7 => u64 ) ,
134+ ( too_many_arguments_threshold, "too_many_arguments_threshold" : u64 , 7 ) ,
135135 /// Lint: TYPE_COMPLEXITY. The maximum complexity a type can have
136- ( type_complexity_threshold, "type_complexity_threshold" , 250 => u64 ) ,
136+ ( type_complexity_threshold, "type_complexity_threshold" : u64 , 250 ) ,
137137 /// Lint: MANY_SINGLE_CHAR_NAMES. The maximum number of single char bindings a scope may have
138- ( single_char_binding_names_threshold, "single_char_binding_names_threshold" , 5 => u64 ) ,
138+ ( single_char_binding_names_threshold, "single_char_binding_names_threshold" : u64 , 5 ) ,
139139 /// Lint: BOXED_LOCAL. The maximum size of objects (in bytes) that will be linted. Larger objects are ok on the heap
140- ( too_large_for_stack, "too_large_for_stack" , 200 => u64 ) ,
140+ ( too_large_for_stack, "too_large_for_stack" : u64 , 200 ) ,
141141 /// Lint: ENUM_VARIANT_NAMES. The minimum number of enum variants for the lints about variant names to trigger
142- ( enum_variant_name_threshold, "enum_variant_name_threshold" , 3 => u64 ) ,
142+ ( enum_variant_name_threshold, "enum_variant_name_threshold" : u64 , 3 ) ,
143143 /// Lint: LARGE_ENUM_VARIANT. The maximum size of a enum's variant to avoid box suggestion
144- ( enum_variant_size_threshold, "enum_variant_size_threshold" , 200 => u64 ) ,
144+ ( enum_variant_size_threshold, "enum_variant_size_threshold" : u64 , 200 ) ,
145145 /// Lint: VERBOSE_BIT_MASK. The maximum allowed size of a bit mask before suggesting to use 'trailing_zeros'
146- ( verbose_bit_mask_threshold, "verbose_bit_mask_threshold" , 1 => u64 ) ,
146+ ( verbose_bit_mask_threshold, "verbose_bit_mask_threshold" : u64 , 1 ) ,
147147 /// Lint: DECIMAL_LITERAL_REPRESENTATION. The lower bound for linting decimal literals
148- ( literal_representation_threshold, "literal_representation_threshold" , 16384 => u64 ) ,
148+ ( literal_representation_threshold, "literal_representation_threshold" : u64 , 16384 ) ,
149149 /// Lint: TRIVIALLY_COPY_PASS_BY_REF. The maximum size (in bytes) to consider a `Copy` type for passing by value instead of by reference.
150- ( trivial_copy_size_limit, "trivial_copy_size_limit" , None => Option <u64 >) ,
150+ ( trivial_copy_size_limit, "trivial_copy_size_limit" : Option <u64 >, None ) ,
151151 /// Lint: TOO_MANY_LINES. The maximum number of lines a function or method can have
152- ( too_many_lines_threshold, "too_many_lines_threshold" , 100 => u64 ) ,
152+ ( too_many_lines_threshold, "too_many_lines_threshold" : u64 , 100 ) ,
153153 /// Lint: LARGE_STACK_ARRAYS. The maximum allowed size for arrays on the stack
154- ( array_size_threshold, "array_size_threshold" , 512_000 => u64 ) ,
154+ ( array_size_threshold, "array_size_threshold" : u64 , 512_000 ) ,
155155 /// Lint: VEC_BOX. The size of the boxed type in bytes, where boxing in a `Vec` is allowed
156- ( vec_box_size_threshold, "vec_box_size_threshold" , 4096 => u64 ) ,
156+ ( vec_box_size_threshold, "vec_box_size_threshold" : u64 , 4096 ) ,
157157}
158158
159159impl Default for Conf {
@@ -164,32 +164,26 @@ impl Default for Conf {
164164}
165165
166166/// Search for the configuration file.
167- pub fn lookup_conf_file ( ) -> io:: Result < Option < path :: PathBuf > > {
167+ pub fn lookup_conf_file ( ) -> io:: Result < Option < PathBuf > > {
168168 /// Possible filename to search for.
169169 const CONFIG_FILE_NAMES : [ & str ; 2 ] = [ ".clippy.toml" , "clippy.toml" ] ;
170170
171171 // Start looking for a config file in CLIPPY_CONF_DIR, or failing that, CARGO_MANIFEST_DIR.
172172 // If neither of those exist, use ".".
173- let mut current = path:: PathBuf :: from (
174- env:: var ( "CLIPPY_CONF_DIR" )
175- . or_else ( |_| env:: var ( "CARGO_MANIFEST_DIR" ) )
176- . unwrap_or_else ( |_| "." . to_string ( ) ) ,
177- ) ;
173+ let mut current = env:: var_os ( "CLIPPY_CONF_DIR" )
174+ . or_else ( || env:: var_os ( "CARGO_MANIFEST_DIR" ) )
175+ . map_or_else ( || PathBuf :: from ( "." ) , PathBuf :: from) ;
178176 loop {
179177 for config_file_name in & CONFIG_FILE_NAMES {
180178 let config_file = current. join ( config_file_name) ;
181179 match fs:: metadata ( & config_file) {
182180 // Only return if it's a file to handle the unlikely situation of a directory named
183181 // `clippy.toml`.
184- Ok ( ref md) if md. is_file ( ) => return Ok ( Some ( config_file) ) ,
182+ Ok ( ref md) if ! md. is_dir ( ) => return Ok ( Some ( config_file) ) ,
185183 // Return the error if it's something other than `NotFound`; otherwise we didn't
186184 // find the project file yet, and continue searching.
187- Err ( e) => {
188- if e. kind ( ) != io:: ErrorKind :: NotFound {
189- return Err ( e) ;
190- }
191- } ,
192- _ => ( ) ,
185+ Err ( e) if e. kind ( ) != io:: ErrorKind :: NotFound => return Err ( e) ,
186+ _ => { } ,
193187 }
194188 }
195189
@@ -210,28 +204,14 @@ fn default(errors: Vec<Error>) -> (Conf, Vec<Error>) {
210204/// Read the `toml` configuration file.
211205///
212206/// In case of error, the function tries to continue as much as possible.
213- pub fn read ( path : Option < & path:: Path > ) -> ( Conf , Vec < Error > ) {
214- let path = if let Some ( path) = path {
215- path
216- } else {
217- return default ( Vec :: new ( ) ) ;
218- } ;
219-
220- let file = match fs:: File :: open ( path) {
221- Ok ( mut file) => {
222- let mut buf = String :: new ( ) ;
223-
224- if let Err ( err) = file. read_to_string ( & mut buf) {
225- return default ( vec ! [ err. into( ) ] ) ;
226- }
227-
228- buf
229- } ,
207+ pub fn read ( path : & Path ) -> ( Conf , Vec < Error > ) {
208+ let content = match fs:: read_to_string ( path) {
209+ Ok ( content) => content,
230210 Err ( err) => return default ( vec ! [ err. into( ) ] ) ,
231211 } ;
232212
233213 assert ! ( ERRORS . lock( ) . expect( "no threading -> mutex always safe" ) . is_empty( ) ) ;
234- match toml:: from_str ( & file ) {
214+ match toml:: from_str ( & content ) {
235215 Ok ( toml) => {
236216 let mut errors = ERRORS . lock ( ) . expect ( "no threading -> mutex always safe" ) . split_off ( 0 ) ;
237217
0 commit comments