|
Blog -
Program
|
|
Written by Dennis Reinhardt
|
|
Friday, 27 February 2009 14:57 |
I recently added comment and string management to my JavaScript indenter. To see the need, consider the statement:
make_call("(");
The left parenthesis text argument is a perfectly valid argument. But, we must have a complicated state machine to correctly determine that the parenthesis in quotes must be ignore for purposes of indenting. It is easier to substitute some other string for the quoted parenthesis, runs the indentation, and then substitute back later.
This logic also applies to comments ... or so it would seem at first blush. However, there are several hidden complexities in comments.
1. It is difficult to know where the comment belongs. For example, consider the input:
if (A) {B} /* comment */
and the code gets rendered in expanded format:
1. if ( 2. A 3.){ 4. B 5.}
If the comment applies mostly to the test performed, we would place it on line 2. If it applied mostly to the action, it would go on line 4. If it applied to the overall statement, it would be promoted to a line of its own prior to line 1 or on the same line at 1. The comment could go on line 5 because that is where it appears in the source.
No choice is always optimal and I picked not moving the comment.
2. Comments ending lines and blank lines should be preserved on output. For example, the input
var A=1; /* one */ var B=2; /* two */
is correct (i.e. will compile) when re-written as
var A=1; /* one */ var B=2; /* two */
but looks wrong to humans. The problem is that when people comment their code, they are also breaking it into natural chunks. Comments are also style hints.
It took me several days to code this correctly. It sure sounds simple.
You can try out the JavaScript indenter [update: site taken down and link removed] online.
Trackback(0)
|
|
Last Updated on Wednesday, 12 May 2010 13:16 |
if (a==b) {yada; yada;} // comment
gets re-arranged to
// comment
if (a==b) {yada; yada}
before indenting is performed.
It is possible to fool the promotion. For example,
if (a==b) {yada; yada; /*comment*/}
will not promote to the beginning of the if, but to the beginning of the block denoted by {...}.
Dennis