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

[Feature] Consistent foreach style #1638

Open
dereuromark opened this issue Nov 17, 2023 · 2 comments
Open

[Feature] Consistent foreach style #1638

dereuromark opened this issue Nov 17, 2023 · 2 comments

Comments

@dereuromark
Copy link
Contributor

dereuromark commented Nov 17, 2023

I see code like

foreach ($usecases as $usecase) :
    $usecase->setDirty('name', true);
    $usecasesTable->save($usecase);
endforeach;

in some of the projects.

I would like to auto fix this via sniffer to the cleaner version

foreach ($usecases as $usecase) {
    $usecase->setDirty('name', true);
    $usecasesTable->save($usecase);
}

Especially since the former cannot be properly used by modern IDEs as PHPStorm. Even latest version doesnt show the closing part to the opening.

Is there an easy way to add this without accidentally killing the code or levels of nesting?
I checked existing sniffers and didnt find a matching one so far.

I wonder which other tokens might also be of the same type we can replace:

        T_ENDIF               => T_ENDIF,
        T_ENDFOR              => T_ENDFOR,
        T_ENDFOREACH          => T_ENDFOREACH,
        T_ENDWHILE            => T_ENDWHILE,
        T_ENDSWITCH           => T_ENDSWITCH,
        T_ENDDECLARE          => T_ENDDECLARE,
@dereuromark
Copy link
Contributor Author

I analyzed the phpcs tokens

<?php
        foreach ($usecases as $usecase) :
// T_WHITESPACE (216) code=392, line=42, column=1, length=8, level=2, conditions={"65":333,"199":310}, content=`        `
// T_FOREACH (217) code=297, line=42, column=9, length=7, parenthesis_opener=219, parenthesis_closer=225, parenthesis_owner=217, scope_condition=217, scope_opener=227, scope_closer=251, level=2, conditions={"65":333,"199":310}, content=`foreach`
// T_WHITESPACE (218) code=392, line=42, column=16, length=1, level=2, conditions={"65":333,"199":310}, content=` `
// T_OPEN_PARENTHESIS (219) code=PHPCS_T_OPEN_PARENTHESIS, line=42, column=17, length=1, parenthesis_opener=219, parenthesis_owner=217, parenthesis_closer=225, level=2, conditions={"65":333,"199":310}, content=`(`
// T_VARIABLE (220) code=266, line=42, column=18, length=9, nested_parenthesis={"219":225}, level=2, conditions={"65":333,"199":310}, content=`$usecases`
// T_WHITESPACE (221) code=392, line=42, column=27, length=1, nested_parenthesis={"219":225}, level=2, conditions={"65":333,"199":310}, content=` `
// T_AS (222) code=301, line=42, column=28, length=2, nested_parenthesis={"219":225}, level=2, conditions={"65":333,"199":310}, content=`as`
// T_WHITESPACE (223) code=392, line=42, column=30, length=1, nested_parenthesis={"219":225}, level=2, conditions={"65":333,"199":310}, content=` `
// T_VARIABLE (224) code=266, line=42, column=31, length=8, nested_parenthesis={"219":225}, level=2, conditions={"65":333,"199":310}, content=`$usecase`
// T_CLOSE_PARENTHESIS (225) code=PHPCS_T_CLOSE_PARENTHESIS, line=42, column=39, length=1, parenthesis_owner=217, parenthesis_opener=219, parenthesis_closer=225, level=2, conditions={"65":333,"199":310}, content=`)`
// T_WHITESPACE (226) code=392, line=42, column=40, length=1, level=2, conditions={"65":333,"199":310}, content=` `
// T_COLON (227) code=PHPCS_T_COLON, line=42, column=41, length=1, scope_condition=217, scope_opener=227, scope_closer=251, level=2, conditions={"65":333,"199":310}, content=`:`
// T_WHITESPACE (228) code=392, line=42, column=42, length=0, level=3, conditions={"65":333,"199":310,"217":297}, content=`\n`
            $usecase->setDirty('name', true);
// T_WHITESPACE (229) code=392, line=43, column=1, length=12, level=3, conditions={"65":333,"199":310,"217":297}, content=`            `
// T_VARIABLE (230) code=266, line=43, column=13, length=8, level=3, conditions={"65":333,"199":310,"217":297}, content=`$usecase`
// T_OBJECT_OPERATOR (231) code=384, line=43, column=21, length=2, level=3, conditions={"65":333,"199":310,"217":297}, content=`->`
// T_STRING (232) code=262, line=43, column=23, length=8, level=3, conditions={"65":333,"199":310,"217":297}, content=`setDirty`
// T_OPEN_PARENTHESIS (233) code=PHPCS_T_OPEN_PARENTHESIS, line=43, column=31, length=1, parenthesis_opener=233, parenthesis_closer=238, level=3, conditions={"65":333,"199":310,"217":297}, content=`(`
// T_CONSTANT_ENCAPSED_STRING (234) code=269, line=43, column=32, length=6, nested_parenthesis={"233":238}, level=3, conditions={"65":333,"199":310,"217":297}, content=`'name'`
// T_COMMA (235) code=PHPCS_T_COMMA, line=43, column=38, length=1, nested_parenthesis={"233":238}, level=3, conditions={"65":333,"199":310,"217":297}, content=`,`
// T_WHITESPACE (236) code=392, line=43, column=39, length=1, nested_parenthesis={"233":238}, level=3, conditions={"65":333,"199":310,"217":297}, content=` `
// T_TRUE (237) code=PHPCS_T_TRUE, line=43, column=40, length=4, nested_parenthesis={"233":238}, level=3, conditions={"65":333,"199":310,"217":297}, content=`true`
// T_CLOSE_PARENTHESIS (238) code=PHPCS_T_CLOSE_PARENTHESIS, line=43, column=44, length=1, parenthesis_opener=233, parenthesis_closer=238, level=3, conditions={"65":333,"199":310,"217":297}, content=`)`
// T_SEMICOLON (239) code=PHPCS_T_SEMICOLON, line=43, column=45, length=1, level=3, conditions={"65":333,"199":310,"217":297}, content=`;`
// T_WHITESPACE (240) code=392, line=43, column=46, length=0, level=3, conditions={"65":333,"199":310,"217":297}, content=`\n`
            $usecasesTable->save($usecase);
// T_WHITESPACE (241) code=392, line=44, column=1, length=12, level=3, conditions={"65":333,"199":310,"217":297}, content=`            `
// T_VARIABLE (242) code=266, line=44, column=13, length=14, level=3, conditions={"65":333,"199":310,"217":297}, content=`$usecasesTable`
// T_OBJECT_OPERATOR (243) code=384, line=44, column=27, length=2, level=3, conditions={"65":333,"199":310,"217":297}, content=`->`
// T_STRING (244) code=262, line=44, column=29, length=4, level=3, conditions={"65":333,"199":310,"217":297}, content=`save`
// T_OPEN_PARENTHESIS (245) code=PHPCS_T_OPEN_PARENTHESIS, line=44, column=33, length=1, parenthesis_opener=245, parenthesis_closer=247, level=3, conditions={"65":333,"199":310,"217":297}, content=`(`
// T_VARIABLE (246) code=266, line=44, column=34, length=8, nested_parenthesis={"245":247}, level=3, conditions={"65":333,"199":310,"217":297}, content=`$usecase`
// T_CLOSE_PARENTHESIS (247) code=PHPCS_T_CLOSE_PARENTHESIS, line=44, column=42, length=1, parenthesis_opener=245, parenthesis_closer=247, level=3, conditions={"65":333,"199":310,"217":297}, content=`)`
// T_SEMICOLON (248) code=PHPCS_T_SEMICOLON, line=44, column=43, length=1, level=3, conditions={"65":333,"199":310,"217":297}, content=`;`
// T_WHITESPACE (249) code=392, line=44, column=44, length=0, level=3, conditions={"65":333,"199":310,"217":297}, content=`\n`
        endforeach;
// T_WHITESPACE (250) code=392, line=45, column=1, length=8, level=3, conditions={"65":333,"199":310,"217":297}, content=`        `
// T_ENDFOREACH (251) code=298, line=45, column=9, length=10, scope_condition=217, scope_opener=227, scope_closer=251, level=2, conditions={"65":333,"199":310}, content=`endforeach`
// T_SEMICOLON (252) code=PHPCS_T_SEMICOLON, line=45, column=19, length=1, level=2, conditions={"65":333,"199":310}, content=`;`
// T_WHITESPACE (253) code=392, line=45, column=20, length=0, level=2, conditions={"65":333,"199":310}, content=`\n`

It seems we just have to sniff for the T_ENDFOREACH, go to the scope_opener index and replace both.
Seems like it should work safely.

Any interest in a sniff for this in the community or maintainer group?

@dereuromark
Copy link
Contributor Author

I whipped sth up that seems to work fine already:
php-collective/code-sniffer#6

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

1 participant