php-parser icon indicating copy to clipboard operation
php-parser copied to clipboard

Namespace should not be nested

Open ve3 opened this issue 3 months ago • 2 comments

From PHP document ( https://www.php.net/manual/en/language.namespaces.faq.php#language.namespaces.faq.nested ), it said Nested namespaces are not allowed.

Here is same of PHP namespaces in 2 styles.

01 Simple style

namespace MyProject;
    const TASK_DATE = '';


namespace Another;
    echo TASK_DATE;

The echo line said Fatal error: Uncaught Error: Undefined constant "Another\TASK_DATE".

02 Bracket style

namespace MyProject {
    const TASK_DATE = '';
}

namespace Another {
    echo TASK_DATE;
}

The result is same error Fatal error: Uncaught Error: Undefined constant "Another\TASK_DATE".

=> This mean that simple style Another namespace is not nested under MyProject same as bracket style did.

BUT.. the php-parser parse these two differently!

Simple style result

{
  "kind": "program",
  "children": [
    {
      "children": [
        {
          "name": "Another",
          "withBrackets": false
        }
      ],
      "name": "MyProject",
      "withBrackets": false
    }
  ]
}

Bracket style result

{
  "kind": "program",
  "children": [
    {
      "name": "Another",
      "withBrackets": true
    },
    {
      "name": "MyProject",
      "withBrackets": true
    }
  ]
}

Since it is not allowed to nested namespace (from PHP document above) and the simple and bracket styles work the same, I think php parser should treat them the same as well. ??

JS Code I use to parse the PHP file.

// initialize a new parser instance
const parser = new engine({
  // some options :
  parser: {
    extractDoc: true,
    locations: true,
    php8: true,
  },
  ast: {
    withPositions: true,
  },
  lexer: {
    all_tokens: true,
  },
});

const phpFile = fs.readFileSync("./example.php");


// Log out results
console.log("File parse:", JSON.stringify(parser.parseCode(phpFile), null, 2));

ve3 avatar Sep 21 '25 07:09 ve3

I'm not sure about this that why you nested them like that but I've tested with other parser like nikic/PHP-Parser they did not nested the namespace.

Same PHP as above and here is the result.

Simple style result

[
    {
        "nodeType": "Stmt_Namespace",
        "name": {
            "nodeType": "Name",
            "name": "MyProject"
        },
    },
    {
        "nodeType": "Stmt_Namespace",
        "name": {
            "nodeType": "Name",
            "name": "Another"
        }
    }
]

Bracket style result

[
    {
        "nodeType": "Stmt_Namespace",
        "name": {
            "nodeType": "Name",
            "name": "MyProject"
        },
        
    },
    {
        "nodeType": "Stmt_Namespace",
        "name": {
            "nodeType": "Name",
            "name": "Another"
        }
    }
]

ve3 avatar Sep 23 '25 18:09 ve3

👍 I'd say we should aim for the output structure nikic/PHP-Parser generates as suggested by @ve3. Contributions are welcome!

czosel avatar Sep 29 '25 06:09 czosel