diff --git a/src/coverlet.core/Helpers/InstrumentationHelper.cs b/src/coverlet.core/Helpers/InstrumentationHelper.cs index 70dd7b677..a95327322 100644 --- a/src/coverlet.core/Helpers/InstrumentationHelper.cs +++ b/src/coverlet.core/Helpers/InstrumentationHelper.cs @@ -178,12 +178,13 @@ public bool PortablePdbHasLocalSource(string module, out string firstNotFoundDoc Document document = metadataReader.GetDocument(docHandle); string docName = _sourceRootTranslator.ResolveFilePath(metadataReader.GetString(document.Name)); Guid languageGuid = metadataReader.GetGuid(document.Language); + // We verify all docs and return false if not all are present in local // We could have false negative if doc is not a source // Btw check for all possible extension could be weak approach // We exlude from the check the autogenerated source file(i.e. source generators) // We exclude special F# construct https://github.com/coverlet-coverage/coverlet/issues/1145 - if (!_fileSystem.Exists(docName) && !docName.EndsWith(".g.cs") && + if (!_fileSystem.Exists(docName) && !IsGeneratedDocumentName(docName) && !IsUnknownModuleInFSharpAssembly(languageGuid, docName)) { return (false, docName); @@ -449,6 +450,35 @@ private static bool IsAssembly(string filePath) } } + // Follow the same rules that exist in Microsoft.CodeAnalysis + // https://sourceroslyn.io/#Microsoft.CodeAnalysis/InternalUtilities/GeneratedCodeUtilities.cs,55bff725ec9f1338,references + private static bool IsGeneratedDocumentName(string docPath) + { + if (!string.IsNullOrEmpty(docPath)) + { + string fileName = Path.GetFileName(docPath); + if (fileName.StartsWith("TemporaryGeneratedFile_", StringComparison.OrdinalIgnoreCase)) + { + return true; + } + + string extension = Path.GetExtension(fileName); + if (!string.IsNullOrEmpty(extension)) + { + string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(docPath); + if (fileNameWithoutExtension.EndsWith(".designer", StringComparison.OrdinalIgnoreCase) || + fileNameWithoutExtension.EndsWith(".generated", StringComparison.OrdinalIgnoreCase) || + fileNameWithoutExtension.EndsWith(".g", StringComparison.OrdinalIgnoreCase) || + fileNameWithoutExtension.EndsWith(".g.i", StringComparison.OrdinalIgnoreCase)) + { + return true; + } + } + } + + return false; + } + private static bool IsUnknownModuleInFSharpAssembly(Guid languageGuid, string docName) { // https://github.com/dotnet/runtime/blob/main/docs/design/specs/PortablePdb-Metadata.md#document-table-0x30