Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Syntax errors caused by namespace resolution #78

Closed
JakeBooher opened this issue Nov 3, 2023 · 3 comments · Fixed by #80
Closed

Syntax errors caused by namespace resolution #78

JakeBooher opened this issue Nov 3, 2023 · 3 comments · Fixed by #80
Assignees

Comments

@JakeBooher
Copy link

Serializable Closure Version

1.3.2

PHP Version

8.2

Description

It seems that when there is a switch statement that contains a class reference the namespace resolution that happens during serialization causes the colon to be removed at the end of the case line, steps to reproduce contains a CLI command to replicate this behavior.

syntax error, unexpected token "return"

Steps To Reproduce

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Laravel\SerializableClosure\Serializers\Native;

class DebugCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'debug';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Execute the console command.
     */
    public function handle()
    {
        $cacheClosure = static function(): array {
            $var = new \stdClass();

            switch(true) {
                case $var instanceof \stdClass:
                    return true;

                default:
                    return false;
            }
        };

        $cacheData = [
           'helloWorld' =>  $cacheClosure
        ];

        Native::wrapClosures($cacheData, new \SplObjectStorage());
        $cacheContent = serialize($cacheData);

        dump($cacheContent);exit;

        unserialize($cacheContent);exit;
    }
}
@nunomaduro
Copy link
Member

@JakeBooher Can you open a pull request, that adds multiple tests for this specific scenario? So we can work on a solution after?

@JakeBooher
Copy link
Author

JakeBooher commented Nov 3, 2023

I've added a test case here: #79

The following is the error you will receive:

 syntax error, unexpected token "return"

  at laravel-serializable-closure://function () {
        $var = new \stdClass();

        switch(true) {
            case $var instanceof \stdClass
                return true;

            default:
                return false;
        }
    }:7
      3▕         $var = new \stdClass();
      4▕ 
      5▕         switch(true) {
      6▕             case $var instanceof \stdClass
  ➜   7▕                 return true;
      8▕ 
      9▕             default:
     10▕                 return false;
     11▕         }

@JakeBooher
Copy link
Author

It seems like this is related to the usage of instanceof specifically due to the following:

                case 'id_name':
                    switch ($token[0]) {
                        // named arguments...
                        case ':':
                            if ($lastState === 'closure' && $context === 'root') {
                                $state = 'closure';
                                $code .= $id_start.$token;
                            }

In my case $context is instanceof so it does not append the : correctly. What is the reason for limiting the colon to only being applied with the context root?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants