Skip to content

Commit

Permalink
Get rid of EventReader.
Browse files Browse the repository at this point in the history
EventReader was a wrapper over IParser that offered some abstractions for parsing,
but also had some design flaws. It has been replaced by extension methods for IParser.
The extension methods provide the same functionality,
and allow to always use the same type to represent the parser.
  • Loading branch information
aaubry committed Aug 30, 2016
1 parent 5dbf200 commit 2bededd
Show file tree
Hide file tree
Showing 28 changed files with 151 additions and 190 deletions.
4 changes: 2 additions & 2 deletions YamlDotNet.Test/Serialization/SerializationTestHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,9 @@ protected TextReader UsingReaderFor(string text)
return new StringReader(text);
}

protected static EventReader EventReaderFor(string yaml)
protected static IParser ParserFor(string yaml)
{
return new EventReader(new Parser(new StringReader(yaml)));
return new Parser(new StringReader(yaml));
}

protected string Lines(params string[] lines)
Expand Down
10 changes: 5 additions & 5 deletions YamlDotNet.Test/Serialization/SerializationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ public void DeserializeListOfDictionaries()
[Fact]
public void DeserializeTwoDocuments()
{
var reader = EventReaderFor(Lines(
var reader = ParserFor(Lines(
"---",
"aaa: 111",
"---",
Expand All @@ -613,7 +613,7 @@ public void DeserializeTwoDocuments()
[Fact]
public void DeserializeThreeDocuments()
{
var reader = EventReaderFor(Lines(
var reader = ParserFor(Lines(
"---",
"aaa: 111",
"---",
Expand Down Expand Up @@ -963,7 +963,7 @@ public void BackreferencesAreMergedWithMappings()
var stream = Yaml.StreamFrom("backreference.yaml");

var parser = new MergingParser(new Parser(stream));
var result = Deserializer.Deserialize<Dictionary<string, Dictionary<string, string>>>(new EventReader(parser));
var result = Deserializer.Deserialize<Dictionary<string, Dictionary<string, string>>>(parser);

var alias = result["alias"];
alias.Should()
Expand All @@ -986,7 +986,7 @@ public void MergingDoesNotProduceDuplicateAnchors()
useMyValue:
key: *myValue
"));
var result = Deserializer.Deserialize<Dictionary<string, Dictionary<string, string>>>(new EventReader(parser));
var result = Deserializer.Deserialize<Dictionary<string, Dictionary<string, string>>>(parser);

var alias = result["alias"];
alias.Should()
Expand Down Expand Up @@ -1037,7 +1037,7 @@ public void ExampleFromSpecificationIsHandledCorrectly()
label: center/big
"));

var result = Deserializer.Deserialize<Dictionary<string, List<Dictionary<string, string>>>>(new EventReader(parser));
var result = Deserializer.Deserialize<Dictionary<string, List<Dictionary<string, string>>>>(parser);

int index = 0;
foreach (var mapping in result["results"])
Expand Down
11 changes: 6 additions & 5 deletions YamlDotNet/Core/IParser.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
// This file is part of YamlDotNet - A .NET library for YAML.
// Copyright (c) Antoine Aubry and contributors

// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Expand All @@ -19,7 +19,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

using YamlDotNet.Core.Events;
using YamlDotNet.Core.Events;

namespace YamlDotNet.Core
{
Expand All @@ -29,7 +29,8 @@ namespace YamlDotNet.Core
public interface IParser
{
/// <summary>
/// Gets the current event.
/// Gets the current event. Returns null before the first call to <see cref="MoveNext" />,
/// and also after <see cref="MoveNext" /> returns false.
/// </summary>
ParsingEvent Current { get; }

Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
// This file is part of YamlDotNet - A .NET library for YAML.
// Copyright (c) Antoine Aubry and contributors

// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Expand All @@ -19,51 +19,26 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

using System.IO;
using System.Globalization;
using System.IO;
using YamlDotNet.Core.Events;

namespace YamlDotNet.Core
{
/// <summary>
/// Reads events from a sequence of <see cref="ParsingEvent" />.
/// Extension methods that provide useful abstractions over <see cref="IParser"/>.
/// </summary>
public class EventReader
public static class ParserExtensions
{
private readonly IParser parser;
private bool endOfStream;

/// <summary>
/// Initializes a new instance of the <see cref="EventReader"/> class.
/// </summary>
/// <param name="parser">The parser that provides the events.</param>
public EventReader(IParser parser)
{
this.parser = parser;
MoveNext();
}

/// <summary>
/// Gets the underlying parser.
/// </summary>
/// <value>The parser.</value>
public IParser Parser
{
get
{
return parser;
}
}

/// <summary>
/// Ensures that the current event is of the specified type, returns it and moves to the next event.
/// </summary>
/// <typeparam name="T">Type of the <see cref="ParsingEvent"/>.</typeparam>
/// <returns>Returns the current event.</returns>
/// <exception cref="YamlException">If the current event is not of the specified type.</exception>
public T Expect<T>() where T : ParsingEvent
public static T Expect<T>(this IParser parser) where T : ParsingEvent
{
var expectedEvent = Allow<T>();
var expectedEvent = parser.Allow<T>();
if (expectedEvent == null)
{
// TODO: Throw a better exception
Expand All @@ -79,18 +54,16 @@ public T Expect<T>() where T : ParsingEvent
/// </summary>
/// <typeparam name="T">Type of the event.</typeparam>
/// <returns>Returns true if the current event is of type <typeparamref name="T"/>. Otherwise returns false.</returns>
public bool Accept<T>() where T : ParsingEvent
public static bool Accept<T>(this IParser parser) where T : ParsingEvent
{
ThrowIfAtEndOfStream();
return parser.Current is T;
}

private void ThrowIfAtEndOfStream()
{
if (endOfStream)
if(parser.Current == null)
{
throw new EndOfStreamException();
if (!parser.MoveNext())
{
throw new EndOfStreamException();
}
}
return parser.Current is T;
}

/// <summary>
Expand All @@ -100,14 +73,14 @@ private void ThrowIfAtEndOfStream()
/// </summary>
/// <typeparam name="T">Type of the <see cref="ParsingEvent"/>.</typeparam>
/// <returns>Returns the current event if it is of type T; otherwise returns null.</returns>
public T Allow<T>() where T : ParsingEvent
public static T Allow<T>(this IParser parser) where T : ParsingEvent
{
if (!Accept<T>())
if (!parser.Accept<T>())
{
return null;
}
var @event = (T) parser.Current;
MoveNext();
var @event = (T)parser.Current;
parser.MoveNext();
return @event;
}

Expand All @@ -116,32 +89,27 @@ public T Allow<T>() where T : ParsingEvent
/// </summary>
/// <typeparam name="T">Type of the <see cref="ParsingEvent"/>.</typeparam>
/// <returns>Returns the current event if it is of type T; otherwise returns null.</returns>
public T Peek<T>() where T : ParsingEvent
public static T Peek<T>(this IParser parser) where T : ParsingEvent
{
if (!Accept<T>())
if (!parser.Accept<T>())
{
return null;
}
return (T) parser.Current;
return (T)parser.Current;
}

/// <summary>
/// Skips the current event and any nested event.
/// </summary>
public void SkipThisAndNestedEvents()
public static void SkipThisAndNestedEvents(this IParser parser)
{
var depth = 0;
do
{
depth += Peek<ParsingEvent>().NestingIncrease;
MoveNext();
depth += parser.Peek<ParsingEvent>().NestingIncrease;
parser.MoveNext();
}
while(depth > 0);
}

private void MoveNext()
{
endOfStream = !parser.MoveNext();
while (depth > 0);
}
}
}
11 changes: 5 additions & 6 deletions YamlDotNet/RepresentationModel/YamlDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,16 @@ public YamlDocument(string rootNode)
/// <summary>
/// Initializes a new instance of the <see cref="YamlDocument"/> class.
/// </summary>
/// <param name="events">The events.</param>
internal YamlDocument(EventReader events)
internal YamlDocument(IParser parser)
{
DocumentLoadingState state = new DocumentLoadingState();

events.Expect<DocumentStart>();
parser.Expect<DocumentStart>();

while (!events.Accept<DocumentEnd>())
while (!parser.Accept<DocumentEnd>())
{
Debug.Assert(RootNode == null);
RootNode = YamlNode.ParseNode(events, state);
RootNode = YamlNode.ParseNode(parser, state);

if (RootNode is YamlAliasNode)
{
Expand All @@ -89,7 +88,7 @@ internal YamlDocument(EventReader events)
}
#endif

events.Expect<DocumentEnd>();
parser.Expect<DocumentEnd>();
}

/// <summary>
Expand Down
22 changes: 10 additions & 12 deletions YamlDotNet/RepresentationModel/YamlMappingNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,24 +59,22 @@ public IDictionary<YamlNode, YamlNode> Children
/// <summary>
/// Initializes a new instance of the <see cref="YamlMappingNode"/> class.
/// </summary>
/// <param name="events">The events.</param>
/// <param name="state">The state.</param>
internal YamlMappingNode(EventReader events, DocumentLoadingState state)
internal YamlMappingNode(IParser parser, DocumentLoadingState state)
{
Load(events, state);
Load(parser, state);
}

private void Load(EventReader events, DocumentLoadingState state)
private void Load(IParser parser, DocumentLoadingState state)
{
MappingStart mapping = events.Expect<MappingStart>();
MappingStart mapping = parser.Expect<MappingStart>();
base.Load(mapping, state);
Style = mapping.Style;

bool hasUnresolvedAliases = false;
while (!events.Accept<MappingEnd>())
while (!parser.Accept<MappingEnd>())
{
YamlNode key = ParseNode(events, state);
YamlNode value = ParseNode(events, state);
YamlNode key = ParseNode(parser, state);
YamlNode value = ParseNode(parser, state);

try
{
Expand Down Expand Up @@ -111,7 +109,7 @@ private void Load(EventReader events, DocumentLoadingState state)
}
#endif

events.Expect<MappingEnd>();
parser.Expect<MappingEnd>();
}

/// <summary>
Expand Down Expand Up @@ -394,9 +392,9 @@ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()

#endregion

void IYamlConvertible.Read(EventReader reader, Type expectedType, Func<EventReader, Type, object> nestedObjectDeserializer)
void IYamlConvertible.Read(IParser parser, Type expectedType, Func<IParser, Type, object> nestedObjectDeserializer)
{
Load(reader, new DocumentLoadingState());
Load(parser, new DocumentLoadingState());
}

void IYamlConvertible.Write(IEmitter emitter)
Expand Down
22 changes: 10 additions & 12 deletions YamlDotNet/RepresentationModel/YamlNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,31 +73,29 @@ internal void Load(NodeEvent yamlEvent, DocumentLoadingState state)
}

/// <summary>
/// Parses the node represented by the next event in <paramref name="events" />.
/// Parses the node represented by the next event in <paramref name="parser" />.
/// </summary>
/// <param name="events">The events.</param>
/// <param name="state">The state.</param>
/// <returns>Returns the node that has been parsed.</returns>
static internal YamlNode ParseNode(EventReader events, DocumentLoadingState state)
static internal YamlNode ParseNode(IParser parser, DocumentLoadingState state)
{
if (events.Accept<Scalar>())
if (parser.Accept<Scalar>())
{
return new YamlScalarNode(events, state);
return new YamlScalarNode(parser, state);
}

if (events.Accept<SequenceStart>())
if (parser.Accept<SequenceStart>())
{
return new YamlSequenceNode(events, state);
return new YamlSequenceNode(parser, state);
}

if (events.Accept<MappingStart>())
if (parser.Accept<MappingStart>())
{
return new YamlMappingNode(events, state);
return new YamlMappingNode(parser, state);
}

if (events.Accept<AnchorAlias>())
if (parser.Accept<AnchorAlias>())
{
AnchorAlias alias = events.Expect<AnchorAlias>();
AnchorAlias alias = parser.Expect<AnchorAlias>();
return state.GetNode(alias.Value, false, alias.Start, alias.End) ?? new YamlAliasNode(alias.Value);
}

Expand Down
Loading

0 comments on commit 2bededd

Please sign in to comment.