Skip to content

Commit

Permalink
Merge pull request #16 from phug-php/profiler
Browse files Browse the repository at this point in the history
Profiler
  • Loading branch information
kylekatarnls authored Aug 8, 2017
2 parents 45fcb73 + 4311a32 commit aab11a7
Show file tree
Hide file tree
Showing 31 changed files with 1,605 additions and 117 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ install:
- travis_retry composer install

script:
- vendor/bin/phug-dev check --report --ignore-tests --ignore-debug
- vendor/bin/phpunit -c vendor/phug/dev-tool/config --debug

notifications:
slack: phug:nzXFnxhU14RWK2EQSDL0u08z
Expand Down
51 changes: 27 additions & 24 deletions src/Phug/Renderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
use Phug\Renderer\Event\HtmlEvent;
use Phug\Renderer\Event\RenderEvent;
use Phug\Renderer\Partial\Debug\DebuggerTrait;
use Phug\Renderer\Profiler\ProfilerModule;
use Phug\Util\ModuleContainerInterface;
use Phug\Util\Partial\ModuleContainerTrait;
use Phug\Util\SandBox;
Expand Down Expand Up @@ -79,6 +78,8 @@ public function __construct($options = null)

$this->compiler = new $compilerClassName($options);

$this->initDebugOptions($this);

$adapterClassName = $this->getOption('adapter_class_name');

if (!is_a($adapterClassName, AdapterInterface::class, true)) {
Expand All @@ -89,9 +90,6 @@ public function __construct($options = null)
}
$this->adapter = new $adapterClassName($this, $options);

if ($this->getOption('enable_profiler')) {
$this->addModule(ProfilerModule::class);
}
$this->addModules($this->getOption('modules'));
foreach ($this->getStaticModules() as $moduleClassName) {
$interfaces = class_implements($moduleClassName);
Expand All @@ -100,31 +98,31 @@ public function __construct($options = null)
) {
$this->compiler->addModule($moduleClassName);
$this->setOptionsRecursive([
'compiler_options' => $moduleClassName,
'compiler_modules' => [$moduleClassName],
]);
}
if (in_array(FormatterModuleInterface::class, $interfaces) &&
!$this->compiler->getFormatter()->hasModule($moduleClassName)
) {
$this->compiler->getFormatter()->addModule($moduleClassName);
$this->setOptionsRecursive([
'formatter_options' => $moduleClassName,
'formatter_modules' => [$moduleClassName],
]);
}
if (in_array(ParserModuleInterface::class, $interfaces) &&
!$this->compiler->getParser()->hasModule($moduleClassName)
) {
$this->compiler->getParser()->addModule($moduleClassName);
$this->setOptionsRecursive([
'parser_options' => $moduleClassName,
'parser_modules' => [$moduleClassName],
]);
}
if (in_array(LexerModuleInterface::class, $interfaces) &&
!$this->compiler->getParser()->getLexer()->hasModule($moduleClassName)
) {
$this->compiler->getParser()->getLexer()->addModule($moduleClassName);
$this->setOptionsRecursive([
'lexer_options' => $moduleClassName,
'lexer_modules' => [$moduleClassName],
]);
}
}
Expand All @@ -145,6 +143,11 @@ private function handleOptionAliases()
}
}

private function mergeWithSharedVariables(array $parameters)
{
return array_merge($this->getOption('shared_variables'), $parameters);
}

/**
* @return AdapterInterface
*/
Expand All @@ -161,11 +164,6 @@ public function getCompiler()
return $this->compiler;
}

private function mergeWithSharedVariables(array $parameters)
{
return array_merge($this->getOption('shared_variables'), $parameters);
}

/**
* @param array|string $variables
* @param mixed $value
Expand Down Expand Up @@ -218,12 +216,12 @@ public function callAdapter($method, $path, $input, callable $getSource, array $
{
$source = '';

$event = new RenderEvent($input, $path, $method, $parameters);
$this->trigger($event);
$input = $event->getInput();
$path = $event->getPath();
$method = $event->getMethod();
$parameters = $event->getParameters();
$renderEvent = new RenderEvent($input, $path, $method, $parameters);
$this->trigger($renderEvent);
$input = $renderEvent->getInput();
$path = $renderEvent->getPath();
$method = $renderEvent->getMethod();
$parameters = $renderEvent->getParameters();
if ($self = $this->getOption('self')) {
$self = $self === true ? 'self' : strval($self);
$parameters = [
Expand Down Expand Up @@ -255,10 +253,15 @@ public function callAdapter($method, $path, $input, callable $getSource, array $
);
});

$event = new HtmlEvent($sandBox->getResult(), $sandBox->getBuffer(), $sandBox->getThrowable());
$this->trigger($event);
$htmlEvent = new HtmlEvent(
$renderEvent,
$sandBox->getResult(),
$sandBox->getBuffer(),
$sandBox->getThrowable()
);
$this->trigger($htmlEvent);

if ($error = $event->getError()) {
if ($error = $htmlEvent->getError()) {
$this->handleError($error, 1, $path, $source, $parameters, [
'debug' => $this->getOption('debug'),
'error_handler' => $this->getOption('error_handler'),
Expand All @@ -268,11 +271,11 @@ public function callAdapter($method, $path, $input, callable $getSource, array $
]);
}

if ($buffer = $event->getBuffer()) {
if ($buffer = $htmlEvent->getBuffer()) {
echo $buffer;
}

return $event->getResult();
return $htmlEvent->getResult();
}

/**
Expand Down
19 changes: 15 additions & 4 deletions src/Phug/Renderer/Event/HtmlEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,37 @@

class HtmlEvent extends Event
{
private $renderEvent;
private $result;
private $buffer;
private $error;

/**
* CompileEvent constructor.
*
* @param mixed $result
* @param string $buffer
* @param \Throwable $error
* @param RenderEvent $renderEvent
* @param mixed $result
* @param string $buffer
* @param \Throwable $error
*/
public function __construct($result, $buffer, $error)
public function __construct(RenderEvent $renderEvent, $result, $buffer, $error)
{
parent::__construct(RendererEvent::HTML);

$this->renderEvent = $renderEvent;
$this->result = $result;
$this->buffer = $buffer;
$this->error = $error;
}

/**
* @return RenderEvent
*/
public function getRenderEvent()
{
return $this->renderEvent;
}

/**
* @return string
*/
Expand Down
40 changes: 40 additions & 0 deletions src/Phug/Renderer/Partial/Debug/DebuggerTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

use Phug\Formatter;
use Phug\Renderer;
use Phug\Renderer\Profiler\EventList;
use Phug\Renderer\Profiler\ProfilerModule;
use Phug\RendererException;
use Phug\Util\Exception\LocatedException;
use Phug\Util\SandBox;
Expand Down Expand Up @@ -238,6 +240,44 @@ protected function setDebugFormatter(Formatter $debugFormatter)
$this->debugFormatter = $debugFormatter;
}

protected function initDebugOptions(Renderer $profilerContainer)
{
$profilerContainer->setOptionsDefaults([
'memory_limit' => $profilerContainer->getOption('debug') ? -1 : 0x3200000, // 50MB by default in debug
'execution_max_time' => $profilerContainer->getOption('debug') ? -1 : 30000, // 30s by default in debug
]);

if (!$profilerContainer->getOption('enable_profiler') && $profilerContainer->getOption('execution_max_time') > -1) {
$profilerContainer->setOptionsRecursive([
'enable_profiler' => true,
'profiler' => [
'display' => false,
'log' => false,
],
]);
}
if ($profilerContainer->getOption('enable_profiler')) {
$profilerContainer->setOptionsDefaults([
'profiler' => [
'time_precision' => 3,
'line_height' => 30,
'display' => true,
'log' => false,
],
]);
$events = new EventList();
$profilerContainer->addModule(new ProfilerModule($events, $profilerContainer));
$compiler = $profilerContainer->getCompiler();
$compiler->addModule(new ProfilerModule($events, $compiler));
$formatter = $compiler->getFormatter();
$formatter->addModule(new ProfilerModule($events, $formatter));
$parser = $compiler->getParser();
$parser->addModule(new ProfilerModule($events, $parser));
$lexer = $parser->getLexer();
$lexer->addModule(new ProfilerModule($events, $lexer));
}
}

/**
* @return Formatter
*/
Expand Down
125 changes: 125 additions & 0 deletions src/Phug/Renderer/Profiler/Dump.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<?php

namespace Phug\Renderer\Profiler;

use Phug\Event;
use Phug\Util\ModuleContainerInterface;
use ReflectionMethod;
use Traversable;

class Dump
{
private $object;

public function __construct($object)
{
$this->object = $object;
}

private function dumpArray($object, $deep, $maxDeep = 3)
{
$result = ($object instanceof Traversable
? get_class($object)
: 'array'
).' ';
$count = 0;
$content = '';
foreach ($object as $key => $value) {
if (++$count <= 16) {
$content .= "\n".str_repeat(' ', ($deep + 1) * 2);
$content .= $count === 16
? '...'
: var_export($key, true).' => '.
$this->dumpValue($value, $deep + 1, $maxDeep);
}
}
$result .= $count
? "($count) [$content\n".str_repeat(' ', $deep * 2).']'
: '[]';

return $result;
}

private function getExposedProperties($object, $deep)
{
$result = "\n";
foreach (get_class_methods($object) as $method) {
if (mb_strlen($result) > 0x80000) {
$result .= str_repeat(' ', ($deep + 1) * 2).'...';
break;
}
if (preg_match('/^get[A-Z]/', $method)) {
if ($method === 'getOptions') {
continue;
}
$reflexion = new ReflectionMethod($object, $method);
if ($reflexion->getNumberOfRequiredParameters() > 0) {
continue;
}
$value = call_user_func([$object, $method]);
if ($value instanceof ModuleContainerInterface) {
continue;
}

$result .= str_repeat(' ', ($deep + 1) * 2).
mb_substr($method, 3).' => '.
($value instanceof Event
? $value->getName().' event'
: $this->dumpValue($value, $deep + 1)
).
"\n";
}
}

return $result.str_repeat(' ', $deep * 2);
}

private function dumpObject($object, $deep, $maxDeep = 3)
{
$result = get_class($object).' {'.(
$deep <= $maxDeep
? $this->getExposedProperties($object, $deep)
: '...'
).'}';

if (mb_strlen($result) > 0x80000) {
$result = mb_substr($result, 0, 0x80000 - 3).'...';
}

return $result;
}

private function dumpValue($object, $deep, $maxDeep = 3)
{
$type = gettype($object);

if (in_array($type, [
'boolean',
'integer',
'double',
'string',
'resource',
'NULL',
])) {
return var_export($object, true);
}

if ($type === 'array' || $object instanceof Traversable) {
return $this->dumpArray($object, $deep, $maxDeep);
}

return $this->dumpObject($object, $deep, $maxDeep);
}

/**
* Return a simplified dump of an object/value.
*
* @param mixed $object
*
* @return string
*/
public function dump()
{
return $this->dumpValue($this->object, 0);
}
}
Loading

0 comments on commit aab11a7

Please sign in to comment.