Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/1.10.x' into test/box
Browse files Browse the repository at this point in the history
  • Loading branch information
theofidry committed Mar 8, 2024
2 parents f6b321b + 6b52280 commit 51c5534
Show file tree
Hide file tree
Showing 40 changed files with 1,008 additions and 116 deletions.
12 changes: 6 additions & 6 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions conf/config.level3.neon
Expand Up @@ -10,6 +10,8 @@ conditionalTags:
phpstan.rules.rule: %featureToggles.readOnlyByPhpDoc%
PHPStan\Rules\Variables\ParameterOutAssignedTypeRule:
phpstan.rules.rule: %featureToggles.paramOutType%
PHPStan\Rules\Variables\ParameterOutExecutionEndTypeRule:
phpstan.rules.rule: %featureToggles.paramOutType%

rules:
- PHPStan\Rules\Arrays\ArrayDestructuringRule
Expand Down Expand Up @@ -94,5 +96,9 @@ services:

-
class: PHPStan\Rules\Properties\ReadOnlyByPhpDocPropertyAssignRule

-
class: PHPStan\Rules\Variables\ParameterOutAssignedTypeRule

-
class: PHPStan\Rules\Variables\ParameterOutExecutionEndTypeRule
5 changes: 5 additions & 0 deletions conf/config.level4.neon
Expand Up @@ -27,6 +27,8 @@ conditionalTags:
phpstan.rules.rule: %featureToggles.notAnalysedTrait%
PHPStan\Rules\Comparison\LogicalXorConstantConditionRule:
phpstan.rules.rule: %featureToggles.logicalXor%
PHPStan\Rules\TooWideTypehints\TooWideParameterOutTypeRule:
phpstan.rules.rule: %featureToggles.paramOutType%

parameters:
checkAdvancedIsset: true
Expand Down Expand Up @@ -237,3 +239,6 @@ services:
reportUncheckedExceptionDeadCatch: %exceptions.reportUncheckedExceptionDeadCatch%
tags:
- phpstan.rules.rule

-
class: PHPStan\Rules\TooWideTypehints\TooWideParameterOutTypeRule
2 changes: 2 additions & 0 deletions conf/config.neon
Expand Up @@ -124,6 +124,7 @@ parameters:
reportMaybesInPropertyPhpDocTypes: false
reportStaticMethodSignatures: false
reportWrongPhpDocTypeInVarTag: false
reportAnyTypeWideningInVarTag: false
checkMissingOverrideMethodAttribute: false
mixinExcludeClasses: []
scanFiles: []
Expand Down Expand Up @@ -998,6 +999,7 @@ services:
class: PHPStan\Rules\PhpDoc\VarTagTypeRuleHelper
arguments:
checkTypeAgainstPhpDocType: %reportWrongPhpDocTypeInVarTag%
strictWideningCheck: %reportAnyTypeWideningInVarTag%

-
class: PHPStan\Rules\Playground\NeverRuleHelper
Expand Down
1 change: 1 addition & 0 deletions conf/parametersSchema.neon
Expand Up @@ -121,6 +121,7 @@ parametersSchema:
reportMaybesInPropertyPhpDocTypes: bool()
reportStaticMethodSignatures: bool()
reportWrongPhpDocTypeInVarTag: bool()
reportAnyTypeWideningInVarTag: bool()
checkMissingOverrideMethodAttribute: bool()
parallel: structure([
jobSize: int(),
Expand Down
6 changes: 3 additions & 3 deletions resources/functionMap.php
Expand Up @@ -7420,7 +7420,7 @@
'mysqli::get_charset' => ['object'],
'mysqli::get_client_info' => ['string'],
'mysqli::get_connection_stats' => ['array|false'],
'mysqli::get_warnings' => ['mysqli_warning'],
'mysqli::get_warnings' => ['mysqli_warning|false'],
'mysqli::init' => ['mysqli'],
'mysqli::kill' => ['bool', 'processid'=>'int'],
'mysqli::more_results' => ['bool'],
Expand Down Expand Up @@ -7563,7 +7563,7 @@
'mysqli_stmt::fetch' => ['bool|null'],
'mysqli_stmt::free_result' => ['void'],
'mysqli_stmt::get_result' => ['mysqli_result|false'],
'mysqli_stmt::get_warnings' => ['object'],
'mysqli_stmt::get_warnings' => ['mysqli_warning|false'],
'mysqli_stmt::more_results' => ['bool'],
'mysqli_stmt::next_result' => ['bool'],
'mysqli_stmt::num_rows' => ['int<0,max>|numeric-string'],
Expand All @@ -7587,7 +7587,7 @@
'mysqli_stmt_field_count' => ['0|positive-int', 'stmt'=>'mysqli_stmt'],
'mysqli_stmt_free_result' => ['void', 'stmt'=>'mysqli_stmt'],
'mysqli_stmt_get_result' => ['mysqli_result|false', 'stmt'=>'mysqli_stmt'],
'mysqli_stmt_get_warnings' => ['object|false', 'stmt'=>'mysqli_stmt'],
'mysqli_stmt_get_warnings' => ['mysqli_warning|false', 'stmt'=>'mysqli_stmt'],
'mysqli_stmt_init' => ['mysqli_stmt|false', 'link'=>'mysqli'],
'mysqli_stmt_insert_id' => ['', 'stmt'=>'mysqli_stmt'],
'mysqli_stmt_more_results' => ['bool', 'stmt'=>'mysqli_stmt'],
Expand Down
10 changes: 10 additions & 0 deletions src/Analyser/MutatingScope.php
Expand Up @@ -35,6 +35,7 @@
use PHPStan\Node\Expr\GetIterableValueTypeExpr;
use PHPStan\Node\Expr\GetOffsetValueTypeExpr;
use PHPStan\Node\Expr\OriginalPropertyTypeExpr;
use PHPStan\Node\Expr\ParameterVariableOriginalValueExpr;
use PHPStan\Node\Expr\PropertyInitializationExpr;
use PHPStan\Node\Expr\SetExistingOffsetValueTypeExpr;
use PHPStan\Node\Expr\SetOffsetValueTypeExpr;
Expand Down Expand Up @@ -2786,6 +2787,10 @@ private function enterFunctionLike(
$parameterNode = new Variable($parameter->getName());
$expressionTypes[$paramExprString] = ExpressionTypeHolder::createYes($parameterNode, $parameterType);

$parameterOriginalValueExpr = new ParameterVariableOriginalValueExpr($parameter->getName());
$parameterOriginalValueExprString = $this->getNodeKey($parameterOriginalValueExpr);
$expressionTypes[$parameterOriginalValueExprString] = ExpressionTypeHolder::createYes($parameterOriginalValueExpr, $parameterType);

$nativeParameterType = $parameter->getNativeType();
if ($parameter->isVariadic()) {
if ($this->phpVersion->supportsNamedArguments() && $functionReflection->acceptsNamedArguments()) {
Expand All @@ -2795,6 +2800,7 @@ private function enterFunctionLike(
}
}
$nativeExpressionTypes[$paramExprString] = ExpressionTypeHolder::createYes($parameterNode, $nativeParameterType);
$nativeExpressionTypes[$parameterOriginalValueExprString] = ExpressionTypeHolder::createYes($parameterOriginalValueExpr, $nativeParameterType);
}

if ($preserveThis && array_key_exists('$this', $this->expressionTypes)) {
Expand Down Expand Up @@ -3477,6 +3483,10 @@ public function assignVariable(string $variableName, Type $type, Type $nativeTyp
}
}

$parameterOriginalValueExprString = $this->getNodeKey(new ParameterVariableOriginalValueExpr($variableName));
unset($scope->expressionTypes[$parameterOriginalValueExprString]);
unset($scope->nativeExpressionTypes[$parameterOriginalValueExprString]);

return $scope;
}

Expand Down
34 changes: 34 additions & 0 deletions src/Node/Expr/ParameterVariableOriginalValueExpr.php
@@ -0,0 +1,34 @@
<?php declare(strict_types = 1);

namespace PHPStan\Node\Expr;

use PhpParser\Node\Expr;
use PHPStan\Node\VirtualNode;

class ParameterVariableOriginalValueExpr extends Expr implements VirtualNode
{

public function __construct(private string $variableName)
{
parent::__construct([]);
}

public function getVariableName(): string
{
return $this->variableName;
}

public function getType(): string
{
return 'PHPStan_Node_ParameterVariableOriginalValueExpr';
}

/**
* @return string[]
*/
public function getSubNodeNames(): array
{
return [];
}

}
6 changes: 6 additions & 0 deletions src/Node/Printer/Printer.php
Expand Up @@ -9,6 +9,7 @@
use PHPStan\Node\Expr\GetIterableValueTypeExpr;
use PHPStan\Node\Expr\GetOffsetValueTypeExpr;
use PHPStan\Node\Expr\OriginalPropertyTypeExpr;
use PHPStan\Node\Expr\ParameterVariableOriginalValueExpr;
use PHPStan\Node\Expr\PropertyInitializationExpr;
use PHPStan\Node\Expr\SetExistingOffsetValueTypeExpr;
use PHPStan\Node\Expr\SetOffsetValueTypeExpr;
Expand Down Expand Up @@ -81,6 +82,11 @@ protected function pPHPStan_Node_PropertyInitializationExpr(PropertyInitializati
return sprintf('__phpstanPropertyInitialization(%s)', $expr->getPropertyName());
}

protected function pPHPStan_Node_ParameterVariableOriginalValueExpr(ParameterVariableOriginalValueExpr $expr): string // phpcs:ignore
{
return sprintf('__phpstanParameterVariableOriginalValue(%s)', $expr->getVariableName());
}

protected function pPHPStan_Node_IssetExpr(IssetExpr $expr): string // phpcs:ignore
{
return sprintf('__phpstanIssetExpr(%s)', $this->p($expr->getExpr()));
Expand Down
10 changes: 3 additions & 7 deletions src/PhpDoc/StubValidator.php
Expand Up @@ -157,6 +157,7 @@ private function getRuleRegistry(Container $container): RuleRegistry
$phpVersion = $container->getByType(PhpVersion::class);
$localTypeAliasesCheck = $container->getByType(LocalTypeAliasesCheck::class);
$phpClassReflectionExtension = $container->getByType(PhpClassReflectionExtension::class);
$genericCallableRuleHelper = $container->getByType(GenericCallableRuleHelper::class);

$rules = [
// level 0
Expand All @@ -182,13 +183,8 @@ private function getRuleRegistry(Container $container): RuleRegistry
new MethodTemplateTypeRule($fileTypeMapper, $templateTypeCheck),
new MethodSignatureVarianceRule($varianceCheck),
new TraitTemplateTypeRule($fileTypeMapper, $templateTypeCheck),
new IncompatiblePhpDocTypeRule(
$fileTypeMapper,
$genericObjectTypeCheck,
$unresolvableTypeHelper,
$container->getByType(GenericCallableRuleHelper::class),
),
new IncompatiblePropertyPhpDocTypeRule($genericObjectTypeCheck, $unresolvableTypeHelper),
new IncompatiblePhpDocTypeRule($fileTypeMapper, $genericObjectTypeCheck, $unresolvableTypeHelper, $genericCallableRuleHelper),
new IncompatiblePropertyPhpDocTypeRule($genericObjectTypeCheck, $unresolvableTypeHelper, $genericCallableRuleHelper),
new InvalidPhpDocTagValueRule(
$container->getByType(Lexer::class),
$container->getByType(PhpDocParser::class),
Expand Down
22 changes: 22 additions & 0 deletions src/Reflection/BetterReflection/BetterReflectionProvider.php
Expand Up @@ -3,6 +3,7 @@
namespace PHPStan\Reflection\BetterReflection;

use Closure;
use Nette\Utils\Strings;
use PhpParser\Node;
use PHPStan\Analyser\Scope;
use PHPStan\BetterReflection\Identifier\Exception\InvalidIdentifierName;
Expand Down Expand Up @@ -43,6 +44,7 @@
use PHPStan\Reflection\SignatureMap\NativeFunctionReflectionProvider;
use PHPStan\Reflection\SignatureMap\SignatureMapProvider;
use PHPStan\ShouldNotHappenException;
use PHPStan\TrinaryLogic;
use PHPStan\Type\FileTypeMapper;
use PHPStan\Type\Generic\TemplateTypeMap;
use PHPStan\Type\Type;
Expand Down Expand Up @@ -360,11 +362,31 @@ public function getConstant(Node\Name $nameNode, ?NamespaceAnswerer $namespaceAn
$constantReflection = $this->reflector->reflectConstant($constantName);
$fileName = $constantReflection->getFileName();
$constantValueType = $this->initializerExprTypeResolver->getType($constantReflection->getValueExpression(), InitializerExprContext::fromGlobalConstant($constantReflection));
$docComment = $constantReflection->getDocComment();

$isDeprecated = TrinaryLogic::createNo();
$deprecatedDescription = null;
if ($docComment !== null) {
$resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($fileName, null, null, null, $docComment);
$isDeprecated = TrinaryLogic::createFromBoolean($resolvedPhpDoc->isDeprecated());

if ($resolvedPhpDoc->isDeprecated() && $resolvedPhpDoc->getDeprecatedTag() !== null) {
$deprecatedMessage = $resolvedPhpDoc->getDeprecatedTag()->getMessage();

// filter raw version number messages like in
// https://github.com/JetBrains/phpstorm-stubs/blob/9608c953230b08f07b703ecfe459cc58d5421437/filter/filter.php#L478
if (Strings::match($deprecatedMessage ?? '', '#^\d+\.\d+(\.\d+)?$#') === null) {
$deprecatedDescription = $deprecatedMessage;
}
}
}

return $this->cachedConstants[$constantName] = new RuntimeConstantReflection(
$constantName,
$constantValueType,
$fileName,
$isDeprecated,
$deprecatedDescription,
);
}

Expand Down
10 changes: 5 additions & 5 deletions src/Reflection/BetterReflection/SourceLocator/PhpFileCleaner.php
Expand Up @@ -101,7 +101,7 @@ public function clean(string $contents, int $maxMatches): string
continue;
}

if ($char === '<' && $this->peek('<') && $this->match('{<<<[ \t]*+([\'"]?)([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*+)\\1(?:\r\n|\n|\r)}A', $match) && $match !== null) {
if ($char === '<' && $this->peek('<') && $this->match('{<<<[ \t]*+([\'"]?)([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*+)\\1(?:\r\n|\n|\r)}A', $match)) {
$this->index += strlen($match[0]);
$this->skipHeredoc($match[2]);
$clean .= 'null';
Expand All @@ -123,15 +123,14 @@ public function clean(string $contents, int $maxMatches): string
$inType
&& $char === 'c'
&& $this->match('~.\b(?<![\$:>])const(\s++[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff\-]*+)~Ais', $match, $this->index - 1)
&& $match !== null
) {
// It's invalid PHP but it does not matter
$clean .= 'class_const' . $match[1];
$this->index += strlen($match[0]) - 1;
continue;
}

if ($char === 'd' && $this->match('~.\b(?<![\$:>])define\s*+\(~Ais', $match, $this->index - 1) && $match !== null) {
if ($char === 'd' && $this->match('~.\b(?<![\$:>])define\s*+\(~Ais', $match, $this->index - 1)) {
$inDefine = true;
$clean .= $match[0];
$this->index += strlen($match[0]) - 1;
Expand All @@ -142,7 +141,7 @@ public function clean(string $contents, int $maxMatches): string
$type = $this->typeConfig[$char];

if (substr($this->contents, $this->index, $type['length']) === $type['name']) {
if ($maxMatches === 1 && $this->match($type['pattern'], $match, $this->index - 1) && $match !== null) {
if ($maxMatches === 1 && $this->match($type['pattern'], $match, $this->index - 1)) {
return $clean . $match[0];
}

Expand All @@ -151,7 +150,7 @@ public function clean(string $contents, int $maxMatches): string
}

$this->index += 1;
if ($this->match($this->restPattern, $match) && $match !== null) {
if ($this->match($this->restPattern, $match)) {
$clean .= $char . $match[0];
$this->index += strlen($match[0]);
} else {
Expand Down Expand Up @@ -286,6 +285,7 @@ private function peek(string $char): bool

/**
* @param string[]|null $match
* @param-out string[] $match
*/
private function match(string $regex, ?array &$match = null, ?int $offset = null): bool
{
Expand Down
6 changes: 4 additions & 2 deletions src/Reflection/Constant/RuntimeConstantReflection.php
Expand Up @@ -13,6 +13,8 @@ public function __construct(
private string $name,
private Type $valueType,
private ?string $fileName,
private TrinaryLogic $isDeprecated,
private ?string $deprecatedDescription,
)
{
}
Expand All @@ -34,12 +36,12 @@ public function getFileName(): ?string

public function isDeprecated(): TrinaryLogic
{
return TrinaryLogic::createNo();
return $this->isDeprecated;
}

public function getDeprecatedDescription(): ?string
{
return null;
return $this->deprecatedDescription;
}

public function isInternal(): TrinaryLogic
Expand Down

0 comments on commit 51c5534

Please sign in to comment.