This repository was archived by the owner on Dec 1, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 43
Expand file tree
/
Copy pathHardenVarrayOrDarrayTypehintsMigration.hack
More file actions
122 lines (114 loc) · 3.84 KB
/
HardenVarrayOrDarrayTypehintsMigration.hack
File metadata and controls
122 lines (114 loc) · 3.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
namespace Facebook\HHAST;
use namespace HH\Lib\C;
final class HardenVarrayOrDarrayTypehintsMigration extends StepBasedMigration {
<<__Override>>
public function getSteps(): Traversable<IMigrationStep> {
return vec[
new NodeTypeMigrationStep<ParameterDeclaration, _>(
'Migrate varray_or_darray parameters',
$node ==> self::migrateParameter($node),
),
new NodeTypeMigrationStep<FunctionDeclarationHeader, _>(
'Migrate varray_or_darray return types',
$node ==> $node->withType(self::migrateReturnType($node->getType())),
),
new NodeTypeMigrationStep<LambdaSignature, _>(
'Migrate varray_or_darray return types in lambda functions',
$node ==> $node->withType(static::migrateReturnType($node->getType())),
),
];
}
private static function migrateParameter(
ParameterDeclaration $param,
): ParameterDeclaration {
list($attr, $type) = static::migrate(
$param->getAttribute(),
$param->getType(),
);
return $param->withAttribute($attr)->withType($type);
}
private static function migrateReturnType(
?ITypeSpecifier $type,
): ?ITypeSpecifier {
$wrapper = null;
if ($type is AttributizedSpecifier) {
$wrapper = $type;
$type = $type->getType();
}
list($attr, $type) = static::migrate($wrapper?->getAttributeSpec(), $type);
return $wrapper is null || $attr is null || $type is null
? $type
: $wrapper->withAttributeSpec($attr)
->withType($type as ISimpleCreationSpecifier);
}
/**
* Shared part of migrateParameter() and migrateReturnType().
*/
private static function migrate(
?OldAttributeSpecification $old_attr_spec,
?ITypeSpecifier $type,
): (?OldAttributeSpecification, ?ITypeSpecifier) {
if ($type is GenericTypeSpecifier) {
$name = $type->getClassType();
if ($name is NameToken && $name->getText() === 'varray_or_darray') {
$new_attr_spec = self::removeSoft($old_attr_spec);
if ($old_attr_spec is nonnull && $new_attr_spec is null) {
// The whole attribute spec is being removed. Preserve whitespace and
// comments by concatenating trivia from before $old_attr_spec, after
// $old_attr_spec, and before $type.
$between = NodeList::concat(
$old_attr_spec->getLastTokenx()->getTrailing(),
$type->getFirstTokenx()->getLeading(),
);
// Common edge case: Single space between <<__Soft>> varray_or_darray
// should be removed.
if (
$between->getCount() === 1 &&
C\onlyx($between->getChildren())->getText() === ' '
) {
$between = NodeList::createMaybeEmptyList(vec[]);
}
$type = $type->replaceDescendant(
$type->getFirstTokenx(),
$type->getFirstTokenx()->withLeading(
NodeList::concat(
$old_attr_spec->getFirstTokenx()->getLeading(),
$between,
),
),
);
}
return tuple($new_attr_spec, $type);
}
}
return tuple($old_attr_spec, $type);
}
private static function removeSoft(
?OldAttributeSpecification $attr_spec,
): ?OldAttributeSpecification {
if ($attr_spec is null) {
return null;
}
$attrs = $attr_spec->getAttributes()->filterChildren(
$item ==> {
$name = $item->getItem()->getType();
if ($name is NameToken && $name->getText() === '__Soft') {
return false;
}
return true;
},
);
if ($attrs->isEmpty()) {
return null;
}
return $attr_spec->withAttributes($attrs);
}
}