in lib/src/pubspec.dart [415:504]
Map<String, PackageRange> _parseDependencies(String field, YamlNode? node) {
var dependencies = <String, PackageRange>{};
// Allow an empty dependencies key.
if (node == null || node.value == null) return dependencies;
if (node is! YamlMap) {
_error('"$field" field must be a map.', node.span);
}
var nonStringNode = node.nodes.keys
.firstWhere((e) => e.value is! String, orElse: () => null);
if (nonStringNode != null) {
_error('A dependency name must be a string.', nonStringNode.span);
}
node.nodes.forEach((nameNode, specNode) {
var name = nameNode.value;
var spec = specNode.value;
if (fields['name'] != null && name == this.name) {
_error('A package may not list itself as a dependency.', nameNode.span);
}
YamlNode? descriptionNode;
String? sourceName;
VersionConstraint versionConstraint = VersionRange();
var features = const <String, FeatureDependency>{};
if (spec == null) {
sourceName = _sources!.defaultSource.name;
} else if (spec is String) {
sourceName = _sources!.defaultSource.name;
versionConstraint = _parseVersionConstraint(specNode);
} else if (spec is Map) {
// Don't write to the immutable YAML map.
spec = Map.from(spec);
var specMap = specNode as YamlMap;
if (spec.containsKey('version')) {
spec.remove('version');
versionConstraint = _parseVersionConstraint(specMap.nodes['version']);
}
if (spec.containsKey('features')) {
spec.remove('features');
features = _parseDependencyFeatures(specMap.nodes['features']);
}
var sourceNames = spec.keys.toList();
if (sourceNames.length > 1) {
_error('A dependency may only have one source.', specNode.span);
} else if (sourceNames.isEmpty) {
// Default to a hosted dependency if no source is specified.
sourceName = 'hosted';
}
sourceName ??= sourceNames.single;
if (sourceName is! String) {
_error('A source name must be a string.',
specMap.nodes.keys.single.span);
}
descriptionNode ??= specMap.nodes[sourceName];
} else {
_error('A dependency specification must be a string or a mapping.',
specNode.span);
}
// Let the source validate the description.
var ref = _wrapFormatException('description', descriptionNode?.span, () {
String? pubspecPath;
var location = _location;
if (location != null && _isFileUri(location)) {
pubspecPath = path.fromUri(_location);
}
return _sources![sourceName]!.parseRef(
name,
descriptionNode?.value,
containingPath: pubspecPath,
languageVersion: languageVersion,
);
}, targetPackage: name);
dependencies[name] =
ref.withConstraint(versionConstraint).withFeatures(features);
});
return dependencies;
}