Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions src/etc/licenseck.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
# option. This file may not be copied, modified, or distributed
# except according to those terms.

license0 = """// Copyright 2012-2013 The Rust Project Developers. See the
license0 = """\
// 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.
//
Expand All @@ -19,7 +20,8 @@
// except according to those terms.
"""

license1 = """// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
license1 = """\
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
Expand All @@ -30,7 +32,8 @@
// except according to those terms.
"""

license2 = """// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
license2 = """\
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
Expand All @@ -41,7 +44,8 @@
// except according to those terms.
"""

license3 = """# Copyright 2013 The Rust Project Developers. See the COPYRIGHT
license3 = """\
# Copyright 2013 The Rust Project Developers. See the COPYRIGHT
# file at the top-level directory of this distribution and at
# http://rust-lang.org/COPYRIGHT.
#
Expand All @@ -52,7 +56,19 @@
# except according to those terms.
"""

licenses = [license0, license1, license2, license3]
license4 = """\
// 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.
//
// 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.
"""

licenses = [license0, license1, license2, license3, license4]

exceptions = [
"rt/rust_android_dummy.cpp", # BSD, chromium
Expand Down
66 changes: 38 additions & 28 deletions src/libsyntax/parse/comments.rs
Original file line number Diff line number Diff line change
@@ -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.
//
Expand All @@ -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;
Expand Down Expand Up @@ -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(~"/*!")
}

Expand Down Expand Up @@ -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 {
Expand Down
37 changes: 26 additions & 11 deletions src/libsyntax/parse/lexer.rs
Original file line number Diff line number Diff line change
@@ -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.
//
Expand Down Expand Up @@ -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
Expand All @@ -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); }
_ => ()
Expand All @@ -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> {
Expand All @@ -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 {
Expand Down
29 changes: 24 additions & 5 deletions src/test/pretty/doc-comments.rs
Original file line number Diff line number Diff line change
@@ -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.
//
Expand All @@ -19,24 +19,43 @@ 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
*/

/**
* 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"];
}