public Node/*!*/ Represent(object data) { Node node; bool ignoreAlias = HasIdentity(data); object dataKey = data ?? _NullKey; if (!ignoreAlias) { if (_representedObjects.TryGetValue(dataKey, out node)) { if (node == null) { LinkNode link = new LinkNode(); List<LinkNode> list; if (!_links.TryGetValue(dataKey, out list)) { _links.Add(dataKey, list = new List<LinkNode>()); } list.Add(link); return link; } return node; } _representedObjects.Add(dataKey, null); } node = CreateNode(data); if (!ignoreAlias) { _representedObjects[dataKey] = node; List<LinkNode> list; if (_links.TryGetValue(dataKey, out list)) { _links.Remove(dataKey); foreach (LinkNode n in list) { n.Linked = node; } } } return node; }
//TODO: remove Ruby-specific stuff from this layer public Hash ConstructMapping(Node mappingNode) { MappingNode map = mappingNode as MappingNode; if (map == null) { throw new ConstructorException("expected a mapping node, but found: " + mappingNode); } Hash mapping = new Hash(_globalScope.Context); LinkedList <Hash> merge = null; foreach (KeyValuePair <Node, Node> entry in map.Nodes) { Node key_v = entry.Key; Node value_v = entry.Value; if (key_v.Tag == "tag:yaml.org,2002:merge") { if (merge != null) { throw new ConstructorException("while constructing a mapping: found duplicate merge key"); } SequenceNode sequence; merge = new LinkedList <Hash>(); if (value_v is MappingNode) { merge.AddLast(ConstructMapping(value_v)); } else if ((sequence = value_v as SequenceNode) != null) { foreach (Node subNode in sequence.Nodes) { if (!(subNode is MappingNode)) { throw new ConstructorException("while constructing a mapping: expected a mapping for merging, but found: " + subNode); } merge.AddFirst(ConstructMapping(subNode)); } } else { throw new ConstructorException("while constructing a mapping: expected a mapping or list of mappings for merging, but found: " + value_v); } } else if (key_v.Tag == "tag:yaml.org,2002:value") { if (mapping.ContainsKey("=")) { throw new ConstructorException("while construction a mapping: found duplicate value key"); } mapping.Add("=", ConstructObject(value_v)); } else { object kk = ConstructObject(key_v); object vv = ConstructObject(value_v); LinkNode linkNode = vv as LinkNode; if (linkNode != null) { AddFixer(linkNode.Linked, delegate(Node node, object real) { IDictionaryOps.SetElement(_globalScope.Context, mapping, kk, real); }); } IDictionaryOps.SetElement(_globalScope.Context, mapping, kk, vv); } } if (null != merge) { merge.AddLast(mapping); mapping = new Hash(_globalScope.Context); foreach (Hash m in merge) { foreach (KeyValuePair <object, object> e in m) { IDictionaryOps.SetElement(_globalScope.Context, mapping, e.Key, e.Value); } } } return(mapping); }