Skip to content

Commit 3f7d2bb

Browse files
committed
Lots more cleanup
- Registering a function can typehint on callable - No need for a special prettyPrint function when debugging - Simplified validation by removing default types and variadics. - Using short array syntax in functions. - Removing the ability to inject a parser or interpreter from runtimes. - TreeInterpreter now requires a RuntimeInterface in the constructor.
1 parent 96feef1 commit 3f7d2bb

File tree

9 files changed

+104
-193
lines changed

9 files changed

+104
-193
lines changed

src/Runtime/AbstractRuntime.php

Lines changed: 81 additions & 122 deletions
Large diffs are not rendered by default.

src/Runtime/AstRuntime.php

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,30 +13,13 @@ class AstRuntime extends AbstractRuntime
1313
{
1414
/** @var TreeVisitorInterface */
1515
private $interpreter;
16-
17-
/** @var array */
18-
private $visitorOptions;
19-
20-
/** @var array Internal AST cache */
2116
private $cache = [];
22-
23-
/** @var int Number of cached entries */
2417
private $cachedCount = 0;
2518

26-
/**
27-
* @param array $config Configuration options for the runtime.
28-
* - parser: Parser to use (optional)
29-
* - interpreter: Interprets the AST (optional)
30-
*/
31-
public function __construct(array $config = [])
19+
public function __construct()
3220
{
33-
$this->visitorOptions = ['runtime' => $this];
34-
$this->parser = isset($config['parser'])
35-
? $config['parser']
36-
: new Parser();
37-
$this->interpreter = isset($config['interpreter'])
38-
? $config['interpreter']
39-
: new TreeInterpreter($this);
21+
$this->parser = new Parser();
22+
$this->interpreter = new TreeInterpreter($this);
4023
}
4124

4225
public function search($expression, $data)
@@ -49,25 +32,21 @@ public function search($expression, $data)
4932
$this->cache[$expression] = $this->parser->parse($expression);
5033
}
5134

52-
return $this->interpreter->visit(
53-
$this->cache[$expression],
54-
$data,
55-
$this->visitorOptions
56-
);
35+
return $this->interpreter->visit($this->cache[$expression], $data);
5736
}
5837

5938
public function debug($expression, $data, $out = STDOUT)
6039
{
6140
fprintf($out, "Expression\n==========\n\n%s\n\n", $expression);
6241
list($_, $lexTime) = $this->printDebugTokens($out, $expression);
6342
list($ast, $parseTime) = $this->printDebugAst($out, $expression);
64-
fprintf($out, "\nData\n====\n\n%s\n\n", $this->prettyJson($data));
43+
fprintf($out, "\nData\n====\n\n%s\n\n", json_encode($data, JSON_PRETTY_PRINT));
6544

6645
$t = microtime(true);
67-
$result = $this->interpreter->visit($ast, $data, $this->visitorOptions);
46+
$result = $this->interpreter->visit($ast, $data);
6847
$interpretTime = (microtime(true) - $t) * 1000;
6948

70-
fprintf($out, "\nResult\n======\n\n%s\n\n", $this->prettyJson($result));
49+
fprintf($out, "\nResult\n======\n\n%s\n\n", json_encode($result, JSON_PRETTY_PRINT));
7150
fwrite($out, "Time\n====\n\n");
7251
fprintf($out, "Lexer time: %f ms\n", $lexTime);
7352
fprintf($out, "Parse time: %f ms\n", $parseTime);

src/Runtime/CompilerRuntime.php

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,13 @@ class CompilerRuntime extends AbstractRuntime
2020

2121
/**
2222
* @param array $config Array of configuration options.
23-
* - parser: Parses expressions
2423
* - dir: Directory used to store compiled PHP files.
2524
* @throws \RuntimeException if the cache directory cannot be created
2625
*/
2726
public function __construct(array $config = [])
2827
{
2928
$this->compiler = new TreeCompiler();
30-
$this->parser = isset($config['parser'])
31-
? $config['parser']
32-
: new Parser();
29+
$this->parser = new Parser();
3330

3431
if (!isset($config['dir'])) {
3532
$config['dir'] = sys_get_temp_dir();
@@ -74,18 +71,16 @@ public function search($expression, $data)
7471

7572
public function clearCache()
7673
{
77-
$files = glob("{$this->cacheDir}/jmespath_*.php");
78-
foreach ($files as $file) {
74+
foreach (glob("{$this->cacheDir}/jmespath_*.php") as $file) {
7975
unlink($file);
8076
}
8177
}
8278

8379
public function debug($expression, $data, $out = STDOUT)
8480
{
8581
fprintf($out, "Expression\n==========\n\n%s\n\n", $expression);
86-
list($tokens, $lexTime) = $this->printDebugTokens($out, $expression);
87-
list($ast, $parseTime) = $this->printDebugAst($out, $expression);
88-
82+
list($_, $lexTime) = $this->printDebugTokens($out, $expression);
83+
list($_, $parseTime) = $this->printDebugAst($out, $expression);
8984
$hash = md5($expression);
9085
$functionName = "jmespath_{$hash}";
9186
$filename = "{$this->cacheDir}/{$functionName}.php";
@@ -95,8 +90,8 @@ public function debug($expression, $data, $out = STDOUT)
9590
$interpretTime = (microtime(true) - $t) * 1000;
9691

9792
fprintf($out, "\nSource\n======\n\n%s", file_get_contents($filename));
98-
fprintf($out, "\nData\n====\n\n%s\n\n", $this->prettyJson($data));
99-
fprintf($out, "\nResult\n======\n\n%s\n\n", $this->prettyJson($result));
93+
fprintf($out, "\nData\n====\n\n%s\n\n", json_encode($data, JSON_PRETTY_PRINT));
94+
fprintf($out, "\nResult\n======\n\n%s\n\n", json_encode($result, JSON_PRETTY_PRINT));
10095
fwrite($out, "Time\n====\n\n");
10196
fprintf($out, "Lexer time: %f ms\n", $lexTime);
10297
fprintf($out, "Parse time: %f ms\n", $parseTime);

src/Runtime/RuntimeInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public function debug($expression, $data, $out = STDOUT);
4444
* @throws \InvalidArgumentException if the function is not callable or is
4545
* a built-in function.
4646
*/
47-
public function registerFunction($name, $fn);
47+
public function registerFunction($name, callable $fn);
4848

4949
/**
5050
* Invokes a named function.

src/Tree/TreeCompiler.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,19 @@ public function visit(array $node, $data, array $args = null)
2424
$this->source = '';
2525
$this->indentation = 0;
2626
$this->write("<?php\n");
27+
2728
if (isset($args['expression'])) {
2829
$this->write("// {$args['expression']}");
2930
}
31+
3032
$this->write("function {$args['function_name']}(JmesPath\\Runtime\\RuntimeInterface \$runtime, \$value) {")
31-
->indent()
33+
->indent()
3234
->write('$current = $value;')
3335
->dispatch($node)
3436
->write('')
3537
->write('return $value;')
36-
->outdent()
37-
->write('}');
38+
->outdent()
39+
->write('}');
3840

3941
return $this->source;
4042
}
@@ -281,7 +283,7 @@ private function visit_expression(array $node)
281283
$child = var_export($node['children'][0], true);
282284

283285
return $this->write("\$value = new \\JmesPath\\Tree\\ExprNode("
284-
. "new \\JmesPath\\Tree\\TreeInterpreter(), $child);");
286+
. "new \\JmesPath\\Tree\\TreeInterpreter(new \\JmesPath\\Runtime\\AstRuntime()), $child);");
285287
}
286288

287289
private function visit_flatten(array $node)

src/Tree/TreeInterpreter.php

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<?php
22
namespace JmesPath\Tree;
33

4-
use JmesPath\Runtime\AstRuntime;
54
use JmesPath\Runtime\RuntimeInterface;
65

76
/**
@@ -12,19 +11,13 @@ class TreeInterpreter implements TreeVisitorInterface
1211
/** @var RuntimeInterface Runtime used to manage function calls */
1312
private $runtime;
1413

15-
public function __construct(RuntimeInterface $runtime = null)
14+
public function __construct(RuntimeInterface $runtime)
1615
{
1716
$this->runtime = $runtime;
1817
}
1918

2019
public function visit(array $node, $data, array $args = null)
2120
{
22-
if (!$this->runtime) {
23-
$this->runtime = isset($args['runtime'])
24-
? $args['runtime']
25-
: new AstRuntime();
26-
}
27-
2821
return $this->dispatch($node, $data);
2922
}
3023

tests/Runtime/AbstractRuntimeTest.php

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,6 @@
33

44
class AbstractRuntimeTest extends \PHPUnit_Framework_TestCase
55
{
6-
/**
7-
* @expectedException \InvalidArgumentException
8-
* @expectedExceptionMessage Function must be callable
9-
*/
10-
public function testEnsuresFunctionsAreCallable()
11-
{
12-
$r = $this->getMockBuilder('JmesPath\Runtime\AbstractRuntime')
13-
->getMockForAbstractClass();
14-
$r->registerFunction('foo', 'bar');
15-
}
16-
176
/**
187
* @expectedException \RuntimeException
198
* @expectedExceptionMessage Call to undefined function foo

tests/Runtime/AstRuntimeTest.php

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
11
<?php
22
namespace JmesPath\Tests\Runtime;
33

4-
use JmesPath\Parser;
54
use JmesPath\Runtime\AstRuntime;
6-
use JmesPath\Tree\TreeInterpreter;
7-
use JmesPath\Lexer;
85

96
class AstRuntimeTest extends \PHPUnit_Framework_TestCase
107
{
118
public function testClearsCache()
129
{
13-
$r = new AstRuntime([
14-
'parser' => new Parser(new Lexer()),
15-
'interpreter' => new TreeInterpreter()
16-
]);
10+
$r = new AstRuntime();
1711
$r->search('foo', array());
1812
$this->assertNotEmpty($this->readAttribute($r, 'cache'));
1913
$r->clearCache();

tests/Tree/TreeInterpreterTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class TreeInterpreterTest extends \PHPUnit_Framework_TestCase
1111
{
1212
public function testReturnsNullWhenMergingNonArray()
1313
{
14-
$t = new TreeInterpreter();
14+
$t = new TreeInterpreter(new AstRuntime());
1515
$this->assertNull($t->visit(array(
1616
'type' => 'flatten',
1717
'children' => array(

0 commit comments

Comments
 (0)