/// <summary>
        /// Handles BuildMessage event when an ItemGroup discovery/evaluation is logged.
        /// </summary>
        /// <param name="args">The <see cref="BuildMessageEventArgs"/> instance containing the event data.</param>
        /// <param name="prefix">The prefix string.</param>
        public void AddItemGroup(BuildMessageEventArgs args, string prefix, NamedNode containerNode)
        {
            var project = construction.GetOrAddProject(args.BuildEventContext.ProjectContextId);
            var target  = project.GetTargetById(args.BuildEventContext.TargetId);

            var itemGroup = ItemGroupParser.ParsePropertyOrItemList(args.Message, prefix, stringTable);

            if (itemGroup is Property property)
            {
                itemGroup = new Item
                {
                    Text = property.Value
                };
                containerNode.Name = property.Name;
                containerNode.AddChild(itemGroup);
            }
            else if (itemGroup is Parameter parameter)
            {
                containerNode.Name = parameter.Name;
                foreach (ParentedNode child in parameter.Children)
                {
                    child.Parent = null;
                    containerNode.AddChild(child);
                }
            }

            if (target.LastChild is NamedNode last &&
                last.GetType() == containerNode.GetType() &&
                last.Name == containerNode.Name)
            {
                foreach (ParentedNode child in containerNode.Children)
                {
                    child.Parent = null;
                    last.AddChild(child);
                }

                return;
            }

            target.AddChild(containerNode);
        }
Exemple #2
0
        private void ProcessTaskParameter(TaskParameterEventArgs args)
        {
            string itemName = args.ItemName;
            var    items    = args.Items.OfType <ITaskItem>().ToArray();

            NamedNode parent = null;
            BaseNode  node   = null;

            if (args.Kind == TaskParameterMessageKind.TaskInput || args.Kind == TaskParameterMessageKind.TaskOutput)
            {
                var task = GetTask(args);
                if (task == null || IgnoreParameters(task))
                {
                    return;
                }

                string folderName = args.Kind == TaskParameterMessageKind.TaskInput ? Strings.Parameters : Strings.OutputItems;
                parent = task.GetOrCreateNodeWithName <Folder>(folderName);

                node = CreateParameterNode(itemName, items);
            }
            else if (args.Kind == TaskParameterMessageKind.AddItem || args.Kind == TaskParameterMessageKind.RemoveItem)
            {
                parent = GetTarget(args);

                NamedNode named;
                if (args.Kind == TaskParameterMessageKind.AddItem)
                {
                    named = new AddItem();
                }
                else
                {
                    named = new RemoveItem();
                }

                named.Name = itemName;

                AddItems(items, named);
                node = named;
            }

            if (node != null && parent != null)
            {
                parent.AddChild(node);
            }
        }
Exemple #3
0
        /// <summary>
        /// Handles BuildMessage event when an ItemGroup discovery/evaluation is logged.
        /// </summary>
        /// <param name="args">The <see cref="BuildMessageEventArgs"/> instance containing the event data.</param>
        /// <param name="prefix">The prefix string.</param>
        public void AddItemGroup(BuildMessageEventArgs args, string prefix, NamedNode containerNode)
        {
            var project   = construction.GetOrAddProject(args.BuildEventContext.ProjectContextId);
            var target    = project.GetTargetById(args.BuildEventContext.TargetId);
            var itemGroup = ItemGroupParser.ParsePropertyOrItemList(args.Message, prefix, stringTable);
            var property  = itemGroup as Property;

            if (property != null)
            {
                itemGroup = new Item
                {
                    Name = property.Name,
                    Text = property.Value
                };
                containerNode.Name = stringTable.Intern(property.Name);
            }

            containerNode.AddChild(itemGroup);
            target.AddChild(containerNode);
        }
        private void ProcessTaskParameter(TaskParameterEventArgs args)
        {
            string itemType = args.ItemType;
            var    items    = args.Items;
            var    kind     = args.Kind;

            NamedNode parent = null;
            BaseNode  node   = null;

            if (kind == TaskParameterMessageKind.TaskInput || kind == TaskParameterMessageKind.TaskOutput)
            {
                var task = GetTask(args);
                if (task == null || IgnoreParameters(task))
                {
                    return;
                }

                bool isOutput = kind == TaskParameterMessageKind.TaskOutput;

                string folderName = isOutput ? Strings.OutputItems : Strings.Parameters;
                parent = task.GetOrCreateNodeWithName <Folder>(folderName);

                node = CreateParameterNode(itemType, items, isOutput);
            }
            else if (
                kind == TaskParameterMessageKind.AddItem ||
                kind == TaskParameterMessageKind.RemoveItem ||
                kind == TaskParameterMessageKind.SkippedTargetInputs ||
                kind == TaskParameterMessageKind.SkippedTargetOutputs)
            {
                parent = GetTarget(args);

                NamedNode named;
                if (kind == TaskParameterMessageKind.AddItem)
                {
                    named = new AddItem
                    {
                        LineNumber = args.LineNumber
                    };
                }
                else if (kind == TaskParameterMessageKind.RemoveItem)
                {
                    named = new RemoveItem
                    {
                        LineNumber = args.LineNumber
                    };
                }
                else
                {
                    named = new Folder();
                    if (kind == TaskParameterMessageKind.SkippedTargetInputs)
                    {
                        itemType = Strings.Inputs;
                    }
                    else
                    {
                        itemType = Strings.Outputs;
                    }
                }

                named.Name = itemType;

                AddItems(items, named);
                node = named;
            }

            if (node != null && parent != null)
            {
                parent.AddChild(node);
            }
        }
Exemple #5
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 BaseNode ParsePropertyOrItemList(string message, string prefix, StringCache stringTable, bool isOutputItem = false)
        {
            if (!TextUtilities.ContainsLineBreak(message))
            {
                var nameValue = TextUtilities.ParseNameValue(message, trimFromStart: prefix.Length);
                if (!isOutputItem)
                {
                    var property = new Property
                    {
                        Name  = stringTable.Intern(nameValue.Key),
                        Value = stringTable.Intern(nameValue.Value)
                    };
                    return(property);
                }
                else
                {
                    var singleItem = new AddItem {
                        Name = stringTable.Intern(nameValue.Key)
                    };
                    var item = new Item {
                        Text = stringTable.Intern(nameValue.Value)
                    };
                    singleItem.AddChild(item);
                    return(singleItem);
                }
            }

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

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

            NamedNode parameter = isOutputItem ? new AddItem() : 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 = stringTable.Intern(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);
        }