Skip to content
This repository was archived by the owner on Dec 19, 2018. It is now read-only.

Commit 18db41a

Browse files
author
N. Taylor Mullen
committed
Add TagHelperDescriptorResolver implementation.
- Added a basic TagHelperDescriptor creation mechanism to the TagHelperDescriptorResolver. - Added an ITagHelperTypeResolver to be responsible for determining valid TagHelper types. #99
1 parent 369a300 commit 18db41a

File tree

8 files changed

+162
-33
lines changed

8 files changed

+162
-33
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
6+
namespace Microsoft.AspNet.Razor.Runtime
7+
{
8+
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)]
9+
internal sealed class NotNullAttribute : Attribute
10+
{
11+
}
12+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
7+
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
8+
{
9+
/// <summary>
10+
/// Defines a class that is used to resolve tag helper <see cref="Type"/>s.
11+
/// </summary>
12+
public interface ITagHelperTypeResolver
13+
{
14+
/// <summary>
15+
/// Resolves tag helper <see cref="Type"/>s.
16+
/// </summary>
17+
/// <param name="lookupText">
18+
/// A <see cref="string"/> location on where to find tag helper <see cref="Type"/>s.
19+
/// </param>
20+
/// <returns>An <see cref="IEnumerable{Type}"/> of <see cref="Type"/>s that represent tag helpers.</returns>
21+
IEnumerable<Type> Resolve(string lookupText);
22+
}
23+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
using System.Reflection;
8+
using Microsoft.AspNet.Razor.TagHelpers;
9+
10+
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
11+
{
12+
/// <summary>
13+
/// Used to resolve <see cref="TagHelperDescriptor"/>s.
14+
/// </summary>
15+
public class TagHelperDescriptorResolver : ITagHelperDescriptorResolver
16+
{
17+
private const string TagHelperNameEnding = "TagHelper";
18+
private const ContentBehavior DefaultContentBehavior = default(ContentBehavior);
19+
20+
private ITagHelperTypeResolver _tagHelperTypeResolver;
21+
22+
/// <summary>
23+
/// Instantiates a new instance of the <see cref="TagHelperDescriptorResolver"/> class.
24+
/// </summary>
25+
/// <param name="tagHelperTypeResolver">
26+
/// A type resolver used to resolve tag helper <see cref="Type"/>s.
27+
/// </param>
28+
public TagHelperDescriptorResolver([NotNull] ITagHelperTypeResolver tagHelperTypeResolver)
29+
{
30+
_tagHelperTypeResolver = tagHelperTypeResolver;
31+
}
32+
33+
/// <summary>
34+
/// Resolves <see cref="TagHelperDescriptor"/>s based on the given <paramref name="lookupText"/>.
35+
/// </summary>
36+
/// <param name="lookupText">
37+
/// A <see cref="string"/> location on where to find tag helper <see cref="Type"/>s.
38+
/// </param>
39+
/// <returns>An <see cref="IEnumerable{TagHelperDescriptor}"/> that represent tag helpers associated with the
40+
/// given <paramref name="lookupText"/>.</returns>
41+
public IEnumerable<TagHelperDescriptor> Resolve(string lookupText)
42+
{
43+
var tagHelperTypes = _tagHelperTypeResolver.Resolve(lookupText);
44+
45+
var descriptors = tagHelperTypes.Select(GetTagHelperDescriptors);
46+
47+
// TODO: Validate no conflicting ContentBehaviors after:
48+
// https://github.com/aspnet/Razor/issues/122 and https://github.com/aspnet/Razor/issues/120
49+
50+
return descriptors;
51+
}
52+
53+
// TODO: Make this method return multiple TagHelperDescriptors based on a TagNameAttribute:
54+
// https://github.com/aspnet/Razor/issues/120
55+
private static TagHelperDescriptor GetTagHelperDescriptors(Type type)
56+
{
57+
var tagName = GetTagNameTarget(type);
58+
var tagHelperTypeName = type.FullName;
59+
var attributeDescriptors = GetTagHelperAttributeDescriptors(type);
60+
var contentBehavior = GetContentBehavior(type);
61+
62+
return new TagHelperDescriptor(tagName,
63+
tagHelperTypeName,
64+
contentBehavior,
65+
attributeDescriptors);
66+
}
67+
68+
// TODO: Make this method support TagNameAttribute targets: https://github.com/aspnet/Razor/issues/120
69+
private static string GetTagNameTarget(Type tagHelperType)
70+
{
71+
var name = tagHelperType.Name;
72+
73+
if (name.EndsWith(TagHelperNameEnding, StringComparison.OrdinalIgnoreCase))
74+
{
75+
name = name.Substring(0, name.Length - TagHelperNameEnding.Length);
76+
}
77+
78+
return name;
79+
}
80+
81+
private static IEnumerable<TagHelperAttributeDescriptor> GetTagHelperAttributeDescriptors(Type type)
82+
{
83+
var typeInfo = type.GetTypeInfo();
84+
var properties = typeInfo.DeclaredProperties.Where(IsValidTagHelperProperty);
85+
var attributeDescriptors = properties.Select(ToTagHelperAttributeDescriptor);
86+
87+
// TODO: Validate no conflicting HTML attribute names: https://github.com/aspnet/Razor/issues/121
88+
89+
return attributeDescriptors;
90+
}
91+
92+
// TODO: Make the HTML attribute name support names from a AttributeNameAttribute:
93+
// https://github.com/aspnet/Razor/issues/121
94+
private static TagHelperAttributeDescriptor ToTagHelperAttributeDescriptor(PropertyInfo property)
95+
{
96+
return new TagHelperAttributeDescriptor(property.Name, property);
97+
}
98+
99+
// TODO: Make the content behavior pull from a ContentBehaviorAttribute: https://github.com/aspnet/Razor/issues/122
100+
private static ContentBehavior GetContentBehavior(Type type)
101+
{
102+
return DefaultContentBehavior;
103+
}
104+
105+
private static bool IsValidTagHelperProperty(PropertyInfo property)
106+
{
107+
return property.GetMethod != null && property.SetMethod != null;
108+
}
109+
}
110+
}

src/Microsoft.AspNet.Razor/Parser/RazorParser.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class RazorParser
1919
{
2020
private ITagHelperDescriptorResolver _tagHelperDescriptorResolver;
2121

22-
public RazorParser([NotNull] ITagHelperDescriptorResolver tagHelperDescriptorResolver,
22+
public RazorParser(ITagHelperDescriptorResolver tagHelperDescriptorResolver,
2323
[NotNull] ParserBase codeParser,
2424
[NotNull] ParserBase markupParser)
2525
{
@@ -143,12 +143,15 @@ private ParserResults ParseCore(ITextDocument input)
143143
current = rewriter.Rewrite(current);
144144
}
145145

146-
var tagHelperRegistrationVisitor = new TagHelperRegistrationVisitor(_tagHelperDescriptorResolver);
147-
var tagHelperProvider = tagHelperRegistrationVisitor.CreateProvider(current);
146+
if (_tagHelperDescriptorResolver != null)
147+
{
148+
var tagHelperRegistrationVisitor = new TagHelperRegistrationVisitor(_tagHelperDescriptorResolver);
149+
var tagHelperProvider = tagHelperRegistrationVisitor.CreateProvider(current);
148150

149-
var tagHelperParseTreeRewriter = new TagHelperParseTreeRewriter(tagHelperProvider);
150-
// Rewrite the document to utilize tag helpers
151-
current = tagHelperParseTreeRewriter.Rewrite(current);
151+
var tagHelperParseTreeRewriter = new TagHelperParseTreeRewriter(tagHelperProvider);
152+
// Rewrite the document to utilize tag helpers
153+
current = tagHelperParseTreeRewriter.Rewrite(current);
154+
}
152155

153156
// Link the leaf nodes into a chain
154157
Span prev = null;

src/Microsoft.AspNet.Razor/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33

44
using System.Runtime.CompilerServices;
55

6-
[assembly: InternalsVisibleTo("Microsoft.AspNet.Razor.Test")]
6+
[assembly: InternalsVisibleTo("Microsoft.AspNet.Razor.Test")]
7+
[assembly: InternalsVisibleTo("Microsoft.AspNet.Razor.Runtime.Test")]

src/Microsoft.AspNet.Razor/RazorEngineHost.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,11 @@ public RazorEngineHost(RazorCodeLanguage codeLanguage, Func<ParserBase> markupPa
113113
/// </summary>
114114
public virtual RazorCodeLanguage CodeLanguage { get; protected set; }
115115

116+
/// <summary>
117+
/// The <see cref="ITagHelperDescriptorResolver"/> used to resolve <see cref="TagHelperDescriptor"/>s.
118+
/// </summary>
119+
public virtual ITagHelperDescriptorResolver TagHelperDescriptorResolver { get; protected set; }
120+
116121
/// <summary>
117122
/// Boolean indicating if instrumentation code should be injected into the output page
118123
/// </summary>
@@ -161,12 +166,6 @@ public virtual ParserBase CreateMarkupParser()
161166
return null;
162167
}
163168

164-
// TODO: Document this as part of https://github.com/aspnet/Razor/issues/99
165-
public virtual ITagHelperDescriptorResolver CreateTagHelperDescriptorResolver()
166-
{
167-
return new TagHelperDescriptorResolver();
168-
}
169-
170169
/// <summary>
171170
/// Gets an instance of the code parser and is provided an opportunity to decorate or replace it
172171
/// </summary>

src/Microsoft.AspNet.Razor/RazorTemplateEngine.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,8 @@ protected internal virtual RazorParser CreateParser()
185185
{
186186
var codeParser = Host.CodeLanguage.CreateCodeParser();
187187
var markupParser = Host.CreateMarkupParser();
188-
var tagHelperDescriptorResolver = Host.CreateTagHelperDescriptorResolver();
189188

190-
return new RazorParser(tagHelperDescriptorResolver,
189+
return new RazorParser(Host.TagHelperDescriptorResolver,
191190
Host.DecorateCodeParser(codeParser),
192191
Host.DecorateMarkupParser(markupParser))
193192
{

src/Microsoft.AspNet.Razor/TagHelpers/TagHelperDescriptorResolver.cs

Lines changed: 0 additions & 18 deletions
This file was deleted.

0 commit comments

Comments
 (0)