closure icon indicating copy to clipboard operation
closure copied to clipboard

Fix Syntax error with array access in string interpolation

Open abdrzakoxa opened this issue 5 years ago • 7 comments

Fix #62

abdrzakoxa avatar Nov 24 '20 01:11 abdrzakoxa

A complex test

namespace Test;
const foo = 'foo';

$closure = function () {
    $x = [
        'fooConst' => 1,
        'foo' => 3,
    ];
    $y = [
        'foo' => 'Const'
    ];
    return "${x[foo]}${x[foo . "${y[foo]}"]}";
};

echo $closure(), PHP_EOL; //> 31

echo \Opis\Closure\serialize($closure), PHP_EOL; 
//  return "${x[\Test\foo]}${x[\Test\foo . "${y[\Test\foo]}"]}";

sorinsarca avatar Apr 09 '21 13:04 sorinsarca

My two cents on this issue: the heuristic nature of the parser should be preserved. It served us well for years and we all knew too well that there are edge cases that won't work. Our purpose was never to build a full PHP parser, just a good enough approximation of it.

msarca avatar Apr 09 '21 13:04 msarca

My two cents on this issue: the heuristic nature of the parser should be preserved. It served us well for years and we all knew too well that there are edge cases that won't work. Our purpose was never to build a full PHP parser, just a good enough approximation of it.

I agree. Not to mention that in 4.x this issue is solved.

sorinsarca avatar Apr 09 '21 14:04 sorinsarca

A complex test

namespace Test;
const foo = 'foo';

$closure = function () {
    $x = [
        'fooConst' => 1,
        'foo' => 3,
    ];
    $y = [
        'foo' => 'Const'
    ];
    return "${x[foo]}${x[foo . "${y[foo]}"]}";
};

echo $closure(), PHP_EOL; //> 31

echo \Opis\Closure\serialize($closure), PHP_EOL; 
//  return "${x[\Test\foo]}${x[\Test\foo . "${y[\Test\foo]}"]}";

I just test this and it's passed

    const bar = 'bar';
    public function testComplexConstant()
    {
        $c = function () {
            $x = [
                'barConst' => 1,
                'bar' => 3,
            ];
            $y = [
                'bar' => 'Const'
            ];
            return "${x[bar]}${x[bar . "${y[bar]}"]}";
        };
        $u = $this->s($c);
        self::assertEquals($c(), $u());
    }

abdrzakoxa avatar Apr 09 '21 14:04 abdrzakoxa

I just test this and it's passed

My bad, I meant:

namespace Test;

const foo = 'fooVal';

$closure = function () {
    $x = [
        'fooValConst' => 1,
        'fooVal' => 3,
        'foo' => 4,
    ];
    $y = [
        'fooVal' => 'Const'
    ];
    return "${x[foo]}${x[foo . "${y[foo]}"]}$x[foo]${x[foo]}";
};

echo $closure(), PHP_EOL; //> 3143

echo \Opis\Closure\serialize($closure), PHP_EOL;
// return "{x[\Test\foo]}{x[\Test\foo . "{y[\Test\foo]}"]}$x[foo]{x[\Test\foo]}";

Please test the generated source code, not the results of the function call.

sorinsarca avatar Apr 09 '21 14:04 sorinsarca

I just test this and it's passed

My bad, I meant:

namespace Test;

const foo = 'fooVal';

$closure = function () {
    $x = [
        'fooValConst' => 1,
        'fooVal' => 3,
        'foo' => 4,
    ];
    $y = [
        'fooVal' => 'Const'
    ];
    return "${x[foo]}${x[foo . "${y[foo]}"]}$x[foo]${x[foo]}";
};

echo $closure(), PHP_EOL; //> 3143

echo \Opis\Closure\serialize($closure), PHP_EOL;
// return "{x[\Test\foo]}{x[\Test\foo . "{y[\Test\foo]}"]}$x[foo]{x[\Test\foo]}";

Please test the generated source code, not the results of the function call.

But also this was passed

       const foo = 'fooVal';
       $c = function () {
            $x = [
                'fooValConst' => 1,
                'fooVal' => 3,
                'foo' => 4,
            ];
            $y = [
                'fooVal' => 'Const'
            ];
            return "${x[foo]}${x[foo . "${y[foo]}"]}$x[foo]${x[foo]}";
        };
        $u = $this->s($c);
        echo $u(); // 3143

pls make sure you have latest changes for this branch

abdrzakoxa avatar Apr 09 '21 14:04 abdrzakoxa

@sorinsarca All possible problems now are solved for this issue You can review it now

abdrzakoxa avatar Apr 09 '21 15:04 abdrzakoxa