in lib/src/packages_file.dart [33:141]
PackageConfig parse(
List<int> source, Uri baseLocation, void Function(Object error) onError) {
if (baseLocation.isScheme('package')) {
onError(PackageConfigArgumentError(
baseLocation, 'baseLocation', 'Must not be a package: URI'));
return PackageConfig.empty;
}
var index = 0;
var packages = <Package>[];
var packageNames = <String>{};
while (index < source.length) {
var ignoreLine = false;
var start = index;
var separatorIndex = -1;
var end = source.length;
var char = source[index++];
if (char == $cr || char == $lf) {
continue;
}
if (char == $colon) {
onError(PackageConfigFormatException(
'Missing package name', source, index - 1));
ignoreLine = true; // Ignore if package name is invalid.
} else {
ignoreLine = char == $hash; // Ignore if comment.
}
var queryStart = -1;
var fragmentStart = -1;
while (index < source.length) {
char = source[index++];
if (char == $colon && separatorIndex < 0) {
separatorIndex = index - 1;
} else if (char == $cr || char == $lf) {
end = index - 1;
break;
} else if (char == $question && queryStart < 0 && fragmentStart < 0) {
queryStart = index - 1;
} else if (char == $hash && fragmentStart < 0) {
fragmentStart = index - 1;
}
}
if (ignoreLine) continue;
if (separatorIndex < 0) {
onError(
PackageConfigFormatException("No ':' on line", source, index - 1));
continue;
}
var packageName = String.fromCharCodes(source, start, separatorIndex);
var invalidIndex = checkPackageName(packageName);
if (invalidIndex >= 0) {
onError(PackageConfigFormatException(
'Not a valid package name', source, start + invalidIndex));
continue;
}
if (queryStart >= 0) {
onError(PackageConfigFormatException(
'Location URI must not have query', source, queryStart));
end = queryStart;
} else if (fragmentStart >= 0) {
onError(PackageConfigFormatException(
'Location URI must not have fragment', source, fragmentStart));
end = fragmentStart;
}
var packageValue = String.fromCharCodes(source, separatorIndex + 1, end);
Uri packageLocation;
try {
packageLocation = Uri.parse(packageValue);
} on FormatException catch (e) {
onError(PackageConfigFormatException.from(e));
continue;
}
var relativeRoot = !hasAbsolutePath(packageLocation);
packageLocation = baseLocation.resolveUri(packageLocation);
if (packageLocation.isScheme('package')) {
onError(PackageConfigFormatException(
'Package URI as location for package', source, separatorIndex + 1));
continue;
}
var path = packageLocation.path;
if (!path.endsWith('/')) {
path += '/';
packageLocation = packageLocation.replace(path: path);
}
if (packageNames.contains(packageName)) {
onError(PackageConfigFormatException(
'Same package name occured more than once', source, start));
continue;
}
var rootUri = packageLocation;
if (path.endsWith('/lib/')) {
// Assume default Pub package layout. Include package itself in root.
rootUri =
packageLocation.replace(path: path.substring(0, path.length - 4));
}
var package = SimplePackage.validate(packageName, rootUri, packageLocation,
_languageVersion, null, relativeRoot, (error) {
if (error is ArgumentError) {
onError(PackageConfigFormatException(error.message, source));
} else {
onError(error);
}
});
if (package != null) {
packages.add(package);
packageNames.add(packageName);
}
}
return SimplePackageConfig(1, packages, null, onError);
}