@@ -83,6 +83,7 @@ pub enum Lint {
83
83
NonCamelCaseTypes ,
84
84
NonUppercaseStatics ,
85
85
NonUppercasePatternStatics ,
86
+ NonSnakeCaseFunctions ,
86
87
UppercaseVariables ,
87
88
UnnecessaryParens ,
88
89
TypeLimits ,
@@ -220,6 +221,13 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[
220
221
default : Warn
221
222
} ) ,
222
223
224
+ ( "non_snake_case_functions" ,
225
+ LintSpec {
226
+ lint : NonSnakeCaseFunctions ,
227
+ desc : "methods and functions should have snake case names" ,
228
+ default : Warn
229
+ } ) ,
230
+
223
231
( "uppercase_variables" ,
224
232
LintSpec {
225
233
lint : UppercaseVariables ,
@@ -1342,6 +1350,30 @@ fn check_item_non_camel_case_types(cx: &Context, it: &ast::Item) {
1342
1350
}
1343
1351
}
1344
1352
1353
+ fn check_snake_case ( cx : & Context , sort : & str , ident : ast:: Ident , span : Span ) {
1354
+ fn is_snake_case ( ident : ast:: Ident ) -> bool {
1355
+ let ident = token:: get_ident ( ident) ;
1356
+ assert ! ( !ident. get( ) . is_empty( ) ) ;
1357
+ let ident = ident. get ( ) . trim_chars ( '_' ) ;
1358
+
1359
+ let mut allow_underscore = true ;
1360
+ ident. chars ( ) . all ( |c| {
1361
+ allow_underscore = match c {
1362
+ c if c. is_lowercase ( ) || c. is_digit ( ) => true ,
1363
+ '_' if allow_underscore => false ,
1364
+ _ => return false ,
1365
+ } ;
1366
+ true
1367
+ } )
1368
+ }
1369
+
1370
+ if !is_snake_case ( ident) {
1371
+ cx. span_lint ( NonSnakeCaseFunctions , span,
1372
+ format ! ( "{} `{}` should have a snake case identifier" ,
1373
+ sort, token:: get_ident( ident) ) . as_slice ( ) ) ;
1374
+ }
1375
+ }
1376
+
1345
1377
fn check_item_non_uppercase_statics ( cx : & Context , it : & ast:: Item ) {
1346
1378
match it. node {
1347
1379
// only check static constants
@@ -1618,7 +1650,27 @@ fn check_missing_doc_item(cx: &Context, it: &ast::Item) {
1618
1650
desc) ;
1619
1651
}
1620
1652
1653
+ #[ deriving( Eq ) ]
1654
+ enum MethodContext {
1655
+ TraitDefaultImpl ,
1656
+ TraitImpl ,
1657
+ PlainImpl
1658
+ }
1659
+
1621
1660
fn check_missing_doc_method ( cx : & Context , m : & ast:: Method ) {
1661
+ // If the method is an impl for a trait, don't doc.
1662
+ if method_context ( cx, m) == TraitImpl { return ; }
1663
+
1664
+ // Otherwise, doc according to privacy. This will also check
1665
+ // doc for default methods defined on traits.
1666
+ check_missing_doc_attrs ( cx,
1667
+ Some ( m. id ) ,
1668
+ m. attrs . as_slice ( ) ,
1669
+ m. span ,
1670
+ "a method" ) ;
1671
+ }
1672
+
1673
+ fn method_context ( cx : & Context , m : & ast:: Method ) -> MethodContext {
1622
1674
let did = ast:: DefId {
1623
1675
krate : ast:: LOCAL_CRATE ,
1624
1676
node : m. id
@@ -1628,25 +1680,16 @@ fn check_missing_doc_method(cx: &Context, m: &ast::Method) {
1628
1680
None => cx. tcx . sess . span_bug ( m. span , "missing method descriptor?!" ) ,
1629
1681
Some ( md) => {
1630
1682
match md. container {
1631
- // Always check default methods defined on traits.
1632
- ty:: TraitContainer ( ..) => { }
1633
- // For methods defined on impls, it depends on whether
1634
- // it is an implementation for a trait or is a plain
1635
- // impl.
1683
+ ty:: TraitContainer ( ..) => TraitDefaultImpl ,
1636
1684
ty:: ImplContainer ( cid) => {
1637
1685
match ty:: impl_trait_ref ( cx. tcx , cid) {
1638
- Some ( ..) => return , // impl for trait: don't doc
1639
- None => { } // plain impl: doc according to privacy
1686
+ Some ( ..) => TraitImpl ,
1687
+ None => PlainImpl
1640
1688
}
1641
1689
}
1642
1690
}
1643
1691
}
1644
1692
}
1645
- check_missing_doc_attrs ( cx,
1646
- Some ( m. id ) ,
1647
- m. attrs . as_slice ( ) ,
1648
- m. span ,
1649
- "a method" ) ;
1650
1693
}
1651
1694
1652
1695
fn check_missing_doc_ty_method ( cx : & Context , tm : & ast:: TypeMethod ) {
@@ -1889,26 +1932,36 @@ impl<'a> Visitor<()> for Context<'a> {
1889
1932
}
1890
1933
1891
1934
match * fk {
1892
- visit:: FkMethod ( _ , _, m) => {
1935
+ visit:: FkMethod ( ident , _, m) => {
1893
1936
self . with_lint_attrs ( m. attrs . as_slice ( ) , |cx| {
1894
1937
check_missing_doc_method ( cx, m) ;
1895
1938
check_attrs_usage ( cx, m. attrs . as_slice ( ) ) ;
1896
1939
1940
+ match method_context ( cx, m) {
1941
+ PlainImpl => check_snake_case ( cx, "method" , ident, span) ,
1942
+ TraitDefaultImpl => check_snake_case ( cx, "trait method" , ident, span) ,
1943
+ _ => ( ) ,
1944
+ }
1945
+
1897
1946
cx. visit_ids ( |v| {
1898
1947
v. visit_fn ( fk, decl, body, span, id, ( ) ) ;
1899
1948
} ) ;
1900
1949
recurse ( cx) ;
1901
1950
} )
1951
+ } ,
1952
+ visit:: FkItemFn ( ident, _, _, _) => {
1953
+ check_snake_case ( self , "function" , ident, span) ;
1954
+ recurse ( self ) ;
1902
1955
}
1903
1956
_ => recurse ( self ) ,
1904
1957
}
1905
1958
}
1906
1959
1907
-
1908
1960
fn visit_ty_method ( & mut self , t : & ast:: TypeMethod , _: ( ) ) {
1909
1961
self . with_lint_attrs ( t. attrs . as_slice ( ) , |cx| {
1910
1962
check_missing_doc_ty_method ( cx, t) ;
1911
1963
check_attrs_usage ( cx, t. attrs . as_slice ( ) ) ;
1964
+ check_snake_case ( cx, "trait method" , t. ident , t. span ) ;
1912
1965
1913
1966
visit:: walk_ty_method ( cx, t, ( ) ) ;
1914
1967
} )
0 commit comments