NonCamelCaseTypes,
NonUppercaseStatics,
NonUppercasePatternStatics,
+ NonSnakeCaseFunctions,
UppercaseVariables,
UnnecessaryParens,
TypeLimits,
default: Warn
}),
+ ("non_snake_case_functions",
+ LintSpec {
+ lint: NonSnakeCaseFunctions,
+ desc: "methods and functions should have snake case names",
+ default: Warn
+ }),
+
("uppercase_variables",
LintSpec {
lint: UppercaseVariables,
}
}
+fn check_snake_case(cx: &Context, sort: &str, ident: ast::Ident, span: Span) {
+ fn is_snake_case(ident: ast::Ident) -> bool {
+ let ident = token::get_ident(ident);
+ assert!(!ident.get().is_empty());
+ let ident = ident.get().trim_chars('_');
+
+ let mut allow_underscore = true;
+ ident.chars().all(|c| {
+ allow_underscore = match c {
+ c if c.is_lowercase() || c.is_digit() => true,
+ '_' if allow_underscore => false,
+ _ => return false,
+ };
+ true
+ })
+ }
+
+ if !is_snake_case(ident) {
+ cx.span_lint(NonSnakeCaseFunctions, span,
+ format!("{} `{}` should have a snake case identifier",
+ sort, token::get_ident(ident)).as_slice());
+ }
+}
+
fn check_item_non_uppercase_statics(cx: &Context, it: &ast::Item) {
match it.node {
// only check static constants
desc);
}
+#[deriving(Eq)]
+enum MethodContext {
+ TraitDefaultImpl,
+ TraitImpl,
+ PlainImpl
+}
+
fn check_missing_doc_method(cx: &Context, m: &ast::Method) {
+ // If the method is an impl for a trait, don't doc.
+ if method_context(cx, m) == TraitImpl { return; }
+
+ // Otherwise, doc according to privacy. This will also check
+ // doc for default methods defined on traits.
+ check_missing_doc_attrs(cx,
+ Some(m.id),
+ m.attrs.as_slice(),
+ m.span,
+ "a method");
+}
+
+fn method_context(cx: &Context, m: &ast::Method) -> MethodContext {
let did = ast::DefId {
krate: ast::LOCAL_CRATE,
node: m.id
None => cx.tcx.sess.span_bug(m.span, "missing method descriptor?!"),
Some(md) => {
match md.container {
- // Always check default methods defined on traits.
- ty::TraitContainer(..) => {}
- // For methods defined on impls, it depends on whether
- // it is an implementation for a trait or is a plain
- // impl.
+ ty::TraitContainer(..) => TraitDefaultImpl,
ty::ImplContainer(cid) => {
match ty::impl_trait_ref(cx.tcx, cid) {
- Some(..) => return, // impl for trait: don't doc
- None => {} // plain impl: doc according to privacy
+ Some(..) => TraitImpl,
+ None => PlainImpl
}
}
}
}
}
- check_missing_doc_attrs(cx,
- Some(m.id),
- m.attrs.as_slice(),
- m.span,
- "a method");
}
fn check_missing_doc_ty_method(cx: &Context, tm: &ast::TypeMethod) {
}
match *fk {
- visit::FkMethod(_, _, m) => {
+ visit::FkMethod(ident, _, m) => {
self.with_lint_attrs(m.attrs.as_slice(), |cx| {
check_missing_doc_method(cx, m);
check_attrs_usage(cx, m.attrs.as_slice());
+ match method_context(cx, m) {
+ PlainImpl => check_snake_case(cx, "method", ident, span),
+ TraitDefaultImpl => check_snake_case(cx, "trait method", ident, span),
+ _ => (),
+ }
+
cx.visit_ids(|v| {
v.visit_fn(fk, decl, body, span, id, ());
});
recurse(cx);
})
+ },
+ visit::FkItemFn(ident, _, _, _) => {
+ check_snake_case(self, "function", ident, span);
+ recurse(self);
}
_ => recurse(self),
}
}
-
fn visit_ty_method(&mut self, t: &ast::TypeMethod, _: ()) {
self.with_lint_attrs(t.attrs.as_slice(), |cx| {
check_missing_doc_ty_method(cx, t);
check_attrs_usage(cx, t.attrs.as_slice());
+ check_snake_case(cx, "trait method", t.ident, t.span);
visit::walk_ty_method(cx, t, ());
})
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![deny(non_snake_case_functions)]
+#![allow(dead_code)]
+
+struct Foo;
+
+impl Foo {
+ fn Foo_Method() {}
+ //~^ ERROR method `Foo_Method` should have a snake case identifier
+
+ // Don't allow two underscores in a row
+ fn foo__method(&self) {}
+ //~^ ERROR method `foo__method` should have a snake case identifier
+
+ pub fn xyZ(&mut self) {}
+ //~^ ERROR method `xyZ` should have a snake case identifier
+}
+
+trait X {
+ fn ABC();
+ //~^ ERROR trait method `ABC` should have a snake case identifier
+
+ fn a_b_C(&self) {}
+ //~^ ERROR trait method `a_b_C` should have a snake case identifier
+
+ fn something__else(&mut self);
+ //~^ ERROR trait method `something__else` should have a snake case identifier
+}
+
+impl X for Foo {
+ // These errors should be caught at the trait definition not the impl
+ fn ABC() {}
+ fn something__else(&mut self) {}
+}
+
+fn Cookie() {}
+//~^ ERROR function `Cookie` should have a snake case identifier
+
+pub fn bi_S_Cuit() {}
+//~^ ERROR function `bi_S_Cuit` should have a snake case identifier
+
+fn main() { }