OLD | NEW |
| (Empty) |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 library services.src.refactoring.naming_conventions; | |
6 | |
7 import 'package:analysis_services/correction/status.dart'; | |
8 import 'package:analysis_services/src/correction/strings.dart'; | |
9 | |
10 | |
11 /** | |
12 * Returns the [RefactoringStatus] with severity: | |
13 * OK if the name is valid; | |
14 * WARNING if the name is discouraged; | |
15 * ERROR if the name is illegal. | |
16 */ | |
17 RefactoringStatus validateClassName(String name) { | |
18 return _validateUpperCamelCase(name, "Class"); | |
19 } | |
20 | |
21 /** | |
22 * Returns the [RefactoringStatus] with severity: | |
23 * OK if the name is valid; | |
24 * WARNING if the name is discouraged; | |
25 * ERROR if the name is illegal. | |
26 */ | |
27 RefactoringStatus validateConstantName(String name) { | |
28 // null | |
29 if (name == null) { | |
30 return new RefactoringStatus.error("Constant name must not be null."); | |
31 } | |
32 // is not identifier | |
33 RefactoringStatus status = | |
34 _validateIdentifier(name, "Constant name", 'an uppercase letter or undersc
ore'); | |
35 if (!status.isOK) { | |
36 return status; | |
37 } | |
38 // is private, OK | |
39 int startIndex = 0; | |
40 if (name.codeUnitAt(0) == CHAR_UNDERSCORE) { | |
41 startIndex++; | |
42 } | |
43 // does not start with lower case | |
44 for (int i = startIndex; i < name.length; i++) { | |
45 int c = name.codeUnitAt(i); | |
46 if (!isUpperCase(c) && !isDigit(c) && c != CHAR_UNDERSCORE) { | |
47 return new RefactoringStatus.warning( | |
48 "Constant name should be all uppercase with underscores."); | |
49 } | |
50 } | |
51 // OK | |
52 return new RefactoringStatus(); | |
53 } | |
54 | |
55 /** | |
56 * Returns the [RefactoringStatus] with severity: | |
57 * OK if the name is valid; | |
58 * WARNING if the name is discouraged; | |
59 * ERROR if the name is illegal. | |
60 */ | |
61 RefactoringStatus validateConstructorName(String name) { | |
62 if (name != null && name.isEmpty) { | |
63 return new RefactoringStatus(); | |
64 } | |
65 return _validateLowerCamelCase(name, "Constructor"); | |
66 } | |
67 | |
68 /** | |
69 * Returns the [RefactoringStatus] with severity: | |
70 * OK if the name is valid; | |
71 * WARNING if the name is discouraged; | |
72 * ERROR if the name is illegal. | |
73 */ | |
74 RefactoringStatus validateFieldName(String name) { | |
75 return _validateLowerCamelCase(name, "Field"); | |
76 } | |
77 | |
78 /** | |
79 * Returns the [RefactoringStatus] with severity: | |
80 * OK if the name is valid; | |
81 * WARNING if the name is discouraged; | |
82 * ERROR if the name is illegal. | |
83 */ | |
84 RefactoringStatus validateFunctionName(String name) { | |
85 return _validateLowerCamelCase(name, "Function"); | |
86 } | |
87 | |
88 /** | |
89 * Returns the [RefactoringStatus] with severity: | |
90 * OK if the name is valid; | |
91 * WARNING if the name is discouraged; | |
92 * ERROR if the name is illegal. | |
93 */ | |
94 RefactoringStatus validateFunctionTypeAliasName(String name) { | |
95 return _validateUpperCamelCase(name, "Function type alias"); | |
96 } | |
97 | |
98 /** | |
99 * Returns the [RefactoringStatus] with severity: | |
100 * OK if the name is valid; | |
101 * WARNING if the name is discouraged; | |
102 * ERROR if the name is illegal. | |
103 */ | |
104 RefactoringStatus validateImportPrefixName(String name) { | |
105 if (name != null && name.isEmpty) { | |
106 return new RefactoringStatus(); | |
107 } | |
108 return _validateLowerCamelCase(name, "Import prefix"); | |
109 } | |
110 | |
111 /** | |
112 * Returns the [RefactoringStatus] with severity: | |
113 * OK if the name is valid; | |
114 * WARNING if the name is discouraged; | |
115 * ERROR if the name is illegal. | |
116 */ | |
117 RefactoringStatus validateLibraryName(String name) { | |
118 // null | |
119 if (name == null) { | |
120 return new RefactoringStatus.error("Library name must not be null."); | |
121 } | |
122 // blank | |
123 if (isBlank(name)) { | |
124 return new RefactoringStatus.error("Library name must not be blank."); | |
125 } | |
126 // check identifiers | |
127 List<String> identifiers = name.split('.'); | |
128 for (String identifier in identifiers) { | |
129 RefactoringStatus status = | |
130 _validateIdentifier( | |
131 identifier, | |
132 "Library name identifier", | |
133 "a lowercase letter or underscore"); | |
134 if (!status.isOK) { | |
135 return status; | |
136 } | |
137 } | |
138 // should not have upper-case letters | |
139 for (String identifier in identifiers) { | |
140 for (int c in identifier.codeUnits) { | |
141 if (isUpperCase(c)) { | |
142 return new RefactoringStatus.warning( | |
143 "Library name should consist of lowercase identifier separated by do
ts."); | |
144 } | |
145 } | |
146 } | |
147 // OK | |
148 return new RefactoringStatus(); | |
149 } | |
150 | |
151 /** | |
152 * Returns the [RefactoringStatus] with severity: | |
153 * OK if the name is valid; | |
154 * WARNING if the name is discouraged; | |
155 * ERROR if the name is illegal. | |
156 */ | |
157 RefactoringStatus validateMethodName(String name) { | |
158 return _validateLowerCamelCase(name, "Method"); | |
159 } | |
160 | |
161 /** | |
162 * Returns the [RefactoringStatus] with severity: | |
163 * OK if the name is valid; | |
164 * WARNING if the name is discouraged; | |
165 * ERROR if the name is illegal. | |
166 */ | |
167 RefactoringStatus validateParameterName(String name) { | |
168 return _validateLowerCamelCase(name, "Parameter"); | |
169 } | |
170 | |
171 /** | |
172 * Returns the [RefactoringStatus] with severity: | |
173 * OK if the name is valid; | |
174 * WARNING if the name is discouraged; | |
175 * ERROR if the name is illegal. | |
176 */ | |
177 RefactoringStatus validateVariableName(String name) { | |
178 return _validateLowerCamelCase(name, "Variable"); | |
179 } | |
180 | |
181 RefactoringStatus _validateIdentifier(String identifier, String desc, | |
182 String beginDesc) { | |
183 // has leading/trailing spaces | |
184 String trimmed = identifier.trim(); | |
185 if (identifier != trimmed) { | |
186 String message = "$desc must not start or end with a blank."; | |
187 return new RefactoringStatus.error(message); | |
188 } | |
189 // empty | |
190 int length = identifier.length; | |
191 if (length == 0) { | |
192 String message = "$desc must not be empty."; | |
193 return new RefactoringStatus.error(message); | |
194 } | |
195 int currentChar = identifier.codeUnitAt(0); | |
196 if (!isLetter(currentChar) && | |
197 currentChar != CHAR_UNDERSCORE && | |
198 currentChar != CHAR_DOLLAR) { | |
199 String message = "$desc must begin with $beginDesc."; | |
200 return new RefactoringStatus.error(message); | |
201 } | |
202 for (int i = 1; i < length; i++) { | |
203 currentChar = identifier.codeUnitAt(i); | |
204 if (!isLetterOrDigit(currentChar) && | |
205 currentChar != CHAR_UNDERSCORE && | |
206 currentChar != CHAR_DOLLAR) { | |
207 String charStr = new String.fromCharCode(currentChar); | |
208 String message = "$desc must not contain '$charStr'."; | |
209 return new RefactoringStatus.error(message); | |
210 } | |
211 } | |
212 return new RefactoringStatus(); | |
213 } | |
214 | |
215 /** | |
216 * Validates [identifier], should be lower camel case. | |
217 */ | |
218 RefactoringStatus _validateLowerCamelCase(String identifier, String desc) { | |
219 desc += ' name'; | |
220 // null | |
221 if (identifier == null) { | |
222 String message = "$desc must not be null."; | |
223 return new RefactoringStatus.error(message); | |
224 } | |
225 // is not identifier | |
226 RefactoringStatus status = | |
227 _validateIdentifier(identifier, desc, "a lowercase letter or underscore"); | |
228 if (!status.isOK) { | |
229 return status; | |
230 } | |
231 // is private, OK | |
232 if (identifier.codeUnitAt(0) == CHAR_UNDERSCORE) { | |
233 return new RefactoringStatus(); | |
234 } | |
235 // leading $, OK | |
236 if (identifier.codeUnitAt(0) == CHAR_DOLLAR) { | |
237 return new RefactoringStatus(); | |
238 } | |
239 // does not start with lower case | |
240 if (!isLowerCase(identifier.codeUnitAt(0))) { | |
241 String message = "$desc should start with a lowercase letter."; | |
242 return new RefactoringStatus.warning(message); | |
243 } | |
244 // OK | |
245 return new RefactoringStatus(); | |
246 } | |
247 | |
248 /** | |
249 * Validate the given identifier, which should be upper camel case. | |
250 */ | |
251 RefactoringStatus _validateUpperCamelCase(String identifier, String desc) { | |
252 desc += ' name'; | |
253 // null | |
254 if (identifier == null) { | |
255 String message = "$desc must not be null."; | |
256 return new RefactoringStatus.error(message); | |
257 } | |
258 // is not identifier | |
259 RefactoringStatus status = | |
260 _validateIdentifier(identifier, desc, "an uppercase letter or underscore")
; | |
261 if (!status.isOK) { | |
262 return status; | |
263 } | |
264 // is private, OK | |
265 if (identifier.codeUnitAt(0) == CHAR_UNDERSCORE) { | |
266 return new RefactoringStatus(); | |
267 } | |
268 // leading $, OK | |
269 if (identifier.codeUnitAt(0) == CHAR_DOLLAR) { | |
270 return new RefactoringStatus(); | |
271 } | |
272 // does not start with upper case | |
273 if (!isUpperCase(identifier.codeUnitAt(0))) { | |
274 // By convention, class names usually start with an uppercase letter | |
275 String message = "$desc should start with an uppercase letter."; | |
276 return new RefactoringStatus.warning(message); | |
277 } | |
278 // OK | |
279 return new RefactoringStatus(); | |
280 } | |
OLD | NEW |