Chromium Code Reviews| Index: utils/pub/validator/name.dart |
| diff --git a/utils/pub/validator/name.dart b/utils/pub/validator/name.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..b4a2a46d93972e3553f5c2dba102360adc6791df |
| --- /dev/null |
| +++ b/utils/pub/validator/name.dart |
| @@ -0,0 +1,71 @@ |
| +// Copyright (c) 2012, 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. |
| + |
| +library name_validator; |
| + |
| +import 'dart:io'; |
| + |
| +import '../entrypoint.dart'; |
| +import '../io.dart'; |
| +import '../validator.dart'; |
| + |
| +/// Dart reserved words, from the Dart spec. |
| +final _RESERVED_WORDS = [ |
| + "abstract", "as", "dynamic", "export", "external", "factory", "get", |
| + "implements", "import", "library", "operator", "part", "set", "static", |
| + "typedef" |
| +]; |
| + |
| +/// A validator that validates the name of the package and its libraries. |
| +class NameValidator extends Validator { |
| + NameValidator(Entrypoint entrypoint) |
| + : super(entrypoint); |
| + |
| + Future validate() { |
| + _checkName(entrypoint.root.name, 'Package name "${entrypoint.root.name}"'); |
| + |
| + var libDir = join(entrypoint.root.dir, "lib"); |
| + return dirExists(libDir).chain((libDirExists) { |
| + if (!libDirExists) return new Future.immediate([]); |
| + return listDir(libDir, recursive: true); |
| + }).transform((files) { |
| + for (var file in files) { |
| + if (file.contains("/src/")) continue; |
| + if (new Path(file).extension != 'dart') continue; |
| + var libName = new Path(file).filenameWithoutExtension; |
| + _checkName(libName, 'The name of "$file", "$libName",'); |
| + } |
| + }); |
| + } |
| + |
| + void _checkName(String name, String description) { |
| + if (name == "") { |
| + errors.add("$description may not be empty."); |
|
Bob Nystrom
2012/12/06 02:26:43
We should discuss this, but I'm leaning towards th
|
| + } else if (!new RegExp(r"^[a-zA-Z0-9_]*$").hasMatch(name)) { |
| + errors.add("$description may only contain letters, numbers, and " |
| + "underscores."); |
| + } else if (!new RegExp(r"^[a-zA-Z]").hasMatch(name)) { |
| + errors.add("$description must begin with a letter."); |
|
Bob Nystrom
2012/12/06 02:26:43
Or an underscore?
|
| + } else if (new RegExp(r"[A-Z]").hasMatch(name)) { |
| + errors.add('$description must be lower-case. Maybe use ' |
| + '"${_unCamelCase(name)}"?'); |
| + } else if (_RESERVED_WORDS.contains(name)) { |
| + errors.add("$description may not be a reserved word in Dart."); |
| + } |
| + } |
| + |
| + String _unCamelCase(String source) { |
| + var builder = new StringBuffer(); |
| + var lastMatchEnd = 0; |
| + for (var match in new RegExp(r"[a-z]([A-Z])").allMatches(source)) { |
| + builder |
| + ..add(source.substring(lastMatchEnd, match.start + 1)) |
| + ..add("_") |
| + ..add(match.group(1).toLowerCase()); |
| + lastMatchEnd = match.end; |
| + } |
| + builder.add(source.substring(lastMatchEnd)); |
| + return builder.toString().toLowerCase(); |
| + } |
| +} |