Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/4.x' into upstream-master5
Browse files Browse the repository at this point in the history
  • Loading branch information
orklah committed Jan 23, 2022
2 parents c90cffd + 8230efb commit 7c4f080
Show file tree
Hide file tree
Showing 12 changed files with 200 additions and 15 deletions.
5 changes: 5 additions & 0 deletions config.xsd
Expand Up @@ -52,6 +52,11 @@
<xs:documentation xml:lang="en">
Default is runtime-specific: if not present, Psalm will only load the Xdebug stub if psalm has unloaded the extension.
</xs:documentation>

<!-- note: for PHPStorm to mark the attribute as deprecated the doc entry has to be *single line* and start with the word `deprecated` -->
<xs:documentation xml:lang="en">
Deprecated. In Psalm 5 extensions will be loaded based on composer.json and overridden with enableExtensions/disableExtensions.
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="memoizeMethodCallResults" type="xs:boolean" default="false" />
Expand Down
72 changes: 58 additions & 14 deletions psalm-baseline.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="4.9999999.9999999.9999999-dev">
<files psalm-version="dev-master@c90cffd382bb7a5d390387d4ad2a02a4935fba5c">
<file src="examples/TemplateChecker.php">
<PossiblyUndefinedIntArrayOffset occurrences="2">
<code>$comment_block-&gt;tags['variablesfrom'][0]</code>
Expand All @@ -18,6 +18,16 @@
<code>$symbol_parts[1]</code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Config.php">
<DeprecatedMethod occurrences="3">
<code>getAdditionalFileExtensions</code>
<code>getAdditionalFileTypeAnalyzers</code>
<code>getAdditionalFileTypeScanners</code>
</DeprecatedMethod>
<DeprecatedProperty occurrences="1">
<code>$this-&gt;load_xdebug_stub</code>
</DeprecatedProperty>
</file>
<file src="src/Psalm/Config/FileFilter.php">
<PossiblyUndefinedIntArrayOffset occurrences="1">
<code>explode('::', $method_id)[1]</code>
Expand All @@ -37,11 +47,6 @@
<code>$uninitialized_variables[0]</code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/Analyzer/CommentAnalyzer.php">
<PossiblyUndefinedIntArrayOffset occurrences="1">
<code>$line_parts[1]</code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/Analyzer/ProjectAnalyzer.php">
<PossiblyUndefinedIntArrayOffset occurrences="4">
<code>$destination_parts[1]</code>
Expand Down Expand Up @@ -121,6 +126,12 @@
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ArithmeticOpAnalyzer.php">
<DeprecatedClass occurrences="1">
<code>new TPositiveInt()</code>
</DeprecatedClass>
<DeprecatedMethod occurrences="1">
<code>Type::getPositiveInt(true)</code>
</DeprecatedMethod>
<PossiblyUndefinedIntArrayOffset occurrences="2">
<code>$invalid_left_messages[0]</code>
<code>$invalid_right_messages[0]</code>
Expand Down Expand Up @@ -153,6 +164,13 @@
<code>$stmt-&gt;getArgs()[0]</code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallReturnTypeFetcher.php">
<DeprecatedClass occurrences="3">
<code>new TPositiveInt</code>
<code>new TPositiveInt</code>
<code>new TPositiveInt</code>
</DeprecatedClass>
</file>
<file src="src/Psalm/Internal/Analyzer/Statements/Expression/Call/MethodCallAnalyzer.php">
<PossiblyUndefinedIntArrayOffset occurrences="6">
<code>$result-&gt;invalid_method_call_types[0]</code>
Expand All @@ -164,8 +182,7 @@
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/Analyzer/Statements/Expression/CallAnalyzer.php">
<PossiblyUndefinedIntArrayOffset occurrences="3">
<code>$assertion-&gt;rule[0]</code>
<PossiblyUndefinedIntArrayOffset occurrences="2">
<code>$callable_arg-&gt;items[0]</code>
<code>$callable_arg-&gt;items[1]</code>
</PossiblyUndefinedIntArrayOffset>
Expand Down Expand Up @@ -195,6 +212,12 @@
<code>$stmt-&gt;expr-&gt;getArgs()[0]</code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/Cli/Psalm.php">
<DeprecatedProperty occurrences="2">
<code>$config-&gt;load_xdebug_stub</code>
<code>$config-&gt;load_xdebug_stub</code>
</DeprecatedProperty>
</file>
<file src="src/Psalm/Internal/Codebase/InternalCallMapHandler.php">
<PossiblyUndefinedIntArrayOffset occurrences="2">
<code>$callables[0]</code>
Expand Down Expand Up @@ -269,8 +292,7 @@
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php">
<PossiblyUndefinedIntArrayOffset occurrences="4">
<code>$imported_type_data[3]</code>
<PossiblyUndefinedIntArrayOffset occurrences="3">
<code>$l[4]</code>
<code>$r[4]</code>
<code>$var_line_parts[0]</code>
Expand Down Expand Up @@ -306,7 +328,20 @@
<code>$cs[0]</code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/Type/Comparator/IntegerRangeComparator.php">
<DeprecatedClass occurrences="1">
<code>TPositiveInt::class</code>
</DeprecatedClass>
</file>
<file src="src/Psalm/Internal/Type/Comparator/ScalarTypeComparator.php">
<DeprecatedClass occurrences="1">
<code>TPositiveInt::class</code>
</DeprecatedClass>
</file>
<file src="src/Psalm/Internal/Type/TypeCombiner.php">
<DeprecatedClass occurrences="1">
<code>new TPositiveInt()</code>
</DeprecatedClass>
<PossiblyUndefinedIntArrayOffset occurrences="6">
<code>$combination-&gt;array_type_params[1]</code>
<code>$combination-&gt;array_type_params[1]</code>
Expand All @@ -317,6 +352,9 @@
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/Type/TypeParser.php">
<DeprecatedClass occurrences="1">
<code>new TPositiveInt()</code>
</DeprecatedClass>
<PossiblyUndefinedIntArrayOffset occurrences="9">
<code>$intersection_types[0]</code>
<code>$parse_tree-&gt;children[0]</code>
Expand Down Expand Up @@ -354,10 +392,16 @@
<code>VirtualConst</code>
</PropertyNotSetInConstructor>
</file>
<file src="src/Psalm/Storage/Assertion.php">
<PossiblyUndefinedIntArrayOffset occurrences="1">
<code>$rules[0]</code>
</PossiblyUndefinedIntArrayOffset>
<file src="src/Psalm/PluginRegistrationSocket.php">
<DeprecatedMethod occurrences="2">
<code>addFileExtension</code>
<code>addFileExtension</code>
</DeprecatedMethod>
</file>
<file src="src/Psalm/Type.php">
<DeprecatedClass occurrences="1">
<code>new TPositiveInt()</code>
</DeprecatedClass>
</file>
<file src="src/Psalm/Type/Atomic.php">
<PossiblyUndefinedIntArrayOffset occurrences="1">
Expand Down
2 changes: 2 additions & 0 deletions src/Psalm/Config.php
Expand Up @@ -198,6 +198,8 @@ class Config
/**
* Whether or not to load Xdebug stub
*
* @deprecated going to be removed in Psalm 5
*
* @var bool|null
*/
public $load_xdebug_stub;
Expand Down
Expand Up @@ -27,6 +27,7 @@
use Psalm\Storage\ClassLikeStorage;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TClosure;
use Psalm\Type\Atomic\TEmptyMixed;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TGenericObject;
Expand Down Expand Up @@ -191,6 +192,41 @@ public static function analyze(
);
}

if ($stmt->isFirstClassCallable()) {
$return_type_candidate = null;
$method_name_type = $statements_analyzer->node_data->getType($stmt->name);
if ($method_name_type && $method_name_type->isSingleStringLiteral()) {
$method_identifier = new MethodIdentifier(
$fq_class_name,
strtolower($method_name_type->getSingleStringLiteral()->value)
);
//the call to methodExists will register that the method was called from somewhere
if ($codebase->methods->methodExists(
$method_identifier,
$context->calling_method_id,
null,
$statements_analyzer,
$statements_analyzer->getFilePath(),
true,
$context->insideUse()
)) {
$method_storage = $codebase->methods->getStorage($method_identifier);

$return_type_candidate = new Union([new TClosure(
'Closure',
$method_storage->params,
$method_storage->return_type,
$method_storage->pure
)]);
}
}

$statements_analyzer->node_data->setType($stmt, $return_type_candidate ?? Type::getClosure());


return;
}

ArgumentsAnalyzer::analyze(
$statements_analyzer,
$stmt->getArgs(),
Expand Down
Expand Up @@ -231,6 +231,42 @@ public static function analyze(
);
}

if ($stmt->isFirstClassCallable()) {
$return_type_candidate = null;
if (!$stmt->name instanceof PhpParser\Node\Identifier) {
$method_name_type = $statements_analyzer->node_data->getType($stmt->name);
if ($method_name_type && $method_name_type->isSingleStringLiteral()) {
$method_identifier = new MethodIdentifier(
$fq_class_name,
strtolower($method_name_type->getSingleStringLiteral()->value)
);
//the call to methodExists will register that the method was called from somewhere
if ($codebase->methods->methodExists(
$method_identifier,
$context->calling_method_id,
null,
$statements_analyzer,
$statements_analyzer->getFilePath(),
true,
$context->insideUse()
)) {
$method_storage = $codebase->methods->getStorage($method_identifier);

$return_type_candidate = new Union([new TClosure(
'Closure',
$method_storage->params,
$method_storage->return_type,
$method_storage->pure
)]);
}
}
}

$statements_analyzer->node_data->setType($stmt, $return_type_candidate ?? Type::getClosure());

return;
}

if (ArgumentsAnalyzer::analyze(
$statements_analyzer,
$stmt->getArgs(),
Expand Down
Expand Up @@ -1007,7 +1007,10 @@ private static function handleNonExistentClass(
}
}

if (!$class_exists) {
if (!$class_exists &&
//interfaces can't have properties. Except when they do... In PHP Core, they can
!in_array($fq_class_name, ['UnitEnum', 'BackedEnum'], true)
) {
if (IssueBuffer::accepts(
new NoInterfaceProperties(
'Interfaces cannot have properties',
Expand Down
2 changes: 2 additions & 0 deletions src/Psalm/Plugin/RegistrationInterface.php
Expand Up @@ -17,12 +17,14 @@ public function registerHooksFromClass(string $handler): void;
/**
* @param string $fileExtension e.g. `'html'`
* @param class-string<FileScanner> $className
* @deprecated will be removed in v5.0, use \Psalm\Plugin\FileExtensionsInterface instead (#6788)
*/
public function addFileTypeScanner(string $fileExtension, string $className): void;

/**
* @param string $fileExtension e.g. `'html'`
* @param class-string<FileAnalyzer> $className
* @deprecated will be removed in v5.0, use \Psalm\Plugin\FileExtensionsInterface instead (#6788)
*/
public function addFileTypeAnalyzer(string $fileExtension, string $className): void;
}
6 changes: 6 additions & 0 deletions src/Psalm/PluginRegistrationSocket.php
Expand Up @@ -113,6 +113,7 @@ public function registerHooksFromClass(string $handler): void
/**
* @param string $fileExtension e.g. `'html'`
* @param class-string<FileScanner> $className
* @deprecated will be removed in v5.0, use \Psalm\Plugin\FileExtensionsInterface instead (#6788)
*/
public function addFileTypeScanner(string $fileExtension, string $className): void
{
Expand Down Expand Up @@ -140,6 +141,7 @@ public function addFileTypeScanner(string $fileExtension, string $className): vo

/**
* @return array<string, class-string<FileScanner>>
* @deprecated will be removed in v5.0, use \Psalm\PluginFileExtensionsSocket instead (#6788)
*/
public function getAdditionalFileTypeScanners(): array
{
Expand All @@ -149,6 +151,7 @@ public function getAdditionalFileTypeScanners(): array
/**
* @param string $fileExtension e.g. `'html'`
* @param class-string<FileAnalyzer> $className
* @deprecated will be removed in v5.0, use \Psalm\PluginFileExtensionsSocket instead (#6788)
*/
public function addFileTypeAnalyzer(string $fileExtension, string $className): void
{
Expand Down Expand Up @@ -176,6 +179,7 @@ public function addFileTypeAnalyzer(string $fileExtension, string $className): v

/**
* @return array<string, class-string<FileAnalyzer>>
* @deprecated will be removed in v5.0, use \Psalm\PluginFileExtensionsSocket instead (#6788)
*/
public function getAdditionalFileTypeAnalyzers(): array
{
Expand All @@ -184,6 +188,7 @@ public function getAdditionalFileTypeAnalyzers(): array

/**
* @return list<string> e.g. `['html', 'perl']`
* @deprecated will be removed in v5.0, use \Psalm\PluginFileExtensionsSocket instead (#6788)
*/
public function getAdditionalFileExtensions(): array
{
Expand All @@ -192,6 +197,7 @@ public function getAdditionalFileExtensions(): array

/**
* @param string $fileExtension e.g. `'html'`
* @deprecated will be removed in v5.0, use \Psalm\PluginFileExtensionsSocket instead (#6788)
*/
private function addFileExtension(string $fileExtension): void
{
Expand Down
1 change: 1 addition & 0 deletions src/Psalm/Type.php
Expand Up @@ -194,6 +194,7 @@ public static function getLowercaseString(): Union
return new Union([$type]);
}

/** @deprecated will be removed in Psalm 5 */
public static function getPositiveInt(bool $from_calculation = false): Union
{
$union = new Union([new TPositiveInt()]);
Expand Down
1 change: 1 addition & 0 deletions src/Psalm/Type/Atomic/TPositiveInt.php
Expand Up @@ -4,6 +4,7 @@

/**
* Denotes an int that is also positive (strictly > 0)
* @deprecated will be removed in Psalm 5
*/
class TPositiveInt extends TInt
{
Expand Down

0 comments on commit 7c4f080

Please sign in to comment.