diff --git a/composer.json b/composer.json
index 00df1da0a..9e04b3a90 100644
--- a/composer.json
+++ b/composer.json
@@ -46,7 +46,7 @@
},
"extra": {
"branch-alias": {
- "dev-master": "2.11-dev"
+ "dev-master": "3.0-dev"
}
}
}
diff --git a/examples/dump.php b/examples/dump.php
index fc007ea74..0037d1365 100644
--- a/examples/dump.php
+++ b/examples/dump.php
@@ -35,6 +35,14 @@
echo "
Objects
\n";
echo "Hover over the name \$baz to see property declaring class and over the hash #5 to see same objects.
\n";
+enum Suit
+{
+ case Clubs;
+ case Diamonds;
+ case Hearts;
+ case Spades;
+}
+
class ParentClass
{
public $foo = [10, 20];
@@ -42,6 +50,8 @@ class ParentClass
protected $bar = 30;
private $baz = 'parent';
+
+ public Suit $enum = Suit::Clubs;
}
#[\AllowDynamicProperties]
@@ -87,7 +97,8 @@ class ChildClass extends ParentClass
$arr = [
fopen(__FILE__, 'r'),
- new class {},
+ new class {
+},
function ($x, $y) use (&$arr, $obj) {},
];
diff --git a/src/Bridges/Nette/TracyExtension.php b/src/Bridges/Nette/TracyExtension.php
index d4244cc16..b1141531a 100644
--- a/src/Bridges/Nette/TracyExtension.php
+++ b/src/Bridges/Nette/TracyExtension.php
@@ -105,12 +105,17 @@ public function afterCompile(Nette\PhpGenerator\ClassType $class): void
foreach ($options as $key => $value) {
if ($value !== null) {
$tbl = [
- 'keysToHide' => 'array_push(Tracy\Debugger::getBlueScreen()->keysToHide, ... ?)',
- 'fromEmail' => 'if ($logger instanceof Tracy\Logger) $logger->fromEmail = ?',
- 'emailSnooze' => 'if ($logger instanceof Tracy\Logger) $logger->emailSnooze = ?',
+ 'keysToHide' => [
+ '$keysToHide = ?',
+ 'array_push(Tracy\Debugger::$keysToHide, ...$keysToHide)',
+ 'array_push(Tracy\Debugger::getBlueScreen()->keysToHide, ...$keysToHide)',
+ 'array_push(Nette\Bridges\DITracy\ContainerPanel::$keysToHide, ...$keysToHide)',
+ ],
+ 'fromEmail' => ['if ($logger instanceof Tracy\Logger) $logger->fromEmail = ?'],
+ 'emailSnooze' => ['if ($logger instanceof Tracy\Logger) $logger->emailSnooze = ?'],
];
$initialize->addBody($builder->formatPhp(
- ($tbl[$key] ?? 'Tracy\Debugger::$' . $key . ' = ?') . ';',
+ (isset($tbl[$key]) ? implode(";\n", $tbl[$key]) : ('Tracy\Debugger::$' . $key . ' = ?')) . ';',
Nette\DI\Helpers::filterArguments([$value]),
));
}
@@ -131,7 +136,7 @@ public function afterCompile(Nette\PhpGenerator\ClassType $class): void
if ($this->debugMode) {
foreach ($this->config->bar as $item) {
if (is_string($item) && substr($item, 0, 1) === '@') {
- $item = new Statement(['@' . $builder::THIS_CONTAINER, 'getService'], [substr($item, 1)]);
+ $item = new Statement(['@' . $builder::ThisContainer, 'getService'], [substr($item, 1)]);
} elseif (is_string($item)) {
$item = new Statement($item);
}
diff --git a/src/Tracy/BlueScreen/BlueScreen.php b/src/Tracy/BlueScreen/BlueScreen.php
index 4596b7bb7..bd1984e3f 100644
--- a/src/Tracy/BlueScreen/BlueScreen.php
+++ b/src/Tracy/BlueScreen/BlueScreen.php
@@ -321,7 +321,7 @@ public static function highlightFile(
? CodeHighlighter::highlightPhp($source, $line, $column)
: '' . CodeHighlighter::highlightLine(htmlspecialchars($source, ENT_IGNORE, 'UTF-8'), $line, $column) . '
';
- if ($editor = Helpers::editorUri($file, $line)) {
+ if ($editor = Helpers::editorUri($file, line: $line, column: $column)) {
$source = substr_replace($source, ' title="Ctrl-Click to open in editor" data-tracy-href="' . Helpers::escapeHtml($editor) . '"', 4, 0);
}
diff --git a/src/Tracy/BlueScreen/assets/section-stack-callStack.phtml b/src/Tracy/BlueScreen/assets/section-stack-callStack.phtml
index 74b3744d8..f11007713 100644
--- a/src/Tracy/BlueScreen/assets/section-stack-callStack.phtml
+++ b/src/Tracy/BlueScreen/assets/section-stack-callStack.phtml
@@ -57,7 +57,7 @@ if (!$stack) {
- = BlueScreen::highlightFile($sourceMapped['file'], $sourceMapped['line'], php: false) ?>
+ = BlueScreen::highlightFile($sourceMapped['file'], line: $sourceMapped['line'] ?? 0, column: $sourceMapped['column'] ?? 0, php: false) ?>
diff --git a/src/Tracy/BlueScreen/assets/section-stack-sourceFile.phtml b/src/Tracy/BlueScreen/assets/section-stack-sourceFile.phtml
index 492a5269d..bde95a747 100644
--- a/src/Tracy/BlueScreen/assets/section-stack-sourceFile.phtml
+++ b/src/Tracy/BlueScreen/assets/section-stack-sourceFile.phtml
@@ -33,7 +33,7 @@ $sourceMapped = $sourceOriginal ? Debugger::mapSource($file, $line) : null;
File: = Helpers::editorLink($sourceMapped['file'], $sourceMapped['line']) ?>
- = BlueScreen::highlightFile($sourceMapped['file'], $sourceMapped['line'], php: false) ?>
+ = BlueScreen::highlightFile($sourceMapped['file'], line: $sourceMapped['line'] ?? 0, column: $sourceMapped['column'] ?? 0, php: false) ?>
diff --git a/src/Tracy/Debugger/Debugger.php b/src/Tracy/Debugger/Debugger.php
index 23b3c2f26..68e680924 100644
--- a/src/Tracy/Debugger/Debugger.php
+++ b/src/Tracy/Debugger/Debugger.php
@@ -19,7 +19,7 @@
*/
class Debugger
{
- public const Version = '2.11.0';
+ public const Version = '3.0-dev';
/** server modes for Debugger::enable() */
public const
@@ -29,19 +29,19 @@ class Debugger
public const CookieSecret = 'tracy-debug';
- /** @deprecated use Debugger::Version */
+ #[\Deprecated('use Debugger::Version')]
public const VERSION = self::Version;
- /** @deprecated use Debugger::Development */
+ #[\Deprecated('use Debugger::Development')]
public const DEVELOPMENT = self::Development;
- /** @deprecated use Debugger::Production */
+ #[\Deprecated('use Debugger::Production')]
public const PRODUCTION = self::Production;
- /** @deprecated use Debugger::Detect */
+ #[\Deprecated('use Debugger::Detect')]
public const DETECT = self::Detect;
- /** @deprecated use Debugger::CookieSecret */
+ #[\Deprecated('use Debugger::CookieSecret')]
public const COOKIE_SECRET = self::CookieSecret;
/** in production mode is suppressed any debugging output */
@@ -552,6 +552,7 @@ public static function barDump(mixed $var, ?string $title = null, array $options
Dumper::TRUNCATE => self::$maxLength,
Dumper::LOCATION => self::$showLocation ?: Dumper::LOCATION_CLASS | Dumper::LOCATION_SOURCE,
Dumper::LAZY => true,
+ Dumper::KEYS_TO_HIDE => self::$keysToHide,
])];
}
@@ -586,7 +587,7 @@ public static function addSourceMapper(callable $mapper): void
}
- /** @return array{file: string, line: int, label: string, active: bool} */
+ /** @return array{file: string, line: int, column: int, label: string, active: bool} */
public static function mapSource(string $file, int $line): ?array
{
foreach (self::$sourceMappers as $mapper) {
diff --git a/src/Tracy/Debugger/ProductionStrategy.php b/src/Tracy/Debugger/ProductionStrategy.php
index 64fbd02c3..a47db9ed7 100644
--- a/src/Tracy/Debugger/ProductionStrategy.php
+++ b/src/Tracy/Debugger/ProductionStrategy.php
@@ -65,7 +65,7 @@ public function handleError(
$err = 'PHP ' . Helpers::errorTypeToString($severity) . ': ' . Helpers::improveError($message) . " in $file:$line";
}
- Debugger::tryLog($err, Debugger::ERROR);
+ Debugger::tryLog($err, Debugger::WARNING);
}
diff --git a/src/Tracy/Dumper/Exposer.php b/src/Tracy/Dumper/Exposer.php
index 773f54124..02f2745bb 100644
--- a/src/Tracy/Dumper/Exposer.php
+++ b/src/Tracy/Dumper/Exposer.php
@@ -21,6 +21,11 @@ final class Exposer
{
public static function exposeObject(object $obj, Value $value, Describer $describer): void
{
+ if (PHP_VERSION_ID >= 80400 && (new \ReflectionClass($obj))->isUninitializedLazyObject($obj)) {
+ self::exposeLazyObject($obj, $describer, $value);
+ return;
+ }
+
$values = get_mangled_object_vars($obj);
$props = self::getProperties($obj::class);
@@ -276,4 +281,23 @@ public static function exposeDsMap(
$describer->addPropertyTo($value, (string) $i++, new Ds\Pair($k, $v));
}
}
+
+
+ private static function exposeLazyObject(object $obj, Describer $describer, Value $value): void
+ {
+ $rc = new \ReflectionClass($obj);
+ foreach ($rc->getProperties(\ReflectionProperty::IS_PUBLIC) as $prop) {
+ if (!$prop->isLazy($obj)) {
+ $describer->addPropertyTo(
+ $value,
+ $prop->getName(),
+ $prop->getValue($obj),
+ Value::PropertyPublic,
+ described: $describer->describeEnumProperty($obj::class, $prop->getName(), $prop->getValue($obj)),
+ );
+ }
+ }
+
+ $value->value .= ' (lazy)';
+ }
}
diff --git a/src/Tracy/Helpers.php b/src/Tracy/Helpers.php
index 8264fb6f1..0452926df 100644
--- a/src/Tracy/Helpers.php
+++ b/src/Tracy/Helpers.php
@@ -57,6 +57,7 @@ public static function editorUri(
string $action = 'open',
string $search = '',
string $replace = '',
+ ?int $column = null,
): ?string
{
if (Debugger::$editor && $file && ($action === 'create' || @is_file($file))) { // @ - may trigger error
@@ -67,7 +68,7 @@ public static function editorUri(
return strtr(Debugger::$editor, [
'%action' => $action,
'%file' => rawurlencode($file),
- '%line' => $line ?: 1,
+ '%line' => ($line ?: 1) . ($column ? ':' . $column : ''),
'%search' => rawurlencode($search),
'%replace' => rawurlencode($replace),
]);
diff --git a/src/Tracy/Logger/Logger.php b/src/Tracy/Logger/Logger.php
index 43fd3d201..8b9b14a17 100644
--- a/src/Tracy/Logger/Logger.php
+++ b/src/Tracy/Logger/Logger.php
@@ -18,23 +18,22 @@
*/
class Logger implements ILogger
{
- /** @var string|null name of the directory where errors should be logged */
- public $directory;
+ /** name of the directory where errors should be logged */
+ public ?string $directory = null;
- /** @var string|array|null email or emails to which send error notifications */
- public $email;
+ /** email or emails to which send error notifications */
+ public string|array|null $email = null;
- /** @var string|null sender of email notifications */
- public $fromEmail;
+ /** sender of email notifications */
+ public ?string $fromEmail = null;
- /** @var mixed interval for sending email is 2 days */
- public $emailSnooze = '2 days';
+ /** interval for sending email is 2 days */
+ public mixed $emailSnooze = '2 days';
/** @var callable handler for sending emails */
public $mailer;
- /** @var BlueScreen|null */
- private $blueScreen;
+ private ?BlueScreen $blueScreen = null;
public function __construct(?string $directory, string|array|null $email = null, ?BlueScreen $blueScreen = null)
@@ -81,10 +80,7 @@ public function log(mixed $message, string $level = self::INFO)
}
- /**
- * @param mixed $message
- */
- public static function formatMessage($message): string
+ public static function formatMessage(mixed $message): string
{
if ($message instanceof \Throwable) {
foreach (Helpers::getExceptionChain($message) as $exception) {
@@ -104,10 +100,7 @@ public static function formatMessage($message): string
}
- /**
- * @param mixed $message
- */
- public static function formatLogLine($message, ?string $exceptionFile = null): string
+ public static function formatLogLine(mixed $message, ?string $exceptionFile = null): string
{
return implode(' ', [
date('[Y-m-d H-i-s]'),
@@ -155,10 +148,7 @@ protected function logException(\Throwable $exception, ?string $file = null): st
}
- /**
- * @param mixed $message
- */
- protected function sendEmail($message): void
+ protected function sendEmail(mixed $message): void
{
$snooze = is_numeric($this->emailSnooze)
? $this->emailSnooze
@@ -177,10 +167,9 @@ protected function sendEmail($message): void
/**
* Default mailer.
- * @param mixed $message
* @internal
*/
- public function defaultMailer($message, string $email): void
+ public function defaultMailer(mixed $message, string $email): void
{
$host = preg_replace('#[^\w.-]+#', '', $_SERVER['SERVER_NAME'] ?? php_uname('n'));
mail(
diff --git a/tests/Tracy/Dumper.debugInfo.phpt b/tests/Dumper/Dumper.debugInfo.phpt
similarity index 100%
rename from tests/Tracy/Dumper.debugInfo.phpt
rename to tests/Dumper/Dumper.debugInfo.phpt
diff --git a/tests/Tracy/Dumper.dump().cli.phpt b/tests/Dumper/Dumper.dump().cli.phpt
similarity index 100%
rename from tests/Tracy/Dumper.dump().cli.phpt
rename to tests/Dumper/Dumper.dump().cli.phpt
diff --git a/tests/Tracy/Dumper.dump().html.phpt b/tests/Dumper/Dumper.dump().html.phpt
similarity index 100%
rename from tests/Tracy/Dumper.dump().html.phpt
rename to tests/Dumper/Dumper.dump().html.phpt
diff --git a/tests/Tracy/Dumper.dump().text.phpt b/tests/Dumper/Dumper.dump().text.phpt
similarity index 100%
rename from tests/Tracy/Dumper.dump().text.phpt
rename to tests/Dumper/Dumper.dump().text.phpt
diff --git a/tests/Tracy/Dumper.exposeObject.phpt b/tests/Dumper/Dumper.exposeObject.phpt
similarity index 100%
rename from tests/Tracy/Dumper.exposeObject.phpt
rename to tests/Dumper/Dumper.exposeObject.phpt
diff --git a/tests/Tracy/Dumper.keys.phpt b/tests/Dumper/Dumper.keys.phpt
similarity index 100%
rename from tests/Tracy/Dumper.keys.phpt
rename to tests/Dumper/Dumper.keys.phpt
diff --git a/tests/Tracy/Dumper.keysToHide.phpt b/tests/Dumper/Dumper.keysToHide.phpt
similarity index 100%
rename from tests/Tracy/Dumper.keysToHide.phpt
rename to tests/Dumper/Dumper.keysToHide.phpt
diff --git a/tests/Tracy/Dumper.nesting-error.phpt b/tests/Dumper/Dumper.nesting-error.phpt
similarity index 100%
rename from tests/Tracy/Dumper.nesting-error.phpt
rename to tests/Dumper/Dumper.nesting-error.phpt
diff --git a/tests/Tracy/Dumper.objectExporters.phpt b/tests/Dumper/Dumper.objectExporters.phpt
similarity index 100%
rename from tests/Tracy/Dumper.objectExporters.phpt
rename to tests/Dumper/Dumper.objectExporters.phpt
diff --git a/tests/Tracy/Dumper.references74.phpt b/tests/Dumper/Dumper.references74.phpt
similarity index 100%
rename from tests/Tracy/Dumper.references74.phpt
rename to tests/Dumper/Dumper.references74.phpt
diff --git a/tests/Tracy/Dumper.scrubber.phpt b/tests/Dumper/Dumper.scrubber.phpt
similarity index 100%
rename from tests/Tracy/Dumper.scrubber.phpt
rename to tests/Dumper/Dumper.scrubber.phpt
diff --git a/tests/Tracy/Dumper.sensitiveValue.phpt b/tests/Dumper/Dumper.sensitiveValue.phpt
similarity index 100%
rename from tests/Tracy/Dumper.sensitiveValue.phpt
rename to tests/Dumper/Dumper.sensitiveValue.phpt
diff --git a/tests/Tracy/Dumper.toHtml().collapse.phpt b/tests/Dumper/Dumper.toHtml().collapse.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toHtml().collapse.phpt
rename to tests/Dumper/Dumper.toHtml().collapse.phpt
diff --git a/tests/Tracy/Dumper.toHtml().depth.phpt b/tests/Dumper/Dumper.toHtml().depth.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toHtml().depth.phpt
rename to tests/Dumper/Dumper.toHtml().depth.phpt
diff --git a/tests/Tracy/Dumper.toHtml().key.phpt b/tests/Dumper/Dumper.toHtml().key.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toHtml().key.phpt
rename to tests/Dumper/Dumper.toHtml().key.phpt
diff --git a/tests/Tracy/Dumper.toHtml().lazy.auto.phpt b/tests/Dumper/Dumper.toHtml().lazy.auto.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toHtml().lazy.auto.phpt
rename to tests/Dumper/Dumper.toHtml().lazy.auto.phpt
diff --git a/tests/Tracy/Dumper.toHtml().lazy.no.phpt b/tests/Dumper/Dumper.toHtml().lazy.no.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toHtml().lazy.no.phpt
rename to tests/Dumper/Dumper.toHtml().lazy.no.phpt
diff --git a/tests/Tracy/Dumper.toHtml().lazy.phpt b/tests/Dumper/Dumper.toHtml().lazy.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toHtml().lazy.phpt
rename to tests/Dumper/Dumper.toHtml().lazy.phpt
diff --git a/tests/Tracy/Dumper.toHtml().live.phpt b/tests/Dumper/Dumper.toHtml().live.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toHtml().live.phpt
rename to tests/Dumper/Dumper.toHtml().live.phpt
diff --git a/tests/Tracy/Dumper.toHtml().locale.phpt b/tests/Dumper/Dumper.toHtml().locale.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toHtml().locale.phpt
rename to tests/Dumper/Dumper.toHtml().locale.phpt
diff --git a/tests/Tracy/Dumper.toHtml().location.phpt b/tests/Dumper/Dumper.toHtml().location.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toHtml().location.phpt
rename to tests/Dumper/Dumper.toHtml().location.phpt
diff --git a/tests/Tracy/Dumper.toHtml().phpt b/tests/Dumper/Dumper.toHtml().phpt
similarity index 100%
rename from tests/Tracy/Dumper.toHtml().phpt
rename to tests/Dumper/Dumper.toHtml().phpt
diff --git a/tests/Tracy/Dumper.toHtml().recursion.phpt b/tests/Dumper/Dumper.toHtml().recursion.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toHtml().recursion.phpt
rename to tests/Dumper/Dumper.toHtml().recursion.phpt
diff --git a/tests/Tracy/Dumper.toHtml().references.phpt b/tests/Dumper/Dumper.toHtml().references.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toHtml().references.phpt
rename to tests/Dumper/Dumper.toHtml().references.phpt
diff --git a/tests/Tracy/Dumper.toHtml().see.phpt b/tests/Dumper/Dumper.toHtml().see.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toHtml().see.phpt
rename to tests/Dumper/Dumper.toHtml().see.phpt
diff --git a/tests/Tracy/Dumper.toHtml().snapshot.phpt b/tests/Dumper/Dumper.toHtml().snapshot.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toHtml().snapshot.phpt
rename to tests/Dumper/Dumper.toHtml().snapshot.phpt
diff --git a/tests/Tracy/Dumper.toHtml().specialChars.phpt b/tests/Dumper/Dumper.toHtml().specialChars.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toHtml().specialChars.phpt
rename to tests/Dumper/Dumper.toHtml().specialChars.phpt
diff --git a/tests/Dumper/Dumper.toHtml().specials.lazyObject.phpt b/tests/Dumper/Dumper.toHtml().specials.lazyObject.phpt
new file mode 100644
index 000000000..02dd62578
--- /dev/null
+++ b/tests/Dumper/Dumper.toHtml().specials.lazyObject.phpt
@@ -0,0 +1,56 @@
+newLazyGhost(function () {});
+
+// new ghost
+Assert::match(
+ <<<'XX'
+ LazyClass (lazy) #%d%
+ XX,
+ Dumper::toHtml($ghost, [Dumper::DEPTH => 3]),
+);
+
+// preinitialized property
+$rc->getProperty('id')->setRawValueWithoutLazyInitialization($ghost, 123);
+
+Assert::match(
+ <<<'XX'
+ LazyClass (lazy) #%d%
+ id: 123
+
+ XX,
+ Dumper::toHtml($ghost, [Dumper::DEPTH => 3]),
+);
+
+// proxy
+$proxy = $rc->newLazyProxy(function () { return new LazyClass; });
+Assert::match(
+ <<<'XX'
+ LazyClass (lazy) #%d%
+ XX,
+ Dumper::toHtml($proxy, [Dumper::DEPTH => 3]),
+);
diff --git a/tests/Tracy/Dumper.toHtml().specials.phpt b/tests/Dumper/Dumper.toHtml().specials.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toHtml().specials.phpt
rename to tests/Dumper/Dumper.toHtml().specials.phpt
diff --git a/tests/Tracy/Dumper.toTerminal().phpt b/tests/Dumper/Dumper.toTerminal().phpt
similarity index 100%
rename from tests/Tracy/Dumper.toTerminal().phpt
rename to tests/Dumper/Dumper.toTerminal().phpt
diff --git a/tests/Tracy/Dumper.toText().depth.phpt b/tests/Dumper/Dumper.toText().depth.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toText().depth.phpt
rename to tests/Dumper/Dumper.toText().depth.phpt
diff --git a/tests/Tracy/Dumper.toText().enumProperty.PhpToken.phpt b/tests/Dumper/Dumper.toText().enumProperty.PhpToken.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toText().enumProperty.PhpToken.phpt
rename to tests/Dumper/Dumper.toText().enumProperty.PhpToken.phpt
diff --git a/tests/Tracy/Dumper.toText().enumProperty.phpt b/tests/Dumper/Dumper.toText().enumProperty.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toText().enumProperty.phpt
rename to tests/Dumper/Dumper.toText().enumProperty.phpt
diff --git a/tests/Tracy/Dumper.toText().locale.phpt b/tests/Dumper/Dumper.toText().locale.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toText().locale.phpt
rename to tests/Dumper/Dumper.toText().locale.phpt
diff --git a/tests/Tracy/Dumper.toText().location.phpt b/tests/Dumper/Dumper.toText().location.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toText().location.phpt
rename to tests/Dumper/Dumper.toText().location.phpt
diff --git a/tests/Tracy/Dumper.toText().nohash.phpt b/tests/Dumper/Dumper.toText().nohash.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toText().nohash.phpt
rename to tests/Dumper/Dumper.toText().nohash.phpt
diff --git a/tests/Tracy/Dumper.toText().phpt b/tests/Dumper/Dumper.toText().phpt
similarity index 100%
rename from tests/Tracy/Dumper.toText().phpt
rename to tests/Dumper/Dumper.toText().phpt
diff --git a/tests/Tracy/Dumper.toText().recursion.phpt b/tests/Dumper/Dumper.toText().recursion.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toText().recursion.phpt
rename to tests/Dumper/Dumper.toText().recursion.phpt
diff --git a/tests/Tracy/Dumper.toText().references.phpt b/tests/Dumper/Dumper.toText().references.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toText().references.phpt
rename to tests/Dumper/Dumper.toText().references.phpt
diff --git a/tests/Tracy/Dumper.toText().see.phpt b/tests/Dumper/Dumper.toText().see.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toText().see.phpt
rename to tests/Dumper/Dumper.toText().see.phpt
diff --git a/tests/Tracy/Dumper.toText().specialChars.phpt b/tests/Dumper/Dumper.toText().specialChars.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toText().specialChars.phpt
rename to tests/Dumper/Dumper.toText().specialChars.phpt
diff --git a/tests/Tracy/Dumper.toText().specials.dom.php84.phpt b/tests/Dumper/Dumper.toText().specials.dom.php84.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toText().specials.dom.php84.phpt
rename to tests/Dumper/Dumper.toText().specials.dom.php84.phpt
diff --git a/tests/Tracy/Dumper.toText().specials.dom.phpt b/tests/Dumper/Dumper.toText().specials.dom.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toText().specials.dom.phpt
rename to tests/Dumper/Dumper.toText().specials.dom.phpt
diff --git a/tests/Tracy/Dumper.toText().specials.ds.phpt b/tests/Dumper/Dumper.toText().specials.ds.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toText().specials.ds.phpt
rename to tests/Dumper/Dumper.toText().specials.ds.phpt
diff --git a/tests/Tracy/Dumper.toText().specials.enum.phpt b/tests/Dumper/Dumper.toText().specials.enum.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toText().specials.enum.phpt
rename to tests/Dumper/Dumper.toText().specials.enum.phpt
diff --git a/tests/Tracy/Dumper.toText().specials.fiber.phpt b/tests/Dumper/Dumper.toText().specials.fiber.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toText().specials.fiber.phpt
rename to tests/Dumper/Dumper.toText().specials.fiber.phpt
diff --git a/tests/Tracy/Dumper.toText().specials.generator.phpt b/tests/Dumper/Dumper.toText().specials.generator.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toText().specials.generator.phpt
rename to tests/Dumper/Dumper.toText().specials.generator.phpt
diff --git a/tests/Dumper/Dumper.toText().specials.lazyObject.phpt b/tests/Dumper/Dumper.toText().specials.lazyObject.phpt
new file mode 100644
index 000000000..db52dfab8
--- /dev/null
+++ b/tests/Dumper/Dumper.toText().specials.lazyObject.phpt
@@ -0,0 +1,54 @@
+newLazyGhost(function () {});
+
+// new ghost
+Assert::match(
+ <<<'XX'
+ LazyClass (lazy) #%d%
+ XX,
+ Dumper::toText($ghost, [Dumper::DEPTH => 3]),
+);
+
+// preinitialized property
+$rc->getProperty('id')->setRawValueWithoutLazyInitialization($ghost, 123);
+
+Assert::match(
+ <<<'XX'
+ LazyClass (lazy) #%d%
+ id: 123
+ XX,
+ Dumper::toText($ghost, [Dumper::DEPTH => 3]),
+);
+
+// proxy
+$proxy = $rc->newLazyProxy(function () { return new LazyClass; });
+Assert::match(
+ <<<'XX'
+ LazyClass (lazy) #%d%
+ XX,
+ Dumper::toText($proxy, [Dumper::DEPTH => 3]),
+);
diff --git a/tests/Tracy/Dumper.toText().specials.phpt b/tests/Dumper/Dumper.toText().specials.phpt
similarity index 100%
rename from tests/Tracy/Dumper.toText().specials.phpt
rename to tests/Dumper/Dumper.toText().specials.phpt
diff --git a/tests/Tracy/dump().cli.phpt b/tests/Dumper/dump().cli.phpt
similarity index 100%
rename from tests/Tracy/dump().cli.phpt
rename to tests/Dumper/dump().cli.phpt
diff --git a/tests/Tracy/dump().html.phpt b/tests/Dumper/dump().html.phpt
similarity index 100%
rename from tests/Tracy/dump().html.phpt
rename to tests/Dumper/dump().html.phpt
diff --git a/tests/Tracy/dump().text.phpt b/tests/Dumper/dump().text.phpt
similarity index 100%
rename from tests/Tracy/dump().text.phpt
rename to tests/Dumper/dump().text.phpt
diff --git a/tests/Tracy/fixtures/DumpClass.php b/tests/Dumper/fixtures/DumpClass.php
similarity index 100%
rename from tests/Tracy/fixtures/DumpClass.php
rename to tests/Dumper/fixtures/DumpClass.php
diff --git a/tools/open-in-editor/linux/open-editor.sh b/tools/open-in-editor/linux/open-editor.sh
index 69e37be83..8cabf2789 100755
--- a/tools/open-in-editor/linux/open-editor.sh
+++ b/tools/open-in-editor/linux/open-editor.sh
@@ -6,7 +6,7 @@ declare -A mapping
#
# Visual Studio Code
-#editor='code --goto "$FILE":"$LINE"'
+#editor='code --goto "$FILE":"$LINE":"$COLUMN"'
# Emacs
#editor='emacs +$LINE "$FILE"'
# gVim
@@ -17,11 +17,9 @@ declare -A mapping
#editor='pluma +$LINE "$FILE"'
# PHPStorm
# To enable PHPStorm command-line interface, folow this guide: https://www.jetbrains.com/help/phpstorm/working-with-the-ide-features-from-command-line.html
-#editor='phpstorm --line $LINE "$FILE"'
+#editor='phpstorm --line $LINE --column $COLUMN "$FILE"'
# VS Codium
#editor='codium --goto "$FILE":"$LINE"'
-# Visual Studio Code
-#editor='code --goto "$FILE":"$LINE"'
#
# Optionally configure custom mapping here:
@@ -56,16 +54,21 @@ action=`echo $url | sed -r "s/$regex/\1/i"`
uri_params=`echo $url | sed -r "s/$regex/\2/i"`
file=`get_param $uri_params "file"`
-line=`get_param $uri_params "line"`
+line_param=`get_param $uri_params "line"`
search=`get_param $uri_params "search"`
replace=`get_param $uri_params "replace"`
+# Parse line and column from line parameter (format: "12:5" or just "12")
+IFS=':' read -r line column <<< "$line_param"
+column="${column:-1}"
+
# Debug?
#echo "action '$action'"
#echo "file '$file'"
#echo "line '$line'"
#echo "search '$search'"
#echo "replace '$replace'"
+#echo "column '$column'"
# Convert URI encoded codes to normal characters (e.g. '%2F' => '/').
printf -v file "${file//%/\\x}"
@@ -102,6 +105,7 @@ fi
# Format the command according to the selected editor.
command="${editor//\$FILE/$file}"
command="${command//\$LINE/$line}"
+command="${command//\$COLUMN/$column}"
# Debug?
#echo $command
diff --git a/tools/open-in-editor/windows/open-editor.js b/tools/open-in-editor/windows/open-editor.js
index ac1093e70..86f699483 100644
--- a/tools/open-in-editor/windows/open-editor.js
+++ b/tools/open-in-editor/windows/open-editor.js
@@ -1,7 +1,7 @@
var settings = {
// PhpStorm
- // editor: '"C:\\Program Files\\JetBrains\\PhpStorm 2018.1.2\\bin\\phpstorm64.exe" --line %line% "%file%"',
+ // editor: '"C:\\Program Files\\JetBrains\\PhpStorm 2018.1.2\\bin\\phpstorm64.exe" --line %line% --column %column% "%file%"',
// title: 'PhpStorm',
// NetBeans
@@ -14,7 +14,7 @@ var settings = {
// editor: '"C:\\Program Files\\SciTE\\scite.exe" "-open:%file%" -goto:%line%',
// EmEditor
- // editor: '"C:\\Program Files\\EmEditor\\EmEditor.exe" "%file%" /l %line%',
+ // editor: '"C:\\Program Files\\EmEditor\\EmEditor.exe" "%file%" /l %line% /cl %column%',
// PSPad Editor
// editor: '"C:\\Program Files\\PSPad editor\\PSPad.exe" -%line% "%file%"',
@@ -26,7 +26,7 @@ var settings = {
// editor: '"C:\\Program Files\\Sublime Text 2\\sublime_text.exe" "%file%:%line%"',
// Visual Studio Code / VSCodium
- // editor: '"C:\\Program Files\\Microsoft VS Code\\Code.exe" --goto "%file%:%line%"',
+ // editor: '"C:\\Program Files\\Microsoft VS Code\\Code.exe" --goto "%file%:%line%:%column%"',
mappings: {
// '/remotepath': '/localpath'
@@ -41,7 +41,7 @@ if (!settings.editor) {
}
var url = WScript.Arguments(0);
-var match = /^editor:\/\/(open|create|fix)\/?\?file=([^&]+)&line=(\d+)(?:&search=([^&]*)&replace=([^&]*))?/.exec(url);
+var match = /^editor:\/\/(open|create|fix)\/?\?file=([^&]+)&line=(\d+)(?::(\d+))?(?:&search=([^&]*)&replace=([^&]*))?/.exec(url);
if (!match) {
WScript.Echo('Unexpected URI ' + url);
WScript.Quit();
@@ -53,8 +53,9 @@ for (var i in match) {
var action = match[1];
var file = match[2];
var line = match[3];
-var search = match[4];
-var replace = match[5];
+var column = match[4] || 1;
+var search = match[5];
+var replace = match[6];
var shell = new ActiveXObject('WScript.Shell');
var fileSystem = new ActiveXObject('Scripting.FileSystemObject');
@@ -76,7 +77,7 @@ if (action === 'create' && !fileSystem.FileExists(file)) {
fileSystem.OpenTextFile(file, 2).Write(lines.join('\n'));
}
-var command = settings.editor.replace(/%line%/, line).replace(/%file%/, file);
+var command = settings.editor.replace(/%line%/, line).replace(/%column%/, column).replace(/%file%/, file);
shell.Exec(command);
if (settings.title) {