Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misc quick fixes and improvements #901

Merged
merged 10 commits into from
Jun 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -294,9 +294,15 @@
'$dependentLayerResolver' => service('layer_resolver.dependent'),
]);
$services->set(LegacyDependencyLayersAnalyser::class);
$services->set(TokenInLayerAnalyser::class);
$services->set(TokenInLayerAnalyser::class)
->args([
'$config' => param('analyser'),
]);
$services->set(LayerForTokenAnalyser::class);
$services->set(UnassignedTokenAnalyser::class);
$services->set(UnassignedTokenAnalyser::class)
->args([
'$config' => param('analyser'),
]);

/*
* OutputFormatter
Expand Down
6 changes: 3 additions & 3 deletions docs/debugging.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ combined with other tools like `wc` or `grep`.
## `debug:layer`

With the `debug:layer`-command you can list all tokens which are matched in
a specific layer.
a specific layer. This command only shows tokens that would be emitted by your analyser configuration.

```bash
php deptrac.phar debug:layer --config-file=examples/DirectoryLayer.depfile.yaml Layer1
Expand All @@ -19,7 +19,7 @@ examples\Layer1\SomeClass2

## `debug:token`

The `debug:token` (previously `debug:class-like`)-command will let you know which layers a specified token belongs to.
The `debug:token` (previously `debug:class-like`)-command will let you know which layers a specified token belongs to. Since you can specify the token type, this commands ignores your analyser configuration for emitted token types.

```bash
php deptrac.phar debug:token --config-file=examples/DirectoryLayer.depfile.yaml 'examples\Layer1\AnotherClassLikeAController' class-like
Expand All @@ -32,7 +32,7 @@ Layer1

With the `debug:unassigned`-command you list all tokens in your path that are
not assigned to any layer. This is useful to test that your collector
configuration for layers is correct.
configuration for layers is correct. This command only shows tokens that would be emitted by your analyser configuration.

```bash
php deptrac.phar debug:unassigned --config-file=examples/DirectoryLayer.depfile.yaml
Expand Down
4 changes: 2 additions & 2 deletions docs/depfile.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ configuration.

If your depfile configuration becomes too large, you can split it up into
multiple files that can then be imported in the main depfile using the `imports`
section.
section. This is also useful to separate your baseline from the rest of the configuration, so it can be regenerated by the `baseline` formatter.

Example:

```yaml
imports:
- some/depfile.yaml
- deptrac.baseline.yaml
```

## deptrac section
Expand Down
16 changes: 8 additions & 8 deletions src/Analyser/LayerForTokenAnalyser.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

use Qossmic\Deptrac\Ast\AstMap\AstMap;
use Qossmic\Deptrac\Ast\AstMap\TokenReferenceInterface;
use Qossmic\Deptrac\Console\Exception\InvalidTokenException;
use Qossmic\Deptrac\Dependency\TokenResolver;
use Qossmic\Deptrac\Exception\ShouldNotHappenException;
use Qossmic\Deptrac\Layer\LayerResolverInterface;
use function array_values;
use function ksort;
Expand All @@ -33,20 +33,20 @@ public function __construct(
/**
* @return array<string, string[]>
*/
public function findLayerForToken(string $tokenName, string $tokenType): array
public function findLayerForToken(string $tokenName, TokenType $tokenType): array
{
$astMap = $this->astMapExtractor->extract();

switch ($tokenType) {
case 'class-like':
switch ($tokenType->value) {
case TokenType::CLASS_LIKE:
return $this->findLayersForReferences($astMap->getClassLikeReferences(), $tokenName, $astMap);
case 'function':
case TokenType::FUNCTION:
return $this->findLayersForReferences($astMap->getFunctionLikeReferences(), $tokenName, $astMap);
case 'file':
case TokenType::FILE:
return $this->findLayersForReferences($astMap->getFileReferences(), $tokenName, $astMap);
default:
throw new ShouldNotHappenException();
}

throw InvalidTokenException::invalidTokenType($tokenType, ['class-like', 'function', 'file']);
}

/**
Expand Down
56 changes: 47 additions & 9 deletions src/Analyser/TokenInLayerAnalyser.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Qossmic\Deptrac\Analyser;

use Qossmic\Deptrac\Dependency\DependencyResolver;
use Qossmic\Deptrac\Dependency\TokenResolver;
use Qossmic\Deptrac\Layer\LayerResolverInterface;
use function array_values;
Expand All @@ -16,14 +17,34 @@ class TokenInLayerAnalyser
private TokenResolver $tokenResolver;
private LayerResolverInterface $layerResolver;

/**
* @var array<string>
*/
private array $tokenTypes;

/**
* @param array{types?: array<string>} $config
*/
public function __construct(
AstMapExtractor $astMapExtractor,
TokenResolver $tokenResolver,
LayerResolverInterface $layerResolver
LayerResolverInterface $layerResolver,
array $config
) {
$this->astMapExtractor = $astMapExtractor;
$this->tokenResolver = $tokenResolver;
$this->layerResolver = $layerResolver;
$emitters = array_merge(DependencyResolver::DEFAULT_EMITTERS, $config);
$this->tokenTypes = array_filter(
array_map(
static function (string $emitterType): ?string {
$tokenType = TokenType::tryFromEmitterType($emitterType);

return null === $tokenType ? null : $tokenType->value;
},
$emitters['types']
)
);
}

/**
Expand All @@ -34,17 +55,34 @@ public function findTokensInLayer(string $layer): array
$astMap = $this->astMapExtractor->extract();

$matchingTokens = [];
foreach ($astMap->getClassLikeReferences() as $classReference) {
$classToken = $this->tokenResolver->resolve($classReference->getToken(), $astMap);
if (in_array($layer, $this->layerResolver->getLayersForReference($classToken, $astMap), true)) {
$matchingTokens[] = $classToken->getToken()->toString();

if (in_array(TokenType::CLASS_LIKE, $this->tokenTypes, true)) {
foreach ($astMap->getClassLikeReferences() as $classReference) {
$classToken = $this->tokenResolver->resolve($classReference->getToken(), $astMap);
if (in_array($layer, $this->layerResolver->getLayersForReference($classToken, $astMap), true)) {
$matchingTokens[] = $classToken->getToken()
->toString();
}
}
}

if (in_array(TokenType::FUNCTION, $this->tokenTypes, true)) {
foreach ($astMap->getFunctionLikeReferences() as $functionReference) {
$functionToken = $this->tokenResolver->resolve($functionReference->getToken(), $astMap);
if (in_array($layer, $this->layerResolver->getLayersForReference($functionToken, $astMap), true)) {
$matchingTokens[] = $functionToken->getToken()
->toString();
}
}
}

foreach ($astMap->getFunctionLikeReferences() as $functionReference) {
$functionToken = $this->tokenResolver->resolve($functionReference->getToken(), $astMap);
if (in_array($layer, $this->layerResolver->getLayersForReference($functionToken, $astMap), true)) {
$matchingTokens[] = $functionToken->getToken()->toString();
if (in_array(TokenType::FILE, $this->tokenTypes, true)) {
foreach ($astMap->getFileReferences() as $fileReference) {
$fileToken = $this->tokenResolver->resolve($fileReference->getToken(), $astMap);
if (in_array($layer, $this->layerResolver->getLayersForReference($fileToken, $astMap), true)) {
$matchingTokens[] = $fileToken->getToken()
->toString();
}
}
}

Expand Down
61 changes: 61 additions & 0 deletions src/Analyser/TokenType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

declare(strict_types=1);

namespace Qossmic\Deptrac\Analyser;

use Qossmic\Deptrac\Console\Exception\InvalidTokenException;
use Qossmic\Deptrac\Dependency\Emitter\EmitterTypes;

/**
* @psalm-immutable
*/
class TokenType
{
public const CLASS_LIKE = 'class-like';
public const FUNCTION = 'function';
public const FILE = 'file';

/** @var 'class-like'|'function'|'file' */
public string $value;

/** @param 'class-like'|'function'|'file' $value */
private function __construct(string $value)
{
$this->value = $value;
}

/**
* @return array{'class-like', 'function', 'file'}
*/
public static function values(): array
{
return [
self::CLASS_LIKE,
self::FUNCTION,
self::FILE,
];
}

public static function from(string $value): self
{
if (!in_array($value, self::values(), true)) {
throw InvalidTokenException::invalidTokenType($value, self::values());
}

return new self($value);
}

public static function tryFromEmitterType(string $emitterType): ?self
{
if (EmitterTypes::CLASS_TOKEN === $emitterType) {
$emitterType = self::CLASS_LIKE;
}

try {
return self::from($emitterType);
} catch (InvalidTokenException $exception) {
return null;
}
}
}
57 changes: 46 additions & 11 deletions src/Analyser/UnassignedTokenAnalyser.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Qossmic\Deptrac\Analyser;

use Qossmic\Deptrac\Dependency\DependencyResolver;
use Qossmic\Deptrac\Dependency\TokenResolver;
use Qossmic\Deptrac\Layer\LayerResolverInterface;
use function array_values;
Expand All @@ -15,14 +16,34 @@ class UnassignedTokenAnalyser
private TokenResolver $tokenResolver;
private LayerResolverInterface $layerResolver;

/**
* @var array<string>
*/
private array $tokenTypes;

/**
* @param array{types?: array<string>} $config
*/
public function __construct(
AstMapExtractor $astMapExtractor,
TokenResolver $tokenResolver,
LayerResolverInterface $layerResolver
LayerResolverInterface $layerResolver,
array $config
) {
$this->astMapExtractor = $astMapExtractor;
$this->tokenResolver = $tokenResolver;
$this->layerResolver = $layerResolver;
$emitters = array_merge(DependencyResolver::DEFAULT_EMITTERS, $config);
$this->tokenTypes = array_filter(
array_map(
static function (string $emitterType): ?string {
$tokenType = TokenType::tryFromEmitterType($emitterType);

return null === $tokenType ? null : $tokenType->value;
},
$emitters['types']
)
);
}

/**
Expand All @@ -33,19 +54,33 @@ public function findUnassignedTokens(): array
$astMap = $this->astMapExtractor->extract();
$unassignedTokens = [];

foreach ($astMap->getClassLikeReferences() as $classReference) {
$token = $this->tokenResolver->resolve($classReference->getToken(), $astMap);
$matchingLayers = $this->layerResolver->getLayersForReference($token, $astMap);
if ([] === $matchingLayers) {
$unassignedTokens[] = $classReference->getToken()->toString();
if (in_array(TokenType::CLASS_LIKE, $this->tokenTypes, true)) {
foreach ($astMap->getClassLikeReferences() as $classReference) {
$token = $this->tokenResolver->resolve($classReference->getToken(), $astMap);
$matchingLayers = $this->layerResolver->getLayersForReference($token, $astMap);
if ([] === $matchingLayers) {
$unassignedTokens[] = $classReference->getToken()->toString();
}
}
}

if (in_array(TokenType::FUNCTION, $this->tokenTypes, true)) {
foreach ($astMap->getFunctionLikeReferences() as $functionReference) {
$token = $this->tokenResolver->resolve($functionReference->getToken(), $astMap);
$matchingLayers = $this->layerResolver->getLayersForReference($token, $astMap);
if ([] === $matchingLayers) {
$unassignedTokens[] = $functionReference->getToken()->toString();
}
}
}

foreach ($astMap->getFunctionLikeReferences() as $functionReference) {
$token = $this->tokenResolver->resolve($functionReference->getToken(), $astMap);
$matchingLayers = $this->layerResolver->getLayersForReference($token, $astMap);
if ([] === $matchingLayers) {
$unassignedTokens[] = $functionReference->getToken()->toString();
if (in_array(TokenType::FILE, $this->tokenTypes, true)) {
foreach ($astMap->getFileReferences() as $fileReference) {
$token = $this->tokenResolver->resolve($fileReference->getToken(), $astMap);
$matchingLayers = $this->layerResolver->getLayersForReference($token, $astMap);
if ([] === $matchingLayers) {
$unassignedTokens[] = $fileReference->getToken()->toString();
}
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/Console/Command/DebugTokenCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Qossmic\Deptrac\Console\Command;

use Qossmic\Deptrac\Analyser\TokenType;
use Qossmic\Deptrac\Console\Symfony\Style;
use Qossmic\Deptrac\Console\Symfony\SymfonyOutput;
use Symfony\Component\Console\Command\Command;
Expand Down Expand Up @@ -42,7 +43,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
/** @var string $tokenType */
$tokenType = $input->getArgument('type');

$this->runner->run($tokenName, $tokenType, $symfonyOutput);
$this->runner->run($tokenName, TokenType::from($tokenType), $symfonyOutput);

return 0;
}
Expand Down
3 changes: 2 additions & 1 deletion src/Console/Command/DebugTokenRunner.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Qossmic\Deptrac\Console\Command;

use Qossmic\Deptrac\Analyser\LayerForTokenAnalyser;
use Qossmic\Deptrac\Analyser\TokenType;
use Qossmic\Deptrac\Console\Output;
use function implode;
use function sprintf;
Expand All @@ -21,7 +22,7 @@ public function __construct(LayerForTokenAnalyser $processor)
$this->processor = $processor;
}

public function run(string $tokenName, string $tokenType, Output $output): void
public function run(string $tokenName, TokenType $tokenType, Output $output): void
{
$matches = $this->processor->findLayerForToken($tokenName, $tokenType);

Expand Down
9 changes: 8 additions & 1 deletion src/Console/Command/DebugUnassignedRunner.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ public function __construct(UnassignedTokenAnalyser $processor)

public function run(Output $output): void
{
$output->writeLineFormatted($this->processor->findUnassignedTokens());
$unassignedTokens = $this->processor->findUnassignedTokens();
if ([] === $unassignedTokens) {
$output->writeLineFormatted('There are not unassigned tokens.');

return;
}

$output->writeLineFormatted($unassignedTokens);
}
}
Loading