Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion PHPCSUtils/Utils/FunctionDeclarations.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ public static function getName(File $phpcsFile, $stackPtr)
* - `"has_body"` index could be set to `true` for functions without body in the case of
* parse errors or live coding.
* - Defensive coding against incorrect calls to this method.
* - Defensive coding against incorrect results due to parse errors in the code under scan.
* - More efficient checking whether a function has a body.
* - Support for PHP 8.0 identifier name tokens in return types, cross-version PHP & PHPCS.
* - The results of this function call are cached during a PHPCS run for faster response times.
Expand Down Expand Up @@ -277,7 +278,10 @@ public static function getProperties(File $phpcsFile, $stackPtr)
break;
}

if ($scopeOpener === null && $tokens[$i]['code'] === \T_SEMICOLON) {
if ($scopeOpener === null
&& ($tokens[$i]['code'] === \T_SEMICOLON
|| $tokens[$i]['code'] === \T_OPEN_CURLY_BRACKET)
) {
// End of abstract/interface function definition.
break;
}
Expand Down
4 changes: 4 additions & 0 deletions Tests/Utils/FunctionDeclarations/GetPropertiesDiffTest.inc
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<?php

/* testInvalidTypeParseError */
// This test MUST have code containing name tokens after this code sample.
function InvalidType($param): ?\&\SomeType {}

/* testMessyPhpcsAnnotationsMethod */
trait FooTrait {
/**
Expand Down
26 changes: 26 additions & 0 deletions Tests/Utils/FunctionDeclarations/GetPropertiesDiffTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,32 @@ public function testNonExistentToken()
FunctionDeclarations::getProperties(self::$phpcsFile, 10000);
}

/**
* Test that for invalid code, the return type parsing doesn't grab too many tokens.
*
* @return void
*/
public function testInvalidTypeParseError()
{
$php8Names = parent::usesPhp8NameTokens();

// Offsets are relative to the T_FUNCTION token.
$expected = [
'scope' => 'public',
'scope_specified' => false,
'return_type' => ($php8Names === true) ? '?\\\\SomeType' : '?\\&\\SomeType',
'return_type_token' => 9,
'return_type_end_token' => ($php8Names === true) ? 11 : 12,
'nullable_return_type' => true,
'is_abstract' => false,
'is_final' => false,
'is_static' => false,
'has_body' => true,
];

$this->getPropertiesTestHelper('/* ' . __FUNCTION__ . ' */', $expected);
}

/**
* Test handling of the PHPCS 3.2.0+ annotations between the keywords.
*
Expand Down