libsyntax: don't parse ////, /***/ as doc comments

This commit is contained in:
Kang Seonghoon 2013-02-13 11:37:07 +09:00
parent 1a394e57f7
commit 6d98ca94cc
3 changed files with 89 additions and 45 deletions

View File

@ -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) == '*' {
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);
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 {

View File

@ -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 {

View File

@ -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
*/
}
#[doc = "unsugared outer doc-comments work also"]
fn e() { }
/********************************/
/*
* some multi-line non-doc comment preceded by a separator
*/
fn f() {
/********************************/
/**
* some multi-line outer-docs preceded by a separator
*/
fn f() { }
#[doc = "unsugared outer doc-comments work also"]
fn g() { }
fn h() {
#[doc = "as do inner ones"];
}