public static void AnalyzeResolveAssemblyReference(Task rar) { var results = rar.FindChild <Folder>(c => c.Name == "Results"); if (results != null) { results.SortChildren(); foreach (var reference in results.Children.OfType <Parameter>()) { if (reference.Name.StartsWith("Dependency ") || reference.Name.StartsWith("Unified Dependency ")) { bool foundNotCopyLocalBecauseMetadata = false; var requiredBy = new List <Item>(); foreach (var message in reference.Children.OfType <Item>()) { string text = message.Text; if (text.StartsWith("Required by \"")) { requiredBy.Add(message); } else if (text == @"This reference is not ""CopyLocal"" because at least one source item had ""Private"" set to ""false"" and no source items had ""Private"" set to ""true"".") { foundNotCopyLocalBecauseMetadata = true; } } if (foundNotCopyLocalBecauseMetadata) { var assemblies = rar.FindChild <Folder>("Parameters")?.FindChild <Parameter>("Assemblies"); if (assemblies != null) { var dictionary = assemblies.Children .OfType <Item>() .GroupBy(i => i.Text, StringComparer.OrdinalIgnoreCase) .ToDictionary(g => g.Key, g => g.First(), StringComparer.OrdinalIgnoreCase); foreach (var sourceItem in requiredBy) { int prefixLength = "Required by \"".Length; string text = sourceItem.Text; var referenceName = text.Substring(prefixLength, text.Length - prefixLength - 2); Item foundSourceItem; if (dictionary.TryGetValue(referenceName, out foundSourceItem)) { foreach (var metadata in foundSourceItem.Children.OfType <Metadata>()) { if (metadata.Name == "Private") { sourceItem.AddChild(new Metadata() { Name = metadata.Name, Value = metadata.Value }); } } } } } } } } } }
public void AnalyzeResolveAssemblyReference(Task rar) { currentUsedLocations.Clear(); var results = rar.FindChild <Folder>(c => c.Name == "Results"); var parameters = rar.FindChild <Folder>(c => c.Name == "Parameters"); TotalRARDuration += rar.Duration; IList <string> searchPaths = null; if (parameters != null) { var searchPathsNode = parameters.FindChild <NamedNode>(c => c.Name == "SearchPaths"); if (searchPathsNode != null) { searchPaths = searchPathsNode.Children.Select(c => c.ToString()).ToArray(); } } if (results != null) { results.SortChildren(); foreach (var reference in results.Children.OfType <Parameter>()) { const string ResolvedFilePathIs = "Resolved file path is \""; string resolvedFilePath = null; var resolvedFilePathNode = reference.FindChild <Item>(i => i.ToString().StartsWith(ResolvedFilePathIs)); if (resolvedFilePathNode != null) { var text = resolvedFilePathNode.ToString(); resolvedFilePath = text.Substring(ResolvedFilePathIs.Length, text.Length - ResolvedFilePathIs.Length - 2); } const string ReferenceFoundAt = "Reference found at search path location \""; var foundAtLocation = reference.FindChild <Item>(i => i.ToString().StartsWith(ReferenceFoundAt)); if (foundAtLocation != null) { var text = foundAtLocation.ToString(); var location = text.Substring(ReferenceFoundAt.Length, text.Length - ReferenceFoundAt.Length - 2); // filter out the case where the assembly is resolved from the AssemblyFiles parameter // In this case the location matches the resolved file path. if (resolvedFilePath == null || resolvedFilePath != location) { UsedLocations.Add(location); currentUsedLocations.Add(location); } } var thisReferenceName = ParseReferenceName(reference.Name); if (reference.Name.StartsWith("Dependency ") || reference.Name.StartsWith("Unified Dependency ")) { bool foundNotCopyLocalBecauseMetadata = false; var requiredBy = new List <Item>(); Item notCopyLocalMessage = null; foreach (var message in reference.Children.OfType <Item>()) { string text = message.Text; if (text.StartsWith("Required by \"")) { requiredBy.Add(message); } else if (text == @"This reference is not ""CopyLocal"" because at least one source item had ""Private"" set to ""false"" and no source items had ""Private"" set to ""true"".") { foundNotCopyLocalBecauseMetadata = true; notCopyLocalMessage = message; } } if (foundNotCopyLocalBecauseMetadata) { var assemblies = rar.FindChild <Folder>("Parameters")?.FindChild <Parameter>("Assemblies"); if (assemblies != null) { var dictionary = assemblies.Children .OfType <Item>() .GroupBy(i => i.Text, StringComparer.OrdinalIgnoreCase) .ToDictionary(g => g.Key, g => g.First(), StringComparer.OrdinalIgnoreCase); foreach (var sourceItem in requiredBy) { int prefixLength = "Required by \"".Length; string text = sourceItem.Text; var referenceName = text.Substring(prefixLength, text.Length - prefixLength - 2); Item foundSourceItem; if (dictionary.TryGetValue(referenceName, out foundSourceItem)) { foreach (var metadata in foundSourceItem.Children.OfType <Metadata>()) { if (metadata.Name == "Private") { sourceItem.AddChild(new Metadata() { Name = metadata.Name, Value = metadata.Value }); if (notCopyLocalMessage != null) { notCopyLocalMessage.AddChild(new Message { Text = $"{foundSourceItem.ToString()} has {metadata.Name} set to {metadata.Value}" }); } } } } } } } } } } if (searchPaths != null) { foreach (var searchPath in searchPaths) { if (currentUsedLocations.Contains(searchPath)) { var usedLocations = rar.GetOrCreateNodeWithName <Folder>(Strings.UsedLocations); usedLocations.AddChild(new Item { Text = searchPath }); UnusedLocations.Remove(searchPath); } else { var unusedLocations = rar.GetOrCreateNodeWithName <Folder>(Strings.UnusedLocations); unusedLocations.AddChild(new Item { Text = searchPath }); if (!UsedLocations.Contains(searchPath)) { UnusedLocations.Add(searchPath); } else { UnusedLocations.Remove(searchPath); } } } } }
internal static CompilationWrites?TryParse(Task task) { var parameters = task.FindChild <Folder>(c => c.Name == Strings.Parameters); if (parameters == null) { // Probably localized MSBuild that we don't yet support return(null); } string assembly = null; string refAssembly = null; string xmlDocumentation = null; string sourceLink = null; var hasPdb = false; foreach (var property in parameters.Children.OfType <Property>()) { switch (property.Name) { case "OutputAssembly": assembly = property.Value; break; case "OutputRefAssembly": refAssembly = property.Value; break; case "DocumentationFile": xmlDocumentation = property.Value; break; case "SourceLink": sourceLink = property.Value; break; case "DebugType": switch (property.Value.ToLower()) { case "full": case "portable": case "pdbonly": hasPdb = true; break; } break; } } if (string.IsNullOrEmpty(assembly) && string.IsNullOrEmpty(refAssembly)) { return(null); } var pdb = hasPdb && !string.IsNullOrEmpty(assembly) ? Path.ChangeExtension(assembly, ".pdb") : null; return(new CompilationWrites( assembly, refAssembly, pdb, xmlDocumentation, sourceLink)); }