* Move psalm entry-point to a Cli command class
* Moved psalter to the CLI command class
* Moved psalm-language-server to the CLI command class
* Moved psalm-refactor to the CLI command class
* Moved psalm_plugin to the CLI command class
* Use CLI commands directly and deprecate trampolines
* Require CLI commands directly and don't use trampolines
* Announce isAbsolutePath() removal
* Deprecate \Psalm\requireAutoloaders() function
* Deprecate \Psalm\getVendorDir() function
* Deprecate Psalm\getArguments() function
* Deprecate \Psalm\getPathsToCheck() function
* Deprecate \Psalm\getPsalmHelpText() function
* Deprecate \Psalm\initialiseConfig() function
* Deprecate Psalm\update_config_file() function
* Deprecate \Psalm\get_path_to_config() function
* Deprecate Psalm\getMemoryLimitInBytes() function
* CS fix
* Untangle Psalm entrypoint
* Untangle Psalter entrypoint
* Drop command_functions.php references
* Adjust phar build
* Flag unexpected tags on function docblocks
Fixesvimeo/psalm#5782
* Document new issue
* Fix spacing
Co-authored-by: Matthew Brown <github@muglug.com>
* Allow __toString to return never
Fixesvimeo/psalm#5653
* Push $return_is_exit down
* Produce unique control actions
* Test suggesting `@return never`
* Do not consider isset checks on static properties as redundant
Unlike normal properties, static properties do not have a prescribed
initialization sequence, so they can always be uninitialized (or unset).
Thus `isset()` checks on them are never redundant.
Fixesvimeo/psalm#5489
* Fix issue with nullable is_static
Handle array plus operator (fixes#5588).
Handle array spread operator.
Improve string concatenation to resolve to literal instead of unknown string.
I feel like it should be possible to let ConstantTypeResolver take advantage of
the better type analysis in ArrayAnalyzer, ConcatAnalyzer, etc, but it would
require a restructuring that's beyond me for the time being.
* ConcatAnalyzer improvements.
Deduplicate code.
Improve type inference.
Allow literal type inference when only one side has multiple types (fixes#5483).
Fix invalid type inference with negative int as right operand.
* Fix inference to be lowercase-string when concatenating int.
* Fix TNonEmptyLowercaseString to not be subtype of TNonFalsyString.
'0' is a non-empty-lowercase-string that is falsy.
* Fix other issues with non-falsy-string.
* Nest ands and ors
Co-authored-by: Matthew Brown <github@muglug.com>
* Do not consider isset checks on static properties as redundant
Unlike normal properties, static properties do not have a prescribed
initialization sequence, so they can always be uninitialized (or unset).
Thus `isset()` checks on them are never redundant.
Fixesvimeo/psalm#5489
* Fix issue with nullable is_static
Previously, Psalm would treat unions like `class-string|numeric-string`
as `numeric-string`, while the only case when string should subsume
`class-string` is when we're combining `class-string` with non-specific
`string`.
Fixesvimeo/psalm#5491
* Improve @no-named-arguments support and variadics.
Handling of argument unpacking and variadics still needs a pretty big makeover, but this is a good start.
Fixes#5420
Improves #5453 (iterable works, array still causes issues)
* Remove unneeded imports.
* Added event to prevent tainting.
* Remove optional codebase parameter.
* Removed falsy check for codebase.
* Use two separate hooks for adding and removing taints
* Add slashes
* Update add/remove taint test name.
* Cleaned up SafeArrayKeyChecker example plugin.
* Added more AddRemoveTaintsEvent calls to codebase.
* Fix type check error with $added_taints param.
* Added AddRemoveTaintsEvent to remaining classes.
* Fix post-merge error.
* Add comma
* Remove $int_offset that never existed
Co-authored-by: Matt Brown <github@muglug.com>
Fixesvimeo/psalm#5405
Requires new patch release.
This PR reverts changes to the signature of `IssueBuffer::finish()` and
introduces separate method to be used to capture `$_SERVER`
* Disable property invariance checks for templates
Property invariance checks were already disabled for template
properties, this also disabled the checks for arrays, lists,
class-string-maps, and iterables that contain templates.
Partially fixes#5371
* CS fixes
* Fix and simplify hasTemplate.
Add hasTemplate to TypeNode and simplify implementation with getChildNodes.
* Revert hasTemplate change and add containsTemplate.
* Check class-string too.
* Wrap entrypoints into IIFE to protect their variables
Fixesvimeo/psalm#5359
* Add tests for Psalm variable isolation
* Capture environment before registering autoloader
* Emit ImplicitToStringCast in more places
Fixesvimeo/psalm#5320
`to_string_cast` is set on successful comparison, thus it needs to
always bubble up (it will be ignored in UnionTypeComparator if some part
does not match).
* Fix implicit casts
* Fix handling of string method references in self-out context
Previously Psalm would assume that any variable it sees in the arrow
function body is defined (and mixed, if it's not available in the outer
scope). This prevented undefined variable detection. Dropping that
assumption allows it to work.
Fixesvimeo/psalm#5331
* Add documention to LSP
Add descriptions for all Classes, Functions, Methods, Class Constants for LSP methods for Hover, SignatureInformation and Completions
* Descriptions for class name completions
* PHPCS
* Fix docblock being overriden
* Remove trailing comma in args
* Add description to function param before early `continue`
* Update php-language-server-protocol to 1.5
* Break up long array docblocks
* Break up docblock onto newline
Co-authored-by: Matthew Brown <github@muglug.com>
* Fix#4240 - allow type aliases to be used as type parameters
* Fix issues that phpcs found
* Fix#4240 - stop type aliases being everywhere in the same file
* Fix #4240- re-add stuff that was deleted unnecessarily
When checking code like the following:
```
<?php
function checkNegated(string $key): void {
$arr = [
0 => "foo",
1 => "bar",
];
if (!array_key_exists($key, $arr)) {
printf("not found\n");
}
}
function check(string $key): void {
$arr = [
0 => "foo",
1 => "bar",
];
if (array_key_exists($key, $arr)) {
printf("found\n");
}
}
```
the `if` in `checkNegated` would cause:
```
ERROR: RedundantCondition - 9:10 - Type string for $key is never =int(0)
```
This happens when the array keys are all int literals, but the "needle"
is a string.
`array_key_exists()` uses a loose equality comparison, but the generated
assertions for this specific case
(`AssertionFinder::getArrayKeyExistsAssertions`) was generating strict
equality clauses. This commit fixes it by changing the generated clause
from `=` to `~`.
* Add completions for functions
Provide autocompletions in the LSP for all global functions and functions from namespaces used in the current context.
* Uncomment code
* PHPCS
* Simplify functions map
Co-authored-by: Matthew Brown <github@muglug.com>
* Switch to storing lowercase function string in array key
* Fix spacing
Co-authored-by: Matthew Brown <github@muglug.com>
* Implement NonInvariantChildProperty detection
See https://github.com/vimeo/psalm/issues/4184
* Delete test cases with 'parentSetsWiderTypeInConstructor'
As I understand it these are not valid test cases. They
emit NonInvariantPropertyType issues which seems correct - the property
type variation is I think a latent bug in the sample code.
* Reduce shortcode for NonInvariantPropertyType to 1+max used shortcode on master
* Track references on global variables
Add global type references to the type map, and fix up unused detection on global variables.
* Add null assertions
* PHPCS
* Add constant fetch to reference map
To support showing constant types on hover of constant references, we need to add them to the ref map.
* Fix root constants
* PHPCBF
* Add completions for known array keys
* Use dynamic gap value
* Provide completions for known type contexts
* Fix formatting
* Remove trailing comma
* PHPCS fixes
* Remove support for literal floats
* Fix test for floats
* Remove ReflectionType::getName(), move ReflectionType::isBuiltin()
* `ReflectionType::getName()` was never there: https://3v4l.org/1iZt4
* `ReflectionType::isBuiltin()` was moved to
`ReflectionNamedType::isBuiltin()` in PHP 8
Fixesvimeo/psalm#5089
* Fix test
* Mark test as php 8.0 only
* Use separate exit code to indicate Psalm finding issues
This will allow to distinguish successful run that found some issues
from crashes.
* Fix e2e test expectations
* Documented exit statuses
* Support compleitions on class references
This provides completions on class references (as opposed to initiated objects via the type map), so you can do `MyClass::` and get completitions for static methods and constants etc.
* Only provide completions for references that don't exist
* Remove file map cache when re-analyzing files
When the project is re-analyzed under the single thread condition (not using a process pool), the filemaps are not cleared before re-analyzing files. This means that file maps only get appended to. If you delete the contents of a file via the LSP, the file map will still be populated with all the old values for example.
In doing this I had to write a few more tests to check my assumptions too, so adding those additional tests.
* Rename test
* Formatting
* Formatting again!
* #4997 added more precise stub for `count()` returning `0` or `positive-int` on known types
* #4997 updated `count()` to support `\SimpleXmlElement` and `\ResourceBundle` counting, as well as handling hardcoded 2-element-arrays cases
This patch:
* adds support for `count(\SimpleXmlElement)` (https://www.php.net/manual/en/simplexmlelement.count.php)
* adds support for `count(\ResourceBundle)` (https://www.php.net/manual/en/resourcebundle.count.php)
* removes usage of global constants from stub (not supported - see https://www.php.net/manual/en/function.count.php)
* adds support for identifying fixed-element-count arrays, for example `count(callable&array)`, which is always `2`
* #4997 adapted `FunctionCallReturnTypeFetcher` to infer `TPositiveInt` for `count(TNonEmptyArray)` and `count(TNonEmptyList)`
* The `FunctionCallReturnTypeFetcher` is responsible for defining the precise type of a `\count(T)`
expression when given a `T`, so we baked the whole type resolution for `positive-int`, `0` and
`positive-int|0` directly in there.
While this complicates things, it is also true that it is not possible right now (for the stubs)
to provide the level of detail around `count()` that is required by the type inference system
for such a complex function with so many different semantics.
* Split unit test over multiple jobs in GitHub Actions, lowering the total run time
* rename FileManipulationTest to FileManipulationTestCase so it does not run as a standalone Test