SanderRonde / phpstan-vscode

PHPStan plugin for VSCode
https://marketplace.visualstudio.com/items?itemName=SanderRonde.phpstan-vscode
MIT License
37 stars 7 forks source link

phpstan runs twice if used with a code formatter #38

Closed kdevan closed 11 months ago

kdevan commented 11 months ago

Just thought I'd see if anyone else runs into this and if anyone can find a solution. Looking at the logs I noticed that phpstan is running twice when used with a code formatter. In my case I also use Laravel Pint for code formatting. It does make sense because on save phpstan runs, then Laravel Pint runs which saves the file again, so phpstan runs again after that.

I found that it's possible to choose the order of code actions using this feature:

"editor.codeActionsOnSave": [
  "source.organizeImports",
  "source.fixAll.eslint"
]

But this would require adding a custom code action for phpstan I believe. Kind of like this extension does.

Has anyone else run into this and is there any other solution?

SanderRonde commented 11 months ago

Ah this makes sense... I can't really think of a great solution. I could delay the check until a file has "settled" but there's really no telling how long a formatting operation is going to take. On top of that it would require me to no longer use the standard vscode file-change API which would suck.

I think the easiest solution for now indeed is to use editor.codeActionsOnSave and to use phpstan.scanFileForErrors as the action. It's not as great as the normal way since this does treat it like a force-check but it's probably better than running it twice..

kdevan commented 11 months ago

It seems phpstan.scanFileForErrors will not run if phpstan.enabled is set to false. If phpstan.enabled is set to true then it is still running twice. Does this mean that phpstan and the watcher are both enabled and disabled together using this option? It seems like there may need to be a way to separate the two, if I'm understanding correctly.

SanderRonde commented 11 months ago

Hmm are you sure? It runs just fine for me with phpstan.enabled set to false. Only the watcher should be linked to phpstan.enabled. What do the logs in the output panel say?

kdevan commented 11 months ago

Just to update, I've been trying to get this to work. That is good news that it's already separated, that definitely should make this possible, so I've continued troubleshooting on my end.

From what I've read, editor.formatOnSave is supposed to be set to false for editor.codeActionsOnSave to work. But when I set it to false neither pint or phpstan are running at all. No logs or anything. And when I set it to true, it's just the same issue. So I think this might just be something on my end because editor.codeActionsOnSave should at least be running. I'll keep trying things and testing on my end to see what I can figure out.

Thanks for all the information that's making this possible!

SanderRonde commented 11 months ago

Sounds like editor.codeActionsOnSave isn't properly populated right? Does it contain the phpstan.scanFileForErrors command (and the pint one)?

kdevan commented 11 months ago

Hmm good point. I had this:

"editor.formatOnSave": false,
"editor.codeActionsOnSave": [
  "source.fixAll",
  "phpstan.scanFileForErrors"
]

I found the pint command and tried this:

"editor.formatOnSave": false,
"editor.codeActionsOnSave": [
  "laravel-pint.format",
  "phpstan.scanFileForErrors"
]

Still though, nothing runs at all. I'm going to continue testing this a bit now though. I appreciate the continued guidance, definitely on the right track.

Edit: Ah looks like commands may need to be source actions.. Going to keep digging here a bit and see if I can find a way to do that.

kdevan commented 11 months ago

Ok, a bit hacky but got this working!

First I created a tasks.json file which goes along with the other files in the .vscode folder. Mine looks like this:

{
  // https://code.visualstudio.com/docs/editor/tasks#_custom-tasks
  "version": "2.0.0",
  "tasks": [
    {
      "label": "phpstan-scanFile",
      "command": "${command:phpstan.scanFileForErrors}"
    },
    {
      "label": "laravel-pint-formatFile",
      "command": "${command:laravel-pint.format}"
    }
  ]
}

Then I needed to use this plugin which lets you run tasks on save.

Then in settings.json I have this (adding all the relevant settings in case it's useful for someone else):

"editor.defaultFormatter": "open-southeners.laravel-pint",
"laravel-pint.enable": true,
"phpstan.enabled": false,
"editor.formatOnSave": false,
"triggerTaskOnSave.tasks": {
  "laravel-pint-formatFile": ["*.php"],
  "phpstan-scanFile": ["*.php"]
},

This is perfect for my needs and things are running much smoother now. Couldn't have figured this out without your help, thank you!