done() || ! $stream->next() instanceof OpeningParenthesisToken) { return CallableType::default(); } $stream->forward(); if ($stream->done()) { throw new ExpectedTypeForCallable(); } $parameters = []; while (! $stream->next() instanceof ClosingParenthesisToken) { $parameters[] = $stream->read(); if (! $stream->done() && $stream->next() instanceof CommaToken) { $stream->forward(); } if ($stream->done()) { throw new ExpectedClosingParenthesisAfterCallable($parameters); } } $stream->forward(); if ($stream->done()) { throw new ExpectedColonAfterCallableClosingParenthesis($parameters); } if (! ($next = $stream->forward()) instanceof ColonToken) { throw new UnexpectedTokenAfterCallableClosingParenthesis($parameters, $next); } if ($stream->done()) { throw new ExpectedReturnTypeAfterCallableColon($parameters); } $returnType = $stream->read(); return new CallableType($parameters, $returnType); } public function symbol(): string { return 'callable'; } }