| 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 |