OLD | NEW |
| (Empty) |
1 // Copyright (c) 2014, 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 library yaml.yaml_node_wrapper; | |
6 | |
7 import 'dart:collection'; | |
8 | |
9 import 'package:collection/collection.dart' as pkg_collection; | |
10 import 'package:source_span/source_span.dart'; | |
11 | |
12 import 'null_span.dart'; | |
13 import 'style.dart'; | |
14 import 'yaml_node.dart'; | |
15 | |
16 /// A wrapper that makes a normal Dart map behave like a [YamlMap]. | |
17 class YamlMapWrapper extends MapBase | |
18 with pkg_collection.UnmodifiableMapMixin | |
19 implements YamlMap { | |
20 final CollectionStyle style = CollectionStyle.ANY; | |
21 | |
22 final Map _dartMap; | |
23 | |
24 final SourceSpan span; | |
25 | |
26 final Map<dynamic, YamlNode> nodes; | |
27 | |
28 Map get value => this; | |
29 | |
30 Iterable get keys => _dartMap.keys; | |
31 | |
32 YamlMapWrapper(Map dartMap, sourceUrl) | |
33 : this._(dartMap, new NullSpan(sourceUrl)); | |
34 | |
35 YamlMapWrapper._(Map dartMap, SourceSpan span) | |
36 : _dartMap = dartMap, | |
37 span = span, | |
38 nodes = new _YamlMapNodes(dartMap, span); | |
39 | |
40 operator [](Object key) { | |
41 var value = _dartMap[key]; | |
42 if (value is Map) return new YamlMapWrapper._(value, span); | |
43 if (value is List) return new YamlListWrapper._(value, span); | |
44 return value; | |
45 } | |
46 | |
47 int get hashCode => _dartMap.hashCode; | |
48 | |
49 operator ==(Object other) => | |
50 other is YamlMapWrapper && other._dartMap == _dartMap; | |
51 } | |
52 | |
53 /// The implementation of [YamlMapWrapper.nodes] as a wrapper around the Dart | |
54 /// map. | |
55 class _YamlMapNodes extends MapBase<dynamic, YamlNode> | |
56 with pkg_collection.UnmodifiableMapMixin<dynamic, YamlNode> { | |
57 final Map _dartMap; | |
58 | |
59 final SourceSpan _span; | |
60 | |
61 Iterable get keys => _dartMap.keys.map((key) => | |
62 new YamlScalar.internalWithSpan(key, _span)); | |
63 | |
64 _YamlMapNodes(this._dartMap, this._span); | |
65 | |
66 YamlNode operator [](Object key) { | |
67 // Use "as" here because key being assigned to invalidates type propagation. | |
68 if (key is YamlScalar) key = (key as YamlScalar).value; | |
69 if (!_dartMap.containsKey(key)) return null; | |
70 return _nodeForValue(_dartMap[key], _span); | |
71 } | |
72 | |
73 int get hashCode => _dartMap.hashCode; | |
74 | |
75 operator ==(Object other) => | |
76 other is _YamlMapNodes && other._dartMap == _dartMap; | |
77 } | |
78 | |
79 // TODO(nweiz): Use UnmodifiableListMixin when issue 18970 is fixed. | |
80 /// A wrapper that makes a normal Dart list behave like a [YamlList]. | |
81 class YamlListWrapper extends ListBase implements YamlList { | |
82 final CollectionStyle style = CollectionStyle.ANY; | |
83 | |
84 final List _dartList; | |
85 | |
86 final SourceSpan span; | |
87 | |
88 final List<YamlNode> nodes; | |
89 | |
90 List get value => this; | |
91 | |
92 int get length => _dartList.length; | |
93 | |
94 set length(int index) { | |
95 throw new UnsupportedError("Cannot modify an unmodifiable List."); | |
96 } | |
97 | |
98 YamlListWrapper(List dartList, sourceUrl) | |
99 : this._(dartList, new NullSpan(sourceUrl)); | |
100 | |
101 YamlListWrapper._(List dartList, SourceSpan span) | |
102 : _dartList = dartList, | |
103 span = span, | |
104 nodes = new _YamlListNodes(dartList, span); | |
105 | |
106 operator [](int index) { | |
107 var value = _dartList[index]; | |
108 if (value is Map) return new YamlMapWrapper._(value, span); | |
109 if (value is List) return new YamlListWrapper._(value, span); | |
110 return value; | |
111 } | |
112 | |
113 operator []=(int index, value) { | |
114 throw new UnsupportedError("Cannot modify an unmodifiable List."); | |
115 } | |
116 | |
117 int get hashCode => _dartList.hashCode; | |
118 | |
119 operator ==(Object other) => | |
120 other is YamlListWrapper && other._dartList == _dartList; | |
121 } | |
122 | |
123 // TODO(nweiz): Use UnmodifiableListMixin when issue 18970 is fixed. | |
124 /// The implementation of [YamlListWrapper.nodes] as a wrapper around the Dart | |
125 /// list. | |
126 class _YamlListNodes extends ListBase<YamlNode> { | |
127 final List _dartList; | |
128 | |
129 final SourceSpan _span; | |
130 | |
131 int get length => _dartList.length; | |
132 | |
133 set length(int index) { | |
134 throw new UnsupportedError("Cannot modify an unmodifiable List."); | |
135 } | |
136 | |
137 _YamlListNodes(this._dartList, this._span); | |
138 | |
139 YamlNode operator [](int index) => _nodeForValue(_dartList[index], _span); | |
140 | |
141 operator []=(int index, value) { | |
142 throw new UnsupportedError("Cannot modify an unmodifiable List."); | |
143 } | |
144 | |
145 int get hashCode => _dartList.hashCode; | |
146 | |
147 operator ==(Object other) => | |
148 other is _YamlListNodes && other._dartList == _dartList; | |
149 } | |
150 | |
151 YamlNode _nodeForValue(value, SourceSpan span) { | |
152 if (value is Map) return new YamlMapWrapper._(value, span); | |
153 if (value is List) return new YamlListWrapper._(value, span); | |
154 return new YamlScalar.internalWithSpan(value, span); | |
155 } | |
OLD | NEW |