public Construction()
 {
     Build                 = new Build();
     Build.Name            = "Build";
     this.stringTable      = Build.StringTable;
     this.messageProcessor = new MessageProcessor(this, stringTable);
     Intern(Strings.Assembly);
     Intern(Strings.CommandLineArguments);
     Intern(Strings.DoubleWrites);
     Intern(Strings.Evaluation);
     Intern(Strings.Note);
     Intern(Strings.OutputItems);
     Intern(Strings.Parameters);
     Intern(Strings.Properties);
     Intern(Strings.UnusedLocations);
     Intern(Strings.Warnings);
     Intern(nameof(AddItem));
     Intern(nameof(CopyTask));
     Intern(nameof(CscTask));
     Intern(nameof(ResolveAssemblyReferenceTask));
     Intern(nameof(EntryTarget));
     Intern(nameof(Folder));
     Intern(nameof(Import));
     Intern(nameof(Item));
     Intern(nameof(Metadata));
     Intern(nameof(NoImport));
     Intern(nameof(Parameter));
     Intern(nameof(ProjectEvaluation));
     Intern(nameof(Property));
     Intern(nameof(RemoveItem));
     Intern(nameof(Target));
     Intern(nameof(Task));
     Intern(nameof(TimedNode));
 }
Esempio n. 2
0
 public Construction()
 {
     Build                 = new Build();
     Build.Name            = "Build";
     this.stringTable      = Build.StringTable;
     this.messageProcessor = new MessageProcessor(this, stringTable);
 }
Esempio n. 3
0
        private BaseNode ReadNode(XElement element)
        {
            var name = element.Name.LocalName;

            if (name == "Metadata")
            {
                var metadata = new Metadata()
                {
                    Name  = GetString(element, AttributeNames.Name),
                    Value = ReadTextContent(element)
                };

                return(metadata);
            }
            else if (name == "Property")
            {
                var property = new Property()
                {
                    Name  = GetString(element, AttributeNames.Name),
                    Value = ReadTextContent(element)
                };

                return(property);
            }

            var node = Serialization.CreateNode(name);

            var folder = node as Folder;

            if (folder != null)
            {
                folder.Name = name;
            }

            var build = node as Build;

            if (build != null)
            {
                this.stringTable = build.StringTable;
            }

            ReadAttributes(node, element);

            if (element.HasElements)
            {
                var treeNode = (TreeNode)node;
                foreach (var childElement in element.Elements())
                {
                    var childNode = ReadNode(childElement);
                    treeNode.AddChild(childNode);
                }
            }

            return(node);
        }
        private object ReadNode(XElement element)
        {
            var name = element.Name.LocalName;

            if (name == "Metadata")
            {
                var metadata = new Metadata()
                {
                    Name  = GetString(element, AttributeNames.Name),
                    Value = ReadTextContent(element)
                };

                return(metadata);
            }
            else if (name == "Property")
            {
                var property = new Property()
                {
                    Name  = GetString(element, AttributeNames.Name),
                    Value = ReadTextContent(element)
                };

                return(property);
            }

            Type type = null;

            if (!Serialization.ObjectModelTypes.TryGetValue(name, out type))
            {
                type = typeof(Folder);
            }

            var node = (TreeNode)Activator.CreateInstance(type);

            var build = node as Build;

            if (build != null)
            {
                this.stringTable = build.StringTable;
            }

            ReadAttributes(node, element);

            if (element.HasElements)
            {
                foreach (var childElement in element.Elements())
                {
                    var childNode = ReadNode(childElement);
                    node.AddChild(childNode);
                }
            }

            return(node);
        }
Esempio n. 5
0
 public Construction()
 {
     Build                 = new Build();
     Build.Name            = "Build";
     this.stringTable      = Build.StringTable;
     this.messageProcessor = new MessageProcessor(this, stringTable);
     Intern(Strings.Evaluation);
     Intern(Strings.Properties);
     Intern(Strings.OutputItems);
     Intern(Strings.Parameters);
 }
        private static void VisitMessage(Message message, StringCache stringTable)
        {
            var match = Strings.ImportingProjectRegex.Match(message.Text);

            if (match.Success && match.Groups.Count == 5)
            {
                var project         = match.Groups["File"].Value;
                var importedProject = match.Groups["ImportedProject"].Value;
                var line            = int.Parse(match.Groups["Line"].Value);
                var column          = int.Parse(match.Groups["Column"].Value);

                project         = stringTable.Intern(project);
                importedProject = stringTable.Intern(importedProject);

                AddImport(
                    message,
                    project,
                    importedProject,
                    line,
                    column,
                    imported: true);
                return;
            }

            string reason;

            match = Strings.ProjectWasNotImportedRegex(message.Text, out reason);
            if (match.Success && match.Groups.Count > 4)
            {
                var project         = match.Groups["File"].Value;
                var importedProject = match.Groups["ImportedProject"].Value;
                var line            = int.Parse(match.Groups["Line"].Value);
                var column          = int.Parse(match.Groups["Column"].Value);
                // var reason = match.Groups["Reason"].Value;

                project         = stringTable.Intern(project);
                importedProject = stringTable.Intern(importedProject);
                reason          = stringTable.Intern("Not imported due to " + reason);

                AddImport(
                    message,
                    project,
                    importedProject,
                    line,
                    column,
                    imported: false,
                    reason: reason);
                return;
            }
        }
Esempio n. 7
0
            static Item Add(TreeNode parent, string text, Span span, int spaces, StringCache stringTable)
            {
                if (spaces >= span.Length || parent == null)
                {
                    return(null);
                }

                string line = text.Substring(span.Start + spaces, span.Length - spaces);

                var item = new Item
                {
                    Text = stringTable.Intern(line)
                };

                parent.AddChild(item);
                return(item);
            }
Esempio n. 8
0
        public static void ParseThereWasAConflict(TreeNode parent, string message, StringCache stringTable)
        {
            if (lineSpans == null)
            {
                lineSpans = new List <Span>(10240);
            }

            lineSpans.Clear();
            message.CollectLineSpans(lineSpans, includeLineBreakInSpan: false);

            Item item4  = null;
            Item item8  = null;
            Item item10 = null;

            for (int i = 0; i < lineSpans.Count; i++)
            {
                var lineSpan = lineSpans[i];
                var numberOfLeadingSpaces = TextUtilities.GetNumberOfLeadingSpaces(message, lineSpan);
                switch (numberOfLeadingSpaces)
                {
                case 0:
                case 4:
                    item4  = Add(parent, message, lineSpan, numberOfLeadingSpaces, stringTable);
                    item8  = null;
                    item10 = null;
                    break;

                case 8:
                    item8  = Add(item4, message, lineSpan, numberOfLeadingSpaces, stringTable);
                    item10 = null;
                    break;

                case 10:
                    item10 = Add(item8, message, lineSpan, numberOfLeadingSpaces, stringTable);
                    break;

                case 12:
                    Add(item10, message, lineSpan, numberOfLeadingSpaces, stringTable);
                    break;

                default:
                    Add(item10 ?? item8 ?? item4 ?? parent, message, lineSpan, numberOfLeadingSpaces, stringTable);
                    break;
                }
            }
        public static TextNode TryGetImportOrNoImport(string text, StringCache stringTable)
        {
            var match = Strings.ProjectImportedRegex.Match(text);

            if (match.Success && match.Groups.Count == 5)
            {
                var project         = match.Groups["File"].Value;
                var importedProject = match.Groups["ImportedProject"].Value;
                var line            = int.Parse(match.Groups["Line"].Value);
                var column          = int.Parse(match.Groups["Column"].Value);

                project         = stringTable.Intern(project);
                importedProject = stringTable.Intern(importedProject);

                var result = new Import(project, importedProject, line, column);
                return(result);
            }

            match = Strings.ProjectWasNotImportedRegex(text, out string reason);
            if (match.Success && match.Groups.Count > 4)
            {
                var project         = match.Groups["File"].Value;
                var importedProject = match.Groups["ImportedProject"].Value;
                var line            = int.Parse(match.Groups["Line"].Value);
                var column          = int.Parse(match.Groups["Column"].Value);

                project         = stringTable.Intern(project);
                importedProject = stringTable.Intern(importedProject);
                reason          = stringTable.Intern("Not imported due to " + reason);

                var noImport = new NoImport(project, importedProject, line, column, reason);
                return(noImport);
            }

            return(null);
        }
Esempio n. 10
0
        /// <summary>
        /// Parses a log output string to a list of Items (e.g. ItemGroup with metadata or property string).
        /// </summary>
        /// <param name="message">The message output from the logger.</param>
        /// <param name="prefix">The prefix parsed out (e.g. 'Output Item(s): '.).</param>
        /// <param name="name">Out: The name of the list.</param>
        /// <returns>List of items within the list and all metadata.</returns>
        public static object ParsePropertyOrItemList(string message, string prefix, StringCache stringTable)
        {
            message = message.Replace("\r\n", "\n");
            message = message.Replace('\r', '\n');
            var lines = message.Split('\n');

            if (lines.Length == 1)
            {
                var line = lines[0];
                line = line.Substring(prefix.Length);
                var nameValue = ParseNameValue(line);
                var property  = new Property
                {
                    Name  = stringTable.Intern(nameValue.Key),
                    Value = stringTable.Intern(nameValue.Value)
                };
                return(property);
            }

            var parameter = new Parameter();

            if (lines[0].Length > prefix.Length)
            {
                // we have a weird case of multi-line value
                var nameValue = ParseNameValue(lines[0].Substring(prefix.Length));

                parameter.Name = stringTable.Intern(nameValue.Key);

                parameter.AddChild(new Item
                {
                    Text = stringTable.Intern(nameValue.Value.Replace("\r", ""))
                });

                for (int i = 1; i < lines.Length; i++)
                {
                    parameter.AddChild(new Item
                    {
                        Text = stringTable.Intern(lines[i].Replace("\r", ""))
                    });
                }

                return(parameter);
            }

            Item currentItem = null;

            foreach (var line in lines)
            {
                switch (GetNumberOfLeadingSpaces(line))
                {
                case 4:
                    if (line.EndsWith("=", StringComparison.Ordinal))
                    {
                        parameter.Name = stringTable.Intern(line.Substring(4, line.Length - 5));
                    }
                    break;

                case 8:
                    currentItem = new Item
                    {
                        Text = stringTable.Intern(line.Substring(8))
                    };
                    parameter.AddChild(currentItem);
                    break;

                case 16:
                    if (currentItem != null)
                    {
                        var currentLine = line.Substring(16);
                        if (!currentLine.Contains("="))
                        {
                            // must be a continuation of the metadata value from the previous line
                            if (currentItem.HasChildren)
                            {
                                var metadata = currentItem.Children[currentItem.Children.Count - 1] as Metadata;
                                if (metadata != null)
                                {
                                    metadata.Value = stringTable.Intern((metadata.Value ?? "") + currentLine);
                                }
                            }
                        }
                        else
                        {
                            var nameValue = ParseNameValue(currentLine);
                            var metadata  = new Metadata
                            {
                                Name  = stringTable.Intern(nameValue.Key),
                                Value = stringTable.Intern(nameValue.Value)
                            };
                            currentItem.AddChild(metadata);
                        }
                    }
                    break;
                }
            }

            return(parameter);
        }
Esempio n. 11
0
 public MessageProcessor(Construction construction, StringCache stringTable)
 {
     this.construction = construction;
     this.stringTable  = stringTable;
 }
        public static void HandleThereWasAConflict(Parameter parameter, string message, StringCache stringTable)
        {
            var      numberOfLeadingSpaces = TextUtilities.GetNumberOfLeadingSpaces(message);
            TreeNode node = parameter;

            switch (numberOfLeadingSpaces)
            {
            case 0:
                parameter.AddChild(new Item()
                {
                    Text = stringTable.Intern(message)
                });
                break;

            case 4:
                node = parameter.LastChild as TreeNode ?? node;
                Add(node, message, 4);
                break;

            case 6:
            {
                if (parameter.LastChild is TreeNode item)
                {
                    node = item;
                    if (item.LastChild is TreeNode item2)
                    {
                        node = item2;
                    }
                }
                Add(node, message, 6);
            }
            break;

            case 8:
            {
                if (parameter.LastChild is TreeNode item)
                {
                    node = item;
                    if (item.LastChild is TreeNode item2)
                    {
                        node = item2;
                        if (item2.LastChild is TreeNode item3)
                        {
                            node = item3;
                        }
                    }
                }
                Add(node, message, 8);
            }
            break;

            default:
                Add(node, message, 0);
                break;
            }

            void Add(TreeNode parent, string text, int spaces)
            {
                text = text.Substring(spaces);
                parent.AddChild(new Item
                {
                    Text = stringTable.Intern(text)
                });
            }
        }
Esempio n. 13
0
        /// <summary>
        /// Parses a log output string to a list of Items (e.g. ItemGroup with metadata or property string).
        /// </summary>
        /// <param name="message">The message output from the logger.</param>
        /// <param name="prefix">The prefix parsed out (e.g. 'Output Item(s): '.).</param>
        /// <returns>List of items within the list and all metadata.</returns>
        public static object ParsePropertyOrItemList(string message, string prefix, StringCache stringTable)
        {
            if (!TextUtilities.ContainsLineBreak(message))
            {
                var nameValue = TextUtilities.ParseNameValue(message, trimFromStart: prefix.Length);
                var property  = new Property
                {
                    Name  = stringTable.Intern(nameValue.Key),
                    Value = stringTable.Intern(nameValue.Value)
                };
                return(property);
            }

            // Can't use a field initializer with ThreadStatic.
            if (lineSpans == null)
            {
                lineSpans = new List <Span>(10240);
            }

            lineSpans.Clear();
            message.CollectLineSpans(lineSpans, includeLineBreakInSpan: false);

            var parameter = new Parameter();

            if (lineSpans[0].Length > prefix.Length)
            {
                // we have a weird case of multi-line value
                var nameValue = TextUtilities.ParseNameValue(message, lineSpans[0].Skip(prefix.Length));

                parameter.Name = stringTable.Intern(nameValue.Key);

                parameter.AddChild(new Item
                {
                    Text = stringTable.Intern(nameValue.Value)
                });

                for (int i = 1; i < lineSpans.Count; i++)
                {
                    parameter.AddChild(new Item
                    {
                        Text = stringTable.Intern(message.Substring(lineSpans[i]))
                    });
                }

                return(parameter);
            }

            Item     currentItem     = null;
            Property currentProperty = null;

            foreach (var lineSpan in lineSpans)
            {
                if (TextUtilities.IsWhitespace(message, lineSpan))
                {
                    continue;
                }

                var numberOfLeadingSpaces = TextUtilities.GetNumberOfLeadingSpaces(message, lineSpan);
                switch (numberOfLeadingSpaces)
                {
                case 4:
                    if (message[lineSpan.End - 1] == '=')
                    {
                        parameter.Name = stringTable.Intern(message.Substring(lineSpan.Start + 4, lineSpan.Length - 5));
                    }
                    break;

                case 8:
                    var skip8  = message.Substring(lineSpan.Skip(8));
                    var equals = skip8.IndexOf('=');
                    if (equals != -1)
                    {
                        var kvp = TextUtilities.ParseNameValueWithEqualsPosition(skip8, equals);
                        currentProperty = new Property
                        {
                            Name  = stringTable.Intern(kvp.Key),
                            Value = stringTable.Intern(kvp.Value)
                        };
                        parameter.AddChild(currentProperty);
                        currentItem = null;
                    }
                    else
                    {
                        currentItem = new Item
                        {
                            Text = stringTable.Intern(skip8)
                        };
                        parameter.AddChild(currentItem);
                        currentProperty = null;
                    }
                    break;

                case 16:
                    if (currentItem == null && currentProperty != null)
                    {
                        // we incorrectly interpreted the previous line as Property, not Item (because it had '=')
                        // and so we created a property out of name/value.
                        // Fix this by turning it into an Item.
                        if (parameter.LastChild == currentProperty)
                        {
                            currentItem = new Item
                            {
                                Text = currentProperty.Name + "=" + currentProperty.Value
                            };
                            parameter.Children.RemoveAt(parameter.Children.Count - 1);
                            currentProperty = null;
                            parameter.AddChild(currentItem);
                        }
                    }

                    if (currentItem != null)
                    {
                        var span16   = lineSpan.Skip(16);
                        var equals16 = message.IndexOf(span16, '=');
                        if (equals16 == -1)
                        {
                            // must be a continuation of the metadata value from the previous line
                            if (currentItem.HasChildren)
                            {
                                var metadata = currentItem.Children[currentItem.Children.Count - 1] as Metadata;
                                if (metadata != null)
                                {
                                    var currentLine = message.Substring(span16);
                                    if (!string.IsNullOrEmpty(metadata.Value))
                                    {
                                        metadata.Value = metadata.Value + currentLine;
                                    }
                                    else
                                    {
                                        metadata.Value = currentLine;
                                    }
                                }
                            }
                        }
                        else
                        {
                            var nameValue = TextUtilities.ParseNameValueWithEqualsPosition(message, span16, equals16);
                            var metadata  = new Metadata
                            {
                                Name  = stringTable.Intern(nameValue.Key),
                                Value = stringTable.Intern(nameValue.Value)
                            };
                            currentItem.AddChild(metadata);
                        }
                    }
                    break;

                default:
                    var line = message.Substring(lineSpan);
                    if (numberOfLeadingSpaces == 0 && line == prefix)
                    {
                        continue;
                    }

                    // must be a continuation of a multi-line value
                    if (currentProperty != null)
                    {
                        currentProperty.Value += "\n" + line;
                    }
                    else if (currentItem != null && currentItem.HasChildren)
                    {
                        var metadata = currentItem.Children[currentItem.Children.Count - 1] as Metadata;
                        if (metadata != null)
                        {
                            metadata.Value = (metadata.Value ?? "") + line;
                        }
                    }
                    break;
                }
            }

            return(parameter);
        }
        public Build Read(Stream stream)
        {
            Build build = new Build();

            this.stringTable = build.StringTable;

            var stack = new Stack <object>(1024);

            stack.Push(build);

            XmlNodeType previous = XmlNodeType.None;

            try
            {
                var xmlReaderSettings = new XmlReaderSettings()
                {
                    IgnoreWhitespace = true,
                };

                using (reader = XmlReader.Create(stream, xmlReaderSettings))
                {
                    reader.MoveToContent();

                    ReadAttributes();
                    PopulateAttributes(build); // read the attributes on the root Build element that we created manually

                    while (reader.Read())
                    {
                        var nodeType = reader.NodeType;
                        switch (reader.NodeType)
                        {
                        case XmlNodeType.Element:
                            var node = ReadNode();

                            var parent = (TreeNode)stack.Peek();
                            parent.AddChild(node);

                            if (!reader.IsEmptyElement)
                            {
                                stack.Push(node);
                            }

                            break;

                        case XmlNodeType.EndElement:
                        {
                            // if the element content is an empty string
                            if (previous == XmlNodeType.Element)
                            {
                                var valueNode = stack.Peek();
                                SetElementValue(valueNode, "");
                            }

                            stack.Pop();
                            break;
                        }

                        case XmlNodeType.Text:
                        {
                            var    valueNode = stack.Peek();
                            string value     = reader.Value;
                            SetElementValue(valueNode, stringTable.Intern(value));

                            break;
                        }

                        case XmlNodeType.Whitespace:
                        {
                            var valueNode     = stack.Peek();
                            var nameValueNode = valueNode as NameValueNode;
                            if (nameValueNode != null)
                            {
                                nameValueNode.Value = GetCurrentValue();
                            }
                            else
                            {
                                var message = valueNode as Message;
                                if (message != null)
                                {
                                    message.Text = GetCurrentValue();
                                }
                            }

                            break;
                        }

                        case XmlNodeType.None:
                        case XmlNodeType.Attribute:
                        case XmlNodeType.CDATA:
                        case XmlNodeType.EntityReference:
                        case XmlNodeType.Entity:
                        case XmlNodeType.ProcessingInstruction:
                        case XmlNodeType.Comment:
                        case XmlNodeType.Document:
                        case XmlNodeType.DocumentType:
                        case XmlNodeType.DocumentFragment:
                        case XmlNodeType.Notation:
                        case XmlNodeType.SignificantWhitespace:
                        case XmlNodeType.EndEntity:
                        case XmlNodeType.XmlDeclaration:
                        default:
                            break;
                        }

                        previous = nodeType;
                    }
                }
            }
            catch (Exception ex)
            {
                build = new Build()
                {
                    Succeeded = false
                };
                build.AddChild(new Error()
                {
                    Text = "Error when opening XML log file."
                });
                build.AddChild(new Error()
                {
                    Text = ex.ToString()
                });
            }

            return(build);
        }
        public static TextNode TryGetImportOrNoImport(ProjectImportedEventArgs args, StringCache stringTable)
        {
            var message = (string)buildEventArgsFieldMessage.GetValue(args);

            var arguments = lazyFormattedBuildEventArgsFieldArguments.GetValue(args) as object[];

            if (arguments != null && arguments.Length > 0)
            {
                if (arguments.Length == 4)
                {
                    if (message == Strings.ProjectImported)
                    {
                        var importedProject   = stringTable.Intern((string)arguments[0]);
                        var containingProject = stringTable.Intern((string)arguments[1]);
                        var line   = ParseInt(arguments[2]);
                        var column = ParseInt(arguments[3]);
                        var import = new Import(
                            containingProject,
                            importedProject,
                            line,
                            column);
                        return(import);
                    }
                    else if (
                        message == Strings.ProjectImportSkippedExpressionEvaluatedToEmpty ||
                        message == Strings.ProjectImportSkippedNoMatches ||
                        message == Strings.ProjectImportSkippedMissingFile ||
                        message == Strings.ProjectImportSkippedInvalidFile)
                    {
                        var importedProject   = stringTable.Intern((string)arguments[0]);
                        var containingProject = stringTable.Intern((string)arguments[1]);
                        var line   = ParseInt(arguments[2]);
                        var column = ParseInt(arguments[3]);

                        string reason = "";
                        if (message == Strings.ProjectImportSkippedExpressionEvaluatedToEmpty)
                        {
                            reason = "empty expression";
                        }
                        else if (message == Strings.ProjectImportSkippedNoMatches)
                        {
                            reason = "no matches";
                        }
                        else if (message == Strings.ProjectImportSkippedMissingFile)
                        {
                            reason = "missing file";
                        }
                        else if (message == Strings.ProjectImportSkippedInvalidFile)
                        {
                            reason = "invalid file";
                        }

                        var noImport = new NoImport(
                            containingProject,
                            importedProject,
                            line,
                            column,
                            stringTable.Intern(reason));
                        return(noImport);
                    }
                }
                else if (arguments.Length == 6)
                {
                    if (message == Strings.ProjectImportSkippedFalseCondition)
                    {
                        var    project           = (string)arguments[0];
                        var    containingProject = (string)arguments[1];
                        var    line               = ParseInt(arguments[2]);
                        var    column             = ParseInt(arguments[3]);
                        var    condition          = (string)arguments[4];
                        var    evaluatedCondition = (string)arguments[5];
                        string reason             = $"false condition; ({condition} was evaluated as {evaluatedCondition}).";

                        var noImport = new NoImport(
                            stringTable.Intern(containingProject),
                            stringTable.Intern(project),
                            line,
                            column,
                            stringTable.Intern(reason));
                        return(noImport);
                    }
                }
                else if (arguments.Length == 1)
                {
                    if (message == Strings.CouldNotResolveSdk)
                    {
                        var sdk      = (string)arguments[0];
                        var noImport = new NoImport(
                            stringTable.Intern(args.ProjectFile),
                            stringTable.Intern(args.ImportedProjectFile),
                            args.LineNumber,
                            args.ColumnNumber,
                            stringTable.Intern(string.Format(message, sdk)));
                        return(noImport);
                    }
                }
            }

            var parsed = TryGetImportOrNoImport(args.Message, stringTable);

            return(parsed);
        }
        /// <summary>
        /// Parses a log output string to a list of Items (e.g. ItemGroup with metadata or property string).
        /// </summary>
        /// <param name="message">The message output from the logger.</param>
        /// <param name="prefix">The prefix parsed out (e.g. 'Output Item(s): '.).</param>
        /// <param name="name">Out: The name of the list.</param>
        /// <returns>List of items within the list and all metadata.</returns>
        public static object ParsePropertyOrItemList(string message, string prefix, StringCache stringTable)
        {
            if (!Utilities.ContainsLineBreak(message))
            {
                var nameValue = Utilities.ParseNameValue(message, trimFromStart: prefix.Length);
                var property  = new Property
                {
                    Name  = stringTable.Intern(nameValue.Key),
                    Value = stringTable.Intern(nameValue.Value)
                };
                return(property);
            }

            message = message.Replace("\r\n", "\n");
            message = message.Replace('\r', '\n');
            var lines = message.Split('\n');

            var parameter = new Parameter();

            if (lines[0].Length > prefix.Length)
            {
                // we have a weird case of multi-line value
                var nameValue = Utilities.ParseNameValue(lines[0].Substring(prefix.Length));

                parameter.Name = stringTable.Intern(nameValue.Key);

                parameter.AddChild(new Item
                {
                    Text = stringTable.Intern(nameValue.Value.Replace("\r", ""))
                });

                for (int i = 1; i < lines.Length; i++)
                {
                    parameter.AddChild(new Item
                    {
                        Text = stringTable.Intern(lines[i].Replace("\r", ""))
                    });
                }

                return(parameter);
            }

            Item     currentItem     = null;
            Property currentProperty = null;

            foreach (var line in lines)
            {
                var numberOfLeadingSpaces = Utilities.GetNumberOfLeadingSpaces(line);
                switch (numberOfLeadingSpaces)
                {
                case 4:
                    if (line.EndsWith("=", StringComparison.Ordinal))
                    {
                        parameter.Name = stringTable.Intern(line.Substring(4, line.Length - 5));
                    }
                    break;

                case 8:
                    if (line.IndexOf('=') != -1)
                    {
                        var kvp = Utilities.ParseNameValue(line.Substring(8));
                        currentProperty = new Property
                        {
                            Name  = stringTable.Intern(kvp.Key),
                            Value = stringTable.Intern(kvp.Value)
                        };
                        parameter.AddChild(currentProperty);
                        currentItem = null;
                    }
                    else
                    {
                        currentItem = new Item
                        {
                            Text = stringTable.Intern(line.Substring(8))
                        };
                        parameter.AddChild(currentItem);
                        currentProperty = null;
                    }
                    break;

                case 16:
                    var currentLine = line.Substring(16);
                    if (currentItem != null)
                    {
                        if (!currentLine.Contains("="))
                        {
                            // must be a continuation of the metadata value from the previous line
                            if (currentItem.HasChildren)
                            {
                                var metadata = currentItem.Children[currentItem.Children.Count - 1] as Metadata;
                                if (metadata != null)
                                {
                                    metadata.Value = stringTable.Intern((metadata.Value ?? "") + currentLine);
                                }
                            }
                        }
                        else
                        {
                            var nameValue = Utilities.ParseNameValue(currentLine);
                            var metadata  = new Metadata
                            {
                                Name  = stringTable.Intern(nameValue.Key),
                                Value = stringTable.Intern(nameValue.Value)
                            };
                            currentItem.AddChild(metadata);
                        }
                    }
                    break;

                default:
                    if (numberOfLeadingSpaces == 0 && line == prefix)
                    {
                        continue;
                    }

                    // must be a continuation of a multi-line value
                    if (currentProperty != null)
                    {
                        currentProperty.Value += "\n" + line;
                    }
                    else if (currentItem != null && currentItem.HasChildren)
                    {
                        var metadata = currentItem.Children[currentItem.Children.Count - 1] as Metadata;
                        if (metadata != null)
                        {
                            metadata.Value = (metadata.Value ?? "") + line;
                        }
                    }
                    break;
                }
            }

            return(parameter);
        }
 public static void Analyze(Folder evaluation, StringCache stringTable)
 {
     evaluation.VisitAllChildren <Message>(m => VisitMessage(m, stringTable), takeChildrenSnapshot: true);
 }
Esempio n. 18
0
        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);
                        }
                    }
                }
            }
        }