Skip to content

Commit 6db5bd0

Browse files
Parse method calls more leniently (#26)
Allow the expression in the single argument to be anything at all, as long as there’s a matching closing parenthesis at the end. Because we don’t support binary operators or multiple arguments, we don’t need to worry about counting balanced parentheses or anything like that: if the close-paren at the very end of the string doesn’t belong to the open-paren at the beginning of the method call, then there must be a syntax error (or unsupported syntax) somewhere.
1 parent c1576a8 commit 6db5bd0

File tree

2 files changed

+11
-8
lines changed

2 files changed

+11
-8
lines changed

src/JsParsing/BasicJsExpressionParser.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public function parse( $expression ) {
2323
return new NegationOperator( $this->parse( substr( $expression, 1 ) ) );
2424
} elseif ( strncmp( $expression, "'", 1 ) === 0 ) {
2525
return new StringLiteral( substr( $expression, 1, -1 ) );
26-
} elseif ( preg_match( '/^(\w+?)\(\s*([\w.\-\']+?)\s*\)$/', $expression, $matches ) ) {
26+
} elseif ( preg_match( '/^(\w+)\((.*)\)$/', $expression, $matches ) ) {
2727
$methodName = $matches[1];
2828
if ( !array_key_exists( $methodName, $this->methods ) ) {
2929
throw new RuntimeException( "Method '{$methodName}' is undefined" );

tests/php/JsParsing/BasicJsExpressionParserTest.php

+10-7
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public function testCanParseNegationOperator() {
3737
$this->assertFalse( $negation->evaluate( [ 'variable' => true ] ) );
3838
}
3939

40-
public function testCanParseMethodCall_builtin() {
40+
public function testCanParseMethodCall_builtin_variable() {
4141
$jsExpressionEvaluator = new BasicJsExpressionParser( [
4242
'strtoupper' => 'strtoupper',
4343
] );
@@ -48,28 +48,31 @@ public function testCanParseMethodCall_builtin() {
4848
$this->assertSame( 'ABC', $result );
4949
}
5050

51-
public function testCanParseMethodCall_closure() {
51+
public function testCanParseMethodCall_closure_string() {
5252
$jsExpressionEvaluator = new BasicJsExpressionParser( [
5353
'strtoupper' => static function ( string $arg ) {
5454
return strtoupper( $arg );
5555
},
5656
] );
5757

58-
$parsedExpression = $jsExpressionEvaluator->parse( 'strtoupper(var)' );
59-
$result = $parsedExpression->evaluate( [ 'var' => 'abc' ] );
58+
$parsedExpression = $jsExpressionEvaluator->parse( "strtoupper('abc')" );
59+
$result = $parsedExpression->evaluate( [] );
6060

6161
$this->assertSame( 'ABC', $result );
6262
}
6363

64-
public function testCanParseMethodCall_whitespace() {
64+
public function testCanParseMethodCall_whitespace_nested() {
6565
$jsExpressionEvaluator = new BasicJsExpressionParser( [
6666
'strtoupper' => 'strtoupper',
67+
'strrev' => 'strrev',
6768
] );
6869

69-
$parsedExpression = $jsExpressionEvaluator->parse( ' strtoupper( var ) ' );
70+
$parsedExpression = $jsExpressionEvaluator->parse(
71+
' strrev( strtoupper( var ) ) '
72+
);
7073
$result = $parsedExpression->evaluate( [ 'var' => 'abc' ] );
7174

72-
$this->assertSame( 'ABC', $result );
75+
$this->assertSame( 'CBA', $result );
7376
}
7477

7578
public function testIgnoresTrailingAndLeadingSpaces() {

0 commit comments

Comments
 (0)