Skip to content

Commit 620e213

Browse files
committed
Add named type node and improve cs configs
1 parent 67144f0 commit 620e213

11 files changed

+93
-130
lines changed

Diff for: .php-cs-fixer.php

+1
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@
178178
['internal', 'psalm-internal', 'phpstan-internal'],
179179
[
180180
'template',
181+
'template-covariant',
181182
'template-extends',
182183
'extends',
183184
'template-implements',

Diff for: src/Type/ArrayType.php

+30-7
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,49 @@ class ArrayType implements TypeInterface
2020
*/
2121
public const DEFAULT_TYPE_NAME = 'array';
2222

23+
protected readonly TypeInterface $key;
24+
protected readonly bool $isKeyPassed;
25+
26+
protected readonly TypeInterface $value;
27+
protected readonly bool $isValuePassed;
28+
2329
/**
2430
* @param non-empty-string $name
2531
*/
2632
public function __construct(
2733
protected readonly string $name = self::DEFAULT_TYPE_NAME,
28-
protected readonly TypeInterface $key = new ArrayKeyType(),
29-
protected readonly TypeInterface $value = new MixedType(),
30-
) {}
34+
?TypeInterface $key = null,
35+
?TypeInterface $value = null,
36+
) {
37+
$this->key = $key ?? new ArrayKeyType();
38+
$this->isKeyPassed = $key !== null;
39+
40+
$this->value = $value ?? new MixedType();
41+
$this->isValuePassed = $value !== null;
42+
}
3143

3244
#[\Override]
3345
public function getTypeStatement(LocalContext $context): TypeStatement
3446
{
3547
$child = $context->withDetailedTypes(false);
3648

49+
$arguments = [];
50+
51+
if ($this->isKeyPassed) {
52+
$arguments[] = new TemplateArgumentNode(
53+
value: $this->key->getTypeStatement($child),
54+
);
55+
}
56+
57+
if ($this->isValuePassed) {
58+
$arguments[] = new TemplateArgumentNode(
59+
value: $this->value->getTypeStatement($child),
60+
);
61+
}
62+
3763
return new NamedTypeNode(
3864
name: $this->name,
39-
arguments: new TemplateArgumentsListNode([
40-
new TemplateArgumentNode($this->key->getTypeStatement($child)),
41-
new TemplateArgumentNode($this->value->getTypeStatement($child)),
42-
]),
65+
arguments: new TemplateArgumentsListNode($arguments),
4366
);
4467
}
4568

Diff for: src/Type/Builder/ArrayTypeBuilder.php

+2-23
Original file line numberDiff line numberDiff line change
@@ -7,37 +7,17 @@
77
use TypeLang\Mapper\Exception\Definition\Template\Hint\TemplateArgumentHintsNotSupportedException;
88
use TypeLang\Mapper\Exception\Definition\Template\TooManyTemplateArgumentsException;
99
use TypeLang\Mapper\Exception\Definition\TypeNotFoundException;
10-
use TypeLang\Mapper\Type\ArrayKeyType;
1110
use TypeLang\Mapper\Type\ArrayType;
1211
use TypeLang\Mapper\Type\Repository\RepositoryInterface;
1312
use TypeLang\Parser\Node\Stmt\NamedTypeNode;
1413
use TypeLang\Parser\Node\Stmt\Template\TemplateArgumentNode;
1514
use TypeLang\Parser\Node\Stmt\TypeStatement;
1615

1716
/**
18-
* @template-extends Builder<NamedTypeNode, ArrayType>
17+
* @template-extends NamedTypeBuilder<ArrayType>
1918
*/
20-
class ArrayTypeBuilder extends Builder
19+
class ArrayTypeBuilder extends NamedTypeBuilder
2120
{
22-
/**
23-
* @var non-empty-lowercase-string
24-
*/
25-
protected readonly string $lower;
26-
27-
/**
28-
* @param non-empty-string $name
29-
*/
30-
public function __construct(string $name = ArrayType::DEFAULT_TYPE_NAME)
31-
{
32-
$this->lower = \strtolower($name);
33-
}
34-
35-
public function isSupported(TypeStatement $statement): bool
36-
{
37-
return $statement instanceof NamedTypeNode
38-
&& $statement->name->toLowerString() === $this->lower;
39-
}
40-
4121
public function build(TypeStatement $statement, RepositoryInterface $types): ArrayType
4222
{
4323
$this->expectNoShapeFields($statement);
@@ -100,7 +80,6 @@ private function buildByValue(NamedTypeNode $statement, RepositoryInterface $typ
10080

10181
return new ArrayType(
10282
name: $statement->name->toString(),
103-
key: new ArrayKeyType(),
10483
value: $types->getByStatement($value->value),
10584
);
10685
}

Diff for: src/Type/Builder/Builder.php

-2
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@
1616

1717
/**
1818
* @template TStmt of TypeStatement
19-
*
2019
* @template-covariant TType of TypeInterface
21-
*
2220
* @template-implements TypeBuilderInterface<TStmt, TType>
2321
*/
2422
abstract class Builder implements TypeBuilderInterface

Diff for: src/Type/Builder/IntTypeBuilder.php

+2-21
Original file line numberDiff line numberDiff line change
@@ -17,29 +17,10 @@
1717
use TypeLang\Parser\Node\Stmt\UnionTypeNode;
1818

1919
/**
20-
* @template-extends Builder<NamedTypeNode, IntType>
20+
* @template-extends NamedTypeBuilder<IntType>
2121
*/
22-
class IntTypeBuilder extends Builder
22+
class IntTypeBuilder extends NamedTypeBuilder
2323
{
24-
/**
25-
* @var non-empty-lowercase-string
26-
*/
27-
protected readonly string $lower;
28-
29-
/**
30-
* @param non-empty-string $name
31-
*/
32-
public function __construct(string $name = IntType::DEFAULT_TYPE_NAME)
33-
{
34-
$this->lower = \strtolower($name);
35-
}
36-
37-
public function isSupported(TypeStatement $statement): bool
38-
{
39-
return $statement instanceof NamedTypeNode
40-
&& $statement->name->toLowerString() === $this->lower;
41-
}
42-
4324
public function build(TypeStatement $statement, RepositoryInterface $types): IntType
4425
{
4526
$this->expectNoShapeFields($statement);

Diff for: src/Type/Builder/ListTypeBuilder.php

+2-22
Original file line numberDiff line numberDiff line change
@@ -6,34 +6,14 @@
66

77
use TypeLang\Mapper\Type\ListType;
88
use TypeLang\Mapper\Type\Repository\RepositoryInterface;
9-
use TypeLang\Parser\Node\Stmt\NamedTypeNode;
109
use TypeLang\Parser\Node\Stmt\Template\TemplateArgumentNode;
1110
use TypeLang\Parser\Node\Stmt\TypeStatement;
1211

1312
/**
14-
* @template-extends Builder<NamedTypeNode, ListType>
13+
* @template-extends NamedTypeBuilder<ListType>
1514
*/
16-
class ListTypeBuilder extends Builder
15+
class ListTypeBuilder extends NamedTypeBuilder
1716
{
18-
/**
19-
* @var non-empty-lowercase-string
20-
*/
21-
protected readonly string $lower;
22-
23-
/**
24-
* @param non-empty-string $name
25-
*/
26-
public function __construct(string $name = ListType::DEFAULT_TYPE_NAME)
27-
{
28-
$this->lower = \strtolower($name);
29-
}
30-
31-
public function isSupported(TypeStatement $statement): bool
32-
{
33-
return $statement instanceof NamedTypeNode
34-
&& $statement->name->toLowerString() === $this->lower;
35-
}
36-
3717
public function build(TypeStatement $statement, RepositoryInterface $types): ListType
3818
{
3919
if ($statement->arguments === null || $statement->arguments->count() === 0) {

Diff for: src/Type/Builder/NamedTypeBuilder.php

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TypeLang\Mapper\Type\Builder;
6+
7+
use TypeLang\Mapper\Type\TypeInterface;
8+
use TypeLang\Parser\Node\Stmt\NamedTypeNode;
9+
use TypeLang\Parser\Node\Stmt\TypeStatement;
10+
11+
/**
12+
* @template-covariant TType of TypeInterface
13+
* @template-extends Builder<NamedTypeNode, TType>
14+
*/
15+
abstract class NamedTypeBuilder extends Builder
16+
{
17+
/**
18+
* @var non-empty-list<non-empty-lowercase-string>
19+
*/
20+
protected readonly array $lower;
21+
22+
/**
23+
* @param non-empty-array<non-empty-string>|non-empty-string $names
24+
*/
25+
public function __construct(array|string $names)
26+
{
27+
$this->lower = $this->formatNames($names);
28+
}
29+
30+
/**
31+
* @param non-empty-array<non-empty-string>|non-empty-string $names
32+
*
33+
* @return non-empty-list<non-empty-lowercase-string>
34+
*/
35+
private function formatNames(array|string $names): array
36+
{
37+
$result = [];
38+
39+
foreach (\is_string($names) ? [$names] : $names as $name) {
40+
$result[] = \strtolower($name);
41+
}
42+
43+
return $result;
44+
}
45+
46+
public function isSupported(TypeStatement $statement): bool
47+
{
48+
return $statement instanceof NamedTypeNode
49+
&& \in_array($statement->name->toLowerString(), $this->lower, true);
50+
}
51+
}

Diff for: src/Type/Builder/NonEmptyTypeBuilder.php

+2-22
Original file line numberDiff line numberDiff line change
@@ -6,34 +6,14 @@
66

77
use TypeLang\Mapper\Type\NonEmpty;
88
use TypeLang\Mapper\Type\Repository\RepositoryInterface;
9-
use TypeLang\Parser\Node\Stmt\NamedTypeNode;
109
use TypeLang\Parser\Node\Stmt\Template\TemplateArgumentNode;
1110
use TypeLang\Parser\Node\Stmt\TypeStatement;
1211

1312
/**
14-
* @template-extends Builder<NamedTypeNode, NonEmpty>
13+
* @template-extends NamedTypeBuilder<NonEmpty>
1514
*/
16-
class NonEmptyTypeBuilder extends Builder
15+
class NonEmptyTypeBuilder extends NamedTypeBuilder
1716
{
18-
/**
19-
* @var non-empty-lowercase-string
20-
*/
21-
protected readonly string $lower;
22-
23-
/**
24-
* @param non-empty-string $name
25-
*/
26-
public function __construct(string $name = NonEmpty::DEFAULT_TYPE_NAME)
27-
{
28-
$this->lower = \strtolower($name);
29-
}
30-
31-
public function isSupported(TypeStatement $statement): bool
32-
{
33-
return $statement instanceof NamedTypeNode
34-
&& $statement->name->toLowerString() === $this->lower;
35-
}
36-
3717
public function build(TypeStatement $statement, RepositoryInterface $types): NonEmpty
3818
{
3919
$this->expectNoShapeFields($statement);

Diff for: src/Type/Builder/SimpleTypeBuilder.php

+3-30
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,10 @@
1010
use TypeLang\Parser\Node\Stmt\TypeStatement;
1111

1212
/**
13-
* @template-extends Builder<NamedTypeNode, SimpleType>
13+
* @template-extends NamedTypeBuilder<SimpleType>
1414
*/
15-
class SimpleTypeBuilder extends Builder
15+
class SimpleTypeBuilder extends NamedTypeBuilder
1616
{
17-
/**
18-
* @var non-empty-list<non-empty-lowercase-string>
19-
*/
20-
protected readonly array $lower;
21-
2217
/**
2318
* @param non-empty-array<non-empty-string>|non-empty-string $names
2419
* @param class-string<SimpleType> $type
@@ -27,29 +22,7 @@ public function __construct(
2722
array|string $names,
2823
protected readonly string $type,
2924
) {
30-
$this->lower = $this->formatNames($names);
31-
}
32-
33-
/**
34-
* @param non-empty-array<non-empty-string>|non-empty-string $names
35-
*
36-
* @return non-empty-list<non-empty-lowercase-string>
37-
*/
38-
private function formatNames(array|string $names): array
39-
{
40-
$result = [];
41-
42-
foreach (\is_string($names) ? [$names] : $names as $name) {
43-
$result[] = \strtolower($name);
44-
}
45-
46-
return $result;
47-
}
48-
49-
public function isSupported(TypeStatement $statement): bool
50-
{
51-
return $statement instanceof NamedTypeNode
52-
&& \in_array($statement->name->toLowerString(), $this->lower, true);
25+
parent::__construct($names);
5326
}
5427

5528
public function build(TypeStatement $statement, RepositoryInterface $types): SimpleType

Diff for: src/Type/Builder/TypeBuilderInterface.php

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
/**
1313
* @template TStmt of TypeStatement
14-
*
1514
* @template-covariant TType of TypeInterface
1615
*/
1716
interface TypeBuilderInterface

Diff for: src/Type/NullableType.php

-2
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,13 @@
44

55
namespace TypeLang\Mapper\Type;
66

7-
use TypeLang\Mapper\Type\Attribute\TargetTemplateArgument;
87
use TypeLang\Mapper\Type\Context\LocalContext;
98
use TypeLang\Parser\Node\Stmt\NullableTypeNode;
109
use TypeLang\Parser\Node\Stmt\TypeStatement;
1110

1211
class NullableType implements TypeInterface
1312
{
1413
public function __construct(
15-
#[TargetTemplateArgument]
1614
private readonly TypeInterface $parent,
1715
) {}
1816

0 commit comments

Comments
 (0)