diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs index a8db06fe08546..7a0fdd6b1b0b6 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 e8afd0b96a2a5..4392acdf75e6d 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 { @@ -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 { diff --git a/src/test/pretty/doc-comments.rs b/src/test/pretty/doc-comments.rs index d3e7c7b44dd1b..a866afd240592 100644 --- a/src/test/pretty/doc-comments.rs +++ b/src/test/pretty/doc-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. // @@ -19,6 +19,14 @@ fn b() { //! some single line inner-docs } +////////////////////////////////// +// some single-line non-doc comment preceded by a separator + +////////////////////////////////// +/// some single-line outer-docs preceded by a separator +/// (and trailing whitespaces) +fn c() { } + /* * some multi-line non-doc comment */ @@ -26,17 +34,28 @@ fn b() { /** * some multi-line outer-docs */ -fn c() { } +fn d() { } -fn d() { +fn e() { /*! * some multi-line inner-docs */ } +/********************************/ +/* + * some multi-line non-doc comment preceded by a separator + */ + +/********************************/ +/** + * some multi-line outer-docs preceded by a separator + */ +fn f() { } + #[doc = "unsugared outer doc-comments work also"] -fn e() { } +fn g() { } -fn f() { +fn h() { #[doc = "as do inner ones"]; }