Skip to content

Commit

Permalink
make is_array() check once per context change #271
Browse files Browse the repository at this point in the history
  • Loading branch information
Zordius Chen committed Mar 23, 2017
1 parent 8765854 commit 046de72
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 20 deletions.
25 changes: 13 additions & 12 deletions src/Compiler.php
Expand Up @@ -133,6 +133,7 @@ public static function composePHPRender($context, $code) {
'runtime' => '{$context['runtime']}',
);
{$context['renderex']}
{$context['ops']['array_check']}
{$context['ops']['op_start']}'$code'{$context['ops']['op_end']}
};
VAREND
Expand Down Expand Up @@ -236,23 +237,23 @@ protected static function getVariableNameOrSubExpression(&$context, $var) {
* @return array<string> variable names
*
* @expect array('$in', 'this') when input array('flags'=>array('spvar'=>true,'debug'=>0)), array(null)
* @expect array('((is_array($in) && isset($in[\'true\'])) ? $in[\'true\'] : null)', '[true]') when input array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array('true')
* @expect array('((is_array($in) && isset($in[\'false\'])) ? $in[\'false\'] : null)', '[false]') when input array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array('false')
* @expect array('(($inary && isset($in[\'true\'])) ? $in[\'true\'] : null)', '[true]') when input array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array('true')
* @expect array('(($inary && isset($in[\'false\'])) ? $in[\'false\'] : null)', '[false]') when input array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array('false')
* @expect array('true', 'true') when input array('flags'=>array('spvar'=>true,'debug'=>0)), array(-1, 'true')
* @expect array('false', 'false') when input array('flags'=>array('spvar'=>true,'debug'=>0)), array(-1, 'false')
* @expect array('((is_array($in) && isset($in[\'2\'])) ? $in[\'2\'] : null)', '[2]') when input array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array('2')
* @expect array('(($inary && isset($in[\'2\'])) ? $in[\'2\'] : null)', '[2]') when input array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array('2')
* @expect array('2', '2') when input array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0)), array(-1, '2')
* @expect array('((is_array($in) && isset($in[\'@index\'])) ? $in[\'@index\'] : null)', '[@index]') when input array('flags'=>array('spvar'=>false,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array('@index')
* @expect array('(($inary && isset($in[\'@index\'])) ? $in[\'@index\'] : null)', '[@index]') when input array('flags'=>array('spvar'=>false,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array('@index')
* @expect array("(isset(\$cx['sp_vars']['index']) ? \$cx['sp_vars']['index'] : null)", '@[index]') when input array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array('@index')
* @expect array("(isset(\$cx['sp_vars']['key']) ? \$cx['sp_vars']['key'] : null)", '@[key]') when input array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array('@key')
* @expect array("(isset(\$cx['sp_vars']['first']) ? \$cx['sp_vars']['first'] : null)", '@[first]') when input array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array('@first')
* @expect array("(isset(\$cx['sp_vars']['last']) ? \$cx['sp_vars']['last'] : null)", '@[last]') when input array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array('@last')
* @expect array('((is_array($in) && isset($in[\'"a"\'])) ? $in[\'"a"\'] : null)', '["a"]') when input array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array('"a"')
* @expect array('(($inary && isset($in[\'"a"\'])) ? $in[\'"a"\'] : null)', '["a"]') when input array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array('"a"')
* @expect array('"a"', '"a"') when input array('flags'=>array('spvar'=>true,'debug'=>0)), array(-1, '"a"')
* @expect array('((is_array($in) && isset($in[\'a\'])) ? $in[\'a\'] : null)', '[a]') when input array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array('a')
* @expect array('(($inary && isset($in[\'a\'])) ? $in[\'a\'] : null)', '[a]') when input array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array('a')
* @expect array('((isset($cx[\'scopes\'][count($cx[\'scopes\'])-1]) && is_array($cx[\'scopes\'][count($cx[\'scopes\'])-1]) && isset($cx[\'scopes\'][count($cx[\'scopes\'])-1][\'a\'])) ? $cx[\'scopes\'][count($cx[\'scopes\'])-1][\'a\'] : null)', '../[a]') when input array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array(1,'a')
* @expect array('((isset($cx[\'scopes\'][count($cx[\'scopes\'])-3]) && is_array($cx[\'scopes\'][count($cx[\'scopes\'])-3]) && isset($cx[\'scopes\'][count($cx[\'scopes\'])-3][\'a\'])) ? $cx[\'scopes\'][count($cx[\'scopes\'])-3][\'a\'] : null)', '../../../[a]') when input array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array(3,'a')
* @expect array('((is_array($in) && isset($in[\'id\'])) ? $in[\'id\'] : null)', 'this.[id]') when input array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array(null, 'id')
* @expect array('(($inary && isset($in[\'id\'])) ? $in[\'id\'] : null)', 'this.[id]') when input array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array(null, 'id')
* @expect array('LR::v($cx, $in, isset($in) ? $in : null, array(\'id\'))', 'this.[id]') when input array('flags'=>array('prop'=>true,'spvar'=>true,'debug'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0,'standalone'=>0), 'runtime' => 'Runtime', 'runtimealias' => 'LR'), array(null, 'id')
*/
protected static function getVariableName(&$context, $var, $lookup = null, $args = null) {
Expand Down Expand Up @@ -310,7 +311,7 @@ protected static function getVariableName(&$context, $var, $lookup = null, $args
if (($levels === 0) && $p) {
$checks[] = "isset($base$p)";
}
$checks[] = "is_array($base$p)";
$checks[] = ("$base$p" == '$in') ? '$inary' : "is_array($base$p)";
}
$checks[] = "isset($base$n$L)";
$check = ((count($checks) > 1) ? '(' : '') . implode(' && ', $checks) . ((count($checks) > 1) ? ')' : '');
Expand Down Expand Up @@ -443,7 +444,7 @@ protected static function blockCustomHelper(&$context, $vars, $inverted = false)
static::addUsageCount($context, 'helpers', $ch[0]);
$v = static::getVariableNames($context, $vars, $bp);

return $context['ops']['seperator'] . static::getFuncName($context, 'hbbch', ($inverted ? '^' : '#') . implode(' ', $v[1])) . "\$cx, '$ch[0]', {$v[0]}, \$in, $inverted, function(\$cx, \$in) {{$context['ops']['f_start']}";
return $context['ops']['seperator'] . static::getFuncName($context, 'hbbch', ($inverted ? '^' : '#') . implode(' ', $v[1])) . "\$cx, '$ch[0]', {$v[0]}, \$in, $inverted, function(\$cx, \$in) {{$context['ops']['array_check']}{$context['ops']['f_start']}";
}

/**
Expand Down Expand Up @@ -542,7 +543,7 @@ protected static function section(&$context, $vars, $isEach = false) {
$v = static::getVariableNameOrSubExpression($context, $vars[0]);
}
$each = $isEach ? 'true' : 'false';
return $context['ops']['seperator'] . static::getFuncName($context, 'sec', ($isEach ? 'each ' : '') . $v[1] . $be) . "\$cx, {$v[0]}, $bs, \$in, $each, function(\$cx, \$in) {{$context['ops']['f_start']}";
return $context['ops']['seperator'] . static::getFuncName($context, 'sec', ($isEach ? 'each ' : '') . $v[1] . $be) . "\$cx, {$v[0]}, $bs, \$in, $each, function(\$cx, \$in) {{$context['ops']['array_check']}{$context['ops']['f_start']}";
}

/**
Expand All @@ -558,7 +559,7 @@ protected static function with(&$context, $vars) {
$bp = Parser::getBlockParams($vars);
$bs = $bp ? ('array(' . Expression::listString($bp) . ')') : 'null';
$be = $bp ? " as |$bp[0]|" : '';
return $context['ops']['seperator'] . static::getFuncName($context, 'wi', 'with ' . $v[1] . $be) . "\$cx, {$v[0]}, $bs, \$in, function(\$cx, \$in) {{$context['ops']['f_start']}";
return $context['ops']['seperator'] . static::getFuncName($context, 'wi', 'with ' . $v[1] . $be) . "\$cx, {$v[0]}, $bs, \$in, function(\$cx, \$in) {{$context['ops']['array_check']}{$context['ops']['f_start']}";
}

/**
Expand Down Expand Up @@ -612,7 +613,7 @@ protected static function doElse(&$context, $vars) {
return "{$context['ops']['cnd_else']}";
}

return "{$context['ops']['f_end']}}, function(\$cx, \$in) {{$context['ops']['f_start']}";
return "{$context['ops']['f_end']}}, function(\$cx, \$in) {{$context['ops']['array_check']}{$context['ops']['f_start']}";
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/Context.php
Expand Up @@ -169,6 +169,7 @@ public static function create($options) {
);

$context['ops']['enc'] = $context['flags']['hbesc'] ? 'encq' : 'enc';
$context['ops']['array_check'] = '$inary=is_array($in);';
static::updateHelperTable($context, $options);

if ($context['flags']['partnc'] && ($context['flags']['runpart'] == 0)) {
Expand Down
2 changes: 1 addition & 1 deletion src/Partial.php
Expand Up @@ -205,7 +205,7 @@ public static function compile(&$context, $template, $name = 0) {
$sp = '';
}
$code = str_replace(static::$TMP_JS_FUNCTION_STR, 'function', $code);
return "function (\$cx, \$in{$sp}) {{$context['ops']['op_start']}'$code'{$context['ops']['op_end']}}";
return "function (\$cx, \$in{$sp}) {{$context['ops']['array_check']}{$context['ops']['op_start']}'$code'{$context['ops']['op_end']}}";
}
}

14 changes: 7 additions & 7 deletions tests/CompilerTest.php
Expand Up @@ -54,10 +54,10 @@ public function testOn_getVariableName() {
$this->assertEquals(array('$in', 'this'), $method->invokeArgs(null, array_by_ref(array(
array('flags'=>array('spvar'=>true,'debug'=>0)), array(null)
))));
$this->assertEquals(array('((is_array($in) && isset($in[\'true\'])) ? $in[\'true\'] : null)', '[true]'), $method->invokeArgs(null, array_by_ref(array(
$this->assertEquals(array('(($inary && isset($in[\'true\'])) ? $in[\'true\'] : null)', '[true]'), $method->invokeArgs(null, array_by_ref(array(
array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array('true')
))));
$this->assertEquals(array('((is_array($in) && isset($in[\'false\'])) ? $in[\'false\'] : null)', '[false]'), $method->invokeArgs(null, array_by_ref(array(
$this->assertEquals(array('(($inary && isset($in[\'false\'])) ? $in[\'false\'] : null)', '[false]'), $method->invokeArgs(null, array_by_ref(array(
array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array('false')
))));
$this->assertEquals(array('true', 'true'), $method->invokeArgs(null, array_by_ref(array(
Expand All @@ -66,13 +66,13 @@ public function testOn_getVariableName() {
$this->assertEquals(array('false', 'false'), $method->invokeArgs(null, array_by_ref(array(
array('flags'=>array('spvar'=>true,'debug'=>0)), array(-1, 'false')
))));
$this->assertEquals(array('((is_array($in) && isset($in[\'2\'])) ? $in[\'2\'] : null)', '[2]'), $method->invokeArgs(null, array_by_ref(array(
$this->assertEquals(array('(($inary && isset($in[\'2\'])) ? $in[\'2\'] : null)', '[2]'), $method->invokeArgs(null, array_by_ref(array(
array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array('2')
))));
$this->assertEquals(array('2', '2'), $method->invokeArgs(null, array_by_ref(array(
array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0)), array(-1, '2')
))));
$this->assertEquals(array('((is_array($in) && isset($in[\'@index\'])) ? $in[\'@index\'] : null)', '[@index]'), $method->invokeArgs(null, array_by_ref(array(
$this->assertEquals(array('(($inary && isset($in[\'@index\'])) ? $in[\'@index\'] : null)', '[@index]'), $method->invokeArgs(null, array_by_ref(array(
array('flags'=>array('spvar'=>false,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array('@index')
))));
$this->assertEquals(array("(isset(\$cx['sp_vars']['index']) ? \$cx['sp_vars']['index'] : null)", '@[index]'), $method->invokeArgs(null, array_by_ref(array(
Expand All @@ -87,13 +87,13 @@ public function testOn_getVariableName() {
$this->assertEquals(array("(isset(\$cx['sp_vars']['last']) ? \$cx['sp_vars']['last'] : null)", '@[last]'), $method->invokeArgs(null, array_by_ref(array(
array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array('@last')
))));
$this->assertEquals(array('((is_array($in) && isset($in[\'"a"\'])) ? $in[\'"a"\'] : null)', '["a"]'), $method->invokeArgs(null, array_by_ref(array(
$this->assertEquals(array('(($inary && isset($in[\'"a"\'])) ? $in[\'"a"\'] : null)', '["a"]'), $method->invokeArgs(null, array_by_ref(array(
array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array('"a"')
))));
$this->assertEquals(array('"a"', '"a"'), $method->invokeArgs(null, array_by_ref(array(
array('flags'=>array('spvar'=>true,'debug'=>0)), array(-1, '"a"')
))));
$this->assertEquals(array('((is_array($in) && isset($in[\'a\'])) ? $in[\'a\'] : null)', '[a]'), $method->invokeArgs(null, array_by_ref(array(
$this->assertEquals(array('(($inary && isset($in[\'a\'])) ? $in[\'a\'] : null)', '[a]'), $method->invokeArgs(null, array_by_ref(array(
array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array('a')
))));
$this->assertEquals(array('((isset($cx[\'scopes\'][count($cx[\'scopes\'])-1]) && is_array($cx[\'scopes\'][count($cx[\'scopes\'])-1]) && isset($cx[\'scopes\'][count($cx[\'scopes\'])-1][\'a\'])) ? $cx[\'scopes\'][count($cx[\'scopes\'])-1][\'a\'] : null)', '../[a]'), $method->invokeArgs(null, array_by_ref(array(
Expand All @@ -102,7 +102,7 @@ public function testOn_getVariableName() {
$this->assertEquals(array('((isset($cx[\'scopes\'][count($cx[\'scopes\'])-3]) && is_array($cx[\'scopes\'][count($cx[\'scopes\'])-3]) && isset($cx[\'scopes\'][count($cx[\'scopes\'])-3][\'a\'])) ? $cx[\'scopes\'][count($cx[\'scopes\'])-3][\'a\'] : null)', '../../../[a]'), $method->invokeArgs(null, array_by_ref(array(
array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array(3,'a')
))));
$this->assertEquals(array('((is_array($in) && isset($in[\'id\'])) ? $in[\'id\'] : null)', 'this.[id]'), $method->invokeArgs(null, array_by_ref(array(
$this->assertEquals(array('(($inary && isset($in[\'id\'])) ? $in[\'id\'] : null)', 'this.[id]'), $method->invokeArgs(null, array_by_ref(array(
array('flags'=>array('spvar'=>true,'debug'=>0,'prop'=>0,'method'=>0,'mustlok'=>0,'mustlam'=>0,'lambda'=>0,'jslen'=>0)), array(null, 'id')
))));
$this->assertEquals(array('LR::v($cx, $in, isset($in) ? $in : null, array(\'id\'))', 'this.[id]'), $method->invokeArgs(null, array_by_ref(array(
Expand Down

0 comments on commit 046de72

Please sign in to comment.