Skip to content

Commit ed8d676

Browse files
authored
Merge pull request #123 from bigfoot90/fix-comment-parsing
Fix comment parsing
2 parents 0c5d875 + 5127520 commit ed8d676

File tree

6 files changed

+50
-80
lines changed

6 files changed

+50
-80
lines changed

src/Lexer.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,6 @@ public function parseComment()
572572
) {
573573
$token .= $this->str[$this->last];
574574
}
575-
$token .= "\n"; // Adding the line ending.
576575
return new Token($token, Token::TYPE_COMMENT, Token::FLAG_COMMENT_BASH);
577576
}
578577

@@ -641,7 +640,6 @@ public function parseComment()
641640
) {
642641
$token .= $this->str[$this->last];
643642
}
644-
$token .= "\n"; // Adding the line ending.
645643
}
646644

647645
return new Token($token, Token::TYPE_COMMENT, Token::FLAG_COMMENT_SQL);

src/Utils/Formatter.php

Lines changed: 21 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -326,14 +326,6 @@ public function formatList($list)
326326
*/
327327
$prev = null;
328328

329-
/**
330-
* Comments are being formatted separately to maintain the whitespaces
331-
* before and after them.
332-
*
333-
* @var string
334-
*/
335-
$comment = '';
336-
337329
// In order to be able to format the queries correctly, the next token
338330
// must be taken into consideration. The loop below uses two pointers,
339331
// `$prev` and `$curr` which store two consecutive tokens.
@@ -342,39 +334,26 @@ public function formatList($list)
342334
/**
343335
* Token parsed at this moment.
344336
*
345-
* @var Token
337+
* @var Token $curr
346338
*/
347339
$curr = $list->tokens[$list->idx];
348340

349341
if ($curr->type === Token::TYPE_WHITESPACE) {
350342
// Whitespaces are skipped because the formatter adds its own.
351343
continue;
352-
} elseif ($curr->type === Token::TYPE_COMMENT) {
353-
// Whether the comments should be parsed.
354-
if (!empty($this->options['remove_comments'])) {
355-
continue;
356-
}
357-
358-
if ($list->tokens[$list->idx - 1]->type === Token::TYPE_WHITESPACE) {
359-
// The whitespaces before and after are preserved for
360-
// formatting reasons.
361-
$comment .= $list->tokens[$list->idx - 1]->token;
362-
}
363-
$comment .= $this->toString($curr);
364-
if (($list->tokens[$list->idx + 1]->type === Token::TYPE_WHITESPACE)
365-
&& ($list->tokens[$list->idx + 2]->type !== Token::TYPE_COMMENT)
366-
) {
367-
// Adding the next whitespace only there is no comment that
368-
// follows it immediately which may cause adding a
369-
// whitespace twice.
370-
$comment .= $list->tokens[$list->idx + 1]->token;
371-
}
344+
}
372345

373-
// Everything was handled here, no need to continue.
346+
if ($curr->type === Token::TYPE_COMMENT && $this->options['remove_comments']) {
347+
// Skip Comments if option `remove_comments` is enabled
374348
continue;
375349
}
376350

377351
// Checking if pointers were initialized.
352+
/**
353+
* Previous Token.
354+
*
355+
* @var Token $prev
356+
*/
378357
if ($prev !== null) {
379358
// Checking if a new clause started.
380359
if (static::isClause($prev) !== false) {
@@ -453,12 +432,6 @@ public function formatList($list)
453432
$shortGroup = false;
454433
}
455434

456-
// Delimiter must be placed on the same line with the last
457-
// clause.
458-
if ($curr->type === Token::TYPE_DELIMITER) {
459-
$lineEnded = false;
460-
}
461-
462435
// Adding the token.
463436
$ret .= $this->toString($prev);
464437

@@ -469,32 +442,29 @@ public function formatList($list)
469442
$indent = 0;
470443
}
471444

472-
if ($curr->type !== Token::TYPE_COMMENT) {
473-
$ret .= $this->options['line_ending']
474-
. str_repeat($this->options['indentation'], $indent);
475-
}
445+
$ret .= $this->options['line_ending']
446+
. str_repeat($this->options['indentation'], $indent);
447+
476448
$lineEnded = false;
477449
} else {
478450
// If the line ended there is no point in adding whitespaces.
479451
// Also, some tokens do not have spaces before or after them.
480-
if (!(($prev->type === Token::TYPE_OPERATOR && ($prev->value === '.' || $prev->value === '('))
481-
// No space after . (
482-
|| ($curr->type === Token::TYPE_OPERATOR && ($curr->value === '.' || $curr->value === ',' || $curr->value === '(' || $curr->value === ')'))
483-
// No space before . , ( )
484-
|| $curr->type === Token::TYPE_DELIMITER && mb_strlen($curr->value, 'UTF-8') < 2)
452+
if (
485453
// A space after delimiters that are longer than 2 characters.
486-
|| $prev->value === 'DELIMITER'
454+
$prev->value === 'DELIMITER'
455+
|| !(
456+
($prev->type === Token::TYPE_OPERATOR && ($prev->value === '.' || $prev->value === '('))
457+
// No space after . (
458+
|| ($curr->type === Token::TYPE_OPERATOR && ($curr->value === '.' || $curr->value === ',' || $curr->value === '(' || $curr->value === ')'))
459+
// No space before . , ( )
460+
|| $curr->type === Token::TYPE_DELIMITER && mb_strlen($curr->value, 'UTF-8') < 2
461+
)
487462
) {
488463
$ret .= ' ';
489464
}
490465
}
491466
}
492467

493-
if (!empty($comment)) {
494-
$ret .= $comment;
495-
$comment = '';
496-
}
497-
498468
// Iteration finished, consider current token as previous.
499469
$prev = $curr;
500470
}

tests/Utils/CLITest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public function highlightParams()
3939
),
4040
array(
4141
array('q' => 'SELECT /* comment */ 1 /* other */', 'f' => 'text'),
42-
"SELECT\n /* comment */ 1 /* other */\n",
42+
"SELECT\n /* comment */ 1 /* other */\n",
4343
0,
4444
),
4545
array(

tests/Utils/FormatterTest.php

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -249,13 +249,36 @@ public function formatQueries()
249249
'&nbsp;&nbsp;&nbsp;&nbsp;<span class="sql-number">1</span>',
250250
array('type' => 'html'),
251251
),
252+
array(
253+
'SELECT /* Comment */ 1' . "\n" .
254+
'FROM tbl # Comment' . "\n" .
255+
'WHERE 1 -- Comment',
256+
'SELECT' . "\n" .
257+
' /* Comment */ 1' . "\n" .
258+
'FROM' . "\n" .
259+
' tbl # Comment' . "\n" .
260+
'WHERE' . "\n" .
261+
' 1 -- Comment',
262+
array('type' => 'text'),
263+
),
252264
array(
253265
'SELECT 1 # Comment',
254266
'<span class="sql-reserved">SELECT</span>' . '<br/>' .
255-
'&nbsp;&nbsp;&nbsp;&nbsp;<span class="sql-number">1</span> <span class="sql-comment"># Comment' . "\n" .
256-
'</span>',
267+
'&nbsp;&nbsp;&nbsp;&nbsp;<span class="sql-number">1</span> <span class="sql-comment"># Comment</span>',
268+
array('type' => 'html'),
269+
),
270+
array(
271+
'SELECT 1 -- comment',
272+
'<span class="sql-reserved">SELECT</span>' . '<br/>' .
273+
'&nbsp;&nbsp;&nbsp;&nbsp;<span class="sql-number">1</span> <span class="sql-comment">-- comment</span>',
257274
array('type' => 'html'),
258275
),
276+
array(
277+
'SELECT 1 -- comment',
278+
'<span class="sql-reserved">SELECT</span>' . '<br/>' .
279+
'&nbsp;&nbsp;&nbsp;&nbsp;<span class="sql-number">1</span>',
280+
array('type' => 'html', 'remove_comments' => true),
281+
),
259282
array(
260283
'SELECT HEX("1")',
261284
'<span class="sql-reserved">SELECT</span>' . '<br/>' .
@@ -317,19 +340,6 @@ public function formatQueries()
317340
'&nbsp;&nbsp;&nbsp;&nbsp;superado = <span class="sql-number">0</span>',
318341
array('type' => 'html'),
319342
),
320-
array(
321-
'SELECT 1 -- comment',
322-
'<span class="sql-reserved">SELECT</span>' . '<br/>' .
323-
'&nbsp;&nbsp;&nbsp;&nbsp;<span class="sql-number">1</span> <span class="sql-comment">-- comment' . "\n" .
324-
'</span>',
325-
array('type' => 'html'),
326-
),
327-
array(
328-
'SELECT 1 -- comment',
329-
'<span class="sql-reserved">SELECT</span>' . '<br/>' .
330-
'&nbsp;&nbsp;&nbsp;&nbsp;<span class="sql-number">1</span>',
331-
array('type' => 'html', 'remove_comments' => true),
332-
),
333343
array(
334344
'CREATE TABLE IF NOT EXISTS `pma__bookmark` (' . "\n" .
335345
' `id` int(11) NOT NULL auto_increment,' . "\n" .

tests/data/lexer/lexComment.out

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,5 @@ SELECT /*!50000 STRAIGHT_JOIN */ col1 FROM table1, table2 /* select query */
44
-- comment 2";s:5:"lexer";O:15:"SqlParser\Lexer":8:{s:6:"strict";b:0;s:3:"str";s:110:"# comment
55
SELECT /*!50000 STRAIGHT_JOIN */ col1 FROM table1, table2 /* select query */
66
-- comment
7-
-- comment 2";s:3:"len";i:110;s:4:"last";i:111;s:4:"list";O:20:"SqlParser\TokensList":3:{s:6:"tokens";a:23:{i:0;O:15:"SqlParser\Token":5:{s:5:"token";s:10:"# comment
8-
";s:5:"value";s:10:"# comment
9-
";s:4:"type";i:4;s:5:"flags";i:1;s:8:"position";i:0;}i:1;O:15:"SqlParser\Token":5:{s:5:"token";s:6:"SELECT";s:5:"value";s:6:"SELECT";s:4:"type";i:1;s:5:"flags";i:3;s:8:"position";i:10;}i:2;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:16;}i:3;O:15:"SqlParser\Token":5:{s:5:"token";s:8:"/*!50000";s:5:"value";s:8:"/*!50000";s:4:"type";i:4;s:5:"flags";i:10;s:8:"position";i:17;}i:4;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:25;}i:5;O:15:"SqlParser\Token":5:{s:5:"token";s:13:"STRAIGHT_JOIN";s:5:"value";s:13:"STRAIGHT_JOIN";s:4:"type";i:1;s:5:"flags";i:3;s:8:"position";i:26;}i:6;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:39;}i:7;O:15:"SqlParser\Token":5:{s:5:"token";s:2:"*/";s:5:"value";s:2:"*/";s:4:"type";i:4;s:5:"flags";i:2;s:8:"position";i:40;}i:8;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:42;}i:9;O:15:"SqlParser\Token":5:{s:5:"token";s:4:"col1";s:5:"value";s:4:"col1";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:43;}i:10;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:47;}i:11;O:15:"SqlParser\Token":5:{s:5:"token";s:4:"FROM";s:5:"value";s:4:"FROM";s:4:"type";i:1;s:5:"flags";i:3;s:8:"position";i:48;}i:12;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:52;}i:13;O:15:"SqlParser\Token":5:{s:5:"token";s:6:"table1";s:5:"value";s:6:"table1";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:53;}i:14;O:15:"SqlParser\Token":5:{s:5:"token";s:1:",";s:5:"value";s:1:",";s:4:"type";i:2;s:5:"flags";i:16;s:8:"position";i:59;}i:15;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:60;}i:16;O:15:"SqlParser\Token":5:{s:5:"token";s:6:"table2";s:5:"value";s:6:"table2";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:61;}i:17;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:67;}i:18;O:15:"SqlParser\Token":5:{s:5:"token";s:18:"/* select query */";s:5:"value";s:18:"/* select query */";s:4:"type";i:4;s:5:"flags";i:2;s:8:"position";i:68;}i:19;O:15:"SqlParser\Token":5:{s:5:"token";s:1:"
10-
";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:86;}i:20;O:15:"SqlParser\Token":5:{s:5:"token";s:11:"-- comment
11-
";s:5:"value";s:11:"-- comment
12-
";s:4:"type";i:4;s:5:"flags";i:4;s:8:"position";i:87;}i:21;O:15:"SqlParser\Token":5:{s:5:"token";s:13:"-- comment 2
13-
";s:5:"value";s:13:"-- comment 2
14-
";s:4:"type";i:4;s:5:"flags";i:4;s:8:"position";i:98;}i:22;O:15:"SqlParser\Token":5:{s:5:"token";N;s:5:"value";N;s:4:"type";i:9;s:5:"flags";i:0;s:8:"position";N;}}s:5:"count";i:23;s:3:"idx";i:0;}s:9:"delimiter";s:1:";";s:12:"delimiterLen";i:1;s:6:"errors";a:0:{}}s:6:"parser";N;s:6:"errors";a:2:{s:5:"lexer";a:0:{}s:6:"parser";a:0:{}}}
7+
-- comment 2";s:3:"len";i:110;s:4:"last";i:111;s:4:"list";O:20:"SqlParser\TokensList":3:{s:6:"tokens";a:23:{i:0;O:15:"SqlParser\Token":5:{s:5:"token";s:9:"# comment";s:5:"value";s:9:"# comment";s:4:"type";i:4;s:5:"flags";i:1;s:8:"position";i:0;}i:1;O:15:"SqlParser\Token":5:{s:5:"token";s:6:"SELECT";s:5:"value";s:6:"SELECT";s:4:"type";i:1;s:5:"flags";i:3;s:8:"position";i:10;}i:2;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:16;}i:3;O:15:"SqlParser\Token":5:{s:5:"token";s:8:"/*!50000";s:5:"value";s:8:"/*!50000";s:4:"type";i:4;s:5:"flags";i:10;s:8:"position";i:17;}i:4;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:25;}i:5;O:15:"SqlParser\Token":5:{s:5:"token";s:13:"STRAIGHT_JOIN";s:5:"value";s:13:"STRAIGHT_JOIN";s:4:"type";i:1;s:5:"flags";i:3;s:8:"position";i:26;}i:6;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:39;}i:7;O:15:"SqlParser\Token":5:{s:5:"token";s:2:"*/";s:5:"value";s:2:"*/";s:4:"type";i:4;s:5:"flags";i:2;s:8:"position";i:40;}i:8;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:42;}i:9;O:15:"SqlParser\Token":5:{s:5:"token";s:4:"col1";s:5:"value";s:4:"col1";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:43;}i:10;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:47;}i:11;O:15:"SqlParser\Token":5:{s:5:"token";s:4:"FROM";s:5:"value";s:4:"FROM";s:4:"type";i:1;s:5:"flags";i:3;s:8:"position";i:48;}i:12;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:52;}i:13;O:15:"SqlParser\Token":5:{s:5:"token";s:6:"table1";s:5:"value";s:6:"table1";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:53;}i:14;O:15:"SqlParser\Token":5:{s:5:"token";s:1:",";s:5:"value";s:1:",";s:4:"type";i:2;s:5:"flags";i:16;s:8:"position";i:59;}i:15;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:60;}i:16;O:15:"SqlParser\Token":5:{s:5:"token";s:6:"table2";s:5:"value";s:6:"table2";s:4:"type";i:0;s:5:"flags";i:0;s:8:"position";i:61;}i:17;O:15:"SqlParser\Token":5:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:67;}i:18;O:15:"SqlParser\Token":5:{s:5:"token";s:18:"/* select query */";s:5:"value";s:18:"/* select query */";s:4:"type";i:4;s:5:"flags";i:2;s:8:"position";i:68;}i:19;O:15:"SqlParser\Token":5:{s:5:"token";s:1:"
8+
";s:5:"value";s:1:" ";s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:86;}i:20;O:15:"SqlParser\Token":5:{s:5:"token";s:10:"-- comment";s:5:"value";s:10:"-- comment";s:4:"type";i:4;s:5:"flags";i:4;s:8:"position";i:87;}i:21;O:15:"SqlParser\Token":5:{s:5:"token";s:12:"-- comment 2";s:5:"value";s:12:"-- comment 2";s:4:"type";i:4;s:5:"flags";i:4;s:8:"position";i:98;}i:22;O:15:"SqlParser\Token":5:{s:5:"token";N;s:5:"value";N;s:4:"type";i:9;s:5:"flags";i:0;s:8:"position";N;}}s:5:"count";i:23;s:3:"idx";i:0;}s:9:"delimiter";s:1:";";s:12:"delimiterLen";i:1;s:6:"errors";a:0:{}}s:6:"parser";N;s:6:"errors";a:2:{s:5:"lexer";a:0:{}s:6:"parser";a:0:{}}}

0 commit comments

Comments
 (0)