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
/
Copy pathFunctionNamingLinter.hack
126 lines (113 loc) · 3.09 KB
/
FunctionNamingLinter.hack
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
123
124
125
126
/*
* 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\Str;
abstract class FunctionNamingLinter extends AutoFixingASTLinter {
const type TContext = IFunctionishDeclaration;
const type TNode = FunctionDeclarationHeader;
abstract public function getSuggestedNameForFunction(
string $name,
FunctionDeclaration $fun,
): string;
abstract public function getSuggestedNameForInstanceMethod(
string $name,
MethodishDeclaration $meth,
): string;
abstract public function getSuggestedNameForStaticMethod(
string $name,
MethodishDeclaration $meth,
): string;
protected function getErrorDescription(
string $what,
?string $class,
string $name,
string $suggestion,
): string {
if ($class === null) {
return Str\format(
'%s "%s()" does not match conventions; consider renaming to "%s"',
$what,
$name,
$suggestion,
);
}
return Str\format(
'%s "%s()" in class "%s" does not match conventions; consider renaming '.
'to "%s"',
$what,
$name,
$class,
$suggestion,
);
}
private function getCurrentNameNodeForFunctionOrMethod(Node $node): ?Token {
if ($node is FunctionDeclaration) {
return $node->getDeclarationHeader()->getName();
}
if ($node is MethodishDeclaration) {
return $node->getFunctionDeclHeader()->getName();
}
return null;
}
<<__Override>>
final public function getLintErrorForNode(
this::TContext $func,
this::TNode $header,
): ?FunctionNamingLintError {
$token = $header->getName();
if (!$token is NameToken) {
return null;
}
$old = $token->getText();
if (Str\starts_with($old, '__')) {
return null;
}
if ($func is FunctionDeclaration) {
$what = 'Function';
$new = $this->getSuggestedNameForFunction($old, $func);
} else if ($func is MethodishDeclaration) {
if (
$header->getModifiers()
?->getFirstDescendantByType<StaticToken>() is null
) {
$what = 'Method';
$new = $this->getSuggestedNameForInstanceMethod($old, $func);
} else {
$what = 'Static method';
$new = $this->getSuggestedNameForStaticMethod($old, $func);
}
} else {
invariant_violation("Can't handle type %s", \get_class($func));
}
if ($old === $new) {
return null;
}
$root = $this->getAST();
$ns = __Private\Resolution\get_current_namespace($root, $func);
if ($func is FunctionDeclaration) {
$class = null;
} else {
$class = (
$root->getFirstAncestorOfDescendantWhere(
$func,
$c ==> $c is ClassishDeclaration,
) as ClassishDeclaration
)->getName()->getText();
}
return new FunctionNamingLintError(
$this,
$this->getErrorDescription($what, $class, $old, $new),
$ns,
$class,
$old,
$new,
$header,
);
}
}