Removing Microsoft.AspNet.Razor.Runtime.Precompilation
This commit is contained in:
parent
605dceea02
commit
c05551e167
23
Razor.sln
23
Razor.sln
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 14
|
# Visual Studio 14
|
||||||
VisualStudioVersion = 14.0.23107.0
|
VisualStudioVersion = 14.0.24720.0
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{3C0D6505-79B3-49D0-B4C3-176F0F1836ED}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{3C0D6505-79B3-49D0-B4C3-176F0F1836ED}"
|
||||||
EndProject
|
EndProject
|
||||||
|
|
@ -17,12 +17,6 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Razor.Runt
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Razor.Test.Sources", "src\Microsoft.AspNet.Razor.Test.Sources\Microsoft.AspNet.Razor.Test.Sources.xproj", "{E3A2A305-634D-4BA6-95DB-AA06D6C442B0}"
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Razor.Test.Sources", "src\Microsoft.AspNet.Razor.Test.Sources\Microsoft.AspNet.Razor.Test.Sources.xproj", "{E3A2A305-634D-4BA6-95DB-AA06D6C442B0}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Razor.Runtime.Precompilation", "src\Microsoft.AspNet.Razor.Runtime.Precompilation\Microsoft.AspNet.Razor.Runtime.Precompilation.xproj", "{3B7ECD22-4C02-45CF-92E8-98C074DD9D0E}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Razor.Runtime.Precompilation.Test", "test\Microsoft.AspNet.Razor.Runtime.Precompilation.Test\Microsoft.AspNet.Razor.Runtime.Precompilation.Test.xproj", "{C626444C-5A63-42BC-ACAE-DBB2CD3EDE25}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Razor.Runtime.Precompilation.Files", "test\Microsoft.AspNet.Razor.Runtime.Precompilation.Files\Microsoft.AspNet.Razor.Runtime.Precompilation.Files.xproj", "{125D4CC1-5317-495F-88B8-472DFD9C1097}"
|
|
||||||
EndProject
|
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
|
@ -49,18 +43,6 @@ Global
|
||||||
{E3A2A305-634D-4BA6-95DB-AA06D6C442B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{E3A2A305-634D-4BA6-95DB-AA06D6C442B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{E3A2A305-634D-4BA6-95DB-AA06D6C442B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{E3A2A305-634D-4BA6-95DB-AA06D6C442B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{E3A2A305-634D-4BA6-95DB-AA06D6C442B0}.Release|Any CPU.Build.0 = Release|Any CPU
|
{E3A2A305-634D-4BA6-95DB-AA06D6C442B0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{3B7ECD22-4C02-45CF-92E8-98C074DD9D0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{3B7ECD22-4C02-45CF-92E8-98C074DD9D0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{3B7ECD22-4C02-45CF-92E8-98C074DD9D0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{3B7ECD22-4C02-45CF-92E8-98C074DD9D0E}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{C626444C-5A63-42BC-ACAE-DBB2CD3EDE25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{C626444C-5A63-42BC-ACAE-DBB2CD3EDE25}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{C626444C-5A63-42BC-ACAE-DBB2CD3EDE25}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{C626444C-5A63-42BC-ACAE-DBB2CD3EDE25}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{125D4CC1-5317-495F-88B8-472DFD9C1097}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{125D4CC1-5317-495F-88B8-472DFD9C1097}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{125D4CC1-5317-495F-88B8-472DFD9C1097}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{125D4CC1-5317-495F-88B8-472DFD9C1097}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
@ -71,8 +53,5 @@ Global
|
||||||
{D0196096-1B01-4133-AACE-1A10A0F7247C} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED}
|
{D0196096-1B01-4133-AACE-1A10A0F7247C} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED}
|
||||||
{0535998A-E32C-4D1A-80D1-0B15A513C471} = {92463391-81BE-462B-AC3C-78C6C760741F}
|
{0535998A-E32C-4D1A-80D1-0B15A513C471} = {92463391-81BE-462B-AC3C-78C6C760741F}
|
||||||
{E3A2A305-634D-4BA6-95DB-AA06D6C442B0} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED}
|
{E3A2A305-634D-4BA6-95DB-AA06D6C442B0} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED}
|
||||||
{3B7ECD22-4C02-45CF-92E8-98C074DD9D0E} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED}
|
|
||||||
{C626444C-5A63-42BC-ACAE-DBB2CD3EDE25} = {92463391-81BE-462B-AC3C-78C6C760741F}
|
|
||||||
{125D4CC1-5317-495F-88B8-472DFD9C1097} = {92463391-81BE-462B-AC3C-78C6C760741F}
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
|
||||||
|
|
@ -1,230 +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.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.Immutable;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using System.Reflection;
|
|
||||||
using Microsoft.CodeAnalysis;
|
|
||||||
using Microsoft.Extensions.Internal;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Utilities to work with creating <see cref="Attribute"/> instances from <see cref="AttributeData"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static class CodeAnalysisAttributeUtilities
|
|
||||||
{
|
|
||||||
private static readonly ConcurrentDictionary<ConstructorInfo, Func<object[], Attribute>> _constructorCache =
|
|
||||||
new ConcurrentDictionary<ConstructorInfo, Func<object[], Attribute>>();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the sequence of <see cref="Attribute"/>s of type <typeparamref name="TAttribute"/>
|
|
||||||
/// that are declared on the specified <paramref name="symbol"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TAttribute">The <see cref="Attribute"/> type.</typeparam>
|
|
||||||
/// <param name="symbol">The <see cref="ISymbol"/> to find attributes on.</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static IEnumerable<TAttribute> GetCustomAttributes<TAttribute>(ISymbol symbol)
|
|
||||||
where TAttribute : Attribute
|
|
||||||
{
|
|
||||||
if (symbol == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(symbol));
|
|
||||||
}
|
|
||||||
|
|
||||||
var attributes = symbol.GetAttributes();
|
|
||||||
if (attributes.Length > 0)
|
|
||||||
{
|
|
||||||
return attributes
|
|
||||||
.Where(attribute => CodeAnalysisSymbolBasedTypeInfo.IsType(
|
|
||||||
attribute.AttributeClass,
|
|
||||||
typeof(TAttribute).GetTypeInfo()))
|
|
||||||
.Select(attribute => CreateAttribute<TAttribute>(attribute))
|
|
||||||
.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Enumerable.Empty<TAttribute>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static TAttribute CreateAttribute<TAttribute>(AttributeData attributeData)
|
|
||||||
where TAttribute : Attribute
|
|
||||||
{
|
|
||||||
TAttribute attribute;
|
|
||||||
var matchInfo = MatchConstructor(typeof(TAttribute), attributeData.ConstructorArguments);
|
|
||||||
Func<object[], Attribute> constructorDelegate;
|
|
||||||
if (!_constructorCache.TryGetValue(matchInfo.Constructor, out constructorDelegate))
|
|
||||||
{
|
|
||||||
constructorDelegate = MakeFastConstructorInvoker(matchInfo);
|
|
||||||
_constructorCache[matchInfo.Constructor] = constructorDelegate;
|
|
||||||
}
|
|
||||||
|
|
||||||
attribute = (TAttribute)constructorDelegate(matchInfo.ArgumentValues);
|
|
||||||
|
|
||||||
if (attributeData.NamedArguments.Length > 0)
|
|
||||||
{
|
|
||||||
var helpers = PropertyHelper.GetVisibleProperties(attribute);
|
|
||||||
foreach (var item in attributeData.NamedArguments)
|
|
||||||
{
|
|
||||||
var helper = helpers.FirstOrDefault(
|
|
||||||
propertyHelper => string.Equals(propertyHelper.Name, item.Key, StringComparison.Ordinal));
|
|
||||||
|
|
||||||
if (helper == null)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException(
|
|
||||||
Resources.FormatCodeAnalysis_PropertyNotFound(item.Key, attribute.GetType().FullName));
|
|
||||||
}
|
|
||||||
|
|
||||||
var propertyValue = ConvertTypedConstantValue(
|
|
||||||
helper.Property.PropertyType,
|
|
||||||
item.Value);
|
|
||||||
helper.SetValue(attribute, propertyValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return attribute;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Func<object[], Attribute> MakeFastConstructorInvoker(ConstructorMatchInfo matchInfo)
|
|
||||||
{
|
|
||||||
var argsParameter = Expression.Parameter(typeof(object[]), "args");
|
|
||||||
var parameters = new Expression[matchInfo.ArgumentValues.Length];
|
|
||||||
|
|
||||||
for (var index = 0; index < matchInfo.ArgumentValues.Length; index++)
|
|
||||||
{
|
|
||||||
parameters[index] =
|
|
||||||
Expression.Convert(
|
|
||||||
Expression.ArrayIndex(
|
|
||||||
argsParameter,
|
|
||||||
Expression.Constant(index)),
|
|
||||||
matchInfo.ArgumentValues[index].GetType());
|
|
||||||
}
|
|
||||||
|
|
||||||
// () => new TAttribute(args)
|
|
||||||
var lambda =
|
|
||||||
Expression.Lambda<Func<object[], Attribute>>(
|
|
||||||
Expression.New(
|
|
||||||
matchInfo.Constructor,
|
|
||||||
parameters),
|
|
||||||
argsParameter);
|
|
||||||
|
|
||||||
return lambda.Compile();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ConstructorMatchInfo MatchConstructor(
|
|
||||||
Type type,
|
|
||||||
ImmutableArray<TypedConstant> symbolConstructorArguments)
|
|
||||||
{
|
|
||||||
var constructor = FindConstructor(type, symbolConstructorArguments);
|
|
||||||
var constructorParmaters = constructor.GetParameters();
|
|
||||||
|
|
||||||
var arguments = new object[symbolConstructorArguments.Length];
|
|
||||||
for (var i = 0; i < arguments.Length; i++)
|
|
||||||
{
|
|
||||||
var value = ConvertTypedConstantValue(
|
|
||||||
constructorParmaters[i].ParameterType,
|
|
||||||
symbolConstructorArguments[i]);
|
|
||||||
|
|
||||||
arguments[i] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ConstructorMatchInfo
|
|
||||||
{
|
|
||||||
Constructor = constructor,
|
|
||||||
ArgumentValues = arguments
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ConstructorInfo FindConstructor(
|
|
||||||
Type type,
|
|
||||||
ImmutableArray<TypedConstant> symbolConstructorArguments)
|
|
||||||
{
|
|
||||||
var constructors = type.GetConstructors();
|
|
||||||
foreach (var constructor in constructors)
|
|
||||||
{
|
|
||||||
var runtimeParameters = constructor.GetParameters();
|
|
||||||
if (runtimeParameters.Length != symbolConstructorArguments.Length)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var parametersMatched = true;
|
|
||||||
for (var index = 0; index < runtimeParameters.Length; index++)
|
|
||||||
{
|
|
||||||
var runtimeParameter = runtimeParameters[index].ParameterType;
|
|
||||||
if (symbolConstructorArguments[index].Kind == TypedConstantKind.Array &&
|
|
||||||
runtimeParameter.IsArray)
|
|
||||||
{
|
|
||||||
var arrayType = (IArrayTypeSymbol)symbolConstructorArguments[index].Type;
|
|
||||||
if (!CodeAnalysisSymbolBasedTypeInfo.IsType(
|
|
||||||
arrayType.ElementType,
|
|
||||||
runtimeParameter.GetElementType().GetTypeInfo()))
|
|
||||||
{
|
|
||||||
parametersMatched = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!CodeAnalysisSymbolBasedTypeInfo.IsType(
|
|
||||||
symbolConstructorArguments[index].Type,
|
|
||||||
runtimeParameter.GetTypeInfo()))
|
|
||||||
{
|
|
||||||
parametersMatched = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parametersMatched)
|
|
||||||
{
|
|
||||||
return constructor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InvalidOperationException(Resources.FormatCodeAnalysisConstructorNotFound(type.FullName));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static object ConvertTypedConstantValue(
|
|
||||||
Type type,
|
|
||||||
TypedConstant constructorArgument)
|
|
||||||
{
|
|
||||||
switch (constructorArgument.Kind)
|
|
||||||
{
|
|
||||||
case TypedConstantKind.Enum:
|
|
||||||
return Enum.ToObject(type, constructorArgument.Value);
|
|
||||||
case TypedConstantKind.Primitive:
|
|
||||||
return constructorArgument.Value;
|
|
||||||
case TypedConstantKind.Type:
|
|
||||||
var typeSymbol = (INamedTypeSymbol)constructorArgument.Value;
|
|
||||||
var typeName = CodeAnalysisSymbolBasedTypeInfo.GetAssemblyQualifiedName(typeSymbol);
|
|
||||||
return Type.GetType(typeName);
|
|
||||||
case TypedConstantKind.Array:
|
|
||||||
Debug.Assert(type.IsArray && constructorArgument.Values != null);
|
|
||||||
var elementType = type.GetElementType();
|
|
||||||
var values = Array.CreateInstance(elementType, constructorArgument.Values.Length);
|
|
||||||
for (var index = 0; index < values.Length; index++)
|
|
||||||
{
|
|
||||||
values.SetValue(
|
|
||||||
ConvertTypedConstantValue(elementType, constructorArgument.Values[index]),
|
|
||||||
index);
|
|
||||||
}
|
|
||||||
return values;
|
|
||||||
default:
|
|
||||||
throw new NotSupportedException(
|
|
||||||
Resources.FormatCodeAnalysis_TypeConstantKindNotSupported(constructorArgument.Kind));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private struct ConstructorMatchInfo
|
|
||||||
{
|
|
||||||
public ConstructorInfo Constructor;
|
|
||||||
|
|
||||||
public object[] ArgumentValues;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
|
||||||
using Microsoft.CodeAnalysis;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// <see cref="IPropertyInfo"/> implementation using Code Analysis symbols.
|
|
||||||
/// </summary>
|
|
||||||
[DebuggerDisplay("{Name, PropertyType}")]
|
|
||||||
public class CodeAnalysisSymbolBasedPropertyInfo : IPropertyInfo
|
|
||||||
{
|
|
||||||
private readonly IPropertySymbol _propertySymbol;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of <see cref="CodeAnalysisSymbolBasedPropertyInfo"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="propertySymbol">The <see cref="IPropertySymbol"/>.</param>
|
|
||||||
public CodeAnalysisSymbolBasedPropertyInfo(IPropertySymbol propertySymbol)
|
|
||||||
{
|
|
||||||
if (propertySymbol == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(propertySymbol));
|
|
||||||
}
|
|
||||||
|
|
||||||
_propertySymbol = propertySymbol;
|
|
||||||
PropertyType = new CodeAnalysisSymbolBasedTypeInfo(_propertySymbol.Type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool HasPublicGetter
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _propertySymbol.GetMethod != null &&
|
|
||||||
_propertySymbol.GetMethod.DeclaredAccessibility == Accessibility.Public;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool HasPublicSetter
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _propertySymbol.SetMethod != null &&
|
|
||||||
_propertySymbol.SetMethod.DeclaredAccessibility == Accessibility.Public;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string Name => _propertySymbol.MetadataName;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public ITypeInfo PropertyType { get; }
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public IEnumerable<TAttribute> GetCustomAttributes<TAttribute>()
|
|
||||||
where TAttribute : Attribute
|
|
||||||
{
|
|
||||||
return CodeAnalysisAttributeUtilities.GetCustomAttributes<TAttribute>(_propertySymbol);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,383 +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.Diagnostics;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
|
||||||
using Microsoft.CodeAnalysis;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// <see cref="ITypeInfo"/> implementation using Code Analysis symbols.
|
|
||||||
/// </summary>
|
|
||||||
[DebuggerDisplay("{Name}")]
|
|
||||||
public class CodeAnalysisSymbolBasedTypeInfo : ITypeInfo
|
|
||||||
{
|
|
||||||
private static readonly System.Reflection.TypeInfo OpenGenericDictionaryTypeInfo =
|
|
||||||
typeof(IDictionary<,>).GetTypeInfo();
|
|
||||||
private readonly ITypeSymbol _type;
|
|
||||||
private readonly ITypeSymbol _underlyingType;
|
|
||||||
private string _fullName;
|
|
||||||
private string _sanitizedFullName;
|
|
||||||
private List<IPropertyInfo> _properties;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of <see cref="CodeAnalysisSymbolBasedTypeInfo"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="propertySymbol">The <see cref="IPropertySymbol"/>.</param>
|
|
||||||
public CodeAnalysisSymbolBasedTypeInfo(ITypeSymbol type)
|
|
||||||
{
|
|
||||||
if (type == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(type));
|
|
||||||
}
|
|
||||||
|
|
||||||
_type = type;
|
|
||||||
_underlyingType = UnwrapArrayType(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string FullName
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_fullName == null)
|
|
||||||
{
|
|
||||||
_fullName = GetFullName(_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _fullName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The <see cref="ITypeSymbol"/> instance.
|
|
||||||
/// </summary>
|
|
||||||
public ITypeSymbol TypeSymbol => _type;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool IsEnum => _type.TypeKind == TypeKind.Enum;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool IsAbstract => _type.IsAbstract;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool IsGenericType
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _type.Kind == SymbolKind.NamedType &&
|
|
||||||
((INamedTypeSymbol)_type).IsGenericType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool IsNested => _underlyingType.ContainingType != null;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool IsPublic
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _type.DeclaredAccessibility == Accessibility.Public ||
|
|
||||||
_type.TypeKind == TypeKind.Array;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string Name
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_type.TypeKind == TypeKind.Array)
|
|
||||||
{
|
|
||||||
return _underlyingType.MetadataName + "[]";
|
|
||||||
}
|
|
||||||
|
|
||||||
return _type.MetadataName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public IEnumerable<IPropertyInfo> Properties
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_properties == null)
|
|
||||||
{
|
|
||||||
_properties = GetProperties(_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _properties;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool ImplementsInterface(ITypeInfo interfaceTypeInfo)
|
|
||||||
{
|
|
||||||
if (interfaceTypeInfo == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(interfaceTypeInfo));
|
|
||||||
}
|
|
||||||
|
|
||||||
var runtimeTypeInfo = interfaceTypeInfo as RuntimeTypeInfo;
|
|
||||||
if (runtimeTypeInfo != null)
|
|
||||||
{
|
|
||||||
return runtimeTypeInfo.TypeInfo.IsInterface &&
|
|
||||||
_type.AllInterfaces.Any(implementedInterface => IsType(implementedInterface, runtimeTypeInfo.TypeInfo));
|
|
||||||
}
|
|
||||||
|
|
||||||
var codeAnalysisTypeInfo = interfaceTypeInfo as CodeAnalysisSymbolBasedTypeInfo;
|
|
||||||
if (codeAnalysisTypeInfo != null)
|
|
||||||
{
|
|
||||||
return codeAnalysisTypeInfo.TypeSymbol.TypeKind == TypeKind.Interface &&
|
|
||||||
_type.AllInterfaces.Any(
|
|
||||||
implementedInterface => implementedInterface == codeAnalysisTypeInfo.TypeSymbol);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new ArgumentException(
|
|
||||||
Resources.FormatArgumentMustBeAnInstanceOf(
|
|
||||||
typeof(RuntimeTypeInfo).FullName,
|
|
||||||
typeof(CodeAnalysisSymbolBasedTypeInfo).FullName),
|
|
||||||
nameof(interfaceTypeInfo));
|
|
||||||
}
|
|
||||||
|
|
||||||
private string SanitizedFullName
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_sanitizedFullName == null)
|
|
||||||
{
|
|
||||||
_sanitizedFullName = RuntimeTypeInfo.SanitizeFullName(FullName);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _sanitizedFullName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public IEnumerable<TAttribute> GetCustomAttributes<TAttribute>()
|
|
||||||
where TAttribute : Attribute
|
|
||||||
{
|
|
||||||
return CodeAnalysisAttributeUtilities.GetCustomAttributes<TAttribute>(_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public ITypeInfo[] GetGenericDictionaryParameters()
|
|
||||||
{
|
|
||||||
INamedTypeSymbol dictionaryInterface;
|
|
||||||
if (_type.Kind == SymbolKind.NamedType &&
|
|
||||||
IsType(((INamedTypeSymbol)_type).ConstructedFrom, OpenGenericDictionaryTypeInfo))
|
|
||||||
{
|
|
||||||
dictionaryInterface = (INamedTypeSymbol)_type;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dictionaryInterface = _type
|
|
||||||
.AllInterfaces
|
|
||||||
.FirstOrDefault(implementedInterface =>
|
|
||||||
IsType(implementedInterface.ConstructedFrom, OpenGenericDictionaryTypeInfo));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dictionaryInterface != null)
|
|
||||||
{
|
|
||||||
Debug.Assert(dictionaryInterface.TypeArguments.Length == 2);
|
|
||||||
|
|
||||||
return new[]
|
|
||||||
{
|
|
||||||
new CodeAnalysisSymbolBasedTypeInfo(dictionaryInterface.TypeArguments[0]),
|
|
||||||
new CodeAnalysisSymbolBasedTypeInfo(dictionaryInterface.TypeArguments[1]),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value that indicates if <paramref name="targetTypeInfo"/> is represented using
|
|
||||||
/// <paramref name="sourceTypeSymbol"/> in the symbol graph.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sourceTypeSymbol">The <see cref="ITypeSymbol"/>.</param>
|
|
||||||
/// <param name="targetTypeInfo">The <see cref="System.Reflection.TypeInfo"/>.</param>
|
|
||||||
/// <returns><c>true</c> if <paramref name="targetTypeInfo"/> is a symbol for
|
|
||||||
/// <paramref name="sourceTypeSymbol"/>.</returns>
|
|
||||||
public static bool IsType(
|
|
||||||
ITypeSymbol sourceTypeSymbol,
|
|
||||||
System.Reflection.TypeInfo targetTypeInfo)
|
|
||||||
{
|
|
||||||
return string.Equals(
|
|
||||||
RuntimeTypeInfo.SanitizeFullName(targetTypeInfo.FullName),
|
|
||||||
RuntimeTypeInfo.SanitizeFullName(GetFullName(sourceTypeSymbol)),
|
|
||||||
StringComparison.Ordinal);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the assembly qualified named of the specified <paramref name="symbol"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="symbol">The <see cref="ITypeSymbol" /> to generate the name for.</param>
|
|
||||||
/// <returns>The assembly qualified name.</returns>
|
|
||||||
public static string GetAssemblyQualifiedName(ITypeSymbol symbol)
|
|
||||||
{
|
|
||||||
if (symbol == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(symbol));
|
|
||||||
}
|
|
||||||
|
|
||||||
var builder = new StringBuilder();
|
|
||||||
GetAssemblyQualifiedName(builder, symbol);
|
|
||||||
|
|
||||||
return builder.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 otherSymbolBasedType = other as CodeAnalysisSymbolBasedTypeInfo;
|
|
||||||
if (otherSymbolBasedType != null)
|
|
||||||
{
|
|
||||||
return otherSymbolBasedType.TypeSymbol == TypeSymbol;
|
|
||||||
}
|
|
||||||
|
|
||||||
return string.Equals(
|
|
||||||
SanitizedFullName,
|
|
||||||
RuntimeTypeInfo.SanitizeFullName(other.FullName),
|
|
||||||
StringComparison.Ordinal);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override int GetHashCode() => SanitizedFullName.GetHashCode();
|
|
||||||
|
|
||||||
private static List<IPropertyInfo> GetProperties(ITypeSymbol typeSymbol)
|
|
||||||
{
|
|
||||||
var properties = new List<IPropertyInfo>();
|
|
||||||
var overridenProperties = new HashSet<IPropertySymbol>();
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
foreach (var member in typeSymbol.GetMembers().Where(m => m.Kind == SymbolKind.Property))
|
|
||||||
{
|
|
||||||
var propertySymbol = (IPropertySymbol)member;
|
|
||||||
if (!propertySymbol.IsIndexer && !overridenProperties.Contains(propertySymbol))
|
|
||||||
{
|
|
||||||
var propertyInfo = new CodeAnalysisSymbolBasedPropertyInfo(propertySymbol);
|
|
||||||
properties.Add(propertyInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (propertySymbol.IsOverride)
|
|
||||||
{
|
|
||||||
overridenProperties.Add(propertySymbol.OverriddenProperty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
typeSymbol = typeSymbol.BaseType;
|
|
||||||
|
|
||||||
} while (typeSymbol != null);
|
|
||||||
|
|
||||||
return properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetFullName(ITypeSymbol typeSymbol)
|
|
||||||
{
|
|
||||||
var nameBuilder = new StringBuilder();
|
|
||||||
GetFullName(nameBuilder, typeSymbol);
|
|
||||||
|
|
||||||
return nameBuilder.Length == 0 ? null : nameBuilder.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void GetFullName(StringBuilder nameBuilder, ITypeSymbol typeSymbol)
|
|
||||||
{
|
|
||||||
if (typeSymbol.Kind == SymbolKind.TypeParameter)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var insertIndex = nameBuilder.Length;
|
|
||||||
if (typeSymbol.TypeKind == TypeKind.Array)
|
|
||||||
{
|
|
||||||
var arrayType = (IArrayTypeSymbol)typeSymbol;
|
|
||||||
GetAssemblyQualifiedName(nameBuilder, arrayType.ElementType);
|
|
||||||
nameBuilder.Append("[]");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
nameBuilder.Append(typeSymbol.MetadataName);
|
|
||||||
if (typeSymbol.Kind == SymbolKind.NamedType)
|
|
||||||
{
|
|
||||||
var namedSymbol = (INamedTypeSymbol)typeSymbol;
|
|
||||||
// The symbol represents a generic but not open generic type
|
|
||||||
if (namedSymbol.IsGenericType &&
|
|
||||||
namedSymbol.ConstructedFrom != namedSymbol)
|
|
||||||
{
|
|
||||||
nameBuilder.Append('[');
|
|
||||||
foreach (var typeArgument in namedSymbol.TypeArguments)
|
|
||||||
{
|
|
||||||
nameBuilder.Append('[');
|
|
||||||
GetAssemblyQualifiedName(nameBuilder, typeArgument);
|
|
||||||
nameBuilder.Append("],");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Removing trailing slash
|
|
||||||
Debug.Assert(nameBuilder.Length > 0 && nameBuilder[nameBuilder.Length - 1] == ',');
|
|
||||||
nameBuilder.Length--;
|
|
||||||
nameBuilder.Append("]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var containingType = typeSymbol.ContainingType;
|
|
||||||
while (containingType != null)
|
|
||||||
{
|
|
||||||
nameBuilder
|
|
||||||
.Insert(insertIndex, '+')
|
|
||||||
.Insert(insertIndex, containingType.MetadataName);
|
|
||||||
|
|
||||||
containingType = containingType.ContainingType;
|
|
||||||
}
|
|
||||||
|
|
||||||
var containingNamespace = typeSymbol.ContainingNamespace;
|
|
||||||
while (!containingNamespace.IsGlobalNamespace)
|
|
||||||
{
|
|
||||||
nameBuilder
|
|
||||||
.Insert(insertIndex, '.')
|
|
||||||
.Insert(insertIndex, containingNamespace.MetadataName);
|
|
||||||
|
|
||||||
containingNamespace = containingNamespace.ContainingNamespace;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void GetAssemblyQualifiedName(StringBuilder builder, ITypeSymbol typeSymbol)
|
|
||||||
{
|
|
||||||
GetFullName(builder, typeSymbol);
|
|
||||||
typeSymbol = UnwrapArrayType(typeSymbol);
|
|
||||||
|
|
||||||
builder
|
|
||||||
.Append(", ")
|
|
||||||
.Append(typeSymbol.ContainingAssembly.Identity);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ITypeSymbol UnwrapArrayType(ITypeSymbol type)
|
|
||||||
{
|
|
||||||
if (type.TypeKind == TypeKind.Array)
|
|
||||||
{
|
|
||||||
return ((IArrayTypeSymbol)type).ElementType;
|
|
||||||
}
|
|
||||||
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<PropertyGroup>
|
|
||||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
|
||||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<ProjectGuid>3b7ecd22-4c02-45cf-92e8-98c074dd9d0e</ProjectGuid>
|
|
||||||
<RootNamespace>Microsoft.AspNet.Razor.Runtime.Precompilation</RootNamespace>
|
|
||||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
|
||||||
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<SchemaVersion>2.0</SchemaVersion>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
|
||||||
</Project>
|
|
||||||
|
|
@ -1,117 +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;
|
|
||||||
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
|
||||||
using Microsoft.CodeAnalysis;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// <see cref="TagHelperTypeResolver"/> used during Razor precompilation.
|
|
||||||
/// </summary>
|
|
||||||
public class PrecompilationTagHelperTypeResolver : TagHelperTypeResolver
|
|
||||||
{
|
|
||||||
private readonly object _assemblyLookupLock = new object();
|
|
||||||
private readonly Dictionary<string, IEnumerable<ITypeInfo>> _assemblyLookup
|
|
||||||
= new Dictionary<string, IEnumerable<ITypeInfo>>(StringComparer.Ordinal);
|
|
||||||
private readonly CodeAnalysis.Compilation _compilation;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of <see cref="PrecompilationTagHelperTypeResolver"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="compilation">The <see cref="CodeAnalysis.Compilation"/>.</param>
|
|
||||||
public PrecompilationTagHelperTypeResolver(CodeAnalysis.Compilation compilation)
|
|
||||||
{
|
|
||||||
if (compilation == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(compilation));
|
|
||||||
}
|
|
||||||
|
|
||||||
_compilation = compilation;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override IEnumerable<ITypeInfo> GetTopLevelExportedTypes(AssemblyName assemblyName)
|
|
||||||
{
|
|
||||||
if (assemblyName == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(assemblyName));
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (_assemblyLookupLock)
|
|
||||||
{
|
|
||||||
IEnumerable<ITypeInfo> result;
|
|
||||||
if (!_assemblyLookup.TryGetValue(assemblyName.Name, out result))
|
|
||||||
{
|
|
||||||
result = GetExportedTypes(assemblyName.Name);
|
|
||||||
_assemblyLookup[assemblyName.Name] = result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Internal for unit testing
|
|
||||||
internal IEnumerable<ITypeInfo> GetExportedTypes(string assemblyName)
|
|
||||||
{
|
|
||||||
if (string.Equals(_compilation.AssemblyName, assemblyName, StringComparison.Ordinal))
|
|
||||||
{
|
|
||||||
return GetExportedTypes(_compilation.Assembly);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach (var reference in _compilation.References)
|
|
||||||
{
|
|
||||||
var compilationReference = reference as CompilationReference;
|
|
||||||
if (compilationReference != null &&
|
|
||||||
string.Equals(
|
|
||||||
compilationReference.Compilation.AssemblyName,
|
|
||||||
assemblyName,
|
|
||||||
StringComparison.Ordinal))
|
|
||||||
{
|
|
||||||
return GetExportedTypes(compilationReference.Compilation.Assembly);
|
|
||||||
}
|
|
||||||
|
|
||||||
var assemblySymbol = _compilation.GetAssemblyOrModuleSymbol(reference) as IAssemblySymbol;
|
|
||||||
if (string.Equals(
|
|
||||||
assemblySymbol?.Identity.Name,
|
|
||||||
assemblyName,
|
|
||||||
StringComparison.Ordinal))
|
|
||||||
{
|
|
||||||
return GetExportedTypes(assemblySymbol);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InvalidOperationException(
|
|
||||||
Resources.FormatCodeAnalysis_UnableToLoadAssemblyReference(assemblyName));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<ITypeInfo> GetExportedTypes(IAssemblySymbol assembly)
|
|
||||||
{
|
|
||||||
var exportedTypes = new List<ITypeInfo>();
|
|
||||||
GetExportedTypes(assembly.GlobalNamespace, exportedTypes);
|
|
||||||
return exportedTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void GetExportedTypes(INamespaceSymbol namespaceSymbol, List<ITypeInfo> exportedTypes)
|
|
||||||
{
|
|
||||||
foreach (var type in namespaceSymbol.GetTypeMembers())
|
|
||||||
{
|
|
||||||
if (type.TypeKind == TypeKind.Class &&
|
|
||||||
type.DeclaredAccessibility == Accessibility.Public)
|
|
||||||
{
|
|
||||||
exportedTypes.Add(new CodeAnalysisSymbolBasedTypeInfo(type));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var subNamespace in namespaceSymbol.GetNamespaceMembers())
|
|
||||||
{
|
|
||||||
GetExportedTypes(subNamespace, exportedTypes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,10 +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.Reflection;
|
|
||||||
using System.Resources;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
|
|
||||||
[assembly: InternalsVisibleTo("Microsoft.AspNet.Razor.Runtime.Precompilation.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
|
||||||
[assembly: NeutralResourcesLanguage("en-us")]
|
|
||||||
[assembly: AssemblyMetadata("Serviceable", "True")]
|
|
||||||
|
|
@ -1,110 +0,0 @@
|
||||||
// <auto-generated />
|
|
||||||
namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|
||||||
{
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Resources;
|
|
||||||
|
|
||||||
internal static class Resources
|
|
||||||
{
|
|
||||||
private static readonly ResourceManager _resourceManager
|
|
||||||
= new ResourceManager("Microsoft.AspNet.Razor.Runtime.Precompilation.Resources", typeof(Resources).GetTypeInfo().Assembly);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Argument must be an instance of '{0}' or '{1}'.
|
|
||||||
/// </summary>
|
|
||||||
internal static string ArgumentMustBeAnInstanceOf
|
|
||||||
{
|
|
||||||
get { return GetString("ArgumentMustBeAnInstanceOf"); }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Argument must be an instance of '{0}' or '{1}'.
|
|
||||||
/// </summary>
|
|
||||||
internal static string FormatArgumentMustBeAnInstanceOf(object p0, object p1)
|
|
||||||
{
|
|
||||||
return string.Format(CultureInfo.CurrentCulture, GetString("ArgumentMustBeAnInstanceOf"), p0, p1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Unable to find a suitable constructor for type '{0}'.
|
|
||||||
/// </summary>
|
|
||||||
internal static string CodeAnalysisConstructorNotFound
|
|
||||||
{
|
|
||||||
get { return GetString("CodeAnalysisConstructorNotFound"); }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Unable to find a suitable constructor for type '{0}'.
|
|
||||||
/// </summary>
|
|
||||||
internal static string FormatCodeAnalysisConstructorNotFound(object p0)
|
|
||||||
{
|
|
||||||
return string.Format(CultureInfo.CurrentCulture, GetString("CodeAnalysisConstructorNotFound"), p0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Unable to find property {0} on type {1}.
|
|
||||||
/// </summary>
|
|
||||||
internal static string CodeAnalysis_PropertyNotFound
|
|
||||||
{
|
|
||||||
get { return GetString("CodeAnalysis_PropertyNotFound"); }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Unable to find property {0} on type {1}.
|
|
||||||
/// </summary>
|
|
||||||
internal static string FormatCodeAnalysis_PropertyNotFound(object p0, object p1)
|
|
||||||
{
|
|
||||||
return string.Format(CultureInfo.CurrentCulture, GetString("CodeAnalysis_PropertyNotFound"), p0, p1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The type constant kind '{0}' is not supported.
|
|
||||||
/// </summary>
|
|
||||||
internal static string CodeAnalysis_TypeConstantKindNotSupported
|
|
||||||
{
|
|
||||||
get { return GetString("CodeAnalysis_TypeConstantKindNotSupported"); }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The type constant kind '{0}' is not supported.
|
|
||||||
/// </summary>
|
|
||||||
internal static string FormatCodeAnalysis_TypeConstantKindNotSupported(object p0)
|
|
||||||
{
|
|
||||||
return string.Format(CultureInfo.CurrentCulture, GetString("CodeAnalysis_TypeConstantKindNotSupported"), p0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Unable to load assembly reference '{0}'.
|
|
||||||
/// </summary>
|
|
||||||
internal static string CodeAnalysis_UnableToLoadAssemblyReference
|
|
||||||
{
|
|
||||||
get { return GetString("CodeAnalysis_UnableToLoadAssemblyReference"); }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Unable to load assembly reference '{0}'.
|
|
||||||
/// </summary>
|
|
||||||
internal static string FormatCodeAnalysis_UnableToLoadAssemblyReference(object p0)
|
|
||||||
{
|
|
||||||
return string.Format(CultureInfo.CurrentCulture, GetString("CodeAnalysis_UnableToLoadAssemblyReference"), p0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetString(string name, params string[] formatterNames)
|
|
||||||
{
|
|
||||||
var value = _resourceManager.GetString(name);
|
|
||||||
|
|
||||||
System.Diagnostics.Debug.Assert(value != null);
|
|
||||||
|
|
||||||
if (formatterNames != null)
|
|
||||||
{
|
|
||||||
for (var i = 0; i < formatterNames.Length; i++)
|
|
||||||
{
|
|
||||||
value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,135 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<root>
|
|
||||||
<!--
|
|
||||||
Microsoft ResX Schema
|
|
||||||
|
|
||||||
Version 2.0
|
|
||||||
|
|
||||||
The primary goals of this format is to allow a simple XML format
|
|
||||||
that is mostly human readable. The generation and parsing of the
|
|
||||||
various data types are done through the TypeConverter classes
|
|
||||||
associated with the data types.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
... ado.net/XML headers & schema ...
|
|
||||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
|
||||||
<resheader name="version">2.0</resheader>
|
|
||||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
|
||||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
|
||||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
|
||||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
|
||||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
|
||||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
|
||||||
</data>
|
|
||||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
|
||||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
|
||||||
<comment>This is a comment</comment>
|
|
||||||
</data>
|
|
||||||
|
|
||||||
There are any number of "resheader" rows that contain simple
|
|
||||||
name/value pairs.
|
|
||||||
|
|
||||||
Each data row contains a name, and value. The row also contains a
|
|
||||||
type or mimetype. Type corresponds to a .NET class that support
|
|
||||||
text/value conversion through the TypeConverter architecture.
|
|
||||||
Classes that don't support this are serialized and stored with the
|
|
||||||
mimetype set.
|
|
||||||
|
|
||||||
The mimetype is used for serialized objects, and tells the
|
|
||||||
ResXResourceReader how to depersist the object. This is currently not
|
|
||||||
extensible. For a given mimetype the value must be set accordingly:
|
|
||||||
|
|
||||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
|
||||||
that the ResXResourceWriter will generate, however the reader can
|
|
||||||
read any of the formats listed below.
|
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.binary.base64
|
|
||||||
value : The object must be serialized with
|
|
||||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
|
||||||
: and then encoded with base64 encoding.
|
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.soap.base64
|
|
||||||
value : The object must be serialized with
|
|
||||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
|
||||||
: and then encoded with base64 encoding.
|
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
|
||||||
value : The object must be serialized into a byte array
|
|
||||||
: using a System.ComponentModel.TypeConverter
|
|
||||||
: and then encoded with base64 encoding.
|
|
||||||
-->
|
|
||||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
|
||||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
|
||||||
<xsd:element name="root" msdata:IsDataSet="true">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:choice maxOccurs="unbounded">
|
|
||||||
<xsd:element name="metadata">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
|
||||||
<xsd:attribute name="type" type="xsd:string" />
|
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
|
||||||
<xsd:attribute ref="xml:space" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="assembly">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:attribute name="alias" type="xsd:string" />
|
|
||||||
<xsd:attribute name="name" type="xsd:string" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="data">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
|
||||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
|
||||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
|
||||||
<xsd:attribute ref="xml:space" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="resheader">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
</xsd:choice>
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
</xsd:schema>
|
|
||||||
<resheader name="resmimetype">
|
|
||||||
<value>text/microsoft-resx</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="version">
|
|
||||||
<value>2.0</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="reader">
|
|
||||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="writer">
|
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
|
||||||
</resheader>
|
|
||||||
<data name="ArgumentMustBeAnInstanceOf" xml:space="preserve">
|
|
||||||
<value>Argument must be an instance of '{0}' or '{1}'.</value>
|
|
||||||
</data>
|
|
||||||
<data name="CodeAnalysisConstructorNotFound" xml:space="preserve">
|
|
||||||
<value>Unable to find a suitable constructor for type '{0}'.</value>
|
|
||||||
</data>
|
|
||||||
<data name="CodeAnalysis_PropertyNotFound" xml:space="preserve">
|
|
||||||
<value>Unable to find property {0} on type {1}.</value>
|
|
||||||
</data>
|
|
||||||
<data name="CodeAnalysis_TypeConstantKindNotSupported" xml:space="preserve">
|
|
||||||
<value>The type constant kind '{0}' is not supported.</value>
|
|
||||||
</data>
|
|
||||||
<data name="CodeAnalysis_UnableToLoadAssemblyReference" xml:space="preserve">
|
|
||||||
<value>Unable to load assembly reference '{0}'.</value>
|
|
||||||
</data>
|
|
||||||
</root>
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
{
|
|
||||||
"description": "Supports tag helper resolution during precompilation.",
|
|
||||||
"version": "4.0.0-*",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git://github.com/aspnet/razor"
|
|
||||||
},
|
|
||||||
"compilationOptions": {
|
|
||||||
"warningsAsErrors": true,
|
|
||||||
"keyFile": "../../tools/Key.snk"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"Microsoft.Extensions.PropertyActivator.Sources": {
|
|
||||||
"version": "1.0.0-*",
|
|
||||||
"type": "build"
|
|
||||||
},
|
|
||||||
"Microsoft.Extensions.PropertyHelper.Sources": {
|
|
||||||
"version": "1.0.0-*",
|
|
||||||
"type": "build"
|
|
||||||
},
|
|
||||||
"Microsoft.AspNet.Razor.Runtime": "4.0.0-*",
|
|
||||||
"Microsoft.Dnx.Compilation.CSharp.Abstractions": "1.0.0-*"
|
|
||||||
},
|
|
||||||
"frameworks": {
|
|
||||||
"net451": {
|
|
||||||
"frameworkAssemblies": {
|
|
||||||
"System.Runtime": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dotnet5.4": {
|
|
||||||
"dependencies": {
|
|
||||||
"System.Collections.Concurrent": "4.0.11-*",
|
|
||||||
"System.Linq.Expressions": "4.0.11-*",
|
|
||||||
"System.Reflection.TypeExtensions": "4.1.0-*"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|
||||||
{
|
|
||||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
|
|
||||||
public class AttributesWithArrayConstructorArgumentsAttribute : Attribute
|
|
||||||
{
|
|
||||||
public AttributesWithArrayConstructorArgumentsAttribute(string[] stringArgs, int[] intArgs)
|
|
||||||
{
|
|
||||||
StringArgs = stringArgs;
|
|
||||||
IntArgs = intArgs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AttributesWithArrayConstructorArgumentsAttribute(string[] stringArgs, Type[] typeArgs, int[] intArgs)
|
|
||||||
{
|
|
||||||
StringArgs = stringArgs;
|
|
||||||
TypeArgs = typeArgs;
|
|
||||||
IntArgs = intArgs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AttributesWithArrayConstructorArgumentsAttribute(int[] intArgs, Type[] typeArgs)
|
|
||||||
{
|
|
||||||
IntArgs = intArgs;
|
|
||||||
TypeArgs = typeArgs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string[] StringArgs { get; }
|
|
||||||
|
|
||||||
public Type[] TypeArgs { get; }
|
|
||||||
|
|
||||||
public int[] IntArgs { get; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,16 +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;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|
||||||
{
|
|
||||||
public class ArrayPropertiesAttribute : Attribute
|
|
||||||
{
|
|
||||||
public Type[] ArrayOfTypes { get; set; }
|
|
||||||
|
|
||||||
public int[] ArrayOfInts { get; set; }
|
|
||||||
|
|
||||||
public DayOfWeek[] Days { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,28 +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.Precompilation
|
|
||||||
{
|
|
||||||
internal class InternalType
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PublicType
|
|
||||||
{
|
|
||||||
private class NestedPrivateType
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ContainerType
|
|
||||||
{
|
|
||||||
public class NestedType
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class GenericType<TVal>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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.
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|
||||||
{
|
|
||||||
public struct MyStruct
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum MyEnum
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface MyInterface
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class MyAbstractClass
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public partial class MyPartialClass
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public partial class MyPartialClass
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class MySealedClass
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,38 +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;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Razor.Runtime
|
|
||||||
{
|
|
||||||
public class DerivingFromIList : IReadOnlyList<string>
|
|
||||||
{
|
|
||||||
public string this[int index]
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Count
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerator<string> GetEnumerator()
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
IEnumerator IEnumerable.GetEnumerator()
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +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;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Razor.Runtime
|
|
||||||
{
|
|
||||||
public class DerivingFromList : List<string>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +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;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|
||||||
{
|
|
||||||
public class EnumPropertyAttribute : Attribute
|
|
||||||
{
|
|
||||||
public DayOfWeek DayOfWeek { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<PropertyGroup>
|
|
||||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
|
||||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<ProjectGuid>125d4cc1-5317-495f-88b8-472dfd9c1097</ProjectGuid>
|
|
||||||
<RootNamespace>Microsoft.AspNet.Razor.Runtime.Precompilation.Files</RootNamespace>
|
|
||||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
|
||||||
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<SchemaVersion>2.0</SchemaVersion>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
|
||||||
</Project>
|
|
||||||
|
|
@ -1,24 +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;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|
||||||
{
|
|
||||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
|
|
||||||
public class MultipleConstructorArgumentsAttribute : Attribute
|
|
||||||
{
|
|
||||||
public MultipleConstructorArgumentsAttribute(string firstArgument, string secondArgument, int thirdArgument)
|
|
||||||
{
|
|
||||||
FirstArgument = firstArgument;
|
|
||||||
SecondArgument = secondArgument;
|
|
||||||
ThirdArgument = thirdArgument;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string FirstArgument { get; }
|
|
||||||
|
|
||||||
public string SecondArgument { get; }
|
|
||||||
|
|
||||||
public int ThirdArgument { get; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,21 +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.Precompilation
|
|
||||||
{
|
|
||||||
public class TypeWithArrayProperties
|
|
||||||
{
|
|
||||||
public MyAbstractClass[] AbstractArray { get; set; }
|
|
||||||
|
|
||||||
public IDisposable[] DisposableArray { get; }
|
|
||||||
|
|
||||||
public ContainerType.NestedType[] NestedArrayType { get; }
|
|
||||||
|
|
||||||
internal InternalType[] InternalArray { get; set; }
|
|
||||||
|
|
||||||
public ICollection<IDictionary<string, IList<object[]>>>[] GenericArray { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,52 +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.ComponentModel;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using System.Resources;
|
|
||||||
using Microsoft.AspNet.Razor.TagHelpers;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|
||||||
{
|
|
||||||
[HtmlTargetElement("img", Attributes = AppendVersionAttributeName + "," + SrcAttributeName)]
|
|
||||||
[HtmlTargetElement("image", Attributes = SrcAttributeName)]
|
|
||||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
||||||
[EnumProperty(DayOfWeek = DayOfWeek.Friday)]
|
|
||||||
[CustomValidation(typeof(Validator), "ValidationMethod", ErrorMessageResourceType = typeof(ResourceManager))]
|
|
||||||
[RestrictChildren("ol", "ul", "li", "dl", "dd")]
|
|
||||||
[ArrayProperties(
|
|
||||||
ArrayOfInts = new[] { 7, 8, 9 },
|
|
||||||
ArrayOfTypes = new[] { typeof(ITagHelper), typeof(Guid) },
|
|
||||||
Days = new[] { DayOfWeek.Saturday })]
|
|
||||||
public class TypeWithAttributes
|
|
||||||
{
|
|
||||||
private const string AppendVersionAttributeName = "asp-append-version";
|
|
||||||
private const string SrcAttributeName = "src";
|
|
||||||
|
|
||||||
[HtmlAttributeName(SrcAttributeName)]
|
|
||||||
[Required(AllowEmptyStrings = true)]
|
|
||||||
public string Src { get; set; }
|
|
||||||
|
|
||||||
[HtmlAttributeName(AppendVersionAttributeName, DictionaryAttributePrefix = "prefix")]
|
|
||||||
[HtmlAttributeNotBound]
|
|
||||||
public bool AppendVersion { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
|
||||||
[ArrayProperties(
|
|
||||||
ArrayOfInts = new int[0],
|
|
||||||
ArrayOfTypes = new[] { typeof(TypeWithAttributes) },
|
|
||||||
Days = new[] { DayOfWeek.Sunday, DayOfWeek.Monday, DayOfWeek.Wednesday, DayOfWeek.Sunday })]
|
|
||||||
public ViewContext ViewContext { get; set; }
|
|
||||||
|
|
||||||
[AttributesWithArrayConstructorArguments(new[] { 1, 2 }, new[] { typeof(Uri), typeof(IList<>) })]
|
|
||||||
[AttributesWithArrayConstructorArguments(new[] { "Hello", "world" }, new[] { typeof(List<Guid>) }, new int[0])]
|
|
||||||
[AttributesWithArrayConstructorArguments(
|
|
||||||
new[] { "world", "Hello" },
|
|
||||||
new[] { typeof(IDictionary<string, object>) },
|
|
||||||
new[] { 1 })]
|
|
||||||
protected IEditableObject HostingEnvironment { get; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,23 +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.AspNet.Razor.TagHelpers;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|
||||||
{
|
|
||||||
public class TypeWithComplexPropertyFullNames
|
|
||||||
{
|
|
||||||
public int Property1 { get; set; }
|
|
||||||
|
|
||||||
public int[] Property2 { get; set; }
|
|
||||||
|
|
||||||
public List<long> Property3 { get; set; }
|
|
||||||
|
|
||||||
public List<Tuple<string, DateTimeOffset>> Property4 { get; }
|
|
||||||
|
|
||||||
public IDictionary<ILookup<string, TagHelper>, IList<Comparer<byte[]>>> Property5 { get; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|
||||||
{
|
|
||||||
public class TypeWithDictionaryProperties
|
|
||||||
{
|
|
||||||
public IDictionary<string, string> RouteValues1 { get; set; } =
|
|
||||||
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
public Dictionary<int, string> RouteValues2 { get; set; } =
|
|
||||||
new Dictionary<int, string>();
|
|
||||||
|
|
||||||
public Dictionary<List<string>, float> RouteValues3 { get; set; } =
|
|
||||||
new Dictionary<List<string>, float>();
|
|
||||||
|
|
||||||
public IDictionary<string, ParserResults> CustomDictionary { get; set; } =
|
|
||||||
new Dictionary<string, ParserResults>();
|
|
||||||
|
|
||||||
public IDictionary NonGenericDictionary { get; set; } =
|
|
||||||
new Dictionary<string, string>();
|
|
||||||
|
|
||||||
public object ObjectType { get; set; } =
|
|
||||||
new Dictionary<string, string>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +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.Precompilation
|
|
||||||
{
|
|
||||||
[MultipleConstructorArguments(firstArgument: "First1", secondArgument: "Second1", thirdArgument: 31)]
|
|
||||||
[MultipleConstructorArguments(secondArgument: "Second2", firstArgument: "First2", thirdArgument: 32)]
|
|
||||||
[MultipleConstructorArguments(thirdArgument: 33, secondArgument: "Second3", firstArgument: "First3")]
|
|
||||||
public class TypeWithNamedAttributes
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +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.Precompilation
|
|
||||||
{
|
|
||||||
public class Animal
|
|
||||||
{
|
|
||||||
public virtual string Name { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Mammal : Animal
|
|
||||||
{
|
|
||||||
public override string Name { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Dog : Mammal
|
|
||||||
{
|
|
||||||
public override string Name { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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.Runtime.Precompilation
|
|
||||||
{
|
|
||||||
public class ViewContext
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
{
|
|
||||||
"version": "1.0.0-*",
|
|
||||||
"compilationOptions": {
|
|
||||||
"warningsAsErrors": true,
|
|
||||||
"keyFile": "../../tools/Key.snk"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"Microsoft.AspNet.Razor.Runtime.Precompilation": "4.0.0-*"
|
|
||||||
},
|
|
||||||
"frameworks": {
|
|
||||||
"dnx451": {
|
|
||||||
"frameworkAssemblies": {
|
|
||||||
"System.ComponentModel.DataAnnotations": "4.0.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dnxcore50": {
|
|
||||||
"dependencies": {
|
|
||||||
"System.ComponentModel.Annotations": "4.0.11-*"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,18 +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.ComponentModel;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using Microsoft.AspNet.Razor.TagHelpers;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Razor.Precompilation
|
|
||||||
{
|
|
||||||
[RestrictChildren(Never)]
|
|
||||||
[CustomValidation(typeof(TypeDoesNotExist)]
|
|
||||||
[HtmlTargetElement("img"
|
|
||||||
public class TypeWithMalformedAttribute
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,16 +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;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Razor.Precompilation
|
|
||||||
{
|
|
||||||
public class TypeWithMalformedProperties
|
|
||||||
{
|
|
||||||
public DateTime DateTime { get }
|
|
||||||
|
|
||||||
public int DateTime2 => "Hello world";
|
|
||||||
|
|
||||||
public string CustomOrder { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,10 +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.Mvc.Razor.Precompilation
|
|
||||||
{
|
|
||||||
public class TypeWithMissingReferences : ITagHelper
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,83 +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.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Reflection;
|
|
||||||
using Microsoft.CodeAnalysis;
|
|
||||||
using Microsoft.CodeAnalysis.CSharp;
|
|
||||||
using Microsoft.Dnx.Compilation.CSharp;
|
|
||||||
using Microsoft.Extensions.CompilationAbstractions;
|
|
||||||
using Microsoft.Extensions.PlatformAbstractions;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|
||||||
{
|
|
||||||
public static class CompilationUtility
|
|
||||||
{
|
|
||||||
private static readonly ConcurrentDictionary<string, AssemblyMetadata> _metadataCache =
|
|
||||||
new ConcurrentDictionary<string, AssemblyMetadata>(StringComparer.Ordinal);
|
|
||||||
private static readonly Assembly ExecutingAssembly = typeof(CompilationUtility).GetTypeInfo().Assembly;
|
|
||||||
public static readonly string GeneratedAssemblyName = Path.GetRandomFileName() + "." + Path.GetRandomFileName();
|
|
||||||
|
|
||||||
public static CodeAnalysis.Compilation GetCompilation(params string[] resourceFiles)
|
|
||||||
{
|
|
||||||
var assemblyVersion = ExecutingAssembly.GetName().Version;
|
|
||||||
|
|
||||||
var syntaxTrees = new List<SyntaxTree>
|
|
||||||
{
|
|
||||||
CSharpSyntaxTree.ParseText(
|
|
||||||
$"[assembly: {typeof(AssemblyVersionAttribute).FullName}(\"{assemblyVersion}\")]")
|
|
||||||
};
|
|
||||||
|
|
||||||
foreach (var resourceFile in resourceFiles)
|
|
||||||
{
|
|
||||||
var resourceContent = ReadManifestResource(resourceFile);
|
|
||||||
syntaxTrees.Add(CSharpSyntaxTree.ParseText(resourceContent));
|
|
||||||
}
|
|
||||||
|
|
||||||
var libraryExporter = CompilationServices.Default.LibraryExporter;
|
|
||||||
var applicationName = ExecutingAssembly.GetName().Name;
|
|
||||||
var libraryExport = libraryExporter.GetExport(applicationName);
|
|
||||||
|
|
||||||
var references = new List<MetadataReference>();
|
|
||||||
var roslynReference = libraryExport.MetadataReferences[0] as IRoslynMetadataReference;
|
|
||||||
var compilationReference = roslynReference?.MetadataReference as CompilationReference;
|
|
||||||
if (compilationReference != null)
|
|
||||||
{
|
|
||||||
references.AddRange(compilationReference.Compilation.References);
|
|
||||||
references.Add(roslynReference.MetadataReference);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var export = libraryExporter.GetAllExports(applicationName);
|
|
||||||
foreach (var metadataReference in export.MetadataReferences)
|
|
||||||
{
|
|
||||||
var reference = metadataReference.ConvertMetadataReference(
|
|
||||||
fileReference => _metadataCache.GetOrAdd(
|
|
||||||
fileReference.Path,
|
|
||||||
_ => fileReference.CreateAssemblyMetadata()));
|
|
||||||
references.Add(reference);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return CSharpCompilation.Create(
|
|
||||||
GeneratedAssemblyName,
|
|
||||||
syntaxTrees,
|
|
||||||
references);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string ReadManifestResource(string path)
|
|
||||||
{
|
|
||||||
path = $"{ExecutingAssembly.GetName().Name}.{path}.cs";
|
|
||||||
using (var contentStream = ExecutingAssembly.GetManifestResourceStream(path))
|
|
||||||
{
|
|
||||||
using (var reader = new StreamReader(contentStream))
|
|
||||||
{
|
|
||||||
return reader.ReadToEnd();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<PropertyGroup>
|
|
||||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
|
||||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<ProjectGuid>c626444c-5a63-42bc-acae-dbb2cd3ede25</ProjectGuid>
|
|
||||||
<RootNamespace>Microsoft.AspNet.Razor.Runtime.Precompilation.Test</RootNamespace>
|
|
||||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
|
||||||
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup>
|
|
||||||
<SchemaVersion>2.0</SchemaVersion>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
|
||||||
</Project>
|
|
||||||
|
|
@ -1,80 +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.AspNet.Razor.Compilation.TagHelpers;
|
|
||||||
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
|
||||||
using Microsoft.AspNet.Razor.Test.Internal;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|
||||||
{
|
|
||||||
public class PrecompilationTagHelperDescriptorFactoryTest : TagHelperDescriptorFactoryTest
|
|
||||||
{
|
|
||||||
public override ITypeInfo GetTypeInfo(Type tagHelperType)
|
|
||||||
{
|
|
||||||
var paths = new[]
|
|
||||||
{
|
|
||||||
$"TagHelperDescriptorFactoryTagHelpers",
|
|
||||||
$"CommonTagHelpers",
|
|
||||||
};
|
|
||||||
|
|
||||||
var compilation = CompilationUtility.GetCompilation(paths);
|
|
||||||
var typeResolver = new PrecompilationTagHelperTypeResolver(compilation);
|
|
||||||
|
|
||||||
return Assert.Single(typeResolver.GetExportedTypes(CompilationUtility.GeneratedAssemblyName),
|
|
||||||
generatedType => string.Equals(generatedType.FullName, tagHelperType.FullName, StringComparison.Ordinal));
|
|
||||||
}
|
|
||||||
|
|
||||||
[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);
|
|
||||||
#if DNXCORE50
|
|
||||||
// In CoreCLR type forwarding of System.Runtime types causes issues with comparing FullNames for generic types.
|
|
||||||
// We'll work around this by sanitizing the type names so that the assembly qualification is removed.
|
|
||||||
foreach (var attributeDescriptor in expectedAttributeDescriptors)
|
|
||||||
{
|
|
||||||
attributeDescriptor.TypeName = RuntimeTypeInfo.SanitizeFullName(attributeDescriptor.TypeName);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var attributeDescriptor in descriptor.Attributes)
|
|
||||||
{
|
|
||||||
attributeDescriptor.TypeName = RuntimeTypeInfo.SanitizeFullName(attributeDescriptor.TypeName);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Assert.Equal(
|
|
||||||
expectedAttributeDescriptors,
|
|
||||||
descriptor.Attributes,
|
|
||||||
TagHelperAttributeDescriptorComparer.Default);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,625 +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.ComponentModel;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
|
||||||
using Microsoft.AspNet.Razor.TagHelpers;
|
|
||||||
using Microsoft.AspNet.Testing;
|
|
||||||
using Microsoft.CodeAnalysis.CSharp;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|
||||||
{
|
|
||||||
public class PrecompilationTagHelperTypeResolverTest
|
|
||||||
{
|
|
||||||
private static readonly ITypeInfo TagHelperTypeInfo = new RuntimeTypeInfo(typeof(ITagHelper).GetTypeInfo());
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(typeof(TypeDerivingFromITagHelper))]
|
|
||||||
[InlineData(typeof(AttributeTargetingTagHelper))]
|
|
||||||
[InlineData(typeof(TagHelperInGlobalNamespace))]
|
|
||||||
public void TypesReturnedFromGetTopLevelExportedTypes_ReturnsTopLevelTypeInfo(Type expected)
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var compilation = CompilationUtility.GetCompilation("TagHelperDescriptorFactoryTagHelpers");
|
|
||||||
var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
var actual = Assert.Single(exportedTypes, type => type.FullName == expected.FullName);
|
|
||||||
AssertEqual(expected, actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void ImplementsInterface_ThrowsIfPassedInParameterIsNotRuntimeTypeOrCodeAnalysisBasedTypeInfo()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var interfaceType = new TestTypeInfo();
|
|
||||||
var compilation = CompilationUtility.GetCompilation(nameof(DerivingFromList));
|
|
||||||
var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
var actual = Assert.Single(exportedTypes);
|
|
||||||
ExceptionAssert.ThrowsArgument(() => actual.ImplementsInterface(interfaceType),
|
|
||||||
"interfaceTypeInfo",
|
|
||||||
$"Argument must be an instance of '{typeof(RuntimeTypeInfo)}' or '{typeof(CodeAnalysisSymbolBasedTypeInfo)}'.");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(typeof(DerivingFromList))]
|
|
||||||
[InlineData(typeof(DerivingFromIList))]
|
|
||||||
public void ImplementsInterface_ReturnsTrueIfTypeDerivesFromInterface(Type expected)
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var interfaceType = new RuntimeTypeInfo(typeof(IEnumerable<string>).GetTypeInfo());
|
|
||||||
var compilation = CompilationUtility.GetCompilation(expected.Name);
|
|
||||||
var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
var actual = Assert.Single(exportedTypes);
|
|
||||||
Assert.True(actual.ImplementsInterface(interfaceType));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(typeof(TagHelper))]
|
|
||||||
[InlineData(typeof(IEnumerable<string>))]
|
|
||||||
public void ImplementsInterface_ReturnsFalseIfTypeDoesNotDerivesFromInterface(Type interfaceType)
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var interfaceTypeInfo = new RuntimeTypeInfo(interfaceType.GetTypeInfo());
|
|
||||||
var compilation = CompilationUtility.GetCompilation("TagHelperDescriptorFactoryTagHelpers");
|
|
||||||
var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
var actual = Assert.Single(exportedTypes, type => type.Name == nameof(RequiredParentTagHelper));
|
|
||||||
Assert.False(actual.ImplementsInterface(interfaceTypeInfo));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void PropertyNamesForComplexPropertiesAreGeneratedCorrectly()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var expectedType = typeof(TypeWithComplexPropertyFullNames);
|
|
||||||
var compilation = CompilationUtility.GetCompilation(expectedType.Name);
|
|
||||||
var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
var actual = Assert.Single(exportedTypes);
|
|
||||||
AssertEqual(expectedType, actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void PropertyNamesForArrayPropertiesAreGeneratedCorrectly()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var expectedType = typeof(TypeWithArrayProperties);
|
|
||||||
var compilation = CompilationUtility.GetCompilation(expectedType.Name);
|
|
||||||
var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
var actual = Assert.Single(exportedTypes);
|
|
||||||
AssertEqual(expectedType, actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void GetTopLevelExportedTypes_DoesNotReturnNonPublicOrNestedTypes()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var compilation = CompilationUtility.GetCompilation("AssemblyWithNonPublicTypes");
|
|
||||||
var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Collection(exportedTypes,
|
|
||||||
typeInfo =>
|
|
||||||
{
|
|
||||||
AssertEqual(typeof(PublicType), typeInfo);
|
|
||||||
},
|
|
||||||
typeInfo =>
|
|
||||||
{
|
|
||||||
AssertEqual(typeof(ContainerType), typeInfo);
|
|
||||||
},
|
|
||||||
typeInfo =>
|
|
||||||
{
|
|
||||||
AssertEqual(typeof(GenericType<>), typeInfo);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void GetTopLevelExportedTypes_DoesNotReturnValueTypesOrInterfaces()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var compilation = CompilationUtility.GetCompilation("AssemblyWithNonTypes");
|
|
||||||
var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Collection(exportedTypes,
|
|
||||||
typeInfo =>
|
|
||||||
{
|
|
||||||
AssertEqual(typeof(MyAbstractClass), typeInfo);
|
|
||||||
},
|
|
||||||
typeInfo =>
|
|
||||||
{
|
|
||||||
AssertEqual(typeof(MyPartialClass), typeInfo);
|
|
||||||
},
|
|
||||||
typeInfo =>
|
|
||||||
{
|
|
||||||
AssertEqual(typeof(MySealedClass), typeInfo);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void GetExportedTypes_PopulatesAttributes()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var expected = typeof(TypeWithAttributes).GetTypeInfo();
|
|
||||||
var compilation = CompilationUtility.GetCompilation(expected.Name);
|
|
||||||
var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
var actual = Assert.Single(exportedTypes);
|
|
||||||
AssertEqual(expected.AsType(), actual);
|
|
||||||
|
|
||||||
AssertAttributes<HtmlTargetElementAttribute>(
|
|
||||||
expected,
|
|
||||||
actual,
|
|
||||||
(expectedAttribute, actualAttribute) =>
|
|
||||||
{
|
|
||||||
Assert.Equal(expectedAttribute.Tag, actualAttribute.Tag);
|
|
||||||
Assert.Equal(expectedAttribute.Attributes, actualAttribute.Attributes);
|
|
||||||
},
|
|
||||||
discoveredAttributes => discoveredAttributes.OrderBy(attribute => attribute.Tag));
|
|
||||||
|
|
||||||
// Verify if enum in attribute constructors works.
|
|
||||||
AssertAttributes<EditorBrowsableAttribute>(
|
|
||||||
expected,
|
|
||||||
actual,
|
|
||||||
(expectedAttribute, actualAttribute) =>
|
|
||||||
{
|
|
||||||
Assert.Equal(expectedAttribute.State, actualAttribute.State);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Verify if enum in attribute property works.
|
|
||||||
AssertAttributes<EnumPropertyAttribute>(
|
|
||||||
expected,
|
|
||||||
actual,
|
|
||||||
(expectedAttribute, actualAttribute) =>
|
|
||||||
{
|
|
||||||
Assert.Equal(expectedAttribute.DayOfWeek, actualAttribute.DayOfWeek);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Verify if Type in attribute constructor and property works.
|
|
||||||
AssertAttributes<CustomValidationAttribute>(
|
|
||||||
expected,
|
|
||||||
actual,
|
|
||||||
(expectedAttribute, actualAttribute) =>
|
|
||||||
{
|
|
||||||
Assert.Same(expectedAttribute.ValidatorType, actualAttribute.ValidatorType);
|
|
||||||
Assert.Equal(expectedAttribute.Method, actualAttribute.Method);
|
|
||||||
Assert.Same(
|
|
||||||
expectedAttribute.ErrorMessageResourceType,
|
|
||||||
actualAttribute.ErrorMessageResourceType);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Verify if array arguments work in constructor.
|
|
||||||
AssertAttributes<RestrictChildrenAttribute>(
|
|
||||||
expected,
|
|
||||||
actual,
|
|
||||||
(expectedAttribute, actualAttribute) =>
|
|
||||||
{
|
|
||||||
Assert.Equal(
|
|
||||||
expectedAttribute.ChildTags,
|
|
||||||
actualAttribute.ChildTags);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Complex array bindings
|
|
||||||
AssertAttributes<ArrayPropertiesAttribute>(
|
|
||||||
expected,
|
|
||||||
actual,
|
|
||||||
(expectedAttribute, actualAttribute) =>
|
|
||||||
{
|
|
||||||
Assert.Equal(expectedAttribute.ArrayOfTypes, actualAttribute.ArrayOfTypes);
|
|
||||||
Assert.Equal(expectedAttribute.ArrayOfInts, actualAttribute.ArrayOfInts);
|
|
||||||
Assert.Equal(expectedAttribute.Days, actualAttribute.Days);
|
|
||||||
});
|
|
||||||
|
|
||||||
var expectedProperties = expected.DeclaredProperties;
|
|
||||||
Assert.Collection(actual.Properties,
|
|
||||||
property =>
|
|
||||||
{
|
|
||||||
Assert.Equal(nameof(TypeWithAttributes.Src), property.Name);
|
|
||||||
var expectedProperty = Assert.Single(expectedProperties, p => p.Name == property.Name);
|
|
||||||
AssertAttributes<HtmlAttributeNameAttribute>(
|
|
||||||
expectedProperty,
|
|
||||||
property,
|
|
||||||
(expectedAttribute, actualAttribute) =>
|
|
||||||
{
|
|
||||||
Assert.Equal(expectedAttribute.Name, actualAttribute.Name);
|
|
||||||
Assert.Equal(expectedAttribute.DictionaryAttributePrefix, actualAttribute.DictionaryAttributePrefix);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Verify boolean values bind.
|
|
||||||
AssertAttributes<RequiredAttribute>(
|
|
||||||
expectedProperty,
|
|
||||||
property,
|
|
||||||
(expectedAttribute, actualAttribute) =>
|
|
||||||
{
|
|
||||||
Assert.Equal(expectedAttribute.AllowEmptyStrings, actualAttribute.AllowEmptyStrings);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
property =>
|
|
||||||
{
|
|
||||||
Assert.Equal(nameof(TypeWithAttributes.AppendVersion), property.Name);
|
|
||||||
var expectedProperty = Assert.Single(expectedProperties, p => p.Name == property.Name);
|
|
||||||
AssertAttributes<HtmlAttributeNameAttribute>(
|
|
||||||
expectedProperty,
|
|
||||||
property,
|
|
||||||
(expectedAttribute, actualAttribute) =>
|
|
||||||
{
|
|
||||||
Assert.Equal(expectedAttribute.Name, actualAttribute.Name);
|
|
||||||
Assert.Equal(expectedAttribute.DictionaryAttributePrefix, actualAttribute.DictionaryAttributePrefix);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Attribute without constructor arguments or properties.
|
|
||||||
Assert.Single(expectedProperty.GetCustomAttributes<HtmlAttributeNotBoundAttribute>());
|
|
||||||
Assert.Single(property.GetCustomAttributes<HtmlAttributeNotBoundAttribute>());
|
|
||||||
},
|
|
||||||
property =>
|
|
||||||
{
|
|
||||||
Assert.Equal(nameof(TypeWithAttributes.ViewContext), property.Name);
|
|
||||||
var expectedProperty = Assert.Single(expectedProperties, p => p.Name == property.Name);
|
|
||||||
|
|
||||||
AssertAttributes<EditorBrowsableAttribute>(
|
|
||||||
expectedProperty,
|
|
||||||
property,
|
|
||||||
(expectedAttribute, actualAttribute) =>
|
|
||||||
{
|
|
||||||
Assert.Equal(expectedAttribute.State, actualAttribute.State);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Complex array bindings in properties
|
|
||||||
AssertAttributes<ArrayPropertiesAttribute>(
|
|
||||||
expected,
|
|
||||||
actual,
|
|
||||||
(expectedAttribute, actualAttribute) =>
|
|
||||||
{
|
|
||||||
Assert.Equal(expectedAttribute.ArrayOfTypes, actualAttribute.ArrayOfTypes);
|
|
||||||
Assert.Equal(expectedAttribute.ArrayOfInts, actualAttribute.ArrayOfInts);
|
|
||||||
Assert.Equal(expectedAttribute.Days, actualAttribute.Days);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
property =>
|
|
||||||
{
|
|
||||||
Assert.Equal("HostingEnvironment", property.Name);
|
|
||||||
Assert.Single(expectedProperties, p => p.Name == property.Name);
|
|
||||||
|
|
||||||
// Complex array bindings in constructor arguments
|
|
||||||
AssertAttributes<AttributesWithArrayConstructorArgumentsAttribute>(
|
|
||||||
expected,
|
|
||||||
actual,
|
|
||||||
(expectedAttribute, actualAttribute) =>
|
|
||||||
{
|
|
||||||
Assert.Equal(expectedAttribute.StringArgs, actualAttribute.StringArgs);
|
|
||||||
Assert.Equal(expectedAttribute.IntArgs, actualAttribute.IntArgs);
|
|
||||||
Assert.Equal(expectedAttribute.TypeArgs, actualAttribute.TypeArgs);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void GetExportedTypes_WithDerivedAttributes()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var expected = typeof(DerivedTagHelper);
|
|
||||||
var compilation = CompilationUtility.GetCompilation("TagHelperDescriptorFactoryTagHelpers");
|
|
||||||
var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
var actual = Assert.Single(exportedTypes, type => type.Name == expected.Name);
|
|
||||||
AssertEqual(expected, actual);
|
|
||||||
|
|
||||||
var expectedProperties = expected.GetProperties();
|
|
||||||
AssertAttributes<BaseAttribute>(
|
|
||||||
expectedProperties.First(p => p.Name == nameof(DerivedTagHelper.DerivedProperty)),
|
|
||||||
actual.Properties.First(p => p.Name == nameof(DerivedTagHelper.DerivedProperty)),
|
|
||||||
(expectedAttribute, actualAttribute) =>
|
|
||||||
{
|
|
||||||
Assert.Equal(expectedAttribute.BaseProperty, actualAttribute.BaseProperty);
|
|
||||||
});
|
|
||||||
|
|
||||||
AssertAttributes<HtmlAttributeNameAttribute>(
|
|
||||||
expectedProperties.First(p => p.Name == nameof(DerivedTagHelper.NewProperty) &&
|
|
||||||
p.PropertyType == typeof(Type)),
|
|
||||||
actual.Properties.First(p => p.Name == nameof(DerivedTagHelper.NewProperty) &&
|
|
||||||
p.PropertyType.Name == typeof(Type).Name),
|
|
||||||
(expectedAttribute, actualAttribute) =>
|
|
||||||
{
|
|
||||||
Assert.Equal(expectedAttribute.Name, actualAttribute.Name);
|
|
||||||
Assert.Equal(
|
|
||||||
expectedAttribute.DictionaryAttributePrefix,
|
|
||||||
actualAttribute.DictionaryAttributePrefix);
|
|
||||||
});
|
|
||||||
|
|
||||||
var expectedVirtualProperty = expectedProperties.First(
|
|
||||||
p => p.Name == nameof(DerivedTagHelper.VirtualProperty));
|
|
||||||
var actualVirtualProperty = actual.Properties.First(
|
|
||||||
p => p.Name == nameof(DerivedTagHelper.VirtualProperty));
|
|
||||||
|
|
||||||
Assert.Empty(expectedVirtualProperty.GetCustomAttributes<HtmlAttributeNotBoundAttribute>());
|
|
||||||
Assert.Empty(actualVirtualProperty.GetCustomAttributes<HtmlAttributeNotBoundAttribute>());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void GetExportedTypes_CorrectlyIdentifiesIfTypeDerivesFromDictionary()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var compilation = CompilationUtility.GetCompilation(nameof(TypeWithDictionaryProperties));
|
|
||||||
var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
var exportedType = Assert.Single(exportedTypes);
|
|
||||||
AssertEqual(typeof(TypeWithDictionaryProperties), exportedType);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void GetExportedTypes_WorksCorrectlyForOverridenProperties()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var compilation = CompilationUtility.GetCompilation("TypesWithInheritedProperties");
|
|
||||||
var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Collection(exportedTypes,
|
|
||||||
typeInfo =>
|
|
||||||
{
|
|
||||||
AssertEqual(typeof(Animal), typeInfo);
|
|
||||||
},
|
|
||||||
typeInfo =>
|
|
||||||
{
|
|
||||||
AssertEqual(typeof(Mammal), typeInfo);
|
|
||||||
},
|
|
||||||
typeInfo =>
|
|
||||||
{
|
|
||||||
AssertEqual(typeof(Dog), typeInfo);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void GetExportedTypes_WorksIfAttributeConstructorArgumentsAreOutOfOrder()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var expectedType = typeof(TypeWithNamedAttributes);
|
|
||||||
var compilation = CompilationUtility.GetCompilation(expectedType.Name);
|
|
||||||
var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
var exportedType = Assert.Single(exportedTypes);
|
|
||||||
AssertEqual(expectedType, exportedType);
|
|
||||||
|
|
||||||
var attributes = exportedType.GetCustomAttributes<MultipleConstructorArgumentsAttribute>();
|
|
||||||
|
|
||||||
AssertAttributes<MultipleConstructorArgumentsAttribute>(
|
|
||||||
expectedType.GetTypeInfo(),
|
|
||||||
exportedType,
|
|
||||||
(expectedAttribute, actualAttribute) =>
|
|
||||||
{
|
|
||||||
Assert.Equal(expectedAttribute.FirstArgument, actualAttribute.FirstArgument);
|
|
||||||
Assert.Equal(expectedAttribute.SecondArgument, actualAttribute.SecondArgument);
|
|
||||||
Assert.Equal(expectedAttribute.ThirdArgument, actualAttribute.ThirdArgument);
|
|
||||||
},
|
|
||||||
discoveredAttributes => discoveredAttributes.OrderBy(attribute => attribute.FirstArgument));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void GetExportedTypes_WorksIfAttributesAreMalformedErrors()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var compilation = CompilationUtility.GetCompilation("BadFiles.TypeWithMalformedAttribute");
|
|
||||||
var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
var actual = Assert.Single(exportedTypes);
|
|
||||||
var targetElementAttribute = Assert.Single(actual.GetCustomAttributes<HtmlTargetElementAttribute>());
|
|
||||||
Assert.Equal("img", targetElementAttribute.Tag);
|
|
||||||
Assert.Null(targetElementAttribute.Attributes);
|
|
||||||
|
|
||||||
Assert.Empty(actual.GetCustomAttributes<EditorBrowsableAttribute>());
|
|
||||||
var ex = Assert.Throws<InvalidOperationException>(
|
|
||||||
() => actual.GetCustomAttributes<CustomValidationAttribute>());
|
|
||||||
Assert.Equal($"Unable to find a suitable constructor for type '{typeof(CustomValidationAttribute).FullName}'.",
|
|
||||||
ex.Message);
|
|
||||||
|
|
||||||
ex = Assert.Throws<InvalidOperationException>(
|
|
||||||
() => actual.GetCustomAttributes<RestrictChildrenAttribute>());
|
|
||||||
Assert.Equal($"Unable to find a suitable constructor for type '{typeof(RestrictChildrenAttribute).FullName}'.",
|
|
||||||
ex.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void GetExportedTypes_WorksForPropertiesWithErrors()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var compilation = CompilationUtility.GetCompilation("BadFiles.TypeWithMalformedProperties");
|
|
||||||
var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
var actual = Assert.Single(exportedTypes);
|
|
||||||
Assert.Collection(actual.Properties,
|
|
||||||
property =>
|
|
||||||
{
|
|
||||||
Assert.Equal("DateTime", property.Name);
|
|
||||||
Assert.Equal(typeof(DateTime).Name, property.PropertyType.Name);
|
|
||||||
Assert.True(property.HasPublicGetter);
|
|
||||||
Assert.False(property.HasPublicSetter);
|
|
||||||
},
|
|
||||||
property =>
|
|
||||||
{
|
|
||||||
Assert.Equal("DateTime2", property.Name);
|
|
||||||
Assert.Equal(typeof(int).Name, property.PropertyType.Name);
|
|
||||||
Assert.True(property.HasPublicGetter);
|
|
||||||
Assert.False(property.HasPublicSetter);
|
|
||||||
},
|
|
||||||
property =>
|
|
||||||
{
|
|
||||||
Assert.Equal("CustomOrder", property.Name);
|
|
||||||
Assert.Equal(typeof(string).Name, property.PropertyType.Name);
|
|
||||||
Assert.True(property.HasPublicGetter);
|
|
||||||
Assert.True(property.HasPublicSetter);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void GetExportedTypes_WorksForTypesWithErrors()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var compilation = CompilationUtility.GetCompilation("BadFiles.TypeWithMissingReferences");
|
|
||||||
var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
var type = Assert.Single(exportedTypes);
|
|
||||||
Assert.False(type.ImplementsInterface(TagHelperTypeInfo));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void AssertAttributes<TAttribute>(
|
|
||||||
MemberInfo expected,
|
|
||||||
IMemberInfo actual,
|
|
||||||
Action<TAttribute, TAttribute> assertItem)
|
|
||||||
where TAttribute : Attribute
|
|
||||||
{
|
|
||||||
AssertAttributes(expected, actual, assertItem, attributes => attributes);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void AssertAttributes<TAttribute>(
|
|
||||||
MemberInfo expected,
|
|
||||||
IMemberInfo actual,
|
|
||||||
Action<TAttribute, TAttribute> assertItem,
|
|
||||||
Func<IEnumerable<TAttribute>, IEnumerable<TAttribute>> reorderDiscoveredAttributes)
|
|
||||||
where TAttribute : Attribute
|
|
||||||
{
|
|
||||||
var expectedAttributes = reorderDiscoveredAttributes(expected.GetCustomAttributes<TAttribute>());
|
|
||||||
var actualAttributes = reorderDiscoveredAttributes(actual.GetCustomAttributes<TAttribute>());
|
|
||||||
|
|
||||||
Assert.Equal(expectedAttributes, actualAttributes, new DelegateAssertion<TAttribute>(assertItem));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void AssertEqual(Type expected, ITypeInfo actual)
|
|
||||||
{
|
|
||||||
AssertEqual(new RuntimeTypeInfo(expected.GetTypeInfo()), actual, assertProperties: true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void AssertEqual(ITypeInfo expected, ITypeInfo actual, bool assertProperties)
|
|
||||||
{
|
|
||||||
var runtimeType = Assert.IsType<RuntimeTypeInfo>(expected);
|
|
||||||
|
|
||||||
var actualFullName = actual.FullName.Replace(
|
|
||||||
CompilationUtility.GeneratedAssemblyName,
|
|
||||||
runtimeType.TypeInfo.Assembly.GetName().Name);
|
|
||||||
|
|
||||||
Assert.Equal(expected.Name, actual.Name);
|
|
||||||
#if DNXCORE50
|
|
||||||
Assert.Equal(
|
|
||||||
RuntimeTypeInfo.SanitizeFullName(expected.FullName),
|
|
||||||
RuntimeTypeInfo.SanitizeFullName(actualFullName));
|
|
||||||
#endif
|
|
||||||
Assert.Equal(expected.IsPublic, actual.IsPublic);
|
|
||||||
Assert.Equal(expected.IsAbstract, actual.IsAbstract);
|
|
||||||
Assert.Equal(expected.IsGenericType, actual.IsGenericType);
|
|
||||||
Assert.Equal(
|
|
||||||
expected.ImplementsInterface(TagHelperTypeInfo),
|
|
||||||
actual.ImplementsInterface(TagHelperTypeInfo));
|
|
||||||
Assert.Equal(
|
|
||||||
expected.GetGenericDictionaryParameters(),
|
|
||||||
actual.GetGenericDictionaryParameters(),
|
|
||||||
new DelegateAssertion<ITypeInfo>((x, y) => AssertEqual(x, y, assertProperties: false)));
|
|
||||||
|
|
||||||
if (assertProperties)
|
|
||||||
{
|
|
||||||
Assert.Equal(
|
|
||||||
expected.Properties.OrderBy(p => p.Name),
|
|
||||||
actual.Properties.OrderBy(p => p.Name),
|
|
||||||
new DelegateAssertion<IPropertyInfo>((x, y) => AssertEqual(x, y)));
|
|
||||||
}
|
|
||||||
|
|
||||||
Assert.True(actual.Equals(expected));
|
|
||||||
Assert.True(expected.Equals(actual));
|
|
||||||
Assert.Equal(expected.GetHashCode(), actual.GetHashCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void AssertEqual(IPropertyInfo expected, IPropertyInfo actual)
|
|
||||||
{
|
|
||||||
Assert.Equal(expected.Name, actual.Name);
|
|
||||||
Assert.Equal(expected.HasPublicGetter, actual.HasPublicGetter);
|
|
||||||
Assert.Equal(expected.HasPublicSetter, actual.HasPublicSetter);
|
|
||||||
AssertEqual(expected.PropertyType, actual.PropertyType, assertProperties: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class DelegateAssertion<T> : IEqualityComparer<T>
|
|
||||||
{
|
|
||||||
private readonly Action<T, T> _assert;
|
|
||||||
|
|
||||||
public DelegateAssertion(Action<T, T> assert)
|
|
||||||
{
|
|
||||||
_assert = assert;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Equals(T x, T y)
|
|
||||||
{
|
|
||||||
_assert(x, y);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetHashCode(T obj) => 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
{
|
|
||||||
"version": "1.0.0",
|
|
||||||
"compilationOptions": {
|
|
||||||
"warningsAsErrors": true,
|
|
||||||
"keyFile": "../../tools/Key.snk"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"Microsoft.AspNet.Razor.Runtime.Precompilation.Files": "1.0.0-*",
|
|
||||||
"Microsoft.AspNet.Razor.Runtime.Test": "1.0.0-*",
|
|
||||||
"Microsoft.AspNet.Razor.Test.Sources": {
|
|
||||||
"version": "4.0.0-*",
|
|
||||||
"type": "build"
|
|
||||||
},
|
|
||||||
"Microsoft.Dnx.Compilation.CSharp.Common": "1.0.0-*",
|
|
||||||
"Microsoft.Extensions.HashCodeCombiner.Sources": {
|
|
||||||
"type": "build",
|
|
||||||
"version": "1.0.0-*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"resource": [
|
|
||||||
"../Microsoft.AspNet.Razor.Runtime.Precompilation.Files/*.cs",
|
|
||||||
"../Microsoft.AspNet.Razor.Runtime.Test/Runtime/TagHelpers/TestTagHelpers/*.cs",
|
|
||||||
"BadFiles/*.cs"
|
|
||||||
],
|
|
||||||
"commands": {
|
|
||||||
"test": "xunit.runner.aspnet"
|
|
||||||
},
|
|
||||||
"frameworks": {
|
|
||||||
"dnx451": {
|
|
||||||
"frameworkAssemblies": {
|
|
||||||
"System.Text.Encoding": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dnxcore50": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue