Inline isCallable and isTruthy into compiled templates
~3-5% performance gain.
This commit is contained in:
@@ -140,14 +140,14 @@ class Compiler {
|
|||||||
|
|
||||||
const SECTION = '
|
const SECTION = '
|
||||||
private function section%s(\Mustache\Buffer $buffer, \Mustache\Context $context, $value) {
|
private function section%s(\Mustache\Buffer $buffer, \Mustache\Context $context, $value) {
|
||||||
if ($context->isCallable($value)) {
|
if (!is_string($value) && is_callable($value)) {
|
||||||
$source = %s;
|
$source = %s;
|
||||||
$buffer->write(
|
$buffer->write(
|
||||||
$this->mustache
|
$this->mustache
|
||||||
->loadLambda((string) call_user_func($value, $source)%s)
|
->loadLambda((string) call_user_func($value, $source)%s)
|
||||||
->renderInternal($context, $buffer->getIndent())
|
->renderInternal($context, $buffer->getIndent())
|
||||||
);
|
);
|
||||||
} elseif ($context->isTruthy($value)) {
|
} elseif (!empty($value)) {
|
||||||
$values = $context->isIterable($value) ? $value : array($value);
|
$values = $context->isIterable($value) ? $value : array($value);
|
||||||
foreach ($values as $value) {
|
foreach ($values as $value) {
|
||||||
$context->push($value);%s
|
$context->push($value);%s
|
||||||
@@ -191,7 +191,8 @@ class Compiler {
|
|||||||
|
|
||||||
const INVERTED_SECTION = '
|
const INVERTED_SECTION = '
|
||||||
// %s inverted section
|
// %s inverted section
|
||||||
if (!$context->isTruthy($context->%s(%s))) {
|
$value = $context->%s(%s);
|
||||||
|
if (empty($value)) {
|
||||||
%s
|
%s
|
||||||
}';
|
}';
|
||||||
|
|
||||||
@@ -232,7 +233,7 @@ class Compiler {
|
|||||||
|
|
||||||
const VARIABLE = '
|
const VARIABLE = '
|
||||||
$value = $context->%s(%s);
|
$value = $context->%s(%s);
|
||||||
if ($context->isCallable($value)) {
|
if (!is_string($value) && is_callable($value)) {
|
||||||
$value = $this->mustache
|
$value = $this->mustache
|
||||||
->loadLambda((string) call_user_func($value))
|
->loadLambda((string) call_user_func($value))
|
||||||
->renderInternal($context, $buffer->getIndent());
|
->renderInternal($context, $buffer->getIndent());
|
||||||
|
|||||||
@@ -28,36 +28,6 @@ class Context {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function to test whether a value is 'truthy'.
|
|
||||||
*
|
|
||||||
* @param mixed $value
|
|
||||||
*
|
|
||||||
* @return boolean True if the value is 'truthy'
|
|
||||||
*/
|
|
||||||
public function isTruthy($value) {
|
|
||||||
return !empty($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Higher order sections helper: tests whether a value is a valid callback.
|
|
||||||
*
|
|
||||||
* In Mustache.php, a variable is considered 'callable' if the variable is:
|
|
||||||
*
|
|
||||||
* 1. An anonymous function.
|
|
||||||
* 2. An object and the name of a public function, e.g. `array($someObject, 'methodName')`
|
|
||||||
* 3. A class name and the name of a public static function, e.g. `array('SomeClass', 'methodName')`
|
|
||||||
*
|
|
||||||
* Note that this specifically excludes strings, which PHP would normally consider 'callable'.
|
|
||||||
*
|
|
||||||
* @param mixed $value
|
|
||||||
*
|
|
||||||
* @return boolean True if the value is 'callable'
|
|
||||||
*/
|
|
||||||
public function isCallable($value) {
|
|
||||||
return !is_string($value) && is_callable($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests whether a value should be iterated over (e.g. in a section context).
|
* Tests whether a value should be iterated over (e.g. in a section context).
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -36,57 +36,6 @@ class ContextTest extends \PHPUnit_Framework_TestCase {
|
|||||||
$this->assertEquals('NAME', $three->find('name'));
|
$this->assertEquals('NAME', $three->find('name'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testIsTruthy() {
|
|
||||||
$context = new Context;
|
|
||||||
|
|
||||||
$this->assertTrue($context->isTruthy('string'));
|
|
||||||
$this->assertTrue($context->isTruthy(new \StdClass));
|
|
||||||
$this->assertTrue($context->isTruthy(1));
|
|
||||||
$this->assertTrue($context->isTruthy(array('a', 'b')));
|
|
||||||
|
|
||||||
$this->assertFalse($context->isTruthy(null));
|
|
||||||
$this->assertFalse($context->isTruthy(''));
|
|
||||||
$this->assertFalse($context->isTruthy(0));
|
|
||||||
$this->assertFalse($context->isTruthy(array()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testIsCallable() {
|
|
||||||
$dummy = new TestDummy;
|
|
||||||
$context = new Context;
|
|
||||||
|
|
||||||
$this->assertTrue($context->isCallable(function() {
|
|
||||||
return null;
|
|
||||||
}));
|
|
||||||
$this->assertTrue($context->isCallable(array('\Mustache\Test\TestDummy', 'foo')));
|
|
||||||
$this->assertTrue($context->isCallable(array($dummy, 'bar')));
|
|
||||||
$this->assertTrue($context->isCallable($dummy));
|
|
||||||
|
|
||||||
$this->assertFalse($context->isCallable('count'));
|
|
||||||
$this->assertFalse($context->isCallable('TestDummy::foo'));
|
|
||||||
$this->assertFalse($context->isCallable(array('\Mustache\Test\TestDummy', 'name')));
|
|
||||||
$this->assertFalse($context->isCallable(array('NotReallyAClass', 'foo')));
|
|
||||||
$this->assertFalse($context->isCallable(array($dummy, 'name')));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dataProvider getIterables
|
|
||||||
*/
|
|
||||||
public function testIsIterable($value, $iterable) {
|
|
||||||
$context = new Context;
|
|
||||||
$this->assertEquals($iterable, $context->isIterable($value));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getIterables() {
|
|
||||||
return array(
|
|
||||||
array(array(0 => 'a', 1 => 'b'), true),
|
|
||||||
array(array(0 => 'a', 2 => 'b'), false),
|
|
||||||
array(array(1 => 'a', 2 => 'b'), false),
|
|
||||||
array(array('a' => 0, 'b' => 1), false),
|
|
||||||
array('some string', false),
|
|
||||||
array(new \ArrayIterator, true),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testPushPopAndLast() {
|
public function testPushPopAndLast() {
|
||||||
$context = new Context;
|
$context = new Context;
|
||||||
$this->assertFalse($context->last());
|
$this->assertFalse($context->last());
|
||||||
|
|||||||
Reference in New Issue
Block a user