internal static bool IsNuGetAssembly(AssemblyReference assemblyReference) { var assemblyName = assemblyReference.GetAssemblyName(); var isNuGetAssembly = assemblyName.Name == null || NuGetAssembly.MatchesName(assemblyName.Name); // Originally I wanted to also check the strong name token, to reduce the risk that someone compiled their // code against a custom NuGet assembly with APIs that we don't ship. However, JetBrains compiled their // products against custom NuGet assemblies with a different public token, so we can't do that check if we // want to find out which APIs they're using. return(isNuGetAssembly); }
internal static bool HasReferenceToNuGetAssembly(MetadataReader metadata) { foreach (var assemblyReferenceHandle in metadata.AssemblyReferences) { var assemblyReference = metadata.GetAssemblyReference(assemblyReferenceHandle); if (NuGetAssembly.IsNuGetAssembly(assemblyReference)) { return(true); } } return(false); }
private static UsageInformation?GetApisUsedByAssembly(string file) { // Skip NuGet's own assemblies string filename = Path.GetFileNameWithoutExtension(file); if (NuGetAssembly.MatchesName(filename) || filename.Equals("NuGet.Core", StringComparison.OrdinalIgnoreCase)) { return(null); } if (filename.StartsWith("NuGet.", StringComparison.OrdinalIgnoreCase)) { Console.Error.WriteLine("Suspicious assembly name: " + file); } using var fileStream = File.OpenRead(file); using var peReader = new PEReader(fileStream); MetadataReader metadata; try { metadata = peReader.GetMetadataReader(); } catch (InvalidOperationException) { // Not a .NET assembly return(null); } if (!AssemblyAnalyser.HasReferenceToNuGetAssembly(metadata)) { return(null); } UsageInformation usedNuGetApis = AssemblyAnalyser.FindUsedNuGetApis(metadata); return(usedNuGetApis); }
internal static UsageInformation FindUsedNuGetApis(MetadataReader metadata) { var result = new UsageInformation(); void AddMember(string assembly, string member) { if (!result.MemberReferences.TryGetValue(assembly, out HashSet <string>?apis)) { apis = new HashSet <string>(); result.MemberReferences[assembly] = apis; } apis.Add(member); } foreach (var memberReferenceHandle in metadata.MemberReferences) { var memberReference = metadata.GetMemberReference(memberReferenceHandle); var foundAssemblyReference = TryFindAssemblyReference(memberReferenceHandle, metadata, out var assemblyReference); if (foundAssemblyReference && NuGetAssembly.IsNuGetAssembly(assemblyReference)) { var assemblyName = assemblyReference.GetAssemblyName(); var version = assemblyName.Version?.ToString(); if (version != null) { result.Versions.Add(version); } var kind = memberReference.GetKind(); switch (kind) { case MemberReferenceKind.Method: { var(assembly, member) = TypeNameGenerator.GetFullName(memberReferenceHandle, metadata); var sig = memberReference.DecodeMethodSignature(MethodSignatureDecoder.Default, null); var methodSignature = GetMethodSignature(member, sig); AddMember(assembly, methodSignature); } break; case MemberReferenceKind.Field: { var(assembly, member) = TypeNameGenerator.GetFullName(memberReferenceHandle, metadata); AddMember(assembly, member); } break; default: throw new NotImplementedException(kind.ToString()); } } } if (result.MemberReferences.SelectMany(r => r.Value).Any()) { if (TryGetTargetFramework(metadata, out string?targetFramework)) { result.TargetFrameworks.Add(targetFramework); } } return(result); }