| // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| import 'package:analyzer/dart/ast/token.dart'; |
| |
| // A camel case string here is defined as: |
| // * An arbitrary number of optional leading `_`s or `$`s, |
| // * followed by an upper-case letter, `$` or `?`, |
| // * followed by any number of letters, digits, `?` or `$`s. |
| // |
| // This ensures that the text contains a `$`, `?` or upper-case letter |
| // before any lower-case letter or digit, and no letters or `?`s before an |
| // `_`. |
| final _camelCasePattern = RegExp(r'^_*(?:\$+_+)*[$?A-Z][$?a-zA-Z\d]*$'); |
| |
| // An identifier here is defined as: |
| // * A sequence of `_`, `$`, letters or digits, |
| // * where no `$` comes after a digit. |
| final _identifier = RegExp(r'^[_$a-z]+(\d[_a-z\d]*)?$', caseSensitive: false); |
| |
| // A lower camel-case here is defined as: |
| // * Any number of optional leading underscores, |
| // * a lower case letter, `$` or `?` followed by a "word-tail" |
| // (a sequence of lower-case letters, digits, `$` or `?`), |
| // * followed by any number of either |
| // * an upper case letter followed by a word tail, or |
| // * an underscore and then a digit followed by a word tail. |
| // * and potentially ended by a single optional underscore. |
| final _lowerCamelCase = RegExp( |
| r'^_*[?$a-z][a-z\d?$]*(?:(?:[A-Z]|_\d)[a-z\d?$]*)*_?$', |
| ); |
| |
| @Deprecated('Prefer: ascii_utils.isValidFileName') |
| final _lowerCaseUnderScoreWithDots = RegExp( |
| r'^_?[_a-z\d]*(?:\.[a-z][_a-z\d]*)*$', |
| ); |
| |
| // A lower-case underscored (snake-case) with leading underscores is defined as |
| // * An optional leading sequence of any number of underscores, |
| // * followed by a sequence of lower-case letters, digits and underscores, |
| // * with no two adjacent underscores, |
| // * and not ending in an underscore. |
| final _lowerCaseUnderScoreWithLeadingUnderscores = RegExp( |
| r'^_*[a-z](?:_?[a-z\d])*$', |
| ); |
| |
| final Set<String> _reservedWords = { |
| for (var entry in Keyword.keywords.entries) |
| if (entry.value.isReservedWord) entry.key, |
| }; |
| |
| // A library prefix here is defined as: |
| // * An optional leading `?`, |
| // * then any number of underscores, `_`, |
| // * then a lower-case letter, |
| // * followed by any number of lower-case letters, digits and underscores. |
| final _validLibraryPrefix = RegExp(r'^\$?_*[a-z][_a-z\d]*$'); |
| |
| /// Whether this [string] is formatted in `CamelCase`. |
| bool isCamelCase(String string) => _isCamelCase(string); |
| |
| /// Whether this [fileName] is a Dart file. |
| bool isDartFileName(String fileName) => fileName.endsWith('.dart'); |
| |
| /// Whether [id] is `lowerCamelCase`. |
| bool isLowerCamelCase(String id) => |
| id.length == 1 && isUpperCase(id.codeUnitAt(0)) || |
| id == '_' || |
| _lowerCamelCase.hasMatch(id); |
| |
| /// Whether this [id] is `lower_camel_case_with_underscores_or.dots`. |
| bool isLowerCaseUnderScoreWithDots(String id) => |
| // ignore: deprecated_member_use_from_same_package |
| _lowerCaseUnderScoreWithDots.hasMatch(id); |
| |
| /// Whether the given code unit [c] is upper case. |
| bool isUpperCase(int c) => c >= 0x40 && c <= 0x5A; |
| |
| /// Whether this [libraryPrefix] is valid. |
| bool isValidLibraryPrefix(String libraryPrefix) => |
| _validLibraryPrefix.hasMatch(libraryPrefix); |
| |
| /// Whether this [id] is a valid package name. |
| bool isValidPackageName(String id) => |
| _lowerCaseUnderScoreWithLeadingUnderscores.hasMatch(id) && |
| _isIdentifier(id) && |
| !_isReservedWord(id); |
| |
| bool _isCamelCase(String name) => _camelCasePattern.hasMatch(name); |
| |
| /// Whether this [name] is a legal Dart identifier. |
| bool _isIdentifier(String name) => _identifier.hasMatch(name); |
| |
| /// Whether the given word is a Dart reserved word. |
| bool _isReservedWord(String word) => _reservedWords.contains(word); |