Skip to content

Commit

Permalink
Merge pull request #12 from tweakphp/fix-dd
Browse files Browse the repository at this point in the history
fix dd & add stacked output
  • Loading branch information
saeedvaziry authored Jan 25, 2025
2 parents e37398e + 947f40f commit 0ed9203
Show file tree
Hide file tree
Showing 9 changed files with 163 additions and 85 deletions.
5 changes: 4 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
"require": {
"php": ">=7.4",
"ext-json": "*",
"psy/psysh": "*"
"psy/psysh": "*",
"nikic/php-parser": "*",
"symfony/var-dumper": "*",
"symfony/console": "*"
},
"minimum-stability": "stable",
"prefer-stable": true
Expand Down
28 changes: 14 additions & 14 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 2 additions & 10 deletions index.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,6 @@
exit(1);
}

function dd(...$args)
{
if (count($args) === 1) {
return $args[0];
}

return $args;
}

$loader = Loader::load($arguments[1]);

if ($loader === null) {
Expand Down Expand Up @@ -53,6 +44,7 @@ function dd(...$args)
echo 'Invalid arguments'.PHP_EOL;
exit(1);
}
echo $loader->execute(base64_decode($arguments[3])).PHP_EOL;
$output = json_encode($loader->execute(base64_decode($arguments[3])));
echo 'TWEAKPHP_RESULT:'.$output.PHP_EOL;
break;
}
29 changes: 29 additions & 0 deletions src/Casters/LaravelCaster.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace TweakPHP\Client\Casters;

class LaravelCaster
{
public static function casters(): array
{
$casters = [
'Illuminate\Support\Collection' => 'Laravel\Tinker\TinkerCaster::castCollection',
'Illuminate\Support\HtmlString' => 'Laravel\Tinker\TinkerCaster::castHtmlString',
'Illuminate\Support\Stringable' => 'Laravel\Tinker\TinkerCaster::castStringable',
];

if (class_exists('Illuminate\Database\Eloquent\Model')) {
$casters['Illuminate\Database\Eloquent\Model'] = 'Laravel\Tinker\TinkerCaster::castModel';
}

if (class_exists('Illuminate\Process\ProcessResult')) {
$casters['Illuminate\Process\ProcessResult'] = 'Laravel\Tinker\TinkerCaster::castProcessResult';
}

if (class_exists('Illuminate\Foundation\Application')) {
$casters['Illuminate\Foundation\Application'] = 'Laravel\Tinker\TinkerCaster::castApplication';
}

return $casters;
}
}
38 changes: 10 additions & 28 deletions src/Loaders/BaseLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

namespace TweakPHP\Client\Loaders;

use Psy\Configuration;
use Psy\Configuration as ConfigurationAlias;
use Psy\VersionUpdater\Checker;
use TweakPHP\Client\Casters\LaravelCaster;
use TweakPHP\Client\OutputModifiers\CustomOutputModifier;
use TweakPHP\Client\Psy\Configuration;
use TweakPHP\Client\Tinker;

abstract class BaseLoader implements LoaderInterface
Expand All @@ -17,42 +19,22 @@ public function init(): void
'configFile' => null,
]);
$config->setUpdateCheck(Checker::NEVER);
$config->setRawOutput(true);
$config->setInteractiveMode(Configuration::INTERACTIVE_MODE_DISABLED);
$config->setColorMode(Configuration::COLOR_MODE_DISABLED);
$config->setInteractiveMode(ConfigurationAlias::INTERACTIVE_MODE_DISABLED);
$config->setColorMode(ConfigurationAlias::COLOR_MODE_DISABLED);
$config->setRawOutput(false);
$config->setTheme([
'prompt' => '',
]);
$config->setVerbosity(Configuration::VERBOSITY_QUIET);
$config->setHistoryFile(defined('PHP_WINDOWS_VERSION_BUILD') ? 'null' : '/dev/null');
$config->setRawOutput(false);
if (getenv('KUBERNETES_SERVICE_HOST') || defined('PHP_WINDOWS_VERSION_BUILD')) {
$config->setUsePcntl(false);
}
$config->setUsePcntl(false);

if (class_exists('Illuminate\Support\Collection') && class_exists('Laravel\Tinker\TinkerCaster')) {
$config->getPresenter()->addCasters([
\Illuminate\Support\Collection::class => 'Laravel\Tinker\TinkerCaster::castCollection',
]);
}
if (class_exists('Illuminate\Database\Eloquent\Model') && class_exists('Laravel\Tinker\TinkerCaster')) {
$config->getPresenter()->addCasters([
\Illuminate\Database\Eloquent\Model::class => 'Laravel\Tinker\TinkerCaster::castModel',
]);
}
if (class_exists('Illuminate\Foundation\Application') && class_exists('Laravel\Tinker\TinkerCaster')) {
$config->getPresenter()->addCasters([
\Illuminate\Foundation\Application::class => 'Laravel\Tinker\TinkerCaster::castApplication',
]);
}
$config->getPresenter()->addCasters(LaravelCaster::casters());

$this->tinker = new Tinker(new CustomOutputModifier, $config);
}

public function execute(string $code): string
public function execute(string $code): array
{
$output = $this->tinker->execute($code);

return trim($output);
return $this->tinker->execute($code);
}
}
2 changes: 1 addition & 1 deletion src/Loaders/LoaderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ public function version(): string;

public function init(): void;

public function execute(string $code): string;
public function execute(string $code): array;
}
15 changes: 15 additions & 0 deletions src/Psy/Configuration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace TweakPHP\Client\Psy;

class Configuration extends \Psy\Configuration
{
public function getPresenter(): Presenter
{
if (! isset($this->presenter)) {
$this->presenter = new Presenter($this->getOutput()->getFormatter(), $this->forceArrayIndexes());
}

return $this->presenter;
}
}
54 changes: 54 additions & 0 deletions src/Psy/Presenter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace TweakPHP\Client\Psy;

use Psy\VarDumper\Cloner;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\VarDumper\Caster\Caster;
use Symfony\Component\VarDumper\Dumper\HtmlDumper;
use TweakPHP\Client\Tinker;

class Presenter extends \Psy\VarDumper\Presenter
{
private Cloner $cloner;

public function __construct(OutputFormatter $formatter, $forceArrayIndexes = false)
{
parent::__construct($formatter, $forceArrayIndexes);

$this->cloner = new Cloner;
}

public function addCasters(array $casters)
{
parent::addCasters($casters);

$this->cloner->addCasters($casters);
}

public function present($value, ?int $depth = null, int $options = 0): string
{
$dumper = new HtmlDumper;
$dumper->setDumpHeader('');
$data = $this->cloner->cloneVar($value, ! ($options & self::VERBOSE) ? Caster::EXCLUDE_VERBOSE : 0);
if ($depth !== null) {
$data = $data->withMaxDepth($depth);
}

$output = '';
$dumper->dump($data, function ($line, $depth) use (&$output) {
if ($depth >= 0) {
if ($output !== '') {
$output .= \PHP_EOL;
}
$output .= \str_repeat(' ', $depth).$line;
}
});

if (isset(Tinker::$statements[Tinker::$current])) {
Tinker::$statements[Tinker::$current]['html'] = $output;
}

return parent::present($value, $depth, $options);
}
}
65 changes: 34 additions & 31 deletions src/Tinker.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace TweakPHP\Client;

use PhpParser\ParserFactory;
use PhpParser\PrettyPrinter\Standard;
use Psy\Configuration;
use Psy\ExecutionLoopClosure;
use Psy\Shell;
Expand All @@ -16,6 +18,10 @@ class Tinker

protected OutputModifier $outputModifier;

public static array $statements = [];

public static int $current = 0;

public function __construct(OutputModifier $outputModifier, Configuration $config)
{
$this->output = new BufferedOutput;
Expand All @@ -25,23 +31,41 @@ public function __construct(OutputModifier $outputModifier, Configuration $confi
$this->outputModifier = $outputModifier;
}

public function execute(string $phpCode): string
public function execute(string $rawPHPCode): array
{
$phpCode = $this->removeComments($phpCode);

$this->shell->addInput($phpCode);
if (strpos($rawPHPCode, '<?php') === false) {
$rawPHPCode = "<?php\n".$rawPHPCode;
}

if (defined('PHP_WINDOWS_VERSION_BUILD')) {
$this->shell->addInput("\necho('TWEAKPHP_END'); exit();");
$parser = (new ParserFactory)->createForHostVersion();
$prettyPrinter = new Standard;
foreach ($parser->parse($rawPHPCode) as $key => $stmt) {
$code = $prettyPrinter->prettyPrint([$stmt]);
self::$current = $key;
self::$statements[] = [
'line' => $stmt->getStartLine(),
'code' => $code,
];
$output = $this->doExecute($code);
self::$statements[$key]['output'] = $output;
}

$closure = new ExecutionLoopClosure($this->shell);
return [
'output' => self::$statements,
];
}

protected function doExecute(string $code): string
{
$this->shell->addInput($code);
$this->shell->addInput("\necho('TWEAKPHP_END'); exit();");
$this->output = new BufferedOutput;
$this->shell->setOutput($this->output);
$closure = new ExecutionLoopClosure($this->shell);
$closure->execute();
$result = $this->outputModifier->modify($this->cleanOutput($this->output->fetch()));

$output = $this->cleanOutput($this->output->fetch());

return $this->outputModifier->modify($output);
return trim($result);
}

protected function createShell(BufferedOutput $output, Configuration $config): Shell
Expand All @@ -53,27 +77,6 @@ protected function createShell(BufferedOutput $output, Configuration $config): S
return $shell;
}

public function removeComments(string $code): string
{
$tokens = token_get_all("<?php\n".$code.'?>');
$result = '';

foreach ($tokens as $token) {
if (is_array($token)) {
[$id, $text] = $token;

if (in_array($id, [T_COMMENT, T_DOC_COMMENT, T_OPEN_TAG, T_CLOSE_TAG])) {
continue;
}
$result .= $text;
} else {
$result .= $token;
}
}

return $result;
}

protected function cleanOutput(string $output): string
{
$output = preg_replace('/(?s)(<aside.*?<\/aside>)|Exit: Ctrl\+D/ms', '$2', $output);
Expand Down

0 comments on commit 0ed9203

Please sign in to comment.