Add TagHelper documentation resolution to TagHelperDescriptorResolver.
- Added TagHelperUseageDescriptor and associated factory for the TagHelperDescriptorFactory to utilize. - TagHelperUseageDescriptors are only created during design time. - CoreCLR is not supported for XML documentation resolution for now. Can revisit this later when we have better tooling integration with CoreCLR. #352
This commit is contained in:
parent
361a53ba3c
commit
ccf8433f27
|
|
@ -38,23 +38,30 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="assemblyName">The assembly name that contains <paramref name="type"/>.</param>
|
/// <param name="assemblyName">The assembly name that contains <paramref name="type"/>.</param>
|
||||||
/// <param name="type">The type to create a <see cref="TagHelperDescriptor"/> from.</param>
|
/// <param name="type">The type to create a <see cref="TagHelperDescriptor"/> from.</param>
|
||||||
|
/// <param name="designTime">Indicates if the returned <see cref="TagHelperDescriptor"/>s should include
|
||||||
|
/// design time specific information.</param>
|
||||||
|
/// <param name="errorSink">The <see cref="ErrorSink"/> used to collect <see cref="RazorError"/>s encountered
|
||||||
|
/// when creating <see cref="TagHelperDescriptor"/>s for the given <paramref name="type"/>.</param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// A collection of <see cref="TagHelperDescriptor"/>s that describe the given <paramref name="type"/>.
|
/// A collection of <see cref="TagHelperDescriptor"/>s that describe the given <paramref name="type"/>.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public static IEnumerable<TagHelperDescriptor> CreateDescriptors(
|
public static IEnumerable<TagHelperDescriptor> CreateDescriptors(
|
||||||
string assemblyName,
|
string assemblyName,
|
||||||
[NotNull] Type type,
|
[NotNull] Type type,
|
||||||
|
bool designTime,
|
||||||
[NotNull] ErrorSink errorSink)
|
[NotNull] ErrorSink errorSink)
|
||||||
{
|
{
|
||||||
var typeInfo = type.GetTypeInfo();
|
var typeInfo = type.GetTypeInfo();
|
||||||
var attributeDescriptors = GetAttributeDescriptors(type, errorSink);
|
var attributeDescriptors = GetAttributeDescriptors(type, designTime, errorSink);
|
||||||
var targetElementAttributes = GetValidTargetElementAttributes(typeInfo, errorSink);
|
var targetElementAttributes = GetValidTargetElementAttributes(typeInfo, errorSink);
|
||||||
|
|
||||||
var tagHelperDescriptors =
|
var tagHelperDescriptors =
|
||||||
BuildTagHelperDescriptors(
|
BuildTagHelperDescriptors(
|
||||||
typeInfo,
|
typeInfo,
|
||||||
assemblyName,
|
assemblyName,
|
||||||
attributeDescriptors,
|
attributeDescriptors,
|
||||||
targetElementAttributes);
|
targetElementAttributes,
|
||||||
|
designTime);
|
||||||
|
|
||||||
return tagHelperDescriptors.Distinct(TagHelperDescriptorComparer.Default);
|
return tagHelperDescriptors.Distinct(TagHelperDescriptorComparer.Default);
|
||||||
}
|
}
|
||||||
|
|
@ -72,8 +79,18 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
TypeInfo typeInfo,
|
TypeInfo typeInfo,
|
||||||
string assemblyName,
|
string assemblyName,
|
||||||
IEnumerable<TagHelperAttributeDescriptor> attributeDescriptors,
|
IEnumerable<TagHelperAttributeDescriptor> attributeDescriptors,
|
||||||
IEnumerable<TargetElementAttribute> targetElementAttributes)
|
IEnumerable<TargetElementAttribute> targetElementAttributes,
|
||||||
|
bool designTime)
|
||||||
{
|
{
|
||||||
|
TagHelperUsageDescriptor typeUsageDescriptor = null;
|
||||||
|
|
||||||
|
#if !DNXCORE50
|
||||||
|
if (designTime)
|
||||||
|
{
|
||||||
|
typeUsageDescriptor = TagHelperUsageDescriptorFactory.CreateDescriptor(typeInfo.GetType());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
var typeName = typeInfo.FullName;
|
var typeName = typeInfo.FullName;
|
||||||
|
|
||||||
// If there isn't an attribute specifying the tag name derive it from the name
|
// If there isn't an attribute specifying the tag name derive it from the name
|
||||||
|
|
@ -93,19 +110,27 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
typeName,
|
typeName,
|
||||||
assemblyName,
|
assemblyName,
|
||||||
attributeDescriptors,
|
attributeDescriptors,
|
||||||
requiredAttributes: Enumerable.Empty<string>())
|
requiredAttributes: Enumerable.Empty<string>(),
|
||||||
|
usageDescriptor: typeUsageDescriptor)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return targetElementAttributes.Select(
|
return targetElementAttributes.Select(
|
||||||
attribute => BuildTagHelperDescriptor(typeName, assemblyName, attributeDescriptors, attribute));
|
attribute =>
|
||||||
|
BuildTagHelperDescriptor(
|
||||||
|
typeName,
|
||||||
|
assemblyName,
|
||||||
|
attributeDescriptors,
|
||||||
|
attribute,
|
||||||
|
typeUsageDescriptor));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TagHelperDescriptor BuildTagHelperDescriptor(
|
private static TagHelperDescriptor BuildTagHelperDescriptor(
|
||||||
string typeName,
|
string typeName,
|
||||||
string assemblyName,
|
string assemblyName,
|
||||||
IEnumerable<TagHelperAttributeDescriptor> attributeDescriptors,
|
IEnumerable<TagHelperAttributeDescriptor> attributeDescriptors,
|
||||||
TargetElementAttribute targetElementAttribute)
|
TargetElementAttribute targetElementAttribute,
|
||||||
|
TagHelperUsageDescriptor usageDescriptor)
|
||||||
{
|
{
|
||||||
var requiredAttributes = GetCommaSeparatedValues(targetElementAttribute.Attributes);
|
var requiredAttributes = GetCommaSeparatedValues(targetElementAttribute.Attributes);
|
||||||
|
|
||||||
|
|
@ -114,7 +139,8 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
typeName,
|
typeName,
|
||||||
assemblyName,
|
assemblyName,
|
||||||
attributeDescriptors,
|
attributeDescriptors,
|
||||||
requiredAttributes);
|
requiredAttributes,
|
||||||
|
usageDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TagHelperDescriptor BuildTagHelperDescriptor(
|
private static TagHelperDescriptor BuildTagHelperDescriptor(
|
||||||
|
|
@ -122,7 +148,8 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
string typeName,
|
string typeName,
|
||||||
string assemblyName,
|
string assemblyName,
|
||||||
IEnumerable<TagHelperAttributeDescriptor> attributeDescriptors,
|
IEnumerable<TagHelperAttributeDescriptor> attributeDescriptors,
|
||||||
IEnumerable<string> requiredAttributes)
|
IEnumerable<string> requiredAttributes,
|
||||||
|
TagHelperUsageDescriptor usageDescriptor)
|
||||||
{
|
{
|
||||||
return new TagHelperDescriptor(
|
return new TagHelperDescriptor(
|
||||||
prefix: string.Empty,
|
prefix: string.Empty,
|
||||||
|
|
@ -130,7 +157,8 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
typeName: typeName,
|
typeName: typeName,
|
||||||
assemblyName: assemblyName,
|
assemblyName: assemblyName,
|
||||||
attributes: attributeDescriptors,
|
attributes: attributeDescriptors,
|
||||||
requiredAttributes: requiredAttributes);
|
requiredAttributes: requiredAttributes,
|
||||||
|
usageDescriptor: usageDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -225,6 +253,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
|
|
||||||
private static IEnumerable<TagHelperAttributeDescriptor> GetAttributeDescriptors(
|
private static IEnumerable<TagHelperAttributeDescriptor> GetAttributeDescriptors(
|
||||||
Type type,
|
Type type,
|
||||||
|
bool designTime,
|
||||||
ErrorSink errorSink)
|
ErrorSink errorSink)
|
||||||
{
|
{
|
||||||
var accessibleProperties = type.GetRuntimeProperties().Where(IsAccessibleProperty);
|
var accessibleProperties = type.GetRuntimeProperties().Where(IsAccessibleProperty);
|
||||||
|
|
@ -236,7 +265,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
foreach (var property in accessibleProperties)
|
foreach (var property in accessibleProperties)
|
||||||
{
|
{
|
||||||
var attributeNameAttribute = property.GetCustomAttribute<HtmlAttributeNameAttribute>(inherit: false);
|
var attributeNameAttribute = property.GetCustomAttribute<HtmlAttributeNameAttribute>(inherit: false);
|
||||||
var descriptor = ToAttributeDescriptor(property, attributeNameAttribute);
|
var descriptor = ToAttributeDescriptor(property, attributeNameAttribute, designTime);
|
||||||
if (ValidateTagHelperAttributeDescriptor(descriptor, type, errorSink))
|
if (ValidateTagHelperAttributeDescriptor(descriptor, type, errorSink))
|
||||||
{
|
{
|
||||||
bool isInvalid;
|
bool isInvalid;
|
||||||
|
|
@ -246,6 +275,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
parentType: type,
|
parentType: type,
|
||||||
errorSink: errorSink,
|
errorSink: errorSink,
|
||||||
defaultPrefix: descriptor.Name + "-",
|
defaultPrefix: descriptor.Name + "-",
|
||||||
|
designTime: designTime,
|
||||||
isInvalid: out isInvalid);
|
isInvalid: out isInvalid);
|
||||||
|
|
||||||
if (indexerDescriptor != null &&
|
if (indexerDescriptor != null &&
|
||||||
|
|
@ -358,17 +388,19 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
|
|
||||||
private static TagHelperAttributeDescriptor ToAttributeDescriptor(
|
private static TagHelperAttributeDescriptor ToAttributeDescriptor(
|
||||||
PropertyInfo property,
|
PropertyInfo property,
|
||||||
HtmlAttributeNameAttribute attributeNameAttribute)
|
HtmlAttributeNameAttribute attributeNameAttribute,
|
||||||
|
bool designTime)
|
||||||
{
|
{
|
||||||
var attributeName = attributeNameAttribute != null ?
|
var attributeName = attributeNameAttribute != null ?
|
||||||
attributeNameAttribute.Name :
|
attributeNameAttribute.Name :
|
||||||
ToHtmlCase(property.Name);
|
ToHtmlCase(property.Name);
|
||||||
|
|
||||||
return new TagHelperAttributeDescriptor(
|
return ToAttributeDescriptor(
|
||||||
|
property,
|
||||||
attributeName,
|
attributeName,
|
||||||
property.Name,
|
|
||||||
property.PropertyType.FullName,
|
property.PropertyType.FullName,
|
||||||
isIndexer: false);
|
isIndexer: false,
|
||||||
|
designTime: designTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TagHelperAttributeDescriptor ToIndexerAttributeDescriptor(
|
private static TagHelperAttributeDescriptor ToIndexerAttributeDescriptor(
|
||||||
|
|
@ -377,6 +409,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
Type parentType,
|
Type parentType,
|
||||||
ErrorSink errorSink,
|
ErrorSink errorSink,
|
||||||
string defaultPrefix,
|
string defaultPrefix,
|
||||||
|
bool designTime,
|
||||||
out bool isInvalid)
|
out bool isInvalid)
|
||||||
{
|
{
|
||||||
isInvalid = false;
|
isInvalid = false;
|
||||||
|
|
@ -414,11 +447,36 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new TagHelperAttributeDescriptor(
|
return ToAttributeDescriptor(
|
||||||
name: prefix,
|
property,
|
||||||
propertyName: property.Name,
|
attributeName: prefix,
|
||||||
typeName: dictionaryTypeArguments[1].FullName,
|
typeName: dictionaryTypeArguments[1].FullName,
|
||||||
isIndexer: true);
|
isIndexer: true,
|
||||||
|
designTime: designTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TagHelperAttributeDescriptor ToAttributeDescriptor(
|
||||||
|
PropertyInfo property,
|
||||||
|
string attributeName,
|
||||||
|
string typeName,
|
||||||
|
bool isIndexer,
|
||||||
|
bool designTime)
|
||||||
|
{
|
||||||
|
TagHelperUsageDescriptor propertyUsageDescriptor = null;
|
||||||
|
|
||||||
|
#if !DNXCORE50
|
||||||
|
if (designTime)
|
||||||
|
{
|
||||||
|
propertyUsageDescriptor = TagHelperUsageDescriptorFactory.CreateDescriptor(property);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return new TagHelperAttributeDescriptor(
|
||||||
|
attributeName,
|
||||||
|
property.Name,
|
||||||
|
typeName,
|
||||||
|
isIndexer,
|
||||||
|
propertyUsageDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsAccessibleProperty(PropertyInfo property)
|
private static bool IsAccessibleProperty(PropertyInfo property)
|
||||||
|
|
|
||||||
|
|
@ -26,14 +26,16 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly TagHelperTypeResolver _typeResolver;
|
private readonly TagHelperTypeResolver _typeResolver;
|
||||||
|
private readonly bool _designTime;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Instantiates a new instance of the <see cref="TagHelperDescriptorResolver"/> class.
|
/// Instantiates a new instance of the <see cref="TagHelperDescriptorResolver"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TagHelperDescriptorResolver()
|
/// <param name="designTime">Indicates whether resolved <see cref="TagHelperDescriptor"/>s should include
|
||||||
: this(new TagHelperTypeResolver())
|
/// design time specific information.</param>
|
||||||
|
public TagHelperDescriptorResolver(bool designTime)
|
||||||
|
: this(new TagHelperTypeResolver(), designTime)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -41,9 +43,12 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
/// specified <paramref name="typeResolver"/>.
|
/// specified <paramref name="typeResolver"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="typeResolver">The <see cref="TagHelperTypeResolver"/>.</param>
|
/// <param name="typeResolver">The <see cref="TagHelperTypeResolver"/>.</param>
|
||||||
public TagHelperDescriptorResolver(TagHelperTypeResolver typeResolver)
|
/// <param name="designTime">Indicates whether resolved <see cref="TagHelperDescriptor"/>s should include
|
||||||
|
/// design time specific information.</param>
|
||||||
|
public TagHelperDescriptorResolver(TagHelperTypeResolver typeResolver, bool designTime)
|
||||||
{
|
{
|
||||||
_typeResolver = typeResolver;
|
_typeResolver = typeResolver;
|
||||||
|
_designTime = designTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|
@ -113,7 +118,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
/// The name of the assembly to resolve <see cref="TagHelperDescriptor"/>s from.
|
/// The name of the assembly to resolve <see cref="TagHelperDescriptor"/>s from.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <param name="documentLocation">The <see cref="SourceLocation"/> of the directive.</param>
|
/// <param name="documentLocation">The <see cref="SourceLocation"/> of the directive.</param>
|
||||||
/// <param name="errorSink">Used to record errors found when resolving <see cref="TagHelperDescriptor"/>s
|
/// <param name="errorSink">Used to record errors found when resolving <see cref="TagHelperDescriptor"/>s
|
||||||
/// within the given <paramref name="assemblyName"/>.</param>
|
/// within the given <paramref name="assemblyName"/>.</param>
|
||||||
/// <returns><see cref="TagHelperDescriptor"/>s for <see cref="ITagHelper"/>s from the given
|
/// <returns><see cref="TagHelperDescriptor"/>s for <see cref="ITagHelper"/>s from the given
|
||||||
/// <paramref name="assemblyName"/>.</returns>
|
/// <paramref name="assemblyName"/>.</returns>
|
||||||
|
|
@ -128,7 +133,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
|
|
||||||
// Convert types to TagHelperDescriptors
|
// Convert types to TagHelperDescriptors
|
||||||
var descriptors = tagHelperTypes.SelectMany(
|
var descriptors = tagHelperTypes.SelectMany(
|
||||||
type => TagHelperDescriptorFactory.CreateDescriptors(assemblyName, type, errorSink));
|
type => TagHelperDescriptorFactory.CreateDescriptors(assemblyName, type, _designTime, errorSink));
|
||||||
|
|
||||||
return descriptors;
|
return descriptors;
|
||||||
}
|
}
|
||||||
|
|
@ -148,7 +153,8 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
descriptor.TypeName,
|
descriptor.TypeName,
|
||||||
descriptor.AssemblyName,
|
descriptor.AssemblyName,
|
||||||
descriptor.Attributes,
|
descriptor.Attributes,
|
||||||
descriptor.RequiredAttributes));
|
descriptor.RequiredAttributes,
|
||||||
|
descriptor.UsageDescriptor));
|
||||||
}
|
}
|
||||||
|
|
||||||
return descriptors;
|
return descriptors;
|
||||||
|
|
@ -222,7 +228,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
// We need to escape the TypePattern so we can choose to only allow specific regex.
|
// We need to escape the TypePattern so we can choose to only allow specific regex.
|
||||||
var escaped = Regex.Escape(lookupInfo.TypePattern);
|
var escaped = Regex.Escape(lookupInfo.TypePattern);
|
||||||
|
|
||||||
// We surround the escaped with ^ and $ in order ot ensure a regex match matches the entire
|
// We surround the escaped with ^ and $ in order ot ensure a regex match matches the entire
|
||||||
// string. We also replace any '*' or '?' characters with regex to match appropriate content.
|
// string. We also replace any '*' or '?' characters with regex to match appropriate content.
|
||||||
// '*' matches 0 or more characters lazily and '?' matches 1 character.
|
// '*' matches 0 or more characters lazily and '?' matches 1 character.
|
||||||
var pattern = "^" + escaped.Replace(@"\?", ".").Replace(@"\*", ".*?") + "$";
|
var pattern = "^" + escaped.Replace(@"\?", ".").Replace(@"\*", ".*?") + "$";
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,162 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#if !DNXCORE50 // Cannot accurately resolve the location of the documentation XML file in coreclr.
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using Microsoft.AspNet.Razor.TagHelpers;
|
||||||
|
using Microsoft.Framework.Internal;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Factory for providing <see cref="TagHelperUsageDescriptor"/>s from <see cref="Type"/>s and
|
||||||
|
/// <see cref="PropertyInfo"/>s.
|
||||||
|
/// </summary>
|
||||||
|
public static class TagHelperUsageDescriptorFactory
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a <see cref="TagHelperUsageDescriptor"/> from the given <paramref name="type"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">The <see cref="Type"/> to create a <see cref="TagHelperUsageDescriptor"/> from.</param>
|
||||||
|
/// <returns>A <see cref="TagHelperUsageDescriptor"/> that describes the summary and remarks XML documentation
|
||||||
|
/// for the given <paramref name="type"/>.</returns>
|
||||||
|
public static TagHelperUsageDescriptor CreateDescriptor([NotNull] Type type)
|
||||||
|
{
|
||||||
|
var id = XmlDocumentationProvider.GetId(type);
|
||||||
|
|
||||||
|
return CreateDescriptorCore(type.Assembly, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a <see cref="TagHelperUsageDescriptor"/> from the given <paramref name="propertyInfo"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="propertyInfo">The <see cref="PropertyInfo"/> to create a
|
||||||
|
/// <see cref="TagHelperUsageDescriptor"/> from.</param>
|
||||||
|
/// <returns>A <see cref="TagHelperUsageDescriptor"/> that describes the summary and remarks XML documentation
|
||||||
|
/// for the given <paramref name="propertyInfo"/>.</returns>
|
||||||
|
public static TagHelperUsageDescriptor CreateDescriptor([NotNull] PropertyInfo propertyInfo)
|
||||||
|
{
|
||||||
|
var id = XmlDocumentationProvider.GetId(propertyInfo);
|
||||||
|
var declaringAssembly = propertyInfo.DeclaringType.Assembly;
|
||||||
|
|
||||||
|
return CreateDescriptorCore(declaringAssembly, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TagHelperUsageDescriptor CreateDescriptorCore(Assembly assembly, string id)
|
||||||
|
{
|
||||||
|
var assemblyLocation = assembly.Location;
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(assemblyLocation) && !string.IsNullOrEmpty(assembly.CodeBase))
|
||||||
|
{
|
||||||
|
var uri = new UriBuilder(assembly.CodeBase);
|
||||||
|
|
||||||
|
// Normalize the path to a UNC path. This will remove things like file:// from start of the uri.Path.
|
||||||
|
assemblyLocation = Uri.UnescapeDataString(uri.Path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Couldn't resolve a valid assemblyLocation.
|
||||||
|
if (string.IsNullOrEmpty(assemblyLocation))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var xmlDocumentationFile = GetXmlDocumentationFile(assembly, assemblyLocation);
|
||||||
|
|
||||||
|
// Only want to process the file if it exists.
|
||||||
|
if (xmlDocumentationFile != null)
|
||||||
|
{
|
||||||
|
var documentationProvider = new XmlDocumentationProvider(xmlDocumentationFile.FullName);
|
||||||
|
|
||||||
|
var summary = documentationProvider.GetSummary(id);
|
||||||
|
var remarks = documentationProvider.GetRemarks(id);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(summary) || !string.IsNullOrEmpty(remarks))
|
||||||
|
{
|
||||||
|
return new TagHelperUsageDescriptor(summary, remarks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static FileInfo GetXmlDocumentationFile(Assembly assembly, string assemblyLocation)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var assemblyDirectory = Path.GetDirectoryName(assemblyLocation);
|
||||||
|
var assemblyName = Path.GetFileName(assemblyLocation);
|
||||||
|
var assemblyXmlDocumentationName = Path.ChangeExtension(assemblyName, ".xml");
|
||||||
|
|
||||||
|
// Check for a localized XML file for the current culture.
|
||||||
|
var xmlDocumentationFile = GetLocalizedXmlDocumentationFile(
|
||||||
|
CultureInfo.CurrentCulture,
|
||||||
|
assemblyDirectory,
|
||||||
|
assemblyXmlDocumentationName);
|
||||||
|
|
||||||
|
if (xmlDocumentationFile == null)
|
||||||
|
{
|
||||||
|
// Check for a culture-neutral XML file next to the assembly
|
||||||
|
xmlDocumentationFile = new FileInfo(
|
||||||
|
Path.Combine(assemblyDirectory, assemblyXmlDocumentationName));
|
||||||
|
|
||||||
|
if (!xmlDocumentationFile.Exists)
|
||||||
|
{
|
||||||
|
xmlDocumentationFile = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return xmlDocumentationFile;
|
||||||
|
}
|
||||||
|
catch (ArgumentException)
|
||||||
|
{
|
||||||
|
// Could not resolve XML file.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<string> ExpandPaths(
|
||||||
|
CultureInfo culture,
|
||||||
|
string assemblyDirectory,
|
||||||
|
string assemblyXmlDocumentationName)
|
||||||
|
{
|
||||||
|
// Following the fall-back process defined by:
|
||||||
|
// https://msdn.microsoft.com/en-us/library/sb6a8618.aspx#cpconpackagingdeployingresourcesanchor1
|
||||||
|
do
|
||||||
|
{
|
||||||
|
var cultureName = culture.Name;
|
||||||
|
var cultureSpecificFileName =
|
||||||
|
Path.ChangeExtension(assemblyXmlDocumentationName, cultureName + ".xml");
|
||||||
|
|
||||||
|
// Look for a culture specific XML file next to the assembly.
|
||||||
|
yield return Path.Combine(assemblyDirectory, cultureSpecificFileName);
|
||||||
|
|
||||||
|
// Look for an XML file with the same name as the assembly in a culture specific directory.
|
||||||
|
yield return Path.Combine(assemblyDirectory, cultureName, assemblyXmlDocumentationName);
|
||||||
|
|
||||||
|
// Look for a culture specific XML file in a culture specific directory.
|
||||||
|
yield return Path.Combine(assemblyDirectory, cultureName, cultureSpecificFileName);
|
||||||
|
|
||||||
|
culture = culture.Parent;
|
||||||
|
} while (culture != null && culture != CultureInfo.InvariantCulture);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static FileInfo GetLocalizedXmlDocumentationFile(
|
||||||
|
CultureInfo culture,
|
||||||
|
string assemblyDirectory,
|
||||||
|
string assemblyXmlDocumentationName)
|
||||||
|
{
|
||||||
|
var localizedXmlPaths = ExpandPaths(culture, assemblyDirectory, assemblyXmlDocumentationName);
|
||||||
|
var xmlDocumentationFile = localizedXmlPaths
|
||||||
|
.Select(path => new FileInfo(path))
|
||||||
|
.FirstOrDefault(file => file.Exists);
|
||||||
|
|
||||||
|
return xmlDocumentationFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,120 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#if !DNXCORE50
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using Microsoft.Framework.Internal;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Razor.Runtime
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Extracts summary and remarks XML documentation from an XML documentation file.
|
||||||
|
/// </summary>
|
||||||
|
public class XmlDocumentationProvider
|
||||||
|
{
|
||||||
|
private readonly IEnumerable<XElement> _members;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Instantiates a new instance of the <see cref="XmlDocumentationProvider"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="xmlFileLocation">Path to the XML documentation file to read.</param>
|
||||||
|
public XmlDocumentationProvider(string xmlFileLocation)
|
||||||
|
{
|
||||||
|
// XML file processing is defined by: https://msdn.microsoft.com/en-us/library/fsbx0t7x.aspx
|
||||||
|
var xmlDocumentation = XDocument.Load(xmlFileLocation);
|
||||||
|
var documentationRootMembers = xmlDocumentation.Root.Element("members");
|
||||||
|
_members = documentationRootMembers.Elements("member");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves the <c><summary></c> documentation for the given <paramref name="id"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">The id to lookup.</param>
|
||||||
|
/// <returns><c><summary></c> documentation for the given <paramref name="id"/>.</returns>
|
||||||
|
public string GetSummary(string id)
|
||||||
|
{
|
||||||
|
var associatedMemeber = GetMember(id);
|
||||||
|
var summaryElement = associatedMemeber?.Element("summary");
|
||||||
|
|
||||||
|
if (summaryElement != null)
|
||||||
|
{
|
||||||
|
var summaryValue = GetElementValue(summaryElement);
|
||||||
|
|
||||||
|
return summaryValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves the <c><remarks></c> documentation for the given <paramref name="id"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">The id to lookup.</param>
|
||||||
|
/// <returns><c><remarks></c> documentation for the given <paramref name="id"/>.</returns>
|
||||||
|
public string GetRemarks(string id)
|
||||||
|
{
|
||||||
|
var associatedMemeber = GetMember(id);
|
||||||
|
var remarksElement = associatedMemeber?.Element("remarks");
|
||||||
|
|
||||||
|
if (remarksElement != null)
|
||||||
|
{
|
||||||
|
var remarksValue = GetElementValue(remarksElement);
|
||||||
|
|
||||||
|
return remarksValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates the <see cref="string"/> identifier for the given <paramref name="type"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">The <see cref="Type"/> to get the identifier for.</param>
|
||||||
|
/// <returns>The <see cref="string"/> identifier for the given <paramref name="type"/>.</returns>
|
||||||
|
public static string GetId([NotNull] Type type)
|
||||||
|
{
|
||||||
|
return $"T:{type.FullName}";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates the <see cref="string"/> identifier for the given <paramref name="propertyInfo"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="propertyInfo">The <see cref="PropertyInfo"/> to get the identifier for.</param>
|
||||||
|
/// <returns>The <see cref="string"/> identifier for the given <paramref name="propertyInfo"/>.</returns>
|
||||||
|
public static string GetId([NotNull] PropertyInfo propertyInfo)
|
||||||
|
{
|
||||||
|
var declaringTypeInfo = propertyInfo.DeclaringType;
|
||||||
|
return $"P:{declaringTypeInfo.FullName}.{propertyInfo.Name}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private XElement GetMember(string id)
|
||||||
|
{
|
||||||
|
var associatedMemeber = _members
|
||||||
|
.FirstOrDefault(element =>
|
||||||
|
string.Equals(element.Attribute("name").Value, id, StringComparison.Ordinal));
|
||||||
|
|
||||||
|
return associatedMemeber;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetElementValue(XElement element)
|
||||||
|
{
|
||||||
|
var stringBuilder = new StringBuilder();
|
||||||
|
var node = element.FirstNode;
|
||||||
|
|
||||||
|
while (node != null)
|
||||||
|
{
|
||||||
|
stringBuilder.Append(node.ToString(SaveOptions.DisableFormatting));
|
||||||
|
|
||||||
|
node = node.NextNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return stringBuilder.ToString().Trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
@ -9,8 +9,18 @@
|
||||||
"Microsoft.Framework.NotNullAttribute.Sources": { "type": "build", "version": "1.0.0-*" }
|
"Microsoft.Framework.NotNullAttribute.Sources": { "type": "build", "version": "1.0.0-*" }
|
||||||
},
|
},
|
||||||
"frameworks": {
|
"frameworks": {
|
||||||
"net45": { },
|
"net45": {
|
||||||
"dnx451": { },
|
"frameworkAssemblies": {
|
||||||
|
"System.Xml": "4.0.0.0",
|
||||||
|
"System.Xml.Linq": "4.0.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dnx451": {
|
||||||
|
"frameworkAssemblies": {
|
||||||
|
"System.Xml": "4.0.0.0",
|
||||||
|
"System.Xml.Linq": "4.0.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"dnxcore50": {
|
"dnxcore50": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"System.Reflection.Extensions": "4.0.0-beta-*",
|
"System.Reflection.Extensions": "4.0.0-beta-*",
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,8 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
||||||
propertyInfo.Name,
|
propertyInfo.Name,
|
||||||
propertyInfo.PropertyType.FullName,
|
propertyInfo.PropertyType.FullName,
|
||||||
isIndexer: false,
|
isIndexer: false,
|
||||||
isStringProperty: propertyInfo.PropertyType == typeof(string))
|
isStringProperty: propertyInfo.PropertyType == typeof(string),
|
||||||
|
usageDescriptor: null)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -39,6 +40,8 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
||||||
/// If <c>true</c> this <see cref="TagHelperAttributeDescriptor"/> is used for dictionary indexer assignments.
|
/// If <c>true</c> this <see cref="TagHelperAttributeDescriptor"/> is used for dictionary indexer assignments.
|
||||||
/// Otherwise this <see cref="TagHelperAttributeDescriptor"/> is used for property assignment.
|
/// Otherwise this <see cref="TagHelperAttributeDescriptor"/> is used for property assignment.
|
||||||
/// </param>
|
/// </param>
|
||||||
|
/// <param name="usageDescriptor">The <see cref="TagHelperUsageDescriptor"/> that contains information about
|
||||||
|
/// use of this attribute.</param>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// HTML attribute names are matched case-insensitively, regardless of <paramref name="isIndexer"/>.
|
/// HTML attribute names are matched case-insensitively, regardless of <paramref name="isIndexer"/>.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
|
|
@ -46,13 +49,15 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
||||||
[NotNull] string name,
|
[NotNull] string name,
|
||||||
[NotNull] string propertyName,
|
[NotNull] string propertyName,
|
||||||
[NotNull] string typeName,
|
[NotNull] string typeName,
|
||||||
bool isIndexer)
|
bool isIndexer,
|
||||||
|
TagHelperUsageDescriptor usageDescriptor)
|
||||||
: this(
|
: this(
|
||||||
name,
|
name,
|
||||||
propertyName,
|
propertyName,
|
||||||
typeName,
|
typeName,
|
||||||
isIndexer,
|
isIndexer,
|
||||||
isStringProperty: string.Equals(typeName, typeof(string).FullName, StringComparison.Ordinal))
|
isStringProperty: string.Equals(typeName, typeof(string).FullName, StringComparison.Ordinal),
|
||||||
|
usageDescriptor: usageDescriptor)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -62,13 +67,15 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
||||||
[NotNull] string propertyName,
|
[NotNull] string propertyName,
|
||||||
[NotNull] string typeName,
|
[NotNull] string typeName,
|
||||||
bool isIndexer,
|
bool isIndexer,
|
||||||
bool isStringProperty)
|
bool isStringProperty,
|
||||||
|
TagHelperUsageDescriptor usageDescriptor)
|
||||||
{
|
{
|
||||||
Name = name;
|
Name = name;
|
||||||
PropertyName = propertyName;
|
PropertyName = propertyName;
|
||||||
TypeName = typeName;
|
TypeName = typeName;
|
||||||
IsIndexer = isIndexer;
|
IsIndexer = isIndexer;
|
||||||
IsStringProperty = isStringProperty;
|
IsStringProperty = isStringProperty;
|
||||||
|
UsageDescriptor = usageDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -111,6 +118,11 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string TypeName { get; }
|
public string TypeName { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="TagHelperUsageDescriptor"/> that contains information about use of this attribute.
|
||||||
|
/// </summary>
|
||||||
|
public TagHelperUsageDescriptor UsageDescriptor { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether HTML attribute <paramref name="name"/> matches this
|
/// Determines whether HTML attribute <paramref name="name"/> matches this
|
||||||
/// <see cref="TagHelperAttributeDescriptor"/>.
|
/// <see cref="TagHelperAttributeDescriptor"/>.
|
||||||
|
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
||||||
// 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.Framework.Internal;
|
|
||||||
using Microsoft.Internal.Web.Utils;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Razor.TagHelpers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// An <see cref="IEqualityComparer{TagHelperAttributeDescriptor}"/> used to check equality between
|
|
||||||
/// two <see cref="TagHelperAttributeDescriptor"/>s.
|
|
||||||
/// </summary>
|
|
||||||
public class TagHelperAttributeDescriptorComparer : IEqualityComparer<TagHelperAttributeDescriptor>
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A default instance of the <see cref="TagHelperAttributeDescriptorComparer"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly TagHelperAttributeDescriptorComparer Default =
|
|
||||||
new TagHelperAttributeDescriptorComparer();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new <see cref="TagHelperAttributeDescriptorComparer"/> instance.
|
|
||||||
/// </summary>
|
|
||||||
protected TagHelperAttributeDescriptorComparer()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
/// <remarks>
|
|
||||||
/// Determines equality based on <see cref="TagHelperAttributeDescriptor.IsIndexer"/>,
|
|
||||||
/// <see cref="TagHelperAttributeDescriptor.Name"/>, <see cref="TagHelperAttributeDescriptor.PropertyName"/>,
|
|
||||||
/// and <see cref="TagHelperAttributeDescriptor.TypeName"/>. Ignores
|
|
||||||
/// <see cref="TagHelperAttributeDescriptor.IsStringProperty"/> because it can be inferred directly from
|
|
||||||
/// <see cref="TagHelperAttributeDescriptor.TypeName"/>.
|
|
||||||
/// </remarks>
|
|
||||||
public virtual bool Equals(TagHelperAttributeDescriptor descriptorX, TagHelperAttributeDescriptor descriptorY)
|
|
||||||
{
|
|
||||||
if (descriptorX == descriptorY)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check Name and TypeName though each property in a particular tag helper has at most two
|
|
||||||
// TagHelperAttributeDescriptors (one for the indexer and one not). May be comparing attributes between
|
|
||||||
// tag helpers and should be as specific as we can.
|
|
||||||
return descriptorX != null &&
|
|
||||||
descriptorX.IsIndexer == descriptorY.IsIndexer &&
|
|
||||||
string.Equals(descriptorX.Name, descriptorY.Name, StringComparison.OrdinalIgnoreCase) &&
|
|
||||||
string.Equals(descriptorX.PropertyName, descriptorY.PropertyName, StringComparison.Ordinal) &&
|
|
||||||
string.Equals(descriptorX.TypeName, descriptorY.TypeName, StringComparison.Ordinal);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public virtual int GetHashCode([NotNull] TagHelperAttributeDescriptor descriptor)
|
|
||||||
{
|
|
||||||
// Rarely if ever hash TagHelperAttributeDescriptor. If we do, include the Name and TypeName since context
|
|
||||||
// information is not available in the hash.
|
|
||||||
return HashCodeCombiner.Start()
|
|
||||||
.Add(descriptor.IsIndexer)
|
|
||||||
.Add(descriptor.Name, StringComparer.OrdinalIgnoreCase)
|
|
||||||
.Add(descriptor.PropertyName, StringComparer.Ordinal)
|
|
||||||
.Add(descriptor.TypeName, StringComparer.Ordinal)
|
|
||||||
.CombinedHash;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -59,7 +59,8 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
||||||
typeName: typeName,
|
typeName: typeName,
|
||||||
assemblyName: assemblyName,
|
assemblyName: assemblyName,
|
||||||
attributes: attributes,
|
attributes: attributes,
|
||||||
requiredAttributes: requiredAttributes)
|
requiredAttributes: requiredAttributes,
|
||||||
|
usageDescriptor: null)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -81,13 +82,16 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
||||||
/// <param name="requiredAttributes">
|
/// <param name="requiredAttributes">
|
||||||
/// The attribute names required for the tag helper to target the HTML tag.
|
/// The attribute names required for the tag helper to target the HTML tag.
|
||||||
/// </param>
|
/// </param>
|
||||||
|
/// <param name="usageDescriptor">The <see cref="TagHelperUsageDescriptor"/> that contains information about
|
||||||
|
/// how to use the tag helper at design time.</param>
|
||||||
public TagHelperDescriptor(
|
public TagHelperDescriptor(
|
||||||
string prefix,
|
string prefix,
|
||||||
[NotNull] string tagName,
|
[NotNull] string tagName,
|
||||||
[NotNull] string typeName,
|
[NotNull] string typeName,
|
||||||
[NotNull] string assemblyName,
|
[NotNull] string assemblyName,
|
||||||
[NotNull] IEnumerable<TagHelperAttributeDescriptor> attributes,
|
[NotNull] IEnumerable<TagHelperAttributeDescriptor> attributes,
|
||||||
[NotNull] IEnumerable<string> requiredAttributes)
|
[NotNull] IEnumerable<string> requiredAttributes,
|
||||||
|
TagHelperUsageDescriptor usageDescriptor)
|
||||||
{
|
{
|
||||||
Prefix = prefix ?? string.Empty;
|
Prefix = prefix ?? string.Empty;
|
||||||
TagName = tagName;
|
TagName = tagName;
|
||||||
|
|
@ -96,39 +100,40 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
||||||
AssemblyName = assemblyName;
|
AssemblyName = assemblyName;
|
||||||
Attributes = new List<TagHelperAttributeDescriptor>(attributes);
|
Attributes = new List<TagHelperAttributeDescriptor>(attributes);
|
||||||
RequiredAttributes = new List<string>(requiredAttributes);
|
RequiredAttributes = new List<string>(requiredAttributes);
|
||||||
|
UsageDescriptor = usageDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Text used as a required prefix when matching HTML start and end tags in the Razor source to available
|
/// Text used as a required prefix when matching HTML start and end tags in the Razor source to available
|
||||||
/// tag helpers.
|
/// tag helpers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Prefix { get; private set; }
|
public string Prefix { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The tag name that the tag helper should target.
|
/// The tag name that the tag helper should target.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string TagName { get; private set; }
|
public string TagName { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The full tag name that is required for the tag helper to target an HTML element.
|
/// The full tag name that is required for the tag helper to target an HTML element.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>This is equivalent to <see cref="Prefix"/> and <see cref="TagName"/> concatenated.</remarks>
|
/// <remarks>This is equivalent to <see cref="Prefix"/> and <see cref="TagName"/> concatenated.</remarks>
|
||||||
public string FullTagName { get; private set; }
|
public string FullTagName { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The full name of the tag helper class.
|
/// The full name of the tag helper class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string TypeName { get; private set; }
|
public string TypeName { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The name of the assembly containing the tag helper class.
|
/// The name of the assembly containing the tag helper class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string AssemblyName { get; private set; }
|
public string AssemblyName { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The list of attributes the tag helper expects.
|
/// The list of attributes the tag helper expects.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IReadOnlyList<TagHelperAttributeDescriptor> Attributes { get; private set; }
|
public IReadOnlyList<TagHelperAttributeDescriptor> Attributes { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The list of required attribute names the tag helper expects to target an element.
|
/// The list of required attribute names the tag helper expects to target an element.
|
||||||
|
|
@ -136,6 +141,12 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// <c>*</c> at the end of an attribute name acts as a prefix match.
|
/// <c>*</c> at the end of an attribute name acts as a prefix match.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public IReadOnlyList<string> RequiredAttributes { get; private set; }
|
public IReadOnlyList<string> RequiredAttributes { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="TagHelperUsageDescriptor"/> that contains information about how to use the tag helper at
|
||||||
|
/// design time.
|
||||||
|
/// </summary>
|
||||||
|
public TagHelperUsageDescriptor UsageDescriptor { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -31,7 +31,9 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Determines equality based on <see cref="TagHelperDescriptor.TypeName"/>,
|
/// Determines equality based on <see cref="TagHelperDescriptor.TypeName"/>,
|
||||||
/// <see cref="TagHelperDescriptor.AssemblyName"/>, <see cref="TagHelperDescriptor.TagName"/>,
|
/// <see cref="TagHelperDescriptor.AssemblyName"/>, <see cref="TagHelperDescriptor.TagName"/>,
|
||||||
/// and <see cref="TagHelperDescriptor.RequiredAttributes"/>.
|
/// and <see cref="TagHelperDescriptor.RequiredAttributes"/>. Ignores
|
||||||
|
/// <see cref="TagHelperDescriptor.UsageDescriptor"/> because it can be inferred directly from
|
||||||
|
/// <see cref="TagHelperDescriptor.TypeName"/> and <see cref="TagHelperDescriptor.AssemblyName"/>.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public virtual bool Equals(TagHelperDescriptor descriptorX, TagHelperDescriptor descriptorY)
|
public virtual bool Equals(TagHelperDescriptor descriptorX, TagHelperDescriptor descriptorY)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
// 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.AspNet.Razor.TagHelpers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A metadata class containing information about tag helper use.
|
||||||
|
/// </summary>
|
||||||
|
public class TagHelperUsageDescriptor
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Instantiates a new instance of <see cref="TagHelperUsageDescriptor"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="summary">A summary on how to use a tag helper.</param>
|
||||||
|
/// <param name="remarks">Remarks on how to use a tag helper.</param>
|
||||||
|
public TagHelperUsageDescriptor(string summary, string remarks)
|
||||||
|
{
|
||||||
|
Summary = summary;
|
||||||
|
Remarks = remarks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A summary of how to use a tag helper.
|
||||||
|
/// </summary>
|
||||||
|
public string Summary { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Remarks about how to use a tag helper.
|
||||||
|
/// </summary>
|
||||||
|
public string Remarks { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue