about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/comments.rs66
-rw-r--r--src/libsyntax/parse/lexer.rs37
2 files changed, 64 insertions, 39 deletions
diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs
index a8db06fe085..7a0fdd6b1b0 100644
--- a/src/libsyntax/parse/comments.rs
+++ b/src/libsyntax/parse/comments.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -15,6 +15,7 @@ use codemap::{BytePos, CharPos, CodeMap, FileMap, Pos};
 use diagnostic;
 use parse::lexer::{is_whitespace, get_str_from, reader};
 use parse::lexer::{StringReader, bump, is_eof, nextch, TokenAndSpan};
+use parse::lexer::{is_line_non_doc_comment, is_block_non_doc_comment};
 use parse::lexer;
 use parse::token;
 use parse;
@@ -46,9 +47,9 @@ impl cmnt_style : cmp::Eq {
 pub type cmnt = {style: cmnt_style, lines: ~[~str], pos: BytePos};
 
 pub fn is_doc_comment(s: ~str) -> bool {
-    s.starts_with(~"///") ||
+    (s.starts_with(~"///") && !is_line_non_doc_comment(s)) ||
     s.starts_with(~"//!") ||
-    s.starts_with(~"/**") ||
+    (s.starts_with(~"/**") && !is_block_non_doc_comment(s)) ||
     s.starts_with(~"/*!")
 }
 
@@ -231,47 +232,56 @@ fn read_block_comment(rdr: @mut StringReader,
     bump(rdr);
     bump(rdr);
 
+    let mut curr_line = ~"/*";
+
     // doc-comments are not really comments, they are attributes
     if rdr.curr == '*' || rdr.curr == '!' {
         while !(rdr.curr == '*' && nextch(rdr) == '/') && !is_eof(rdr) {
+            str::push_char(&mut curr_line, rdr.curr);
             bump(rdr);
         }
         if !is_eof(rdr) {
+            curr_line += ~"*/";
             bump(rdr);
             bump(rdr);
         }
-        return;
-    }
-
-    let mut curr_line = ~"/*";
-    let mut level: int = 1;
-    while level > 0 {
-        debug!("=== block comment level %d", level);
-        if is_eof(rdr) {(rdr as reader).fatal(~"unterminated block comment");}
-        if rdr.curr == '\n' {
-            trim_whitespace_prefix_and_push_line(&mut lines, curr_line, col);
-            curr_line = ~"";
-            bump(rdr);
-        } else {
-            str::push_char(&mut curr_line, rdr.curr);
-            if rdr.curr == '/' && nextch(rdr) == '*' {
-                bump(rdr);
+        if !is_block_non_doc_comment(curr_line) { return; }
+        assert !curr_line.contains_char('\n');
+        lines.push(curr_line);
+    } else {
+        let mut level: int = 1;
+        while level > 0 {
+            debug!("=== block comment level %d", level);
+            if is_eof(rdr) {
+                (rdr as reader).fatal(~"unterminated block comment");
+            }
+            if rdr.curr == '\n' {
+                trim_whitespace_prefix_and_push_line(&mut lines, curr_line,
+                                                     col);
+                curr_line = ~"";
                 bump(rdr);
-                curr_line += ~"*";
-                level += 1;
             } else {
-                if rdr.curr == '*' && nextch(rdr) == '/' {
+                str::push_char(&mut curr_line, rdr.curr);
+                if rdr.curr == '/' && nextch(rdr) == '*' {
                     bump(rdr);
                     bump(rdr);
-                    curr_line += ~"/";
-                    level -= 1;
-                } else { bump(rdr); }
+                    curr_line += ~"*";
+                    level += 1;
+                } else {
+                    if rdr.curr == '*' && nextch(rdr) == '/' {
+                        bump(rdr);
+                        bump(rdr);
+                        curr_line += ~"/";
+                        level -= 1;
+                    } else { bump(rdr); }
+                }
             }
         }
+        if str::len(curr_line) != 0 {
+            trim_whitespace_prefix_and_push_line(&mut lines, curr_line, col);
+        }
     }
-    if str::len(curr_line) != 0 {
-        trim_whitespace_prefix_and_push_line(&mut lines, curr_line, col);
-    }
+
     let mut style = if code_to_the_left { trailing } else { isolated };
     consume_non_eol_whitespace(rdr);
     if !is_eof(rdr) && rdr.curr != '\n' && vec::len(lines) == 1u {
diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs
index e8afd0b96a2..4392acdf75e 100644
--- a/src/libsyntax/parse/lexer.rs
+++ b/src/libsyntax/parse/lexer.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -253,6 +253,10 @@ fn consume_whitespace_and_comments(rdr: @mut StringReader)
     return consume_any_line_comment(rdr);
 }
 
+pub pure fn is_line_non_doc_comment(s: &str) -> bool {
+    s.trim_right().all(|ch| ch == '/')
+}
+
 // PRECONDITION: rdr.curr is not whitespace
 // EFFECT: eats any kind of comment.
 // returns a Some(sugared-doc-attr) if one exists, None otherwise
@@ -271,15 +275,18 @@ fn consume_any_line_comment(rdr: @mut StringReader)
                     str::push_char(&mut acc, rdr.curr);
                     bump(rdr);
                 }
-                return Some(TokenAndSpan{
-                    tok: token::DOC_COMMENT(rdr.interner.intern(@acc)),
-                    sp: codemap::mk_sp(start_bpos, rdr.pos)
-                });
+                // but comments with only "/"s are not
+                if !is_line_non_doc_comment(acc) {
+                    return Some(TokenAndSpan{
+                        tok: token::DOC_COMMENT(rdr.interner.intern(@acc)),
+                        sp: codemap::mk_sp(start_bpos, rdr.pos)
+                    });
+                }
             } else {
                 while rdr.curr != '\n' && !is_eof(rdr) { bump(rdr); }
-                // Restart whitespace munch.
-                return consume_whitespace_and_comments(rdr);
             }
+            // Restart whitespace munch.
+            return consume_whitespace_and_comments(rdr);
           }
           '*' => { bump(rdr); bump(rdr); return consume_block_comment(rdr); }
           _ => ()
@@ -298,6 +305,11 @@ fn consume_any_line_comment(rdr: @mut StringReader)
     return None;
 }
 
+pub pure fn is_block_non_doc_comment(s: &str) -> bool {
+    assert s.len() >= 1u;
+    str::all_between(s, 1u, s.len() - 1u, |ch| ch == '*')
+}
+
 // might return a sugared-doc-attr
 fn consume_block_comment(rdr: @mut StringReader)
                       -> Option<TokenAndSpan> {
@@ -315,10 +327,13 @@ fn consume_block_comment(rdr: @mut StringReader)
             acc += ~"*/";
             bump(rdr);
             bump(rdr);
-            return Some(TokenAndSpan{
-                tok: token::DOC_COMMENT(rdr.interner.intern(@acc)),
-                sp: codemap::mk_sp(start_bpos, rdr.pos)
-            });
+            // but comments with only "*"s between two "/"s are not
+            if !is_block_non_doc_comment(acc) {
+                return Some(TokenAndSpan{
+                    tok: token::DOC_COMMENT(rdr.interner.intern(@acc)),
+                    sp: codemap::mk_sp(start_bpos, rdr.pos)
+                });
+            }
         }
     } else {
         loop {