1
0
mirror of https://github.com/danog/psalm.git synced 2024-12-03 10:07:52 +01:00
psalm/docs/manipulating_code/fixing.md
2019-06-09 01:07:17 -04:00

429 lines
6.0 KiB
Markdown

# Fixing Code
Psalm is good at finding potential issues in large codebases, but once found, it can be something of a gargantuan task to fix all the issues.
It comes with a tool, called Psalter, that helps you fix code.
You can either run it via its binary
```
vendor/bin/psalter [args]
```
or via Psalm's binary:
```
vendor/bin/psalm --alter [args]
```
## Safety features
Updating code is inherently risky, doing so automatically is even more so. I've added a few features to make it a little more reassuring:
- To see what changes Psalter will make ahead of time, you can run it with `--dry-run`.
- You can target particular versions of PHP via `--php-version`, so that (for example) you don't add nullable typehints to PHP 7.0 code, or any typehints at all to PHP 5.6 code. `--php-version` defaults to your current version.
- it has a `--safe-types` mode that will only update PHP 7 return typehints with information Psalm has gathered from non-docblock sources of type information (e.g. typehinted params, `instanceof` checks, other return typehints etc.)
## Plugins
You can pass in your own manipulation plugins e.g.
```bash
vendor/bin/psalter --plugin=vendor/vimeo/psalm/examples/ClassUnqualifier.php --dry-run
```
The above example plugin converts all unnecessarily qualified classnames in your code to shorter aliased versions.
## Supported fixes
This initial release provides support for the following alterations, corresponding to the names of issues Psalm finds.
To fix all of these at once, run `vendor/bin/psalter --issues=all`
### MissingReturnType
Running `vendor/bin/psalter --issues=MissingReturnType --php-version=7.0` on
```php
function foo() {
return "hello";
}
```
gives
```php
function foo() : string {
return "hello";
}
```
and running `vendor/bin/psalter --issues=MissingReturnType --php-version=5.6` on
```php
function foo() {
return "hello";
}
```
gives
```php
/**
* @return string
*/
function foo() {
return "hello";
}
```
### MissingClosureReturnType
As above, except for closures
### InvalidReturnType
Running `vendor/bin/psalter --issues=InvalidReturnType` on
```php
/**
* @return int
*/
function foo() {
return "hello";
}
```
gives
```php
/**
* @return string
*/
function foo() {
return "hello";
}
```
There's also support for return typehints, so running `vendor/bin/psalter --issues=InvalidReturnType` on
```php
function foo() : int {
return "hello";
}
```
gives
```php
function foo() : string {
return "hello";
}
```
### InvalidNullableReturnType
Running `vendor/bin/psalter --issues=InvalidNullableReturnType --php-version=7.1` on
```php
function foo() : string {
return rand(0, 1) ? "hello" : null;
}
```
gives
```php
function foo() : ?string {
return rand(0, 1) ? "hello" : null;
}
```
and running `vendor/bin/psalter --issues=InvalidNullableReturnType --php-version=7.0` on
```php
function foo() : string {
return rand(0, 1) ? "hello" : null;
}
```
gives
```php
/**
* @return string|null
*/
function foo() {
return rand(0, 1) ? "hello" : null;
}
```
### InvalidFalsableReturnType
Running `vendor/bin/psalter --issues=InvalidFalsableReturnType` on
```php
function foo() : string {
return rand(0, 1) ? "hello" : false;
}
```
gives
```php
/**
* @return string|false
*/
function foo() {
return rand(0, 1) ? "hello" : false;
}
```
### MissingParamType
Running `vendor/bin/psalter --issues=MissingParamType` on
```php
class C {
public static function foo($s) : void {
echo $s;
}
}
C::foo("hello");
```
gives
```php
class C {
/**
* @param string $s
*/
public static function foo($s) : void {
echo $s;
}
}
C::foo("hello");
```
### MismatchingDocblockParamType
Given
```php
class A {}
class B extends A {}
class C extends A {}
class D {}
```
running `vendor/bin/psalter --issues=MismatchingDocblockParamType` on
```php
/**
* @param B|C $first
* @param D $second
*/
function foo(A $first, A $second) : void {}
```
gives
```php
/**
* @param B|C $first
* @param A $second
*/
function foo(A $first, A $second) : void {}
```
### MismatchingDocblockReturnType
Running `vendor/bin/psalter --issues=MismatchingDocblockReturnType` on
```php
/**
* @return int
*/
function foo() : string {
return "hello";
}
```
gives
```php
/**
* @return string
*/
function foo() : string {
return "hello";
}
```
### LessSpecificReturnType
Running `vendor/bin/psalter --issues=LessSpecificReturnType` on
```php
function foo() : ?string {
return "hello";
}
```
gives
```php
function foo() : string {
return "hello";
}
```
### PossiblyUndefinedVariable
Running `vendor/bin/psalter --issues=PossiblyUndefinedVariable` on
```php
function foo()
{
if (rand(0, 1)) {
$a = 5;
}
echo $a;
}
```
gives
```php
function foo()
{
$a = null;
if (rand(0, 1)) {
$a = 5;
}
echo $a;
}
```
### PossiblyUndefinedGlobalVariable
Running `vendor/bin/psalter --issues=PossiblyUndefinedGlobalVariable` on
```php
if (rand(0, 1)) {
$a = 5;
}
echo $a;
```
gives
```php
$a = null;
if (rand(0, 1)) {
$a = 5;
}
echo $a;
```
### UnusedMethod
This removes private unused methods.
Running `vendor/bin/psalter --issues=UnusedMethod` on
```php
class A {
private function foo() : void {}
}
new A();
```
gives
```php
class A {
}
new A();
```
### PossiblyUnusedMethod
This removes protected/public unused methods.
Running `vendor/bin/psalter --issues=PossiblyUnusedMethod` on
```php
class A {
protected function foo() : void {}
public function bar() : void {}
}
new A();
```
gives
```php
class A {
}
new A();
```
### UnusedProperty
This removes private unused properties.
Running `vendor/bin/psalter --issues=UnusedProperty` on
```php
class A {
/** @var string */
private $foo;
}
new A();
```
gives
```php
class A {
}
new A();
```
### PossiblyUnusedProperty
This removes protected/public unused properties.
Running `vendor/bin/psalter --issues=PossiblyUnusedProperty` on
```php
class A {
/** @var string */
public $foo;
/** @var string */
protected $bar;
}
new A();
```
gives
```php
class A {
}
new A();
```