Removing ITypeInfo and related types
This commit is contained in:
parent
c05551e167
commit
b4d631e2f6
|
|
@ -1,30 +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;
|
||||
|
||||
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Metadata common to types and properties.
|
||||
/// </summary>
|
||||
public interface IMemberInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a collection of custom <see cref="Attribute"/>s of type <typeparamref name="TAttribute"/> applied
|
||||
/// to this instance of <see cref="IMemberInfo"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TAttribute">The type of <see cref="Attribute"/> to search for.</typeparam>
|
||||
/// <returns>A sequence of custom <see cref="Attribute"/>s of type
|
||||
/// <typeparamref name="TAttribute"/>.</returns>
|
||||
/// <remarks>Result not include inherited <see cref="Attribute"/>s.</remarks>
|
||||
IEnumerable<TAttribute> GetCustomAttributes<TAttribute>()
|
||||
where TAttribute : Attribute;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +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.
|
||||
|
||||
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains property metadata.
|
||||
/// </summary>
|
||||
public interface IPropertyInfo : IMemberInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this property has a public getter.
|
||||
/// </summary>
|
||||
bool HasPublicGetter { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this property has a public setter.
|
||||
/// </summary>
|
||||
bool HasPublicSetter { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ITypeInfo"/> of the property.
|
||||
/// </summary>
|
||||
ITypeInfo PropertyType { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,74 +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;
|
||||
|
||||
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains type metadata.
|
||||
/// </summary>
|
||||
public interface ITypeInfo : IMemberInfo, IEquatable<ITypeInfo>
|
||||
{
|
||||
/// <summary>
|
||||
/// Fully qualified name of the type.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// On CoreCLR, some BCL types get type forwarded to the full desktop framework implementations at
|
||||
/// runtime. For e.g. we compile against System.String in System.Runtime which is type forwarded to
|
||||
/// mscorlib at runtime. Consequently for generic types where the <see cref="FullName"/> includes the assembly
|
||||
/// qualified name of generic parameters, FullNames would not match.
|
||||
/// Use <see cref="IEquatable{ITypeInfo}.Equals(ITypeInfo)"/> to compare <see cref="ITypeInfo"/>s instead.
|
||||
/// </remarks>
|
||||
string FullName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets <see cref="IPropertyInfo"/>s for all properties of the current type excluding indexers.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Indexers in this context refer to the CLR notion of an indexer (<c>this [string name]</c>
|
||||
/// and does not overlap with the semantics of
|
||||
/// <see cref="Razor.Compilation.TagHelpers.TagHelperAttributeDescriptor.IsIndexer"/>.
|
||||
/// </remarks>
|
||||
IEnumerable<IPropertyInfo> Properties { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the type is an <see cref="Enum"/>.
|
||||
/// </summary>
|
||||
bool IsEnum { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the type is public.
|
||||
/// </summary>
|
||||
bool IsPublic { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the type is abstract or an interface.
|
||||
/// </summary>
|
||||
bool IsAbstract { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the type is generic.
|
||||
/// </summary>
|
||||
bool IsGenericType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the type implements the <param name="interfaceTypeInfo"/> interface.
|
||||
/// </summary>
|
||||
bool ImplementsInterface(ITypeInfo interfaceTypeInfo);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ITypeInfo[]"/> for the <c>TKey</c> and <c>TValue</c> parameters of
|
||||
/// <see cref="IDictionary{TKey, TValue}"/>.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The <see cref="ITypeInfo"/> of <c>TKey</c> and <c>TValue</c>
|
||||
/// parameters if the type implements <see cref="IDictionary{TKey, TValue}"/>, otherwise <c>null</c>.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// For open generic types, <see cref="ITypeInfo" /> for generic type parameters is <c>null</c>.
|
||||
/// </remarks>
|
||||
ITypeInfo[] GetGenericDictionaryParameters();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,54 +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 System.Reflection;
|
||||
|
||||
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="IPropertyInfo"/> adapter for <see cref="PropertyInfo"/> instances.
|
||||
/// </summary>
|
||||
public class RuntimePropertyInfo : IPropertyInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="RuntimePropertyInfo"/>.
|
||||
/// </summary>
|
||||
/// <param name="propertyInfo">The <see cref="PropertyInfo"/> instance to adapt.</param>
|
||||
public RuntimePropertyInfo(PropertyInfo propertyInfo)
|
||||
{
|
||||
if (propertyInfo == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(propertyInfo));
|
||||
}
|
||||
|
||||
Property = propertyInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="PropertyInfo"/> instance.
|
||||
/// </summary>
|
||||
public PropertyInfo Property { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool HasPublicGetter => Property.GetMethod != null && Property.GetMethod.IsPublic;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool HasPublicSetter => Property.SetMethod != null && Property.SetMethod.IsPublic;
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => Property.Name;
|
||||
|
||||
/// <inheritdoc />
|
||||
public ITypeInfo PropertyType => new RuntimeTypeInfo(Property.PropertyType.GetTypeInfo());
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<TAttribute> GetCustomAttributes<TAttribute>() where TAttribute : Attribute
|
||||
=> Property.GetCustomAttributes<TAttribute>(inherit: false);
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString() =>
|
||||
Property.ToString();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,182 +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 System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.AspNet.Razor.TagHelpers;
|
||||
using Microsoft.Extensions.Internal;
|
||||
|
||||
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="ITypeInfo"/> adapter for <see cref="System.Reflection.TypeInfo"/> instances.
|
||||
/// </summary>
|
||||
public class RuntimeTypeInfo : ITypeInfo
|
||||
{
|
||||
private static readonly Regex _fullNameSanitizer = new Regex(
|
||||
@", [A-Za-z\.]+, Version=\d+\.\d+\.\d+\.\d+, Culture=neutral, PublicKeyToken=\w+",
|
||||
RegexOptions.ExplicitCapture,
|
||||
Constants.RegexMatchTimeout);
|
||||
|
||||
private static readonly TypeInfo TagHelperTypeInfo = typeof(ITagHelper).GetTypeInfo();
|
||||
private IEnumerable<IPropertyInfo> _properties;
|
||||
private string _sanitizedFullName;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="RuntimeTypeInfo"/>
|
||||
/// </summary>
|
||||
/// <param name="propertyInfo">The <see cref="System.Reflection.TypeInfo"/> instance to adapt.</param>
|
||||
public RuntimeTypeInfo(TypeInfo typeInfo)
|
||||
{
|
||||
if (typeInfo == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(typeInfo));
|
||||
}
|
||||
|
||||
TypeInfo = typeInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="System.Reflection.TypeInfo"/> instance.
|
||||
/// </summary>
|
||||
public TypeInfo TypeInfo { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => TypeInfo.Name;
|
||||
|
||||
/// <inheritdoc />
|
||||
public string FullName => TypeInfo.FullName;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsEnum => TypeInfo.IsEnum;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsAbstract => TypeInfo.IsAbstract;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsGenericType => TypeInfo.IsGenericType;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsPublic => TypeInfo.IsPublic;
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IPropertyInfo> Properties
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_properties == null)
|
||||
{
|
||||
_properties = TypeInfo
|
||||
.AsType()
|
||||
.GetRuntimeProperties()
|
||||
.Where(property => property.GetIndexParameters().Length == 0)
|
||||
.Select(property => new RuntimePropertyInfo(property));
|
||||
}
|
||||
|
||||
return _properties;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool ImplementsInterface(ITypeInfo interfaceTypeInfo)
|
||||
{
|
||||
if (interfaceTypeInfo == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(interfaceTypeInfo));
|
||||
}
|
||||
|
||||
var runtimeTypeInfo = interfaceTypeInfo as RuntimeTypeInfo;
|
||||
if (runtimeTypeInfo == null)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
Resources.FormatArgumentMustBeAnInstanceOf(typeof(RuntimeTypeInfo).FullName),
|
||||
nameof(interfaceTypeInfo));
|
||||
}
|
||||
|
||||
return runtimeTypeInfo.TypeInfo.IsInterface && runtimeTypeInfo.TypeInfo.IsAssignableFrom(TypeInfo);
|
||||
}
|
||||
|
||||
private string SanitizedFullName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_sanitizedFullName == null)
|
||||
{
|
||||
_sanitizedFullName = SanitizeFullName(FullName);
|
||||
}
|
||||
|
||||
return _sanitizedFullName;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<TAttribute> GetCustomAttributes<TAttribute>() where TAttribute : Attribute =>
|
||||
TypeInfo.GetCustomAttributes<TAttribute>(inherit: false);
|
||||
|
||||
/// <inheritdoc />
|
||||
public ITypeInfo[] GetGenericDictionaryParameters()
|
||||
{
|
||||
return ClosedGenericMatcher.ExtractGenericInterface(
|
||||
TypeInfo.AsType(),
|
||||
typeof(IDictionary<,>))
|
||||
?.GenericTypeArguments
|
||||
.Select(type => type.IsGenericParameter ? null : new RuntimeTypeInfo(type.GetTypeInfo()))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString() => TypeInfo.ToString();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return Equals(obj as ITypeInfo);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(ITypeInfo other)
|
||||
{
|
||||
if (other == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var otherRuntimeType = other as RuntimeTypeInfo;
|
||||
if (otherRuntimeType != null)
|
||||
{
|
||||
return otherRuntimeType.TypeInfo == TypeInfo;
|
||||
}
|
||||
|
||||
return string.Equals(
|
||||
SanitizedFullName,
|
||||
SanitizeFullName(other.FullName),
|
||||
StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode() => SanitizedFullName.GetHashCode();
|
||||
|
||||
/// <summary>
|
||||
/// Removes assembly qualification from generic type parameters for the specified <paramref name="fullName"/>.
|
||||
/// </summary>
|
||||
/// <param name="fullName">Full name.</param>
|
||||
/// <returns>Full name without fully qualified generic parameters.</returns>
|
||||
/// <example>
|
||||
/// <c>typeof(<see cref="List{string}"/>).FullName</c> is
|
||||
/// List`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]
|
||||
/// <c>Sanitize(typeof(<see cref="List{string}"/>.FullName</c> returns
|
||||
/// List`1[[System.String]
|
||||
/// </example>
|
||||
public static string SanitizeFullName(string fullName)
|
||||
{
|
||||
// In CoreCLR, some types (such as System.String) are type forwarded from System.Runtime
|
||||
// to mscorlib at runtime. Type names of generic type parameters includes the assembly qualified name;
|
||||
// consequently the type name generated at precompilation differs from the one at runtime. We'll
|
||||
// avoid dealing with these inconsistencies by removing assembly information from TypeInfo.FullName.
|
||||
return _fullNameSanitizer.Replace(fullName, string.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,11 +9,12 @@ using System.Reflection;
|
|||
using System.Text.RegularExpressions;
|
||||
using Microsoft.AspNet.Razor.Compilation.TagHelpers;
|
||||
using Microsoft.AspNet.Razor.TagHelpers;
|
||||
using Microsoft.Extensions.Internal;
|
||||
|
||||
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Factory for <see cref="TagHelperDescriptor"/>s from <see cref="ITypeInfo"/>s.
|
||||
/// Factory for <see cref="TagHelperDescriptor"/>s from <see cref="Type"/>s.
|
||||
/// </summary>
|
||||
public class TagHelperDescriptorFactory
|
||||
{
|
||||
|
|
@ -31,8 +32,6 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
RegexOptions.None,
|
||||
Constants.RegexMatchTimeout);
|
||||
|
||||
private static readonly ITypeInfo StringTypeInfo = new RuntimeTypeInfo(typeof(string).GetTypeInfo());
|
||||
|
||||
#if !DOTNET5_4
|
||||
private readonly TagHelperDesignTimeDescriptorFactory _designTimeDescriptorFactory;
|
||||
#endif
|
||||
|
|
@ -63,24 +62,24 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="TagHelperDescriptor"/> from the given <paramref name="typeInfo"/>.
|
||||
/// Creates a <see cref="TagHelperDescriptor"/> from the given <paramref name="type"/>.
|
||||
/// </summary>
|
||||
/// <param name="assemblyName">The assembly name that contains <paramref name="type"/>.</param>
|
||||
/// <param name="typeInfo">The <see cref="ITypeInfo"/> to create a <see cref="TagHelperDescriptor"/> from.
|
||||
/// <param name="type">The <see cref="Type"/> to create a <see cref="TagHelperDescriptor"/> from.
|
||||
/// </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="typeInfo"/>.</param>
|
||||
/// when creating <see cref="TagHelperDescriptor"/>s for the given <paramref name="type"/>.</param>
|
||||
/// <returns>
|
||||
/// A collection of <see cref="TagHelperDescriptor"/>s that describe the given <paramref name="typeInfo"/>.
|
||||
/// A collection of <see cref="TagHelperDescriptor"/>s that describe the given <paramref name="type"/>.
|
||||
/// </returns>
|
||||
public virtual IEnumerable<TagHelperDescriptor> CreateDescriptors(
|
||||
string assemblyName,
|
||||
ITypeInfo typeInfo,
|
||||
Type type,
|
||||
ErrorSink errorSink)
|
||||
{
|
||||
if (typeInfo == null)
|
||||
if (type == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(typeInfo));
|
||||
throw new ArgumentNullException(nameof(type));
|
||||
}
|
||||
|
||||
if (errorSink == null)
|
||||
|
|
@ -88,18 +87,18 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
throw new ArgumentNullException(nameof(errorSink));
|
||||
}
|
||||
|
||||
if (ShouldSkipDescriptorCreation(typeInfo))
|
||||
if (ShouldSkipDescriptorCreation(type.GetTypeInfo()))
|
||||
{
|
||||
return Enumerable.Empty<TagHelperDescriptor>();
|
||||
}
|
||||
|
||||
var attributeDescriptors = GetAttributeDescriptors(typeInfo, errorSink);
|
||||
var targetElementAttributes = GetValidHtmlTargetElementAttributes(typeInfo, errorSink);
|
||||
var allowedChildren = GetAllowedChildren(typeInfo, errorSink);
|
||||
var attributeDescriptors = GetAttributeDescriptors(type, errorSink);
|
||||
var targetElementAttributes = GetValidHtmlTargetElementAttributes(type, errorSink);
|
||||
var allowedChildren = GetAllowedChildren(type, errorSink);
|
||||
|
||||
var tagHelperDescriptors =
|
||||
BuildTagHelperDescriptors(
|
||||
typeInfo,
|
||||
type,
|
||||
assemblyName,
|
||||
attributeDescriptors,
|
||||
targetElementAttributes,
|
||||
|
|
@ -109,17 +108,18 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
}
|
||||
|
||||
private static IEnumerable<HtmlTargetElementAttribute> GetValidHtmlTargetElementAttributes(
|
||||
ITypeInfo typeInfo,
|
||||
Type type,
|
||||
ErrorSink errorSink)
|
||||
{
|
||||
var targetElementAttributes = typeInfo.GetCustomAttributes<HtmlTargetElementAttribute>();
|
||||
|
||||
var targetElementAttributes = type
|
||||
.GetTypeInfo()
|
||||
.GetCustomAttributes<HtmlTargetElementAttribute>(inherit: false);
|
||||
return targetElementAttributes.Where(
|
||||
attribute => ValidHtmlTargetElementAttributeNames(attribute, errorSink));
|
||||
}
|
||||
|
||||
private IEnumerable<TagHelperDescriptor> BuildTagHelperDescriptors(
|
||||
ITypeInfo typeInfo,
|
||||
Type type,
|
||||
string assemblyName,
|
||||
IEnumerable<TagHelperAttributeDescriptor> attributeDescriptors,
|
||||
IEnumerable<HtmlTargetElementAttribute> targetElementAttributes,
|
||||
|
|
@ -130,21 +130,16 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
#if !DOTNET5_4
|
||||
if (_designTime)
|
||||
{
|
||||
var runtimeTypeInfo = typeInfo as RuntimeTypeInfo;
|
||||
if (runtimeTypeInfo != null)
|
||||
{
|
||||
typeDesignTimeDescriptor =
|
||||
_designTimeDescriptorFactory.CreateDescriptor(runtimeTypeInfo.TypeInfo.AsType());
|
||||
}
|
||||
typeDesignTimeDescriptor = _designTimeDescriptorFactory.CreateDescriptor(type);
|
||||
}
|
||||
#endif
|
||||
|
||||
var typeName = typeInfo.FullName;
|
||||
var typeName = type.FullName;
|
||||
|
||||
// If there isn't an attribute specifying the tag name derive it from the name
|
||||
if (!targetElementAttributes.Any())
|
||||
{
|
||||
var name = typeInfo.Name;
|
||||
var name = type.Name;
|
||||
|
||||
if (name.EndsWith(TagHelperNameEnding, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
|
|
@ -177,18 +172,16 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
typeDesignTimeDescriptor));
|
||||
}
|
||||
|
||||
private static IEnumerable<string> GetAllowedChildren(ITypeInfo typeInfo, ErrorSink errorSink)
|
||||
private static IEnumerable<string> GetAllowedChildren(Type type, ErrorSink errorSink)
|
||||
{
|
||||
var restrictChildrenAttribute = typeInfo
|
||||
.GetCustomAttributes<RestrictChildrenAttribute>()
|
||||
.FirstOrDefault();
|
||||
var restrictChildrenAttribute = type.GetTypeInfo().GetCustomAttribute<RestrictChildrenAttribute>(inherit: false);
|
||||
if (restrictChildrenAttribute == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var allowedChildren = restrictChildrenAttribute.ChildTags;
|
||||
var validAllowedChildren = GetValidAllowedChildren(allowedChildren, typeInfo.FullName, errorSink);
|
||||
var validAllowedChildren = GetValidAllowedChildren(allowedChildren, type.FullName, errorSink);
|
||||
|
||||
if (validAllowedChildren.Any())
|
||||
{
|
||||
|
|
@ -405,14 +398,14 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
return validName;
|
||||
}
|
||||
|
||||
private IEnumerable<TagHelperAttributeDescriptor> GetAttributeDescriptors(ITypeInfo type, ErrorSink errorSink)
|
||||
private IEnumerable<TagHelperAttributeDescriptor> GetAttributeDescriptors(Type type, ErrorSink errorSink)
|
||||
{
|
||||
var attributeDescriptors = new List<TagHelperAttributeDescriptor>();
|
||||
|
||||
// Keep indexer descriptors separate to avoid sorting the combined list later.
|
||||
var indexerDescriptors = new List<TagHelperAttributeDescriptor>();
|
||||
|
||||
var accessibleProperties = type.Properties.Where(IsAccessibleProperty);
|
||||
var accessibleProperties = type.GetRuntimeProperties().Where(IsAccessibleProperty);
|
||||
foreach (var property in accessibleProperties)
|
||||
{
|
||||
if (ShouldSkipDescriptorCreation(property))
|
||||
|
|
@ -421,14 +414,14 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
}
|
||||
|
||||
var attributeNameAttribute = property
|
||||
.GetCustomAttributes<HtmlAttributeNameAttribute>()
|
||||
.GetCustomAttributes<HtmlAttributeNameAttribute>(inherit: false)
|
||||
.FirstOrDefault();
|
||||
var hasExplicitName =
|
||||
attributeNameAttribute != null && !string.IsNullOrEmpty(attributeNameAttribute.Name);
|
||||
var attributeName = hasExplicitName ? attributeNameAttribute.Name : ToHtmlCase(property.Name);
|
||||
|
||||
TagHelperAttributeDescriptor mainDescriptor = null;
|
||||
if (property.HasPublicSetter)
|
||||
if (property.SetMethod != null && property.SetMethod.IsPublic)
|
||||
{
|
||||
mainDescriptor = ToAttributeDescriptor(property, attributeName);
|
||||
if (!ValidateTagHelperAttributeDescriptor(mainDescriptor, type, errorSink))
|
||||
|
|
@ -491,7 +484,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
// Internal for testing.
|
||||
internal static bool ValidateTagHelperAttributeDescriptor(
|
||||
TagHelperAttributeDescriptor attributeDescriptor,
|
||||
ITypeInfo parentType,
|
||||
Type parentType,
|
||||
ErrorSink errorSink)
|
||||
{
|
||||
string nameOrPrefix;
|
||||
|
|
@ -523,13 +516,11 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
nameOrPrefix);
|
||||
}
|
||||
|
||||
private bool ShouldSkipDescriptorCreation(IMemberInfo memberInfo)
|
||||
private bool ShouldSkipDescriptorCreation(MemberInfo memberInfo)
|
||||
{
|
||||
if (_designTime)
|
||||
{
|
||||
var editorBrowsableAttribute = memberInfo
|
||||
.GetCustomAttributes<EditorBrowsableAttribute>()
|
||||
.FirstOrDefault();
|
||||
var editorBrowsableAttribute = memberInfo.GetCustomAttribute<EditorBrowsableAttribute>(inherit: false);
|
||||
|
||||
return editorBrowsableAttribute != null &&
|
||||
editorBrowsableAttribute.State == EditorBrowsableState.Never;
|
||||
|
|
@ -540,7 +531,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
|
||||
private static bool ValidateTagHelperAttributeNameOrPrefix(
|
||||
string attributeNameOrPrefix,
|
||||
ITypeInfo parentType,
|
||||
Type parentType,
|
||||
string propertyName,
|
||||
ErrorSink errorSink,
|
||||
string nameOrPrefix)
|
||||
|
|
@ -608,28 +599,33 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
return isValid;
|
||||
}
|
||||
|
||||
private TagHelperAttributeDescriptor ToAttributeDescriptor(IPropertyInfo property, string attributeName)
|
||||
private TagHelperAttributeDescriptor ToAttributeDescriptor(PropertyInfo property, string attributeName)
|
||||
{
|
||||
return ToAttributeDescriptor(
|
||||
property,
|
||||
attributeName,
|
||||
property.PropertyType.FullName,
|
||||
isIndexer: false,
|
||||
isStringProperty: StringTypeInfo.Equals(property.PropertyType));
|
||||
isStringProperty: typeof(string) == property.PropertyType);
|
||||
}
|
||||
|
||||
private TagHelperAttributeDescriptor ToIndexerAttributeDescriptor(
|
||||
IPropertyInfo property,
|
||||
PropertyInfo property,
|
||||
HtmlAttributeNameAttribute attributeNameAttribute,
|
||||
ITypeInfo parentType,
|
||||
Type parentType,
|
||||
ErrorSink errorSink,
|
||||
string defaultPrefix,
|
||||
out bool isInvalid)
|
||||
{
|
||||
isInvalid = false;
|
||||
var hasPublicSetter = property.HasPublicSetter;
|
||||
var dictionaryTypeArguments = property.PropertyType.GetGenericDictionaryParameters();
|
||||
if (!StringTypeInfo.Equals(dictionaryTypeArguments?[0]))
|
||||
var hasPublicSetter = property.SetMethod != null && property.SetMethod.IsPublic;
|
||||
var dictionaryTypeArguments = ClosedGenericMatcher.ExtractGenericInterface(
|
||||
property.PropertyType,
|
||||
typeof(IDictionary<,>))
|
||||
?.GenericTypeArguments
|
||||
.Select(type => type.IsGenericParameter ? null : type)
|
||||
.ToArray();
|
||||
if (dictionaryTypeArguments?[0] != typeof(string))
|
||||
{
|
||||
if (attributeNameAttribute?.DictionaryAttributePrefix != null)
|
||||
{
|
||||
|
|
@ -698,11 +694,11 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
attributeName: prefix,
|
||||
typeName: dictionaryTypeArguments[1].FullName,
|
||||
isIndexer: true,
|
||||
isStringProperty: StringTypeInfo.Equals(dictionaryTypeArguments[1]));
|
||||
isStringProperty: typeof(string) == dictionaryTypeArguments[1]);
|
||||
}
|
||||
|
||||
private TagHelperAttributeDescriptor ToAttributeDescriptor(
|
||||
IPropertyInfo property,
|
||||
PropertyInfo property,
|
||||
string attributeName,
|
||||
string typeName,
|
||||
bool isIndexer,
|
||||
|
|
@ -713,12 +709,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
#if !DOTNET5_4
|
||||
if (_designTime)
|
||||
{
|
||||
var runtimeProperty = property as RuntimePropertyInfo;
|
||||
if (runtimeProperty != null)
|
||||
{
|
||||
propertyDesignTimeDescriptor =
|
||||
_designTimeDescriptorFactory.CreateAttributeDescriptor(runtimeProperty.Property);
|
||||
}
|
||||
propertyDesignTimeDescriptor = _designTimeDescriptorFactory.CreateAttributeDescriptor(property);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -726,7 +717,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
{
|
||||
Name = attributeName,
|
||||
PropertyName = property.Name,
|
||||
IsEnum = property.PropertyType.IsEnum,
|
||||
IsEnum = property.PropertyType.GetTypeInfo().IsEnum,
|
||||
TypeName = typeName,
|
||||
IsStringProperty = isStringProperty,
|
||||
IsIndexer = isIndexer,
|
||||
|
|
@ -734,11 +725,13 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
};
|
||||
}
|
||||
|
||||
private static bool IsAccessibleProperty(IPropertyInfo property)
|
||||
private static bool IsAccessibleProperty(PropertyInfo property)
|
||||
{
|
||||
// Accessible properties are those with public getters and without [HtmlAttributeNotBound].
|
||||
return property.HasPublicGetter &&
|
||||
property.GetCustomAttributes<HtmlAttributeNotBoundAttribute>().FirstOrDefault() == null;
|
||||
return property.GetIndexParameters().Length == 0 &&
|
||||
property.GetMethod != null &&
|
||||
property.GetMethod.IsPublic &&
|
||||
property.GetCustomAttribute<HtmlAttributeNotBoundAttribute>(inherit: false) == null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
/// </summary>
|
||||
public class TagHelperTypeResolver
|
||||
{
|
||||
private static readonly ITypeInfo ITagHelperTypeInfo = new RuntimeTypeInfo(typeof(ITagHelper).GetTypeInfo());
|
||||
private static readonly TypeInfo ITagHelperTypeInfo = typeof(ITagHelper).GetTypeInfo();
|
||||
|
||||
/// <summary>
|
||||
/// Locates valid <see cref="ITagHelper"/> types from the <see cref="Assembly"/> named <paramref name="name"/>.
|
||||
|
|
@ -25,8 +25,8 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
/// </param>
|
||||
/// <param name="errorSink">The <see cref="ErrorSink"/> used to record errors found when resolving
|
||||
/// <see cref="ITagHelper"/> types.</param>
|
||||
/// <returns>An <see cref="IEnumerable{ITypeInfo}"/> of valid <see cref="ITagHelper"/> types.</returns>
|
||||
public IEnumerable<ITypeInfo> Resolve(
|
||||
/// <returns>An <see cref="IEnumerable{Type}"/> of valid <see cref="ITagHelper"/> types.</returns>
|
||||
public IEnumerable<Type> Resolve(
|
||||
string name,
|
||||
SourceLocation documentLocation,
|
||||
ErrorSink errorSink)
|
||||
|
|
@ -44,15 +44,15 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
Resources.TagHelperTypeResolver_TagHelperAssemblyNameCannotBeEmptyOrNull,
|
||||
errorLength);
|
||||
|
||||
return Enumerable.Empty<ITypeInfo>();
|
||||
return Type.EmptyTypes;
|
||||
}
|
||||
|
||||
var assemblyName = new AssemblyName(name);
|
||||
|
||||
IEnumerable<ITypeInfo> libraryTypes;
|
||||
IEnumerable<TypeInfo> libraryTypes;
|
||||
try
|
||||
{
|
||||
libraryTypes = GetTopLevelExportedTypes(assemblyName);
|
||||
libraryTypes = GetExportedTypes(assemblyName);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -63,31 +63,10 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
ex.Message),
|
||||
name.Length);
|
||||
|
||||
return Enumerable.Empty<ITypeInfo>();
|
||||
return Type.EmptyTypes;
|
||||
}
|
||||
|
||||
return libraryTypes.Where(IsTagHelper);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all non-nested exported types from the given <paramref name="assemblyName"/>
|
||||
/// </summary>
|
||||
/// <param name="assemblyName">The <see cref="AssemblyName"/> to get <see cref="ITypeInfo"/>s from.</param>
|
||||
/// <returns>
|
||||
/// An <see cref="IEnumerable{ITypeInfo}"/> of types exported from the given <paramref name="assemblyName"/>.
|
||||
/// </returns>
|
||||
protected virtual IEnumerable<ITypeInfo> GetTopLevelExportedTypes(AssemblyName assemblyName)
|
||||
{
|
||||
if (assemblyName == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(assemblyName));
|
||||
}
|
||||
|
||||
var exportedTypeInfos = GetExportedTypes(assemblyName);
|
||||
|
||||
return exportedTypeInfos
|
||||
.Where(typeInfo => !typeInfo.IsNested)
|
||||
.Select(typeInfo => new RuntimeTypeInfo(typeInfo));
|
||||
return libraryTypes.Where(IsTagHelper).Select(t => t.AsType());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -105,12 +84,14 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
}
|
||||
|
||||
// Internal for testing.
|
||||
internal virtual bool IsTagHelper(ITypeInfo typeInfo)
|
||||
internal virtual bool IsTagHelper(TypeInfo typeInfo)
|
||||
{
|
||||
return typeInfo.IsPublic &&
|
||||
!typeInfo.IsAbstract &&
|
||||
!typeInfo.IsGenericType &&
|
||||
typeInfo.ImplementsInterface(ITagHelperTypeInfo);
|
||||
return
|
||||
!typeInfo.IsNested &&
|
||||
typeInfo.IsPublic &&
|
||||
!typeInfo.IsAbstract &&
|
||||
!typeInfo.IsGenericType &&
|
||||
ITagHelperTypeInfo.IsAssignableFrom(typeInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,160 +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.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNet.Razor.TagHelpers;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||
{
|
||||
public class RuntimePropertyInfoTest
|
||||
{
|
||||
[Fact]
|
||||
public void PropertyInfo_ReturnsMetadataOfAdaptingProperty()
|
||||
{
|
||||
// Arrange
|
||||
var property = GetPropertyInfo(nameof(TestType.Property));
|
||||
var runtimePropertyInfo = new RuntimePropertyInfo(property);
|
||||
|
||||
// Act
|
||||
var actual = runtimePropertyInfo.Property;
|
||||
|
||||
// Assert
|
||||
Assert.Same(property, actual);
|
||||
var runtimeTypeInfo = Assert.IsType<RuntimeTypeInfo>(runtimePropertyInfo.PropertyType);
|
||||
Assert.Same(property.PropertyType, runtimeTypeInfo.TypeInfo);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(nameof(TestType.Property))]
|
||||
[InlineData(nameof(TestType.PrivateSetter))]
|
||||
[InlineData(nameof(TestType.PropertyWithoutSetter))]
|
||||
public void HasPublicGetter_ReturnsTrueIfGetterExistsAndIsPublic(string propertyName)
|
||||
{
|
||||
// Arrange
|
||||
var property = GetPropertyInfo(propertyName);
|
||||
var runtimePropertyInfo = new RuntimePropertyInfo(property);
|
||||
|
||||
// Act
|
||||
var result = runtimePropertyInfo.HasPublicGetter;
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(nameof(TestType.PrivateGetter))]
|
||||
[InlineData(nameof(TestType.PropertyWithoutGetter))]
|
||||
[InlineData("ProtectedProperty")]
|
||||
public void HasPublicGetter_ReturnsFalseIfGetterDoesNotExistOrIsNonPublic(string propertyName)
|
||||
{
|
||||
// Arrange
|
||||
var property = GetPropertyInfo(propertyName);
|
||||
var runtimePropertyInfo = new RuntimePropertyInfo(property);
|
||||
|
||||
// Act
|
||||
var result = runtimePropertyInfo.HasPublicGetter;
|
||||
|
||||
// Assert
|
||||
Assert.False(result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(nameof(TestType.Property))]
|
||||
[InlineData(nameof(TestType.PrivateGetter))]
|
||||
[InlineData(nameof(TestType.PropertyWithoutGetter))]
|
||||
public void HasPublicSetter_ReturnsTrueIfSetterExistsAndIsPublic(string propertyName)
|
||||
{
|
||||
// Arrange
|
||||
var property = GetPropertyInfo(propertyName);
|
||||
var runtimePropertyInfo = new RuntimePropertyInfo(property);
|
||||
|
||||
// Act
|
||||
var result = runtimePropertyInfo.HasPublicSetter;
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(nameof(TestType.PrivateSetter))]
|
||||
[InlineData(nameof(TestType.PropertyWithoutSetter))]
|
||||
[InlineData("ProtectedProperty")]
|
||||
public void HasPublicSetter_ReturnsFalseIfGetterDoesNotExistOrIsNonPublic(string propertyName)
|
||||
{
|
||||
// Arrange
|
||||
var property = GetPropertyInfo(propertyName);
|
||||
var runtimePropertyInfo = new RuntimePropertyInfo(property);
|
||||
|
||||
// Act
|
||||
var result = runtimePropertyInfo.HasPublicSetter;
|
||||
|
||||
// Assert
|
||||
Assert.False(result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetAttributes_ReturnsCustomAttributesOfSpecifiedType()
|
||||
{
|
||||
// Arrange
|
||||
var property = GetPropertyInfo(nameof(TestType.PropertyWithAttributes));
|
||||
var runtimeProperty = new RuntimePropertyInfo(property);
|
||||
|
||||
// Act
|
||||
var attributes = property.GetCustomAttributes<HtmlAttributeNameAttribute>();
|
||||
|
||||
// Assert
|
||||
var htmlAttributeName = Assert.Single(attributes);
|
||||
Assert.Equal("somename", htmlAttributeName.Name);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetAttributes_DoesNotInheritAttributes()
|
||||
{
|
||||
// Arrange
|
||||
var property = GetPropertyInfo(nameof(TestType.PropertyWithAttributes));
|
||||
var runtimeProperty = new RuntimePropertyInfo(property);
|
||||
|
||||
// Act
|
||||
var attributes = property.GetCustomAttributes<HtmlAttributeNotBoundAttribute>();
|
||||
|
||||
// Assert
|
||||
Assert.Empty(attributes);
|
||||
}
|
||||
|
||||
private static PropertyInfo GetPropertyInfo(string propertyName)
|
||||
{
|
||||
return typeof(TestType).GetRuntimeProperties()
|
||||
.FirstOrDefault(p => p.Name == propertyName);
|
||||
}
|
||||
|
||||
public class BaseType
|
||||
{
|
||||
[HtmlAttributeNotBound]
|
||||
public virtual string PropertyWithAttributes { get; }
|
||||
}
|
||||
|
||||
public class TestType : BaseType
|
||||
{
|
||||
public string Property { get; set; }
|
||||
|
||||
public int PrivateSetter { get; private set; }
|
||||
|
||||
public object PrivateGetter { private get; set; }
|
||||
|
||||
protected DateTimeOffset ProtectedProperty { get; set; }
|
||||
|
||||
public string PropertyWithoutGetter
|
||||
{
|
||||
set { }
|
||||
}
|
||||
|
||||
public int PropertyWithoutSetter => 0;
|
||||
|
||||
[HtmlAttributeName("somename")]
|
||||
public override string PropertyWithAttributes { get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,159 +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 System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNet.Razor.Compilation.TagHelpers;
|
||||
using Microsoft.AspNet.Razor.TagHelpers;
|
||||
using Microsoft.AspNet.Razor.Test.Internal;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||
{
|
||||
public class RuntimeTagHelperDescriptorFactoryTest : TagHelperDescriptorFactoryTest
|
||||
{
|
||||
public override ITypeInfo GetTypeInfo(Type tagHelperType) =>
|
||||
new RuntimeTypeInfo(tagHelperType.GetTypeInfo());
|
||||
|
||||
[Fact]
|
||||
public void CreateDescriptors_BuildsDescriptorsFromSimpleTypes()
|
||||
{
|
||||
// Arrange
|
||||
var errorSink = new ErrorSink();
|
||||
var objectAssemblyName = typeof(object).GetTypeInfo().Assembly.GetName().Name;
|
||||
var expectedDescriptor =
|
||||
CreateTagHelperDescriptor("object", "System.Object", objectAssemblyName);
|
||||
var factory = new TagHelperDescriptorFactory(designTime: false);
|
||||
|
||||
// Act
|
||||
var descriptors = factory.CreateDescriptors(
|
||||
objectAssemblyName,
|
||||
GetTypeInfo(typeof(object)),
|
||||
errorSink: errorSink);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(errorSink.Errors);
|
||||
var descriptor = Assert.Single(descriptors);
|
||||
Assert.Equal(expectedDescriptor, descriptor, CaseSensitiveTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(TagHelperWithPrefixData))]
|
||||
public void CreateDescriptors_WithPrefixes_ReturnsExpectedAttributeDescriptors(
|
||||
Type tagHelperType,
|
||||
IEnumerable<TagHelperAttributeDescriptor> expectedAttributeDescriptors,
|
||||
string[] expectedErrorMessages)
|
||||
{
|
||||
// Arrange
|
||||
var errorSink = new ErrorSink();
|
||||
var factory = new TagHelperDescriptorFactory(designTime: false);
|
||||
|
||||
// Act
|
||||
var descriptors = factory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
GetTypeInfo(tagHelperType),
|
||||
errorSink: errorSink);
|
||||
|
||||
// Assert
|
||||
var errors = errorSink.Errors.ToArray();
|
||||
Assert.Equal(expectedErrorMessages.Length, errors.Length);
|
||||
|
||||
for (var i = 0; i < errors.Length; i++)
|
||||
{
|
||||
Assert.Equal(0, errors[i].Length);
|
||||
Assert.Equal(SourceLocation.Zero, errors[i].Location);
|
||||
Assert.Equal(expectedErrorMessages[i], errors[i].Message, StringComparer.Ordinal);
|
||||
}
|
||||
|
||||
var descriptor = Assert.Single(descriptors);
|
||||
Assert.Equal(
|
||||
expectedAttributeDescriptors,
|
||||
descriptor.Attributes,
|
||||
TagHelperAttributeDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
// TagHelperDesignTimeDescriptors are not created in CoreCLR.
|
||||
#if !DNXCORE50
|
||||
public static TheoryData OutputElementHintData
|
||||
{
|
||||
get
|
||||
{
|
||||
// tagHelperType, expectedDescriptors
|
||||
return new TheoryData<Type, TagHelperDescriptor[]>
|
||||
{
|
||||
{
|
||||
typeof(OutputElementHintTagHelper),
|
||||
new[]
|
||||
{
|
||||
new TagHelperDescriptor
|
||||
{
|
||||
TagName = "output-element-hint",
|
||||
TypeName = typeof(OutputElementHintTagHelper).FullName,
|
||||
AssemblyName = AssemblyName,
|
||||
DesignTimeDescriptor = new TagHelperDesignTimeDescriptor
|
||||
{
|
||||
OutputElementHint = "strong"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
typeof(MulitpleDescriptorTagHelperWithOutputElementHint),
|
||||
new[]
|
||||
{
|
||||
new TagHelperDescriptor
|
||||
{
|
||||
TagName = "a",
|
||||
TypeName = typeof(MulitpleDescriptorTagHelperWithOutputElementHint).FullName,
|
||||
AssemblyName = AssemblyName,
|
||||
DesignTimeDescriptor = new TagHelperDesignTimeDescriptor
|
||||
{
|
||||
OutputElementHint = "div"
|
||||
}
|
||||
},
|
||||
new TagHelperDescriptor
|
||||
{
|
||||
TagName = "p",
|
||||
TypeName = typeof(MulitpleDescriptorTagHelperWithOutputElementHint).FullName,
|
||||
AssemblyName = AssemblyName,
|
||||
DesignTimeDescriptor = new TagHelperDesignTimeDescriptor
|
||||
{
|
||||
OutputElementHint = "div"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(OutputElementHintData))]
|
||||
public void CreateDescriptors_CreatesDesignTimeDescriptorsWithOutputElementHint(
|
||||
Type tagHelperType,
|
||||
TagHelperDescriptor[] expectedDescriptors)
|
||||
{
|
||||
// Arrange
|
||||
var errorSink = new ErrorSink();
|
||||
var factory = new TagHelperDescriptorFactory(designTime: true);
|
||||
|
||||
// Act
|
||||
var descriptors = factory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
GetTypeInfo(tagHelperType),
|
||||
errorSink: errorSink);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(errorSink.Errors);
|
||||
|
||||
// We don't care about order. Mono returns reflected attributes differently so we need to ensure order
|
||||
// doesn't matter by sorting.
|
||||
descriptors = descriptors.OrderBy(descriptor => descriptor.TagName);
|
||||
|
||||
Assert.Equal(expectedDescriptors, descriptors, CaseSensitiveTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -1,535 +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;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Razor.TagHelpers;
|
||||
using Microsoft.AspNet.Testing;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||
{
|
||||
public class RuntimeTypeInfoTest
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(typeof(int))]
|
||||
[InlineData(typeof(string))]
|
||||
[InlineData(typeof(Tuple<>))]
|
||||
[InlineData(typeof(Tuple<>))]
|
||||
[InlineData(typeof(IDictionary<string, string>))]
|
||||
[InlineData(typeof(IDictionary<string, IDictionary<string, CustomType>>))]
|
||||
[InlineData(typeof(IList<IReadOnlyList<IDictionary<List<string>, Tuple<CustomType, object[]>>>>))]
|
||||
[InlineData(typeof(AbstractType))]
|
||||
[InlineData(typeof(PrivateType))]
|
||||
[InlineData(typeof(KnownKeyDictionary<>))]
|
||||
[InlineData(typeof(KnownKeyDictionary<string>))]
|
||||
public void RuntimeTypeInfo_ReturnsMetadataOfAdaptingType(Type type)
|
||||
{
|
||||
// Arrange
|
||||
var typeInfo = type.GetTypeInfo();
|
||||
var runtimeTypeInfo = new RuntimeTypeInfo(typeInfo);
|
||||
|
||||
// Act and Assert
|
||||
Assert.Same(typeInfo, runtimeTypeInfo.TypeInfo);
|
||||
Assert.Equal(typeInfo.Name, runtimeTypeInfo.Name);
|
||||
Assert.Equal(type.FullName, runtimeTypeInfo.FullName);
|
||||
Assert.Equal(typeInfo.IsAbstract, runtimeTypeInfo.IsAbstract);
|
||||
Assert.Equal(typeInfo.IsGenericType, runtimeTypeInfo.IsGenericType);
|
||||
Assert.Equal(typeInfo.IsPublic, runtimeTypeInfo.IsPublic);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Properties_ReturnsPublicPropertiesOfAdaptingType()
|
||||
{
|
||||
// Arrange
|
||||
var typeInfo = typeof(SubType).GetTypeInfo();
|
||||
var runtimeTypeInfo = new RuntimeTypeInfo(typeInfo);
|
||||
|
||||
// Act and Assert
|
||||
Assert.Collection(runtimeTypeInfo.Properties,
|
||||
property =>
|
||||
{
|
||||
Assert.IsType<RuntimePropertyInfo>(property);
|
||||
Assert.Equal("Property1", property.Name);
|
||||
},
|
||||
property =>
|
||||
{
|
||||
Assert.IsType<RuntimePropertyInfo>(property);
|
||||
Assert.Equal("Property2", property.Name);
|
||||
},
|
||||
property =>
|
||||
{
|
||||
Assert.IsType<RuntimePropertyInfo>(property);
|
||||
Assert.Equal("Property3", property.Name);
|
||||
},
|
||||
property =>
|
||||
{
|
||||
Assert.IsType<RuntimePropertyInfo>(property);
|
||||
Assert.Equal("Property4", property.Name);
|
||||
},
|
||||
property =>
|
||||
{
|
||||
Assert.IsType<RuntimePropertyInfo>(property);
|
||||
Assert.Equal("BaseTypeProperty", property.Name);
|
||||
},
|
||||
property =>
|
||||
{
|
||||
Assert.IsType<RuntimePropertyInfo>(property);
|
||||
Assert.Equal("ProtectedProperty", property.Name);
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetCustomAttributes_ReturnsAllAttributesOfType()
|
||||
{
|
||||
// Arrange
|
||||
var typeInfo = typeof(TypeWithAttributes).GetTypeInfo();
|
||||
var runtimeTypeInfo = new RuntimeTypeInfo(typeInfo);
|
||||
var expected = typeInfo.GetCustomAttributes<HtmlTargetElementAttribute>();
|
||||
|
||||
// Act
|
||||
var actual = runtimeTypeInfo.GetCustomAttributes<HtmlTargetElementAttribute>();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetCustomAttributes_DoesNotInheritAttributesFromBaseType()
|
||||
{
|
||||
// Arrange
|
||||
var typeInfo = typeof(SubType).GetTypeInfo();
|
||||
var runtimeTypeInfo = new RuntimeTypeInfo(typeInfo);
|
||||
|
||||
// Act
|
||||
var actual = runtimeTypeInfo.GetCustomAttributes<EditorBrowsableAttribute>();
|
||||
|
||||
// Assert
|
||||
Assert.Empty(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ImplementsInterface_ThrowsIfArgumentIsNotRuntimeType()
|
||||
{
|
||||
// Arrange
|
||||
var typeInfo = new RuntimeTypeInfo(typeof(object).GetTypeInfo());
|
||||
var interfaceTypeInfo = new TestTypeInfo();
|
||||
|
||||
// Act and Assert
|
||||
ExceptionAssert.ThrowsArgument(() => typeInfo.ImplementsInterface(interfaceTypeInfo),
|
||||
"interfaceTypeInfo",
|
||||
$"Argument must be an instance of '{typeof(RuntimeTypeInfo)}'.");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(typeof(ITagHelper), typeof(ITagHelper))]
|
||||
[InlineData(typeof(TagHelper), typeof(ITagHelper))]
|
||||
[InlineData(typeof(ImplementsITagHelper), typeof(ITagHelper))]
|
||||
[InlineData(typeof(DerivesFromTagHelper), typeof(ITagHelper))]
|
||||
[InlineData(typeof(Fake.ImplementsRealITagHelper), typeof(ITagHelper))]
|
||||
[InlineData(typeof(string), typeof(IEnumerable<char>))]
|
||||
[InlineData(typeof(Dictionary<string, string>), typeof(IDictionary<string, string>))]
|
||||
[InlineData(typeof(List<string>), typeof(IList<string>))]
|
||||
[InlineData(typeof(IList<string>), typeof(IEnumerable<string>))]
|
||||
public void ImplementsInterface_ReturnsTrueIfTypeImplementsInterface(Type runtimeType, Type interfaceType)
|
||||
{
|
||||
// Arrange
|
||||
var runtimeTypeInfo = new RuntimeTypeInfo(runtimeType.GetTypeInfo());
|
||||
var interfaceTypeInfo = new RuntimeTypeInfo(interfaceType.GetTypeInfo());
|
||||
|
||||
// Act
|
||||
var result = runtimeTypeInfo.ImplementsInterface(interfaceTypeInfo);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(typeof(string), typeof(object))]
|
||||
[InlineData(typeof(DerivesFromTagHelper), typeof(TagHelper))]
|
||||
[InlineData(typeof(string), typeof(ITagHelper))]
|
||||
[InlineData(typeof(string), typeof(IList<char>))]
|
||||
[InlineData(typeof(SubType), typeof(ITagHelper))]
|
||||
[InlineData(typeof(Fake.DoesNotImplementRealITagHelper), typeof(ITagHelper))]
|
||||
[InlineData(typeof(IDictionary<,>), typeof(IDictionary<string, string>))]
|
||||
public void ImplementsInterface_ReturnsTrueIfTypeDoesNotImplementInterface(Type runtimeType, Type interfaceType)
|
||||
{
|
||||
// Arrange
|
||||
var runtimeTypeInfo = new RuntimeTypeInfo(runtimeType.GetTypeInfo());
|
||||
var interfaceTypeInfo = new RuntimeTypeInfo(interfaceType.GetTypeInfo());
|
||||
|
||||
// Act
|
||||
var result = runtimeTypeInfo.ImplementsInterface(interfaceTypeInfo);
|
||||
|
||||
// Assert
|
||||
Assert.False(result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(typeof(Dictionary<string, string>), new[] { typeof(string), typeof(string) })]
|
||||
[InlineData(typeof(DerivesFromDictionary), new[] { typeof(int), typeof(object) })]
|
||||
[InlineData(typeof(ImplementsIDictionary), new[] { typeof(List<string>), typeof(string) })]
|
||||
[InlineData(typeof(IDictionary<string, IDictionary<string, CustomType>>),
|
||||
new[] { typeof(string), typeof(IDictionary<string, CustomType>) })]
|
||||
[InlineData(typeof(KnownKeyDictionary<ImplementsIDictionary>),
|
||||
new[] { typeof(string), typeof(ImplementsIDictionary) })]
|
||||
public void GetGenericDictionaryParameters_ReturnsKeyAndValueParameterTypeNames(
|
||||
Type type,
|
||||
Type[] expectedTypes)
|
||||
{
|
||||
// Arrange
|
||||
var runtimeTypeInfo = new RuntimeTypeInfo(type.GetTypeInfo());
|
||||
|
||||
// Act
|
||||
var actual = runtimeTypeInfo.GetGenericDictionaryParameters();
|
||||
|
||||
// Assert
|
||||
Assert.Collection(actual,
|
||||
keyType =>
|
||||
{
|
||||
Assert.Equal(new RuntimeTypeInfo(expectedTypes[0].GetTypeInfo()), keyType);
|
||||
},
|
||||
valueType =>
|
||||
{
|
||||
Assert.Equal(new RuntimeTypeInfo(expectedTypes[1].GetTypeInfo()), valueType);
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetGenericDictionaryParameters_WorksWhenValueParameterIsOpen()
|
||||
{
|
||||
// Arrange
|
||||
var runtimeTypeInfo = new RuntimeTypeInfo(typeof(KnownKeyDictionary<>).GetTypeInfo());
|
||||
|
||||
// Act
|
||||
var actual = runtimeTypeInfo.GetGenericDictionaryParameters();
|
||||
|
||||
// Assert
|
||||
Assert.Collection(actual,
|
||||
keyType =>
|
||||
{
|
||||
Assert.Equal(new RuntimeTypeInfo(typeof(string).GetTypeInfo()), keyType);
|
||||
},
|
||||
valueType =>
|
||||
{
|
||||
Assert.Null(valueType);
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetGenericDictionaryParameters_WorksWhenKeyAndValueParametersAreOpen()
|
||||
{
|
||||
// Arrange
|
||||
var runtimeTypeInfo = new RuntimeTypeInfo(typeof(Dictionary<,>).GetTypeInfo());
|
||||
|
||||
// Act
|
||||
var actual = runtimeTypeInfo.GetGenericDictionaryParameters();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(new RuntimeTypeInfo[] { null, null }, actual);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(typeof(int))]
|
||||
[InlineData(typeof(string))]
|
||||
[InlineData(typeof(List<string>))]
|
||||
[InlineData(typeof(IDictionary))]
|
||||
[InlineData(typeof(ITagHelper))]
|
||||
public void GetGenericDictionaryParameterNames_ReturnsNullIfTypeDoesNotImplementGenericDictionary(Type type)
|
||||
{
|
||||
// Arrange
|
||||
var runtimeTypeInfo = new RuntimeTypeInfo(type.GetTypeInfo());
|
||||
|
||||
// Act
|
||||
var actual = runtimeTypeInfo.GetGenericDictionaryParameters();
|
||||
|
||||
// Assert
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(typeof(string))]
|
||||
[InlineData(typeof(IDictionary<,>))]
|
||||
[InlineData(typeof(ITagHelper))]
|
||||
[InlineData(typeof(TagHelper))]
|
||||
public void Equals_ReturnsTrueIfTypeInfosAreIdentical(Type type)
|
||||
{
|
||||
// Arrange
|
||||
var typeA = new RuntimeTypeInfo(type.GetTypeInfo());
|
||||
var typeB = new RuntimeTypeInfo(type.GetTypeInfo());
|
||||
|
||||
// Act
|
||||
var equals = typeA.Equals(typeB);
|
||||
var hashCodeA = typeA.GetHashCode();
|
||||
var hashCodeB = typeB.GetHashCode();
|
||||
|
||||
// Assert
|
||||
Assert.True(equals);
|
||||
Assert.Equal(hashCodeA, hashCodeB);
|
||||
}
|
||||
|
||||
public static TheoryData Equals_ReturnsTrueIfTypeFullNamesAreIdenticalData =>
|
||||
new TheoryData<Type, string>
|
||||
{
|
||||
{ typeof(string), typeof(string).FullName },
|
||||
{ typeof(ITagHelper), typeof(ITagHelper).FullName },
|
||||
{ typeof(TagHelper), typeof(TagHelper).FullName },
|
||||
{ typeof(TagHelper), typeof(TagHelper).FullName },
|
||||
{ typeof(IDictionary<,>), typeof(IDictionary<,>).FullName },
|
||||
{
|
||||
typeof(IDictionary<string,string>),
|
||||
typeof(IDictionary<string, string>).FullName
|
||||
},
|
||||
};
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(Equals_ReturnsTrueIfTypeFullNamesAreIdenticalData))]
|
||||
public void Equals_ReturnsTrueIfTypeInfoNamesAreIdentical(Type type, string fullName)
|
||||
{
|
||||
// Arrange
|
||||
var typeA = new RuntimeTypeInfo(type.GetTypeInfo());
|
||||
var typeB = new TestTypeInfo
|
||||
{
|
||||
FullName = fullName
|
||||
};
|
||||
|
||||
// Act
|
||||
var equals = typeA.Equals(typeB);
|
||||
|
||||
// Assert
|
||||
Assert.True(equals);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(typeof(string), typeof(object))]
|
||||
[InlineData(typeof(IDictionary<,>), typeof(IDictionary<string, string>))]
|
||||
[InlineData(typeof(KnownKeyDictionary<string>), typeof(IDictionary<string, string>))]
|
||||
[InlineData(typeof(ITagHelper), typeof(TagHelper))]
|
||||
public void Equals_ReturnsFalseIfTypeInfosAreDifferent(Type typeA, Type typeB)
|
||||
{
|
||||
// Arrange
|
||||
var typeAInfo = new RuntimeTypeInfo(typeA.GetTypeInfo());
|
||||
var typeBInfo = new RuntimeTypeInfo(typeB.GetTypeInfo());
|
||||
|
||||
// Act
|
||||
var equals = typeAInfo.Equals(typeBInfo);
|
||||
var hashCodeA = typeAInfo.GetHashCode();
|
||||
var hashCodeB = typeBInfo.GetHashCode();
|
||||
|
||||
// Assert
|
||||
Assert.False(equals);
|
||||
Assert.NotEqual(hashCodeA, hashCodeB);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(Equals_ReturnsTrueIfTypeFullNamesAreIdenticalData))]
|
||||
public void Equals_ReturnsFalseIfTypeInfoNamesAreDifferent(Type type, string fullName)
|
||||
{
|
||||
// Arrange
|
||||
var typeA = new RuntimeTypeInfo(type.GetTypeInfo());
|
||||
var typeB = new TestTypeInfo
|
||||
{
|
||||
FullName = "Different" + fullName
|
||||
};
|
||||
|
||||
// Act
|
||||
var equals = typeA.Equals(typeB);
|
||||
|
||||
// Assert
|
||||
Assert.False(equals);
|
||||
}
|
||||
|
||||
public class AbstractType
|
||||
{
|
||||
}
|
||||
|
||||
internal class InternalType
|
||||
{
|
||||
}
|
||||
|
||||
private class PrivateType
|
||||
{
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
private class BaseType
|
||||
{
|
||||
public string this[string key]
|
||||
{
|
||||
get { return ""; }
|
||||
set { }
|
||||
}
|
||||
|
||||
public string BaseTypeProperty { get; set; }
|
||||
|
||||
protected int ProtectedProperty { get; set; }
|
||||
}
|
||||
|
||||
private class SubType : BaseType
|
||||
{
|
||||
public string Property1 { get; set; }
|
||||
|
||||
public int Property2 { get; }
|
||||
|
||||
public object Property3 { private get; set; }
|
||||
|
||||
private int Property4 { get; set; }
|
||||
}
|
||||
|
||||
[HtmlTargetElement("test1")]
|
||||
[HtmlTargetElement("test2")]
|
||||
private class TypeWithAttributes
|
||||
{
|
||||
}
|
||||
|
||||
private class DerivesFromTagHelper : TagHelper
|
||||
{
|
||||
}
|
||||
|
||||
private class ImplementsITagHelper : ITagHelper
|
||||
{
|
||||
public int Order { get; } = 0;
|
||||
|
||||
public void Init(TagHelperContext context)
|
||||
{
|
||||
}
|
||||
|
||||
public Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
private class DerivesFromDictionary : Dictionary<int, object>
|
||||
{
|
||||
}
|
||||
|
||||
private class ImplementsIDictionary : IDictionary<List<string>, string>, IReadOnlyList<int>
|
||||
{
|
||||
public int this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public string this[List<string> key]
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public ICollection<List<string>> Keys
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public ICollection<string> Values
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(KeyValuePair<List<string>, string> item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Add(List<string> key, string value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool Contains(KeyValuePair<List<string>, string> item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool ContainsKey(List<string> key)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void CopyTo(KeyValuePair<List<string>, string>[] array, int arrayIndex)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerator<KeyValuePair<List<string>, string>> GetEnumerator()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool Remove(KeyValuePair<List<string>, string> item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool Remove(List<string> key)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool TryGetValue(List<string> key, out string value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
IEnumerator<int> IEnumerable<int>.GetEnumerator()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public class KnownKeyDictionary<TValue> : Dictionary<string, TValue>
|
||||
{
|
||||
}
|
||||
|
||||
private class CustomType
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ using Xunit;
|
|||
|
||||
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||
{
|
||||
public abstract class TagHelperDescriptorFactoryTest
|
||||
public class TagHelperDescriptorFactoryTest
|
||||
{
|
||||
protected static readonly AssemblyName TagHelperDescriptorFactoryTestAssembly =
|
||||
typeof(TagHelperDescriptorFactoryTest).GetTypeInfo().Assembly.GetName();
|
||||
|
|
@ -93,7 +93,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
// Act
|
||||
var descriptors = factory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
GetTypeInfo(tagHelperType),
|
||||
tagHelperType,
|
||||
errorSink: errorSink);
|
||||
|
||||
// Assert
|
||||
|
|
@ -182,7 +182,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
// Act
|
||||
var descriptors = factory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
GetTypeInfo(tagHelperType),
|
||||
tagHelperType,
|
||||
errorSink: errorSink);
|
||||
|
||||
// Assert
|
||||
|
|
@ -252,7 +252,6 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
}
|
||||
}
|
||||
|
||||
public abstract ITypeInfo GetTypeInfo(Type tagHelperType);
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RestrictChildrenData))]
|
||||
|
|
@ -267,7 +266,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
// Act
|
||||
var descriptors = factory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
GetTypeInfo(tagHelperType),
|
||||
tagHelperType,
|
||||
errorSink: errorSink);
|
||||
|
||||
// Assert
|
||||
|
|
@ -356,7 +355,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
// Act
|
||||
var descriptors = factory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
GetTypeInfo(tagHelperType),
|
||||
tagHelperType,
|
||||
errorSink: errorSink);
|
||||
|
||||
// Assert
|
||||
|
|
@ -592,7 +591,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
// Act
|
||||
var descriptors = factory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
GetTypeInfo(tagHelperType),
|
||||
tagHelperType,
|
||||
errorSink);
|
||||
|
||||
// Assert
|
||||
|
|
@ -794,7 +793,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
// Act
|
||||
var descriptors = factory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
GetTypeInfo(tagHelperType),
|
||||
tagHelperType,
|
||||
errorSink: errorSink);
|
||||
|
||||
// Assert
|
||||
|
|
@ -843,7 +842,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
// Act
|
||||
var descriptors = factory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
GetTypeInfo(tagHelperType),
|
||||
tagHelperType,
|
||||
errorSink: errorSink);
|
||||
|
||||
// Assert
|
||||
|
|
@ -880,7 +879,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
// Act
|
||||
var descriptors = factory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
GetTypeInfo(typeof(OverriddenAttributeTagHelper)),
|
||||
typeof(OverriddenAttributeTagHelper),
|
||||
errorSink: errorSink);
|
||||
|
||||
// Assert
|
||||
|
|
@ -914,7 +913,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
// Act
|
||||
var descriptors = factory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
GetTypeInfo(typeof(InheritedOverriddenAttributeTagHelper)),
|
||||
typeof(InheritedOverriddenAttributeTagHelper),
|
||||
errorSink: errorSink);
|
||||
|
||||
// Assert
|
||||
|
|
@ -948,7 +947,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
// Act
|
||||
var descriptors = factory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
GetTypeInfo(typeof(InheritedNotOverriddenAttributeTagHelper)),
|
||||
typeof(InheritedNotOverriddenAttributeTagHelper),
|
||||
errorSink: errorSink);
|
||||
// Assert
|
||||
Assert.Empty(errorSink.Errors);
|
||||
|
|
@ -978,7 +977,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
// Act
|
||||
var descriptors = factory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
GetTypeInfo(typeof(InheritedSingleAttributeTagHelper)),
|
||||
typeof(InheritedSingleAttributeTagHelper),
|
||||
errorSink: errorSink);
|
||||
|
||||
// Assert
|
||||
|
|
@ -1006,7 +1005,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
// Act
|
||||
var descriptors = factory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
GetTypeInfo(typeof(SingleAttributeTagHelper)),
|
||||
typeof(SingleAttributeTagHelper),
|
||||
errorSink: new ErrorSink());
|
||||
|
||||
// Assert
|
||||
|
|
@ -1035,7 +1034,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
// Act
|
||||
var descriptors = factory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
GetTypeInfo(typeof(MissingAccessorTagHelper)),
|
||||
typeof(MissingAccessorTagHelper),
|
||||
errorSink: errorSink);
|
||||
|
||||
// Assert
|
||||
|
|
@ -1064,7 +1063,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
// Act
|
||||
var descriptors = factory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
GetTypeInfo(typeof(NonPublicAccessorTagHelper)),
|
||||
typeof(NonPublicAccessorTagHelper),
|
||||
errorSink: errorSink);
|
||||
|
||||
// Assert
|
||||
|
|
@ -1096,7 +1095,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
// Act
|
||||
var descriptors = factory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
GetTypeInfo(typeof(NotBoundAttributeTagHelper)),
|
||||
typeof(NotBoundAttributeTagHelper),
|
||||
errorSink: errorSink);
|
||||
|
||||
// Assert
|
||||
|
|
@ -1115,7 +1114,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
// Act
|
||||
var descriptors = factory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
GetTypeInfo(typeof(DuplicateAttributeNameTagHelper)),
|
||||
typeof(DuplicateAttributeNameTagHelper),
|
||||
errorSink: errorSink);
|
||||
|
||||
// Assert
|
||||
|
|
@ -1164,7 +1163,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
// Act
|
||||
var descriptors = factory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
GetTypeInfo(typeof(MultiTagTagHelper)),
|
||||
typeof(MultiTagTagHelper),
|
||||
errorSink: errorSink);
|
||||
|
||||
// Assert
|
||||
|
|
@ -1196,7 +1195,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
// Act
|
||||
var descriptors = factory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
GetTypeInfo(typeof(InheritedMultiTagTagHelper)),
|
||||
typeof(InheritedMultiTagTagHelper),
|
||||
errorSink: errorSink);
|
||||
|
||||
// Assert
|
||||
|
|
@ -1226,7 +1225,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
// Act
|
||||
var descriptors = factory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
GetTypeInfo(typeof(DuplicateTagNameTagHelper)),
|
||||
typeof(DuplicateTagNameTagHelper),
|
||||
errorSink: errorSink);
|
||||
|
||||
// Assert
|
||||
|
|
@ -1256,7 +1255,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
// Act
|
||||
var descriptors = factory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
GetTypeInfo(typeof(OverrideNameTagHelper)),
|
||||
typeof(OverrideNameTagHelper),
|
||||
errorSink: errorSink);
|
||||
|
||||
// Assert
|
||||
|
|
@ -1444,7 +1443,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
// Act
|
||||
var descriptors = factory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
GetTypeInfo(type),
|
||||
type,
|
||||
errorSink: errorSink);
|
||||
|
||||
// Assert
|
||||
|
|
@ -1694,7 +1693,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
// Act
|
||||
var result = TagHelperDescriptorFactory.ValidateTagHelperAttributeDescriptor(
|
||||
descriptor,
|
||||
GetTypeInfo(typeof(MultiTagTagHelper)),
|
||||
typeof(MultiTagTagHelper),
|
||||
errorSink);
|
||||
|
||||
// Assert
|
||||
|
|
@ -1736,7 +1735,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
// Act
|
||||
var result = TagHelperDescriptorFactory.ValidateTagHelperAttributeDescriptor(
|
||||
descriptor,
|
||||
GetTypeInfo(typeof(MultiTagTagHelper)),
|
||||
typeof(MultiTagTagHelper),
|
||||
errorSink);
|
||||
|
||||
// Assert
|
||||
|
|
@ -1782,7 +1781,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
// Act
|
||||
var result = TagHelperDescriptorFactory.ValidateTagHelperAttributeDescriptor(
|
||||
descriptor,
|
||||
GetTypeInfo(typeof(MultiTagTagHelper)),
|
||||
typeof(MultiTagTagHelper),
|
||||
errorSink);
|
||||
|
||||
// Assert
|
||||
|
|
@ -1837,7 +1836,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
// Act
|
||||
var result = TagHelperDescriptorFactory.ValidateTagHelperAttributeDescriptor(
|
||||
descriptor,
|
||||
GetTypeInfo(typeof(MultiTagTagHelper)),
|
||||
typeof(MultiTagTagHelper),
|
||||
errorSink);
|
||||
|
||||
// Assert
|
||||
|
|
@ -1925,6 +1924,145 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
Assert.Equal(expectedErrors, errorSink.Errors);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateDescriptors_BuildsDescriptorsFromSimpleTypes()
|
||||
{
|
||||
// Arrange
|
||||
var errorSink = new ErrorSink();
|
||||
var objectAssemblyName = typeof(object).GetTypeInfo().Assembly.GetName().Name;
|
||||
var expectedDescriptor =
|
||||
CreateTagHelperDescriptor("object", "System.Object", objectAssemblyName);
|
||||
var factory = new TagHelperDescriptorFactory(designTime: false);
|
||||
|
||||
// Act
|
||||
var descriptors = factory.CreateDescriptors(
|
||||
objectAssemblyName,
|
||||
typeof(object),
|
||||
errorSink: errorSink);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(errorSink.Errors);
|
||||
var descriptor = Assert.Single(descriptors);
|
||||
Assert.Equal(expectedDescriptor, descriptor, CaseSensitiveTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(TagHelperWithPrefixData))]
|
||||
public void CreateDescriptors_WithPrefixes_ReturnsExpectedAttributeDescriptors(
|
||||
Type tagHelperType,
|
||||
IEnumerable<TagHelperAttributeDescriptor> expectedAttributeDescriptors,
|
||||
string[] expectedErrorMessages)
|
||||
{
|
||||
// Arrange
|
||||
var errorSink = new ErrorSink();
|
||||
var factory = new TagHelperDescriptorFactory(designTime: false);
|
||||
|
||||
// Act
|
||||
var descriptors = factory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
tagHelperType,
|
||||
errorSink: errorSink);
|
||||
|
||||
// Assert
|
||||
var errors = errorSink.Errors.ToArray();
|
||||
Assert.Equal(expectedErrorMessages.Length, errors.Length);
|
||||
|
||||
for (var i = 0; i < errors.Length; i++)
|
||||
{
|
||||
Assert.Equal(0, errors[i].Length);
|
||||
Assert.Equal(SourceLocation.Zero, errors[i].Location);
|
||||
Assert.Equal(expectedErrorMessages[i], errors[i].Message, StringComparer.Ordinal);
|
||||
}
|
||||
|
||||
var descriptor = Assert.Single(descriptors);
|
||||
Assert.Equal(
|
||||
expectedAttributeDescriptors,
|
||||
descriptor.Attributes,
|
||||
TagHelperAttributeDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
// TagHelperDesignTimeDescriptors are not created in CoreCLR.
|
||||
#if !DNXCORE50
|
||||
public static TheoryData OutputElementHintData
|
||||
{
|
||||
get
|
||||
{
|
||||
// tagHelperType, expectedDescriptors
|
||||
return new TheoryData<Type, TagHelperDescriptor[]>
|
||||
{
|
||||
{
|
||||
typeof(OutputElementHintTagHelper),
|
||||
new[]
|
||||
{
|
||||
new TagHelperDescriptor
|
||||
{
|
||||
TagName = "output-element-hint",
|
||||
TypeName = typeof(OutputElementHintTagHelper).FullName,
|
||||
AssemblyName = AssemblyName,
|
||||
DesignTimeDescriptor = new TagHelperDesignTimeDescriptor
|
||||
{
|
||||
OutputElementHint = "strong"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
typeof(MulitpleDescriptorTagHelperWithOutputElementHint),
|
||||
new[]
|
||||
{
|
||||
new TagHelperDescriptor
|
||||
{
|
||||
TagName = "a",
|
||||
TypeName = typeof(MulitpleDescriptorTagHelperWithOutputElementHint).FullName,
|
||||
AssemblyName = AssemblyName,
|
||||
DesignTimeDescriptor = new TagHelperDesignTimeDescriptor
|
||||
{
|
||||
OutputElementHint = "div"
|
||||
}
|
||||
},
|
||||
new TagHelperDescriptor
|
||||
{
|
||||
TagName = "p",
|
||||
TypeName = typeof(MulitpleDescriptorTagHelperWithOutputElementHint).FullName,
|
||||
AssemblyName = AssemblyName,
|
||||
DesignTimeDescriptor = new TagHelperDesignTimeDescriptor
|
||||
{
|
||||
OutputElementHint = "div"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(OutputElementHintData))]
|
||||
public void CreateDescriptors_CreatesDesignTimeDescriptorsWithOutputElementHint(
|
||||
Type tagHelperType,
|
||||
TagHelperDescriptor[] expectedDescriptors)
|
||||
{
|
||||
// Arrange
|
||||
var errorSink = new ErrorSink();
|
||||
var factory = new TagHelperDescriptorFactory(designTime: true);
|
||||
|
||||
// Act
|
||||
var descriptors = factory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
tagHelperType,
|
||||
errorSink: errorSink);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(errorSink.Errors);
|
||||
|
||||
// We don't care about order. Mono returns reflected attributes differently so we need to ensure order
|
||||
// doesn't matter by sorting.
|
||||
descriptors = descriptors.OrderBy(descriptor => descriptor.TagName);
|
||||
|
||||
Assert.Equal(expectedDescriptors, descriptors, CaseSensitiveTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
#endif
|
||||
|
||||
private static TheoryData<string, string[]> GetInvalidNameOrPrefixData(
|
||||
Func<string, string, string> onNameError,
|
||||
string whitespaceErrorString,
|
||||
|
|
|
|||
|
|
@ -1414,7 +1414,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
return types?.Select(type => type.GetTypeInfo()) ?? Enumerable.Empty<TypeInfo>();
|
||||
}
|
||||
|
||||
internal override bool IsTagHelper(ITypeInfo typeInfo)
|
||||
internal override bool IsTagHelper(TypeInfo typeInfo)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,13 +66,11 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
Assert.Collection(types,
|
||||
type =>
|
||||
{
|
||||
var typeInfo = Assert.IsType<RuntimeTypeInfo>(type);
|
||||
Assert.Equal(typeof(Valid_PlainTagHelper).GetTypeInfo(), typeInfo.TypeInfo);
|
||||
Assert.Equal(typeof(Valid_PlainTagHelper), type);
|
||||
},
|
||||
type =>
|
||||
{
|
||||
var typeInfo = Assert.IsType<RuntimeTypeInfo>(type);
|
||||
Assert.Equal(typeof(Valid_InheritedTagHelper).GetTypeInfo(), typeInfo.TypeInfo);
|
||||
Assert.Equal(typeof(Valid_InheritedTagHelper), type);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +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.
|
||||
|
||||
namespace Microsoft.AspNet.Razor.Fake
|
||||
{
|
||||
public class DoesNotImplementRealITagHelper : Microsoft.AspNet.Razor.Fake.ITagHelper
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +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.Threading.Tasks;
|
||||
using Microsoft.AspNet.Razor.TagHelpers;
|
||||
|
||||
namespace Microsoft.AspNet.Razor.Fake
|
||||
{
|
||||
public interface ITagHelper
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +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.Threading.Tasks;
|
||||
using Microsoft.AspNet.Razor.TagHelpers;
|
||||
|
||||
namespace Microsoft.AspNet.Razor.Fake
|
||||
{
|
||||
public class ImplementsRealITagHelper : Microsoft.AspNet.Razor.TagHelpers.ITagHelper
|
||||
{
|
||||
public int Order
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public void Init(TagHelperContext context)
|
||||
{
|
||||
}
|
||||
|
||||
public Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -429,58 +429,4 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
|||
public class MulitpleDescriptorTagHelperWithOutputElementHint : TagHelper
|
||||
{
|
||||
}
|
||||
|
||||
public class TypeDerivingFromITagHelper : ITagHelper
|
||||
{
|
||||
public int Order { get; } = 0;
|
||||
|
||||
public void Init(TagHelperContext context)
|
||||
{
|
||||
}
|
||||
|
||||
public Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public class BaseAttribute : Attribute
|
||||
{
|
||||
public string BaseProperty { get; set; }
|
||||
}
|
||||
|
||||
public class DerivedAttribute : BaseAttribute
|
||||
{
|
||||
public string DerivedProperty { get; set; }
|
||||
}
|
||||
|
||||
public class BaseTagHelper : TagHelper
|
||||
{
|
||||
[Derived(DerivedProperty = "DerivedPropertyValue")]
|
||||
public string BaseProperty { get; set; }
|
||||
|
||||
[HtmlAttributeNotBound]
|
||||
public virtual string VirtualProperty { get; set; }
|
||||
|
||||
public int NewProperty { get; set; }
|
||||
|
||||
public virtual new string Order { get; set; }
|
||||
}
|
||||
|
||||
public class DerivedTagHelper : BaseTagHelper
|
||||
{
|
||||
public override string VirtualProperty { get; set; }
|
||||
|
||||
[Base(BaseProperty = "BaseValue")]
|
||||
public string DerivedProperty { get; set; }
|
||||
|
||||
[HtmlAttributeName("new-property")]
|
||||
public new Type NewProperty { get; set; }
|
||||
|
||||
public override string Order { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
public class TagHelperInGlobalNamespace : TagHelper
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,81 +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;
|
||||
|
||||
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||
{
|
||||
public class TestTypeInfo : ITypeInfo
|
||||
{
|
||||
public string FullName { get; set; }
|
||||
|
||||
public bool IsAbstract
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsGenericType
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsPublic
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsEnum
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public bool ImplementsInterface(ITypeInfo other)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IPropertyInfo> Properties
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public bool Equals(ITypeInfo other)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<TAttribute> GetCustomAttributes<TAttribute>() where TAttribute : Attribute
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public ITypeInfo[] GetGenericDictionaryParameters()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue