prettier / plugin-php

Prettier PHP Plugin
https://loilo.github.io/prettier-php-playground/
MIT License
1.74k stars 128 forks source link

Missing comments within anonymous class #320

Closed hawkrives closed 6 years ago

hawkrives commented 6 years ago

PHP: 7.0 Node: 9 prettier-php: 26c6262 prettier: d676188

I apologize for this code, but it's in my codebase, and prettier-php told me to report it.

> ./node_modules/.bin/prettier --write ./test.php
[error] test.php: Error: Comment "// body of anonymous class" was not printed. Please report this error!
[error]     at astComments.forEach.comment (/Users/rives/Projects/tribe/node_modules/prettier/index.js:54:13)
[error]     at Array.forEach (<anonymous>)
[error]     at ensureAllCommentsPrinted (/Users/rives/Projects/tribe/node_modules/prettier/index.js:52:15)
[error]     at formatWithCursor (/Users/rives/Projects/tribe/node_modules/prettier/index.js:117:3)
[error]     at Object.formatWithCursor (/Users/rives/Projects/tribe/node_modules/prettier/index.js:390:12)
[error]     at format (/Users/rives/Projects/tribe/node_modules/prettier/src/cli/util.js:157:19)
[error]     at eachFilename (/Users/rives/Projects/tribe/node_modules/prettier/src/cli/util.js:382:16)
[error]     at filePaths.forEach.filePath (/Users/rives/Projects/tribe/node_modules/prettier/src/cli/util.js:322:7)
[error]     at Array.forEach (<anonymous>)
[error]     at eachFilename (/Users/rives/Projects/tribe/node_modules/prettier/src/cli/util.js:321:15)

test.php

<?php

abstract class Taxonomy_Service_Provider implements ServiceProviderInterface {

    protected function register( Container $container ) {

        // within member function
        $container[ 'taxonomy.' . $this->taxonomy . '.config' ] = function ( $container ) {
            // within anonymous function

            return new class( $this->taxonomy, $this->post_types ) extends Taxonomy_Config {

                // body of anonymous class
                public function get_args() {
                    // body of member function of anonymous class
                    return []; // after return in member function of anonymous class
                } // after member function on anonymous class

            };
        };

    }
}

The problem: None of the comments within the anonymous class are printed. (The outer two comments are printed, so they're fine.)

mgrip commented 6 years ago

Ugh this is a tough one - the problem is around the locations of the different nodes. Although they are all correct, they break the assumption made in prettier core that all "child nodes" are exclusive and don't contain one another. So in this case, the new node has 3 children, 2 arguments (kind = propertylookup) and one what (kind = class). Technically the class node encloses the 2 property lookup nodes. However, the comment functionality in prettier core makes the assumption that all child nodes of new are exclusive, and once it sees that the // body of member function of anonymous class comment comes after the first propertylookup node, it also assumes it comes after the class node (because the class node technically starts before the propertylookup node). Not really sure what the approach should be for this one...

Some potential options

czosel commented 6 years ago

Wow, that really sounds tough. I’m surprised though - is this really the first time we have overlapping node locations? If yes, do you think it’ll be the only time?

mgrip commented 6 years ago

I think so. Off the top of my head I don't know of anything similar to the new anonymous class syntax (and apparently javascript never has this problem)

mgrip commented 6 years ago

Ok Its not pretty but I think I managed to get something along the lines of this working

or updating our loc functions, to specifically look for anonymous classes and bump the start offset back.

I'll try and post a PR at some point today

alexander-akait commented 6 years ago

Fixed: https://github.com/prettier/plugin-php/pull/348