Clean up JSON src-gen known-type resolution (#57092)
authorLayomi Akinrinade <laakinri@microsoft.com>
Tue, 10 Aug 2021 23:44:47 +0000 (16:44 -0700)
committerGitHub <noreply@github.com>
Tue, 10 Aug 2021 23:44:47 +0000 (16:44 -0700)
src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs
src/libraries/System.Text.Json/gen/Reflection/MetadataLoadContextInternal.cs

index b763eb5..f761410 100644 (file)
@@ -101,39 +101,39 @@ namespace System.Text.Json.SourceGeneration
                 _executionContext = executionContext;
                 _metadataLoadContext = new MetadataLoadContextInternal(executionContext.Compilation);
 
-                _ilistOfTType = ResolveType(SpecialType.System_Collections_Generic_IList_T);
-                _icollectionOfTType = ResolveType(SpecialType.System_Collections_Generic_ICollection_T);
-                _ienumerableOfTType = ResolveType(SpecialType.System_Collections_Generic_IEnumerable_T);
-                _ienumerableType = ResolveType(SpecialType.System_Collections_IEnumerable);
-
-                _listOfTType = ResolveType(typeof(List<>).FullName!);
-                _dictionaryType = ResolveType(typeof(Dictionary<,>).FullName!);
-                _idictionaryOfTKeyTValueType = ResolveType(typeof(IDictionary<,>).FullName!);
-                _ireadonlyDictionaryType = ResolveType(typeof(IReadOnlyDictionary<,>).FullName!);
-                _isetType = ResolveType(typeof(ISet<>).FullName!);
-                _stackOfTType = ResolveType(typeof(Stack<>).FullName!);
-                _queueOfTType = ResolveType(typeof(Queue<>).FullName!);
-                _concurrentStackType = ResolveType(typeof(ConcurrentStack<>).FullName!);
-                _concurrentQueueType = ResolveType(typeof(ConcurrentQueue<>).FullName!);
-                _idictionaryType = ResolveType(typeof(IDictionary).FullName!);
-                _ilistType = ResolveType(typeof(IList).FullName!);
-                _stackType = ResolveType(typeof(Stack).FullName!);
-                _queueType = ResolveType(typeof(Queue).FullName!);
-                _keyValuePair = ResolveType(typeof(KeyValuePair<,>).FullName!);
-
-                _booleanType = ResolveType(SpecialType.System_Boolean);
-                _charType = ResolveType(SpecialType.System_Char);
-                _dateTimeType = ResolveType(SpecialType.System_DateTime);
-                _nullableOfTType = ResolveType(SpecialType.System_Nullable_T);
-                _objectType = ResolveType(SpecialType.System_Object);
-                _stringType = ResolveType(SpecialType.System_String);
-
-                _dateTimeOffsetType = ResolveType(typeof(DateTimeOffset).FullName!);
-                _byteArrayType = ResolveType(typeof(byte[]).FullName!);
-                _guidType = ResolveType(typeof(Guid).FullName!);
-                _uriType = ResolveType(typeof(Uri).FullName!);
-                _versionType = ResolveType(typeof(Version).FullName!);
-                _jsonElementType = ResolveType(JsonElementFullName);
+                _ilistOfTType = _metadataLoadContext.Resolve(SpecialType.System_Collections_Generic_IList_T);
+                _icollectionOfTType = _metadataLoadContext.Resolve(SpecialType.System_Collections_Generic_ICollection_T);
+                _ienumerableOfTType = _metadataLoadContext.Resolve(SpecialType.System_Collections_Generic_IEnumerable_T);
+                _ienumerableType = _metadataLoadContext.Resolve(SpecialType.System_Collections_IEnumerable);
+
+                _listOfTType = _metadataLoadContext.Resolve(typeof(List<>));
+                _dictionaryType = _metadataLoadContext.Resolve(typeof(Dictionary<,>));
+                _idictionaryOfTKeyTValueType = _metadataLoadContext.Resolve(typeof(IDictionary<,>));
+                _ireadonlyDictionaryType = _metadataLoadContext.Resolve(typeof(IReadOnlyDictionary<,>));
+                _isetType = _metadataLoadContext.Resolve(typeof(ISet<>));
+                _stackOfTType = _metadataLoadContext.Resolve(typeof(Stack<>));
+                _queueOfTType = _metadataLoadContext.Resolve(typeof(Queue<>));
+                _concurrentStackType = _metadataLoadContext.Resolve(typeof(ConcurrentStack<>));
+                _concurrentQueueType = _metadataLoadContext.Resolve(typeof(ConcurrentQueue<>));
+                _idictionaryType = _metadataLoadContext.Resolve(typeof(IDictionary));
+                _ilistType = _metadataLoadContext.Resolve(typeof(IList));
+                _stackType = _metadataLoadContext.Resolve(typeof(Stack));
+                _queueType = _metadataLoadContext.Resolve(typeof(Queue));
+                _keyValuePair = _metadataLoadContext.Resolve(typeof(KeyValuePair<,>));
+
+                _booleanType = _metadataLoadContext.Resolve(SpecialType.System_Boolean);
+                _charType = _metadataLoadContext.Resolve(SpecialType.System_Char);
+                _dateTimeType = _metadataLoadContext.Resolve(SpecialType.System_DateTime);
+                _nullableOfTType = _metadataLoadContext.Resolve(SpecialType.System_Nullable_T);
+                _objectType = _metadataLoadContext.Resolve(SpecialType.System_Object);
+                _stringType = _metadataLoadContext.Resolve(SpecialType.System_String);
+
+                _dateTimeOffsetType = _metadataLoadContext.Resolve(typeof(DateTimeOffset));
+                _byteArrayType = _metadataLoadContext.Resolve(typeof(byte[]));
+                _guidType = _metadataLoadContext.Resolve(typeof(Guid));
+                _uriType = _metadataLoadContext.Resolve(typeof(Uri));
+                _versionType = _metadataLoadContext.Resolve(typeof(Version));
+                _jsonElementType = _metadataLoadContext.Resolve(JsonElementFullName);
 
                 PopulateKnownTypes();
             }
@@ -256,7 +256,7 @@ namespace System.Text.Json.SourceGeneration
             }
 
             // Returns true if a given type derives directly from JsonSerializerContext.
-            private bool DerivesFromJsonSerializerContext(
+            private static bool DerivesFromJsonSerializerContext(
                 ClassDeclarationSyntax classDeclarationSyntax,
                 INamedTypeSymbol jsonSerializerContextSymbol,
                 SemanticModel compilationSemanticModel)
@@ -1090,17 +1090,17 @@ namespace System.Text.Json.SourceGeneration
             private void PopulateNumberTypes()
             {
                 Debug.Assert(_numberTypes != null);
-                _numberTypes.Add(ResolveType(SpecialType.System_Byte));
-                _numberTypes.Add(ResolveType(SpecialType.System_Decimal));
-                _numberTypes.Add(ResolveType(SpecialType.System_Double));
-                _numberTypes.Add(ResolveType(SpecialType.System_Int16));
-                _numberTypes.Add(ResolveType(SpecialType.System_SByte));
-                _numberTypes.Add(ResolveType(SpecialType.System_Int32));
-                _numberTypes.Add(ResolveType(SpecialType.System_Int64));
-                _numberTypes.Add(ResolveType(SpecialType.System_Single));
-                _numberTypes.Add(ResolveType(SpecialType.System_UInt16));
-                _numberTypes.Add(ResolveType(SpecialType.System_UInt32));
-                _numberTypes.Add(ResolveType(SpecialType.System_UInt64));
+                _numberTypes.Add(_metadataLoadContext.Resolve(SpecialType.System_Byte));
+                _numberTypes.Add(_metadataLoadContext.Resolve(SpecialType.System_Decimal));
+                _numberTypes.Add(_metadataLoadContext.Resolve(SpecialType.System_Double));
+                _numberTypes.Add(_metadataLoadContext.Resolve(SpecialType.System_Int16));
+                _numberTypes.Add(_metadataLoadContext.Resolve(SpecialType.System_SByte));
+                _numberTypes.Add(_metadataLoadContext.Resolve(SpecialType.System_Int32));
+                _numberTypes.Add(_metadataLoadContext.Resolve(SpecialType.System_Int64));
+                _numberTypes.Add(_metadataLoadContext.Resolve(SpecialType.System_Single));
+                _numberTypes.Add(_metadataLoadContext.Resolve(SpecialType.System_UInt16));
+                _numberTypes.Add(_metadataLoadContext.Resolve(SpecialType.System_UInt32));
+                _numberTypes.Add(_metadataLoadContext.Resolve(SpecialType.System_UInt64));
             }
 
             private void PopulateKnownTypes()
@@ -1122,18 +1122,6 @@ namespace System.Text.Json.SourceGeneration
                 _knownTypes.Add(_versionType);
                 _knownTypes.Add(_jsonElementType);
             }
-
-            private Type ResolveType(string fullyQualifiedMetadataName)
-            {
-                INamedTypeSymbol? typeSymbol = _executionContext.Compilation.GetTypeByMetadataName(fullyQualifiedMetadataName);
-                return typeSymbol.AsType(_metadataLoadContext);
-            }
-
-            private Type ResolveType(SpecialType specialType)
-            {
-                INamedTypeSymbol? typeSymbol = _executionContext.Compilation.GetSpecialType(specialType);
-                return typeSymbol.AsType(_metadataLoadContext);
-            }
         }
     }
 }
index 1d87aa8..c088cc6 100644 (file)
@@ -12,101 +12,25 @@ namespace System.Text.Json.Reflection
 {
     internal class MetadataLoadContextInternal
     {
-        private readonly Dictionary<string, IAssemblySymbol> _assemblies = new Dictionary<string, IAssemblySymbol>(StringComparer.OrdinalIgnoreCase);
-
         private readonly Compilation _compilation;
 
-        private IAssemblySymbol? _collectionsAssemblySymbol;
-
         public MetadataLoadContextInternal(Compilation compilation)
         {
             _compilation = compilation;
-            Dictionary<AssemblyName, IAssemblySymbol> assemblies = compilation.References
-                .OfType<PortableExecutableReference>()
-                .ToDictionary(
-                    r => string.IsNullOrWhiteSpace(r.FilePath) ?
-                        new AssemblyName(r.Display) : AssemblyName.GetAssemblyName(r.FilePath),
-                    r => (IAssemblySymbol)compilation.GetAssemblyOrModuleSymbol(r)!);
-
-            foreach (var item in assemblies)
-            {
-                string key = item.Key.Name;
-                _assemblies[key] = item.Value!;
-
-                if (_collectionsAssemblySymbol == null && key == "System.Collections")
-                {
-                    _collectionsAssemblySymbol = item.Value!;
-                }
-            }
-
-            CoreAssembly = new AssemblyWrapper(compilation.GetTypeByMetadataName("System.Object")!.ContainingAssembly, this);
-            MainAssembly = new AssemblyWrapper(compilation.Assembly, this);
         }
 
-        public Type? Resolve(Type type)
-        {
-            string assemblyName = type.Assembly.GetName().Name;
-            IAssemblySymbol assemblySymbol;
-
-            if (assemblyName == "System.Private.CoreLib" || assemblyName == "mscorlib" || assemblyName == "System.Runtime" || assemblyName == "System.Private.Uri")
-            {
-                Type resolvedType = ResolveFromAssembly(type, CoreAssembly.Symbol);
-                if (resolvedType != null)
-                {
-                    return resolvedType;
-                }
-
-                if (_collectionsAssemblySymbol != null && typeof(IEnumerable).IsAssignableFrom(type))
-                {
-                    resolvedType = ResolveFromAssembly(type, _collectionsAssemblySymbol);
-                    if (resolvedType != null)
-                    {
-                        return resolvedType;
-                    }
-                }
-            }
+        public Type? Resolve(Type type) => Resolve(type.FullName!);
 
-            CustomAttributeData? typeForwardedFrom = type.GetCustomAttributeData(typeof(TypeForwardedFromAttribute));
-            if (typeForwardedFrom != null)
-            {
-                assemblyName = typeForwardedFrom.GetConstructorArgument<string>(0);
-            }
-
-            if (!_assemblies.TryGetValue(new AssemblyName(assemblyName).Name, out assemblySymbol))
-            {
-                return null;
-            }
-
-            return ResolveFromAssembly(type, assemblySymbol);
-        }
-
-        private Type? ResolveFromAssembly(Type type, IAssemblySymbol assemblySymbol)
+        public Type? Resolve(string fullyQualifiedMetadataName)
         {
-            if (type.IsArray)
-            {
-                var typeSymbol = assemblySymbol.GetTypeByMetadataName(type.GetElementType().FullName);
-                if (typeSymbol == null)
-                {
-                    return null!;
-                }
-
-                return _compilation.CreateArrayTypeSymbol(typeSymbol).AsType(this);
-            }
-
-            // Resolve the full name
-            return assemblySymbol.GetTypeByMetadataName(type.FullName)!.AsType(this);
+            INamedTypeSymbol? typeSymbol = _compilation.GetTypeByMetadataName(fullyQualifiedMetadataName);
+            return typeSymbol.AsType(this);
         }
 
-        private AssemblyWrapper CoreAssembly { get; }
-        public Assembly MainAssembly { get; }
-
-        internal Assembly LoadFromAssemblyName(string fullName)
+        public Type Resolve(SpecialType specialType)
         {
-            if (_assemblies.TryGetValue(new AssemblyName(fullName).Name, out var assembly))
-            {
-                return new AssemblyWrapper(assembly, this);
-            }
-            return null!;
+            INamedTypeSymbol? typeSymbol = _compilation.GetSpecialType(specialType);
+            return typeSymbol.AsType(this);
         }
     }
 }