in src/Parser.php [1689:1731]
private function parseFunctionType(Node $functionDeclaration, $canBeAbstract = false, $isAnonymous = false) {
$functionDeclaration->functionKeyword = $this->eat1(TokenKind::FunctionKeyword);
$functionDeclaration->byRefToken = $this->eatOptional1(TokenKind::AmpersandToken);
$functionDeclaration->name = $isAnonymous
? $this->eatOptional($this->nameOrKeywordOrReservedWordTokens)
: $this->eat($this->nameOrKeywordOrReservedWordTokens);
if (isset($functionDeclaration->name)) {
$functionDeclaration->name->kind = TokenKind::Name;
}
if ($isAnonymous && isset($functionDeclaration->name)) {
// Anonymous functions should not have names
$functionDeclaration->name = new SkippedToken($functionDeclaration->name); // TODO instead handle this during post-walk
}
$functionDeclaration->openParen = $this->eat1(TokenKind::OpenParenToken);
$functionDeclaration->parameters = $this->parseDelimitedList(
DelimitedList\ParameterDeclarationList::class,
TokenKind::CommaToken,
$this->isParameterStartFn(),
$this->parseParameterFn(),
$functionDeclaration);
$functionDeclaration->closeParen = $this->eat1(TokenKind::CloseParenToken);
if ($isAnonymous) {
$functionDeclaration->anonymousFunctionUseClause = $this->parseAnonymousFunctionUseClause($functionDeclaration);
}
if ($this->checkToken(TokenKind::ColonToken)) {
$functionDeclaration->colonToken = $this->eat1(TokenKind::ColonToken);
$functionDeclaration->questionToken = $this->eatOptional1(TokenKind::QuestionToken);
$this->parseAndSetReturnTypeDeclarationList($functionDeclaration);
}
if ($canBeAbstract) {
$functionDeclaration->compoundStatementOrSemicolon = $this->eatOptional1(TokenKind::SemicolonToken);
}
if (!isset($functionDeclaration->compoundStatementOrSemicolon)) {
$functionDeclaration->compoundStatementOrSemicolon = $this->parseCompoundStatement($functionDeclaration);
}
}