_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();
}
}
// Returns true if a given type derives directly from JsonSerializerContext.
- private bool DerivesFromJsonSerializerContext(
+ private static bool DerivesFromJsonSerializerContext(
ClassDeclarationSyntax classDeclarationSyntax,
INamedTypeSymbol jsonSerializerContextSymbol,
SemanticModel compilationSemanticModel)
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()
_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);
- }
}
}
}
{
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);
}
}
}