-
-
Notifications
You must be signed in to change notification settings - Fork 78
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #188 from mglaman/config_export-check
Detect missing `config_export` annotation key
- Loading branch information
Showing
7 changed files
with
180 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?php declare(strict_types=1); | ||
|
||
namespace PHPStan\Rules\Deprecations; | ||
|
||
use PhpParser\Node; | ||
use PHPStan\Analyser\Scope; | ||
use PHPStan\Reflection\ClassReflection; | ||
use PHPStan\Reflection\ReflectionProvider; | ||
|
||
final class ConfigEntityConfigExportRule extends DeprecatedAnnotationsRuleBase | ||
{ | ||
|
||
protected function getExpectedInterface(): string | ||
{ | ||
return 'Drupal\Core\Config\Entity\ConfigEntityInterface'; | ||
} | ||
|
||
protected function doProcessNode(ClassReflection $reflection, Node\Stmt\Class_ $node, Scope $scope): array | ||
{ | ||
$annotation = $reflection->getResolvedPhpDoc(); | ||
// Plugins should always be annotated, but maybe this class is missing its | ||
// annotation since it swaps an existing one. | ||
if ($annotation === null) { | ||
return []; | ||
} | ||
$hasMatch = strpos($annotation->getPhpDocString(), 'config_export = {') === false; | ||
if ($hasMatch) { | ||
return [ | ||
'Configuration entity must define a `config_export` key. See https://www.drupal.org/node/2481909', | ||
]; | ||
} | ||
return []; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
<?php declare(strict_types=1); | ||
|
||
namespace PHPStan\Rules\Deprecations; | ||
|
||
use PhpParser\Node; | ||
use PHPStan\Analyser\Scope; | ||
use PHPStan\Reflection\ClassReflection; | ||
use PHPStan\Reflection\ReflectionProvider; | ||
use PHPStan\Rules\Rule; | ||
|
||
abstract class DeprecatedAnnotationsRuleBase implements Rule | ||
{ | ||
|
||
/** | ||
* @var \PHPStan\Reflection\ReflectionProvider | ||
*/ | ||
protected $reflectionProvider; | ||
|
||
public function __construct(ReflectionProvider $reflectionProvider) | ||
{ | ||
$this->reflectionProvider = $reflectionProvider; | ||
} | ||
|
||
public function getNodeType(): string | ||
{ | ||
return Node\Stmt\Class_::class; | ||
} | ||
|
||
abstract protected function getExpectedInterface(): string; | ||
|
||
abstract protected function doProcessNode( | ||
ClassReflection $reflection, | ||
Node\Stmt\Class_ $node, | ||
Scope $scope | ||
): array; | ||
|
||
public function processNode(Node $node, Scope $scope): array | ||
{ | ||
assert($node instanceof Node\Stmt\Class_); | ||
if ($node->extends === null) { | ||
return []; | ||
} | ||
if ($node->name === null) { | ||
return []; | ||
} | ||
$className = $node->name->name; | ||
$namespace = $scope->getNamespace(); | ||
$reflection = $this->reflectionProvider->getClass($namespace . '\\' . $className); | ||
$implementsExpectedInterface = $reflection->implementsInterface($this->getExpectedInterface()); | ||
if (!$implementsExpectedInterface) { | ||
return []; | ||
} | ||
|
||
return $this->doProcessNode($reflection, $node, $scope); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
tests/fixtures/drupal/modules/phpstan_fixtures/src/Entity/ConfigWithExport.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<?php declare(strict_types=1); | ||
|
||
namespace Drupal\phpstan_fixtures\Entity; | ||
|
||
use Drupal\Core\Config\Entity\ConfigEntityBase; | ||
|
||
/** | ||
* Defines the ConfigTest configuration entity. | ||
* | ||
* @ConfigEntityType( | ||
* id = "config_test", | ||
* label = @Translation("Test configuration"), | ||
* config_export = { | ||
* "id", | ||
* "label", | ||
* "weight", | ||
* "style", | ||
* "size", | ||
* "size_value", | ||
* "protected_property", | ||
* }, | ||
* ) | ||
*/ | ||
final class ConfigWithExport extends ConfigEntityBase { | ||
|
||
} |
17 changes: 17 additions & 0 deletions
17
tests/fixtures/drupal/modules/phpstan_fixtures/src/Entity/ConfigWithoutExport.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?php declare(strict_types=1); | ||
|
||
namespace Drupal\phpstan_fixtures\Entity; | ||
|
||
use Drupal\Core\Config\Entity\ConfigEntityBase; | ||
|
||
/** | ||
* Defines the ConfigTest configuration entity. | ||
* | ||
* @ConfigEntityType( | ||
* id = "config_test", | ||
* label = @Translation("Test configuration"), | ||
* ) | ||
*/ | ||
final class ConfigWithoutExport extends ConfigEntityBase { | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<?php declare(strict_types=1); | ||
|
||
namespace PHPStan\Drupal\Rules; | ||
|
||
use PHPStan\Drupal\AnalyzerTestBase; | ||
|
||
final class ConfigEntityConfigExportRuleTest extends AnalyzerTestBase { | ||
|
||
/** | ||
* @dataProvider pluginData | ||
*/ | ||
public function testConfigExportRuleCheck(string $path, int $count, array $errorMessages): void | ||
{ | ||
$errors = $this->runAnalyze($path); | ||
self::assertCount($count, $errors->getErrors(), var_export($errors, true)); | ||
foreach ($errors->getErrors() as $key => $error) { | ||
self::assertEquals($errorMessages[$key], $error->getMessage()); | ||
} | ||
} | ||
|
||
public function pluginData(): \Generator | ||
{ | ||
yield [ | ||
__DIR__ . '/../../fixtures/drupal/modules/phpstan_fixtures/src/Entity/ConfigWithoutExport.php', | ||
1, | ||
[ | ||
'Configuration entity must define a `config_export` key. See https://www.drupal.org/node/2481909', | ||
] | ||
]; | ||
yield [ | ||
__DIR__ . '/../../fixtures/drupal/modules/phpstan_fixtures/src/Entity/ConfigWithExport.php', | ||
0, | ||
[] | ||
]; | ||
} | ||
|
||
|
||
} |