Skip to content

Commit

Permalink
Merge pull request #575 from jolicode/stub-sf-functions
Browse files Browse the repository at this point in the history
Add official support strings and var-dumper functions
  • Loading branch information
lyrixx authored Nov 15, 2024
2 parents a1e2761 + 8c8b608 commit 0813a7c
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* Better rendering of run errors
* Add `check()` function to ensure requirements are met
* Add `ProblemException` to handle problems in a more structured way
* Add official support for symfony/string and symfony/var-dumper functions

### Internal

Expand Down
13 changes: 13 additions & 0 deletions doc/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,19 @@ Castor provides the following built-in functions:
- [`yaml_dump`](going-further/helpers/yaml.md)
- [`yaml_parse`](going-further/helpers/yaml.md)

## Vendor helpers

Some vendor helpers are also included natively in Castor:

- Functions from symfony/string:
- [`u`](https://symfony.com/doc/current/string.html#method-reference)
- [`b`](https://symfony.com/doc/current/string.html#method-reference)
- [`s`](https://symfony.com/doc/current/string.html#method-reference)

- Functions from symfony/var-dumper:
- [`dump`](https://symfony.com/doc/current/components/var_dumper.html#the-dump-function)
- [`dd`](https://symfony.com/doc/current/components/var_dumper.html#the-dump-function)

## Attributes

Castor provides the following attributes to register tasks, listener, etc:
Expand Down
20 changes: 19 additions & 1 deletion src/Stub/StubsGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ private function generateCastorStubs(string $dest): void
\Symfony\Contracts\HttpClient\Exception\ExceptionInterface::class,
\Symfony\Contracts\HttpClient\HttpClientInterface::class,
\Symfony\Contracts\HttpClient\ResponseInterface::class,
\Symfony\Component\String\AbstractString::class,
\Symfony\Component\String\AbstractUnicodeString::class,
\Symfony\Component\String\ByteString::class,
\Symfony\Component\String\CodePointString::class,
\Symfony\Component\String\Exception\ExceptionInterface::class,
\Symfony\Component\String\UnicodeString::class,
];

foreach ($frequentlyUsedClasses as $class) {
Expand All @@ -86,6 +92,10 @@ private function generateCastorStubs(string $dest): void
$files[] = $file;
}

// Expose some functions provided by vendors
$files[] = "{$basePath}/vendor/symfony/string/Resources/functions.php";
$files[] = "{$basePath}/vendor/symfony/var-dumper/Resources/functions/dump.php";

$stmts = $this->doGenerate($files);

array_unshift($stmts, new Stmt\Nop([
Expand Down Expand Up @@ -127,16 +137,24 @@ private function doGenerate(array $files): array

$phpDocNodeTraverser = new PhpDocNodeTraverser([new PhpDocNodeVisitor($nameResolver)]);

$nodeVisitor = new NodeVisitor($phpDocNodeTraverser, $lexer, $phpDocParser);

$traverser = new NodeTraverser();
$traverser->addVisitor($nameResolver);
$traverser->addVisitor(new NodeVisitor($phpDocNodeTraverser, $lexer, $phpDocParser));
$traverser->addVisitor($nodeVisitor);

// Parse all files one by one, traverse the related AST then merge all statements
foreach ($files as $file) {
$fileStmts = $parser->parse((string) file_get_contents((string) $file));
if (!$fileStmts) {
continue;
}

$firstStmt = $fileStmts[0];
if (!$firstStmt instanceof Stmt\Namespace_) {
$fileStmts = [new Stmt\Namespace_(null, $fileStmts)];
}

$stmts = array_merge($stmts, $traverser->traverse($fileStmts));
}

Expand Down
34 changes: 34 additions & 0 deletions tests/Stub/fixtures/global-namespace/expected.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace Symfony\Component\String {
if (!\function_exists(\Symfony\Component\String\u::class)) {
function u(?string $string = ''): \Symfony\Component\String\UnicodeString
{
}
}
if (!\function_exists(\Symfony\Component\String\b::class)) {
function b(?string $string = ''): \Symfony\Component\String\ByteString
{
}
}
if (!\function_exists(\Symfony\Component\String\s::class)) {
/**
* @return \Symfony\Component\String\UnicodeString|\Symfony\Component\String\ByteString
*/
function s(?string $string = ''): \Symfony\Component\String\AbstractString
{
}
}
}
namespace {
if (!\function_exists('dump')) {
function dump(mixed ...$vars): mixed
{
}
}
if (!\function_exists('dd')) {
function dd(mixed ...$vars): never
{
}
}
}
38 changes: 38 additions & 0 deletions tests/Stub/fixtures/global-namespace/input1.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\String;

if (!\function_exists(u::class)) {
function u(?string $string = ''): UnicodeString
{
return new UnicodeString($string ?? '');
}
}

if (!\function_exists(b::class)) {
function b(?string $string = ''): ByteString
{
return new ByteString($string ?? '');
}
}

if (!\function_exists(s::class)) {
/**
* @return UnicodeString|ByteString
*/
function s(?string $string = ''): AbstractString
{
$string ??= '';

return preg_match('//u', $string) ? new UnicodeString($string) : new ByteString($string);
}
}
58 changes: 58 additions & 0 deletions tests/Stub/fixtures/global-namespace/input2.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

use Symfony\Component\VarDumper\Caster\ScalarStub;
use Symfony\Component\VarDumper\VarDumper;

if (!function_exists('dump')) {
function dump(mixed ...$vars): mixed
{
if (!$vars) {
VarDumper::dump(new ScalarStub('🐛'));

return null;
}

if (array_key_exists(0, $vars) && 1 === count($vars)) {
VarDumper::dump($vars[0]);
$k = 0;
} else {
foreach ($vars as $k => $v) {
VarDumper::dump($v, is_int($k) ? 1 + $k : $k);
}
}

if (1 < count($vars)) {
return $vars;
}

return $vars[$k];
}
}

if (!function_exists('dd')) {
function dd(mixed ...$vars): never
{
if (!\in_array(\PHP_SAPI, ['cli', 'phpdbg', 'embed'], true) && !headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}

if (array_key_exists(0, $vars) && 1 === count($vars)) {
VarDumper::dump($vars[0]);
} else {
foreach ($vars as $k => $v) {
VarDumper::dump($v, is_int($k) ? 1 + $k : $k);
}
}

exit(1);
}
}

0 comments on commit 0813a7c

Please sign in to comment.