Remove Razor from projects
This commit is contained in:
parent
1fdc5132cb
commit
270f66198f
|
|
@ -10,7 +10,6 @@ using Microsoft.AspNetCore.Mvc.Razor.Host;
|
|||
using Microsoft.AspNetCore.Mvc.Razor.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Microsoft.AspNetCore.Razor.Compilation.TagHelpers;
|
||||
using Microsoft.AspNetCore.Razor.Evolution;
|
||||
using Microsoft.AspNetCore.Razor.Runtime.TagHelpers;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
|
|
@ -64,11 +63,6 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
|
||||
private static void AddRazorViewEngineFeatureProviders(IMvcCoreBuilder builder)
|
||||
{
|
||||
if (!builder.PartManager.FeatureProviders.OfType<TagHelperFeatureProvider>().Any())
|
||||
{
|
||||
builder.PartManager.FeatureProviders.Add(new TagHelperFeatureProvider());
|
||||
}
|
||||
|
||||
if (!builder.PartManager.FeatureProviders.OfType<MetadataReferenceFeatureProvider>().Any())
|
||||
{
|
||||
builder.PartManager.FeatureProviders.Add(new MetadataReferenceFeatureProvider());
|
||||
|
|
@ -158,12 +152,6 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
|
||||
services.TryAddSingleton<IRazorViewEngine, RazorViewEngine>();
|
||||
|
||||
services.TryAddSingleton<ITagHelperTypeResolver, TagHelperTypeResolver>();
|
||||
services.TryAddSingleton<ITagHelperDescriptorFactory>(s => new TagHelperDescriptorFactory(designTime: false));
|
||||
services.TryAddSingleton<TagHelperDescriptorResolver>();
|
||||
services.TryAddSingleton<ViewComponentTagHelperDescriptorResolver>();
|
||||
services.TryAddSingleton<ITagHelperDescriptorResolver, CompositeTagHelperDescriptorResolver>();
|
||||
|
||||
// Caches compilation artifacts across the lifetime of the application.
|
||||
services.TryAddSingleton<ICompilerCacheProvider, DefaultCompilerCacheProvider>();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,33 +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.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Razor.Compilation.TagHelpers;
|
||||
using Microsoft.AspNetCore.Razor.Runtime.TagHelpers;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
||||
{
|
||||
public class CompositeTagHelperDescriptorResolver : ITagHelperDescriptorResolver
|
||||
{
|
||||
private readonly TagHelperDescriptorResolver _tagHelperDescriptorResolver;
|
||||
private readonly ViewComponentTagHelperDescriptorResolver _viewComponentTagHelperDescriptorResolver;
|
||||
|
||||
public CompositeTagHelperDescriptorResolver(
|
||||
TagHelperDescriptorResolver tagHelperDescriptorResolver,
|
||||
ViewComponentTagHelperDescriptorResolver viewComponentTagHelperDescriptorResolver)
|
||||
{
|
||||
_tagHelperDescriptorResolver = tagHelperDescriptorResolver;
|
||||
_viewComponentTagHelperDescriptorResolver = viewComponentTagHelperDescriptorResolver;
|
||||
}
|
||||
|
||||
public IEnumerable<TagHelperDescriptor> Resolve(TagHelperDescriptorResolutionContext resolutionContext)
|
||||
{
|
||||
var descriptors = new List<TagHelperDescriptor>();
|
||||
|
||||
descriptors.AddRange(_tagHelperDescriptorResolver.Resolve(resolutionContext));
|
||||
descriptors.AddRange(_viewComponentTagHelperDescriptorResolver.Resolve(resolutionContext));
|
||||
|
||||
return descriptors;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,6 @@ using System;
|
|||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
|
||||
using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
|
||||
using Microsoft.AspNetCore.Razor.Runtime.TagHelpers;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
|
||||
|
|
@ -34,7 +33,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
|||
}
|
||||
|
||||
services.Replace(ServiceDescriptor.Transient<ITagHelperActivator, ServiceBasedTagHelperActivator>());
|
||||
services.Replace(ServiceDescriptor.Transient<ITagHelperTypeResolver, FeatureTagHelperTypeResolver>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,266 +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;
|
||||
using Microsoft.AspNetCore.Mvc.Razor.Host;
|
||||
using Microsoft.AspNetCore.Mvc.ViewComponents;
|
||||
using Microsoft.AspNetCore.Razor.Compilation.TagHelpers;
|
||||
using Microsoft.AspNetCore.Razor.Runtime.TagHelpers;
|
||||
using Microsoft.Extensions.Internal;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides methods to create tag helper representations of view components.
|
||||
/// </summary>
|
||||
public class ViewComponentTagHelperDescriptorFactory
|
||||
{
|
||||
private readonly IViewComponentDescriptorProvider _descriptorProvider;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="ViewComponentTagHelperDescriptorFactory"/>,
|
||||
/// then creates <see cref="TagHelperDescriptor"/>s for <see cref="ViewComponent"/>s
|
||||
/// in the given <see cref="IViewComponentDescriptorProvider"/>.
|
||||
/// </summary>
|
||||
/// <param name="descriptorProvider">The provider of <see cref="ViewComponentDescriptor"/>s.</param>
|
||||
public ViewComponentTagHelperDescriptorFactory(IViewComponentDescriptorProvider descriptorProvider)
|
||||
{
|
||||
if (descriptorProvider == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(descriptorProvider));
|
||||
}
|
||||
|
||||
_descriptorProvider = descriptorProvider;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates <see cref="TagHelperDescriptor"/> representations of <see cref="ViewComponent"/>s
|
||||
/// in an <see href="Assembly"/> represented by the given <paramref name="assemblyName"/>.
|
||||
/// </summary>
|
||||
/// <param name="assemblyName">The name of the assembly containing
|
||||
/// the <see cref="ViewComponent"/>s to translate.</param>
|
||||
/// <returns>A <see cref="IEnumerable{TagHelperDescriptor}"/>,
|
||||
/// one for each <see cref="ViewComponent"/>.</returns>
|
||||
public IEnumerable<TagHelperDescriptor> CreateDescriptors(string assemblyName)
|
||||
{
|
||||
if (assemblyName == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(assemblyName));
|
||||
}
|
||||
|
||||
var viewComponentDescriptors = _descriptorProvider
|
||||
.GetViewComponents()
|
||||
.Where(viewComponent => string.Equals(assemblyName, viewComponent.TypeInfo.Assembly.GetName().Name,
|
||||
StringComparison.Ordinal));
|
||||
|
||||
var tagHelperDescriptors = viewComponentDescriptors
|
||||
.Where(d => !d.MethodInfo.ContainsGenericParameters)
|
||||
.Select(viewComponentDescriptor => CreateDescriptor(viewComponentDescriptor));
|
||||
|
||||
return tagHelperDescriptors;
|
||||
}
|
||||
|
||||
private TagHelperDescriptor CreateDescriptor(ViewComponentDescriptor viewComponentDescriptor)
|
||||
{
|
||||
var assemblyName = viewComponentDescriptor.TypeInfo.Assembly.GetName().Name;
|
||||
var tagName = GetTagName(viewComponentDescriptor);
|
||||
var typeName = $"__Generated__{viewComponentDescriptor.ShortName}ViewComponentTagHelper";
|
||||
|
||||
var tagHelperDescriptor = new TagHelperDescriptor
|
||||
{
|
||||
TagName = tagName,
|
||||
TypeName = typeName,
|
||||
AssemblyName = assemblyName
|
||||
};
|
||||
|
||||
SetAttributeDescriptors(viewComponentDescriptor, tagHelperDescriptor);
|
||||
|
||||
tagHelperDescriptor.PropertyBag.Add(
|
||||
ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey, viewComponentDescriptor.ShortName);
|
||||
|
||||
return tagHelperDescriptor;
|
||||
}
|
||||
|
||||
private void SetAttributeDescriptors(ViewComponentDescriptor viewComponentDescriptor,
|
||||
TagHelperDescriptor tagHelperDescriptor)
|
||||
{
|
||||
var methodParameters = viewComponentDescriptor.MethodInfo.GetParameters();
|
||||
var attributeDescriptors = new List<TagHelperAttributeDescriptor>();
|
||||
var indexerDescriptors = new List<TagHelperAttributeDescriptor>();
|
||||
var requiredAttributeDescriptors = new List<TagHelperRequiredAttributeDescriptor>();
|
||||
|
||||
foreach (var parameter in methodParameters)
|
||||
{
|
||||
var lowerKebabName = TagHelperDescriptorFactory.ToHtmlCase(parameter.Name);
|
||||
var typeName = GetCSharpTypeName(parameter.ParameterType);
|
||||
var descriptor = new TagHelperAttributeDescriptor
|
||||
{
|
||||
Name = lowerKebabName,
|
||||
PropertyName = parameter.Name,
|
||||
TypeName = typeName
|
||||
};
|
||||
|
||||
descriptor.IsEnum = parameter.ParameterType.GetTypeInfo().IsEnum;
|
||||
descriptor.IsIndexer = false;
|
||||
|
||||
attributeDescriptors.Add(descriptor);
|
||||
|
||||
var indexerDescriptor = GetIndexerAttributeDescriptor(parameter, lowerKebabName);
|
||||
if (indexerDescriptor != null)
|
||||
{
|
||||
indexerDescriptors.Add(indexerDescriptor);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set required attributes only for non-indexer attributes. Indexer attributes can't be required attributes
|
||||
// because there are two ways of setting values for the attribute.
|
||||
requiredAttributeDescriptors.Add(new TagHelperRequiredAttributeDescriptor
|
||||
{
|
||||
Name = lowerKebabName
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
attributeDescriptors.AddRange(indexerDescriptors);
|
||||
tagHelperDescriptor.Attributes = attributeDescriptors;
|
||||
tagHelperDescriptor.RequiredAttributes = requiredAttributeDescriptors;
|
||||
}
|
||||
|
||||
private TagHelperAttributeDescriptor GetIndexerAttributeDescriptor(ParameterInfo parameter, string name)
|
||||
{
|
||||
var dictionaryTypeArguments = ClosedGenericMatcher.ExtractGenericInterface(
|
||||
parameter.ParameterType,
|
||||
typeof(IDictionary<,>))
|
||||
?.GenericTypeArguments
|
||||
.Select(t => t.IsGenericParameter ? null : t)
|
||||
.ToArray();
|
||||
|
||||
if (dictionaryTypeArguments?[0] != typeof(string))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var type = dictionaryTypeArguments[1];
|
||||
var descriptor = new TagHelperAttributeDescriptor
|
||||
{
|
||||
Name = name + "-",
|
||||
PropertyName = parameter.Name,
|
||||
TypeName = GetCSharpTypeName(type),
|
||||
IsEnum = type.GetTypeInfo().IsEnum,
|
||||
IsIndexer = true
|
||||
};
|
||||
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
private string GetTagName(ViewComponentDescriptor descriptor)
|
||||
{
|
||||
return $"vc:{TagHelperDescriptorFactory.ToHtmlCase(descriptor.ShortName)}";
|
||||
}
|
||||
|
||||
// Internal for testing.
|
||||
internal static string GetCSharpTypeName(Type type)
|
||||
{
|
||||
var outputBuilder = new StringBuilder();
|
||||
WriteCSharpTypeName(type, outputBuilder);
|
||||
|
||||
var typeName = outputBuilder.ToString();
|
||||
|
||||
// We don't want to add global:: to the top level type because Razor does that for us.
|
||||
return typeName.Substring("global::".Length);
|
||||
}
|
||||
|
||||
private static void WriteCSharpTypeName(Type type, StringBuilder outputBuilder)
|
||||
{
|
||||
var typeInfo = type.GetTypeInfo();
|
||||
if (typeInfo.IsByRef)
|
||||
{
|
||||
WriteCSharpTypeName(typeInfo.GetElementType(), outputBuilder);
|
||||
}
|
||||
else if (typeInfo.IsNested)
|
||||
{
|
||||
WriteNestedTypes(type, outputBuilder);
|
||||
}
|
||||
else if (typeInfo.IsGenericType)
|
||||
{
|
||||
outputBuilder.Append("global::");
|
||||
var part = type.FullName.Substring(0, type.FullName.IndexOf('`'));
|
||||
outputBuilder.Append(part);
|
||||
|
||||
var genericArguments = type.GenericTypeArguments;
|
||||
WriteGenericArguments(genericArguments, 0, genericArguments.Length, outputBuilder);
|
||||
}
|
||||
else
|
||||
{
|
||||
outputBuilder.Append("global::");
|
||||
outputBuilder.Append(type.FullName);
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteNestedTypes(Type type, StringBuilder outputBuilder)
|
||||
{
|
||||
var nestedTypes = new List<Type>();
|
||||
var currentType = type;
|
||||
do
|
||||
{
|
||||
nestedTypes.Insert(0, currentType);
|
||||
currentType = currentType.DeclaringType;
|
||||
} while (currentType.IsNested);
|
||||
|
||||
nestedTypes.Insert(0, currentType);
|
||||
|
||||
outputBuilder.Append("global::");
|
||||
outputBuilder.Append(currentType.Namespace);
|
||||
outputBuilder.Append(".");
|
||||
|
||||
var typeArgumentIndex = 0;
|
||||
for (var i = 0; i < nestedTypes.Count; i++)
|
||||
{
|
||||
var nestedType = nestedTypes[i];
|
||||
var arityIndex = nestedType.Name.IndexOf('`');
|
||||
if (arityIndex >= 0)
|
||||
{
|
||||
var part = nestedType.Name.Substring(0, arityIndex);
|
||||
outputBuilder.Append(part);
|
||||
|
||||
var genericArguments = type.GenericTypeArguments;
|
||||
var typeArgumentCount = nestedType.IsConstructedGenericType ?
|
||||
nestedType.GenericTypeArguments.Length : nestedType.GetTypeInfo().GenericTypeParameters.Length;
|
||||
|
||||
WriteGenericArguments(genericArguments, typeArgumentIndex, typeArgumentCount, outputBuilder);
|
||||
|
||||
typeArgumentIndex = typeArgumentCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
outputBuilder.Append(nestedType.Name);
|
||||
}
|
||||
|
||||
if (i + 1 < nestedTypes.Count)
|
||||
{
|
||||
outputBuilder.Append(".");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteGenericArguments(Type[] genericArguments, int startIndex, int length, StringBuilder outputBuilder)
|
||||
{
|
||||
outputBuilder.Append("<");
|
||||
|
||||
for (var i = startIndex; i < length; i++)
|
||||
{
|
||||
WriteCSharpTypeName(genericArguments[i], outputBuilder);
|
||||
if (i + 1 < length)
|
||||
{
|
||||
outputBuilder.Append(", ");
|
||||
}
|
||||
}
|
||||
|
||||
outputBuilder.Append(">");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +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.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Mvc.ViewComponents;
|
||||
using Microsoft.AspNetCore.Razor;
|
||||
using Microsoft.AspNetCore.Razor.Compilation.TagHelpers;
|
||||
using Microsoft.AspNetCore.Razor.Runtime.TagHelpers;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
||||
{
|
||||
public class ViewComponentTagHelperDescriptorResolver : TagHelperDescriptorResolver
|
||||
{
|
||||
private readonly ViewComponentTagHelperDescriptorFactory _descriptorFactory;
|
||||
|
||||
public ViewComponentTagHelperDescriptorResolver(
|
||||
IViewComponentDescriptorProvider viewComponentDescriptorProvider)
|
||||
: base(designTime: false)
|
||||
{
|
||||
_descriptorFactory = new ViewComponentTagHelperDescriptorFactory(viewComponentDescriptorProvider);
|
||||
}
|
||||
|
||||
protected override IEnumerable<TagHelperDescriptor> ResolveDescriptorsInAssembly(
|
||||
string assemblyName,
|
||||
SourceLocation documentLocation,
|
||||
ErrorSink errorSink)
|
||||
{
|
||||
return _descriptorFactory.CreateDescriptors(assemblyName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,94 +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.AspNetCore.Razor;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
|
||||
using Microsoft.AspNetCore.Razor.Runtime.TagHelpers;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.TagHelpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Resolves tag helper types from the <see cref="ApplicationPartManager.ApplicationParts"/>
|
||||
/// of the application.
|
||||
/// </summary>
|
||||
public class FeatureTagHelperTypeResolver : TagHelperTypeResolver
|
||||
{
|
||||
private readonly TagHelperFeature _feature;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new <see cref="FeatureTagHelperTypeResolver"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="manager">The <see cref="ApplicationPartManager"/> of the application.</param>
|
||||
public FeatureTagHelperTypeResolver(ApplicationPartManager manager)
|
||||
{
|
||||
if (manager == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(manager));
|
||||
}
|
||||
|
||||
_feature = new TagHelperFeature();
|
||||
manager.PopulateFeature(_feature);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IEnumerable<TypeInfo> GetExportedTypes(AssemblyName assemblyName)
|
||||
{
|
||||
if (assemblyName == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(assemblyName));
|
||||
}
|
||||
|
||||
var results = new List<TypeInfo>();
|
||||
for (var i = 0; i < _feature.TagHelpers.Count; i++)
|
||||
{
|
||||
var tagHelperAssemblyName = _feature.TagHelpers[i].Assembly.GetName();
|
||||
|
||||
if (AssemblyNameComparer.OrdinalIgnoreCase.Equals(tagHelperAssemblyName, assemblyName))
|
||||
{
|
||||
results.Add(_feature.TagHelpers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected sealed override bool IsTagHelper(TypeInfo typeInfo)
|
||||
{
|
||||
// Return true always as we have already decided what types are tag helpers when GetExportedTypes
|
||||
// gets called.
|
||||
return true;
|
||||
}
|
||||
|
||||
private class AssemblyNameComparer : IEqualityComparer<AssemblyName>
|
||||
{
|
||||
public static readonly IEqualityComparer<AssemblyName> OrdinalIgnoreCase = new AssemblyNameComparer();
|
||||
|
||||
private AssemblyNameComparer()
|
||||
{
|
||||
}
|
||||
|
||||
public bool Equals(AssemblyName x, AssemblyName y)
|
||||
{
|
||||
// Ignore case because that's what Assembly.Load does.
|
||||
return string.Equals(x.Name, y.Name, StringComparison.OrdinalIgnoreCase) &&
|
||||
string.Equals(x.CultureName ?? string.Empty, y.CultureName ?? string.Empty, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
public int GetHashCode(AssemblyName obj)
|
||||
{
|
||||
var hashCode = 0;
|
||||
if (obj.Name != null)
|
||||
{
|
||||
hashCode ^= obj.Name.GetHashCode();
|
||||
}
|
||||
|
||||
hashCode ^= (obj.CultureName ?? string.Empty).GetHashCode();
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,36 +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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
|
||||
using Microsoft.AspNetCore.Razor.Runtime.TagHelpers;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.TagHelpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Discovers tag helpers from a list of <see cref="ApplicationPart"/> instances.
|
||||
/// </summary>
|
||||
public class TagHelperFeatureProvider : IApplicationFeatureProvider<TagHelperFeature>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public void PopulateFeature(IEnumerable<ApplicationPart> parts, TagHelperFeature feature)
|
||||
{
|
||||
foreach (var type in parts.OfType<IApplicationPartTypeProvider>())
|
||||
{
|
||||
ProcessPart(type, feature);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ProcessPart(IApplicationPartTypeProvider part, TagHelperFeature feature)
|
||||
{
|
||||
foreach (var type in part.Types)
|
||||
{
|
||||
if (TagHelperConventions.IsTagHelper(type) && !feature.TagHelpers.Contains(type))
|
||||
{
|
||||
feature.TagHelpers.Add(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@
|
|||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Mvc.Razor\Microsoft.AspNetCore.Mvc.Razor.csproj" />
|
||||
<ProjectReference Include="..\Microsoft.AspNetCore.Mvc.TestCommon\Microsoft.AspNetCore.Mvc.TestCommon.csproj" />
|
||||
|
||||
<PackageReference Include="Microsoft.AspNetCore.Razor" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Testing" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(TestSdkVersion)" />
|
||||
<PackageReference Include="Moq" Version="$(MoqVersion)" />
|
||||
|
|
|
|||
|
|
@ -1,73 +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.Globalization;
|
||||
using Microsoft.AspNetCore.Razor;
|
||||
using Microsoft.AspNetCore.Razor.Parser.SyntaxTree;
|
||||
using Microsoft.AspNetCore.Razor.Text;
|
||||
using Microsoft.AspNetCore.Razor.Tokenizer.Symbols;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor
|
||||
{
|
||||
internal class RawTextSymbol : ISymbol
|
||||
{
|
||||
public SourceLocation Start { get; private set; }
|
||||
public string Content { get; private set; }
|
||||
|
||||
public RawTextSymbol(SourceLocation start, string content)
|
||||
{
|
||||
if (content == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(content));
|
||||
}
|
||||
|
||||
Start = start;
|
||||
Content = content;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
var other = obj as RawTextSymbol;
|
||||
return Equals(Start, other.Start) && Equals(Content, other.Content);
|
||||
}
|
||||
|
||||
internal bool EquivalentTo(ISymbol sym)
|
||||
{
|
||||
return Equals(Start, sym.Start) && Equals(Content, sym.Content);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Start.GetHashCode() +
|
||||
(13 * Content.GetHashCode());
|
||||
}
|
||||
|
||||
public void OffsetStart(SourceLocation documentStart)
|
||||
{
|
||||
Start = documentStart + Start;
|
||||
}
|
||||
|
||||
public void ChangeStart(SourceLocation newStart)
|
||||
{
|
||||
Start = newStart;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(CultureInfo.InvariantCulture, "{0} RAW - [{1}]", Start, Content);
|
||||
}
|
||||
|
||||
internal void CalculateStart(Span prev)
|
||||
{
|
||||
if (prev == null)
|
||||
{
|
||||
Start = SourceLocation.Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
Start = new SourceLocationTracker(prev.Start).UpdateLocation(prev.Content).CurrentLocation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,79 +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.AspNetCore.Razor;
|
||||
using Microsoft.AspNetCore.Razor.Chunks.Generators;
|
||||
using Microsoft.AspNetCore.Razor.Editor;
|
||||
using Microsoft.AspNetCore.Razor.Parser.SyntaxTree;
|
||||
using Microsoft.AspNetCore.Razor.Tokenizer.Symbols;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor
|
||||
{
|
||||
public class SpanConstructor
|
||||
{
|
||||
public SpanBuilder Builder { get; private set; }
|
||||
|
||||
internal static IEnumerable<ISymbol> TestTokenizer(string str)
|
||||
{
|
||||
yield return new RawTextSymbol(SourceLocation.Zero, str);
|
||||
}
|
||||
|
||||
public SpanConstructor(SpanKind kind, IEnumerable<ISymbol> symbols)
|
||||
{
|
||||
Builder = new SpanBuilder();
|
||||
Builder.Kind = kind;
|
||||
Builder.EditHandler = SpanEditHandler.CreateDefault(TestTokenizer);
|
||||
foreach (ISymbol sym in symbols)
|
||||
{
|
||||
Builder.Accept(sym);
|
||||
}
|
||||
}
|
||||
|
||||
private Span Build()
|
||||
{
|
||||
return Builder.Build();
|
||||
}
|
||||
|
||||
public SpanConstructor With(ISpanChunkGenerator generator)
|
||||
{
|
||||
Builder.ChunkGenerator = generator;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SpanConstructor With(SpanEditHandler handler)
|
||||
{
|
||||
Builder.EditHandler = handler;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SpanConstructor With(Action<ISpanChunkGenerator> generatorConfigurer)
|
||||
{
|
||||
generatorConfigurer(Builder.ChunkGenerator);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SpanConstructor With(Action<SpanEditHandler> handlerConfigurer)
|
||||
{
|
||||
handlerConfigurer(Builder.EditHandler);
|
||||
return this;
|
||||
}
|
||||
|
||||
public static implicit operator Span(SpanConstructor self)
|
||||
{
|
||||
return self.Build();
|
||||
}
|
||||
|
||||
public SpanConstructor Hidden()
|
||||
{
|
||||
Builder.ChunkGenerator = SpanChunkGenerator.Null;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SpanConstructor Accepts(AcceptedCharacters accepted)
|
||||
{
|
||||
return With(eh => eh.AcceptedCharacters = accepted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,110 +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 Microsoft.AspNetCore.Razor;
|
||||
using Microsoft.AspNetCore.Razor.Parser.SyntaxTree;
|
||||
using Microsoft.AspNetCore.Razor.Text;
|
||||
using Microsoft.AspNetCore.Razor.Tokenizer;
|
||||
using Microsoft.AspNetCore.Razor.Tokenizer.Internal;
|
||||
using Microsoft.AspNetCore.Razor.Tokenizer.Symbols;
|
||||
using Microsoft.AspNetCore.Razor.Tokenizer.Symbols.Internal;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor
|
||||
{
|
||||
public class SpanFactory
|
||||
{
|
||||
public Func<ITextDocument, ITokenizer> MarkupTokenizerFactory { get; set; }
|
||||
public Func<ITextDocument, ITokenizer> CodeTokenizerFactory { get; set; }
|
||||
public SourceLocationTracker LocationTracker { get; private set; }
|
||||
|
||||
public static SpanFactory CreateCsHtml()
|
||||
{
|
||||
return new SpanFactory()
|
||||
{
|
||||
MarkupTokenizerFactory = doc => new HtmlTokenizer(doc),
|
||||
CodeTokenizerFactory = doc => new CSharpTokenizer(doc)
|
||||
};
|
||||
}
|
||||
|
||||
public SpanFactory()
|
||||
{
|
||||
LocationTracker = new SourceLocationTracker();
|
||||
}
|
||||
|
||||
public SpanConstructor Span(SpanKind kind, string content, CSharpSymbolType type)
|
||||
{
|
||||
return CreateSymbolSpan(kind, content, st => new CSharpSymbol(st, content, type));
|
||||
}
|
||||
|
||||
public SpanConstructor Span(SpanKind kind, string content, HtmlSymbolType type)
|
||||
{
|
||||
return CreateSymbolSpan(kind, content, st => new HtmlSymbol(st, content, type));
|
||||
}
|
||||
|
||||
public SpanConstructor Span(SpanKind kind, string content, bool markup)
|
||||
{
|
||||
return new SpanConstructor(kind, Tokenize(new[] { content }, markup));
|
||||
}
|
||||
|
||||
public SpanConstructor Span(SpanKind kind, string[] content, bool markup)
|
||||
{
|
||||
return new SpanConstructor(kind, Tokenize(content, markup));
|
||||
}
|
||||
|
||||
public SpanConstructor Span(SpanKind kind, params ISymbol[] symbols)
|
||||
{
|
||||
return new SpanConstructor(kind, symbols);
|
||||
}
|
||||
|
||||
private SpanConstructor CreateSymbolSpan(SpanKind kind, string content, Func<SourceLocation, ISymbol> ctor)
|
||||
{
|
||||
var start = LocationTracker.CurrentLocation;
|
||||
LocationTracker.UpdateLocation(content);
|
||||
return new SpanConstructor(kind, new[] { ctor(start) });
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
LocationTracker.CurrentLocation = SourceLocation.Zero;
|
||||
}
|
||||
|
||||
private IEnumerable<ISymbol> Tokenize(IEnumerable<string> contentFragments, bool markup)
|
||||
{
|
||||
return contentFragments.SelectMany(fragment => Tokenize(fragment, markup));
|
||||
}
|
||||
|
||||
private IEnumerable<ISymbol> Tokenize(string content, bool markup)
|
||||
{
|
||||
var tok = MakeTokenizer(markup, new SeekableTextReader(content));
|
||||
ISymbol sym;
|
||||
ISymbol last = null;
|
||||
while ((sym = tok.NextSymbol()) != null)
|
||||
{
|
||||
OffsetStart(sym, LocationTracker.CurrentLocation);
|
||||
last = sym;
|
||||
yield return sym;
|
||||
}
|
||||
LocationTracker.UpdateLocation(content);
|
||||
}
|
||||
|
||||
private ITokenizer MakeTokenizer(bool markup, SeekableTextReader seekableTextReader)
|
||||
{
|
||||
if (markup)
|
||||
{
|
||||
return MarkupTokenizerFactory(seekableTextReader);
|
||||
}
|
||||
else
|
||||
{
|
||||
return CodeTokenizerFactory(seekableTextReader);
|
||||
}
|
||||
}
|
||||
|
||||
private void OffsetStart(ISymbol sym, SourceLocation sourceLocation)
|
||||
{
|
||||
sym.OffsetStart(sourceLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,126 +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 Microsoft.AspNetCore.Razor;
|
||||
using Microsoft.AspNetCore.Razor.Chunks.Generators;
|
||||
using Microsoft.AspNetCore.Razor.Parser;
|
||||
using Microsoft.AspNetCore.Razor.Parser.SyntaxTree;
|
||||
using Microsoft.AspNetCore.Razor.Text;
|
||||
using Microsoft.AspNetCore.Razor.Tokenizer.Symbols;
|
||||
using Microsoft.AspNetCore.Razor.Tokenizer.Symbols.Internal;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor
|
||||
{
|
||||
public static class SpanFactoryExtensions
|
||||
{
|
||||
public static UnclassifiedCodeSpanConstructor EmptyCSharp(this SpanFactory self)
|
||||
{
|
||||
var symbol = new CSharpSymbol(self.LocationTracker.CurrentLocation, string.Empty, CSharpSymbolType.Unknown);
|
||||
return new UnclassifiedCodeSpanConstructor(self.Span(SpanKind.Code, symbol));
|
||||
}
|
||||
|
||||
public static SpanConstructor EmptyHtml(this SpanFactory self)
|
||||
{
|
||||
var symbol = new HtmlSymbol(self.LocationTracker.CurrentLocation, string.Empty, HtmlSymbolType.Unknown);
|
||||
return self.Span(SpanKind.Markup, symbol)
|
||||
.With(new MarkupChunkGenerator());
|
||||
}
|
||||
|
||||
public static UnclassifiedCodeSpanConstructor Code(this SpanFactory self, string content)
|
||||
{
|
||||
return new UnclassifiedCodeSpanConstructor(
|
||||
self.Span(SpanKind.Code, content, markup: false));
|
||||
}
|
||||
|
||||
public static SpanConstructor CodeTransition(this SpanFactory self)
|
||||
{
|
||||
return self.Span(SpanKind.Transition, SyntaxConstants.TransitionString, markup: false)
|
||||
.Accepts(AcceptedCharacters.None);
|
||||
}
|
||||
|
||||
public static SpanConstructor CodeTransition(this SpanFactory self, string content)
|
||||
{
|
||||
return self.Span(SpanKind.Transition, content, markup: false).Accepts(AcceptedCharacters.None);
|
||||
}
|
||||
|
||||
public static SpanConstructor CodeTransition(this SpanFactory self, CSharpSymbolType type)
|
||||
{
|
||||
return self.Span(SpanKind.Transition, SyntaxConstants.TransitionString, type)
|
||||
.Accepts(AcceptedCharacters.None);
|
||||
}
|
||||
|
||||
public static SpanConstructor CodeTransition(this SpanFactory self, string content, CSharpSymbolType type)
|
||||
{
|
||||
return self.Span(SpanKind.Transition, content, type).Accepts(AcceptedCharacters.None);
|
||||
}
|
||||
|
||||
public static SpanConstructor MarkupTransition(this SpanFactory self)
|
||||
{
|
||||
return self.Span(SpanKind.Transition, SyntaxConstants.TransitionString, markup: true)
|
||||
.Accepts(AcceptedCharacters.None);
|
||||
}
|
||||
|
||||
public static SpanConstructor MarkupTransition(this SpanFactory self, string content)
|
||||
{
|
||||
return self.Span(SpanKind.Transition, content, markup: true).Accepts(AcceptedCharacters.None);
|
||||
}
|
||||
|
||||
public static SpanConstructor MarkupTransition(this SpanFactory self, HtmlSymbolType type)
|
||||
{
|
||||
return self.Span(SpanKind.Transition, SyntaxConstants.TransitionString, type)
|
||||
.Accepts(AcceptedCharacters.None);
|
||||
}
|
||||
|
||||
public static SpanConstructor MarkupTransition(this SpanFactory self, string content, HtmlSymbolType type)
|
||||
{
|
||||
return self.Span(SpanKind.Transition, content, type).Accepts(AcceptedCharacters.None);
|
||||
}
|
||||
|
||||
public static SpanConstructor MetaCode(this SpanFactory self, string content)
|
||||
{
|
||||
return self.Span(SpanKind.MetaCode, content, markup: false);
|
||||
}
|
||||
|
||||
public static SpanConstructor MetaCode(this SpanFactory self, string content, CSharpSymbolType type)
|
||||
{
|
||||
return self.Span(SpanKind.MetaCode, content, type);
|
||||
}
|
||||
|
||||
public static SpanConstructor MetaMarkup(this SpanFactory self, string content)
|
||||
{
|
||||
return self.Span(SpanKind.MetaCode, content, markup: true);
|
||||
}
|
||||
|
||||
public static SpanConstructor MetaMarkup(this SpanFactory self, string content, HtmlSymbolType type)
|
||||
{
|
||||
return self.Span(SpanKind.MetaCode, content, type);
|
||||
}
|
||||
|
||||
public static SpanConstructor Comment(this SpanFactory self, string content, CSharpSymbolType type)
|
||||
{
|
||||
return self.Span(SpanKind.Comment, content, type);
|
||||
}
|
||||
|
||||
public static SpanConstructor Comment(this SpanFactory self, string content, HtmlSymbolType type)
|
||||
{
|
||||
return self.Span(SpanKind.Comment, content, type);
|
||||
}
|
||||
|
||||
public static SpanConstructor Markup(this SpanFactory self, string content)
|
||||
{
|
||||
return self.Span(SpanKind.Markup, content, markup: true).With(new MarkupChunkGenerator());
|
||||
}
|
||||
|
||||
public static SpanConstructor Markup(this SpanFactory self, params string[] content)
|
||||
{
|
||||
return self.Span(SpanKind.Markup, content, markup: true).With(new MarkupChunkGenerator());
|
||||
}
|
||||
|
||||
public static SourceLocation GetLocationAndAdvance(this SourceLocationTracker self, string content)
|
||||
{
|
||||
var ret = self.CurrentLocation;
|
||||
self.UpdateLocation(content);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,22 +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 Microsoft.AspNetCore.Razor.Chunks.Generators;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor
|
||||
{
|
||||
public class UnclassifiedCodeSpanConstructor
|
||||
{
|
||||
private readonly SpanConstructor _self;
|
||||
|
||||
public UnclassifiedCodeSpanConstructor(SpanConstructor self)
|
||||
{
|
||||
_self = self;
|
||||
}
|
||||
|
||||
public SpanConstructor As(ISpanChunkGenerator codeGenerator)
|
||||
{
|
||||
return _self.With(codeGenerator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -26,7 +26,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Test.DependencyInjection
|
|||
.ConfigureApplicationPartManager(manager =>
|
||||
{
|
||||
manager.ApplicationParts.Add(new TestApplicationPart());
|
||||
manager.FeatureProviders.Add(new TagHelperFeatureProvider());
|
||||
});
|
||||
|
||||
// Act
|
||||
|
|
@ -35,9 +34,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Test.DependencyInjection
|
|||
// Assert
|
||||
var activatorDescriptor = Assert.Single(services.ToList(), d => d.ServiceType == typeof(ITagHelperActivator));
|
||||
Assert.Equal(typeof(ServiceBasedTagHelperActivator), activatorDescriptor.ImplementationType);
|
||||
|
||||
var resolverDescriptor = Assert.Single(services.ToList(), d => d.ServiceType == typeof(ITagHelperTypeResolver));
|
||||
Assert.Equal(typeof(FeatureTagHelperTypeResolver), resolverDescriptor.ImplementationType);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -60,9 +56,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Test.DependencyInjection
|
|||
|
||||
// Assert
|
||||
var collection = services.ToList();
|
||||
Assert.Equal(4, collection.Count);
|
||||
Assert.Equal(3, collection.Count);
|
||||
|
||||
var tagHelperOne = Assert.Single(collection,t => t.ServiceType == typeof(TestTagHelperOne));
|
||||
var tagHelperOne = Assert.Single(collection, t => t.ServiceType == typeof(TestTagHelperOne));
|
||||
Assert.Equal(typeof(TestTagHelperOne), tagHelperOne.ImplementationType);
|
||||
Assert.Equal(ServiceLifetime.Transient, tagHelperOne.Lifetime);
|
||||
|
||||
|
|
@ -73,10 +69,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Test.DependencyInjection
|
|||
var activator = Assert.Single(collection, t => t.ServiceType == typeof(ITagHelperActivator));
|
||||
Assert.Equal(typeof(ServiceBasedTagHelperActivator), activator.ImplementationType);
|
||||
Assert.Equal(ServiceLifetime.Transient, activator.Lifetime);
|
||||
|
||||
var typeResolver = Assert.Single(collection, t => t.ServiceType == typeof(ITagHelperTypeResolver));
|
||||
Assert.Equal(typeof(FeatureTagHelperTypeResolver), typeResolver.ImplementationType);
|
||||
Assert.Equal(ServiceLifetime.Transient, typeResolver.Lifetime);
|
||||
}
|
||||
|
||||
private class TestTagHelperOne : TagHelper
|
||||
|
|
|
|||
|
|
@ -115,7 +115,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Test.DependencyInjection
|
|||
.ConfigureApplicationPartManager(manager =>
|
||||
{
|
||||
manager.ApplicationParts.Add(new TestApplicationPart());
|
||||
manager.FeatureProviders.Add(new TagHelperFeatureProvider());
|
||||
});
|
||||
|
||||
// Act
|
||||
|
|
@ -124,9 +123,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Test.DependencyInjection
|
|||
// Assert
|
||||
var activatorDescriptor = Assert.Single(services.ToList(), d => d.ServiceType == typeof(ITagHelperActivator));
|
||||
Assert.Equal(typeof(ServiceBasedTagHelperActivator), activatorDescriptor.ImplementationType);
|
||||
|
||||
var resolverDescriptor = Assert.Single(services.ToList(), d => d.ServiceType == typeof(ITagHelperTypeResolver));
|
||||
Assert.Equal(typeof(FeatureTagHelperTypeResolver), resolverDescriptor.ImplementationType);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -149,7 +145,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Test.DependencyInjection
|
|||
|
||||
// Assert
|
||||
var collection = services.ToList();
|
||||
Assert.Equal(4, collection.Count);
|
||||
Assert.Equal(3, collection.Count);
|
||||
|
||||
var tagHelperOne = Assert.Single(collection, t => t.ServiceType == typeof(TestTagHelperOne));
|
||||
Assert.Equal(typeof(TestTagHelperOne), tagHelperOne.ImplementationType);
|
||||
|
|
@ -162,10 +158,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Test.DependencyInjection
|
|||
var activator = Assert.Single(collection, t => t.ServiceType == typeof(ITagHelperActivator));
|
||||
Assert.Equal(typeof(ServiceBasedTagHelperActivator), activator.ImplementationType);
|
||||
Assert.Equal(ServiceLifetime.Transient, activator.Lifetime);
|
||||
|
||||
var typeResolver = Assert.Single(collection, t => t.ServiceType == typeof(ITagHelperTypeResolver));
|
||||
Assert.Equal(typeof(FeatureTagHelperTypeResolver), typeResolver.ImplementationType);
|
||||
Assert.Equal(ServiceLifetime.Transient, typeResolver.Lifetime);
|
||||
}
|
||||
|
||||
private class TestTagHelperOne : TagHelper
|
||||
|
|
|
|||
|
|
@ -1,368 +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.AspNetCore.Mvc.Razor.Host;
|
||||
using Microsoft.AspNetCore.Mvc.Razor.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ViewComponents;
|
||||
using Microsoft.AspNetCore.Razor.Compilation.TagHelpers;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers.Testing;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.Test.Internal
|
||||
{
|
||||
public class ViewComponentTagHelperDescriptorFactoryTest
|
||||
{
|
||||
public static TheoryData AssemblyData
|
||||
{
|
||||
get
|
||||
{
|
||||
var provider = new TestViewComponentDescriptorProvider();
|
||||
|
||||
var assemblyOne = "Microsoft.AspNetCore.Mvc.Razor";
|
||||
var assemblyTwo = "Microsoft.AspNetCore.Mvc.Razor.Test";
|
||||
var assemblyNone = string.Empty;
|
||||
|
||||
return new TheoryData<string, IEnumerable<TagHelperDescriptor>>
|
||||
{
|
||||
{ assemblyOne, new [] { provider.GetTagHelperDescriptorOne() } },
|
||||
{ assemblyTwo, new [] { provider.GetTagHelperDescriptorTwo(), provider.GetTagHelperDescriptorGeneric() } },
|
||||
{ assemblyNone, Enumerable.Empty<TagHelperDescriptor>() }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(AssemblyData))]
|
||||
public void CreateDescriptors_ReturnsCorrectDescriptors(
|
||||
string assemblyName,
|
||||
IEnumerable<TagHelperDescriptor> expectedDescriptors)
|
||||
{
|
||||
// Arrange
|
||||
var provider = new TestViewComponentDescriptorProvider();
|
||||
var factory = new ViewComponentTagHelperDescriptorFactory(provider);
|
||||
|
||||
// Act
|
||||
var descriptors = factory.CreateDescriptors(assemblyName);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedDescriptors, descriptors, CaseSensitiveTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
public static TheoryData TypeData
|
||||
{
|
||||
get
|
||||
{
|
||||
var refParamType = typeof(ViewComponentTagHelperDescriptorFactoryTest).GetMethod("MethodWithRefParam").GetParameters().First().ParameterType;
|
||||
|
||||
return new TheoryData<Type, string>
|
||||
{
|
||||
{ typeof(string), "System.String" },
|
||||
{ typeof(string[,]), "System.String[,]" },
|
||||
{ typeof(List<int*[]>), "System.Collections.Generic.List<global::System.Int32*[]>" },
|
||||
{ typeof(List<string[,,]>), "System.Collections.Generic.List<global::System.String[,,]>" },
|
||||
{ typeof(Dictionary<string[], List<string>>),
|
||||
"System.Collections.Generic.Dictionary<global::System.String[], global::System.Collections.Generic.List<global::System.String>>" },
|
||||
{ typeof(Dictionary<string, List<string[,]>>),
|
||||
"System.Collections.Generic.Dictionary<global::System.String, global::System.Collections.Generic.List<global::System.String[,]>>" },
|
||||
{ refParamType, "System.String[]" },
|
||||
{ typeof(NonGeneric.Nested1<bool, string>.Nested2),
|
||||
"Microsoft.AspNetCore.Mvc.Razor.Test.Internal.ViewComponentTagHelperDescriptorFactoryTest.NonGeneric.Nested1<global::System.Boolean, global::System.String>.Nested2" },
|
||||
{ typeof(GenericType<string, int>.GenericNestedType<bool, string>),
|
||||
"Microsoft.AspNetCore.Mvc.Razor.Test.Internal.ViewComponentTagHelperDescriptorFactoryTest.GenericType<global::System.String, global::System.Int32>.GenericNestedType<global::System.Boolean, global::System.String>" },
|
||||
{ typeof(GenericType<string, int>.NonGenericNested.MultiNestedType<bool, string>),
|
||||
"Microsoft.AspNetCore.Mvc.Razor.Test.Internal.ViewComponentTagHelperDescriptorFactoryTest.GenericType<global::System.String, global::System.Int32>.NonGenericNested.MultiNestedType<global::System.Boolean, global::System.String>" },
|
||||
{ typeof(Dictionary<GenericType<string, int>.NonGenericNested.MultiNestedType<bool, string>, List<string[]>>),
|
||||
"System.Collections.Generic.Dictionary<global::Microsoft.AspNetCore.Mvc.Razor.Test.Internal.ViewComponentTagHelperDescriptorFactoryTest.GenericType<global::System.String, global::System.Int32>.NonGenericNested.MultiNestedType<global::System.Boolean, global::System.String>, global::System.Collections.Generic.List<global::System.String[]>>" },
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(TypeData))]
|
||||
public void GetCSharpTypeName_ReturnsCorrectTypeNames(Type type, string expected)
|
||||
{
|
||||
// Act
|
||||
var typeName = ViewComponentTagHelperDescriptorFactory.GetCSharpTypeName(type);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, typeName);
|
||||
}
|
||||
|
||||
// Separated from GetCSharpTypeName_ReturnsCorrectTypeNames to work around problems serializing and
|
||||
// deserializing this ref type.
|
||||
[Fact]
|
||||
public void GetCSharpTypeName_ReturnsCorrectTypeNames_ForOutParameter()
|
||||
{
|
||||
// Arrange
|
||||
var type = typeof(ViewComponentTagHelperDescriptorFactoryTest).GetMethod("MethodWithOutParam").GetParameters().First().ParameterType;
|
||||
var expected = "System.Collections.Generic.List<global::System.Char*[]>";
|
||||
|
||||
// Act
|
||||
var typeName = ViewComponentTagHelperDescriptorFactory.GetCSharpTypeName(type);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, typeName);
|
||||
}
|
||||
|
||||
// Test invokes are needed for method creation in TestViewComponentDescriptorProvider.
|
||||
public enum TestEnum
|
||||
{
|
||||
A = 1,
|
||||
B = 2,
|
||||
C = 3
|
||||
}
|
||||
|
||||
public void TestInvokeOne(string foo, string bar)
|
||||
{
|
||||
}
|
||||
|
||||
public void TestInvokeTwo(TestEnum testEnum, string testString, int baz = 5)
|
||||
{
|
||||
}
|
||||
|
||||
public void InvokeWithGenericParams(List<string> Foo, Dictionary<string, int> Bar)
|
||||
{
|
||||
}
|
||||
|
||||
public void InvokeWithOpenGeneric<T>(List<T> baz)
|
||||
{
|
||||
}
|
||||
|
||||
private class TestViewComponentDescriptorProvider : IViewComponentDescriptorProvider
|
||||
{
|
||||
private readonly ViewComponentDescriptor _viewComponentDescriptorOne = new ViewComponentDescriptor
|
||||
{
|
||||
DisplayName = "OneDisplayName",
|
||||
FullName = "OneViewComponent",
|
||||
ShortName = "One",
|
||||
MethodInfo = typeof(ViewComponentTagHelperDescriptorFactoryTest)
|
||||
.GetMethod(nameof(ViewComponentTagHelperDescriptorFactoryTest.TestInvokeOne)),
|
||||
TypeInfo = typeof(ViewComponentTagHelperDescriptorFactory).GetTypeInfo(),
|
||||
Parameters = typeof(ViewComponentTagHelperDescriptorFactoryTest)
|
||||
.GetMethod(nameof(ViewComponentTagHelperDescriptorFactoryTest.TestInvokeOne)).GetParameters()
|
||||
};
|
||||
|
||||
private readonly ViewComponentDescriptor _viewComponentDescriptorTwo = new ViewComponentDescriptor
|
||||
{
|
||||
DisplayName = "TwoDisplayName",
|
||||
FullName = "TwoViewComponent",
|
||||
ShortName = "Two",
|
||||
MethodInfo = typeof(ViewComponentTagHelperDescriptorFactoryTest)
|
||||
.GetMethod(nameof(ViewComponentTagHelperDescriptorFactoryTest.TestInvokeTwo)),
|
||||
TypeInfo = typeof(ViewComponentTagHelperDescriptorFactoryTest).GetTypeInfo(),
|
||||
Parameters = typeof(ViewComponentTagHelperDescriptorFactoryTest)
|
||||
.GetMethod(nameof(ViewComponentTagHelperDescriptorFactoryTest.TestInvokeTwo)).GetParameters()
|
||||
};
|
||||
|
||||
private readonly ViewComponentDescriptor _viewComponentDescriptorGeneric = new ViewComponentDescriptor
|
||||
{
|
||||
DisplayName = "GenericDisplayName",
|
||||
FullName = "GenericViewComponent",
|
||||
ShortName = "Generic",
|
||||
MethodInfo = typeof(ViewComponentTagHelperDescriptorFactoryTest)
|
||||
.GetMethod(nameof(ViewComponentTagHelperDescriptorFactoryTest.InvokeWithGenericParams)),
|
||||
TypeInfo = typeof(ViewComponentTagHelperDescriptorFactoryTest).GetTypeInfo(),
|
||||
Parameters = typeof(ViewComponentTagHelperDescriptorFactoryTest)
|
||||
.GetMethod(nameof(ViewComponentTagHelperDescriptorFactoryTest.InvokeWithGenericParams)).GetParameters()
|
||||
};
|
||||
|
||||
private readonly ViewComponentDescriptor _viewComponentDescriptorOpenGeneric = new ViewComponentDescriptor
|
||||
{
|
||||
DisplayName = "OpenGenericDisplayName",
|
||||
FullName = "OpenGenericViewComponent",
|
||||
ShortName = "OpenGeneric",
|
||||
MethodInfo = typeof(ViewComponentTagHelperDescriptorFactoryTest)
|
||||
.GetMethod(nameof(ViewComponentTagHelperDescriptorFactoryTest.InvokeWithOpenGeneric)),
|
||||
TypeInfo = typeof(ViewComponentTagHelperDescriptorFactoryTest).GetTypeInfo(),
|
||||
Parameters = typeof(ViewComponentTagHelperDescriptorFactoryTest)
|
||||
.GetMethod(nameof(ViewComponentTagHelperDescriptorFactoryTest.InvokeWithOpenGeneric)).GetParameters()
|
||||
};
|
||||
|
||||
public TagHelperDescriptor GetTagHelperDescriptorOne()
|
||||
{
|
||||
var descriptor = new TagHelperDescriptor
|
||||
{
|
||||
TagName = "vc:one",
|
||||
TypeName = "__Generated__OneViewComponentTagHelper",
|
||||
AssemblyName = "Microsoft.AspNetCore.Mvc.Razor",
|
||||
Attributes = new List<TagHelperAttributeDescriptor>
|
||||
{
|
||||
new TagHelperAttributeDescriptor
|
||||
{
|
||||
Name = "foo",
|
||||
PropertyName = "foo",
|
||||
TypeName = typeof(string).FullName
|
||||
},
|
||||
new TagHelperAttributeDescriptor
|
||||
{
|
||||
Name = "bar",
|
||||
PropertyName = "bar",
|
||||
TypeName = typeof(string).FullName
|
||||
}
|
||||
},
|
||||
RequiredAttributes = new List<TagHelperRequiredAttributeDescriptor>
|
||||
{
|
||||
new TagHelperRequiredAttributeDescriptor
|
||||
{
|
||||
Name = "foo"
|
||||
},
|
||||
new TagHelperRequiredAttributeDescriptor
|
||||
{
|
||||
Name = "bar"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
descriptor.PropertyBag.Add(ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey, "One");
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
public TagHelperDescriptor GetTagHelperDescriptorTwo()
|
||||
{
|
||||
var descriptor = new TagHelperDescriptor
|
||||
{
|
||||
TagName = "vc:two",
|
||||
TypeName = "__Generated__TwoViewComponentTagHelper",
|
||||
AssemblyName = "Microsoft.AspNetCore.Mvc.Razor.Test",
|
||||
Attributes = new List<TagHelperAttributeDescriptor>
|
||||
{
|
||||
new TagHelperAttributeDescriptor
|
||||
{
|
||||
Name = "test-enum",
|
||||
PropertyName = "testEnum",
|
||||
TypeName = ViewComponentTagHelperDescriptorFactory.GetCSharpTypeName(typeof(TestEnum)),
|
||||
IsEnum = true
|
||||
},
|
||||
|
||||
new TagHelperAttributeDescriptor
|
||||
{
|
||||
Name = "test-string",
|
||||
PropertyName = "testString",
|
||||
TypeName = typeof(string).FullName
|
||||
},
|
||||
|
||||
new TagHelperAttributeDescriptor
|
||||
{
|
||||
Name = "baz",
|
||||
PropertyName = "baz",
|
||||
TypeName = typeof(int).FullName
|
||||
}
|
||||
},
|
||||
RequiredAttributes = new List<TagHelperRequiredAttributeDescriptor>
|
||||
{
|
||||
new TagHelperRequiredAttributeDescriptor
|
||||
{
|
||||
Name = "test-enum"
|
||||
},
|
||||
|
||||
new TagHelperRequiredAttributeDescriptor
|
||||
{
|
||||
Name = "test-string"
|
||||
},
|
||||
|
||||
new TagHelperRequiredAttributeDescriptor
|
||||
{
|
||||
Name = "baz"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
descriptor.PropertyBag.Add(ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey, "Two");
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
public TagHelperDescriptor GetTagHelperDescriptorGeneric()
|
||||
{
|
||||
var descriptor = new TagHelperDescriptor
|
||||
{
|
||||
TagName = "vc:generic",
|
||||
TypeName = "__Generated__GenericViewComponentTagHelper",
|
||||
AssemblyName = "Microsoft.AspNetCore.Mvc.Razor.Test",
|
||||
Attributes = new List<TagHelperAttributeDescriptor>
|
||||
{
|
||||
new TagHelperAttributeDescriptor
|
||||
{
|
||||
Name = "foo",
|
||||
PropertyName = "Foo",
|
||||
TypeName = ViewComponentTagHelperDescriptorFactory.GetCSharpTypeName(typeof(List<string>))
|
||||
},
|
||||
|
||||
new TagHelperAttributeDescriptor
|
||||
{
|
||||
Name = "bar",
|
||||
PropertyName = "Bar",
|
||||
TypeName = ViewComponentTagHelperDescriptorFactory.GetCSharpTypeName(typeof(Dictionary<string, int>))
|
||||
},
|
||||
|
||||
new TagHelperAttributeDescriptor
|
||||
{
|
||||
Name = "bar-",
|
||||
PropertyName = "Bar",
|
||||
TypeName = typeof(int).FullName,
|
||||
IsIndexer = true
|
||||
}
|
||||
},
|
||||
RequiredAttributes = new List<TagHelperRequiredAttributeDescriptor>
|
||||
{
|
||||
new TagHelperRequiredAttributeDescriptor
|
||||
{
|
||||
Name = "foo"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
descriptor.PropertyBag.Add(ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey, "Generic");
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
public IEnumerable<ViewComponentDescriptor> GetViewComponents()
|
||||
{
|
||||
return new List<ViewComponentDescriptor>
|
||||
{
|
||||
_viewComponentDescriptorOne,
|
||||
_viewComponentDescriptorTwo,
|
||||
_viewComponentDescriptorGeneric,
|
||||
_viewComponentDescriptorOpenGeneric
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public void MethodWithOutParam(out List<char*[]> foo)
|
||||
{
|
||||
foo = null;
|
||||
}
|
||||
|
||||
public void MethodWithRefParam(ref string[] bar)
|
||||
{
|
||||
}
|
||||
|
||||
private class GenericType<T1, T2>
|
||||
{
|
||||
public class GenericNestedType<T3, T4>
|
||||
{
|
||||
}
|
||||
|
||||
public class NonGenericNested
|
||||
{
|
||||
public class MultiNestedType<T5, T6>
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class NonGeneric
|
||||
{
|
||||
public class Nested1<T1, T2>
|
||||
{
|
||||
public class Nested2
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,248 +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.Globalization;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Razor;
|
||||
using Microsoft.AspNetCore.Razor.Chunks.Generators;
|
||||
using Microsoft.AspNetCore.Razor.Editor;
|
||||
using Microsoft.AspNetCore.Razor.Parser.SyntaxTree;
|
||||
using Microsoft.AspNetCore.Razor.Text;
|
||||
using Microsoft.AspNetCore.Razor.Tokenizer;
|
||||
using Microsoft.AspNetCore.Razor.Tokenizer.Internal;
|
||||
using Microsoft.AspNetCore.Razor.Tokenizer.Symbols;
|
||||
using Microsoft.AspNetCore.Razor.Tokenizer.Symbols.Internal;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.Host.Test
|
||||
{
|
||||
public static class SpanFactoryExtensions
|
||||
{
|
||||
public static SpanConstructor EmptyHtml(this SpanFactory self)
|
||||
{
|
||||
return self.Span(SpanKind.Markup, new HtmlSymbol(self.LocationTracker.CurrentLocation, String.Empty, HtmlSymbolType.Unknown))
|
||||
.With(new MarkupChunkGenerator());
|
||||
}
|
||||
|
||||
public static UnclassifiedCodeSpanConstructor Code(this SpanFactory self, string content)
|
||||
{
|
||||
return new UnclassifiedCodeSpanConstructor(
|
||||
self.Span(SpanKind.Code, content, markup: false));
|
||||
}
|
||||
|
||||
public static SpanConstructor CodeTransition(this SpanFactory self, string content)
|
||||
{
|
||||
return self.Span(SpanKind.Transition, content, markup: false).Accepts(AcceptedCharacters.None);
|
||||
}
|
||||
|
||||
public static SpanConstructor MetaCode(this SpanFactory self, string content)
|
||||
{
|
||||
return self.Span(SpanKind.MetaCode, content, markup: false);
|
||||
}
|
||||
public static SpanConstructor Markup(this SpanFactory self, string content)
|
||||
{
|
||||
return self.Span(SpanKind.Markup, content, markup: true).With(new MarkupChunkGenerator());
|
||||
}
|
||||
}
|
||||
|
||||
public class SpanFactory
|
||||
{
|
||||
public Func<ITextDocument, ITokenizer> MarkupTokenizerFactory { get; set; }
|
||||
public Func<ITextDocument, ITokenizer> CodeTokenizerFactory { get; set; }
|
||||
public SourceLocationTracker LocationTracker { get; private set; }
|
||||
|
||||
public static SpanFactory CreateCsHtml()
|
||||
{
|
||||
return new SpanFactory()
|
||||
{
|
||||
MarkupTokenizerFactory = doc => new HtmlTokenizer(doc),
|
||||
CodeTokenizerFactory = doc => new CSharpTokenizer(doc)
|
||||
};
|
||||
}
|
||||
|
||||
public SpanFactory()
|
||||
{
|
||||
LocationTracker = new SourceLocationTracker();
|
||||
}
|
||||
|
||||
|
||||
public SpanConstructor Span(SpanKind kind, string content, bool markup)
|
||||
{
|
||||
return new SpanConstructor(kind, Tokenize(new[] { content }, markup));
|
||||
}
|
||||
|
||||
public SpanConstructor Span(SpanKind kind, params ISymbol[] symbols)
|
||||
{
|
||||
return new SpanConstructor(kind, symbols);
|
||||
}
|
||||
|
||||
private IEnumerable<ISymbol> Tokenize(IEnumerable<string> contentFragments, bool markup)
|
||||
{
|
||||
return contentFragments.SelectMany(fragment => Tokenize(fragment, markup));
|
||||
}
|
||||
|
||||
private IEnumerable<ISymbol> Tokenize(string content, bool markup)
|
||||
{
|
||||
ITokenizer tok = MakeTokenizer(markup, new SeekableTextReader(content));
|
||||
ISymbol sym;
|
||||
ISymbol last = null;
|
||||
while ((sym = tok.NextSymbol()) != null)
|
||||
{
|
||||
OffsetStart(sym, LocationTracker.CurrentLocation);
|
||||
last = sym;
|
||||
yield return sym;
|
||||
}
|
||||
LocationTracker.UpdateLocation(content);
|
||||
}
|
||||
|
||||
private ITokenizer MakeTokenizer(bool markup, SeekableTextReader seekableTextReader)
|
||||
{
|
||||
if (markup)
|
||||
{
|
||||
return MarkupTokenizerFactory(seekableTextReader);
|
||||
}
|
||||
else
|
||||
{
|
||||
return CodeTokenizerFactory(seekableTextReader);
|
||||
}
|
||||
}
|
||||
|
||||
private void OffsetStart(ISymbol sym, SourceLocation sourceLocation)
|
||||
{
|
||||
sym.OffsetStart(sourceLocation);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SpanConstructorExtensions
|
||||
{
|
||||
public static SpanConstructor Accepts(this SpanConstructor self, AcceptedCharacters accepted)
|
||||
{
|
||||
return self.With(eh => eh.AcceptedCharacters = accepted);
|
||||
}
|
||||
}
|
||||
|
||||
public class UnclassifiedCodeSpanConstructor
|
||||
{
|
||||
SpanConstructor _self;
|
||||
|
||||
public UnclassifiedCodeSpanConstructor(SpanConstructor self)
|
||||
{
|
||||
_self = self;
|
||||
}
|
||||
|
||||
public SpanConstructor As(ISpanChunkGenerator codeGenerator)
|
||||
{
|
||||
return _self.With(codeGenerator);
|
||||
}
|
||||
}
|
||||
|
||||
public class SpanConstructor
|
||||
{
|
||||
public SpanBuilder Builder { get; private set; }
|
||||
|
||||
internal static IEnumerable<ISymbol> TestTokenizer(string str)
|
||||
{
|
||||
yield return new RawTextSymbol(SourceLocation.Zero, str);
|
||||
}
|
||||
|
||||
public SpanConstructor(SpanKind kind, IEnumerable<ISymbol> symbols)
|
||||
{
|
||||
Builder = new SpanBuilder();
|
||||
Builder.Kind = kind;
|
||||
Builder.EditHandler = SpanEditHandler.CreateDefault(TestTokenizer);
|
||||
foreach (ISymbol sym in symbols)
|
||||
{
|
||||
Builder.Accept(sym);
|
||||
}
|
||||
}
|
||||
|
||||
private Span Build()
|
||||
{
|
||||
return Builder.Build();
|
||||
}
|
||||
|
||||
public SpanConstructor With(ISpanChunkGenerator generator)
|
||||
{
|
||||
Builder.ChunkGenerator = generator;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SpanConstructor With(SpanEditHandler handler)
|
||||
{
|
||||
Builder.EditHandler = handler;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SpanConstructor With(Action<SpanEditHandler> handlerConfigurer)
|
||||
{
|
||||
handlerConfigurer(Builder.EditHandler);
|
||||
return this;
|
||||
}
|
||||
|
||||
public static implicit operator Span(SpanConstructor self)
|
||||
{
|
||||
return self.Build();
|
||||
}
|
||||
}
|
||||
|
||||
internal class RawTextSymbol : ISymbol
|
||||
{
|
||||
public SourceLocation Start { get; private set; }
|
||||
public string Content { get; private set; }
|
||||
|
||||
public RawTextSymbol(SourceLocation start, string content)
|
||||
{
|
||||
if (content == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(content));
|
||||
}
|
||||
|
||||
Start = start;
|
||||
Content = content;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
RawTextSymbol other = obj as RawTextSymbol;
|
||||
return Equals(Start, other.Start) && Equals(Content, other.Content);
|
||||
}
|
||||
|
||||
internal bool EquivalentTo(ISymbol sym)
|
||||
{
|
||||
return Equals(Start, sym.Start) && Equals(Content, sym.Content);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Start.GetHashCode();
|
||||
}
|
||||
|
||||
public void OffsetStart(SourceLocation documentStart)
|
||||
{
|
||||
Start = documentStart + Start;
|
||||
}
|
||||
|
||||
public void ChangeStart(SourceLocation newStart)
|
||||
{
|
||||
Start = newStart;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format(CultureInfo.InvariantCulture, "{0} RAW - [{1}]", Start, Content);
|
||||
}
|
||||
|
||||
internal void CalculateStart(Span prev)
|
||||
{
|
||||
if (prev == null)
|
||||
{
|
||||
Start = SourceLocation.Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
Start = new SourceLocationTracker(prev.Start).UpdateLocation(prev.Content).CurrentLocation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,99 +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.AspNetCore.Mvc.ApplicationParts;
|
||||
using Microsoft.AspNetCore.Mvc.TagHelpers;
|
||||
using Microsoft.AspNetCore.Razor;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.TagHelpers
|
||||
{
|
||||
public class FeatureTagHelperTypeResolverTest
|
||||
{
|
||||
[Fact]
|
||||
public void Resolve_ReturnsTagHelpers_FromApplicationParts()
|
||||
{
|
||||
// Arrange
|
||||
var manager = new ApplicationPartManager();
|
||||
var types = new[] { typeof(TestTagHelper) };
|
||||
manager.ApplicationParts.Add(new TestApplicationPart(types));
|
||||
manager.FeatureProviders.Add(new TestFeatureProvider());
|
||||
|
||||
var resolver = new FeatureTagHelperTypeResolver(manager);
|
||||
|
||||
var assemblyName = typeof(FeatureTagHelperTypeResolverTest).GetTypeInfo().Assembly.GetName().Name;
|
||||
|
||||
// Act
|
||||
var result = resolver.Resolve(assemblyName, SourceLocation.Undefined, new ErrorSink());
|
||||
|
||||
// Assert
|
||||
var type = Assert.Single(result);
|
||||
Assert.Equal(typeof(TestTagHelper), type);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Resolve_ReturnsTagHelpers_FilteredByAssembly()
|
||||
{
|
||||
// Arrange
|
||||
var manager = new ApplicationPartManager();
|
||||
var types = new[] { typeof(TestTagHelper) };
|
||||
manager.ApplicationParts.Add(new AssemblyPart(typeof(InputTagHelper).GetTypeInfo().Assembly));
|
||||
manager.ApplicationParts.Add(new TestApplicationPart(types));
|
||||
manager.FeatureProviders.Add(new TestFeatureProvider());
|
||||
|
||||
var resolver = new FeatureTagHelperTypeResolver(manager);
|
||||
|
||||
var assemblyName = typeof(FeatureTagHelperTypeResolverTest).GetTypeInfo().Assembly.GetName().Name;
|
||||
|
||||
// Act
|
||||
var result = resolver.Resolve(assemblyName, SourceLocation.Undefined, new ErrorSink());
|
||||
|
||||
// Assert
|
||||
var type = Assert.Single(result);
|
||||
Assert.Equal(typeof(TestTagHelper), type);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Resolve_ReturnsEmptyTypesList_IfAssemblyLoadFails()
|
||||
{
|
||||
// Arrange
|
||||
var manager = new ApplicationPartManager();
|
||||
var types = new[] { typeof(TestTagHelper) };
|
||||
manager.ApplicationParts.Add(new AssemblyPart(typeof(InputTagHelper).GetTypeInfo().Assembly));
|
||||
manager.ApplicationParts.Add(new TestApplicationPart(types));
|
||||
manager.FeatureProviders.Add(new TestFeatureProvider());
|
||||
|
||||
var resolver = new FeatureTagHelperTypeResolver(manager);
|
||||
|
||||
// Act
|
||||
var result = resolver.Resolve("UnknownAssembly", SourceLocation.Undefined, new ErrorSink());
|
||||
|
||||
// Assert
|
||||
Assert.Empty(result);
|
||||
}
|
||||
|
||||
private class TestFeatureProvider : IApplicationFeatureProvider<TagHelperFeature>
|
||||
{
|
||||
public void PopulateFeature(IEnumerable<ApplicationPart> parts, TagHelperFeature feature)
|
||||
{
|
||||
foreach (var type in parts.OfType<IApplicationPartTypeProvider>().SelectMany(tp => tp.Types))
|
||||
{
|
||||
feature.TagHelpers.Add(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class TestTagHelper : TagHelper
|
||||
{
|
||||
}
|
||||
|
||||
private class NotInPartsTagHelper : TagHelper
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,87 +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.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
|
||||
using Microsoft.AspNetCore.Mvc.Razor.TagHelpers.TagHelperFeatureProviderTests;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.TagHelpers
|
||||
{
|
||||
public class TagHelperFeatureProviderTest
|
||||
{
|
||||
[Fact]
|
||||
public void Populate_IncludesTagHelpers()
|
||||
{
|
||||
// Arrange
|
||||
var manager = new ApplicationPartManager();
|
||||
manager.ApplicationParts.Add(new TestApplicationPart(typeof(DiscoveryTagHelper)));
|
||||
manager.FeatureProviders.Add(new TagHelperFeatureProvider());
|
||||
|
||||
var feature = new TagHelperFeature();
|
||||
|
||||
// Act
|
||||
manager.PopulateFeature(feature);
|
||||
|
||||
// Assert
|
||||
var tagHelperType = Assert.Single(feature.TagHelpers, th => th == typeof(DiscoveryTagHelper).GetTypeInfo());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Populate_DoesNotIncludeDuplicateTagHelpers()
|
||||
{
|
||||
// Arrange
|
||||
var manager = new ApplicationPartManager();
|
||||
manager.ApplicationParts.Add(new TestApplicationPart(typeof(DiscoveryTagHelper)));
|
||||
manager.ApplicationParts.Add(new TestApplicationPart(typeof(DiscoveryTagHelper)));
|
||||
manager.FeatureProviders.Add(new TagHelperFeatureProvider());
|
||||
|
||||
var feature = new TagHelperFeature();
|
||||
|
||||
// Act
|
||||
manager.PopulateFeature(feature);
|
||||
|
||||
// Assert
|
||||
var tagHelperType = Assert.Single(feature.TagHelpers, th => th == typeof(DiscoveryTagHelper).GetTypeInfo());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Populate_OnlyRunsOnPartsThatExportTypes()
|
||||
{
|
||||
// Arrange
|
||||
var manager = new ApplicationPartManager();
|
||||
manager.ApplicationParts.Add(new TestApplicationPart(typeof(DiscoveryTagHelper)));
|
||||
manager.ApplicationParts.Add(new NonApplicationTypeProviderPart());
|
||||
manager.FeatureProviders.Add(new TagHelperFeatureProvider());
|
||||
|
||||
var feature = new TagHelperFeature();
|
||||
|
||||
// Act
|
||||
manager.PopulateFeature(feature);
|
||||
|
||||
// Assert
|
||||
var tagHelperType = Assert.Single(feature.TagHelpers, th => th == typeof(DiscoveryTagHelper).GetTypeInfo());
|
||||
}
|
||||
|
||||
private class NonApplicationTypeProviderPart : ApplicationPart
|
||||
{
|
||||
public override string Name => nameof(NonApplicationTypeProviderPart);
|
||||
|
||||
public IEnumerable<TypeInfo> Types => new[] { typeof(AnotherTagHelper).GetTypeInfo() };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// These types need to be public for the test to work.
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.TagHelpers.TagHelperFeatureProviderTests
|
||||
{
|
||||
public class DiscoveryTagHelper : TagHelper
|
||||
{
|
||||
}
|
||||
|
||||
public class AnotherTagHelper : TagHelper
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -212,7 +212,6 @@ namespace Microsoft.AspNetCore.Mvc
|
|||
Assert.Collection(manager.FeatureProviders,
|
||||
feature => Assert.IsType<ControllerFeatureProvider>(feature),
|
||||
feature => Assert.IsType<ViewComponentFeatureProvider>(feature),
|
||||
feature => Assert.IsType<TagHelperFeatureProvider>(feature),
|
||||
feature => Assert.IsType<MetadataReferenceFeatureProvider>(feature),
|
||||
feature => Assert.IsType<ViewsFeatureProvider>(feature));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@
|
|||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Mvc.ViewFeatures\Microsoft.AspNetCore.Mvc.ViewFeatures.csproj" />
|
||||
|
||||
<PackageReference Include="Microsoft.AspNetCore.Html.Abstractions" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Razor" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Testing" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Abstractions" Version="$(AspNetCoreVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="$(AspNetCoreVersion)" />
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
// 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.Text.RegularExpressions;
|
||||
using Microsoft.AspNetCore.Razor;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc
|
||||
|
|
@ -42,14 +40,5 @@ namespace Microsoft.AspNetCore.Mvc
|
|||
|
||||
return input;
|
||||
}
|
||||
|
||||
// Assuming windows based source location is passed in,
|
||||
// it gets normalized to other platforms.
|
||||
public static SourceLocation NormalizedSourceLocation(int absoluteIndex, int lineIndex, int characterIndex)
|
||||
{
|
||||
var windowsNewLineLength = "\r\n".Length;
|
||||
var differenceInLength = windowsNewLineLength - Environment.NewLine.Length;
|
||||
return new SourceLocation(absoluteIndex - (differenceInLength * lineIndex), lineIndex, characterIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,6 @@
|
|||
// 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.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
|
||||
namespace ControllersFromServicesWebSite.TagHelpers
|
||||
|
|
|
|||
Loading…
Reference in New Issue