Completed
Push — master ( 469dde...5ac91e )
by Kirill
35:14
created

ParserCompileCommand::configure()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 26
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 26
ccs 0
cts 23
cp 0
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 18
nc 1
nop 0
crap 2
1
<?php
2
/**
3
 * This file is part of Railt package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
declare(strict_types=1);
9
10
namespace Railt\SDL\Console;
11
12
use Railt\Compiler\Generator\ParserGenerator;
13
use Railt\Compiler\Grammar\ParsingResult;
14
use Railt\Compiler\Grammar\Reader;
15
use Railt\Io\File;
16
use Railt\SDL\Parser\Factory;
17
use Symfony\Component\Console\Command\Command;
18
use Symfony\Component\Console\Input\InputArgument;
19
use Symfony\Component\Console\Input\InputInterface;
20
use Symfony\Component\Console\Output\OutputInterface;
21
22
/**
23
 * Class ParserCompileCommand
24
 */
25
class ParserCompileCommand extends Command
26
{
27
    /**
28
     * @var string Default parser output path
29
     */
30
    private const DEFAULT_PATH = __DIR__ . '/../Parser';
31
32
    /**
33
     * @var string Default generated parser FQN
34
     */
35
    private const DEFAULT_PARSER_CLASS_NAME = \Railt\SDL\Parser\SchemaParser::class;
36
37
    /**
38
     * @param InputInterface $in
39
     * @param OutputInterface $out
40
     * @return int|null|void
41
     * @throws \LogicException
42
     */
43
    public function execute(InputInterface $in, OutputInterface $out)
44
    {
45
        $grammar = File::fromPathname($in->getArgument('grammar'));
46
47
        $this->buildParser($in, (new Reader())->read($grammar));
0 ignored issues
show
Bug introduced by
It seems like $grammar defined by \Railt\Io\File::fromPath...getArgument('grammar')) on line 45 can also be of type object<Railt\Io\File>; however, Railt\Compiler\Grammar\Reader::read() does only seem to accept object<Railt\Io\Readable>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
48
        $out->writeln('<info>OK</info>');
49
    }
50
51
    /**
52
     * @param InputInterface $in
53
     * @param ParsingResult $reader
54
     * @throws \Symfony\Component\Console\Exception\InvalidArgumentException
55
     */
56
    private function buildParser(InputInterface $in, ParsingResult $reader): void
57
    {
58
        [$class, $namespace] = $this->split($in->getArgument('parser'));
0 ignored issues
show
Bug introduced by
The variable $class does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $namespace does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
59
60
        (new ParserGenerator($reader))
61
            ->class($class)->namespace($namespace)->build()
62
            ->saveTo($in->getArgument('output'));
63
    }
64
65
    /**
66
     * @param string $class
67
     * @return array
68
     */
69
    private function split(string $class): array
70
    {
71
        $parts = \array_filter(\explode('\\', $class));
72
73
        return [\array_pop($parts), \implode('\\', $parts)];
74
    }
75
76
    /**
77
     * @return void
78
     * @throws \Symfony\Component\Console\Exception\InvalidArgumentException
79
     * @throws \Symfony\Component\Console\Exception\LogicException
80
     */
81
    protected function configure(): void
82
    {
83
        $this->setName('parser:compile');
84
        $this->setDescription('Builds a new optimised lexer and parser from .pp/.pp2 grammar file.');
85
86
        $this->addArgument(
87
            'output',
88
            InputArgument::OPTIONAL,
89
            'Output generated lexer directory',
90
            self::DEFAULT_PATH
91
        );
92
93
        $this->addArgument(
94
            'grammar',
95
            InputArgument::OPTIONAL,
96
            'Input grammar file',
97
            Factory::GRAMMAR_FILE
98
        );
99
100
        $this->addArgument(
101
            'parser',
102
            InputArgument::OPTIONAL,
103
            'The parser output class name',
104
            self::DEFAULT_PARSER_CLASS_NAME
105
        );
106
    }
107
}
108