private void TextView_Closed(object sender, EventArgs e) { ThreadHelper.ThrowIfNotOnUIThread(); if (sender is ITextView textView) { textView.Closed -= this.TextView_Closed; if (this.TryGetFileNameFromTextView(textView, out string filename) && this.IsSarifLogFile(filename) && this.IsSarifContentType(textView.TextBuffer.ContentType.TypeName)) { if (textBufferMap.ContainsKey(textView.TextBuffer)) { textBufferMap[textView.TextBuffer]--; if (textBufferMap[textView.TextBuffer] <= 0) { ErrorListService.CloseSarifLogs(new[] { filename }); textBufferMap.TryRemove(textView.TextBuffer, out int value); } } } } }
public void TextViewCreated(ITextView textView) { ThreadHelper.ThrowIfNotOnUIThread(); textView.Closed += this.TextView_Closed; if (this.TryGetFileNameFromTextView(textView, out string filename) && this.IsSarifLogFile(filename) && this.IsSarifContentType(textView.TextBuffer.ContentType.TypeName)) { // since Json (base type of sarif log) editor throws error when file size is greater than 5 MBs // need to listen to content type "text". Only process log if file extension is ".sarif". if (!textBufferMap.ContainsKey(textView.TextBuffer)) { textBufferMap.TryAdd(textView.TextBuffer, 0); if (!ErrorListService.IsSarifLogOpened(filename)) { ErrorListService.ProcessLogFile(filename, ToolFormat.None, promptOnLogConversions: true, cleanErrors: false, openInEditor: false); } } textBufferMap[textView.TextBuffer]++; } Trace.WriteLine($"Opening file: {filename} content type: {textView.TextBuffer.ContentType.TypeName}"); }
/// <inheritdoc/> public void LoadSarifLog(string path, bool promptOnSchemaUpgrade = true) { if (string.IsNullOrWhiteSpace(path)) { return; } ErrorListService.ProcessLogFile(path, SarifViewerPackage.Dte.Solution, ToolFormat.None, promptOnSchemaUpgrade); }
public void TextViewCreated(ITextView textView) { ThreadHelper.ThrowIfNotOnUIThread(); textView.Closed += this.TextView_Closed; if (this.TryGetFileNameFromTextView(textView, out string filename)) { ErrorListService.ProcessLogFile(filename, ToolFormat.None, promptOnLogConversions: true, cleanErrors: false, openInEditor: false); } }
public void LoadSarifLog(string path) { if (!string.IsNullOrWhiteSpace(path)) { try { ErrorListService.ProcessLogFile(path, SarifViewerPackage.Dte.Solution, ToolFormat.None); } catch (InvalidCastException) { } } }
private void TextView_Closed(object sender, EventArgs e) { ThreadHelper.ThrowIfNotOnUIThread(); if (sender is ITextView textView) { textView.Closed -= this.TextView_Closed; if (this.TryGetFileNameFromTextView(textView, out string filename)) { ErrorListService.CloseSarifLogs(new[] { filename }); } } }
public int CreateEditorInstance( uint grfCreateDoc, string pszMkDocument, string pszPhysicalView, IVsHierarchy pvHier, uint itemid, IntPtr punkDocDataExisting, out IntPtr ppunkDocView, out IntPtr ppunkDocData, out string pbstrEditorCaption, out Guid pguidCmdUI, out int pgrfCDW) { ppunkDocView = IntPtr.Zero; ppunkDocData = IntPtr.Zero; pguidCmdUI = Guids.GuidSarifEditorFactory; pgrfCDW = 0; pbstrEditorCaption = null; // Validate inputs if ((grfCreateDoc & (VSConstants.CEF_OPENFILE | VSConstants.CEF_SILENT)) == 0) { return(VSConstants.E_INVALIDARG); } if (punkDocDataExisting != IntPtr.Zero) { return(VSConstants.VS_E_INCOMPATIBLEDOCDATA); } if ((grfCreateDoc & VSConstants.CEF_OPENFILE) == VSConstants.CEF_OPENFILE) { TelemetryProvider.WriteEvent(TelemetryEvent.LogFileOpenedByEditor, TelemetryProvider.CreateKeyValuePair("Format", "SARIF")); ErrorListService.ProcessLogFile(pszMkDocument, SarifViewerPackage.Dte.Solution); } return(VSConstants.S_OK); }
public int CreateEditorInstance( uint grfCreateDoc, string pszMkDocument, string pszPhysicalView, IVsHierarchy pvHier, uint itemid, IntPtr punkDocDataExisting, out IntPtr ppunkDocView, out IntPtr ppunkDocData, out string pbstrEditorCaption, out Guid pguidCmdUI, out int pgrfCDW) { ppunkDocView = IntPtr.Zero; ppunkDocData = IntPtr.Zero; pguidCmdUI = Guids.GuidSarifEditorFactory; pgrfCDW = 0; pbstrEditorCaption = null; // Validate inputs if ((grfCreateDoc & (VSConstants.CEF_OPENFILE | VSConstants.CEF_SILENT)) == 0) { return(VSConstants.E_INVALIDARG); } if (punkDocDataExisting != IntPtr.Zero) { return(VSConstants.VS_E_INCOMPATIBLEDOCDATA); } if ((grfCreateDoc & VSConstants.CEF_OPENFILE) == VSConstants.CEF_OPENFILE) { ErrorListService.ProcessLogFile(pszMkDocument); } return(VSConstants.S_OK); }
private async System.Threading.Tasks.Task MenuItemCallbackAsync(object sender, EventArgs e) { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); var menuCommand = (OleMenuCommand)sender; var menuCmdEventArgs = (OleMenuCmdEventArgs)e; string inputFile = menuCmdEventArgs.InValue as string; string logFile = null; if (!string.IsNullOrWhiteSpace(inputFile)) { // If the input file is a URL, download the file. if (Uri.IsWellFormedUriString(inputFile, UriKind.Absolute)) { TryDownloadFile(inputFile, out logFile); } else { // Verify if the input file is valid. i.e. it exists and has a valid file extension. string logFileExtension = Path.GetExtension(inputFile); // Since we don't have a tool format, only accept *.sarif and *.json files as command input files. if (logFileExtension.Equals(".sarif", StringComparison.OrdinalIgnoreCase) || logFileExtension.Equals(".json", StringComparison.OrdinalIgnoreCase)) { if (File.Exists(inputFile)) { logFile = inputFile; } } } } string toolFormat = ToolFormat.None; if (logFile == null) { FieldInfo[] toolFormatFieldInfos = typeof(ToolFormat).GetFields(); var fieldInfoToOpenFileDialogFilterDisplayString = new List <KeyValuePair <FieldInfo, string> >(toolFormatFieldInfos.Length); // Note that "ImportNoneFilter" represents the SARIF file filter (which matches what the code logic does below as well). foreach (FieldInfo fieldInfo in toolFormatFieldInfos) { string resourceName = string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}", FilterResourceNamePrefix, fieldInfo.Name, FilterResourceNameSuffix); string openFileDialogFilterString = Resources.ResourceManager.GetString(resourceName, CultureInfo.CurrentCulture); fieldInfoToOpenFileDialogFilterDisplayString.Add(new KeyValuePair <FieldInfo, string>(fieldInfo, openFileDialogFilterString)); } // Sort the filters by their display strings so the user has a nice alphabetized list with import SARIF at the top. KeyValuePair <FieldInfo, string> noneFieldInfo = fieldInfoToOpenFileDialogFilterDisplayString. Single(kvp => kvp.Key.Name.Equals(nameof(ToolFormat.None), StringComparison.OrdinalIgnoreCase)); // Linq's OrderBy does the right sorting.. // It ultimately does CultureInfo.CurrentCulture.CompareInfo.Compare(this, strB, CompareOptions.None); IEnumerable <KeyValuePair <FieldInfo, string> > orderedFilters = Enumerable.Repeat(noneFieldInfo, 1).Concat( fieldInfoToOpenFileDialogFilterDisplayString.Where(kvp => kvp.Key != noneFieldInfo.Key). OrderBy(kvp => kvp.Value)); var openFileDialog = new OpenFileDialog() { Title = Resources.ImportLogOpenFileDialogTitle, Filter = string.Join("|", orderedFilters.Select(kvp => kvp.Value)), RestoreDirectory = true, Multiselect = false, }; if (!string.IsNullOrWhiteSpace(inputFile)) { openFileDialog.FileName = Path.GetFileName(inputFile); openFileDialog.InitialDirectory = Path.GetDirectoryName(inputFile); } // Read the user's last tool format selection. int collectionExists; var vsSettingsManager = Package.GetGlobalService(typeof(SVsSettingsManager)) as IVsSettingsManager; if (vsSettingsManager != null && vsSettingsManager.GetReadOnlySettingsStore((uint)__VsEnclosingScopes.EnclosingScopes_UserSettings, out IVsSettingsStore vsSettingsStore) == VSConstants.S_OK && vsSettingsStore.CollectionExists(nameof(SarifViewerPackage), out collectionExists) == VSConstants.S_OK && collectionExists != 0 && vsSettingsStore.GetString(nameof(SarifViewerPackage), ToolFormatSettingName, out string openLogFileToolFormat) == VSConstants.S_OK) { int?filterIndex = null; int currentIndex = 0; foreach (FieldInfo fieldInfo in orderedFilters.Select(kvp => kvp.Key)) { if (fieldInfo.Name.Equals(openLogFileToolFormat, StringComparison.Ordinal)) { filterIndex = currentIndex; break; } currentIndex++; } if (filterIndex.HasValue) { // The filter index in the open file dialog is 1 base. openFileDialog.FilterIndex = filterIndex.Value + 1; } } if (openFileDialog.ShowDialog() != DialogResult.OK) { return; } // The filter index in the open file dialog is 1 base. toolFormat = orderedFilters.Skip(openFileDialog.FilterIndex - 1).First().Key.GetValue(null) as string; // Write the user's last tool format selection. if (vsSettingsManager != null && vsSettingsManager.GetWritableSettingsStore((uint)__VsEnclosingScopes.EnclosingScopes_UserSettings, out IVsWritableSettingsStore vsWritableSettingsStore) == VSConstants.S_OK) { if (vsWritableSettingsStore.CollectionExists(nameof(SarifViewerPackage), out collectionExists) != VSConstants.S_OK || collectionExists == 0) { vsWritableSettingsStore.CreateCollection(nameof(SarifViewerPackage)); } vsWritableSettingsStore.SetString(nameof(SarifViewerPackage), ToolFormatSettingName, toolFormat); } logFile = openFileDialog.FileName; } try { await ErrorListService.ProcessLogFileAsync(logFile, toolFormat, promptOnLogConversions : true, cleanErrors : true, openInEditor : true).ConfigureAwait(continueOnCapturedContext: false); } catch (InvalidOperationException) { VsShellUtilities.ShowMessageBox(Microsoft.VisualStudio.Shell.ServiceProvider.GlobalProvider, string.Format(Resources.LogOpenFail_InvalidFormat_DialogMessage, Path.GetFileName(logFile)), null, // title OLEMSGICON.OLEMSGICON_CRITICAL, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST); } }
/// <inheritdoc/> public void LoadSarifLog(string path) { ErrorListService.ProcessLogFile(path, SarifViewerPackage.Dte.Solution, ToolFormat.None, promptOnLogConversions: true); }
/// <summary> /// This function is the callback used to execute the command when the menu item is clicked. /// See the constructor to see how the menu item is associated with this function using /// OleMenuCommandService service and MenuCommand class. /// </summary> /// <param name="sender">Event sender.</param> /// <param name="e">Event args.</param> private void MenuItemCallback(object sender, EventArgs e) { OleMenuCommand menuCommand = (OleMenuCommand)sender; OleMenuCmdEventArgs menuCmdEventArgs = (OleMenuCmdEventArgs)e; string inputFile = menuCmdEventArgs.InValue as String; string logFile = null; if (!String.IsNullOrWhiteSpace(inputFile)) { // If the input file is a URL, download the file. if (Uri.IsWellFormedUriString(inputFile, UriKind.Absolute)) { TryDownloadFile(inputFile, out logFile); } else { // Verify if the input file is valid. i.e. it exists and has a valid file extension. string logFileExtension = Path.GetExtension(inputFile); // Since we don't have a tool format, only accept *.sarif and *.json files as command input files. if (logFileExtension.Equals(".sarif", StringComparison.OrdinalIgnoreCase) || logFileExtension.Equals(".json", StringComparison.OrdinalIgnoreCase)) { if (File.Exists(inputFile)) { logFile = inputFile; } } } } string toolFormat = ToolFormat.None; if (logFile == null) { string title = "Open Static Analysis Results Interchange Format (SARIF) file"; string filter = "SARIF files (*.sarif)|*.sarif"; switch (menuCommand.CommandID.ID) { // These constants expressed in our VSCT case OpenSarifFileCommandId: { // Native SARIF. All our defaults above are fine break; } case OpenPREfastFileCommandId: { toolFormat = ToolFormat.PREfast; title = "Open PREfast XML log file"; filter = "PREfast log files (*.xml)|*.xml"; break; } case OpenStaticDriverVerifierFileCommandId: { toolFormat = ToolFormat.StaticDriverVerifier; title = "Open Static Driver Verifier trace log file"; filter = "Static Driver Verifier log files (*.tt)|*.tt"; break; } case OpenFxCopFileCommandId: { // FxCop. TODO. We need project file support. FxCop // fullMessages look broken. toolFormat = ToolFormat.FxCop; title = "Open FxCop XML log file"; filter = "FxCop report and project files (*.xml)|*.xml"; break; } case OpenCppCheckFileCommandId: { toolFormat = ToolFormat.CppCheck; title = "Open CppCheck XML log file"; filter = "CppCheck log files (*.xml)|*.xml"; break; } case OpenClangFileCommandId: { toolFormat = ToolFormat.ClangAnalyzer; title = "Open Clang XML log file"; filter = "Clang log files (*.xml)|*.xml"; break; } case OpenAndroidStudioFileCommandId: { toolFormat = ToolFormat.AndroidStudio; title = "Open Android Studio XML log file"; filter = "Android Studio log files (*.xml)|*.xml"; break; } case OpenSemmleFileCommandId: { toolFormat = ToolFormat.SemmleQL; title = "Open Semmle QL CSV log file"; filter = "Semmle QL log files (*.csv)|*.csv"; break; } case OpenPylintFileCommand: { toolFormat = ToolFormat.Pylint; title = "Open Pylint JSON log file"; filter = "Pylint log files (*.json)|*.json"; break; } case OpenTSLintFileCommand: { toolFormat = ToolFormat.TSLint; title = "Open TSLint JSON log file"; filter = "TSLint log files (*.json)|*.json"; break; } } OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Title = title; openFileDialog.Filter = filter; openFileDialog.RestoreDirectory = true; if (!String.IsNullOrWhiteSpace(inputFile)) { openFileDialog.FileName = Path.GetFileName(inputFile); openFileDialog.InitialDirectory = Path.GetDirectoryName(inputFile); } if (openFileDialog.ShowDialog() != DialogResult.OK) { return; } logFile = openFileDialog.FileName; } TelemetryProvider.WriteMenuCommandEvent(toolFormat); try { ErrorListService.ProcessLogFile(logFile, SarifViewerPackage.Dte.Solution, toolFormat); } catch (InvalidOperationException) { VsShellUtilities.ShowMessageBox(SarifViewerPackage.ServiceProvider, string.Format(Resources.LogOpenFail_InvalidFormat_DialogMessage, Path.GetFileName(logFile)), null, // title OLEMSGICON.OLEMSGICON_CRITICAL, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST); } }
/// <inheritdoc/> public void CloseSarifLogs(IEnumerable <string> paths) { ErrorListService.CloseSarifLogs(paths); }
/// <inheritdoc/> public void CloseAllSarifLogs() { ErrorListService.CloseAllSarifLogs(); }
/// <summary> /// This function is the callback used to execute the command when the menu item is clicked. /// See the constructor to see how the menu item is associated with this function using /// OleMenuCommandService service and MenuCommand class. /// </summary> /// <param name="sender">Event sender.</param> /// <param name="e">Event args.</param> private void MenuItemCallback(object sender, EventArgs e) { OleMenuCommand menuCommand = (OleMenuCommand)sender; OleMenuCmdEventArgs menuCmdEventArgs = (OleMenuCmdEventArgs)e; string inputFile = menuCmdEventArgs.InValue as String; string logFile = null; if (!String.IsNullOrWhiteSpace(inputFile)) { // If the input file is a URL, download the file. if (Uri.IsWellFormedUriString(inputFile, UriKind.Absolute)) { TryDownloadFile(inputFile, out logFile); } else { // Verify if the input file is valid. i.e. it exists and has a valid file extension. string logFileExtension = Path.GetExtension(inputFile); // Since we don't have a tool format, only accept *.sarif and *.json files as command input files. if (logFileExtension.Equals(".sarif", StringComparison.OrdinalIgnoreCase) || logFileExtension.Equals(".json", StringComparison.OrdinalIgnoreCase)) { if (File.Exists(inputFile)) { logFile = inputFile; } } } } ToolFormat toolFormat = ToolFormat.None; if (logFile == null) { string title = "Open Static Analysis Results Interchange Format (SARIF) file"; string filter = "SARIF files (*.sarif;*.sarif.json)|*.sarif;*.sarif.json"; switch (menuCommand.CommandID.ID) { // These constants expressed in our VSCT case OpenSarifFileCommandId: { // Native SARIF. All our defaults above are fine break; } case OpenPREfastFileCommandId: { toolFormat = ToolFormat.PREfast; title = "Open PREfast XML log file"; filter = "PREfast log files (*.xml)|*.xml"; break; } case OpenFxCopFileCommandId: { // FxCop. TODO. We need project file support. FxCop // fullMessages look broken. toolFormat = ToolFormat.FxCop; title = "Open FxCop XML log file"; filter = "FxCop report and project files (*.xml)|*.xml"; break; } case OpenCppCheckFileCommandId: { toolFormat = ToolFormat.CppCheck; title = "Open CppCheck XML log file"; filter = "CppCheck log files (*.xml)|*.xml"; break; } case OpenClangFileCommandId: { toolFormat = ToolFormat.ClangAnalyzer; title = "Open Clang XML log file"; filter = "Clang log files (*.xml)|*.xml"; break; } case OpenAndroidStudioFileCommandId: { toolFormat = ToolFormat.AndroidStudio; title = "Open Android Studio XML log file"; filter = "Android Studio log files (*.xml)|*.xml"; break; } } OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Title = title; openFileDialog.Filter = filter; openFileDialog.RestoreDirectory = true; if (!String.IsNullOrWhiteSpace(inputFile)) { openFileDialog.FileName = Path.GetFileName(inputFile); openFileDialog.InitialDirectory = Path.GetDirectoryName(inputFile); } if (openFileDialog.ShowDialog() != DialogResult.OK) { return; } logFile = openFileDialog.FileName; } ErrorListService.ProcessLogFile(logFile, toolFormat); }