public void AnalyzeResolveAssemblyReference()

in src/StructuredLogger/Analyzers/ResolveAssemblyReferenceAnalyzer.cs [20:161]


        public void AnalyzeResolveAssemblyReference(Task rar)
        {
            stringTable = rar.GetNearestParent<Build>()?.StringTable;

            currentUsedLocations.Clear();

            var results = rar.FindChild<Folder>(c => c.Name == Strings.Results);
            var parameters = rar.FindChild<Folder>(c => c.Name == Strings.Parameters);

            TotalRARDuration += rar.Duration;

            IList<string> searchPaths = null;
            if (parameters != null)
            {
                var searchPathsNode = parameters.FindChild<NamedNode>(c => c.Name == Strings.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, StringComparison.Ordinal));
                    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, StringComparison.Ordinal));
                    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 ", StringComparison.Ordinal) || reference.Name.StartsWith("Unified Dependency ", StringComparison.Ordinal))
                    {
                        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>(Strings.Parameters)?.FindChild<Parameter>(Strings.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)
                                                {
                                                    var message = $"{foundSourceItem} has {metadata.Name} set to {metadata.Value}";
                                                    message = stringTable?.Intern(message);
                                                    notCopyLocalMessage.AddChild(new Message
                                                    {
                                                        Text = message
                                                    });
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            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);
                        }
                    }
                }
            }
        }