ircmaxell / tuli
A Static Analyzer for PHP
Installs: 351
Dependents: 0
Suggesters: 0
Security: 0
Stars: 171
Watchers: 11
Forks: 7
Open Issues: 7
Requires
- php: >=5.5
- cilex/cilex: 1.*
- ircmaxell/php-cfg: dev-master
- ircmaxell/php-types: dev-master
Requires (Dev)
- fabpot/php-cs-fixer: 1.*
- phpunit/phpunit: ^4.7
This package is auto-updated.
Last update: 2024-12-20 01:24:05 UTC
README
A static analysis engine...
Usage:
bin/tuli analyze file1 file2 path
Installation
Install it as a composer dependency!!!
$ composer require ircmaxell/tuli dev-master
Then simply execute vendor/bin/tuli
as normal
Or check it out into its own project. Then composer install
the dependencies:
$ composer install
Then simply bin/tuli
to execute.
Example:
code.php:
<?php $a = 1.0; $b = 2; $c = foo($a, $b); $d = foo($b, $c); function foo(int $a, int $b): int { if ($a > $b) { return $a + $b + 0.5; } }
Then, in shell:
$ bin/tuli analyze code.php
Analyzing code.php
Determining Variable Types
Round 1 (15 unresolved variables out of 20)
.
Detecting Type Conversion Issues
Type mismatch on foo() argument 0, found float expecting int code.php:6
Type mismatch on foo() return value, found float expecting int code.php:12
Default return found for non-null type int code.php:10
Done
The three errors it found are:
-
Type mismatch on foo() argument 0, found float expecting int code.php:6
Meaning that at code.php on line 6, you're passing a float to the first argument when it declared an integer
-
Type mismatch on foo() return value, found float expecting int code.php:12
The value that's being returned on line 12 is a float, but it was declared as an integer in the function signature.
-
Default return found for non-null type int code.php:10
There's a default return statement (not supplied) for a typed function
That's it!
Currently Supported Rules:
-
Function Argument Types
It will check all typed function arguments and determine if all calls to that function match the type.
-
Function Return Types
If the function's return value is typed, it will determine if the function actually returns that type.
-
Method Argument Types
It will check all calls to a method for every valid typehint permutation to determine if there's a possible mismatch.
Todo:
- A lot
Another example:
<?php class A { public function foo(int $a) : int { return $a; } } class B extends A { public function foo(float $a) : float { return $a; } } class C extends B { public function foo(int $a) : int { return $a; } } function foo(A $a) : int { return $a->foo(1.0); }
Running:
$ bin/tuli analyze code.php
Analyzing code.php
Determining Variable Types
Round 1 (5 unresolved variables out of 7)
Round 2 (3 unresolved variables out of 7)
Detecting Type Conversion Issues
Detecting Function Argument Errors
Detecting Function Return Errors
Type mismatch on foo() return value, found float expecting int code.php:22
Detecting Method Argument Errors
Type mismatch on A->foo() argument 0, found float expecting int code.php:22
Type mismatch on C->foo() argument 0, found float expecting int code.php:22
Done
Again, it found 3 errors:
-
Type mismatch on foo() return value, found float expecting int code.php:22
It looked at all possible
A::foo()
method definitions (A::foo, B::foo, C::foo), and it detmermined that the general return type is float (since type widening allows int to be passed to float, but not the other way around). Therefore, returning ->foo() directly can result in a type error. -
Type mismatch on A->foo() argument 0, found float expecting int code.php:22
-
Type mismatch on C->foo() argument 0, found float expecting int code.php:22
We know that if you use type A or C, you're trying to pass a float to something that declares an integer.