Skip to content

if{} and if..endif; cause function has wrong docblock (leadingComments) #1166

@ve3

Description

@ve3

I have PHP like this.

<?php

if ( ! function_exists( 'wp_verify_nonce' ) ) :
	/**
	 * Verifies that a correct security nonce was used with time limit.
	 *
	 * @since 2.0.3
	 */
	function wp_verify_nonce() {
	}
endif;


if (!function_exists('wp_nonce_tick')) {
    /**
	 * Returns the time-dependent variable for nonce creation.
	 *
	 * @since 2.5.0
	 */ 
    function wp_nonce_tick() {}
}


/**
 * Is this leading comments?
 * 
 * @since 1.2.3
 */
function do_something() {}

I use this option to parse PHP.

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

Result from glayzzle/php-parser

The result is.

{
  "kind": "program",
  "children": [
    {
      "kind": "if",
      "test": {
        "kind": "unary",
        "type": "!",
        "what": {
          "kind": "call",
          "what": {
            "kind": "name",
            "name": "function_exists",
            "resolution": "uqn"
          },
          "arguments": [
            {
              "kind": "string",
              "value": "wp_verify_nonce",
              "raw": "'wp_verify_nonce'",
              "unicode": false,
              "isDoubleQuote": false
            }
          ]
        }
      },
      "body": {
        "kind": "block",
        "leadingComments": [
          {
            "kind": "commentblock",
            "value": "/**\r\n\t * Verifies that a correct security nonce was used with time limit.\r\n\t *\r\n\t * @since 2.0.3\r\n\t */",
            "offset": 59
          }
        ],
        "children": [
          {
            "kind": "function",
            "name": {
              "kind": "identifier",
              "name": "wp_verify_nonce"
            },
            "arguments": [],
            "byref": false,
            "type": null,
            "nullable": false,
            "body": {
              "kind": "block",
              "children": []
            },
            "attrGroups": []
          }
        ]
      },
      "alternate": null,
      "shortForm": true
    },
    {
      "kind": "if",
      "test": {
        "kind": "unary",
        "type": "!",
        "what": {
          "kind": "call",
          "what": {
            "kind": "name",
            "name": "function_exists",
            "resolution": "uqn"
          },
          "arguments": [
            {
              "kind": "string",
              "value": "wp_nonce_tick",
              "raw": "'wp_nonce_tick'",
              "unicode": false,
              "isDoubleQuote": false
            }
          ]
        }
      },
      "body": {
        "kind": "block",
        "children": [
          {
            "kind": "function",
            "leadingComments": [
              {
                "kind": "commentblock",
                "value": "/**\r\n\t * Returns the time-dependent variable for nonce creation.\r\n\t *\r\n\t * @since 2.5.0\r\n\t */",
                "offset": 256
              }
            ],
            "name": {
              "kind": "identifier",
              "name": "wp_nonce_tick"
            },
            "arguments": [],
            "byref": false,
            "type": null,
            "nullable": false,
            "body": {
              "kind": "block",
              "children": []
            },
            "attrGroups": []
          }
        ]
      },
      "alternate": null,
      "shortForm": false
    },
    {
      "kind": "function",
      "leadingComments": [
        {
          "kind": "commentblock",
          "value": "/**\r\n * Is this leading comments?\r\n * \r\n * @since 1.2.3\r\n */",
          "offset": 392
        }
      ],
      "name": {
        "kind": "identifier",
        "name": "do_something"
      },
      "arguments": [],
      "byref": false,
      "type": null,
      "nullable": false,
      "body": {
        "kind": "block",
        "children": []
      },
      "attrGroups": []
    }
  ]
}

I cut errors and comments out from result above.

The result of first function declaration is differently from second. The leadingComments of second function (and 3rd function) is correctly beside "kind": "function" while the first function is under body above or outside "kind": "function".

The if {..} and if..endif work the exactly same. It should have the same result or not?

Compare with other

Below is result from nikic/php-parser.

[
    {
        "nodeType": "Stmt_If",
        "attributes": {
            "startLine": 3,
            "startTokenPos": 2,
            "startFilePos": 9,
            "endLine": 11,
            "endTokenPos": 32,
            "endFilePos": 203
        },
        "cond": {
            "nodeType": "Expr_BooleanNot",
            "attributes": {
                "startLine": 3,
                "startTokenPos": 6,
                "startFilePos": 14,
                "endLine": 3,
                "endTokenPos": 13,
                "endFilePos": 51
            },
            "expr": {
                "nodeType": "Expr_FuncCall",
                "attributes": {
                    "startLine": 3,
                    "startTokenPos": 8,
                    "startFilePos": 16,
                    "endLine": 3,
                    "endTokenPos": 13,
                    "endFilePos": 51
                },
                "name": {
                    "nodeType": "Name",
                    "attributes": {
                        "startLine": 3,
                        "startTokenPos": 8,
                        "startFilePos": 16,
                        "endLine": 3,
                        "endTokenPos": 8,
                        "endFilePos": 30
                    },
                    "name": "function_exists"
                },
                "args": [
                    {
                        "nodeType": "Arg",
                        "attributes": {
                            "startLine": 3,
                            "startTokenPos": 11,
                            "startFilePos": 33,
                            "endLine": 3,
                            "endTokenPos": 11,
                            "endFilePos": 49
                        },
                        "name": null,
                        "value": {
                            "nodeType": "Scalar_String",
                            "attributes": {
                                "startLine": 3,
                                "startTokenPos": 11,
                                "startFilePos": 33,
                                "endLine": 3,
                                "endTokenPos": 11,
                                "endFilePos": 49,
                                "kind": 1,
                                "rawValue": "'wp_verify_nonce'"
                            },
                            "value": "wp_verify_nonce"
                        },
                        "byRef": false,
                        "unpack": false
                    }
                ]
            }
        },
        "stmts": [
            {
                "nodeType": "Stmt_Function",
                "attributes": {
                    "startLine": 9,
                    "startTokenPos": 21,
                    "startFilePos": 164,
                    "endLine": 10,
                    "endTokenPos": 29,
                    "endFilePos": 195,
                    "comments": [
                        {
                            "nodeType": "Comment_Doc",
                            "text": "\/**\r\n\t * Verifies that a correct security nonce was used with time limit.\r\n\t *\r\n\t * @since 2.0.3\r\n\t *\/",
                            "line": 4,
                            "filePos": 59,
                            "tokenPos": 19,
                            "endLine": 8,
                            "endFilePos": 160,
                            "endTokenPos": 19
                        }
                    ]
                },
                "byRef": false,
                "name": {
                    "nodeType": "Identifier",
                    "attributes": {
                        "startLine": 9,
                        "startTokenPos": 23,
                        "startFilePos": 173,
                        "endLine": 9,
                        "endTokenPos": 23,
                        "endFilePos": 187
                    },
                    "name": "wp_verify_nonce"
                },
                "params": [],
                "returnType": null,
                "stmts": [],
                "attrGroups": []
            }
        ],
        "elseifs": [],
        "else": null
    },
    {
        "nodeType": "Stmt_If",
        "attributes": {
            "startLine": 14,
            "startTokenPos": 34,
            "startFilePos": 210,
            "endLine": 21,
            "endTokenPos": 57,
            "endFilePos": 385
        },
        "cond": {
            "nodeType": "Expr_BooleanNot",
            "attributes": {
                "startLine": 14,
                "startTokenPos": 37,
                "startFilePos": 214,
                "endLine": 14,
                "endTokenPos": 41,
                "endFilePos": 246
            },
            "expr": {
                "nodeType": "Expr_FuncCall",
                "attributes": {
                    "startLine": 14,
                    "startTokenPos": 38,
                    "startFilePos": 215,
                    "endLine": 14,
                    "endTokenPos": 41,
                    "endFilePos": 246
                },
                "name": {
                    "nodeType": "Name",
                    "attributes": {
                        "startLine": 14,
                        "startTokenPos": 38,
                        "startFilePos": 215,
                        "endLine": 14,
                        "endTokenPos": 38,
                        "endFilePos": 229
                    },
                    "name": "function_exists"
                },
                "args": [
                    {
                        "nodeType": "Arg",
                        "attributes": {
                            "startLine": 14,
                            "startTokenPos": 40,
                            "startFilePos": 231,
                            "endLine": 14,
                            "endTokenPos": 40,
                            "endFilePos": 245
                        },
                        "name": null,
                        "value": {
                            "nodeType": "Scalar_String",
                            "attributes": {
                                "startLine": 14,
                                "startTokenPos": 40,
                                "startFilePos": 231,
                                "endLine": 14,
                                "endTokenPos": 40,
                                "endFilePos": 245,
                                "kind": 1,
                                "rawValue": "'wp_nonce_tick'"
                            },
                            "value": "wp_nonce_tick"
                        },
                        "byRef": false,
                        "unpack": false
                    }
                ]
            }
        },
        "stmts": [
            {
                "nodeType": "Stmt_Function",
                "attributes": {
                    "startLine": 20,
                    "startTokenPos": 48,
                    "startFilePos": 356,
                    "endLine": 20,
                    "endTokenPos": 55,
                    "endFilePos": 382,
                    "comments": [
                        {
                            "nodeType": "Comment_Doc",
                            "text": "\/**\r\n\t * Returns the time-dependent variable for nonce creation.\r\n\t *\r\n\t * @since 2.5.0\r\n\t *\/",
                            "line": 15,
                            "filePos": 256,
                            "tokenPos": 46,
                            "endLine": 19,
                            "endFilePos": 348,
                            "endTokenPos": 46
                        }
                    ]
                },
                "byRef": false,
                "name": {
                    "nodeType": "Identifier",
                    "attributes": {
                        "startLine": 20,
                        "startTokenPos": 50,
                        "startFilePos": 365,
                        "endLine": 20,
                        "endTokenPos": 50,
                        "endFilePos": 377
                    },
                    "name": "wp_nonce_tick"
                },
                "params": [],
                "returnType": null,
                "stmts": [],
                "attrGroups": []
            }
        ],
        "elseifs": [],
        "else": null
    },
    {
        "nodeType": "Stmt_Function",
        "attributes": {
            "startLine": 29,
            "startTokenPos": 61,
            "startFilePos": 454,
            "endLine": 29,
            "endTokenPos": 68,
            "endFilePos": 479,
            "comments": [
                {
                    "nodeType": "Comment_Doc",
                    "text": "\/**\r\n * Is this leading comments?\r\n * \r\n * @since 1.2.3\r\n *\/",
                    "line": 24,
                    "filePos": 392,
                    "tokenPos": 59,
                    "endLine": 28,
                    "endFilePos": 451,
                    "endTokenPos": 59
                }
            ]
        },
        "byRef": false,
        "name": {
            "nodeType": "Identifier",
            "attributes": {
                "startLine": 29,
                "startTokenPos": 63,
                "startFilePos": 463,
                "endLine": 29,
                "endTokenPos": 63,
                "endFilePos": 474
            },
            "name": "do_something"
        },
        "params": [],
        "returnType": null,
        "stmts": [],
        "attrGroups": []
    }
]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions