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

Request: Distinguish quoted and unquoted heredoc strings #592

Open
JakeTunaley opened this issue Mar 26, 2019 · 3 comments
Open

Request: Distinguish quoted and unquoted heredoc strings #592

JakeTunaley opened this issue Mar 26, 2019 · 3 comments

Comments

@JakeTunaley
Copy link

JakeTunaley commented Mar 26, 2019

Running the parser (v4.2.1) against the following two code snippets produces identical ASTs.

Snippet 1

<?php
echo <<<FOO
hello world
FOO;

Snippet 2

<?php
echo <<<"FOO"
hello world
FOO;

Common AST

[
    {
        "nodeType": "Stmt_Echo",
        "exprs": [
            {
                "nodeType": "Scalar_String",
                "value": "hello world",
                "attributes": {
                    "startLine": 1,
                    "endLine": 3,
                    "kind": 3,
                    "docLabel": "FOO",
                    "docIndentation": ""
                }
            }
        ],
        "attributes": {
            "startLine": 1,
            "endLine": 3
        }
    }
]

Suggestion

Add a new boolean attribute which is true if and only if kind is PhpParser\Node\ScalarString_::KIND_HEREDOC and the heredoc identifier is wrapped in double-quotes. (This is preferable to a new kind, e.g. PhpParser\Node\ScalarString_::KIND_QUOTED_HEREDOC, to preserve backwards compatibility with scripts checking that attribute for either type of heredoc string).

@nikic
Copy link
Owner

nikic commented Mar 26, 2019

What use case do you have in mind for this? Is it to throw a warning when it's quoted / not quoted, to preserve the format during pretty-printing, or something else?

@JakeTunaley
Copy link
Author

I'm writing a tool that will detect PHP features not supported in some targeted version.

My co-workers and I were instructed that they could write PHP 7.1 before we tried to upgrade the servers, which was a mistake because one of the upgrades didn't take, so now we need to audit all the code we've written since then for things like this.

(And yes, I know the version of PHP just before quoted Heredoc strings were introduced in (5.2) is very, very unsupported, but the server's running Windows Server 2003...)

My current workaround is as follows:

// Node $node: The node being checked
// string $phpCode: The complete contents of the PHP file being checked

if ($node instanceof Node\Scalar\String_ && $node->getAttribute('kind') === Node\Scalar\String_::KIND_HEREDOC) {
    $docLabel = $node->getAttribute('docLabel');
    $sourceCode = substr($phpCode, $node->getStartFilePos(), $node->getEndFilePos() + 1 - $node->getStartFilePos());
    $heredocOpener = substr($sourceCode, 0, strpos($sourceCode, "\n"));
    // Regex matches a quoted heredoc opener
    if (preg_match('/^<<<\s*"' . preg_quote($docLabel) . '"/', $firstLine) === 1) {
        // $node is a quoted heredoc string
    }
}

@TomasVotruba
Copy link
Contributor

I'm writing a tool that will detect PHP features not supported in some targeted version.

Just a tip for similar tool, only with tokens: https://github.com/PHPCompatibility/PHPCompatibility

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

No branches or pull requests

3 participants