about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2013-05-28 16:53:43 -0500
committerAlex Crichton <alex@alexcrichton.com>2013-05-30 01:02:55 -0500
commit4a5d887b58ff9833a968e7a0d28282b915e01de8 (patch)
tree487123b86102561a5ffaa002dab7c35b576f734d
parentaf995ce1e7fe8c30c8f5da3d04e0e2e89762bde4 (diff)
downloadrust-4a5d887b58ff9833a968e7a0d28282b915e01de8.tar.gz
rust-4a5d887b58ff9833a968e7a0d28282b915e01de8.zip
Allow doc(hidden) and --test to disable doc linting
-rw-r--r--src/librustc/middle/lint.rs39
-rw-r--r--src/test/compile-fail/lint-missing-doc.rs13
2 files changed, 49 insertions, 3 deletions
diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs
index c42c8b8bb84..6dd911e8ef3 100644
--- a/src/librustc/middle/lint.rs
+++ b/src/librustc/middle/lint.rs
@@ -297,6 +297,10 @@ struct Context {
     // Just a simple flag if we're currently recursing into a trait
     // implementation. This is only used by the lint_missing_doc() pass
     in_trait_impl: bool,
+    // Another flag for doc lint emissions. Does some parent of the current node
+    // have the doc(hidden) attribute? Treating this as allow(missing_doc) would
+    // play badly with forbid(missing_doc) when it shouldn't.
+    doc_hidden: bool,
     // When recursing into an attributed node of the ast which modifies lint
     // levels, this stack keeps track of the previous lint levels of whatever
     // was modified.
@@ -422,9 +426,30 @@ impl Context {
             }
         }
 
+        // detect doc(hidden)
+        let mut doc_hidden = false;
+        for attr::find_attrs_by_name(attrs, "doc").each |attr| {
+            match attr::get_meta_item_list(attr.node.value) {
+                Some(s) => {
+                    if attr::find_meta_items_by_name(s, "hidden").len() > 0 {
+                        doc_hidden = true;
+                    }
+                }
+                None => {}
+            }
+        }
+        if doc_hidden && !self.doc_hidden {
+            self.doc_hidden = true;
+        } else {
+            doc_hidden = false;
+        }
+
         f();
 
         // rollback
+        if doc_hidden && self.doc_hidden {
+            self.doc_hidden = false;
+        }
         for pushed.times {
             let (lint, lvl, src) = self.lint_stack.pop();
             self.set_level(lint, lvl, src);
@@ -980,9 +1005,16 @@ fn lint_unnecessary_allocations() -> visit::vt<@mut Context> {
 fn lint_missing_doc() -> visit::vt<@mut Context> {
     fn check_attrs(cx: @mut Context, attrs: &[ast::attribute],
                    sp: span, msg: &str) {
-        if !attrs.any(|a| a.node.is_sugared_doc) {
-            cx.span_lint(missing_doc, sp, msg);
-        }
+        // If we're building a test harness, then warning about documentation is
+        // probably not really relevant right now
+        if cx.tcx.sess.opts.test { return }
+        // If we have doc(hidden), nothing to do
+        if cx.doc_hidden { return }
+        // If we're documented, nothing to do
+        if attrs.any(|a| a.node.is_sugared_doc) { return }
+
+        // otherwise, warn!
+        cx.span_lint(missing_doc, sp, msg);
     }
 
     visit::mk_vt(@visit::Visitor {
@@ -1067,6 +1099,7 @@ pub fn check_crate(tcx: ty::ctxt, crate: @ast::crate) {
         lint_stack: ~[],
         visitors: ~[],
         in_trait_impl: false,
+        doc_hidden: false,
     };
 
     // Install defaults.
diff --git a/src/test/compile-fail/lint-missing-doc.rs b/src/test/compile-fail/lint-missing-doc.rs
index fd0b0fb80f8..2350ca68b97 100644
--- a/src/test/compile-fail/lint-missing-doc.rs
+++ b/src/test/compile-fail/lint-missing-doc.rs
@@ -69,4 +69,17 @@ impl F for Foo {
     fn b(&self) {}
 }
 
+// It sure is nice if doc(hidden) implies allow(missing_doc), and that it
+// applies recursively
+#[doc(hidden)]
+mod a {
+    pub fn baz() {}
+    pub mod b {
+        pub fn baz() {}
+    }
+}
+
+#[doc(hidden)]
+pub fn baz() {}
+
 fn main() {}