8000 minor #49439 Add CI check ensuring interfaces have return types (wout… · symfony/symfony@ed6e10a · GitHub
[go: up one dir, main page]

Skip to content

Commit ed6e10a

Browse files
committed
minor #49439 Add CI check ensuring interfaces have return types (wouterj)
This PR was squashed before being merged into the 6.3 branch. Discussion ---------- Add CI check ensuring interfaces have return types | Q | A | ------------- | --- | Branch? | 6.3 | Bug fix? | no | New feature? | no | Deprecations? | no | Tickets | Ref #47551 | License | MIT | Doc PR | - This adds a CI check to enforce all methods on an interface to have a return type (native or PHPdoc). For now, this is a living version of the list I published in #47551. I'll rebase this PR whenever we add more types. Commits ------- 29ea860 Add CI check ensuring interfaces have return types
2 parents 2d33511 + 29ea860 commit ed6e10a

19 files changed

+264
-36
lines changed

.github/expected-missing-return-types.diff

Lines changed: 184 additions & 28 deletions
Large diffs are not rendered by default.

.github/patch-types.php

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?php
22

3-
if (false === getenv('SYMFONY_PATCH_TYPE_DECLARATIONS')) {
3+
$mode = $argv[1] ?? 'patch';
4+
if ('lint' !== $mode && false === getenv('SYMFONY_PATCH_TYPE_DECLARATIONS')) {
45
echo "Please define the SYMFONY_PATCH_TYPE_DECLARATIONS env var when running this script.\n";
56
exit(1);
67
}
@@ -11,6 +12,7 @@
1112

1213
Symfony\Component\ErrorHandler\DebugClassLoader::enable();
1314

15+
$missingReturnTypes = [];
1416
foreach ($loader->getClassMap() as $class => $file) {
1517
$file = realpath($file);
1618

@@ -53,6 +55,7 @@
5355
case false !== strpos($file, '/src/Symfony/Component/VarDumper/Tests/Fixtures/NotLoadableClass.php'):
5456
case false !== strpos($file, '/src/Symfony/Component/VarDumper/Tests/Fixtures/ReflectionIntersectionTypeFixture.php'):
5557
case false !== strpos($file, '/src/Symfony/Component/VarDumper/Tests/Fixtures/ReflectionUnionTypeWithIntersectionFixture.php'):
58+
case false !== strpos($file, '/src/Symfony/Component/VarExporter/Internal'):
5659
case false !== strpos($file, '/src/Symfony/Component/VarExporter/Tests/Fixtures/LazyGhost/ReadOnlyClass.php'):
5760
case false !== strpos($file, '/src/Symfony/Component/VarExporter/Tests/Fixtures/LazyProxy/ReadOnlyClass.php'):
5861
case false !== strpos($file, '/src/Symfony/Component/Cache/Traits/RelayProxy.php'):
@@ -62,6 +65,33 @@
6265
}
6366

6467
class_exists($class);
68+
69+
if ('lint' !== $mode) {
70+
continue;
71+
}
72+
73+
$refl = new \ReflectionClass($class);
74+
foreach ($refl->getMethods() as $method) {
75+
if (
76+
!$refl->isInterface()
77+
|| $method->getReturnType()
78+
|| str_contains($method->getDocComment(), '@return')
79+
|| str_starts_with($method->getName(), '__')
80+
|| $method->getDeclaringClass()->getName() !== $class
81+
) {
82+
continue;
83+
}
84+
85+
$missingReturnTypes[] = $class.'::'.$method->getName();
86+
}
6587
}
6688

67-
Symfony\Component\ErrorHandler\DebugClassLoader::checkClasses();
89+
if ($missingReturnTypes) {
90+
echo \count($missingReturnTypes)." missing return types on interfaces\n\n";
91+
echo implode("\n", $missingReturnTypes);
92+
exit(1);
93+
}
94+
95+
if ('patch' === $mode) {
96+
Symfony\Component\ErrorHandler\DebugClassLoader::checkClasses();
97+
}

.github/workflows/unit-tests.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,11 @@ jobs:
148148
git checkout src/Symfony/Contracts/Service/ResetInterface.php
149149
git diff --exit-code
150150
151+
- name: Check interface return types
152+
if: "matrix.php == '8.1' && ! matrix.mode"
153+
run: |
154+
php .github/patch-types.php lint
155+
151156
- name: Run tests
152157
run: |
153158
_run_tests() {

src/Symfony/Component/Console/Output/OutputInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ public function isDebug(): bool;
8585

8686
/**
8787
* Sets the decorated flag.
88+
*
89+
* @return void
8890
*/
8991
public function setDecorated(bool $decorated);
9092

src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapperInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ interface ViolationMapperInterface
2424
* the given form.
2525
*
2626
* @param bool $allowNonSynchronized Whether to allow mapping to non-synchronized forms
27+
*
28+
* @return void
2729
*/
2830
public function mapViolation(ConstraintViolation $violation, FormInterface $form, bool $allowNonSynchronized = false);
2931
}

src/Symfony/Component/Intl/Data/Bundle/Compiler/BundleCompilerInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ interface BundleCompilerInterface
2323
/**
2424
* Compiles a resource bundle at the given source to the given target
2525
* directory.
26+
*
27+
* @return void
2628
*/
2729
public function compile(string $sourcePath, string $targetDir);
2830
}

src/Symfony/Component/Intl/Data/Bundle/Writer/BundleWriterInterface.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,8 @@
2020
*/
2121
interface BundleWriterInterface
2222
{
23+
/**
24+
* @return void
25+
*/
2326
public function write(string $path, string $locale, mixed $data);
2427
}

src/Symfony/Component/Ldap/Adapter/ConnectionInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ public function isBound(): bool;
3131
* @throws AlreadyExistsException When the connection can't be created because of an LDAP_ALREADY_EXISTS error
3232
* @throws ConnectionTimeoutException When the connection can't be created because of an LDAP_TIMEOUT error
3333
* @throws InvalidCredentialsException When the connection can't be created because of an LDAP_INVALID_CREDENTIALS error
34+
*
35+
* @return void
3436
*/
3537
public function bind(string $dn = null, #[\SensitiveParameter] string $password = null);
3638
}

src/Symfony/Component/Ldap/LdapInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ interface LdapInterface
2929
* Return a connection bound to the ldap.
3030
*
3131
* @throws ConnectionException if dn / password could not be bound
32+
*
33+
* @return void
3234
*/
3335
public function bind(string $dn = null, #[\SensitiveParameter] string $password = null);
3436

src/Symfony/Component/Mime/Header/HeaderInterface.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line ch 1241 ange
@@ -22,6 +22,8 @@ interface HeaderInterface
2222
* Sets the body.
2323
*
2424
* The type depends on the Header concrete class.
25+
*
26+
* @return void
2527
*/
2628
public function setBody(mixed $body);
2729

@@ -32,16 +34,25 @@ public function setBody(mixed $body);
3234
*/
3335
public function getBody(): mixed;
3436

37+
/**
38+
* @return void
39+
*/
3540
public function setCharset(string $charset);
3641

3742
public function getCharset(): ?string;
3843

44+
/**
45+
* @return void
46+
*/
3947
public function setLanguage(string $lang);
4048

4149
public function getLanguage(): ?string;
4250

4351
public function getName(): string;
4452

53+
/**
54+
* @return void
55+
*/
4556
public function setMaxLineLength(int $lineLength);
4657

4758
public function getMaxLineLength(): int;

src/Symfony/Component/PropertyAccess/PropertyAccessorInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ interface PropertyAccessorInterface
4242
* @throws Exception\InvalidArgumentException If the property path is invalid
4343
* @throws Exception\AccessException If a property/index does not exist or is not public
4444
* @throws Exception\UnexpectedTypeException If a value within the path is neither object nor array
45+
*
46+
* @return void
4547
*/
4648
public function setValue(object|array &$objectOrArray, string|PropertyPathInterface $propertyPath, mixed $value);
4749

src/Symfony/Component/Routing/Generator/ConfigurableRequirementsInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ interface ConfigurableRequirementsInterface
4040
/**
4141
* Enables or disables the exception on incorrect parameters.
4242
* Passing null will deactivate the requirements check completely.
43+
*
44+
* @return void
4345
*/
4446
public function setStrictRequirements(?bool $enabled);
4547

src/Symfony/Component/Routing/RequestContextAwareInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ interface RequestContextAwareInterface
1515
{
1616
/**
1717
* Sets the request context.
18+
*
19+
* @return void
1820
*/
1921
public function setContext(RequestContext $context);
2022

src/Symfony/Component/Serializer/Normalizer/DenormalizableInterface.php

Lines changed: 2 additions & 0 deletions
< 10000 thead class="sr-only">
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ interface DenormalizableInterface
3333
* @param string|null $format The format is optionally given to be able to denormalize
3434
* differently based on different input formats
3535
* @param array $context Options for denormalizing
36+
*
37+
* @return void
3638
*/
3739
public function denormalize(DenormalizerInterface $denormalizer, array|string|int|float|bool $data, string $format = null, array $context = []);
3840
}

src/Symfony/Component/Serializer/Tests/Fixtures/Dummy.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public function normalize(NormalizerInterface $normalizer, string $format = null
3333
];
3434
}
3535

36-
public function denormalize(DenormalizerInterface $denormalizer, array|string|int|float|bool $data, string $format = null, array $context = [])
36+
public function denormalize(DenormalizerInterface $denormalizer, array|string|int|float|bool $data, string $format = null, array $context = []): void
3737
{
3838
$this->foo = $data['foo'];
3939
$this->bar = $data['bar'];

src/Symfony/Component/Templating/Helper/HelperInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ public function getName();
2727

2828
/**
2929
* Sets the default charset.
30+
*
31+
* @return void
3032
*/
3133
public function setCharset(string $charset);
3234

src/Symfony/Component/Templating/StreamingEngineInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ interface StreamingEngineInterface
2525
*
2626
* @throws \RuntimeException if the template cannot be rendered
2727
* @throws \LogicException if the template cannot be streamed
28+
*
29+
* @return void
2830
*/
2931
public function stream(string|TemplateReferenceInterface $name, array $parameters = []);
3032
}

src/Symfony/Component/Templating/Tests/DelegatingEngineTest.php

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,10 @@ public function testStreamDelegatesToSupportedEngine()
5050
$streamingEngine = $this->getStreamingEngineMock('template.php', true);
5151
$streamingEngine->expects($this->once())
5252
->method('stream')
53-
->with('template.php', ['foo' => 'bar'])
54-
->willReturn('<html />');
53+
->with('template.php', ['foo' => 'bar']);
5554

5655
$delegatingEngine = new DelegatingEngine([$streamingEngine]);
57-
$result = $delegatingEngine->stream('template.php', ['foo' => 'bar']);
58-
59-
$this->assertNull($result);
56+
$delegatingEngine->stream('template.php', ['foo' => 'bar']);
6057
}
6158

6259
public function testStreamRequiresStreamingEngine()

src/Symfony/Component/Translation/CatalogueMetadataAwareInterface.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ public function getCatalogueMetadata(string $key = '', string $domain = 'message
3131

3232
/**
3333
* Adds catalogue metadata to a message domain.
34+
*
35+
* @return void
3436
*/
3537
public function setCatalogueMetadata(string $key, mixed $value, string $domain = 'messages');
3638

@@ -39,6 +41,8 @@ public function setCatalogueMetadata(string $key, mixed $value, string $domain =
3941
*
4042
* Passing an empty domain will delete all catalogue metadata. Passing an empty key will
4143
* delete all metadata for the given domain.
44+
*
45+
* @return void
4246
*/
4347
public function deleteCatalogueMetadata(string $key = '', string $domain = 'messages');
4448
}

0 commit comments

Comments
 (0)
0