Browse Source

Reader -> CharacterReader

And moved `CharacterReader` and `IdentifierParser` into Avalonia.Utilities.
pull/1773/head
Steven Kirk 8 years ago
parent
commit
dc6f14e775
  1. 6
      src/Avalonia.Base/Utilities/CharacterReader.cs
  2. 4
      src/Avalonia.Base/Utilities/IdentifierParser.cs
  3. 3
      src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaPropertyTypeConverter.cs
  4. 3
      src/Markup/Avalonia.Markup.Xaml/Parsers/PropertyParser.cs
  5. 3
      src/Markup/Avalonia.Markup/Markup/Parsers/ArgumentListParser.cs
  6. 3
      src/Markup/Avalonia.Markup/Markup/Parsers/ExpressionObserverBuilder.cs
  7. 23
      src/Markup/Avalonia.Markup/Markup/Parsers/ExpressionParser.cs
  8. 39
      tests/Avalonia.Markup.Xaml.UnitTests/Parsers/PropertyParserTests.cs

6
src/Markup/Avalonia.Markup/Markup/Parsers/Reader.cs → src/Avalonia.Base/Utilities/CharacterReader.cs

@ -3,14 +3,14 @@
using System; using System;
namespace Avalonia.Markup.Parsers namespace Avalonia.Utilities
{ {
public class Reader public class CharacterReader
{ {
private readonly string _s; private readonly string _s;
private int _i; private int _i;
public Reader(string s) public CharacterReader(string s)
{ {
_s = s; _s = s;
} }

4
src/Markup/Avalonia.Markup/Markup/Parsers/IdentifierParser.cs → src/Avalonia.Base/Utilities/IdentifierParser.cs

@ -4,11 +4,11 @@
using System.Globalization; using System.Globalization;
using System.Text; using System.Text;
namespace Avalonia.Markup.Parsers namespace Avalonia.Utilities
{ {
public static class IdentifierParser public static class IdentifierParser
{ {
public static string Parse(Reader r) public static string Parse(CharacterReader r)
{ {
if (IsValidIdentifierStart(r.Peek)) if (IsValidIdentifierStart(r.Peek))
{ {

3
src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaPropertyTypeConverter.cs

@ -10,6 +10,7 @@ using Avalonia.Markup.Parsers;
using Avalonia.Markup.Xaml.Parsers; using Avalonia.Markup.Xaml.Parsers;
using Avalonia.Markup.Xaml.Templates; using Avalonia.Markup.Xaml.Templates;
using Avalonia.Styling; using Avalonia.Styling;
using Avalonia.Utilities;
using Portable.Xaml.ComponentModel; using Portable.Xaml.ComponentModel;
namespace Avalonia.Markup.Xaml.Converters namespace Avalonia.Markup.Xaml.Converters
@ -25,7 +26,7 @@ namespace Avalonia.Markup.Xaml.Converters
{ {
var registry = AvaloniaPropertyRegistry.Instance; var registry = AvaloniaPropertyRegistry.Instance;
var parser = new PropertyParser(); var parser = new PropertyParser();
var reader = new Reader((string)value); var reader = new CharacterReader((string)value);
var (ns, owner, propertyName) = parser.Parse(reader); var (ns, owner, propertyName) = parser.Parse(reader);
var ownerType = TryResolveOwnerByName(context, ns, owner); var ownerType = TryResolveOwnerByName(context, ns, owner);
var targetType = context.GetFirstAmbientValue<ControlTemplate>()?.TargetType ?? var targetType = context.GetFirstAmbientValue<ControlTemplate>()?.TargetType ??

3
src/Markup/Avalonia.Markup.Xaml/Parsers/PropertyParser.cs

@ -1,12 +1,13 @@
using System; using System;
using Avalonia.Data.Core; using Avalonia.Data.Core;
using Avalonia.Markup.Parsers; using Avalonia.Markup.Parsers;
using Avalonia.Utilities;
namespace Avalonia.Markup.Xaml.Parsers namespace Avalonia.Markup.Xaml.Parsers
{ {
internal class PropertyParser internal class PropertyParser
{ {
public (string ns, string owner, string name) Parse(Reader r) public (string ns, string owner, string name) Parse(CharacterReader r)
{ {
if (r.End) if (r.End)
{ {

3
src/Markup/Avalonia.Markup/Markup/Parsers/ArgumentListParser.cs

@ -2,6 +2,7 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information. // Licensed under the MIT license. See licence.md file in the project root for full license information.
using Avalonia.Data.Core; using Avalonia.Data.Core;
using Avalonia.Utilities;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
@ -10,7 +11,7 @@ namespace Avalonia.Markup.Parsers
{ {
internal static class ArgumentListParser internal static class ArgumentListParser
{ {
public static IList<string> Parse(Reader r, char open, char close) public static IList<string> Parse(CharacterReader r, char open, char close)
{ {
if (r.Peek == open) if (r.Peek == open)
{ {

3
src/Markup/Avalonia.Markup/Markup/Parsers/ExpressionObserverBuilder.cs

@ -1,4 +1,5 @@
using Avalonia.Data.Core; using Avalonia.Data.Core;
using Avalonia.Utilities;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reactive; using System.Reactive;
@ -15,7 +16,7 @@ namespace Avalonia.Markup.Parsers
return new EmptyExpressionNode(); return new EmptyExpressionNode();
} }
var reader = new Reader(expression); var reader = new CharacterReader(expression);
var parser = new ExpressionParser(enableValidation, typeResolver); var parser = new ExpressionParser(enableValidation, typeResolver);
var node = parser.Parse(reader); var node = parser.Parse(reader);

23
src/Markup/Avalonia.Markup/Markup/Parsers/ExpressionParser.cs

@ -3,6 +3,7 @@
using Avalonia.Data.Core; using Avalonia.Data.Core;
using Avalonia.Markup.Parsers.Nodes; using Avalonia.Markup.Parsers.Nodes;
using Avalonia.Utilities;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -20,7 +21,7 @@ namespace Avalonia.Markup.Parsers
_enableValidation = enableValidation; _enableValidation = enableValidation;
} }
public ExpressionNode Parse(Reader r) public ExpressionNode Parse(CharacterReader r)
{ {
var nodes = new List<ExpressionNode>(); var nodes = new List<ExpressionNode>();
var state = State.Start; var state = State.Start;
@ -64,7 +65,7 @@ namespace Avalonia.Markup.Parsers
return nodes.FirstOrDefault(); return nodes.FirstOrDefault();
} }
private State ParseStart(Reader r, IList<ExpressionNode> nodes) private State ParseStart(CharacterReader r, IList<ExpressionNode> nodes)
{ {
if (ParseNot(r)) if (ParseNot(r))
{ {
@ -93,7 +94,7 @@ namespace Avalonia.Markup.Parsers
return State.End; return State.End;
} }
private static State ParseAfterMember(Reader r, IList<ExpressionNode> nodes) private static State ParseAfterMember(CharacterReader r, IList<ExpressionNode> nodes)
{ {
if (ParseMemberAccessor(r)) if (ParseMemberAccessor(r))
{ {
@ -112,7 +113,7 @@ namespace Avalonia.Markup.Parsers
return State.End; return State.End;
} }
private State ParseBeforeMember(Reader r, IList<ExpressionNode> nodes) private State ParseBeforeMember(CharacterReader r, IList<ExpressionNode> nodes)
{ {
if (ParseOpenBrace(r)) if (ParseOpenBrace(r))
{ {
@ -132,7 +133,7 @@ namespace Avalonia.Markup.Parsers
} }
} }
private State ParseAttachedProperty(Reader r, List<ExpressionNode> nodes) private State ParseAttachedProperty(CharacterReader r, List<ExpressionNode> nodes)
{ {
string ns = string.Empty; string ns = string.Empty;
string owner; string owner;
@ -171,7 +172,7 @@ namespace Avalonia.Markup.Parsers
return State.AfterMember; return State.AfterMember;
} }
private State ParseIndexer(Reader r, List<ExpressionNode> nodes) private State ParseIndexer(CharacterReader r, List<ExpressionNode> nodes)
{ {
var args = ArgumentListParser.Parse(r, '[', ']'); var args = ArgumentListParser.Parse(r, '[', ']');
@ -184,27 +185,27 @@ namespace Avalonia.Markup.Parsers
return State.AfterMember; return State.AfterMember;
} }
private static bool ParseNot(Reader r) private static bool ParseNot(CharacterReader r)
{ {
return !r.End && r.TakeIf('!'); return !r.End && r.TakeIf('!');
} }
private static bool ParseMemberAccessor(Reader r) private static bool ParseMemberAccessor(CharacterReader r)
{ {
return !r.End && r.TakeIf('.'); return !r.End && r.TakeIf('.');
} }
private static bool ParseOpenBrace(Reader r) private static bool ParseOpenBrace(CharacterReader r)
{ {
return !r.End && r.TakeIf('('); return !r.End && r.TakeIf('(');
} }
private static bool PeekOpenBracket(Reader r) private static bool PeekOpenBracket(CharacterReader r)
{ {
return !r.End && r.Peek == '['; return !r.End && r.Peek == '[';
} }
private static bool ParseStreamOperator(Reader r) private static bool ParseStreamOperator(CharacterReader r)
{ {
return !r.End && r.TakeIf('^'); return !r.End && r.TakeIf('^');
} }

39
tests/Avalonia.Markup.Xaml.UnitTests/Parsers/PropertyParserTests.cs

@ -2,6 +2,7 @@
using Avalonia.Data.Core; using Avalonia.Data.Core;
using Avalonia.Markup.Parsers; using Avalonia.Markup.Parsers;
using Avalonia.Markup.Xaml.Parsers; using Avalonia.Markup.Xaml.Parsers;
using Avalonia.Utilities;
using Xunit; using Xunit;
namespace Avalonia.Markup.Xaml.UnitTests.Parsers namespace Avalonia.Markup.Xaml.UnitTests.Parsers
@ -12,7 +13,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Parsers
public void Parses_Name() public void Parses_Name()
{ {
var target = new PropertyParser(); var target = new PropertyParser();
var reader = new Reader("Foo"); var reader = new CharacterReader("Foo");
var (ns, owner, name) = target.Parse(reader); var (ns, owner, name) = target.Parse(reader);
Assert.Null(ns); Assert.Null(ns);
@ -24,7 +25,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Parsers
public void Parses_Owner_And_Name() public void Parses_Owner_And_Name()
{ {
var target = new PropertyParser(); var target = new PropertyParser();
var reader = new Reader("Foo.Bar"); var reader = new CharacterReader("Foo.Bar");
var (ns, owner, name) = target.Parse(reader); var (ns, owner, name) = target.Parse(reader);
Assert.Null(ns); Assert.Null(ns);
@ -36,7 +37,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Parsers
public void Parses_Namespace_Owner_And_Name() public void Parses_Namespace_Owner_And_Name()
{ {
var target = new PropertyParser(); var target = new PropertyParser();
var reader = new Reader("foo:Bar.Baz"); var reader = new CharacterReader("foo:Bar.Baz");
var (ns, owner, name) = target.Parse(reader); var (ns, owner, name) = target.Parse(reader);
Assert.Equal("foo", ns); Assert.Equal("foo", ns);
@ -48,7 +49,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Parsers
public void Parses_Owner_And_Name_With_Parentheses() public void Parses_Owner_And_Name_With_Parentheses()
{ {
var target = new PropertyParser(); var target = new PropertyParser();
var reader = new Reader("(Foo.Bar)"); var reader = new CharacterReader("(Foo.Bar)");
var (ns, owner, name) = target.Parse(reader); var (ns, owner, name) = target.Parse(reader);
Assert.Null(ns); Assert.Null(ns);
@ -60,7 +61,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Parsers
public void Parses_Namespace_Owner_And_Name_With_Parentheses() public void Parses_Namespace_Owner_And_Name_With_Parentheses()
{ {
var target = new PropertyParser(); var target = new PropertyParser();
var reader = new Reader("(foo:Bar.Baz)"); var reader = new CharacterReader("(foo:Bar.Baz)");
var (ns, owner, name) = target.Parse(reader); var (ns, owner, name) = target.Parse(reader);
Assert.Equal("foo", ns); Assert.Equal("foo", ns);
@ -72,7 +73,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Parsers
public void Fails_With_Empty_String() public void Fails_With_Empty_String()
{ {
var target = new PropertyParser(); var target = new PropertyParser();
var reader = new Reader(""); var reader = new CharacterReader("");
var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader)); var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader));
Assert.Equal(0, ex.Column); Assert.Equal(0, ex.Column);
@ -83,7 +84,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Parsers
public void Fails_With_Only_Whitespace() public void Fails_With_Only_Whitespace()
{ {
var target = new PropertyParser(); var target = new PropertyParser();
var reader = new Reader(" "); var reader = new CharacterReader(" ");
var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader)); var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader));
Assert.Equal(0, ex.Column); Assert.Equal(0, ex.Column);
@ -94,7 +95,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Parsers
public void Fails_With_Leading_Whitespace() public void Fails_With_Leading_Whitespace()
{ {
var target = new PropertyParser(); var target = new PropertyParser();
var reader = new Reader(" Foo"); var reader = new CharacterReader(" Foo");
var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader)); var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader));
Assert.Equal(0, ex.Column); Assert.Equal(0, ex.Column);
@ -105,7 +106,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Parsers
public void Fails_With_Trailing_Whitespace() public void Fails_With_Trailing_Whitespace()
{ {
var target = new PropertyParser(); var target = new PropertyParser();
var reader = new Reader("Foo "); var reader = new CharacterReader("Foo ");
var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader)); var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader));
Assert.Equal(3, ex.Column); Assert.Equal(3, ex.Column);
@ -116,7 +117,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Parsers
public void Fails_With_Invalid_Property_Name() public void Fails_With_Invalid_Property_Name()
{ {
var target = new PropertyParser(); var target = new PropertyParser();
var reader = new Reader("123"); var reader = new CharacterReader("123");
var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader)); var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader));
Assert.Equal(0, ex.Column); Assert.Equal(0, ex.Column);
@ -127,7 +128,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Parsers
public void Fails_With_Trailing_Junk() public void Fails_With_Trailing_Junk()
{ {
var target = new PropertyParser(); var target = new PropertyParser();
var reader = new Reader("Foo%"); var reader = new CharacterReader("Foo%");
var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader)); var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader));
Assert.Equal(3, ex.Column); Assert.Equal(3, ex.Column);
@ -138,7 +139,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Parsers
public void Fails_With_Invalid_Property_Name_After_Owner() public void Fails_With_Invalid_Property_Name_After_Owner()
{ {
var target = new PropertyParser(); var target = new PropertyParser();
var reader = new Reader("Foo.123"); var reader = new CharacterReader("Foo.123");
var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader)); var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader));
Assert.Equal(4, ex.Column); Assert.Equal(4, ex.Column);
@ -149,7 +150,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Parsers
public void Fails_With_Whitespace_Between_Owner_And_Name() public void Fails_With_Whitespace_Between_Owner_And_Name()
{ {
var target = new PropertyParser(); var target = new PropertyParser();
var reader = new Reader("Foo. Bar"); var reader = new CharacterReader("Foo. Bar");
var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader)); var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader));
Assert.Equal(4, ex.Column); Assert.Equal(4, ex.Column);
@ -160,7 +161,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Parsers
public void Fails_With_Too_Many_Segments() public void Fails_With_Too_Many_Segments()
{ {
var target = new PropertyParser(); var target = new PropertyParser();
var reader = new Reader("Foo.Bar.Baz"); var reader = new CharacterReader("Foo.Bar.Baz");
var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader)); var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader));
Assert.Equal(8, ex.Column); Assert.Equal(8, ex.Column);
@ -171,7 +172,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Parsers
public void Fails_With_Too_Many_Namespaces() public void Fails_With_Too_Many_Namespaces()
{ {
var target = new PropertyParser(); var target = new PropertyParser();
var reader = new Reader("foo:bar:Baz"); var reader = new CharacterReader("foo:bar:Baz");
var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader)); var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader));
Assert.Equal(8, ex.Column); Assert.Equal(8, ex.Column);
@ -182,7 +183,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Parsers
public void Fails_With_Parens_But_No_Owner() public void Fails_With_Parens_But_No_Owner()
{ {
var target = new PropertyParser(); var target = new PropertyParser();
var reader = new Reader("(Foo)"); var reader = new CharacterReader("(Foo)");
var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader)); var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader));
Assert.Equal(1, ex.Column); Assert.Equal(1, ex.Column);
@ -193,7 +194,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Parsers
public void Fails_With_Parens_And_Namespace_But_No_Owner() public void Fails_With_Parens_And_Namespace_But_No_Owner()
{ {
var target = new PropertyParser(); var target = new PropertyParser();
var reader = new Reader("(foo:Bar)"); var reader = new CharacterReader("(foo:Bar)");
var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader)); var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader));
Assert.Equal(1, ex.Column); Assert.Equal(1, ex.Column);
@ -204,7 +205,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Parsers
public void Fails_With_Missing_Close_Parens() public void Fails_With_Missing_Close_Parens()
{ {
var target = new PropertyParser(); var target = new PropertyParser();
var reader = new Reader("(Foo.Bar"); var reader = new CharacterReader("(Foo.Bar");
var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader)); var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader));
Assert.Equal(8, ex.Column); Assert.Equal(8, ex.Column);
@ -215,7 +216,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Parsers
public void Fails_With_Unexpected_Close_Parens() public void Fails_With_Unexpected_Close_Parens()
{ {
var target = new PropertyParser(); var target = new PropertyParser();
var reader = new Reader("Foo.Bar)"); var reader = new CharacterReader("Foo.Bar)");
var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader)); var ex = Assert.Throws<ExpressionParseException>(() => target.Parse(reader));
Assert.Equal(7, ex.Column); Assert.Equal(7, ex.Column);

Loading…
Cancel
Save