예제 #1
0
        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);
                        }
                    }
                }
            }
        }
예제 #2
0
        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}");
        }
예제 #3
0
        /// <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 });
                }
            }
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
            }
        }
예제 #10
0
 /// <inheritdoc/>
 public void LoadSarifLog(string path)
 {
     ErrorListService.ProcessLogFile(path, SarifViewerPackage.Dte.Solution, ToolFormat.None, promptOnLogConversions: true);
 }
예제 #11
0
        /// <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);
            }
        }
예제 #12
0
 /// <inheritdoc/>
 public void CloseSarifLogs(IEnumerable <string> paths)
 {
     ErrorListService.CloseSarifLogs(paths);
 }
예제 #13
0
 /// <inheritdoc/>
 public void CloseAllSarifLogs()
 {
     ErrorListService.CloseAllSarifLogs();
 }
예제 #14
0
        /// <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);
        }