This is an archive of the discontinued LLVM Phabricator instance.

clang-format: Add reflow capability to line comment formatting
Needs ReviewPublic

Authored by faisalv on Jun 29 2014, 5:20 PM.
This revision needs review, but there are no reviewers specified.

Details

Reviewers
None
Summary

Based on an email discussion with Manuel Klimek - (and thoughts from Daniel Jasper and Alexander Kornienko), I have hacked up a quickish patch to allow reflow of line comments (works for me reasonably well in Visual Studio) for clang-format.

The idea is to not just insert a break into a line comment if it exceeds the comment limit, but to consider its subsequent line-comments and reflow and reformat the block of line-commenst. That way you can add a word anywhere in your block of line-comments, clang-format them, and feel *reasonably*;) confident you are within your column limit without abrupt breaks.

The heuristic I have currently used to decide to merge a block of comments is as follows:
If in editor mode (which I kludge-ily/brittley detect - is there a cleaner way to determine this and exactly what text is selected?):

  • for all line comments that are not separated by an additional new line, or an empty comment, or more than 3 forward slashes in sequence, they are joined and reflowed.

If in non-editor mode (which the patch actually has currently disabled - see where I have mistakenly commented out: //clang::format::isInEditorMode();), once we encounter a comment that is on a line that exceeds the column limit, only then do we start joining and then keep joining comment lines until we have enough lines to reflow the comment, and then stop (including following the rules for non-joining in editor mode).

I currently use the comment prefix of the line that is being broken (so just because the first line-comment in the block of comments is with three slashes, does not entail all of them being formatted with three, even if they were written with two) - not sure if that was the most desirable thing to do. Eitherway is ok with me.

I do not know how to run the unittests, since I've mostly worked on clang, and have not had to use the 'unittest' testing framework - so I could really use some help writing tests - Not only to show me how to write and *run* the unittests (or point me to the docs) on a windows environment but also to actually write some tests for this.

My visually confirmed tests are pasted here:
Before: http://pastebin.com/cmGYqBcc
After: http://pastebin.com/ZiRKjMB5

Any constructive feedback and or guidance will be greatly appreciated.

Thanks!

Diff Detail

Event Timeline

faisalv updated this revision to Diff 10968.Jun 29 2014, 5:20 PM
faisalv retitled this revision from to clang-format: Add reflow capability to line comment formatting.
faisalv updated this object.
faisalv edited the test plan for this revision. (Show Details)
faisalv added reviewers: djasper, klimek, alexfh, rsmith.
faisalv added a subscriber: Unknown Object (MLST).
alexfh edited edge metadata.Jun 30 2014, 7:24 AM

Thanks for working on this!

Before I do a thorough review, I'd like you to address a few high-level issues and remove commented code (it shouldn't make it to the repository anyway, and it doesn't help understanding the intentions, FIXME comments work better).

It would be more convenient for reviewers if you generated diff using "diff -u10000" to include all context. Alternatively, you could use the Phabricator's arcanist command-line tool to send your patch for review. Both are fine, choose whatever works better for you.

Second, I would ask you to add your tests to unittest/Format/FormatTest.cpp and run the whole test suite. Unfortunately, I have no idea on how to run clang unittests in Windows. In Linux depending on the way the project is built, running all Clang tests can be done in one of the following ways:

  • in CMake+make builds - "make check-clang"
  • in configure+make builds it should also be "make check-clang"
  • in CMake+ninja builds it can be done using "ninja check-all", iirc.

I'm not sure if the steps described in http://llvm.org/docs/GettingStartedVS.html are enough to run unit tests or not. The best way to know is to write a failing test and to try. If you don't find a way to run the unit tests on Windows, you can always install a copy of Ubuntu on a virtual machine and use it for testing.

Could you also test your patch on some real code? LLVM/Clang sources can be a good test case, just reduce the column limit (to 60 or 30, for example) to have the line breaking/merging code work. This way you can find many test cases you didn't think about.

For example, we need to avoid joining lines with code and various ascii-art, even when the column limit is exceeded and they end up being broken. I'd go with even more conservative approach: detect boundaries of what looks like paragraphs of text, and join lines only within those boundaries. I'm not sure if this fits into your current approach, and this is why I suggested to parse consecutive block comments as a single BreakableToken. This way one could also implement reflowing of block comments in a similar manner.

See a few more random comments inline.

lib/Format/ContinuationIndenter.cpp
947

Any reason to do use lambda here?

1066

We don't use braces around single-line "if" bodies.

1111

We don't use braces around single-line "if" bodies.

1121

Please remove the empty line.

lib/Format/Format.cpp
586

This name doesn't say what the function really does. You probably meant "character" not "token". Token is a lexical entity, e.g. the whole comment. And the implementation is suboptimal. If you want to check that the comment has a form of any number of slashes followed by any number of spaces, then you could write:

Text.rtrim().ltrim("/").empty();

instead.

What are the cases you want this function to detect?

1178

Any reason to do use lambda here?

tools/clang-format/ClangFormat.cpp
307

I'd rather add a separate style option controlling how/when we want to join comments (say, ReflowComments=Never|LongLines|Always). This way what "editor mode" means could be configured externally and explicitly.

330

Please remove trailing empty lines here and in other places.

klimek edited edge metadata.Sep 8 2014, 3:06 AM

This was open for a long time - is this still ongoing?

sorry - been all sorts of busy with my job - might not be able to get
to this for a few months - if some one wishes to move the work forward
(or re-engineer from scratch) meanwhile -
please do so! =)

Faisal Vali

klimek resigned from this revision.Sep 8 2014, 4:40 AM
klimek removed a reviewer: klimek.

Ok, just removing myself as reviewer than, so it doesn't clog my dashboard...

alexfh removed a reviewer: alexfh.Sep 8 2014, 6:51 AM
djasper resigned from this revision.Apr 12 2015, 1:22 AM
djasper removed a reviewer: djasper.
faisalv updated this object.Nov 30 2015, 9:15 PM
faisalv removed a reviewer: rsmith.
faisalv removed subscribers: cfe-commits, klimek.