Skip to content

Commit 6cd7ee6

Browse files
committed
Merge support, parser and reflection
0 parents  commit 6cd7ee6

File tree

134 files changed

+9557
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

134 files changed

+9557
-0
lines changed

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.pp linguist-language=Antlr

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.idea/
2+
vendor/
3+
composer.lock

Compiler.php

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
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\Compiler;
11+
12+
use Hoa\Compiler\Llk\TreeNode;
13+
use Psr\Log\LoggerInterface;
14+
use Railt\Compiler\Filesystem\ReadableInterface;
15+
use Railt\Compiler\Exceptions\CompilerException;
16+
use Railt\Compiler\Exceptions\UnexpectedTokenException;
17+
use Railt\Compiler\Exceptions\UnrecognizedTokenException;
18+
use Railt\Compiler\Reflection\Builder\DocumentBuilder;
19+
use Railt\Compiler\Reflection\Builder\Process\Compilable;
20+
use Railt\Compiler\Reflection\CompilerInterface;
21+
use Railt\Compiler\Reflection\Contracts\Definitions\Definition;
22+
use Railt\Compiler\Reflection\Contracts\Document;
23+
use Railt\Compiler\Reflection\Dictionary;
24+
use Railt\Compiler\Exceptions\TypeConflictException;
25+
use Railt\Compiler\Exceptions\TypeNotFoundException;
26+
use Railt\Compiler\Reflection\Loader;
27+
use Railt\Compiler\Persisting\ArrayPersister;
28+
use Railt\Compiler\Persisting\Persister;
29+
use Railt\Compiler\Persisting\Proxy;
30+
use Railt\Compiler\Reflection\Standard\GraphQLDocument;
31+
use Railt\Compiler\Reflection\Support;
32+
33+
/**
34+
* Class Compiler
35+
*/
36+
class Compiler implements CompilerInterface
37+
{
38+
use Support;
39+
40+
/**
41+
* @var Dictionary
42+
*/
43+
private $loader;
44+
45+
/**
46+
* @var Parser
47+
*/
48+
private $parser;
49+
50+
/**
51+
* @var Persister|ArrayPersister
52+
*/
53+
private $persister;
54+
55+
/**
56+
* @var LoggerInterface
57+
*/
58+
private $logger;
59+
60+
/**
61+
* Compiler constructor.
62+
* @param Persister|null $persister
63+
* @param LoggerInterface|null $logger
64+
* @throws \Railt\Compiler\Exceptions\InitializationException
65+
*/
66+
public function __construct(Persister $persister = null, LoggerInterface $logger = null)
67+
{
68+
$this->logger = $logger;
69+
70+
$this->parser = new Parser($logger);
71+
$this->loader = new Loader($this);
72+
73+
$this->persister = $this->bootPersister($persister);
74+
75+
$this->bootStandardLibrary();
76+
}
77+
78+
/**
79+
* @param null|Persister $persister
80+
* @return Persister
81+
*/
82+
private function bootPersister(?Persister $persister): Persister
83+
{
84+
if ($persister === null) {
85+
return new ArrayPersister();
86+
}
87+
88+
if ($persister instanceof Proxy || $persister instanceof ArrayPersister) {
89+
return $persister;
90+
}
91+
92+
return new Proxy(new ArrayPersister(), $persister);
93+
}
94+
95+
/**
96+
* @param array $extensions
97+
* @return GraphQLDocument
98+
*/
99+
private function bootStandardLibrary(array $extensions = []): GraphQLDocument
100+
{
101+
$std = new GraphQLDocument($this, $extensions);
102+
103+
foreach ($std->getTypes() as $type) {
104+
$this->loader->register($type);
105+
}
106+
107+
return $std;
108+
}
109+
110+
/**
111+
* @param \Closure $then
112+
* @return CompilerInterface
113+
*/
114+
public function registerAutoloader(\Closure $then): CompilerInterface
115+
{
116+
$this->loader->registerAutoloader($then);
117+
118+
return $this;
119+
}
120+
121+
/**
122+
* @param ReadableInterface $readable
123+
* @return Document
124+
* @throws TypeNotFoundException
125+
* @throws TypeConflictException
126+
* @throws UnexpectedTokenException
127+
* @throws UnrecognizedTokenException
128+
* @throws CompilerException
129+
*/
130+
public function compile(ReadableInterface $readable): Document
131+
{
132+
/** @var DocumentBuilder $document */
133+
$document = $this->persister->remember($readable, $this->onCompile());
134+
135+
return $document->withCompiler($this);
136+
}
137+
138+
/**
139+
* @return \Closure
140+
* @throws UnexpectedTokenException
141+
* @throws UnrecognizedTokenException
142+
* @throws CompilerException
143+
*/
144+
private function onCompile(): \Closure
145+
{
146+
return function (ReadableInterface $readable): Document {
147+
$ast = $this->parser->parse($readable);
148+
149+
$document = (new DocumentBuilder($ast, $readable))->withCompiler($this);
150+
151+
$this->bootProcessableTypes($document);
152+
153+
return $document;
154+
};
155+
}
156+
157+
/**
158+
* Process eager loading for compile-time types, like "extend"
159+
*
160+
* @param Document $document
161+
* @return void
162+
*/
163+
private function bootProcessableTypes(Document $document): void
164+
{
165+
foreach ($document->getTypes() as $type) {
166+
if ($type instanceof Compilable && ! $this->isUniqueType($type)) {
167+
$type->compileIfNotCompiled();
168+
}
169+
}
170+
}
171+
172+
/**
173+
* @param Definition $type
174+
* @param bool $force
175+
* @return Dictionary
176+
*/
177+
public function register(Definition $type, bool $force = false): Dictionary
178+
{
179+
return $this->loader->register($type, $force);
180+
}
181+
182+
/**
183+
* @param string $name
184+
* @param Document|null $document
185+
* @return null|Definition
186+
*/
187+
public function get(string $name, Document $document = null): Definition
188+
{
189+
return $this->loader->get($name, $document);
190+
}
191+
192+
/**
193+
* @param Document|null $document
194+
* @return array
195+
*/
196+
public function all(Document $document = null): array
197+
{
198+
return $this->loader->all($document);
199+
}
200+
201+
/**
202+
* @param string $name
203+
* @param Document|null $document
204+
* @return bool
205+
*/
206+
public function has(string $name, Document $document = null): bool
207+
{
208+
return $this->loader->has($name, $document);
209+
}
210+
211+
/**
212+
* @param TreeNode $ast
213+
* @return string
214+
*/
215+
public function dump(TreeNode $ast): string
216+
{
217+
return $this->parser->dump($ast);
218+
}
219+
}

Exceptions/BuildingException.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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\Compiler\Exceptions;
11+
12+
/**
13+
* Class BuildingException
14+
* @package Railt\Compiler\Exceptions
15+
*/
16+
class BuildingException extends \LogicException
17+
{
18+
19+
}

Exceptions/CompilerException.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
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\Compiler\Exceptions;
11+
12+
/**
13+
* Class CompilerException
14+
*/
15+
class CompilerException extends \LogicException
16+
{
17+
18+
}

Exceptions/Helper.php

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
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\Compiler\Exceptions;
11+
12+
/**
13+
* Trait Helper
14+
*/
15+
trait Helper
16+
{
17+
/**
18+
* @var int
19+
*/
20+
protected $column = 0;
21+
22+
/**
23+
* @param string $message
24+
* @param array ...$params
25+
* @return $this|static|\Throwable
26+
*/
27+
public static function create(string $message, ...$params): \Throwable
28+
{
29+
return new static(sprintf($message, ...$params));
30+
}
31+
32+
/**
33+
* @param int $code
34+
* @return self|$this
35+
*/
36+
public function withCode(int $code = 0)
37+
{
38+
$this->code = $code;
39+
40+
return $this;
41+
}
42+
43+
/**
44+
* @param \Throwable $previous
45+
* @return self|$this
46+
*/
47+
public function withParent(\Throwable $previous)
48+
{
49+
$this->previous = $previous;
50+
51+
return $this;
52+
}
53+
54+
/**
55+
* @param string $message
56+
* @param array ...$params
57+
* @throws $this|static
58+
* @throws \Throwable
59+
*/
60+
public static function throw(string $message, ...$params): void
61+
{
62+
throw static::create($message, ...$params);
63+
}
64+
65+
/**
66+
* @param string $file
67+
* @return $this
68+
*/
69+
public function in(string $file)
70+
{
71+
$this->file = $file;
72+
73+
return $this;
74+
}
75+
76+
/**
77+
* @param int $line
78+
* @param int $column
79+
* @return $this
80+
*/
81+
public function on(int $line = 0, int $column = 0)
82+
{
83+
$this->line = $line;
84+
$this->column = $column;
85+
86+
return $this;
87+
}
88+
89+
/**
90+
* @return int
91+
*/
92+
public function getColumn(): int
93+
{
94+
return $this->column;
95+
}
96+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
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\Compiler\Exceptions;
11+
12+
/**
13+
* Class InitializationException
14+
*/
15+
class InitializationException extends CompilerException
16+
{
17+
}

0 commit comments

Comments
 (0)