| File: Linker\TypeNameResolver.WithDiagnostics.cs | Web Access |
| Project: src\runtime\src\tools\illink\src\linker\Mono.Linker.csproj (illink) |
// Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using ILLink.Shared; using ILLink.Shared.TrimAnalysis; using Mono.Cecil; using TypeName = System.Reflection.Metadata.TypeName; namespace Mono.Linker { internal sealed partial class TypeNameResolver { public bool TryResolveTypeName( string typeNameString, in DiagnosticContext diagnosticContext, [NotNullWhen(true)] out TypeReference? typeReference, [NotNullWhen(true)] out List<TypeResolutionRecord>? typeResolutionRecords, bool needsAssemblyName) { typeReference = null; typeResolutionRecords = null; if (string.IsNullOrEmpty(typeNameString)) return false; if (!TypeName.TryParse(typeNameString, out TypeName? parsedTypeName, s_typeNameParseOptions)) return false; if (needsAssemblyName && !IsFullyQualified(parsedTypeName)) { diagnosticContext.AddDiagnostic(DiagnosticId.TypeNameIsNotAssemblyQualified, typeNameString); return false; } // If parsedTypeName doesn't have an assembly name in it but it does have a namespace, // search for the type in the calling object's assembly. If not found, look in the core // assembly. ICustomAttributeProvider? provider = diagnosticContext.Origin.Provider; AssemblyDefinition? referencingAssembly = provider switch { AssemblyDefinition asm => asm, TypeDefinition type => type.Module?.Assembly, IMemberDefinition member => member.DeclaringType.Module.Assembly, null => null, _ => throw new NotSupportedException() }; if (referencingAssembly is null) return false; typeResolutionRecords = new List<TypeResolutionRecord>(); typeReference = ResolveTypeName(referencingAssembly, parsedTypeName, typeResolutionRecords, fallbackToCoreLib: true); return typeReference != null; static bool IsFullyQualified(TypeName typeName) { if (typeName.AssemblyName is null) return false; if (typeName.IsArray || typeName.IsPointer || typeName.IsByRef) return IsFullyQualified(typeName.GetElementType()); if (typeName.IsConstructedGenericType) { foreach (var typeArgument in typeName.GetGenericArguments()) { if (!IsFullyQualified(typeArgument)) return false; } } return true; } } } }