Skip to content

Commit 91b60d0

Browse files
committed
php: Skip class and trait use not to confuse typerefs
See https://www.php.net/manual/en/language.oop5.traits.php. Fixes #4007.
1 parent a864459 commit 91b60d0

File tree

6 files changed

+87
-15
lines changed

6 files changed

+87
-15
lines changed

Units/parser-php.r/php-7-4-typed-props-with-use-trait.b/expected.tags

Lines changed: 0 additions & 3 deletions
This file was deleted.

Units/parser-php.r/php-7-4-typed-props-with-use-trait.b/input.php

Lines changed: 0 additions & 12 deletions
This file was deleted.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
SomeTrait input.php /^trait SomeTrait$/;" t
2+
someMethod input.php /^ public function someMethod() {}$/;" f trait:SomeTrait
3+
SomeOtherTrait input.php /^trait SomeOtherTrait$/;" t
4+
someOtherMethod input.php /^ public function someOtherMethod() {}$/;" f trait:SomeOtherTrait
5+
Test1 input.php /^class Test1$/;" c
6+
id input.php /^ public int $id;$/;" v class:Test1 typeref:unknown:int
7+
Test2 input.php /^class Test2$/;" c
8+
id input.php /^ public int $id;$/;" v class:Test2 typeref:unknown:int
9+
Test3 input.php /^class Test3$/;" c
10+
id input.php /^ public int $id;$/;" v class:Test3 typeref:unknown:int
11+
Test4 input.php /^class Test4$/;" c
12+
id input.php /^ public int $id;$/;" v class:Test4 typeref:unknown:int
13+
Test5 input.php /^class Test5$/;" c
14+
id input.php /^ public int $id;$/;" v class:Test5 typeref:unknown:int
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
trait SomeTrait
4+
{
5+
public function someMethod() {}
6+
}
7+
8+
trait SomeOtherTrait
9+
{
10+
public function someOtherMethod() {}
11+
}
12+
13+
class Test1
14+
{
15+
use SomeTrait;
16+
public int $id;
17+
}
18+
19+
class Test2
20+
{
21+
use SomeTrait, SomeOtherTrait;
22+
public int $id;
23+
}
24+
25+
class Test3
26+
{
27+
use SomeTrait { someMethod as private; }
28+
public int $id;
29+
}
30+
31+
class Test4
32+
{
33+
use SomeTrait, SomeOtherTrait { someOtherMethod as protected; }
34+
public int $id;
35+
}
36+
37+
class Test5
38+
{
39+
use \SomeTrait;
40+
public int $id;
41+
}

parsers/php.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1736,6 +1736,36 @@ static bool parseNamespace (tokenInfo *const token)
17361736
return true;
17371737
}
17381738

1739+
/* skip trait uses not to confuse typerefs
1740+
* use Name;
1741+
* use \\Some\\Name;
1742+
* use Name, Other;
1743+
* use Name { method as private; }
1744+
* use Name, Other { otherMethod as public otherName; }
1745+
*
1746+
* Note that curly braces are only allowed on the last `use`, this is a syntax
1747+
* error:
1748+
* use Name { method as private; }, Other;
1749+
* This has to be split in two `use`es or reordered.
1750+
*/
1751+
static bool parseClassUse (tokenInfo *const token)
1752+
{
1753+
do
1754+
{
1755+
readToken (token);
1756+
if (token->type == TOKEN_OPEN_CURLY)
1757+
{
1758+
enterScope (token, NULL, -1);
1759+
return true;
1760+
}
1761+
}
1762+
while (token->type == TOKEN_IDENTIFIER ||
1763+
token->type == TOKEN_BACKSLASH ||
1764+
token->type == TOKEN_COMMA);
1765+
1766+
return (token->type == TOKEN_SEMICOLON);
1767+
}
1768+
17391769
static void enterScope (tokenInfo *const parentToken,
17401770
const vString *const extraScope,
17411771
const int parentKind)
@@ -1798,6 +1828,8 @@ static void enterScope (tokenInfo *const parentToken,
17981828
* is also used to i.e. "import" traits into a class */
17991829
if (vStringLength (token->scope) == 0)
18001830
readNext = parseUse (token);
1831+
else if (parentKind == K_CLASS || parentKind == K_TRAIT)
1832+
readNext = parseClassUse (token);
18011833
break;
18021834

18031835
case KEYWORD_namespace: readNext = parseNamespace (token); break;

0 commit comments

Comments
 (0)