in src/Migrations/XHPLibV3ToV4Migration.hack [239:312]
private function migrateClass(
ClassishDeclaration $class,
(function(string, Node): string) $type_resolver,
): ClassishDeclaration {
if (
!$class->getKeyword() is ClassToken ||
$class->getExtendsList() is null ||
$class->getBody()->getElements() is null
) {
return $class;
}
$method_name = idx(
self::ASYNCIFY_METHODS,
$type_resolver(
self::withoutTrivia($class->getExtendsListx()),
$class->getExtendsListx(),
),
);
if ($method_name is null) {
return $class;
}
foreach ($class->getBody()->getElementsx()->getChildren() as $decl) {
if (!$decl is MethodishDeclaration) {
continue;
}
$new_header = $decl->getFunctionDeclHeader();
if (self::withoutTrivia($new_header->getName()) !== $method_name) {
continue;
}
// asyncify return type
if ($new_header->hasType()) {
$new_header = $new_header->withType(
self::asyncifyType($new_header->getTypex()),
);
}
// add `async` keyword
if (
$new_header->hasModifiers() && !$new_header->getModifiersx()->isEmpty()
) {
$new_header = $new_header->withModifiers(NodeList::createMaybeEmptyList(
Vec\concat(
$new_header->getModifiersx()->getChildren(),
vec[new AsyncToken(null, self::space())],
),
));
} else {
// If there are no existing modifiers, also move leading Trivia from
// the `function` token to the new `async` token.
$new_header = $new_header
->withModifiers(NodeList::createMaybeEmptyList(vec[
new AsyncToken(
$new_header->getKeyword()->getLeading(),
self::space(),
),
]))
->withKeyword($new_header->getKeyword()->withLeading(null));
}
return $class->replaceDescendant(
$decl->getFunctionDeclHeader(),
// append `Async` to method name
$new_header->withName(
new NameToken(
$new_header->getName()->getFirstTokenx()->getLeading(),
$new_header->getName()->getLastTokenx()->getTrailing(),
$method_name.self::ASYNC_METHOD_SUFFIX,
),
),
);
}
return $class;
}