This repository has been archived by the owner on Dec 19, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 224
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add extensible directive abstractions
- Based generic directive implementation off of descriptors. - Added parsing logic to consume descriptors and parse content that's expected. - Added parsing errors to automagically detect unexpected directive pieces. - Updated visitor implementations to understand the directive bits. - Added a builder abstraction to easily create descriptors. Had to maintain the ability to manually construct a descriptor to enable convenient serialization/deserialization. - Added tests/comparers to verify correctness of parsing. #853
- Loading branch information
1 parent
522f6e9
commit 518378f
Showing
22 changed files
with
1,222 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
src/Microsoft.AspNetCore.Razor.Evolution/DirectiveDescriptor.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// Copyright(c) .NET Foundation.All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System.Collections.Generic; | ||
|
||
namespace Microsoft.AspNetCore.Razor.Evolution | ||
{ | ||
public class DirectiveDescriptor | ||
{ | ||
public string Name { get; set; } | ||
|
||
public DirectiveDescriptorKind Kind { get; set; } | ||
|
||
public IReadOnlyList<DirectiveTokenDescriptor> Tokens { get; set; } | ||
} | ||
} |
96 changes: 96 additions & 0 deletions
96
src/Microsoft.AspNetCore.Razor.Evolution/DirectiveDescriptorBuilder.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
// Copyright(c) .NET Foundation.All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System.Collections.Generic; | ||
|
||
namespace Microsoft.AspNetCore.Razor.Evolution | ||
{ | ||
public static class DirectiveDescriptorBuilder | ||
{ | ||
public static IDirectiveDescriptorBuilder Create(string name) | ||
{ | ||
return new DefaultDirectiveDescriptorBuilder(name, DirectiveDescriptorKind.SingleLine); | ||
} | ||
|
||
public static IDirectiveDescriptorBuilder CreateRazorBlock(string name) | ||
{ | ||
return new DefaultDirectiveDescriptorBuilder(name, DirectiveDescriptorKind.RazorBlock); | ||
} | ||
|
||
public static IDirectiveDescriptorBuilder CreateCodeBlock(string name) | ||
{ | ||
return new DefaultDirectiveDescriptorBuilder(name, DirectiveDescriptorKind.CodeBlock); | ||
} | ||
|
||
private class DefaultDirectiveDescriptorBuilder : IDirectiveDescriptorBuilder | ||
{ | ||
private readonly List<DirectiveTokenDescriptor> _tokenDescriptors; | ||
private readonly string _name; | ||
private readonly DirectiveDescriptorKind _type; | ||
|
||
public DefaultDirectiveDescriptorBuilder(string name, DirectiveDescriptorKind type) | ||
{ | ||
_name = name; | ||
_type = type; | ||
_tokenDescriptors = new List<DirectiveTokenDescriptor>(); | ||
} | ||
|
||
public IDirectiveDescriptorBuilder AddType() | ||
{ | ||
var descriptor = new DirectiveTokenDescriptor() | ||
{ | ||
Kind = DirectiveTokenKind.Type | ||
}; | ||
_tokenDescriptors.Add(descriptor); | ||
|
||
return this; | ||
} | ||
|
||
public IDirectiveDescriptorBuilder AddMember() | ||
{ | ||
var descriptor = new DirectiveTokenDescriptor() | ||
{ | ||
Kind = DirectiveTokenKind.Member | ||
}; | ||
_tokenDescriptors.Add(descriptor); | ||
|
||
return this; | ||
} | ||
|
||
public IDirectiveDescriptorBuilder AddString() | ||
{ | ||
var descriptor = new DirectiveTokenDescriptor() | ||
{ | ||
Kind = DirectiveTokenKind.String | ||
}; | ||
_tokenDescriptors.Add(descriptor); | ||
|
||
return this; | ||
} | ||
|
||
public IDirectiveDescriptorBuilder AddLiteral(string literal) | ||
{ | ||
var descriptor = new DirectiveTokenDescriptor() | ||
{ | ||
Kind = DirectiveTokenKind.Literal, | ||
Value = literal, | ||
}; | ||
_tokenDescriptors.Add(descriptor); | ||
|
||
return this; | ||
} | ||
|
||
public DirectiveDescriptor Build() | ||
{ | ||
var descriptor = new DirectiveDescriptor | ||
{ | ||
Name = _name, | ||
Kind = _type, | ||
Tokens = _tokenDescriptors, | ||
}; | ||
|
||
return descriptor; | ||
} | ||
} | ||
} | ||
} |
49 changes: 49 additions & 0 deletions
49
src/Microsoft.AspNetCore.Razor.Evolution/DirectiveDescriptorComparer.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using Microsoft.Extensions.Internal; | ||
|
||
namespace Microsoft.AspNetCore.Razor.Evolution | ||
{ | ||
internal class DirectiveDescriptorComparer : IEqualityComparer<DirectiveDescriptor> | ||
{ | ||
public static readonly DirectiveDescriptorComparer Default = new DirectiveDescriptorComparer(); | ||
|
||
protected DirectiveDescriptorComparer() | ||
{ | ||
} | ||
|
||
public bool Equals(DirectiveDescriptor descriptorX, DirectiveDescriptor descriptorY) | ||
{ | ||
if (descriptorX == descriptorY) | ||
{ | ||
return true; | ||
} | ||
|
||
return descriptorX != null && | ||
string.Equals(descriptorX.Name, descriptorY.Name, StringComparison.Ordinal) && | ||
descriptorX.Kind == descriptorY.Kind && | ||
Enumerable.SequenceEqual( | ||
descriptorX.Tokens, | ||
descriptorY.Tokens, | ||
DirectiveTokenDescriptorComparer.Default); | ||
} | ||
|
||
public int GetHashCode(DirectiveDescriptor descriptor) | ||
{ | ||
if (descriptor == null) | ||
{ | ||
throw new ArgumentNullException(nameof(descriptor)); | ||
} | ||
|
||
var hashCodeCombiner = HashCodeCombiner.Start(); | ||
hashCodeCombiner.Add(descriptor.Name, StringComparer.Ordinal); | ||
hashCodeCombiner.Add(descriptor.Kind); | ||
|
||
return hashCodeCombiner.CombinedHash; | ||
} | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
src/Microsoft.AspNetCore.Razor.Evolution/DirectiveDescriptorKind.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
// Copyright(c) .NET Foundation.All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
namespace Microsoft.AspNetCore.Razor.Evolution | ||
{ | ||
public enum DirectiveDescriptorKind | ||
{ | ||
SingleLine, | ||
RazorBlock, | ||
CodeBlock | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
src/Microsoft.AspNetCore.Razor.Evolution/DirectiveTokenDescriptor.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
// Copyright(c) .NET Foundation.All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
namespace Microsoft.AspNetCore.Razor.Evolution | ||
{ | ||
public class DirectiveTokenDescriptor | ||
{ | ||
public DirectiveTokenKind Kind { get; set; } | ||
|
||
public string Value { get; set; } | ||
} | ||
} |
44 changes: 44 additions & 0 deletions
44
src/Microsoft.AspNetCore.Razor.Evolution/DirectiveTokenDescriptorComparer.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using Microsoft.Extensions.Internal; | ||
|
||
namespace Microsoft.AspNetCore.Razor.Evolution | ||
{ | ||
internal class DirectiveTokenDescriptorComparer : IEqualityComparer<DirectiveTokenDescriptor> | ||
{ | ||
public static readonly DirectiveTokenDescriptorComparer Default = new DirectiveTokenDescriptorComparer(); | ||
|
||
protected DirectiveTokenDescriptorComparer() | ||
{ | ||
} | ||
|
||
public bool Equals(DirectiveTokenDescriptor descriptorX, DirectiveTokenDescriptor descriptorY) | ||
{ | ||
if (descriptorX == descriptorY) | ||
{ | ||
return true; | ||
} | ||
|
||
return descriptorX != null && | ||
string.Equals(descriptorX.Value, descriptorY.Value, StringComparison.Ordinal) && | ||
descriptorX.Kind == descriptorY.Kind; | ||
} | ||
|
||
public int GetHashCode(DirectiveTokenDescriptor descriptor) | ||
{ | ||
if (descriptor == null) | ||
{ | ||
throw new ArgumentNullException(nameof(descriptor)); | ||
} | ||
|
||
var hashCodeCombiner = HashCodeCombiner.Start(); | ||
hashCodeCombiner.Add(descriptor.Value, StringComparer.Ordinal); | ||
hashCodeCombiner.Add(descriptor.Kind); | ||
|
||
return hashCodeCombiner.CombinedHash; | ||
} | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
src/Microsoft.AspNetCore.Razor.Evolution/DirectiveTokenKind.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// Copyright(c) .NET Foundation.All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
namespace Microsoft.AspNetCore.Razor.Evolution | ||
{ | ||
public enum DirectiveTokenKind | ||
{ | ||
Type, | ||
Member, | ||
String, | ||
Literal | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
src/Microsoft.AspNetCore.Razor.Evolution/IDirectiveDescriptorBuilder.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Copyright(c) .NET Foundation.All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
namespace Microsoft.AspNetCore.Razor.Evolution | ||
{ | ||
public interface IDirectiveDescriptorBuilder | ||
{ | ||
IDirectiveDescriptorBuilder AddType(); | ||
|
||
IDirectiveDescriptorBuilder AddMember(); | ||
|
||
IDirectiveDescriptorBuilder AddString(); | ||
|
||
IDirectiveDescriptorBuilder AddLiteral(string literal); | ||
|
||
DirectiveDescriptor Build(); | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
src/Microsoft.AspNetCore.Razor.Evolution/Intermediate/DirectiveIRNode.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// Copyright(c) .NET Foundation.All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System.Collections.Generic; | ||
using System.Linq; | ||
using Microsoft.AspNetCore.Razor.Evolution.Legacy; | ||
|
||
namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate | ||
{ | ||
public class DirectiveIRNode : RazorIRNode | ||
{ | ||
public override IList<RazorIRNode> Children { get; } = new List<RazorIRNode>(); | ||
|
||
public override RazorIRNode Parent { get; set; } | ||
|
||
internal override SourceLocation SourceLocation { get; set; } | ||
|
||
public string Name { get; set; } | ||
|
||
public IEnumerable<DirectiveTokenIRNode> Tokens => Children.OfType<DirectiveTokenIRNode>(); | ||
|
||
public DirectiveDescriptor Descriptor { get; set; } | ||
|
||
public override void Accept(RazorIRNodeVisitor visitor) | ||
{ | ||
visitor.VisitDirective(this); | ||
} | ||
|
||
public override TResult Accept<TResult>(RazorIRNodeVisitor<TResult> visitor) | ||
{ | ||
return visitor.VisitDirective(this); | ||
} | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
src/Microsoft.AspNetCore.Razor.Evolution/Intermediate/DirectiveTokenIRNode.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Copyright(c) .NET Foundation.All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System.Collections.Generic; | ||
using Microsoft.AspNetCore.Razor.Evolution.Legacy; | ||
|
||
namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate | ||
{ | ||
public class DirectiveTokenIRNode : RazorIRNode | ||
{ | ||
public override IList<RazorIRNode> Children { get; } = EmptyArray; | ||
|
||
public override RazorIRNode Parent { get; set; } | ||
|
||
internal override SourceLocation SourceLocation { get; set; } | ||
|
||
public string Content { get; set; } | ||
|
||
public DirectiveTokenDescriptor Descriptor { get; set; } | ||
|
||
public override void Accept(RazorIRNodeVisitor visitor) | ||
{ | ||
visitor.VisitDirectiveToken(this); | ||
} | ||
|
||
public override TResult Accept<TResult>(RazorIRNodeVisitor<TResult> visitor) | ||
{ | ||
return visitor.VisitDirectiveToken(this); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.