Skip to content

Commit 21edc53

Browse files
committed
Remove legacy nullable format
Compound types containg `?` nullables are deprecated in php, and not supported by phpstan. In v1 we had a work around for this but this was slow and fragile. The nullable format has been deprecated since 2023 and is now removed. We still produce a deprecation error to warn people about invalid type handling. fixes #184
1 parent 0c955dc commit 21edc53

File tree

2 files changed

+40
-43
lines changed

2 files changed

+40
-43
lines changed

src/TypeResolver.php

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -199,14 +199,8 @@ final class TypeResolver
199199
public function __construct(?FqsenResolver $fqsenResolver = null)
200200
{
201201
$this->fqsenResolver = $fqsenResolver ?: new FqsenResolver();
202-
203-
if (class_exists(ParserConfig::class)) {
204-
$this->typeParser = new TypeParser(new ParserConfig([]), new ConstExprParser(new ParserConfig([])));
205-
$this->lexer = new Lexer(new ParserConfig([]));
206-
} else {
207-
$this->typeParser = new TypeParser(new ConstExprParser());
208-
$this->lexer = new Lexer();
209-
}
202+
$this->typeParser = new TypeParser(new ParserConfig([]), new ConstExprParser(new ParserConfig([])));
203+
$this->lexer = new Lexer(new ParserConfig([]));
210204
}
211205

212206
/**
@@ -242,7 +236,19 @@ public function resolve(string $type, ?Context $context = null): Type
242236
$ast = $this->parse($tokenIterator);
243237
$type = $this->createType($ast, $context);
244238

245-
return $this->tryParseRemainingCompoundTypes($tokenIterator, $context, $type);
239+
if (
240+
$tokenIterator->isCurrentTokenType(Lexer::TOKEN_UNION) ||
241+
$tokenIterator->isCurrentTokenType(Lexer::TOKEN_INTERSECTION)
242+
) {
243+
Deprecation::trigger(
244+
'phpdocumentor/type-resolver',
245+
'https://github.com/phpDocumentor/TypeResolver/issues/184',
246+
'Legacy nullable type detected, please update your code as
247+
you are using nullable types in a docblock. support is removed in v2.0.0'
248+
);
249+
}
250+
251+
return $type;
246252
}
247253

248254
public function createType(?TypeNode $type, Context $context): Type

tests/unit/TypeResolverTest.php

Lines changed: 25 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -895,16 +895,28 @@ public function testArrayKeyValueSpecification(): void
895895
* @dataProvider callableProvider
896896
* @dataProvider constExpressions
897897
* @dataProvider shapeStructures
898-
* @dataProvider illegalLegacyFormatProvider
899898
* @testdox create type from $type
900899
*/
901900
public function testTypeBuilding(string $type, Type $expected, bool $deprecation = false): void
902901
{
903-
if ($deprecation) {
904-
$this->expectDeprecationWithIdentifier('https://github.com/phpDocumentor/TypeResolver/issues/184');
905-
} else {
906-
$this->expectNoDeprecationWithIdentifier('https://github.com/phpDocumentor/TypeResolver/issues/184');
907-
}
902+
$this->expectNoDeprecationWithIdentifier('https://github.com/phpDocumentor/TypeResolver/issues/184');
903+
904+
$fixture = new TypeResolver();
905+
$actual = $fixture->resolve($type, new Context('phpDocumentor'));
906+
907+
self::assertEquals($expected, $actual);
908+
}
909+
910+
/**
911+
* @covers ::__construct
912+
* @covers ::resolve
913+
* @covers ::createType
914+
* @dataProvider illegalLegacyFormatProvider
915+
* @testdox create type from $type
916+
*/
917+
public function testTypeBuildingThrowsError(string $type, Type $expected): void
918+
{
919+
$this->expectDeprecationWithIdentifier('https://github.com/phpDocumentor/TypeResolver/issues/184');
908920

909921
$fixture = new TypeResolver();
910922
$actual = $fixture->resolve($type, new Context('phpDocumentor'));
@@ -1359,52 +1371,31 @@ public function illegalLegacyFormatProvider(): array
13591371
return [
13601372
[
13611373
'?string |bool',
1362-
new Compound([new Nullable(new String_()), new Boolean()]),
1363-
true,
1374+
new Nullable(new String_()),
13641375
],
13651376
[
13661377
'?string|?bool',
1367-
new Compound([new Nullable(new String_()), new Nullable(new Boolean())]),
1368-
true,
1378+
new Nullable(new String_()),
13691379
],
13701380
[
13711381
'?string|?bool|null',
1372-
new Compound([new Nullable(new String_()), new Nullable(new Boolean()), new Null_()]),
1373-
true,
1382+
new Nullable(new String_()),
13741383
],
13751384
[
13761385
'?string|bool|Foo',
1377-
new Compound([
1378-
new Nullable(new String_()),
1379-
new Boolean(),
1380-
new Object_(new Fqsen('\\phpDocumentor\\Foo')),
1381-
]),
1382-
true,
1386+
new Nullable(new String_()),
13831387
],
13841388
[
13851389
'?string&bool',
1386-
new Intersection([new Nullable(new String_()), new Boolean()]),
1387-
true,
1390+
new Nullable(new String_()),
13881391
],
13891392
[
13901393
'?string&bool|Foo',
1391-
new Intersection(
1392-
[
1393-
new Nullable(new String_()),
1394-
new Compound([new Boolean(), new Object_(new Fqsen('\\phpDocumentor\\Foo'))]),
1395-
]
1396-
),
1397-
true,
1394+
new Nullable(new String_()),
13981395
],
13991396
[
14001397
'?string&?bool|null',
1401-
new Compound(
1402-
[
1403-
new Intersection([new Nullable(new String_()), new Nullable(new Boolean())]),
1404-
new Null_(),
1405-
]
1406-
),
1407-
true,
1398+
new Nullable(new String_()),
14081399
],
14091400
];
14101401
}

0 commit comments

Comments
 (0)