зеркало из https://github.com/stride3d/SharpYaml.git
Fixed bug in alias resolution.
This commit is contained in:
Родитель
9952b6d2a5
Коммит
453d4461da
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace YamlDotNet.RepresentationModel
|
||||
{
|
||||
|
@ -10,7 +11,7 @@ namespace YamlDotNet.RepresentationModel
|
|||
internal class DocumentLoadingState
|
||||
{
|
||||
private readonly IDictionary<string, YamlNode> anchors = new Dictionary<string, YamlNode>();
|
||||
private readonly IDictionary<YamlNode, object> nodesWithUnresolvedAliases = new Dictionary<YamlNode, object>();
|
||||
private readonly IList<YamlNode> nodesWithUnresolvedAliases = new List<YamlNode>();
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified node to the anchor list.
|
||||
|
@ -62,7 +63,7 @@ namespace YamlDotNet.RepresentationModel
|
|||
/// </param>
|
||||
public void AddNodeWithUnresolvedAliases(YamlNode node)
|
||||
{
|
||||
nodesWithUnresolvedAliases[node] = null;
|
||||
nodesWithUnresolvedAliases.Add(node);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -70,9 +71,19 @@ namespace YamlDotNet.RepresentationModel
|
|||
/// </summary>
|
||||
public void ResolveAliases()
|
||||
{
|
||||
foreach(var node in nodesWithUnresolvedAliases.Keys)
|
||||
foreach(var node in nodesWithUnresolvedAliases)
|
||||
{
|
||||
node.ResolveAliases(this);
|
||||
|
||||
#if DEBUG
|
||||
foreach (var child in node.AllNodes)
|
||||
{
|
||||
if (child is YamlAliasNode)
|
||||
{
|
||||
throw new InvalidOperationException("Error in alias resolution.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using YamlDotNet.Core;
|
||||
|
||||
namespace YamlDotNet.RepresentationModel
|
||||
|
@ -51,7 +52,7 @@ namespace YamlDotNet.RepresentationModel
|
|||
public override bool Equals(object other)
|
||||
{
|
||||
var obj = other as YamlAliasNode;
|
||||
return obj != null && Equals(obj);
|
||||
return obj != null && Equals(obj) && SafeEquals(Anchor, obj.Anchor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -64,5 +65,24 @@ namespace YamlDotNet.RepresentationModel
|
|||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="System.String"/> that represents this instance.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return "*" + Anchor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all nodes from the document, starting on the current node.
|
||||
/// </summary>
|
||||
public override IEnumerable<YamlNode> AllNodes
|
||||
{
|
||||
get { yield return this; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -57,6 +57,16 @@ namespace YamlDotNet.RepresentationModel
|
|||
|
||||
state.ResolveAliases();
|
||||
|
||||
#if DEBUG
|
||||
foreach (var node in AllNodes)
|
||||
{
|
||||
if (node is YamlAliasNode)
|
||||
{
|
||||
throw new InvalidOperationException("Error in alias resolution.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
events.Expect<DocumentEnd>();
|
||||
}
|
||||
|
||||
|
@ -156,5 +166,16 @@ namespace YamlDotNet.RepresentationModel
|
|||
{
|
||||
visitor.Visit(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all nodes from the document.
|
||||
/// </summary>
|
||||
public IEnumerable<YamlNode> AllNodes
|
||||
{
|
||||
get
|
||||
{
|
||||
return RootNode.AllNodes;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using YamlDotNet.Core;
|
||||
using YamlDotNet.Core.Events;
|
||||
|
||||
|
@ -49,6 +50,22 @@ namespace YamlDotNet.RepresentationModel
|
|||
{
|
||||
state.AddNodeWithUnresolvedAliases(this);
|
||||
}
|
||||
#if DEBUG
|
||||
else
|
||||
{
|
||||
foreach (var child in children)
|
||||
{
|
||||
if (child.Key is YamlAliasNode)
|
||||
{
|
||||
throw new InvalidOperationException("Error in alias resolution.");
|
||||
}
|
||||
if (child.Value is YamlAliasNode)
|
||||
{
|
||||
throw new InvalidOperationException("Error in alias resolution.");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
events.Expect<MappingEnd>();
|
||||
}
|
||||
|
@ -202,28 +219,30 @@ namespace YamlDotNet.RepresentationModel
|
|||
internal override void Emit(Emitter emitter, EmitterState state)
|
||||
{
|
||||
emitter.Emit(new MappingStart(Anchor, Tag, true, MappingStyle.Any));
|
||||
foreach (var entry in children) {
|
||||
foreach (var entry in children)
|
||||
{
|
||||
entry.Key.Save(emitter, state);
|
||||
entry.Value.Save(emitter, state);
|
||||
}
|
||||
emitter.Emit(new MappingEnd());
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Accepts the specified visitor by calling the appropriate Visit method on it.
|
||||
/// </summary>
|
||||
/// <param name="visitor">
|
||||
/// A <see cref="IYamlVisitor"/>.
|
||||
/// </param>
|
||||
public override void Accept(IYamlVisitor visitor) {
|
||||
public override void Accept(IYamlVisitor visitor)
|
||||
{
|
||||
visitor.Visit(this);
|
||||
}
|
||||
|
||||
|
||||
/// <summary />
|
||||
public override bool Equals(object other)
|
||||
{
|
||||
var obj = other as YamlMappingNode;
|
||||
if(obj == null || !Equals(obj) || children.Count != obj.children.Count)
|
||||
if (obj == null || !Equals(obj) || children.Count != obj.children.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -231,15 +250,15 @@ namespace YamlDotNet.RepresentationModel
|
|||
foreach (var entry in children)
|
||||
{
|
||||
YamlNode otherNode;
|
||||
if(!obj.children.TryGetValue(entry.Key, out otherNode) || !SafeEquals(entry.Value, otherNode))
|
||||
if (!obj.children.TryGetValue(entry.Key, out otherNode) || !SafeEquals(entry.Value, otherNode))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Serves as a hash function for a particular type.
|
||||
/// </summary>
|
||||
|
@ -249,7 +268,7 @@ namespace YamlDotNet.RepresentationModel
|
|||
public override int GetHashCode()
|
||||
{
|
||||
var hashCode = base.GetHashCode();
|
||||
|
||||
|
||||
foreach (var entry in children)
|
||||
{
|
||||
hashCode = CombineHashCodes(hashCode, GetHashCode(entry.Key));
|
||||
|
@ -258,6 +277,51 @@ namespace YamlDotNet.RepresentationModel
|
|||
return hashCode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all nodes from the document, starting on the current node.
|
||||
/// </summary>
|
||||
public override IEnumerable<YamlNode> AllNodes
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return this;
|
||||
foreach (var child in children)
|
||||
{
|
||||
foreach (var node in child.Key.AllNodes)
|
||||
{
|
||||
yield return node;
|
||||
}
|
||||
foreach (var node in child.Value.AllNodes)
|
||||
{
|
||||
yield return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="System.String"/> that represents this instance.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
var text = new StringBuilder("{ ");
|
||||
|
||||
foreach (var child in children)
|
||||
{
|
||||
if (text.Length > 2)
|
||||
{
|
||||
text.Append(", ");
|
||||
}
|
||||
text.Append("{ ").Append(child.Key).Append(", ").Append(child.Value).Append(" }");
|
||||
}
|
||||
|
||||
text.Append(" }");
|
||||
|
||||
return text.ToString();
|
||||
}
|
||||
|
||||
#region IEnumerable<KeyValuePair<YamlNode,YamlNode>> Members
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using YamlDotNet.Core;
|
||||
using YamlDotNet.Core.Events;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace YamlDotNet.RepresentationModel
|
||||
{
|
||||
|
@ -161,5 +162,13 @@ namespace YamlDotNet.RepresentationModel
|
|||
{
|
||||
return unchecked(((h1 << 5) + h1) ^ h2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all nodes from the document, starting on the current node.
|
||||
/// </summary>
|
||||
public abstract IEnumerable<YamlNode> AllNodes
|
||||
{
|
||||
get;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using YamlDotNet.Core;
|
||||
using YamlDotNet.Core.Events;
|
||||
|
@ -121,5 +122,24 @@ namespace YamlDotNet.RepresentationModel
|
|||
{
|
||||
return value.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="System.String"/> that represents this instance.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all nodes from the document, starting on the current node.
|
||||
/// </summary>
|
||||
public override IEnumerable<YamlNode> AllNodes
|
||||
{
|
||||
get { yield return this; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using YamlDotNet.Core;
|
||||
using YamlDotNet.Core.Events;
|
||||
using System.Text;
|
||||
|
||||
namespace YamlDotNet.RepresentationModel
|
||||
{
|
||||
|
@ -47,6 +49,18 @@ namespace YamlDotNet.RepresentationModel
|
|||
{
|
||||
state.AddNodeWithUnresolvedAliases(this);
|
||||
}
|
||||
#if DEBUG
|
||||
else
|
||||
{
|
||||
foreach (var child in children)
|
||||
{
|
||||
if (child is YamlAliasNode)
|
||||
{
|
||||
throw new InvalidOperationException("Error in alias resolution.");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
events.Expect<SequenceEnd>();
|
||||
}
|
||||
|
@ -118,42 +132,44 @@ namespace YamlDotNet.RepresentationModel
|
|||
internal override void Emit(Emitter emitter, EmitterState state)
|
||||
{
|
||||
emitter.Emit(new SequenceStart(Anchor, Tag, true, SequenceStyle.Any));
|
||||
foreach (var node in children) {
|
||||
foreach (var node in children)
|
||||
{
|
||||
node.Save(emitter, state);
|
||||
}
|
||||
emitter.Emit(new SequenceEnd());
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Accepts the specified visitor by calling the appropriate Visit method on it.
|
||||
/// </summary>
|
||||
/// <param name="visitor">
|
||||
/// A <see cref="IYamlVisitor"/>.
|
||||
/// </param>
|
||||
public override void Accept(IYamlVisitor visitor) {
|
||||
public override void Accept(IYamlVisitor visitor)
|
||||
{
|
||||
visitor.Visit(this);
|
||||
}
|
||||
|
||||
|
||||
/// <summary />
|
||||
public override bool Equals(object other)
|
||||
{
|
||||
var obj = other as YamlSequenceNode;
|
||||
if(obj == null || !Equals(obj) || children.Count != obj.children.Count)
|
||||
if (obj == null || !Equals(obj) || children.Count != obj.children.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for(int i = 0; i < children.Count; ++i)
|
||||
|
||||
for (int i = 0; i < children.Count; ++i)
|
||||
{
|
||||
if(!SafeEquals(children[i], obj.children[i]))
|
||||
if (!SafeEquals(children[i], obj.children[i]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Serves as a hash function for a particular type.
|
||||
/// </summary>
|
||||
|
@ -163,7 +179,7 @@ namespace YamlDotNet.RepresentationModel
|
|||
public override int GetHashCode()
|
||||
{
|
||||
var hashCode = base.GetHashCode();
|
||||
|
||||
|
||||
foreach (var item in children)
|
||||
{
|
||||
hashCode = CombineHashCodes(hashCode, GetHashCode(item));
|
||||
|
@ -171,6 +187,47 @@ namespace YamlDotNet.RepresentationModel
|
|||
return hashCode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all nodes from the document, starting on the current node.
|
||||
/// </summary>
|
||||
public override IEnumerable<YamlNode> AllNodes
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return this;
|
||||
foreach (var child in children)
|
||||
{
|
||||
foreach (var node in child.AllNodes)
|
||||
{
|
||||
yield return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="System.String"/> that represents this instance.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
var text = new StringBuilder("[ ");
|
||||
|
||||
foreach (var child in children)
|
||||
{
|
||||
if(text.Length > 2)
|
||||
{
|
||||
text.Append(", ");
|
||||
}
|
||||
text.Append(child);
|
||||
}
|
||||
|
||||
text.Append(" ]");
|
||||
|
||||
return text.ToString();
|
||||
}
|
||||
|
||||
#region IEnumerable<YamlNode> Members
|
||||
|
||||
|
|
|
@ -283,5 +283,62 @@ namespace YamlDotNet.UnitTests.RepresentationModel
|
|||
RoundtripTest("fail-backreference.yaml");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(AnchorNotFoundException))]
|
||||
public void AllAliasesMustBeResolved()
|
||||
{
|
||||
YamlStream original = new YamlStream();
|
||||
original.Load(YamlFile("invalid-reference.yaml"));
|
||||
|
||||
var visitor = new AliasFindingVisitor();
|
||||
|
||||
try
|
||||
{
|
||||
original.Accept(visitor);
|
||||
}
|
||||
catch (NotSupportedException err)
|
||||
{
|
||||
foreach (var node in visitor.CurrentPath)
|
||||
{
|
||||
TestContext.WriteLine(node.ToString());
|
||||
}
|
||||
|
||||
Assert.Fail();
|
||||
}
|
||||
}
|
||||
|
||||
private class AliasFindingVisitor : YamlVisitor
|
||||
{
|
||||
private readonly Stack<string> _currentPath = new Stack<string>();
|
||||
|
||||
protected override void Visit(YamlMappingNode mapping)
|
||||
{
|
||||
base.Visit(mapping);
|
||||
}
|
||||
|
||||
protected override void VisitChildren(YamlSequenceNode sequence)
|
||||
{
|
||||
int index = 0;
|
||||
foreach (var child in sequence.Children)
|
||||
{
|
||||
_currentPath.Push(string.Format("seq[{0}]", index.ToString()));
|
||||
child.Accept(this);
|
||||
_currentPath.Pop();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void VisitChildren(YamlMappingNode mapping)
|
||||
{
|
||||
foreach (var child in mapping.Children)
|
||||
{
|
||||
_currentPath.Push(string.Format("map[{0}]", child.Key.ToString()));
|
||||
child.Value.Accept(this);
|
||||
_currentPath.Pop();
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> CurrentPath { get { return _currentPath; } }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -158,6 +158,9 @@
|
|||
<ItemGroup>
|
||||
<EmbeddedResource Include="fail-backreference.yaml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="invalid-reference.yaml" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
- [*municipality-0701, *municipality-0711, *municipality-0707, *municipality-0708, *municipality-0709]
|
||||
- [*municipality-1501, *municipality-1505, *municipality-1509, *municipality-1513, *municipality-0211]
|
||||
-
|
||||
- &municipality-0211 0211
|
||||
- &municipality-0701 0701
|
||||
- &municipality-0707 0707
|
||||
- &municipality-0708 0708
|
||||
- &municipality-0709 0709
|
||||
- &municipality-0711 0711
|
||||
- &municipality-1513 1513
|
|
@ -4,7 +4,7 @@
|
|||
<!-- This build file requires .NET 4.0 and nant 0.91 alpha 2 or higher -->
|
||||
<property name="nant.settings.currentframework" value="net-4.0"/>
|
||||
|
||||
<property name="version" value="1.1.6" />
|
||||
<property name="version" value="1.1.7" />
|
||||
|
||||
<fileset id="binaries">
|
||||
<include name="YamlDotNet.Core/bin/Release/YamlDotNet.Core.dll" />
|
||||
|
|
Загрузка…
Ссылка в новой задаче