Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into strict_types
Browse files Browse the repository at this point in the history
  • Loading branch information
danog committed Oct 19, 2023
2 parents f894cde + 24168f6 commit ec959e9
Show file tree
Hide file tree
Showing 199 changed files with 3,758 additions and 1,547 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/bcc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
env:
fail-fast: true

- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-phar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
env:
fail-fast: true

- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0 # required for composer to automatically detect root package version

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
env:
fail-fast: true

- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Get Composer Cache Directories
id: composer-cache
Expand Down Expand Up @@ -63,7 +63,7 @@ jobs:
env:
fail-fast: true

- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Get Composer Cache Directories
id: composer-cache
Expand Down Expand Up @@ -148,7 +148,7 @@ jobs:
env:
fail-fast: true

- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Get Composer Cache Directories
id: composer-cache
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/shepherd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
Expand Down
7 changes: 6 additions & 1 deletion .github/workflows/windows-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,12 @@ jobs:
env:
fail-fast: true

- uses: actions/checkout@v3
- name: PHP Version
run: |
php -v
php -r 'var_dump(PHP_VERSION_ID);'
- uses: actions/checkout@v4

- name: Get Composer Cache Directories
id: composer-cache
Expand Down
9 changes: 9 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@

- The minimum PHP version was raised to PHP 8.1.17.

- [BC] The configuration settings `ignoreInternalFunctionFalseReturn` and `ignoreInternalFunctionNullReturn` are now defaulted to `false`

- [BC] Switched the internal representation of `list<T>` and `non-empty-list<T>` from the TList and TNonEmptyList classes to an unsealed list shape: the TList, TNonEmptyList and TCallableList classes were removed.
Nothing will change for users: the `list<T>` and `non-empty-list<T>` syntax will remain supported and its semantics unchanged.
Psalm 5 already deprecates the `TList`, `TNonEmptyList` and `TCallableList` classes: use `\Psalm\Type::getListAtomic`, `\Psalm\Type::getNonEmptyListAtomic` and `\Psalm\Type::getCallableListAtomic` to instantiate list atomics, or directly instantiate TKeyedArray objects with `is_list=true` where appropriate.

- [BC] The only optional boolean parameter of `TKeyedArray::getGenericArrayType` was removed, and was replaced with a string parameter with a different meaning.

- [BC] The `TDependentListKey` type was removed and replaced with an optional property of the `TIntRange` type.
- [BC] `TCallableArray` and `TCallableList` removed and replaced with `TCallableKeyedArray`.

- [BC] Value of constant `Psalm\Type\TaintKindGroup::ALL_INPUT` changed to reflect new `TaintKind::INPUT_SLEEP` and `TaintKind::INPUT_XPATH` have been added. Accordingly, default values for `$taint` parameters of `Psalm\Codebase::addTaintSource()` and `Psalm\Codebase::addTaintSink()` have been changed as well.

- [BC] Property `Config::$shepherd_host` was replaced with `Config::$shepherd_endpoint`

Expand All @@ -33,6 +38,10 @@

- [BC] `strict_types` is now applied to all files of the Psalm codebase.

- [BC] Properties `Psalm\Type\Atomic\TLiteralFloat::$value` and `Psalm\Type\Atomic\TLiteralInt::$value` became typed (`float` and `int` respectively)

- [BC] Property `Psalm\Storage\EnumCaseStorage::$value` changed from `int|string|null` to `TLiteralInt|TLiteralString|null`

# Upgrading from Psalm 4 to Psalm 5
## Changed

Expand Down
6 changes: 3 additions & 3 deletions bin/update-property-map.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@ function extractClassesFromStatements(array $statements): array
foreach ($files as $file) {
$contents = file_get_contents($file);
// FIXME: find a way to ignore custom entities, for now we strip them.
$contents = preg_replace('#&[a-zA-Z\d.\-_]+;#', '', $contents);
$contents = preg_replace('#%[a-zA-Z\d.\-_]+;#', '', $contents);
$contents = preg_replace('#<!ENTITY[^>]+>#', '', $contents);
$contents = (string) preg_replace('#&[a-zA-Z\d.\-_]+;#', '', $contents);
$contents = (string) preg_replace('#%[a-zA-Z\d.\-_]+;#', '', $contents);
$contents = (string) preg_replace('#<!ENTITY[^>]+>#', '', $contents);
try {
$simple = new SimpleXMLElement($contents);
} catch (Throwable $exception) {
Expand Down
15 changes: 12 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vimeo/psalm",
"type": "library",
"type": "project",
"description": "A static analysis tool for finding errors in PHP applications",
"keywords": [
"php",
Expand Down Expand Up @@ -39,6 +39,9 @@
"symfony/console": "^4.1.6 || ^5.0 || ^6.0",
"symfony/filesystem": "^5.4 || ^6.0"
},
"conflict": {
"nikic/php-parser": "4.17.0"
},
"provide": {
"psalm/psalm": "self.version"
},
Expand Down Expand Up @@ -74,7 +77,8 @@
},
"extra": {
"branch-alias": {
"dev-master": "5.x-dev",
"dev-master": "6.x-dev",
"dev-5.x": "5.x-dev",
"dev-4.x": "4.x-dev",
"dev-3.x": "3.x-dev",
"dev-2.x": "2.x-dev",
Expand Down Expand Up @@ -131,10 +135,15 @@
"scripts-descriptions": {
"cs": "Checks that the code conforms to the coding standard.",
"cs-fix": "Automatically correct coding standard violations.",
"lint": "Runs unit tests.",
"lint": "Lint php files.",
"phpunit": "Runs unit tests in parallel.",
"phpunit-std": "Runs unit tests.",
"psalm": "Runs static analysis.",
"tests": "Runs all available tests."
},
"support": {
"docs": "https://psalm.dev/docs",
"issues": "https://github.com/vimeo/psalm/issues",
"source": "https://github.com/vimeo/psalm"
}
}
8 changes: 6 additions & 2 deletions config.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@
<xs:attribute name="findUnusedBaselineEntry" type="xs:boolean" default="false" />
<xs:attribute name="hideExternalErrors" type="xs:boolean" default="false" />
<xs:attribute name="hoistConstants" type="xs:boolean" default="false" />
<xs:attribute name="ignoreInternalFunctionFalseReturn" type="xs:boolean" default="true" />
<xs:attribute name="ignoreInternalFunctionNullReturn" type="xs:boolean" default="true" />
<xs:attribute name="ignoreInternalFunctionFalseReturn" type="xs:boolean" default="false" />
<xs:attribute name="ignoreInternalFunctionNullReturn" type="xs:boolean" default="false" />
<xs:attribute name="includePhpVersionsInErrorBaseline" type="xs:boolean" default="false" />
<xs:attribute name="inferPropertyTypesFromConstructor" type="xs:boolean" default="true" />
<xs:attribute name="memoizeMethodCallResults" type="xs:boolean" default="false" />
Expand Down Expand Up @@ -230,6 +230,7 @@
<xs:element name="DuplicateFunction" type="IssueHandlerType" minOccurs="0" />
<xs:element name="DuplicateMethod" type="MethodIssueHandlerType" minOccurs="0" />
<xs:element name="DuplicateParam" type="IssueHandlerType" minOccurs="0" />
<xs:element name="DuplicateProperty" type="PropertyIssueHandlerType" minOccurs="0" />
<xs:element name="EmptyArrayAccess" type="IssueHandlerType" minOccurs="0" />
<xs:element name="ExtensionRequirementViolation" type="IssueHandlerType" minOccurs="0" />
<xs:element name="FalsableReturnStatement" type="IssueHandlerType" minOccurs="0" />
Expand Down Expand Up @@ -350,6 +351,7 @@
<xs:element name="NonInvariantDocblockPropertyType" type="IssueHandlerType" minOccurs="0" />
<xs:element name="NonInvariantPropertyType" type="IssueHandlerType" minOccurs="0" />
<xs:element name="NonStaticSelfCall" type="IssueHandlerType" minOccurs="0" />
<xs:element name="NonVariableReferenceReturn" type="IssueHandlerType" minOccurs="0" />
<xs:element name="NoValue" type="IssueHandlerType" minOccurs="0" />
<xs:element name="NullableReturnStatement" type="IssueHandlerType" minOccurs="0" />
<xs:element name="NullArgument" type="ArgumentIssueHandlerType" minOccurs="0" />
Expand Down Expand Up @@ -438,12 +440,14 @@
<xs:element name="TaintedInput" type="IssueHandlerType" minOccurs="0" />
<xs:element name="TaintedLdap" type="IssueHandlerType" minOccurs="0" />
<xs:element name="TaintedShell" type="IssueHandlerType" minOccurs="0" />
<xs:element name="TaintedSleep" type="IssueHandlerType" minOccurs="0" />
<xs:element name="TaintedSql" type="IssueHandlerType" minOccurs="0" />
<xs:element name="TaintedSSRF" type="IssueHandlerType" minOccurs="0" />
<xs:element name="TaintedSystemSecret" type="IssueHandlerType" minOccurs="0" />
<xs:element name="TaintedTextWithQuotes" type="IssueHandlerType" minOccurs="0" />
<xs:element name="TaintedUnserialize" type="IssueHandlerType" minOccurs="0" />
<xs:element name="TaintedUserSecret" type="IssueHandlerType" minOccurs="0" />
<xs:element name="TaintedXpath" type="IssueHandlerType" minOccurs="0" />
<xs:element name="TooFewArguments" type="ArgumentIssueHandlerType" minOccurs="0" />
<xs:element name="TooManyArguments" type="ArgumentIssueHandlerType" minOccurs="0" />
<xs:element name="TooManyTemplateParams" type="FunctionIssueHandlerType" minOccurs="0" />
Expand Down
28 changes: 14 additions & 14 deletions dictionaries/CallMap.php
Original file line number Diff line number Diff line change
Expand Up @@ -1307,8 +1307,8 @@
'date_create_immutable' => ['DateTimeImmutable|false', 'datetime='=>'string', 'timezone='=>'?DateTimeZone'],
'date_create_immutable_from_format' => ['DateTimeImmutable|false', 'format'=>'string', 'datetime'=>'string', 'timezone='=>'?DateTimeZone'],
'date_date_set' => ['DateTime', 'object'=>'DateTime', 'year'=>'int', 'month'=>'int', 'day'=>'int'],
'date_default_timezone_get' => ['string'],
'date_default_timezone_set' => ['bool', 'timezoneId'=>'string'],
'date_default_timezone_get' => ['non-empty-string'],
'date_default_timezone_set' => ['bool', 'timezoneId'=>'non-empty-string'],
'date_diff' => ['DateInterval', 'baseObject'=>'DateTimeInterface', 'targetObject'=>'DateTimeInterface', 'absolute='=>'bool'],
'date_format' => ['string', 'object'=>'DateTimeInterface', 'format'=>'string'],
'date_get_last_errors' => ['array{warning_count:int,warnings:array<int,string>,error_count:int,errors:array<int,string>}|false'],
Expand Down Expand Up @@ -1390,11 +1390,11 @@
'DateTimeInterface::getTimezone' => ['DateTimeZone|false'],
'DateTimeInterface::__serialize' => ['array'],
'DateTimeInterface::__unserialize' => ['void', 'data'=>'array'],
'DateTimeZone::__construct' => ['void', 'timezone'=>'string'],
'DateTimeZone::__construct' => ['void', 'timezone'=>'non-empty-string'],
'DateTimeZone::__set_state' => ['DateTimeZone', 'array'=>'array'],
'DateTimeZone::__wakeup' => ['void'],
'DateTimeZone::getLocation' => ['array|false'],
'DateTimeZone::getName' => ['string'],
'DateTimeZone::getName' => ['non-empty-string'],
'DateTimeZone::getOffset' => ['int', 'datetime'=>'DateTimeInterface'],
'DateTimeZone::getTransitions' => ['list<array{ts: int, time: string, offset: int, isdst: bool, abbr: string}>|false', 'timestampBegin='=>'int', 'timestampEnd='=>'int'],
'DateTimeZone::listAbbreviations' => ['array<string, list<array{dst: bool, offset: int, timezone_id: string|null}>>'],
Expand Down Expand Up @@ -1679,10 +1679,10 @@
'DOMDocument::getElementsByTagName' => ['DOMNodeList', 'qualifiedName'=>'string'],
'DOMDocument::getElementsByTagNameNS' => ['DOMNodeList', 'namespace'=>'?string', 'localName'=>'string'],
'DOMDocument::importNode' => ['DOMNode|false', 'node'=>'DOMNode', 'deep='=>'bool'],
'DOMDocument::load' => ['DOMDocument|bool', 'filename'=>'string', 'options='=>'int'],
'DOMDocument::load' => ['bool', 'filename'=>'string', 'options='=>'int'],
'DOMDocument::loadHTML' => ['bool', 'source'=>'non-empty-string', 'options='=>'int'],
'DOMDocument::loadHTMLFile' => ['bool', 'filename'=>'string', 'options='=>'int'],
'DOMDocument::loadXML' => ['DOMDocument|bool', 'source'=>'non-empty-string', 'options='=>'int'],
'DOMDocument::loadXML' => ['bool', 'source'=>'non-empty-string', 'options='=>'int'],
'DOMDocument::normalizeDocument' => ['void'],
'DOMDocument::registerNodeClass' => ['bool', 'baseClass'=>'string', 'extendedClass'=>'?string'],
'DOMDocument::relaxNGValidate' => ['bool', 'filename'=>'string'],
Expand Down Expand Up @@ -2942,7 +2942,7 @@
'gc_enable' => ['void'],
'gc_enabled' => ['bool'],
'gc_mem_caches' => ['int'],
'gc_status' => ['array{runs:int,collected:int,threshold:int,roots:int,running:bool,protected:bool,full:bool,buffer_size:int}'],
'gc_status' => ['array{runs:int,collected:int,threshold:int,roots:int,running:bool,protected:bool,full:bool,buffer_size:int,application_time:float,collector_time:float,destructor_time:float,free_time:float}'],
'gd_info' => ['array'],
'gearman_bugreport' => [''],
'gearman_client_add_options' => ['', 'client_object'=>'', 'option'=>''],
Expand Down Expand Up @@ -7825,10 +7825,10 @@
'mysqli::begin_transaction' => ['bool', 'flags='=>'int', 'name='=>'?string'],
'mysqli::change_user' => ['bool', 'username'=>'string', 'password'=>'string', 'database'=>'?string'],
'mysqli::character_set_name' => ['string'],
'mysqli::close' => ['bool'],
'mysqli::close' => ['true'],
'mysqli::commit' => ['bool', 'flags='=>'int', 'name='=>'?string'],
'mysqli::connect' => ['bool', 'hostname='=>'string|null', 'username='=>'string|null', 'password='=>'string|null', 'database='=>'string|null', 'port='=>'int|null', 'socket='=>'string|null'],
'mysqli::debug' => ['bool', 'options'=>'string'],
'mysqli::debug' => ['true', 'options'=>'string'],
'mysqli::dump_debug_info' => ['bool'],
'mysqli::escape_string' => ['string', 'string'=>'string'],
'mysqli::execute_query' => ['mysqli_result|bool', 'query'=>'non-empty-string', 'params='=>'list<mixed>|null'],
Expand Down Expand Up @@ -7857,7 +7857,7 @@
'mysqli::select_db' => ['bool', 'database'=>'string'],
'mysqli::set_charset' => ['bool', 'charset'=>'string'],
'mysqli::set_opt' => ['bool', 'option'=>'int', 'value'=>'string|int'],
'mysqli::ssl_set' => ['bool', 'key'=>'?string', 'certificate'=>'?string', 'ca_certificate'=>'?string', 'ca_path'=>'?string', 'cipher_algos'=>'?string'],
'mysqli::ssl_set' => ['true', 'key'=>'?string', 'certificate'=>'?string', 'ca_certificate'=>'?string', 'ca_path'=>'?string', 'cipher_algos'=>'?string'],
'mysqli::stat' => ['string|false'],
'mysqli::stmt_init' => ['mysqli_stmt'],
'mysqli::store_result' => ['mysqli_result|false', 'mode='=>'int'],
Expand Down Expand Up @@ -7903,7 +7903,7 @@
'mysqli_fetch_object' => ['object|false|null', 'result'=>'mysqli_result', 'class='=>'string', 'constructor_args='=>'array'],
'mysqli_fetch_row' => ['list<null|int|float|string>|false|null', 'result'=>'mysqli_result'],
'mysqli_field_count' => ['int', 'mysql'=>'mysqli'],
'mysqli_field_seek' => ['bool', 'result'=>'mysqli_result', 'index'=>'int'],
'mysqli_field_seek' => ['true', 'result'=>'mysqli_result', 'index'=>'int'],
'mysqli_field_tell' => ['int', 'result'=>'mysqli_result'],
'mysqli_free_result' => ['void', 'result'=>'mysqli_result'],
'mysqli_get_cache_stats' => ['array|false'],
Expand Down Expand Up @@ -7957,7 +7957,7 @@
'mysqli_result::fetch_fields' => ['list<object{name:non-empty-string,orgname:string,table:string,orgtable:string,max_length:int,length:int,charsetnr:int,flags:int,type:int,decimals:int,db:string,def:string,catalog:string}>'],
'mysqli_result::fetch_object' => ['object|false|null', 'class='=>'string', 'constructor_args='=>'array'],
'mysqli_result::fetch_row' => ['list<null|int|float|string>|false|null'],
'mysqli_result::field_seek' => ['bool', 'index'=>'int'],
'mysqli_result::field_seek' => ['true', 'index'=>'int'],
'mysqli_result::free' => ['void'],
'mysqli_result::free_result' => ['void'],
'mysqli_rollback' => ['bool', 'mysql'=>'mysqli', 'flags='=>'int', 'name='=>'?string'],
Expand All @@ -7981,7 +7981,7 @@
'mysqli_stmt::attr_set' => ['bool', 'attribute'=>'int', 'value'=>'int'],
'mysqli_stmt::bind_param' => ['bool', 'types'=>'string', '&var'=>'mixed', '&...vars='=>'mixed'],
'mysqli_stmt::bind_result' => ['bool', '&w_var1'=>'', '&...w_vars='=>''],
'mysqli_stmt::close' => ['bool'],
'mysqli_stmt::close' => ['true'],
'mysqli_stmt::data_seek' => ['void', 'offset'=>'int'],
'mysqli_stmt::execute' => ['bool', 'params='=>'list<mixed>|null'],
'mysqli_stmt::fetch' => ['bool|null'],
Expand Down Expand Up @@ -12987,7 +12987,7 @@
'strpbrk' => ['string|false', 'string'=>'string', 'characters'=>'string'],
'strpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'],
'strptime' => ['array|false', 'timestamp'=>'string', 'format'=>'string'],
'strrchr' => ['string|false', 'haystack'=>'string', 'needle'=>'string'],
'strrchr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool'],
'strrev' => ['string', 'string'=>'string'],
'strripos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'],
'strrpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'],
Expand Down
24 changes: 24 additions & 0 deletions dictionaries/CallMap_80_delta.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,22 @@
'old' => ['DOMNodeList', 'namespace'=>'string', 'localName'=>'string'],
'new' => ['DOMNodeList', 'namespace'=>'?string', 'localName'=>'string'],
],
'DOMDocument::load' => [
'old' => ['DOMDocument|bool', 'filename'=>'string', 'options='=>'int'],
'new' => ['bool', 'filename'=>'string', 'options='=>'int'],
],
'DOMDocument::loadXML' => [
'old' => ['DOMDocument|bool', 'source'=>'non-empty-string', 'options='=>'int'],
'new' => ['bool', 'source'=>'non-empty-string', 'options='=>'int'],
],
'DOMDocument::loadHTML' => [
'old' => ['DOMDocument|bool', 'source'=>'non-empty-string', 'options='=>'int'],
'new' => ['bool', 'source'=>'non-empty-string', 'options='=>'int'],
],
'DOMDocument::loadHTMLFile' => [
'old' => ['DOMDocument|bool', 'filename'=>'string', 'options='=>'int'],
'new' => ['bool', 'filename'=>'string', 'options='=>'int'],
],
'DOMImplementation::createDocument' => [
'old' => ['DOMDocument|false', 'namespace='=>'string', 'qualifiedName='=>'string', 'doctype='=>'DOMDocumentType'],
'new' => ['DOMDocument|false', 'namespace='=>'?string', 'qualifiedName='=>'string', 'doctype='=>'?DOMDocumentType'],
Expand Down Expand Up @@ -224,6 +240,14 @@
'old' => ['string', 'locale'=>'string', 'displayLocale='=>'string'],
'new' => ['string', 'locale'=>'string', 'displayLocale='=>'?string'],
],
'mysqli_field_seek' => [
'old' => ['bool', 'result'=>'mysqli_result', 'index'=>'int'],
'new' => ['true', 'result'=>'mysqli_result', 'index'=>'int'],
],
'mysqli_result::field_seek' => [
'old' => ['bool', 'index'=>'int'],
'new' => ['true', 'index'=>'int'],
],
'mysqli_stmt::__construct' => [
'old' => ['void', 'mysql'=>'mysqli', 'query='=>'string'],
'new' => ['void', 'mysql'=>'mysqli', 'query='=>'?string'],
Expand Down
4 changes: 4 additions & 0 deletions dictionaries/CallMap_81_delta.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@
'old' => ['int|false', 'fields'=>'array<array-key, null|scalar|Stringable>', 'separator='=>'string', 'enclosure='=>'string', 'escape='=>'string'],
'new' => ['int|false', 'fields'=>'array<array-key, null|scalar|Stringable>', 'separator='=>'string', 'enclosure='=>'string', 'escape='=>'string', 'eol='=>'string'],
],
'hash_pbkdf2' => [
'old' => ['non-empty-string', 'algo'=>'string', 'password'=>'string', 'salt'=>'string', 'iterations'=>'int', 'length='=>'int', 'binary='=>'bool'],
'new' => ['non-empty-string', 'algo'=>'string', 'password'=>'string', 'salt'=>'string', 'iterations'=>'int', 'length='=>'int', 'binary='=>'bool', 'options=' => 'array'],
],
'finfo_buffer' => [
'old' => ['string|false', 'finfo'=>'resource', 'string'=>'string', 'flags='=>'int', 'context='=>'resource'],
'new' => ['string|false', 'finfo'=>'finfo', 'string'=>'string', 'flags='=>'int', 'context='=>'resource'],
Expand Down
Loading

0 comments on commit ec959e9

Please sign in to comment.