Chromium Code Reviews| Index: pkg/yaml/lib/src/yaml_node_wrapper.dart |
| diff --git a/pkg/yaml/lib/src/yaml_node_wrapper.dart b/pkg/yaml/lib/src/yaml_node_wrapper.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..f686b5ad123377a1c26ac570563892ba9dc8be59 |
| --- /dev/null |
| +++ b/pkg/yaml/lib/src/yaml_node_wrapper.dart |
| @@ -0,0 +1,131 @@ |
| +// Copyright (c) 2014, 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 yaml.yaml_node_wrapper; |
| + |
| +import 'dart:collection'; |
| + |
| +import 'package:collection/collection.dart' as pc; |
|
Bob Nystrom
2014/06/21 00:14:15
Why "pc"? How about "collection"?
nweiz
2014/06/23 22:23:07
"pc" is for "package collection". Just calling it
Bob Nystrom
2014/06/23 23:11:44
I didn't infer that abbreviation at all. The other
nweiz
2014/06/24 00:03:09
The point of using a prefix is to make it clear wh
|
| +import 'package:source_maps/source_maps.dart'; |
| + |
| +import 'dummy_span.dart'; |
| +import 'yaml_node.dart'; |
| + |
| +/// A wrapper that makes a normal Dart map behave like a [YamlMap]. |
| +class YamlMapWrapper extends MapBase |
| + with pc.UnmodifiableMapMixin<dynamic, YamlNode> |
| + implements YamlMap { |
| + final Map _dartMap; |
| + |
| + final Span span; |
| + |
| + final Map<dynamic, YamlNode> nodes; |
| + |
| + Map get value => this; |
| + |
| + Iterable get keys => _dartMap.keys; |
| + |
| + YamlMapWrapper(Map dartMap, String sourceName) |
| + : this._(dartMap, new DummySpan(sourceName)); |
| + |
| + YamlMapWrapper._(Map dartMap, Span span) |
| + : _dartMap = dartMap, |
| + span = span, |
| + nodes = new _YamlMapNodes(dartMap, span); |
| + |
| + operator [](Object key) { |
| + var value = _dartMap[key]; |
| + if (value is Map) return new YamlMapWrapper._(value, span); |
| + if (value is List) return new YamlListWrapper._(value, span); |
|
Bob Nystrom
2014/06/21 00:14:15
Since the wrapper classes don't implement equality
nweiz
2014/06/23 22:23:07
I like implementing equality in terms of the wrapp
|
| + return value; |
| + } |
| +} |
| + |
| +/// The implementation of [YamlMapWrapper.nodes] as a wrapper around the Dart |
| +/// map. |
| +class _YamlMapNodes extends MapBase<dynamic, YamlNode> |
| + with pc.UnmodifiableMapMixin<dynamic, YamlNode> { |
| + final Map _dartMap; |
| + |
| + final Span _span; |
| + |
| + Iterable get keys => |
| + _dartMap.keys.map((key) => new YamlScalar.internal(key, _span)); |
| + |
| + _YamlMapNodes(this._dartMap, this._span); |
| + |
| + YamlNode operator [](Object key) { |
| + if (key is YamlScalar) key = key.value; |
| + if (!_dartMap.containsKey(key)) return null; |
| + var value = _dartMap[key]; |
| + if (value is Map) return new YamlMapWrapper._(value, _span); |
| + if (value is List) return new YamlListWrapper._(value, _span); |
|
Bob Nystrom
2014/06/21 00:14:15
Encapsulate this little blob of logic in a helper
nweiz
2014/06/23 22:23:07
Done.
|
| + return new YamlScalar.internal(value, _span); |
| + } |
| +} |
| + |
| +// TODO(nweiz): Use UnmodifiableListMixin when issue 18970 is fixed. |
| +/// A wrapper that makes a normal Dart list behave like a [YamlList]. |
| +class YamlListWrapper extends ListBase implements YamlList { |
| + final List _dartList; |
| + |
| + final Span span; |
| + |
| + final List<YamlNode> nodes; |
| + |
| + List get value => this; |
| + |
| + int get length => _dartList.length; |
| + |
| + set length(int index) { |
| + throw new UnsupportedError("Cannot modify an unmodifiable List"); |
|
Bob Nystrom
2014/06/21 00:14:15
"."
nweiz
2014/06/23 22:23:07
Done, although this now doesn't match the "dart:"
Bob Nystrom
2014/06/23 23:11:44
Ugh. Well, these are better. :)
|
| + } |
| + |
| + YamlListWrapper(List dartList, String sourceName) |
| + : this._(dartList, new DummySpan(sourceName)); |
| + |
| + YamlListWrapper._(List dartList, Span span) |
| + : _dartList = dartList, |
| + span = span, |
| + nodes = new _YamlListNodes(dartList, span); |
| + |
| + operator [](int index) { |
| + var value = _dartList[index]; |
| + if (value is Map) return new YamlMapWrapper._(value, span); |
| + if (value is List) return new YamlListWrapper._(value, span); |
| + return value; |
| + } |
| + |
| + operator []=(int index, value) { |
| + throw new UnsupportedError("Cannot modify an unmodifiable List"); |
|
Bob Nystrom
2014/06/21 00:14:15
"."
nweiz
2014/06/23 22:23:07
Done.
|
| + } |
| +} |
| + |
| +// TODO(nweiz): Use UnmodifiableListMixin when issue 18970 is fixed. |
| +/// The implementation of [YamlListWrapper.nodes] as a wrapper around the Dart |
| +/// list. |
| +class _YamlListNodes extends ListBase<YamlNode> { |
| + final List _dartList; |
| + |
| + final Span _span; |
| + |
| + int get length => _dartList.length; |
| + |
| + set length(int index) { |
| + throw new UnsupportedError("Cannot modify an unmodifiable List"); |
| + } |
| + |
| + _YamlListNodes(this._dartList, this._span); |
| + |
| + YamlNode operator [](int index) { |
| + var value = _dartList[index]; |
| + if (value is Map) return new YamlMapWrapper._(value, _span); |
| + if (value is List) return new YamlListWrapper._(value, _span); |
| + return new YamlScalar.internal(value, _span); |
| + } |
| + |
| + operator []=(int index, value) { |
| + throw new UnsupportedError("Cannot modify an unmodifiable List"); |
| + } |
| +} |