/// <summary> /// Initializes the logger and subscribes to the relevant events. /// </summary> /// <param name="eventSource">The available events that processEvent logger can subscribe to.</param> public override void Initialize(IEventSource eventSource) { ProcessParameters(); eventSource.BuildStarted += (s, args) => _build = new Build(args); eventSource.BuildFinished += (o, args) => _build.CompleteBuild(args, _logFile, _errors, _warings); eventSource.ProjectStarted += (o, args) => TryProcessEvent(() => _build.AddProject(args)); eventSource.ProjectFinished += (o, args) => TryProcessEvent(() => _build.CompleteProject(args)); eventSource.TargetStarted += (o, args) => TryProcessEvent(() => _build.AddTarget(args)); eventSource.TargetFinished += (o, args) => TryProcessEvent(() => _build.CompleteTarget(args)); eventSource.TaskStarted += (o, args) => TryProcessEvent(() => _build.AddTask(args)); eventSource.TaskFinished += (o, args) => TryProcessEvent(() => _build.CompleteTask(args)); eventSource.TaskFinished += (o, args) => TryProcessEvent(() => _build.CompleteTask(args)); eventSource.MessageRaised += HandleMessageRaised; eventSource.ErrorRaised += (o, args) => { _errors++; _build.AddMessage(args, string.Format("Error {0}: {1}", args.Code, args.Message)); }; eventSource.WarningRaised += (o, args) => { _warings++; _build.AddMessage(args, string.Format("Warning {0}: {1}", args.Code, args.Message)); }; }
private static IEnumerable <StLogger.Error> FindAllErrors(StLogger.Build build) { var lst = new List <StLogger.Error>(); build.VisitAllChildren <StLogger.Error>(er => lst.Add(er)); return(lst); }
public BuildControl(Build build) { InitializeComponent(); DataContext = build; Build = build; var existingTreeViewItemStyle = (Style)Application.Current.Resources[typeof(TreeViewItem)]; var treeViewItemStyle = new Style(typeof(TreeViewItem), existingTreeViewItemStyle); treeViewItemStyle.Setters.Add(new Setter(TreeViewItem.IsExpandedProperty, new Binding("IsExpanded") { Mode = BindingMode.TwoWay })); treeViewItemStyle.Setters.Add(new Setter(TreeViewItem.IsSelectedProperty, new Binding("IsSelected") { Mode = BindingMode.TwoWay })); treeViewItemStyle.Setters.Add(new Setter(TreeViewItem.VisibilityProperty, new Binding("IsVisible") { Mode = BindingMode.TwoWay, Converter = new BooleanToVisibilityConverter() })); treeViewItemStyle.Setters.Add(new EventSetter(MouseDoubleClickEvent, (MouseButtonEventHandler)OnItemDoubleClick)); treeViewItemStyle.Setters.Add(new EventSetter(RequestBringIntoViewEvent, (RequestBringIntoViewEventHandler)TreeViewItem_RequestBringIntoView)); //treeViewItemStyle.Setters.Add(new Setter(FrameworkElement.ContextMenuProperty, contextMenu)); treeView.ItemContainerStyle = treeViewItemStyle; treeView.KeyDown += TreeView_KeyDown; treeView.SelectedItemChanged += TreeView_SelectedItemChanged; resultsList.ItemContainerStyle = treeViewItemStyle; resultsList.SelectedItemChanged += ResultsList_SelectionChanged; breadCrumb.SelectionChanged += BreadCrumb_SelectionChanged; Loaded += BuildControl_Loaded; typingConcurrentOperation.DisplayResults += results => DisplaySearchResults(results); }
public static async Task <Compilation> GetCompilationFromProject(string csprojPath, params string[] preprocessorSymbols) { StLogger.Build build = await GetBuildResult(csprojPath, preprocessorSymbols).ConfigureAwait(false); using (Workspace workspace = GetWorkspaceFromBuild(build, preprocessorSymbols)) { workspace.WorkspaceFailed += WorkSpaceFailed; Project project = workspace.CurrentSolution.Projects.First(); project = project .WithParseOptions((project.ParseOptions as CSharpParseOptions).WithPreprocessorSymbols(preprocessorSymbols)) .WithCompilationOptions((project.CompilationOptions as CSharpCompilationOptions).WithAllowUnsafe(true)); Compilation compilation = await project.GetCompilationAsync().ConfigureAwait(false); return(compilation); } }
private static (StLogger.Build, IEnumerable <StLogger.Error>) ProcessBuildLog(string tempPath) { var reader = new StLogger.BinLogReader(); var stlogger = new StLogger.StructuredLogger(); // prevent output temporary file StLogger.StructuredLogger.SaveLogToDisk = false; // never output, but if not set, throw exception when initializing stlogger.Parameters = "tmp.buildlog"; stlogger.Initialize(reader); reader.Replay(Path.Combine(tempPath, "build.binlog")); stlogger.Shutdown(); StLogger.Build buildlog = stlogger.Construction.Build; if (buildlog.Succeeded) { return(buildlog, null); } else { IEnumerable <StLogger.Error> errors = FindAllErrors(buildlog); return(null, errors); } }
public static IEnumerable <KeyValuePair <string, HashSet <string> > > GetDoubleWrites(Build build) { var analyzer = new DoubleWritesAnalyzer(); build.VisitAllChildren <Task>(task => analyzer.AnalyzeTask(task)); return(analyzer.GetDoubleWrites()); }
private static Workspace GetWorkspaceFromBuild(this StLogger.Build build, params string[] preprocessorSymbols) { StLogger.Project csproj = build.Children.OfType <StLogger.Project>().FirstOrDefault(); if (csproj == null) { throw new InvalidOperationException("cannot find cs project build"); } StLogger.Item[] compileItems = Array.Empty <StLogger.Item>(); var properties = new Dictionary <string, StLogger.Property>(); foreach (StLogger.Folder folder in csproj.Children.OfType <StLogger.Folder>()) { if (folder.Name == "Items") { StLogger.Folder compileFolder = folder.Children.OfType <StLogger.Folder>().FirstOrDefault(x => x.Name == "Compile"); if (compileFolder == null) { throw new InvalidOperationException("failed to get compililation documents"); } compileItems = compileFolder.Children.OfType <StLogger.Item>().ToArray(); } else if (folder.Name == "Properties") { properties = folder.Children.OfType <StLogger.Property>().ToDictionary(x => x.Name); } } StLogger.Item[] assemblies = Array.Empty <StLogger.Item>(); foreach (StLogger.Target target in csproj.Children.OfType <StLogger.Target>()) { if (target.Name == "ResolveReferences") { StLogger.Folder folder = target.Children.OfType <StLogger.Folder>().Where(x => x.Name == "TargetOutputs").FirstOrDefault(); if (folder == null) { throw new InvalidOperationException("cannot find result of resolving assembly"); } assemblies = folder.Children.OfType <StLogger.Item>().ToArray(); } } var ws = new AdhocWorkspace(); Project roslynProject = ws.AddProject(Path.GetFileNameWithoutExtension(csproj.ProjectFile), Microsoft.CodeAnalysis.LanguageNames.CSharp); var projectDir = properties["ProjectDir"].Value; Guid pguid = properties.ContainsKey("ProjectGuid") ? Guid.Parse(properties["ProjectGuid"].Value) : Guid.NewGuid(); var projectGuid = ProjectId.CreateFromSerialized(pguid); foreach (StLogger.Item compile in compileItems) { var filePath = compile.Text; var absFilePath = Path.Combine(projectDir, filePath); roslynProject = roslynProject.AddDocument(filePath, File.ReadAllText(absFilePath)).Project; } foreach (StLogger.Item asm in assemblies) { roslynProject = roslynProject.AddMetadataReference(MetadataReference.CreateFromFile(asm.Text)); } var compopt = roslynProject.CompilationOptions as CSharpCompilationOptions; compopt = roslynProject.CompilationOptions as CSharpCompilationOptions; compopt = compopt ?? new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary); OutputKind kind; switch (properties["OutputType"].Value) { case "Exe": kind = OutputKind.ConsoleApplication; break; case "Library": kind = OutputKind.DynamicallyLinkedLibrary; break; default: kind = OutputKind.DynamicallyLinkedLibrary; break; } roslynProject = roslynProject.WithCompilationOptions(compopt.WithOutputKind(kind).WithAllowUnsafe(true)); var parseopt = roslynProject.ParseOptions as CSharpParseOptions; roslynProject = roslynProject.WithParseOptions(parseopt.WithPreprocessorSymbols(preprocessorSymbols)); if (!ws.TryApplyChanges(roslynProject.Solution)) { throw new InvalidOperationException("failed to apply solution changes to workspace"); } return(ws); }
public static void WriteToXml(Build build, string logFile) { var writer = new XmlLogWriter(); writer.Write(build, logFile); }
public BuildAnalyzer(Build build) { this.build = build; doubleWritesAnalyzer = new DoubleWritesAnalyzer(); resolveAssemblyReferenceAnalyzer = new ResolveAssemblyReferenceAnalyzer(); }
private static void Seal(Build build) { build.VisitAllChildren <TreeNode>(t => t.Seal()); }
public BuildAnalyzer(Build build) { this.build = build; }
public static Build ReadBuild(string filePath) { var eventSource = new BinaryLogReplayEventSource(); byte[] sourceArchive = null; Build build = null; eventSource.OnBlobRead += (kind, bytes) => { if (kind == BinaryLogRecordKind.ProjectImportArchive) { sourceArchive = bytes; } }; eventSource.OnException += ex => { if (build != null) { build.AddChild(new Error() { Text = "Error when reading the file: " + ex.ToString() }); } }; StructuredLogger.SaveLogToDisk = false; StructuredLogger.CurrentBuild = null; var structuredLogger = new StructuredLogger(); structuredLogger.Parameters = "build.buildlog"; structuredLogger.Initialize(eventSource); build = structuredLogger.Construction.Build; var sw = Stopwatch.StartNew(); eventSource.Replay(filePath); var elapsed = sw.Elapsed; structuredLogger.Shutdown(); build = StructuredLogger.CurrentBuild; StructuredLogger.CurrentBuild = null; if (build == null) { build = new Build() { Succeeded = false }; build.AddChild(new Error() { Text = "Error when opening the file: " + filePath }); } var projectImportsZip = Path.ChangeExtension(filePath, ".ProjectImports.zip"); if (sourceArchive == null && File.Exists(projectImportsZip)) { sourceArchive = File.ReadAllBytes(projectImportsZip); } build.SourceFilesArchive = sourceArchive; // build.AddChildAtBeginning(new Message { Text = "Elapsed: " + elapsed.ToString() }); return(build); }
public static Build ReadBuild(Stream stream, Progress progress, byte[] projectImportsArchive = null) { var eventSource = new BinLogReader(); Build build = null; IEnumerable <string> strings = null; eventSource.OnBlobRead += (kind, bytes) => { if (kind == BinaryLogRecordKind.ProjectImportArchive) { projectImportsArchive = bytes; } }; eventSource.OnException += ex => { if (build != null) { build.AddChild(new Error() { Text = "Error when reading the file: " + ex.ToString() }); } }; eventSource.OnStringDictionaryComplete += s => { strings = s; }; StructuredLogger.SaveLogToDisk = false; StructuredLogger.CurrentBuild = null; var structuredLogger = new StructuredLogger(); structuredLogger.Parameters = "build.buildlog"; structuredLogger.Initialize(eventSource); build = structuredLogger.Construction.Build; eventSource.OnFileFormatVersionRead += fileFormatVersion => { build.FileFormatVersion = fileFormatVersion; // strings are deduplicated starting with version 10 if (fileFormatVersion >= 10) { build.StringTable.NormalizeLineEndings = false; if (ReuseBinlogStrings) { build.StringTable.DisableDeduplication = true; } } }; var sw = Stopwatch.StartNew(); eventSource.Replay(stream, progress); var elapsed = sw.Elapsed; if (strings != null) { if (ReuseBinlogStrings) { // since strings are already deduplicated in the file, no need to do it again build.StringTable.SetStrings(strings); } else { // intern all strings in one fell swoop here instead of interning multiple times // one by one when processing task parameters build.StringTable.Intern(strings); } } structuredLogger.Shutdown(); build = StructuredLogger.CurrentBuild; StructuredLogger.CurrentBuild = null; if (build == null) { build = new Build() { Succeeded = false }; build.AddChild(new Error() { Text = "Error when opening the log file." }); } if (build.SourceFilesArchive == null && projectImportsArchive != null) { build.SourceFilesArchive = projectImportsArchive; } // strings = build.StringTable.Instances.OrderBy(s => s).ToArray(); // Serialization.WriteStringsToFile(@"C:\temp\1.txt", strings.ToArray()); return(build); }
public Construction() { Build = new Build(); this.stringTable = Build.StringTable; this.messageProcessor = new MessageProcessor(this, stringTable); }
private void DisplayBuild(Build build) { currentBuild = build != null ? new BuildControl(build) : null; SetContent(currentBuild); GC.Collect(); if (currentBuild != null && currentBuild.Name != null) this.dir.Text = Path.GetDirectoryName(build.Name); }
public Build Read(Stream stream) { Build build = new Build(); this.stringTable = build.StringTable; var stack = new Stack <BaseNode>(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 Build ReadBuild(Stream stream, byte[] projectImportsArchive = null) { var eventSource = new BinaryLogReplayEventSource(); Build build = null; eventSource.OnBlobRead += (kind, bytes) => { if (kind == BinaryLogRecordKind.ProjectImportArchive) { projectImportsArchive = bytes; } }; eventSource.OnException += ex => { if (build != null) { build.AddChild(new Error() { Text = "Error when reading the file: " + ex.ToString() }); } }; StructuredLogger.SaveLogToDisk = false; StructuredLogger.CurrentBuild = null; var structuredLogger = new StructuredLogger(); structuredLogger.Parameters = "build.buildlog"; structuredLogger.Initialize(eventSource); build = structuredLogger.Construction.Build; var sw = Stopwatch.StartNew(); eventSource.Replay(stream); var elapsed = sw.Elapsed; structuredLogger.Shutdown(); build = StructuredLogger.CurrentBuild; StructuredLogger.CurrentBuild = null; if (build == null) { build = new Build() { Succeeded = false }; build.AddChild(new Error() { Text = "Error when opening the log file." }); } if (build.SourceFilesArchive == null && projectImportsArchive != null) { build.SourceFilesArchive = projectImportsArchive; } // build.AddChildAtBeginning(new Message { Text = "Elapsed: " + elapsed.ToString() }); return(build); }
private void PostAnalyzeBuild(Build build) { string Intern(string text) { #if DEBUG text = build.StringTable.Intern(text); #endif return(text); } if (!build.Succeeded) { build.AddChild(new Error { Text = Intern("Build failed.") }); } else { build.AddChild(new Item { Text = Intern("Build succeeded.") }); } build.AddChild(new Property { Name = Intern(Strings.Duration), Value = Intern(build.DurationText) }); doubleWritesAnalyzer.AppendDoubleWritesFolder(build); resolveAssemblyReferenceAnalyzer.AppendFinalReport(build); if (build.LogFilePath != null) { build.AddChildAtBeginning(new Item { Text = Intern(build.LogFilePath) }); } var durations = taskDurations .OrderByDescending(kvp => kvp.Value) .Where(kvp => // no need to include MSBuild and CallTarget tasks as they are not "terminal leaf" tasks !string.Equals(kvp.Key, "MSBuild", StringComparison.OrdinalIgnoreCase) && !string.Equals(kvp.Key, "CallTarget", StringComparison.OrdinalIgnoreCase)) .Take(10) .ToArray(); if (durations.Length > 0) { string folderName = $"Top {durations.Count()} most expensive tasks"; folderName = Intern(folderName); var top10Tasks = build.GetOrCreateNodeWithName <Folder>(folderName); foreach (var kvp in durations) { top10Tasks.AddChild(new Item { Name = Intern(kvp.Key), Text = Intern(TextUtilities.DisplayDuration(kvp.Value)) }); } } if (analyzerReports.Count > 0) { var analyzerReportSummary = build.GetOrCreateNodeWithName <Folder>(Intern($"Analyzer Summary")); CscTaskAnalyzer.CreateMergedReport(analyzerReportSummary, analyzerReports.ToArray()); } }
public BuildAnalyzer(Build build) { this.build = build; doubleWritesAnalyzer = new DoubleWritesAnalyzer(); }
public static IEnumerable <CompilerInvocation> ReadInvocations(Build build) { return(new CompilerInvocationsReader().Read(build)); }