1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-26 20:34:47 +01:00

Fix remaining issues

This commit is contained in:
Matthew Brown 2019-02-06 15:52:43 -05:00
parent e7d73c3ff2
commit c758678022
6 changed files with 44 additions and 3 deletions

View File

@ -182,6 +182,7 @@ class ReturnTypeCollector
)
);
} elseif ($stmt instanceof PhpParser\Node\Stmt\While_) {
$yield_types = array_merge($yield_types, self::getYieldTypeFromExpression($stmt->cond));
$return_types = array_merge(
$return_types,
self::getReturnTypes(
@ -303,6 +304,13 @@ class ReturnTypeCollector
}
return [new Atomic\TMixed()];
} elseif ($stmt instanceof PhpParser\Node\Expr\BinaryOp) {
return array_merge(
self::getYieldTypeFromExpression($stmt->left),
self::getYieldTypeFromExpression($stmt->right)
);
} elseif ($stmt instanceof PhpParser\Node\Expr\Assign) {
return self::getYieldTypeFromExpression($stmt->expr);
}
return [];

View File

@ -8,6 +8,7 @@ use Psalm\Internal\Analyzer\ClosureAnalyzer;
use Psalm\Internal\Analyzer\CommentAnalyzer;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\Analyzer\TraitAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\ArrayAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\AssertionFinder;
use Psalm\Internal\Analyzer\Statements\Expression\AssignmentAnalyzer;
@ -1220,6 +1221,30 @@ class ExpressionAnalyzer
$stmt->inferredType = Type::getNull();
}
$source = $statements_analyzer->getSource();
if ($source instanceof FunctionLikeAnalyzer
&& !($source->getSource() instanceof TraitAnalyzer)
) {
$source->addPossibleParamTypes($context, $codebase);
$storage = $source->getFunctionLikeStorage($statements_analyzer);
if ($storage->return_type) {
foreach ($storage->return_type->getTypes() as $atomic_return_type) {
if ($atomic_return_type instanceof Type\Atomic\TGenericObject
&& $atomic_return_type->value === 'Generator'
) {
if (!$atomic_return_type->type_params[2]->isMixed()
&& !$atomic_return_type->type_params[2]->isVoid()
) {
$stmt->inferredType = clone $atomic_return_type->type_params[2];
}
}
}
}
}
return null;
}

View File

@ -1269,6 +1269,10 @@ class TypeAnalyzer
$container_param = $container_type_part->type_params[$i];
if ($input_type_part->value === 'Generator' && $i === 2) {
continue;
}
if (!$input_param->isEmpty() &&
!self::isContainedBy(
$codebase,

View File

@ -56,7 +56,7 @@ class TextDocument
{
return call(
/**
* @return \Generator<int, Promise, mixed, TextDocumentItem>
* @return \Generator<int, mixed, mixed, TextDocumentItem>
*/
function () use ($textDocument) {
$result = yield $this->handler->request(
@ -64,6 +64,7 @@ class TextDocument
['textDocument' => $textDocument]
);
/** @var TextDocumentItem */
return $this->mapper->map($result, new TextDocumentItem);
}
);

View File

@ -42,6 +42,9 @@ class ProtocolStreamReader implements ProtocolReader
{
$input = new ResourceInputStream($input);
asyncCall(
/**
* @return \Generator<int, string, string, void>
*/
function () use ($input) : \Generator {
while ($this->is_accepting_new_requests && ($chunk = yield $input->read()) !== null) {
/** @var string $chunk */

View File

@ -5,9 +5,9 @@ namespace Amp;
/**
* @template TReturn
* @param callable():\Generator<mixed, mixed, mixed, TReturn> $gen
* @return Promise<TReturn>
* @return callable():Promise<TReturn>
*/
function coroutine(callable $gen) : Promise {}
function coroutine(callable $gen) : callable {}
/**
* @template TReturn