1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-27 04:45:20 +01:00

Allow comments in types (e.g. array shape)

This commit is contained in:
rhertogh 2023-07-15 18:43:47 +02:00
parent 9935b2c71e
commit f378ef1cab
3 changed files with 124 additions and 34 deletions

View File

@ -263,14 +263,6 @@ class CommentAnalyzer
$docblock_type = preg_replace('@^[ \t]*\*@m', '', $docblock_type);
$docblock_type = preg_replace('/,\n\s+}/', '}', $docblock_type);
// Strip out remainders of a line when inline comment is encountered inside curly braces.
if (preg_match('/{(?>[^{}]|(?R))*}/', $docblock_type, $braceMatches, PREG_OFFSET_CAPTURE)) {
$docblock_type =
substr($docblock_type, 0, $braceMatches[0][1])
. preg_replace('%//.*$%m', '', $braceMatches[0][0])
. substr($docblock_type, $braceMatches[0][1] + strlen($braceMatches[0][0]));
}
return str_replace("\n", '', $docblock_type);
}
@ -337,6 +329,17 @@ class CommentAnalyzer
continue;
}
if ($char === '/' && $next_char === '/') {
// Ignore the rest of the current line
$i = strpos($return_block, "\n", $i);
// Remove trailing whitespaces (needed for `sanitizeDocblockType`)
$type = rtrim($type);
$type .= "\n";
continue;
}
if ($char === '[' || $char === '{' || $char === '(' || $char === '<') {
$brackets .= $char;
} elseif ($char === ']' || $char === '}' || $char === ')' || $char === '>') {

View File

@ -1266,6 +1266,59 @@ class AnnotationTest extends TestCase
echo strlen($a);
',
],
'multiLineArrayShapeWithComments' => [
'code' =>
<<<EOT
<?php
/**
* @return array {
* // Array with single quoted keys
* 'single quote keys': array { // Single quoted key
* 'single_quote_key//1': int, // Single quoted key with //
* 'single_quote_key\'//2': string, // Single quoted key with ' and //
* 'single_quote_key\'//\'3': bool, // Single quoted key with 2x ' and //
* 'single_quote_key"//"4': float, // Single quoted key with 2x " and //
* 'single_quote_key"//\'5': array { // Single quoted key with ', " and //
* 'single_quote_key//5//1': int, // Single quoted key with 2x //
* },
* },
* // Array with double quoted keys
* "double quote keys": array { // Double quoted key
* "double_quote_key//1": int, // Double quoted key with //
* "double_quote_key'//2": string, // Double quoted key with ' and //
* "double_quote_key\"//\"3": bool, // Double quoted key with 2x ' and //
* "double_quote_key'//'4": float, // Double quoted key with 2x " and //
* "double_quote_key\"//'5": array { // Double quoted key with ', " and //
* 'double_quote_key//5//1': int, // Double quoted key with 2x //
* },
* },
* }
*/
function f(): array
{
return [
'single quote keys' => [
'single_quote_key//1' => 1,
'single_quote_key\'//2' => 'string',
'single_quote_key\'//\'3' => true,
'single_quote_key"//"4' => 0.1,
'single_quote_key"//\'5' => [
'single_quote_key//5//1' => 1,
],
],
"double quote keys" => [
"double_quote_key//1" => 1,
"double_quote_key'//2" => 'string',
"double_quote_key\"//\"3" => true,
"double_quote_key'//'4" => 0.1,
"double_quote_key\"//'5" => [
"double_quote_key//5//1" => 1,
],
],
];
}
EOT,
],
];
}

View File

@ -76,32 +76,6 @@ class CommentAnalyzerTest extends BaseTestCase
$this->assertSame('Use a string', $comment_docblock[0]->description);
}
/**
* @dataProvider providerSanitizeDocblockType
*/
public function testSanitizeDocblockType(string $doc_block_type, string $expected): void
{
$this->assertSame($expected, CommentAnalyzer::sanitizeDocblockType($doc_block_type));
}
public function providerSanitizeDocblockType(): iterable
{
return [
'arrayShapeComments' => [
'doc_block_type' => <<<EOT
array{ // Comment
// Comment
key1: int, // Comment
// Comment
key2: {, // Comment
key2_1: string, // Comment
} // Comment
}
EOT,
'expected' => 'array{ key1: int, key2: {, key2_1: string, } }',
],
];
}
/**
* @dataProvider providerSplitDocLine
@ -152,6 +126,66 @@ class CommentAnalyzerTest extends BaseTestCase
* }',
],
],
'arrayShapeWithComments' => [
'doc_line' =>
'array { // Comment
* // Comment
* a: int, // Comment
* // Comment
* b: string, // Comment
* // Comment
* }',
'expected' => [
"array {
*
* a: int,
*
* b: string,
*
* }",
],
],
'arrayShapeWithSlashesInKeys' => [
'doc_line' =>
<<<EOT
array {
* // Single quote keys
* array {
* 'single_quote_key//1': int, // Comment with ' in it
* 'single_quote_key//2': int, // Comment with ' in it
* 'single_quote_key\'//\'3': int, // Comment with ' in it
* 'single_quote_key"//"4': int, // Comment with ' in it
* },
* // Double quote keys
* array {
* "double_quote_key//1": int, // Comment with " in it
* "double_quote_key//2": int, // Comment with " in it
* "double_quote_key\"//\"3": int, // Comment with " in it
* "double_quote_key'//'4": int, // Comment with " in it
* }
* }
EOT,
'expected' => [
<<<EOT
array {
*
* array {
* 'single_quote_key//1': int,
* 'single_quote_key//2': int,
* 'single_quote_key\'//\'3': int,
* 'single_quote_key"//"4': int,
* },
*
* array {
* "double_quote_key//1": int,
* "double_quote_key//2": int,
* "double_quote_key\"//\"3": int,
* "double_quote_key'//'4": int,
* }
* }
EOT,
],
],
'func_num_args' => [
'doc_line' =>
'(