| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2015, 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 /// Utility methods used by more than one library in the package. | |
| 6 library package_config.util; | |
| 7 | |
| 8 import "package:charcode/ascii.dart"; | |
| 9 | |
| 10 // All ASCII characters that are valid in a package name, with space | |
| 11 // for all the invalid ones (including space). | |
| 12 const String _validPackageNameCharacters = | |
| 13 r" ! $ &'()*+,-. 0123456789 ; = " | |
| 14 r"@ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz ~ "; | |
| 15 | |
| 16 /// Tests whether something is a valid Dart package name. | |
| 17 bool isValidPackageName(String string) { | |
| 18 return _findInvalidCharacter(string) < 0; | |
| 19 } | |
| 20 | |
| 21 /// Check if a string is a valid package name. | |
| 22 /// | |
| 23 /// Valid package names contain only characters in [_validPackageNameCharacters] | |
| 24 /// and must contain at least one non-'.' character. | |
| 25 /// | |
| 26 /// Returns `-1` if the string is valid. | |
| 27 /// Otherwise returns the index of the first invalid character, | |
| 28 /// or `string.length` if the string contains no non-'.' character. | |
| 29 int _findInvalidCharacter(String string) { | |
| 30 // Becomes non-zero if any non-'.' character is encountered. | |
| 31 int nonDot = 0; | |
| 32 for (int i = 0; i < string.length; i++) { | |
| 33 var c = string.codeUnitAt(i); | |
| 34 if (c > 0x7f || _validPackageNameCharacters.codeUnitAt(c) <= $space) { | |
| 35 return i; | |
| 36 } | |
| 37 nonDot += c ^ $dot; | |
| 38 } | |
| 39 if (nonDot == 0) return string.length; | |
| 40 return -1; | |
| 41 } | |
| 42 | |
| 43 /// Validate that a Uri is a valid package:URI. | |
| 44 String checkValidPackageUri(Uri packageUri) { | |
| 45 if (packageUri.scheme != "package") { | |
| 46 throw new ArgumentError.value(packageUri, "packageUri", | |
| 47 "Not a package: URI"); | |
| 48 } | |
| 49 if (packageUri.hasAuthority) { | |
| 50 throw new ArgumentError.value(packageUri, "packageUri", | |
| 51 "Package URIs must not have a host part"); | |
| 52 } | |
| 53 if (packageUri.hasQuery) { | |
| 54 // A query makes no sense if resolved to a file: URI. | |
| 55 throw new ArgumentError.value(packageUri, "packageUri", | |
| 56 "Package URIs must not have a query part"); | |
| 57 } | |
| 58 if (packageUri.hasFragment) { | |
| 59 // We could leave the fragment after the URL when resolving, | |
| 60 // but it would be odd if "package:foo/foo.dart#1" and | |
| 61 // "package:foo/foo.dart#2" were considered different libraries. | |
| 62 // Keep the syntax open in case we ever get multiple libraries in one file. | |
| 63 throw new ArgumentError.value(packageUri, "packageUri", | |
| 64 "Package URIs must not have a fragment part"); | |
| 65 } | |
| 66 if (packageUri.path.startsWith('/')) { | |
| 67 throw new ArgumentError.value(packageUri, "packageUri", | |
| 68 "Package URIs must not start with a '/'"); | |
| 69 } | |
| 70 int firstSlash = packageUri.path.indexOf('/'); | |
| 71 if (firstSlash == -1) { | |
| 72 throw new ArgumentError.value(packageUri, "packageUri", | |
| 73 "Package URIs must start with the package name followed by a '/'"); | |
| 74 } | |
| 75 String packageName = packageUri.path.substring(0, firstSlash); | |
| 76 int badIndex = _findInvalidCharacter(packageName); | |
| 77 if (badIndex >= 0) { | |
| 78 if (packageName.isEmpty) { | |
| 79 throw new ArgumentError.value(packageUri, "packageUri", | |
| 80 "Package names mus be non-empty"); | |
| 81 } | |
| 82 if (badIndex == packageName.length) { | |
| 83 throw new ArgumentError.value(packageUri, "packageUri", | |
| 84 "Package names must contain at least one non-'.' character"); | |
| 85 } | |
| 86 assert(badIndex < packageName.length); | |
| 87 int badCharCode = packageName.codeUnitAt(badIndex); | |
| 88 var badChar = "U+" + badCharCode.toRadixString(16).padLeft(4, '0'); | |
| 89 if (badCharCode >= 0x20 && badCharCode <= 0x7e) { | |
| 90 // Printable character. | |
| 91 badChar = "'${packageName[badIndex]}' ($badChar)"; | |
| 92 } | |
| 93 throw new ArgumentError.value(packageUri, "packageUri", | |
| 94 "Package names must not contain $badChar"); | |
| 95 } | |
| 96 return packageName; | |
| 97 } | |
| OLD | NEW |