{"id":13505085,"url":"https://github.com/ircmaxell/Tuli","last_synced_at":"2025-03-29T22:31:26.927Z","repository":{"id":56993385,"uuid":"38906346","full_name":"ircmaxell/Tuli","owner":"ircmaxell","description":"A static analysis engine","archived":false,"fork":false,"pushed_at":"2015-10-23T17:55:59.000Z","size":492,"stargazers_count":169,"open_issues_count":7,"forks_count":7,"subscribers_count":11,"default_branch":"master","last_synced_at":"2024-04-14T00:47:23.261Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ircmaxell.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-07-10T23:24:25.000Z","updated_at":"2024-02-27T03:38:01.000Z","dependencies_parsed_at":"2022-08-21T12:50:56.736Z","dependency_job_id":null,"html_url":"https://github.com/ircmaxell/Tuli","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ircmaxell%2FTuli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ircmaxell%2FTuli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ircmaxell%2FTuli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ircmaxell%2FTuli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ircmaxell","download_url":"https://codeload.github.com/ircmaxell/Tuli/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246254077,"owners_count":20747946,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T00:00:58.149Z","updated_at":"2025-03-29T22:31:24.916Z","avatar_url":"https://github.com/ircmaxell.png","language":"PHP","readme":"[![Build Status](https://travis-ci.org/ircmaxell/Tuli.svg)](https://travis-ci.org/ircmaxell/Tuli)\n\n## A static analysis engine...\n\nUsage:\n\n    bin/tuli analyze file1 file2 path\n\n## Installation\n\nInstall it as a composer dependency!!!\n\n`$ composer require ircmaxell/tuli dev-master`\n\nThen simply execute `vendor/bin/tuli` as normal\n\nOr check it out into its own project. Then `composer install` the dependencies:\n\n`$ composer install`\n\nThen simply `bin/tuli` to execute.\n\n## Example:\n\ncode.php:\n\n```php\n\u003c?php\n\n$a = 1.0;\n$b = 2;\n\n$c = foo($a, $b);\n\n$d = foo($b, $c);\n\nfunction foo(int $a, int $b): int {\n    if ($a \u003e $b) {\n        return $a + $b + 0.5;\n    }\n}\n```\n\nThen, in shell:\n\n    $ bin/tuli analyze code.php\n    Analyzing code.php\n    Determining Variable Types\n    Round 1 (15 unresolved variables out of 20)\n    .\n    Detecting Type Conversion Issues\n    Type mismatch on foo() argument 0, found float expecting int code.php:6\n    Type mismatch on foo() return value, found float expecting int code.php:12\n    Default return found for non-null type int code.php:10\n    Done\n\nThe three errors it found are:\n\n * `Type mismatch on foo() argument 0, found float expecting int code.php:6`\n\n \tMeaning that at code.php on line 6, you're passing a float to the first argument when it declared an integer\n\n * `Type mismatch on foo() return value, found float expecting int code.php:12`\n\n \tThe value that's being returned on line 12 is a float, but it was declared as an integer in the function signature.\n\n * `Default return found for non-null type int code.php:10`\n\n \tThere's a default return statement (not supplied) for a typed function\n\nThat's it!\n\n## Currently Supported Rules:\n\n * Function Argument Types\n\n    It will check all typed function arguments and determine if all calls to that function match the type.\n\n * Function Return Types\n\n    If the function's return value is typed, it will determine if the function actually returns that type.\n\n * Method Argument Types\n\n    It will check all calls to a method for every valid typehint permutation to determine if there's a possible mismatch.\n\nTodo:\n\n* A lot\n\n## Another example:\n\n```php\n\u003c?php\n\nclass A {\n    public function foo(int $a) : int {\n        return $a;\n    }\n}\n\nclass B extends A {\n    public function foo(float $a) : float {\n        return $a;\n    }\n}\n\nclass C extends B {\n    public function foo(int $a) : int {\n        return $a;\n    }\n}\n\nfunction foo(A $a) : int {\n    return $a-\u003efoo(1.0);\n}\n```\n\nRunning:\n\n    $ bin/tuli analyze code.php\n    Analyzing code.php\n\n    Determining Variable Types\n    Round 1 (5 unresolved variables out of 7)\n\n    Round 2 (3 unresolved variables out of 7)\n\n    Detecting Type Conversion Issues\n    Detecting Function Argument Errors\n    Detecting Function Return Errors\n    Type mismatch on foo() return value, found float expecting int code.php:22\n    Detecting Method Argument Errors\n    Type mismatch on A-\u003efoo() argument 0, found float expecting int code.php:22\n    Type mismatch on C-\u003efoo() argument 0, found float expecting int code.php:22\n    Done\n\nAgain, it found 3 errors:\n\n * `Type mismatch on foo() return value, found float expecting int code.php:22`\n\n    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 -\u003efoo() directly can result in a type error.\n\n * `Type mismatch on A-\u003efoo() argument 0, found float expecting int code.php:22`\n * `Type mismatch on C-\u003efoo() argument 0, found float expecting int code.php:22`\n\n    We know that if you use type A or C, you're trying to pass a float to something that declares an integer.\n\n","funding_links":[],"categories":["Standalone","Programming Languages"],"sub_categories":["Bugs finders"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fircmaxell%2FTuli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fircmaxell%2FTuli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fircmaxell%2FTuli/lists"}