Add indentation C comment heuristics

See foonathan/standardese#84.
This commit is contained in:
Jonathan Müller 2017-12-06 19:34:36 +01:00
commit b2121b19c2
2 changed files with 91 additions and 6 deletions

View file

@ -202,6 +202,7 @@ namespace
{ {
*result_ += "#line " + std::to_string(line) + "\n"; *result_ += "#line " + std::to_string(line) + "\n";
cur_line_ = line; cur_line_ = line;
cur_column_ = 0;
} }
} }
@ -212,8 +213,13 @@ namespace
for (auto c : str) for (auto c : str)
{ {
*result_ += c; *result_ += c;
++cur_column_;
if (c == '\n') if (c == '\n')
{
++cur_line_; ++cur_line_;
cur_column_ = 0;
}
} }
} }
@ -222,8 +228,13 @@ namespace
if (write_ == true) if (write_ == true)
{ {
result_->push_back(*ptr_); result_->push_back(*ptr_);
++cur_column_;
if (*ptr_ == '\n') if (*ptr_ == '\n')
{
++cur_line_; ++cur_line_;
cur_column_ = 0;
}
} }
++ptr_; ++ptr_;
} }
@ -247,10 +258,15 @@ namespace
void skip_with_linecount() noexcept void skip_with_linecount() noexcept
{ {
if (*ptr_ == '\n' && write_ == true) if (write_ == true)
{
++cur_column_;
if (*ptr_ == '\n')
{ {
result_->push_back('\n'); result_->push_back('\n');
++cur_line_; ++cur_line_;
cur_column_ = 0;
}
} }
++ptr_; ++ptr_;
@ -281,6 +297,11 @@ namespace
return cur_line_; return cur_line_;
} }
unsigned cur_column() const noexcept
{
return cur_column_;
}
bool was_newl() const noexcept bool was_newl() const noexcept
{ {
return result_->empty() || result_->back() == '\n'; return result_->empty() || result_->back() == '\n';
@ -288,7 +309,7 @@ namespace
private: private:
ts::object_ref<std::string> result_; ts::object_ref<std::string> result_;
unsigned cur_line_; unsigned cur_line_, cur_column_;
const char* ptr_; const char* ptr_;
ts::flag write_; ts::flag write_;
}; };
@ -398,9 +419,14 @@ namespace
detail::pp_doc_comment result; detail::pp_doc_comment result;
result.kind = detail::pp_doc_comment::c; result.kind = detail::pp_doc_comment::c;
auto indent = p.cur_column() + 3;
if (starts_with(p, " ")) if (starts_with(p, " "))
{
// skip one whitespace at most // skip one whitespace at most
p.skip(); p.skip();
++indent;
}
while (!starts_with(p, "*/")) while (!starts_with(p, "*/"))
{ {
@ -415,8 +441,16 @@ namespace
result.comment += '\n'; result.comment += '\n';
// skip indentation // skip indentation
while (starts_with(p, " ")) for (auto i = 0u; i < indent && starts_with(p, " "); ++i)
p.skip(); p.skip();
auto extra_indent = 0u;
while (starts_with(p, " "))
{
++extra_indent;
p.skip();
}
// skip continuation star, if any // skip continuation star, if any
if (starts_with(p, "*") && !starts_with(p, "*/")) if (starts_with(p, "*") && !starts_with(p, "*/"))
{ {
@ -425,6 +459,11 @@ namespace
// skip one whitespace at most // skip one whitespace at most
p.skip(); p.skip();
} }
else
{
// insert extra indent again
result.comment += std::string(extra_indent, ' ');
}
} }
else else
{ {

View file

@ -186,6 +186,52 @@ lines
REQUIRE((file->unmatched_comments().size() == 6u + 1u)); REQUIRE((file->unmatched_comments().size() == 6u + 1u));
} }
TEST_CASE("comment content")
{
auto code = R"(
/// simple comment
///no space
/// multi
/// line
/// comment
/** C comment */
/**C comment no space*/
/** Multiline
C
comment */
/** Multiline
C
comment
with
indent */
/** Multiline
* C
* comment
* with
* indent
* star */
)";
auto file = parse({}, "comment-content.cpp", code);
auto comments = file->unmatched_comments();
REQUIRE((comments.size() == 8u));
REQUIRE(comments[0u].content == "simple comment");
REQUIRE(comments[1u].content == "no space");
REQUIRE(comments[2u].content == "multi\nline\ncomment");
REQUIRE(comments[3u].content == "C comment");
REQUIRE(comments[4u].content == "C comment no space");
REQUIRE(comments[5u].content == "Multiline\nC\ncomment");
REQUIRE(comments[6u].content == "Multiline\nC\n comment\n with\n indent");
REQUIRE(comments[7u].content == "Multiline\nC\ncomment\nwith\nindent\nstar");
}
TEST_CASE("comment matching") TEST_CASE("comment matching")
{ {
auto code = R"( auto code = R"(