| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /// This file contains the node classes for the internal representations of YAML | 5 /// This file contains the node classes for the internal representations of YAML |
| 6 /// documents. These nodes are used for both the serialization tree and the | 6 /// documents. These nodes are used for both the serialization tree and the |
| 7 /// representation graph. | 7 /// representation graph. |
| 8 library yaml.model; | 8 library yaml.model; |
| 9 | 9 |
| 10 import 'package:source_maps/source_maps.dart'; | 10 import 'package:source_span/source_span.dart'; |
| 11 | 11 |
| 12 import 'equality.dart'; | 12 import 'equality.dart'; |
| 13 import 'parser.dart'; | 13 import 'parser.dart'; |
| 14 import 'visitor.dart'; | 14 import 'visitor.dart'; |
| 15 import 'yaml_exception.dart'; | 15 import 'yaml_exception.dart'; |
| 16 | 16 |
| 17 /// The prefix for tag types defined by the YAML spec. | 17 /// The prefix for tag types defined by the YAML spec. |
| 18 const _YAML_URI_PREFIX = "tag:yaml.org,2002:"; | 18 const _YAML_URI_PREFIX = "tag:yaml.org,2002:"; |
| 19 | 19 |
| 20 /// A tag that indicates the type of a YAML node. | 20 /// A tag that indicates the type of a YAML node. |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 | 76 |
| 77 /// The abstract class for YAML nodes. | 77 /// The abstract class for YAML nodes. |
| 78 abstract class Node { | 78 abstract class Node { |
| 79 /// Every YAML node has a tag that describes its type. | 79 /// Every YAML node has a tag that describes its type. |
| 80 Tag tag; | 80 Tag tag; |
| 81 | 81 |
| 82 /// Any YAML node can have an anchor associated with it. | 82 /// Any YAML node can have an anchor associated with it. |
| 83 String anchor; | 83 String anchor; |
| 84 | 84 |
| 85 /// The source span for this node. | 85 /// The source span for this node. |
| 86 Span span; | 86 SourceSpan span; |
| 87 | 87 |
| 88 Node(this.tag, this.span, [this.anchor]); | 88 Node(this.tag, this.span, [this.anchor]); |
| 89 | 89 |
| 90 bool operator ==(other) { | 90 bool operator ==(other) { |
| 91 if (other is! Node) return false; | 91 if (other is! Node) return false; |
| 92 return tag == other.tag; | 92 return tag == other.tag; |
| 93 } | 93 } |
| 94 | 94 |
| 95 int get hashCode => tag.hashCode ^ anchor.hashCode; | 95 int get hashCode => tag.hashCode ^ anchor.hashCode; |
| 96 | 96 |
| 97 visit(Visitor v); | 97 visit(Visitor v); |
| 98 } | 98 } |
| 99 | 99 |
| 100 /// A sequence node represents an ordered list of nodes. | 100 /// A sequence node represents an ordered list of nodes. |
| 101 class SequenceNode extends Node { | 101 class SequenceNode extends Node { |
| 102 /// The nodes in the sequence. | 102 /// The nodes in the sequence. |
| 103 List<Node> content; | 103 List<Node> content; |
| 104 | 104 |
| 105 SequenceNode(String tagName, this.content, Span span) | 105 SequenceNode(String tagName, this.content, SourceSpan span) |
| 106 : super(new Tag.sequence(tagName), span); | 106 : super(new Tag.sequence(tagName), span); |
| 107 | 107 |
| 108 /// Two sequences are equal if their tags and contents are equal. | 108 /// Two sequences are equal if their tags and contents are equal. |
| 109 bool operator ==(other) { | 109 bool operator ==(other) { |
| 110 // Should be super != other; bug 2554 | 110 // Should be super != other; bug 2554 |
| 111 if (!(super == other) || other is! SequenceNode) return false; | 111 if (!(super == other) || other is! SequenceNode) return false; |
| 112 if (content.length != other.content.length) return false; | 112 if (content.length != other.content.length) return false; |
| 113 for (var i = 0; i < content.length; i++) { | 113 for (var i = 0; i < content.length; i++) { |
| 114 if (content[i] != other.content[i]) return false; | 114 if (content[i] != other.content[i]) return false; |
| 115 } | 115 } |
| 116 return true; | 116 return true; |
| 117 } | 117 } |
| 118 | 118 |
| 119 String toString() => '$tag [${content.map((e) => '$e').join(', ')}]'; | 119 String toString() => '$tag [${content.map((e) => '$e').join(', ')}]'; |
| 120 | 120 |
| 121 int get hashCode => super.hashCode ^ deepHashCode(content); | 121 int get hashCode => super.hashCode ^ deepHashCode(content); |
| 122 | 122 |
| 123 visit(Visitor v) => v.visitSequence(this); | 123 visit(Visitor v) => v.visitSequence(this); |
| 124 } | 124 } |
| 125 | 125 |
| 126 /// An alias node is a reference to an anchor. | 126 /// An alias node is a reference to an anchor. |
| 127 class AliasNode extends Node { | 127 class AliasNode extends Node { |
| 128 AliasNode(String anchor, Span span) | 128 AliasNode(String anchor, SourceSpan span) |
| 129 : super(new Tag.scalar(Tag.yaml("str")), span, anchor); | 129 : super(new Tag.scalar(Tag.yaml("str")), span, anchor); |
| 130 | 130 |
| 131 visit(Visitor v) => v.visitAlias(this); | 131 visit(Visitor v) => v.visitAlias(this); |
| 132 } | 132 } |
| 133 | 133 |
| 134 /// A scalar node represents all YAML nodes that have a single value. | 134 /// A scalar node represents all YAML nodes that have a single value. |
| 135 class ScalarNode extends Node { | 135 class ScalarNode extends Node { |
| 136 /// The string value of the scalar node, if it was created by the parser. | 136 /// The string value of the scalar node, if it was created by the parser. |
| 137 final String _content; | 137 final String _content; |
| 138 | 138 |
| 139 /// The Dart value of the scalar node, if it was created by the composer. | 139 /// The Dart value of the scalar node, if it was created by the composer. |
| 140 final value; | 140 final value; |
| 141 | 141 |
| 142 /// Creates a new Scalar node. | 142 /// Creates a new Scalar node. |
| 143 /// | 143 /// |
| 144 /// Exactly one of [content] and [value] should be specified. Content should | 144 /// Exactly one of [content] and [value] should be specified. Content should |
| 145 /// be specified for a newly-parsed scalar that hasn't yet been composed. | 145 /// be specified for a newly-parsed scalar that hasn't yet been composed. |
| 146 /// Value should be specified for a composed scalar, although `null` is a | 146 /// Value should be specified for a composed scalar, although `null` is a |
| 147 /// valid value. | 147 /// valid value. |
| 148 ScalarNode(String tagName, Span span, {String content, this.value}) | 148 ScalarNode(String tagName, SourceSpan span, {String content, this.value}) |
| 149 : _content = content, | 149 : _content = content, |
| 150 super(new Tag.scalar(tagName), span); | 150 super(new Tag.scalar(tagName), span); |
| 151 | 151 |
| 152 /// Two scalars are equal if their string representations are equal. | 152 /// Two scalars are equal if their string representations are equal. |
| 153 bool operator ==(other) { | 153 bool operator ==(other) { |
| 154 // Should be super != other; bug 2554 | 154 // Should be super != other; bug 2554 |
| 155 if (!(super == other) || other is! ScalarNode) return false; | 155 if (!(super == other) || other is! ScalarNode) return false; |
| 156 return content == other.content; | 156 return content == other.content; |
| 157 } | 157 } |
| 158 | 158 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 int get hashCode => super.hashCode ^ content.hashCode; | 224 int get hashCode => super.hashCode ^ content.hashCode; |
| 225 | 225 |
| 226 visit(Visitor v) => v.visitScalar(this); | 226 visit(Visitor v) => v.visitScalar(this); |
| 227 } | 227 } |
| 228 | 228 |
| 229 /// A mapping node represents an unordered map of nodes to nodes. | 229 /// A mapping node represents an unordered map of nodes to nodes. |
| 230 class MappingNode extends Node { | 230 class MappingNode extends Node { |
| 231 /// The node map. | 231 /// The node map. |
| 232 Map<Node, Node> content; | 232 Map<Node, Node> content; |
| 233 | 233 |
| 234 MappingNode(String tagName, this.content, Span span) | 234 MappingNode(String tagName, this.content, SourceSpan span) |
| 235 : super(new Tag.mapping(tagName), span); | 235 : super(new Tag.mapping(tagName), span); |
| 236 | 236 |
| 237 /// Two mappings are equal if their tags and contents are equal. | 237 /// Two mappings are equal if their tags and contents are equal. |
| 238 bool operator ==(other) { | 238 bool operator ==(other) { |
| 239 // Should be super != other; bug 2554 | 239 // Should be super != other; bug 2554 |
| 240 if (!(super == other) || other is! MappingNode) return false; | 240 if (!(super == other) || other is! MappingNode) return false; |
| 241 if (content.length != other.content.length) return false; | 241 if (content.length != other.content.length) return false; |
| 242 for (var key in content.keys) { | 242 for (var key in content.keys) { |
| 243 if (!other.content.containsKey(key)) return false; | 243 if (!other.content.containsKey(key)) return false; |
| 244 if (content[key] != other.content[key]) return false; | 244 if (content[key] != other.content[key]) return false; |
| 245 } | 245 } |
| 246 return true; | 246 return true; |
| 247 } | 247 } |
| 248 | 248 |
| 249 String toString() { | 249 String toString() { |
| 250 var strContent = content.keys | 250 var strContent = content.keys |
| 251 .map((k) => '${k}: ${content[k]}') | 251 .map((k) => '${k}: ${content[k]}') |
| 252 .join(', '); | 252 .join(', '); |
| 253 return '$tag {$strContent}'; | 253 return '$tag {$strContent}'; |
| 254 } | 254 } |
| 255 | 255 |
| 256 int get hashCode => super.hashCode ^ deepHashCode(content); | 256 int get hashCode => super.hashCode ^ deepHashCode(content); |
| 257 | 257 |
| 258 visit(Visitor v) => v.visitMapping(this); | 258 visit(Visitor v) => v.visitMapping(this); |
| 259 } | 259 } |
| OLD | NEW |