Replace SymbolLookupCache with comparing FullNames for symbols.
This commit is contained in:
parent
381c055e2f
commit
0376550f2d
|
|
@ -28,33 +28,29 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|||
/// </summary>
|
||||
/// <typeparam name="TAttribute">The <see cref="Attribute"/> type.</typeparam>
|
||||
/// <param name="symbol">The <see cref="ISymbol"/> to find attributes on.</param>
|
||||
/// <param name="symbolLookup">The <see cref="CodeAnalysisSymbolLookupCache"/>.</param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<TAttribute> GetCustomAttributes<TAttribute>(
|
||||
[NotNull] ISymbol symbol,
|
||||
[NotNull] CodeAnalysisSymbolLookupCache symbolLookup)
|
||||
public static IEnumerable<TAttribute> GetCustomAttributes<TAttribute>([NotNull] ISymbol symbol)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
var attributes = symbol.GetAttributes();
|
||||
if (attributes.Length > 0)
|
||||
{
|
||||
var attributeSymbol = symbolLookup.GetSymbol(typeof(TAttribute).GetTypeInfo());
|
||||
return attributes
|
||||
.Where(attribute => attribute.AttributeClass == attributeSymbol)
|
||||
.Select(attribute => CreateAttribute<TAttribute>(attribute, symbolLookup))
|
||||
.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,
|
||||
CodeAnalysisSymbolLookupCache symbolLookup)
|
||||
private static TAttribute CreateAttribute<TAttribute>(AttributeData attributeData)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
TAttribute attribute;
|
||||
var matchInfo = MatchConstructor(typeof(TAttribute), attributeData.ConstructorArguments, symbolLookup);
|
||||
var matchInfo = MatchConstructor(typeof(TAttribute), attributeData.ConstructorArguments);
|
||||
Func<object[], Attribute> constructorDelegate;
|
||||
if (!_constructorCache.TryGetValue(matchInfo.Constructor, out constructorDelegate))
|
||||
{
|
||||
|
|
@ -80,8 +76,7 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|||
|
||||
var propertyValue = ConvertTypedConstantValue(
|
||||
helper.Property.PropertyType,
|
||||
item.Value,
|
||||
symbolLookup);
|
||||
item.Value);
|
||||
helper.SetValue(attribute, propertyValue);
|
||||
}
|
||||
}
|
||||
|
|
@ -117,10 +112,9 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|||
|
||||
private static ConstructorMatchInfo MatchConstructor(
|
||||
Type type,
|
||||
ImmutableArray<TypedConstant> symbolConstructorArguments,
|
||||
CodeAnalysisSymbolLookupCache symbolLookup)
|
||||
ImmutableArray<TypedConstant> symbolConstructorArguments)
|
||||
{
|
||||
var constructor = FindConstructor(type, symbolConstructorArguments, symbolLookup);
|
||||
var constructor = FindConstructor(type, symbolConstructorArguments);
|
||||
var constructorParmaters = constructor.GetParameters();
|
||||
|
||||
var arguments = new object[symbolConstructorArguments.Length];
|
||||
|
|
@ -128,8 +122,7 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|||
{
|
||||
var value = ConvertTypedConstantValue(
|
||||
constructorParmaters[i].ParameterType,
|
||||
symbolConstructorArguments[i],
|
||||
symbolLookup);
|
||||
symbolConstructorArguments[i]);
|
||||
|
||||
arguments[i] = value;
|
||||
}
|
||||
|
|
@ -143,8 +136,7 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|||
|
||||
private static ConstructorInfo FindConstructor(
|
||||
Type type,
|
||||
ImmutableArray<TypedConstant> symbolConstructorArguments,
|
||||
CodeAnalysisSymbolLookupCache symbolLookup)
|
||||
ImmutableArray<TypedConstant> symbolConstructorArguments)
|
||||
{
|
||||
var constructors = type.GetConstructors();
|
||||
foreach (var constructor in constructors)
|
||||
|
|
@ -163,8 +155,9 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|||
runtimeParameter.IsArray)
|
||||
{
|
||||
var arrayType = (IArrayTypeSymbol)symbolConstructorArguments[index].Type;
|
||||
if (symbolLookup.GetSymbol(runtimeParameter.GetElementType().GetTypeInfo()) !=
|
||||
arrayType.ElementType)
|
||||
if (!CodeAnalysisSymbolBasedTypeInfo.IsType(
|
||||
arrayType.ElementType,
|
||||
runtimeParameter.GetElementType().GetTypeInfo()))
|
||||
{
|
||||
parametersMatched = false;
|
||||
break;
|
||||
|
|
@ -172,8 +165,9 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|||
}
|
||||
else
|
||||
{
|
||||
var parameterSymbol = symbolLookup.GetSymbol(runtimeParameter.GetTypeInfo());
|
||||
if (symbolConstructorArguments[index].Type != parameterSymbol)
|
||||
if (!CodeAnalysisSymbolBasedTypeInfo.IsType(
|
||||
symbolConstructorArguments[index].Type,
|
||||
runtimeParameter.GetTypeInfo()))
|
||||
{
|
||||
parametersMatched = false;
|
||||
break;
|
||||
|
|
@ -192,8 +186,7 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|||
|
||||
private static object ConvertTypedConstantValue(
|
||||
Type type,
|
||||
TypedConstant constructorArgument,
|
||||
CodeAnalysisSymbolLookupCache symbolLookup)
|
||||
TypedConstant constructorArgument)
|
||||
{
|
||||
switch (constructorArgument.Kind)
|
||||
{
|
||||
|
|
@ -212,7 +205,7 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|||
for (var index = 0; index < values.Length; index++)
|
||||
{
|
||||
values.SetValue(
|
||||
ConvertTypedConstantValue(elementType, constructorArgument.Values[index], symbolLookup),
|
||||
ConvertTypedConstantValue(elementType, constructorArgument.Values[index]),
|
||||
index);
|
||||
}
|
||||
return values;
|
||||
|
|
|
|||
|
|
@ -17,20 +17,15 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|||
public class CodeAnalysisSymbolBasedPropertyInfo : IPropertyInfo
|
||||
{
|
||||
private readonly IPropertySymbol _propertySymbol;
|
||||
private readonly CodeAnalysisSymbolLookupCache _symbolLookup;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="CodeAnalysisSymbolBasedPropertyInfo"/>.
|
||||
/// </summary>
|
||||
/// <param name="propertySymbol">The <see cref="IPropertySymbol"/>.</param>
|
||||
/// <param name="symbolLookup">The <see cref="CodeAnalysisSymbolLookupCache"/>.</param>
|
||||
public CodeAnalysisSymbolBasedPropertyInfo(
|
||||
[NotNull] IPropertySymbol propertySymbol,
|
||||
[NotNull] CodeAnalysisSymbolLookupCache symbolLookup)
|
||||
public CodeAnalysisSymbolBasedPropertyInfo([NotNull] IPropertySymbol propertySymbol)
|
||||
{
|
||||
_symbolLookup = symbolLookup;
|
||||
_propertySymbol = propertySymbol;
|
||||
PropertyType = new CodeAnalysisSymbolBasedTypeInfo(_propertySymbol.Type, _symbolLookup);
|
||||
PropertyType = new CodeAnalysisSymbolBasedTypeInfo(_propertySymbol.Type);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
@ -63,7 +58,7 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|||
public IEnumerable<TAttribute> GetCustomAttributes<TAttribute>()
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return CodeAnalysisAttributeUtilities.GetCustomAttributes<TAttribute>(_propertySymbol, _symbolLookup);
|
||||
return CodeAnalysisAttributeUtilities.GetCustomAttributes<TAttribute>(_propertySymbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|||
/// </summary>
|
||||
public static readonly System.Reflection.TypeInfo OpenGenericDictionaryTypeInfo =
|
||||
typeof(IDictionary<,>).GetTypeInfo();
|
||||
private readonly CodeAnalysisSymbolLookupCache _symbolLookup;
|
||||
private static readonly System.Reflection.TypeInfo TagHelperTypeInfo =
|
||||
typeof(ITagHelper).GetTypeInfo();
|
||||
private readonly ITypeSymbol _type;
|
||||
private readonly ITypeSymbol _underlyingType;
|
||||
private string _fullName;
|
||||
|
|
@ -34,12 +35,8 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|||
/// Initializes a new instance of <see cref="CodeAnalysisSymbolBasedTypeInfo"/>.
|
||||
/// </summary>
|
||||
/// <param name="propertySymbol">The <see cref="IPropertySymbol"/>.</param>
|
||||
/// <param name="symbolLookup">The <see cref="CodeAnalysisSymbolLookupCache"/>.</param>
|
||||
public CodeAnalysisSymbolBasedTypeInfo(
|
||||
[NotNull] ITypeSymbol type,
|
||||
[NotNull] CodeAnalysisSymbolLookupCache symbolLookup)
|
||||
public CodeAnalysisSymbolBasedTypeInfo([NotNull] ITypeSymbol type)
|
||||
{
|
||||
_symbolLookup = symbolLookup;
|
||||
_type = type;
|
||||
_underlyingType = UnwrapArrayType(type);
|
||||
}
|
||||
|
|
@ -110,7 +107,7 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|||
{
|
||||
if (_properties == null)
|
||||
{
|
||||
_properties = GetProperties(_type, _symbolLookup);
|
||||
_properties = GetProperties(_type);
|
||||
}
|
||||
|
||||
return _properties;
|
||||
|
|
@ -122,8 +119,8 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|||
{
|
||||
get
|
||||
{
|
||||
var interfaceSymbol = _symbolLookup.GetSymbol(typeof(ITagHelper).GetTypeInfo());
|
||||
return _type.AllInterfaces.Any(implementedInterface => implementedInterface == interfaceSymbol);
|
||||
return _type.AllInterfaces.Any(
|
||||
implementedInterface => IsType(implementedInterface, TagHelperTypeInfo));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -131,17 +128,15 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|||
public IEnumerable<TAttribute> GetCustomAttributes<TAttribute>()
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return CodeAnalysisAttributeUtilities.GetCustomAttributes<TAttribute>(_type, _symbolLookup);
|
||||
return CodeAnalysisAttributeUtilities.GetCustomAttributes<TAttribute>(_type);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ITypeInfo[] GetGenericDictionaryParameters()
|
||||
{
|
||||
var dictionarySymbol = _symbolLookup.GetSymbol(OpenGenericDictionaryTypeInfo);
|
||||
|
||||
INamedTypeSymbol dictionaryInterface;
|
||||
if (_type.Kind == SymbolKind.NamedType &&
|
||||
((INamedTypeSymbol)_type).ConstructedFrom == dictionarySymbol)
|
||||
IsType(((INamedTypeSymbol)_type).ConstructedFrom, OpenGenericDictionaryTypeInfo))
|
||||
{
|
||||
dictionaryInterface = (INamedTypeSymbol)_type;
|
||||
}
|
||||
|
|
@ -149,7 +144,8 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|||
{
|
||||
dictionaryInterface = _type
|
||||
.AllInterfaces
|
||||
.FirstOrDefault(implementedInterface => implementedInterface.ConstructedFrom == dictionarySymbol);
|
||||
.FirstOrDefault(implementedInterface =>
|
||||
IsType(implementedInterface.ConstructedFrom, OpenGenericDictionaryTypeInfo));
|
||||
}
|
||||
|
||||
if (dictionaryInterface != null)
|
||||
|
|
@ -158,14 +154,32 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|||
|
||||
return new[]
|
||||
{
|
||||
new CodeAnalysisSymbolBasedTypeInfo(dictionaryInterface.TypeArguments[0], _symbolLookup),
|
||||
new CodeAnalysisSymbolBasedTypeInfo(dictionaryInterface.TypeArguments[1], _symbolLookup),
|
||||
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(
|
||||
targetTypeInfo.FullName,
|
||||
GetFullName(sourceTypeSymbol),
|
||||
StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the assembly qualified named of the specified <paramref name="symbol"/>.
|
||||
/// </summary>
|
||||
|
|
@ -205,9 +219,7 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|||
/// <inheritdoc />
|
||||
public override int GetHashCode() => FullName.GetHashCode();
|
||||
|
||||
private static List<IPropertyInfo> GetProperties(
|
||||
ITypeSymbol typeSymbol,
|
||||
CodeAnalysisSymbolLookupCache symbolLookup)
|
||||
private static List<IPropertyInfo> GetProperties(ITypeSymbol typeSymbol)
|
||||
{
|
||||
var properties = new List<IPropertyInfo>();
|
||||
var overridenProperties = new HashSet<IPropertySymbol>();
|
||||
|
|
@ -219,7 +231,7 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|||
var propertySymbol = (IPropertySymbol)member;
|
||||
if (!propertySymbol.IsIndexer && !overridenProperties.Contains(propertySymbol))
|
||||
{
|
||||
var propertyInfo = new CodeAnalysisSymbolBasedPropertyInfo(propertySymbol, symbolLookup);
|
||||
var propertyInfo = new CodeAnalysisSymbolBasedPropertyInfo(propertySymbol);
|
||||
properties.Add(propertyInfo);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,62 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.Framework.Internal;
|
||||
|
||||
namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
||||
{
|
||||
/// <summary>
|
||||
/// Caches mapping of <see cref="System.Reflection.TypeInfo"/> to <see cref="INamedTypeSymbol"/>.
|
||||
/// </summary>
|
||||
public class CodeAnalysisSymbolLookupCache
|
||||
{
|
||||
private readonly Dictionary<System.Reflection.TypeInfo, INamedTypeSymbol> _symbolLookup =
|
||||
new Dictionary<System.Reflection.TypeInfo, INamedTypeSymbol>();
|
||||
private readonly object _lookupLock = new object();
|
||||
private readonly Compilation _compilation;
|
||||
private INamedTypeSymbol _dictionarySymbol;
|
||||
|
||||
/// <summary>
|
||||
/// Initialzes a new instance of <see cref="CodeAnalysisSymbolLookupCache"/>.
|
||||
/// </summary>
|
||||
/// <param name="compilation">The <see cref="Compilation"/> instance.</param>
|
||||
public CodeAnalysisSymbolLookupCache([NotNull] Compilation compilation)
|
||||
{
|
||||
_compilation = compilation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="INamedTypeSymbol"/> that corresponds to <paramref name="typeInfo"/>.
|
||||
/// </summary>
|
||||
/// <param name="typeInfo">The <see cref="System.Reflection.TypeInfo"/> to lookup.</param>
|
||||
/// <returns></returns>
|
||||
public INamedTypeSymbol GetSymbol([NotNull] System.Reflection.TypeInfo typeInfo)
|
||||
{
|
||||
if (typeInfo == CodeAnalysisSymbolBasedTypeInfo.OpenGenericDictionaryTypeInfo)
|
||||
{
|
||||
if (_dictionarySymbol == null)
|
||||
{
|
||||
// Allow safe races
|
||||
_dictionarySymbol = _compilation.GetTypeByMetadataName(
|
||||
CodeAnalysisSymbolBasedTypeInfo.OpenGenericDictionaryTypeInfo.FullName);
|
||||
}
|
||||
|
||||
return _dictionarySymbol;
|
||||
}
|
||||
|
||||
lock (_lookupLock)
|
||||
{
|
||||
INamedTypeSymbol typeSymbol;
|
||||
if (!_symbolLookup.TryGetValue(typeInfo, out typeSymbol))
|
||||
{
|
||||
typeSymbol = _compilation.GetTypeByMetadataName(typeInfo.FullName);
|
||||
_symbolLookup[typeInfo] = typeSymbol;
|
||||
}
|
||||
|
||||
return typeSymbol;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -19,7 +19,6 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|||
private readonly Dictionary<string, IEnumerable<ITypeInfo>> _assemblyLookup
|
||||
= new Dictionary<string, IEnumerable<ITypeInfo>>(StringComparer.Ordinal);
|
||||
private readonly Compilation _compilation;
|
||||
private readonly CodeAnalysisSymbolLookupCache _symbolLookup;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="PrecompilationTagHelperTypeResolver"/>.
|
||||
|
|
@ -28,11 +27,10 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|||
public PrecompilationTagHelperTypeResolver([NotNull] Compilation compilation)
|
||||
{
|
||||
_compilation = compilation;
|
||||
_symbolLookup = new CodeAnalysisSymbolLookupCache(compilation);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IEnumerable<ITypeInfo> GetTopLevelExportedTypes([NotNull] AssemblyName assemblyName)
|
||||
protected override IEnumerable<ITypeInfo> GetTopLevelExportedTypes([NotNull] AssemblyName assemblyName)
|
||||
{
|
||||
lock (_assemblyLookupLock)
|
||||
{
|
||||
|
|
@ -83,21 +81,21 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation
|
|||
Resources.FormatCodeAnalysis_UnableToLoadAssemblyReference(assemblyName));
|
||||
}
|
||||
|
||||
private List<ITypeInfo> GetExportedTypes(IAssemblySymbol assembly)
|
||||
private static List<ITypeInfo> GetExportedTypes(IAssemblySymbol assembly)
|
||||
{
|
||||
var exportedTypes = new List<ITypeInfo>();
|
||||
GetExportedTypes(assembly.GlobalNamespace, exportedTypes);
|
||||
return exportedTypes;
|
||||
}
|
||||
|
||||
private void GetExportedTypes(INamespaceSymbol namespaceSymbol, List<ITypeInfo> 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, _symbolLookup));
|
||||
exportedTypes.Add(new CodeAnalysisSymbolBasedTypeInfo(type));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue