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
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.23107.0
|
||||
VisualStudioVersion = 14.0.24720.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{3C0D6505-79B3-49D0-B4C3-176F0F1836ED}"
|
||||
EndProject
|
||||
|
|
@ -17,12 +17,6 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Razor.Runt
|
|||
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}"
|
||||
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
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
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}.Release|Any CPU.ActiveCfg = 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
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -71,8 +53,5 @@ Global
|
|||
{D0196096-1B01-4133-AACE-1A10A0F7247C} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED}
|
||||
{0535998A-E32C-4D1A-80D1-0B15A513C471} = {92463391-81BE-462B-AC3C-78C6C760741F}
|
||||
{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
|
||||
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