private void AnalyzeEvaluation(NamedNode folder) { var evaluations = folder.Children.OfType <ProjectEvaluation>().ToArray(); if (!evaluations.Any()) { return; } var longestDuration = evaluations.Max(e => e.Duration.TotalMilliseconds); if (longestDuration == 0) { longestDuration = 1; } foreach (var projectEvaluation in evaluations) { var properties = projectEvaluation.FindChild <NamedNode>(Strings.Properties); if (properties == null) { continue; } properties.SortChildren(); projectEvaluation.RelativeDuration = projectEvaluation.Duration.TotalMilliseconds * 100.0 / longestDuration; } }
public void OnAdded(NamedNode child) { if (child?.LookupKey == null) { return; } EnsureCacheCreated(); var key = new ChildrenCacheKey(child.GetType(), child.LookupKey); childrenCache[key] = child; }
private void AnalyzeEvaluation(NamedNode folder) { foreach (var projectEvaluation in folder.Children.OfType <ProjectEvaluation>()) { var properties = projectEvaluation.FindChild <NamedNode>(Strings.Properties); if (properties == null) { continue; } properties.SortChildren(); } }
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); } }
/// <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); }
/// <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); }
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); } }
public static void Analyze(NamedNode evaluation, StringCache stringTable) { evaluation.VisitAllChildren <Message>(m => VisitMessage(m, stringTable), takeChildrenSnapshot: true); }
/// <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); }