Creates a new PropertyPath. These can be stored to avoid excessive parsing of path strings.
The provided path
should be a String or a List. If it is a list it
should contain only Symbols and integers. This can be used to avoid
parsing.
Note that this constructor will canonicalize identical paths in some cases
to save memory, but this is not guaranteed. Use ==
for comparions
purposes instead of identical
.
// Dart note: this is ported from `function getPath`.
factory PropertyPath([path]) {
if (path is PropertyPath) return path;
if (path == null || (path is List && path.isEmpty)) path = '';
if (path is List) {
var copy = new List.from(path, growable: false);
for (var segment in copy) {
// Dart note: unlike Javascript, we don't support arbitraty objects that
// can be converted to a String.
// TODO(sigmund): consider whether we should support that here. It might
// be easier to add support for that if we switch first to use strings
// for everything instead of symbols.
if (segment is! int && segment is! String && segment is! Symbol) {
throw new ArgumentError(
'List must contain only ints, Strings, and Symbols');
}
}
return new PropertyPath._(copy);
}
var pathObj = _pathCache[path];
if (pathObj != null) return pathObj;
final segments = new _PathParser().parse(path);
if (segments == null) return _InvalidPropertyPath._instance;
// TODO(jmesserly): we could use an UnmodifiableListView here, but that adds
// memory overhead.
pathObj = new PropertyPath._(segments.toList(growable: false));
if (_pathCache.length >= _pathCacheLimit) {
_pathCache.remove(_pathCache.keys.first);
}
_pathCache[path] = pathObj;
return pathObj;
}