diff --git a/.gitignore b/.gitignore
index 6ee0aa6..37f4810 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
+/tmp/
/vendor/
-*.phar
\ No newline at end of file
+*.phar
+cs-check.json
\ No newline at end of file
diff --git a/config/serviceManager.php b/config/serviceManager.php
index 6c6dea7..ef6afed 100644
--- a/config/serviceManager.php
+++ b/config/serviceManager.php
@@ -1,18 +1,21 @@
[
- CheckCommand::class =>CheckCommandFactory::class,
+ CheckCommand::class => CheckCommandFactory::class,
ExtensionCheck::class => ExtensionCheckFactory::class,
ExtensionDetails::class => InvokableFactory::class,
FileParser::class => FileParserFactory::class,
+ SymfonyStyleFactory::class => InvokableFactory::class,
],
-];
\ No newline at end of file
+];
diff --git a/phpcs.xml b/phpcs.xml
new file mode 100644
index 0000000..7749ee0
--- /dev/null
+++ b/phpcs.xml
@@ -0,0 +1,24 @@
+
+
+ Skeleton coding standard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ src
+ tests
+ config
+
\ No newline at end of file
diff --git a/phpstan.neon b/phpstan.neon
new file mode 100644
index 0000000..e51c96f
--- /dev/null
+++ b/phpstan.neon
@@ -0,0 +1,9 @@
+parameters:
+ level: max
+ inferPrivatePropertyTypeFromConstructor: true
+ paths:
+ - src/
+ - tests/
+ excludes_analyse:
+ - %currentWorkingDirectory%/src/TEST
+ tmpDir: tmp/phpstan
\ No newline at end of file
diff --git a/src/Command/CheckCommand.php b/src/Command/CheckCommand.php
index 34ffa47..c312993 100644
--- a/src/Command/CheckCommand.php
+++ b/src/Command/CheckCommand.php
@@ -1,4 +1,5 @@
setHelp('This command allows you to check your extensions...')
->setDefinition(
new InputDefinition([
- new InputArgument('directory', InputArgument::OPTIONAL, "The directory to scan", "./"),
+ new InputArgument(self::ARG_DIRECTORY, InputArgument::OPTIONAL, "The directory to scan", "./"),
])
);
}
@@ -52,7 +56,13 @@ class CheckCommand extends Command
$io = ($this->symfonyStyleFactory)($input, $output);
$io->section("Analyzing Files");
- $this->fileParser->scanForFiles($input->getArgument('directory'));
+
+ $scanDir = $input->getArgument(self::ARG_DIRECTORY);
+ if (empty($scanDir) || !\is_string($scanDir)) {
+ $scanDir = './';
+ }
+ $this->fileParser->scanForFiles($scanDir);
+
$fileCount = $this->fileParser->getFileCount();
$io->text(sprintf('Files: %d', $fileCount));
$io->newLine();
@@ -66,7 +76,7 @@ class CheckCommand extends Command
$progressBar->finish();
$io->newLine(2);
- $io->text(sprintf("Calls to check:", count($classes)));
+ $io->text("Calls to check:");
$io->text(sprintf(
"%d Classes, %d Functions, %d Constants",
count($classes),
@@ -95,16 +105,17 @@ class CheckCommand extends Command
$io->text(sprintf(
"%d> Used, %d> Unused",
count($usedExtensions),
- count($unusedExtensions),
+ count($unusedExtensions)
));
$io->section("Result");
$io->text("Used Extensions:");
$tmp = array_keys($usedExtensions);
natcasesort($tmp);
- foreach($tmp as $usedExtension) {
+ foreach ($tmp as $usedExtension) {
$reason = $usedExtensions[$usedExtension];
- $io->text(sprintf(' %s> %s [Usage: %s]>',
+ $io->text(sprintf(
+ ' %s> %s [Usage: %s]>',
"\u{2713}",
$usedExtension,
implode(", ", array_keys($reason))
@@ -114,8 +125,9 @@ class CheckCommand extends Command
$io->newLine();
$io->text("Unused Extensions:");
- foreach($unusedExtensions as $unusedExtension) {
- $io->text(sprintf(' %s> %s',
+ foreach ($unusedExtensions as $unusedExtension) {
+ $io->text(sprintf(
+ ' %s> %s',
"\u{2717}",
$unusedExtension
));
@@ -124,13 +136,15 @@ class CheckCommand extends Command
return Command::SUCCESS;
}
- private function getProgressBarClosure(&$progressBar): Closure {
- return function() use ($progressBar) {
+ private function getProgressBarClosure(ProgressBar $progressBar): Closure
+ {
+ return function () use ($progressBar) {
$progressBar->advance();
};
}
- private function getStyledProgressBar(OutputInterface $output, int $maxValue): ProgressBar {
+ private function getStyledProgressBar(OutputInterface $output, int $maxValue): ProgressBar
+ {
$progressBar = new ProgressBar($output, $maxValue);
$progressBar->setBarCharacter('=');
$progressBar->setEmptyBarCharacter(' ');
@@ -138,4 +152,4 @@ class CheckCommand extends Command
return $progressBar;
}
-}
\ No newline at end of file
+}
diff --git a/src/Command/CheckCommandFactory.php b/src/Command/CheckCommandFactory.php
index e28e623..c072f79 100644
--- a/src/Command/CheckCommandFactory.php
+++ b/src/Command/CheckCommandFactory.php
@@ -1,23 +1,28 @@
$options
+ */
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
return new CheckCommand(
- new class { public function __invoke($input, $output) { return new SymfonyStyle($input, $output); } },
+ $container->get(SymfonyStyleFactory::class),
$container->get(FileParser::class),
$container->get(ExtensionDetails::class),
- $container->get(ExtensionCheck::class),
+ $container->get(ExtensionCheck::class)
);
}
-}
\ No newline at end of file
+}
diff --git a/src/Extension/ExtensionCheck.php b/src/Extension/ExtensionCheck.php
index 60eb61d..b13a877 100644
--- a/src/Extension/ExtensionCheck.php
+++ b/src/Extension/ExtensionCheck.php
@@ -1,10 +1,13 @@
extensionDetails = $extensionDetails;
}
- public function getUnused(array $usedExtensions) {
+ /**
+ * @param string[] $usedExtensions
+ * @return string[]
+ */
+ public function getUnused(array $usedExtensions): array
+ {
return array_diff(
$this->extensionDetails->getLoadedExtensions(),
$usedExtensions
);
}
- public function checkUsages(array $classes, array $functions, array $constants, Closure $callback) {
+ /**
+ * @param string[] $classes
+ * @param string[] $functions
+ * @param string[] $constants
+ * @return array>
+ */
+ public function checkUsages(array $classes, array $functions, array $constants, Closure $callback)
+ {
$usedExtensions = [];
- foreach($classes as $class) {
+ foreach ($classes as $class) {
$extension = $this->checkClass($class);
if (!empty($extension)) {
@@ -33,7 +48,7 @@ class ExtensionCheck {
$callback();
}
- foreach($functions as $function) {
+ foreach ($functions as $function) {
$extension = $this->checkFunction($function);
if (!empty($extension)) {
@@ -43,7 +58,7 @@ class ExtensionCheck {
$callback();
}
- foreach($constants as $constant) {
+ foreach ($constants as $constant) {
$extension = $this->checkConstant($constant);
if (!empty($extension)) {
@@ -54,11 +69,11 @@ class ExtensionCheck {
}
$tmp = array_keys($usedExtensions);
- foreach($tmp as $usedExtension) {
+ foreach ($tmp as $usedExtension) {
$requiredExtensions = $this->checkRequiredDependency($usedExtension);
if (!empty($requiredExtensions)) {
- foreach($requiredExtensions as $requiredExtension) {
+ foreach ($requiredExtensions as $requiredExtension) {
$usedExtensions[$requiredExtension]['dependency'] = true;
}
}
@@ -69,7 +84,8 @@ class ExtensionCheck {
return $usedExtensions;
}
- private function checkClass($class): ?string {
+ private function checkClass(string $class): ?string
+ {
$classMap = $this->extensionDetails->getExtensionClassMap();
if (!isset($classMap[$class])) {
@@ -79,7 +95,8 @@ class ExtensionCheck {
return $classMap[$class];
}
- private function checkFunction($function): ?string {
+ private function checkFunction(string $function): ?string
+ {
$functionMap = $this->extensionDetails->getExtensionFunctionMap();
if (!isset($functionMap[$function])) {
@@ -89,7 +106,8 @@ class ExtensionCheck {
return $functionMap[$function];
}
- private function checkConstant($function): ?string {
+ private function checkConstant(string $function): ?string
+ {
$constantMap = $this->extensionDetails->getExtensionConstantMap();
if (!isset($constantMap[$function])) {
@@ -99,7 +117,11 @@ class ExtensionCheck {
return $constantMap[$function];
}
- private function checkRequiredDependency($extension): array {
+ /**
+ * @return string[]
+ */
+ private function checkRequiredDependency(string $extension): array
+ {
$dependencyMap = $this->extensionDetails->getExtensionDependencyMap();
if (!isset($dependencyMap[$extension]['required'])) {
@@ -108,5 +130,4 @@ class ExtensionCheck {
return $dependencyMap[$extension]['required'];
}
-
-}
\ No newline at end of file
+}
diff --git a/src/Extension/ExtensionCheckFactory.php b/src/Extension/ExtensionCheckFactory.php
index 33a6e89..20e7f8b 100644
--- a/src/Extension/ExtensionCheckFactory.php
+++ b/src/Extension/ExtensionCheckFactory.php
@@ -1,5 +1,7 @@
$options
+ */
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
return new ExtensionCheck(
$container->get(ExtensionDetails::class)
);
}
-}
\ No newline at end of file
+}
diff --git a/src/Extension/ExtensionDetails.php b/src/Extension/ExtensionDetails.php
index cc056b1..b15e25f 100644
--- a/src/Extension/ExtensionDetails.php
+++ b/src/Extension/ExtensionDetails.php
@@ -1,60 +1,90 @@
loadedExtensions = array_map('strtolower', get_loaded_extensions());
}
- public function getLoadedExtensions(): array {
+ /**
+ * @return string[]
+ */
+ public function getLoadedExtensions(): array
+ {
natcasesort($this->loadedExtensions);
return $this->loadedExtensions;
}
- public function getLoadedExtensionsCount(): int {
+ public function getLoadedExtensionsCount(): int
+ {
return count($this->loadedExtensions);
}
- public function getExtensionClassMap(): array {
+ /**
+ * @return array
+ */
+ public function getExtensionClassMap(): array
+ {
if (empty($this->extensionMap)) {
$this->buildExtensionMaps();
}
- return $this->extensionMap['classes'] ?? [];
+ return $this->extensionMap->classes ?? [];
}
- public function getExtensionFunctionMap(): array {
+ /**
+ * @return array
+ */
+ public function getExtensionFunctionMap(): array
+ {
if (empty($this->extensionMap)) {
$this->buildExtensionMaps();
}
- return $this->extensionMap['functions'] ?? [];
+ return $this->extensionMap->functions ?? [];
}
- public function getExtensionConstantMap(): array {
+ /**
+ * @return array
+ */
+ public function getExtensionConstantMap(): array
+ {
if (empty($this->extensionMap)) {
$this->buildExtensionMaps();
}
- return $this->extensionMap['constants'] ?? [];
+ return $this->extensionMap->constants ?? [];
}
- public function getExtensionDependencyMap(): array {
+ /**
+ * @return array>
+ */
+ public function getExtensionDependencyMap(): array
+ {
if (empty($this->extensionMap)) {
$this->buildExtensionMaps();
}
- return $this->extensionMap['dependencies'] ?? [];
+ return $this->extensionMap->dependencies ?? [];
}
- private function buildExtensionMaps(array $extensionsToExclude = []) {
+ /**
+ * @param string[] $extensionsToExclude
+ */
+ private function buildExtensionMaps(array $extensionsToExclude = []): void
+ {
$extensionClasses = $extensionFunctions = $extensionConstants = $extensionDependencies = $uncheckedExtensions = [];
foreach ($this->loadedExtensions as $loadedExtension) {
if (in_array(strtolower($loadedExtension), array_map('strtolower', $extensionsToExclude))) {
@@ -106,13 +136,12 @@ class ExtensionDetails {
}
}
- $this->extensionMap = [
- 'classes' => $extensionClasses,
- 'functions' => $extensionFunctions,
- 'constants' => $extensionConstants,
- 'dependencies' => $extensionDependencies,
- 'unchecked' => $uncheckedExtensions
- ];
+ $this->extensionMap = new ExtensionMap(
+ $extensionClasses,
+ $extensionFunctions,
+ $extensionConstants,
+ $extensionDependencies,
+ $uncheckedExtensions
+ );
}
-
-}
\ No newline at end of file
+}
diff --git a/src/Extension/ExtensionMap.php b/src/Extension/ExtensionMap.php
new file mode 100644
index 0000000..e7859d8
--- /dev/null
+++ b/src/Extension/ExtensionMap.php
@@ -0,0 +1,42 @@
+ */
+ public $classes;
+
+ /** @var array */
+ public $functions;
+
+ /** @var array */
+ public $constants;
+
+ /** @var array> */
+ public $dependencies;
+
+ /** @var string[] */
+ public $unchecked;
+
+ /**
+ * @param array $classes
+ * @param array $functions
+ * @param array $constants
+ * @param array> $dependencies
+ * @param string[] $unchecked
+ */
+ public function __construct(
+ array $classes = [],
+ array $functions = [],
+ array $constants = [],
+ array $dependencies = [],
+ array $unchecked = []
+ ) {
+ $this->classes = $classes;
+ $this->functions = $functions;
+ $this->constants = $constants;
+ $this->dependencies = $dependencies;
+ $this->unchecked = $unchecked;
+ }
+}
diff --git a/src/Output/SymfonyStyleFactory.php b/src/Output/SymfonyStyleFactory.php
new file mode 100644
index 0000000..a3c1650
--- /dev/null
+++ b/src/Output/SymfonyStyleFactory.php
@@ -0,0 +1,15 @@
+finder = $finder;
}
- public function scanForFiles(string $directory): void {
+ public function scanForFiles(string $directory): void
+ {
$this->finder->files()->name('*.php')->in($directory);
$this->finder->sortByName();
}
@@ -28,8 +34,12 @@ class FileParser {
return $this->finder->count();
}
- public function parseFiles(Closure $callback) {
- $parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
+ /**
+ * @return array
+ */
+ public function parseFiles(Closure $callback): array
+ {
+ $parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7);
$traverser = new NodeTraverser();
@@ -42,9 +52,19 @@ class FileParser {
$constantCollector = new ConstantCollector();
$traverser->addVisitor($constantCollector);
- foreach($this->finder as $file) {
+ foreach ($this->finder as $file) {
$content = $file->getContents();
- $stmts = $parser->parse($content);
+ $stmts = [];
+
+ try {
+ $stmts = $parser->parse($content);
+ } catch (Throwable $e) {
+ echo $e->getMessage();
+ }
+
+ if (empty($stmts)) {
+ continue;
+ }
$traverser->traverse($stmts);
$callback();
@@ -56,4 +76,4 @@ class FileParser {
$constantCollector->getCollected(),
];
}
-}
\ No newline at end of file
+}
diff --git a/src/Parser/FileParserFactory.php b/src/Parser/FileParserFactory.php
index 21113e5..769ba32 100644
--- a/src/Parser/FileParserFactory.php
+++ b/src/Parser/FileParserFactory.php
@@ -1,5 +1,7 @@
$options
+ */
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
return new FileParser(
new Finder()
);
}
-}
\ No newline at end of file
+}
diff --git a/src/Parser/Visitors/ClassCollector.php b/src/Parser/Visitors/ClassCollector.php
index 7890574..bd55242 100644
--- a/src/Parser/Visitors/ClassCollector.php
+++ b/src/Parser/Visitors/ClassCollector.php
@@ -1,28 +1,37 @@
$classes
+ */
private $classes = [];
- public function getCollected(): array {
+ public function getCollected(): array
+ {
$list = array_keys($this->classes);
natcasesort($list);
return array_values($list);
}
- public function enterNode(Node $node) {
+ public function enterNode(Node $node)
+ {
if ($node instanceof Node\Stmt\Class_) {
if (!empty($node->extends)) {
$this->classes[$node->extends->toString()] = true;
}
if (!empty($node->implements)) {
- foreach($node->implements as $implement) {
+ foreach ($node->implements as $implement) {
$this->classes[$implement->toString()] = true;
}
}
@@ -35,7 +44,7 @@ class ClassCollector extends NodeVisitorAbstract implements CollectorInferface {
}
if ($node instanceof Node\Expr\New_) {
- if (!empty($node->class) && $node->class->name instanceof Node\Name) {
+ if (!empty($node->class) && $node->class instanceof Node\Name) {
$this->classes[$node->class->toString()] = true;
}
}
@@ -45,5 +54,7 @@ class ClassCollector extends NodeVisitorAbstract implements CollectorInferface {
$this->classes[$node->class->toString()] = true;
}
}
+
+ return null;
}
-}
\ No newline at end of file
+}
diff --git a/src/Parser/Visitors/CollectorInferface.php b/src/Parser/Visitors/CollectorInferface.php
index fb903b8..2d991e5 100644
--- a/src/Parser/Visitors/CollectorInferface.php
+++ b/src/Parser/Visitors/CollectorInferface.php
@@ -1,7 +1,13 @@
$constants
+ */
private $constants = [];
- public function getCollected(): array {
+ public function getCollected(): array
+ {
$list = array_keys($this->constants);
natcasesort($list);
return array_values($list);
}
- public function enterNode(Node $node) {
+ public function enterNode(Node $node)
+ {
if ($node instanceof Node\Expr\ConstFetch) {
if (!empty($node->name) && $node->name instanceof Node\Name) {
$this->constants[$node->name->toString()] = true;
}
}
+
+ return null;
}
-}
\ No newline at end of file
+}
diff --git a/src/Parser/Visitors/FunctionCollector.php b/src/Parser/Visitors/FunctionCollector.php
index 8d0c268..af0b75d 100644
--- a/src/Parser/Visitors/FunctionCollector.php
+++ b/src/Parser/Visitors/FunctionCollector.php
@@ -1,25 +1,35 @@
$functions
+ */
private $functions = [];
- public function getCollected(): array {
+ public function getCollected(): array
+ {
$list = array_keys($this->functions);
natcasesort($list);
return array_values($list);
}
- public function enterNode(Node $node) {
+ public function enterNode(Node $node)
+ {
if ($node instanceof Node\Expr\FuncCall) {
if (!empty($node->name) && $node->name instanceof Node\Name) {
$this->functions[$node->name->toString()] = true;
}
}
+
+ return null;
}
-}
\ No newline at end of file
+}