From 0376550f2d49e5c5c14a2b76b1dc8aed99a7a853 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Fri, 11 Sep 2015 11:56:49 -0700 Subject: [PATCH] Replace SymbolLookupCache with comparing FullNames for symbols. --- .../CodeAnalysisAttributeUtilities.cs | 47 ++++++-------- .../CodeAnalysisSymbolBasedPropertyInfo.cs | 11 +--- .../CodeAnalysisSymbolBasedTypeInfo.cs | 52 ++++++++++------ .../CodeAnalysisSymbolLookupCache.cs | 62 ------------------- .../PrecompilationTagHelperTypeResolver.cs | 10 ++- 5 files changed, 59 insertions(+), 123 deletions(-) delete mode 100644 src/Microsoft.AspNet.Razor.Runtime.Precompilation/CodeAnalysisSymbolLookupCache.cs diff --git a/src/Microsoft.AspNet.Razor.Runtime.Precompilation/CodeAnalysisAttributeUtilities.cs b/src/Microsoft.AspNet.Razor.Runtime.Precompilation/CodeAnalysisAttributeUtilities.cs index 36e0b672b1..80cb142361 100644 --- a/src/Microsoft.AspNet.Razor.Runtime.Precompilation/CodeAnalysisAttributeUtilities.cs +++ b/src/Microsoft.AspNet.Razor.Runtime.Precompilation/CodeAnalysisAttributeUtilities.cs @@ -28,33 +28,29 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation /// /// The type. /// The to find attributes on. - /// The . /// - public static IEnumerable GetCustomAttributes( - [NotNull] ISymbol symbol, - [NotNull] CodeAnalysisSymbolLookupCache symbolLookup) + public static IEnumerable GetCustomAttributes([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(attribute, symbolLookup)) + .Where(attribute => CodeAnalysisSymbolBasedTypeInfo.IsType( + attribute.AttributeClass, + typeof(TAttribute).GetTypeInfo())) + .Select(attribute => CreateAttribute(attribute)) .ToArray(); } return Enumerable.Empty(); } - private static TAttribute CreateAttribute( - AttributeData attributeData, - CodeAnalysisSymbolLookupCache symbolLookup) + private static TAttribute CreateAttribute(AttributeData attributeData) where TAttribute : Attribute { TAttribute attribute; - var matchInfo = MatchConstructor(typeof(TAttribute), attributeData.ConstructorArguments, symbolLookup); + var matchInfo = MatchConstructor(typeof(TAttribute), attributeData.ConstructorArguments); Func 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 symbolConstructorArguments, - CodeAnalysisSymbolLookupCache symbolLookup) + ImmutableArray 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 symbolConstructorArguments, - CodeAnalysisSymbolLookupCache symbolLookup) + ImmutableArray 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; diff --git a/src/Microsoft.AspNet.Razor.Runtime.Precompilation/CodeAnalysisSymbolBasedPropertyInfo.cs b/src/Microsoft.AspNet.Razor.Runtime.Precompilation/CodeAnalysisSymbolBasedPropertyInfo.cs index 55bf89a154..df39e07492 100644 --- a/src/Microsoft.AspNet.Razor.Runtime.Precompilation/CodeAnalysisSymbolBasedPropertyInfo.cs +++ b/src/Microsoft.AspNet.Razor.Runtime.Precompilation/CodeAnalysisSymbolBasedPropertyInfo.cs @@ -17,20 +17,15 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation public class CodeAnalysisSymbolBasedPropertyInfo : IPropertyInfo { private readonly IPropertySymbol _propertySymbol; - private readonly CodeAnalysisSymbolLookupCache _symbolLookup; /// /// Initializes a new instance of . /// /// The . - /// The . - 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); } /// @@ -63,7 +58,7 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation public IEnumerable GetCustomAttributes() where TAttribute : Attribute { - return CodeAnalysisAttributeUtilities.GetCustomAttributes(_propertySymbol, _symbolLookup); + return CodeAnalysisAttributeUtilities.GetCustomAttributes(_propertySymbol); } } } diff --git a/src/Microsoft.AspNet.Razor.Runtime.Precompilation/CodeAnalysisSymbolBasedTypeInfo.cs b/src/Microsoft.AspNet.Razor.Runtime.Precompilation/CodeAnalysisSymbolBasedTypeInfo.cs index b5f2364aa8..4d7d8ec776 100644 --- a/src/Microsoft.AspNet.Razor.Runtime.Precompilation/CodeAnalysisSymbolBasedTypeInfo.cs +++ b/src/Microsoft.AspNet.Razor.Runtime.Precompilation/CodeAnalysisSymbolBasedTypeInfo.cs @@ -24,7 +24,8 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation /// 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 . /// /// The . - /// The . - 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 GetCustomAttributes() where TAttribute : Attribute { - return CodeAnalysisAttributeUtilities.GetCustomAttributes(_type, _symbolLookup); + return CodeAnalysisAttributeUtilities.GetCustomAttributes(_type); } /// 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; } + /// + /// Gets a value that indicates if is represented using + /// in the symbol graph. + /// + /// The . + /// The . + /// true if is a symbol for + /// . + public static bool IsType( + ITypeSymbol sourceTypeSymbol, + System.Reflection.TypeInfo targetTypeInfo) + { + return string.Equals( + targetTypeInfo.FullName, + GetFullName(sourceTypeSymbol), + StringComparison.Ordinal); + } + /// /// Gets the assembly qualified named of the specified . /// @@ -205,9 +219,7 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation /// public override int GetHashCode() => FullName.GetHashCode(); - private static List GetProperties( - ITypeSymbol typeSymbol, - CodeAnalysisSymbolLookupCache symbolLookup) + private static List GetProperties(ITypeSymbol typeSymbol) { var properties = new List(); var overridenProperties = new HashSet(); @@ -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); } diff --git a/src/Microsoft.AspNet.Razor.Runtime.Precompilation/CodeAnalysisSymbolLookupCache.cs b/src/Microsoft.AspNet.Razor.Runtime.Precompilation/CodeAnalysisSymbolLookupCache.cs deleted file mode 100644 index 831c606038..0000000000 --- a/src/Microsoft.AspNet.Razor.Runtime.Precompilation/CodeAnalysisSymbolLookupCache.cs +++ /dev/null @@ -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 -{ - /// - /// Caches mapping of to . - /// - public class CodeAnalysisSymbolLookupCache - { - private readonly Dictionary _symbolLookup = - new Dictionary(); - private readonly object _lookupLock = new object(); - private readonly Compilation _compilation; - private INamedTypeSymbol _dictionarySymbol; - - /// - /// Initialzes a new instance of . - /// - /// The instance. - public CodeAnalysisSymbolLookupCache([NotNull] Compilation compilation) - { - _compilation = compilation; - } - - /// - /// Gets a that corresponds to . - /// - /// The to lookup. - /// - 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; - } - } - } -} diff --git a/src/Microsoft.AspNet.Razor.Runtime.Precompilation/PrecompilationTagHelperTypeResolver.cs b/src/Microsoft.AspNet.Razor.Runtime.Precompilation/PrecompilationTagHelperTypeResolver.cs index 6d3252c5ca..eba15977fe 100644 --- a/src/Microsoft.AspNet.Razor.Runtime.Precompilation/PrecompilationTagHelperTypeResolver.cs +++ b/src/Microsoft.AspNet.Razor.Runtime.Precompilation/PrecompilationTagHelperTypeResolver.cs @@ -19,7 +19,6 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation private readonly Dictionary> _assemblyLookup = new Dictionary>(StringComparer.Ordinal); private readonly Compilation _compilation; - private readonly CodeAnalysisSymbolLookupCache _symbolLookup; /// /// Initializes a new instance of . @@ -28,11 +27,10 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation public PrecompilationTagHelperTypeResolver([NotNull] Compilation compilation) { _compilation = compilation; - _symbolLookup = new CodeAnalysisSymbolLookupCache(compilation); } /// - protected override IEnumerable GetTopLevelExportedTypes([NotNull] AssemblyName assemblyName) + protected override IEnumerable GetTopLevelExportedTypes([NotNull] AssemblyName assemblyName) { lock (_assemblyLookupLock) { @@ -83,21 +81,21 @@ namespace Microsoft.AspNet.Razor.Runtime.Precompilation Resources.FormatCodeAnalysis_UnableToLoadAssemblyReference(assemblyName)); } - private List GetExportedTypes(IAssemblySymbol assembly) + private static List GetExportedTypes(IAssemblySymbol assembly) { var exportedTypes = new List(); GetExportedTypes(assembly.GlobalNamespace, exportedTypes); return exportedTypes; } - private void GetExportedTypes(INamespaceSymbol namespaceSymbol, List exportedTypes) + private static void GetExportedTypes(INamespaceSymbol namespaceSymbol, List 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)); } }