Esempio n. 1
0
        public SarifLocationTextMarkerTagger(
            ITextView textView,
            ITextBuffer textBuffer,
            IPersistentSpanFactory persistentSpanFactory,
            ITextViewCaretListenerService <ITextMarkerTag> textViewCaretListenerService,
            ISarifErrorListEventSelectionService sarifErrorListEventSelectionService)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            if (!SdkUIUtilities.TryGetFileNameFromTextBuffer(textBuffer, out this.filePath))
            {
                throw new ArgumentException("Always expect to be able to get file name from text buffer.", nameof(textBuffer));
            }

            this.TextBuffer            = textBuffer;
            this.persistentSpanFactory = persistentSpanFactory;
            this.sarifErrorListEventSelectionService = sarifErrorListEventSelectionService;

            // Subscribe to the SARIF error item being selected from the error list
            // so we can properly filter the tags being shown in the editor
            // to the currently selected item.
            this.sarifErrorListEventSelectionService.SelectedItemChanged += this.SelectedSarifItemChanged;

            // Subscribe to the caret position so we can send enter and exit notifications
            // to the tags so they can decide potentially change their colors.
            textViewCaretListenerService.CreateListener(textView, this);
        }
Esempio n. 2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ErrorListCommand"/> class.
        /// Adds our command handlers for menu (commands must exist in the command table file).
        /// </summary>
        /// <param name="package">Owner package, not null.</param>
        private ErrorListCommand(Package package)
        {
            this.package = package ?? throw new ArgumentNullException(nameof(package));

            this.menuCommandService = this.ServiceProvider.GetService(typeof(IMenuCommandService)) as IMenuCommandService;
            Assumes.Present(this.menuCommandService);

            this.AddMenuItem(ClearSarifResultsCommandId);
            this.AddMenuItem(ProvideFeedbackCommandId);
            this.AddMenuItem(UsefulResultCommandId);
            this.AddMenuItem(FalsePositiveResultCommandId);
            this.AddMenuItem(NonActionableResultCommandId);
            this.AddMenuItem(LowValueResultCommandId);
            this.AddMenuItem(NonShippingCodeResultCommandId);
            this.AddMenuItem(OtherResultCommandId);

            // hide by default
            this.SetCommandVisibility(ProvideFeedbackCommandId, false);
            this.SetCommandVisibility(ClearSarifResultsCommandId, false);

            var componentModel = this.ServiceProvider.GetService(typeof(SComponentModel)) as IComponentModel;

            Assumes.Present(componentModel);

            this.selectionService = componentModel.GetService <ISarifErrorListEventSelectionService>();
            this.selectionService.SelectedItemChanged += this.SelectionService_SelectedItemChanged;
            Assumes.Present(this.selectionService);
        }
        public SarifLocationErrorTagger(ITextBuffer textBuffer, IPersistentSpanFactory persistentSpanFactory, ISarifErrorListEventSelectionService sarifErrorListEventSelectionService)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            if (!SdkUIUtilities.TryGetFileNameFromTextBuffer(textBuffer, out this.filePath))
            {
                throw new ArgumentException("Always expect to be able to get file name from text buffer.", nameof(textBuffer));
            }

            this.TextBuffer = textBuffer;

            this.persistentSpanFactory = persistentSpanFactory;
            this.sarifErrorListEventSelectionService = sarifErrorListEventSelectionService;
            this.sarifErrorListEventSelectionService.SelectedItemChanged += this.SarifErrorListEventSelectionService_SelectedItemChanged;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="FixSuggestedActionsSource"/> class.
        /// </summary>
        /// <param name="textView">
        /// The <see cref="ITextView"/> for which this source will offer fix suggestions.
        /// </param>
        /// <param name="textBuffer">
        /// The <see cref="ITextBuffer"/> associated with the <see cref="ITextView"/> for which this
        /// source will offer fix suggestions.
        /// </param>
        /// <param name="persistentSpanFactory">
        /// A factory for creating the persistent spans that specify the error locations and the
        /// replacement locations (which are not necessarily the same).
        /// </param>
        /// <param name="previewProvider">
        /// Creates the XAML UIControl that displays the preview.
        /// </param>
        public FixSuggestedActionsSource(
            ITextView textView,
            ITextBuffer textBuffer,
            IPersistentSpanFactory persistentSpanFactory,
            IPreviewProvider previewProvider)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            this.textView              = textView;
            this.textBuffer            = textBuffer;
            this.persistentSpanFactory = persistentSpanFactory;
            this.previewProvider       = previewProvider;

            if (this.previewProvider is EditActionPreviewProvider editActionPreviewProvider)
            {
                editActionPreviewProvider.ApplyFixesInDocument += this.PreviewProdiver_ApplyFixesInDocument;
            }

            // when text changed and sarif errors item changes, need to refresh errorInFile
            var errorList = ServiceProvider.GlobalProvider.GetService(typeof(SVsErrorList)) as IErrorList;

            this.errorListTableControl = errorList?.TableControl;
            if (this.errorListTableControl != null)
            {
                this.errorListTableControl.EntriesChanged += this.ErrorListTableControl_EntriesChanged;
            }

            var component = ServiceProvider.GlobalProvider.GetService(typeof(SComponentModel)) as IComponentModel;

            this.sarifErrorListEventSelectionService = component?.GetService <ISarifErrorListEventSelectionService>();
            if (this.sarifErrorListEventSelectionService != null)
            {
                this.sarifErrorListEventSelectionService.NavigatedItemChanged += this.SarifListErrorItemNavigated;
            }

            this.RefreshPersistentSpans();

            // Keep track of which error is associated with each suggested action, so that when
            // the action is invoked, the associated error can be marked as fixed. When we mark
            // an error as fixed, we tell VS to recompute the list of suggested actions, so that
            // it doesn't suggest actions for errors that are already fixed.
            this.fixToErrorDictionary = new Dictionary <FixSuggestedAction, SarifErrorListItem>();
        }
Esempio n. 5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SarifExplorerWindow"/> class.
        /// </summary>
        public SarifExplorerWindow()
            : base(null)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            this.Caption = Resources.SarifExplorerCaption;

            // This is the user control hosted by the tool window; Note that, even if this class implements IDisposable,
            // we are not calling Dispose on this object. This is because ToolWindowPane calls Dispose on
            // the object returned by the Content property.
            this.Content           = new SarifToolWindowControl();
            this.Control.Loaded   += this.Control_Loaded;
            this.Control.Unloaded += this.Control_Unloaded;

            var componentModel = (IComponentModel)AsyncPackage.GetGlobalService(typeof(SComponentModel));

            if (componentModel != null)
            {
                this.sarifErrorListEventSelectionService = componentModel.GetService <ISarifErrorListEventSelectionService>();
                this.textViewCaretListenerService        = componentModel.GetService <ITextViewCaretListenerService <ITextMarkerTag> >();
            }
        }
        private void ErrorListInlineLink_Click(object sender, RoutedEventArgs e)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            if (!(sender is Hyperlink hyperLink))
            {
                return;
            }

            if (hyperLink.Tag is int id)
            {
                // The user clicked an in-line link with an integer target. Look for a Location object
                // whose Id property matches that integer. The spec says that might be _any_ Location
                // object under the current result. At present, we only support Location objects that
                // occur in Result.Locations or Result.RelatedLocations. So, for example, we don't
                // look in Result.CodeFlows or Result.Stacks.
                LocationModel location =
                    this.Error.RelatedLocations.
                    Concat(this.Error.Locations).
                    FirstOrDefault(l => l.Id == id);

                if (location == null)
                {
                    return;
                }

                // If a location is found, then we will show this error in the explorer window
                // by setting the navigated item to the error related to this error entry,
                // but... we will navigate the editor to the found location, which for example
                // may be a related location.
                if (this.Error.HasDetails)
                {
                    var componentModel = (IComponentModel)Package.GetGlobalService(typeof(SComponentModel));
                    if (componentModel != null)
                    {
                        ISarifErrorListEventSelectionService sarifSelectionService = componentModel.GetService <ISarifErrorListEventSelectionService>();
                        if (sarifSelectionService != null)
                        {
                            sarifSelectionService.NavigatedItem = this.Error;
                        }
                    }
                }

                location.NavigateTo(usePreviewPane: false, moveFocusToCaretLocation: true);
            }

            // This is super dangerous! We are launching URIs for SARIF logs
            // that can point to anything.
            // https://github.com/microsoft/sarif-visualstudio-extension/issues/171
            else
            {
                string uriString = null;
                if (hyperLink.Tag is string uriAsString)
                {
                    uriString = uriAsString;
                }
                else if (hyperLink.Tag is Uri uri)
                {
                    uriString = uri.ToString();
                }

                SdkUIUtilities.OpenExternalUrl(uriString);
            }
        }