Thanks to
dartdoc
(and some minor hacking), I have some lovely documentation for Hipster MVC, the awesome MVC framework written in Dart.I did run into a problem that is still bugging me. The dartdoc documentation format is written in markdown and is supposed to be able to be embedded in any kind of comment. I had originally used triple-slash comments:
/// Application routers must subclass [HipsterRouter], definining at least the
/// [routes] getter:
///
/// class MyRouter extends HipsterRouter {
/// List get routes() =>
/// [
/// ['page/:num', pageNum, 'page']
/// ];
/// //
/// pageNum(num) {
/// var el = document.query('body');
/// el.innerHTML = _pageNumTemplate(num);
/// }
/// }
HipsterRouter() {
on = new RouterEvents();
this._initializeRoutes();
}
But was forced to switch to slash-star comments instead: /**
* Application routers must subclass [HipsterRouter], definining at least the
* [routes] getter:
*
* class MyRouter extends HipsterRouter {
* List get routes() =>
* [
* ['page/:num', pageNum, 'page']
* ];
* //
* pageNum(num) {
* var el = document.query('body');
* el.innerHTML = _pageNumTemplate(num);
* }
* }
*/
HipsterRouter() {
on = new RouterEvents();
this._initializeRoutes();
}
I rather like the star-slash better (though I must have preferred three-slashes at some point). Somehow slash-start is less noisy. Still, it bugs me that triple slashes stopped working.I eventually track the problem down to the
CommentMap
in dart-sdk/pkg/dartdoc/lib/src/dartdoc/comment_map.dart
. As the name suggests, the comment map links comments to spans of code. The problem starts with the tokenizer that breaks comments (and other things) into chunks. The slash-star formatted chunks are easy for the tokenizer to identify as being part of a whole.
The triple-slash comments, however, are tokenized as separate lines. This leaves it to the calling context to decide if the tokens belong together. In
CommentMap
, this is handled by the private _parseComment
method, which handles it as follows: _parseComments(Source source) {
// ...
while (token.kind != dart2js.EOF_TOKEN) {
if (token.kind == dart2js.COMMENT_TOKEN) {
// ...
} else if (text.startsWith('///')) {
var line = text.substring(3);
// Allow a leading space.
if (line.startsWith(' ')) line = line.substring(1);
if (lastComment == null) {
lastComment = line;
} else {
lastComment = "$lastComment$line";
}
}
} else if (token.kind == dart2js.HASH_TOKEN) {
// ...
}
}
The problem is not obvious from this context, but the tokens have all been stripped of whitespace—including newlines. Since this section of code is responsible for collecting triple-slash comments, it needs the newlines. Without them, this dartdoc: ///....
/// [routes] getter:
///
/// class MyRouter extends HipsterRouter {
/// ...
Is collected as:... [routes] getter: class MyRouter extends HipsterRouter { ...The solution is simple enough, I add a newline character in between the
lastComment
so far, and the newly collected line: // ...
lastComment = "$lastComment\n$line";
// ...
With that, I can again use the triple-slash format to produce pretty documentation:Looking through the code over on github, it does not appear as though this has been fixed yet. So, unless someone fixes this in the meantime, it seems like I have a good excuse to contribute a fix to the Dart SDK. Tomorrow.
Day #559
No comments:
Post a Comment