private void ParseSnapshot(ISnapshotTextContentProvider snapshotContent) { // queue analysis of the parsed tree at High Pri so the active buffer is quickly re-analyzed var snapshot = snapshotContent.Snapshot; if (snapshot.TextBuffer.ContentType.IsOfType(PythonCoreConstants.ContentType)) { PythonAst ast; CollectingErrorSink errorSink; ParsePythonCode((TextContentProvider)snapshotContent, out ast, out errorSink); if (ast != null) { IPythonProjectEntry analysis; if (snapshot.TextBuffer.TryGetPythonAnalysis(out analysis)) { // only update the AST when we're error free, this way we don't remove // a useful analysis with an incomplete and useless analysis. if (errorSink.Errors.Count == 0) { analysis.UpdateTree(ast, new SnapshotCookie(snapshot)); _analysisQueue.Enqueue(analysis, AnalysisPriority.High); } SimpleTagger <ErrorTag> squiggles = _squiggleProvider.GetErrorTagger(snapshot.TextBuffer); squiggles.RemoveTagSpans(x => true); // update squiggles for the live buffer foreach (ErrorResult warning in errorSink.Warnings) { var span = warning.Span; var tspan = CreateSpan(snapshot, span); squiggles.CreateTagSpan(tspan, new ErrorTag("Warning", warning.Message)); } foreach (ErrorResult error in errorSink.Errors) { var span = error.Span; var tspan = CreateSpan(snapshot, span); squiggles.CreateTagSpan(tspan, new ErrorTag("Error", error.Message)); } } } } else if (snapshot.TextBuffer.ContentType.IsOfType("xaml")) { string path = snapshot.TextBuffer.GetFilePath(); if (path != null) { IProjectEntry analysis; XamlProjectEntry xamlProject; if (_projectFiles.TryGetValue(path, out analysis) && (xamlProject = analysis as XamlProjectEntry) != null) { xamlProject.UpdateContent(((TextContentProvider)snapshotContent).GetReader(), new SnapshotCookie(snapshotContent.Snapshot)); _analysisQueue.Enqueue(analysis, AnalysisPriority.High); } } } }
/// <summary> /// Select current tracking text with <paramref name="highlightColor"/>. /// If highlightColor is null than code will be selected with color from <seealso cref="Color"/>. /// If the mark doesn't support tracking changes, then we simply ignore this condition (addresses VS crash /// reported in Bug 476347 : Code Analysis clicking error report C6244 causes VS2012 to crash). /// Tracking changes helps to ensure that we nativate to the right line even if edits to the file /// have occured, but even if that behavior doesn't work right, it is better to /// simply return here (before the fix this code threw an exception which terminated VS). /// </summary> /// <param name="highlightColor">Color</param> public void AddHighlightMarker(string highlightColor) { if (!IsTracking()) { return; } _marker = _tagger.CreateTagSpan(_trackingSpan, new TextMarkerTag(highlightColor ?? Color)); }
/// <summary> /// Select current tracking text with <paramref name="highlightColor"/>. /// If highlightColor is null than code will be selected with color from <seealso cref="Color"/>. /// If the mark doesn't support tracking changes, then we simply ignore this condition (addresses VS crash /// reported in Bug 476347 : Code Analysis clicking error report C6244 causes VS2012 to crash). /// Tracking changes helps to ensure that we nativate to the right line even if edits to the file /// have occured, but even if that behavior doesn't work right, it is better to /// simply return here (before the fix this code threw an exception which terminated VS). /// </summary> /// <param name="highlightColor">Color</param> public void AddSelectionMarker(string highlightColor) { if (!IsTracking()) { return; } m_marker = m_tagger.CreateTagSpan(m_trackingSpan, new TextMarkerTag(highlightColor ?? Color)); }
public void Parse(TextContentProvider /*!*/ content) { var errorSink = new CollectingErrorSink(); SourceUnitTree ast = MakeParseTree(content, errorSink); ISnapshotTextContentProvider snapshotContent = content as ISnapshotTextContentProvider; if (snapshotContent != null) { // queue analysis of the parsed tree at High Pri so the active buffer is quickly re-analyzed var snapshot = snapshotContent.Snapshot; var analysis = AnalysisItem.GetAnalysis(snapshot.TextBuffer); // only update the AST when we're error free, this way we don't remove // a useful analysis with an incomplete and useless analysis. if (errorSink.Errors.Count == 0) { analysis.UpdateTree(ast, new SnapshotCookie(snapshot)); _analysisQueue.Enqueue(analysis, AnalysisPriority.High); } SimpleTagger <ErrorTag> squiggles = _squiggleProvider.GetErrorTagger(snapshot.TextBuffer); squiggles.RemoveTagSpans(x => true); // update squiggles for the live buffer foreach (ErrorResult warning in errorSink.Warnings) { var span = warning.Span; var tspan = CreateSpan(snapshot, span); squiggles.CreateTagSpan(tspan, new ErrorTag("Warning", warning.Message)); } foreach (ErrorResult error in errorSink.Errors) { var span = error.Span; var tspan = CreateSpan(snapshot, span); squiggles.CreateTagSpan(tspan, new ErrorTag("Error", error.Message)); } } else { FileTextContentProvider fileContent = content as FileTextContentProvider; AnalysisItem analysis; if (fileContent != null && _projectFiles.TryGetValue(fileContent.Path, out analysis)) { analysis.UpdateTree(ast, new FileCookie(fileContent.Path)); _analysisQueue.Enqueue(analysis, AnalysisPriority.Normal); } } }
private void CreateErrors() { var errors = errorListProvider.GetErrors(textView.TextBuffer); // Check if we should update the error list based on the error count to avoid refreshing the list without changes if (errors.Count != this.previousErrors.Count) { // remove any previously created errors to get a clean start ClearErrors(); foreach (ValidationError error in errors) { // creates the instance that will be added to the Error List ErrorTask task = new ErrorTask(); task.Category = TaskCategory.All; task.Priority = TaskPriority.Normal; task.Document = textView.TextBuffer.Properties.GetProperty <ITextDocument>(typeof(ITextDocument)).FilePath; task.ErrorCategory = TranslateErrorCategory(error.Severity); task.Text = error.Description; task.Line = textView.TextSnapshot.GetLineNumberFromPosition(error.Span.Start); task.Column = error.Span.Start - textView.TextSnapshot.GetLineFromLineNumber(task.Line).Start; task.Navigate += OnTaskNavigate; errorList.Tasks.Add(task); previousErrors.Add(task); ITrackingSpan span = textView.TextSnapshot.CreateTrackingSpan(error.Span, SpanTrackingMode.EdgeNegative); squiggleTagger.CreateTagSpan(span, new ErrorTag("syntax error", error.Description)); previousSquiggles.Add(new TrackingTagSpan <IErrorTag>(span, new ErrorTag("syntax error", error.Description))); } } }
public void CreateSquiggleSpan(SimpleTagger <ErrorTag> tagger) { if (_rawSpan.Start >= _rawSpan.End || _spanTranslator == null) { return; } // TODO: Map between versions rather than using the current snapshot var snapshot = _spanTranslator.TextBuffer.CurrentSnapshot; var target = _rawSpan.ToSnapshotSpan(snapshot); //SnapshotSpan target = _spanTranslator.TranslateForward( // new Span(_rawSpan.Start.Index, _rawSpan.Length) //); if (target.Length <= 0) { return; } var tagSpan = snapshot.CreateTrackingSpan( target.Start, target.Length, SpanTrackingMode.EdgeInclusive ); tagger.CreateTagSpan(tagSpan, new ErrorTag(ErrorType, _message)); }
private void CreateErrors() { StaDynErrorList.Instance.refreshErrorList(); var errors = StaDynErrorList.Instance.GetErrors(); // remove any previously created errors to get a clean start ClearErrors(); foreach (ValidationError error in errors) { string currentPath = FileUtilities.Instance.getFilePath(textView); if (currentPath == error.File) { try { //ITrackingSpan span = textView.TextSnapshot.CreateTrackingSpan(error.Span, SpanTrackingMode.EdgeNegative); bool writeSquiggle = true; int startIndex = textView.TextBuffer.CurrentSnapshot.GetLineFromLineNumber(error.Line).Start.Position + error.Column; int endIndex = textView.TextBuffer.CurrentSnapshot.GetLineFromLineNumber(error.Line).Start.Position + error.Column + 4; SnapshotPoint point = new SnapshotPoint(textView.TextSnapshot, startIndex + 1); Span span = new Span(startIndex, endIndex - startIndex); ITrackingSpan trackingSpan = textView.TextSnapshot.CreateTrackingSpan(span, SpanTrackingMode.EdgeNegative); SnapshotSpan snapSpan = new SnapshotSpan(textView.TextSnapshot, span); var currentSquiggles = squiggleTagger.GetTaggedSpans(snapSpan); if (currentSquiggles.Count() == 0) { writeSquiggle = true; } else { foreach (var item in currentSquiggles) { if ((string)item.Tag.ToolTipContent == error.Description) { writeSquiggle = false; break; } } } if (writeSquiggle) { squiggleTagger.CreateTagSpan(trackingSpan, new ErrorTag("syntax error", error.Description)); previousSquiggles.Add(new TrackingTagSpan <IErrorTag>(trackingSpan, new ErrorTag("syntax error", error.Description))); } } catch { } } } }
private static void AddErrors(ITextSnapshot snapshot, CollectingErrorSink errorSink, SimpleTagger <ErrorTag> squiggles, TaskProvider provider) { foreach (ErrorResult error in errorSink.Errors) { var span = error.Span; var tspan = CreateSpan(snapshot, span); squiggles.CreateTagSpan(tspan, new ErrorTag(PredefinedErrorTypeNames.SyntaxError, error.Message)); if (provider != null) { provider.AddError(error); } } }
private static void AddWarnings(ITextSnapshot snapshot, CollectingErrorSink errorSink, SimpleTagger <ErrorTag> squiggles, TaskProvider provider) { foreach (ErrorResult warning in errorSink.Warnings) { var span = warning.Span; var tspan = CreateSpan(snapshot, span); squiggles.CreateTagSpan(tspan, new ErrorTag(PredefinedErrorTypeNames.Warning, warning.Message)); if (provider != null) { provider.AddWarning(warning); } } }
public void CreateSquiggleSpan(SimpleTagger <ErrorTag> tagger) { SnapshotSpan target = _spanTranslator.TranslateForward( new Span(_rawSpan.Start.Index, _rawSpan.Length) ); var tagSpan = _spanTranslator.TextBuffer.CurrentSnapshot.CreateTrackingSpan( target.Start, target.Length, SpanTrackingMode.EdgeInclusive ); tagger.CreateTagSpan(tagSpan, new ErrorTag(ErrorType, _message)); }
public void ReportParseErrors(IParseResult parseResult, ITextSnapshot snapshot) { _errorListProvider.SuspendRefresh(); try { // remove any previously created errors to get a clean start ClearErrors(); var messages = (CompilerMessageList)parseResult.CompilerMessages; foreach (var error in messages.GetMessages()) { // creates the instance that will be added to the Error List var nSpan = error.Location.Span; var span = new Span(nSpan.StartPos, nSpan.Length); if (span.Start >= snapshot.Length) { continue; } ErrorTask task = new ErrorTask(); task.Category = TaskCategory.All; task.Priority = TaskPriority.Normal; task.Document = _textBuffer.Properties.GetProperty <ITextDocument>(typeof(ITextDocument)).FilePath; task.ErrorCategory = TranslateErrorCategory(error); task.Text = error.Text; task.Line = snapshot.GetLineNumberFromPosition(span.Start); task.Column = span.Start - snapshot.GetLineFromLineNumber(task.Line).Start; task.Navigate += OnTaskNavigate; _errorListProvider.Tasks.Add(task); _previousErrors.Add(task); var trackingSpan = snapshot.CreateTrackingSpan(span, SpanTrackingMode.EdgeNegative); _squiggleTagger.CreateTagSpan(trackingSpan, new ErrorTag("syntax error", error.Text)); _previousSquiggles.Add(new TrackingTagSpan <IErrorTag>(trackingSpan, new ErrorTag("syntax error", error.Text))); } } finally { _errorListProvider.ResumeRefresh(); } }
public void CreateSquiggleSpan(SimpleTagger <ErrorTag> tagger) { if (_rawSpan.Start >= _rawSpan.End || _spanTranslator == null) { return; } var snapshot = _spanTranslator.TextBuffer.CurrentSnapshot; var target = _spanTranslator.Translate(_rawSpan, _fromVersion, snapshot); if (target.Length <= 0) { return; } var tagSpan = snapshot.CreateTrackingSpan( target.Start, target.Length, SpanTrackingMode.EdgeInclusive ); tagger.CreateTagSpan(tagSpan, new ErrorTagWithMoniker(ErrorType, _message, _moniker)); }
public void CreateSquiggleSpan(SimpleTagger <ErrorTag> tagger) { tagger.CreateTagSpan(_span, new ErrorTag(ErrorType, _message)); }
/////////////////////////////////////////////////////////////////////////////////// // // Validate the mardown directive syntax according to the ruleset definitions // // Copyright (c) 2014 Microsoft Corporation. // Author: Junyi Yi ([email protected]) - Initial version // /////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Validate the whole document according to the specified ruleset. /// </summary> /// <param name="snapshot">The whole document snapshot.</param> /// <param name="errorTagger">The tagger used to generate error squiggles.</param> /// <param name="ruleset">The specified ruleset.</param> public static void ValidateDirectiveSyntax(ITextSnapshot snapshot, DirectiveRuleset ruleset, SimpleTagger<ErrorTag> errorTagger) { // Remove all current error squiggles errorTagger.RemoveTagSpans(errorTagSpan => true); // Get the full document text and clear all HTML tags string text = snapshot.GetText(); text = MarkdownParser.DestroyHtmlTags(text); // Three cases: // 0123456789 01234567 8 01234567 8 // [ WA ab ] [ WA ab \n [ WA ab EOT // | |-endIndex=9 | |-endIndex=8 | |-endIndex=8 // |-startIndex=0 |-startIndex=0 |-startIndex=0 // Greedily search for the pair of '[...]' (supports nested pair '[... [...] ...]') // Here 'Greedily' means if we have a string '[...[...]', it would also treat the latter '[...]' as the pair for (int startIndex = text.IndexOf('['); startIndex >= 0; startIndex = text.IndexOf('[', startIndex)) { int endIndex = MarkdownParser.FindCorrespondingEndBracket(text, startIndex + 1); // Get the directive content string ITrackingSpan overallDirective = snapshot.CreateTrackingSpan(startIndex + 1, endIndex - startIndex - 1, SpanTrackingMode.EdgeInclusive); string directive = overallDirective.GetText(snapshot); var directiveMatches = Regex.Matches(directive, string.Concat(@"^\s*(", ValidationUtilities.DirectiveNameRegularPattern, @")(.*)$")); if (directiveMatches.Count != 1 || !directiveMatches[0].Success || directiveMatches[0].Groups.Count != 3 || directiveMatches[0].Value != directive) { startIndex++; continue; } string directiveName = directiveMatches[0].Groups[1].Value; string directiveContent = directiveMatches[0].Groups[2].Value; var rule = ruleset.TryGetDirectiveRule(directiveName); if (rule != null) { // Get the preceding and following directive string of the same line ITextSnapshotLine line = snapshot.GetLineFromPosition(startIndex); string precedingText = snapshot.GetText(line.Start, startIndex - line.Start); string followingText = endIndex < line.End ? snapshot.GetText(endIndex + 1, line.End - endIndex - 1) : string.Empty; // If we found a exactly-matched rule, just validate it string message = rule.Validate(directiveContent, precedingText, followingText); if (message != null) { ITrackingSpan squiggleSpan = overallDirective; if (rule.SquiggleWholeLine) { squiggleSpan = snapshot.CreateTrackingSpan(line.Start, line.Length, SpanTrackingMode.EdgeInclusive); } errorTagger.CreateTagSpan(squiggleSpan, new ErrorTag(PredefinedErrorTypeNames.SyntaxError, message)); } // If we miss the closing bracket, give out the prompt message if (endIndex >= text.Length || text[endIndex] != ']') { errorTagger.CreateTagSpan(snapshot.CreateTrackingSpan(line.End, 0, SpanTrackingMode.EdgePositive), new ErrorTag(PredefinedErrorTypeNames.CompilerError, "Missing the closing bracket")); } } else { // Otherwise we may take a look at the suspects var suspects = ruleset.GetSuspects(directive); if (suspects.Count() > 0) { StringBuilder suspectPrompt = new StringBuilder(); suspectPrompt.AppendLine("Are you trying to enter one of the following directives?"); foreach (var suspect in suspects) { suspectPrompt.AppendLine(string.Format(" \u2022 {0} - {1}", suspect.ParentRule.DirectiveName, suspect.SuggestionMessage)); } errorTagger.CreateTagSpan(overallDirective, new ErrorTag(PredefinedErrorTypeNames.Warning, suspectPrompt.ToString().TrimEnd())); } } startIndex = endIndex; } }
public void AddAgent(TypingAgent agent) { agent.InsertionSpanUpdated += (sender, args) => tagger.CreateTagSpan(agent.InsertionSpan, agent.Tag); this.TagsChanged(this, new SnapshotSpanEventArgs(new SnapshotSpan(_buffer.CurrentSnapshot, 0, _buffer.CurrentSnapshot.Length))); }
// Re-collapse the spans public void CollapseRegions() { if (_outliningManager == null || _textView == null || _collapsedSpans == null) { return; } ITextSnapshot snapshot = _textView.TextBuffer.CurrentSnapshot; // Get a span that includes all collapsed regions int min = Int32.MinValue; int max = Int32.MinValue; foreach (Tuple <Span, IOutliningRegionTag> span in _collapsedSpans) { if (min == Int32.MinValue || span.Item1.Start < min) { min = span.Item1.Start; } if (max == Int32.MinValue || span.Item1.End > max) { max = span.Item1.End; } } // avoid running if there were no spans if (min == Int32.MinValue) { Debug.Fail("No spans"); return; } // span containing all collapsed regions SnapshotSpan entireSpan = new SnapshotSpan(snapshot, min, max - min); // regions have not yet been tagged by the language service during the undo/redo and // so we need to tag them again in order to do the collapse SimpleTagger <IOutliningRegionTag> simpleTagger = _textView.TextBuffer.Properties.GetOrCreateSingletonProperty <SimpleTagger <IOutliningRegionTag> >(() => new SimpleTagger <IOutliningRegionTag>(_textView.TextBuffer)); Debug.Assert(!simpleTagger.GetTaggedSpans(entireSpan).GetEnumerator().MoveNext(), "The code is not expecting the regions to be tagged already. Verify that redundant tagging is not occurring."); List <Span> toCollapse = new List <Span>(); // tag the regions and add them to the list to be bulk collapsed foreach (Tuple <Span, IOutliningRegionTag> span in _collapsedSpans) { ITrackingSpan tspan = snapshot.CreateTrackingSpan(span.Item1, SpanTrackingMode.EdgeExclusive); simpleTagger.CreateTagSpan(tspan, span.Item2); toCollapse.Add(span.Item1); } // Disable the OutliningUndoManager to avoid it adding our collapse to the undo stack as an expand bool disableOutliningUndo = _textView.Options.IsOutliningUndoEnabled(); try { if (disableOutliningUndo) { _textView.Options.SetOptionValue(DefaultTextViewOptions.OutliningUndoOptionId, false); } // Do the collapse _outliningManager.CollapseAll(entireSpan, colSpan => (!colSpan.IsCollapsed && toCollapse.Contains(colSpan.Extent.GetSpan(snapshot)))); } finally { if (disableOutliningUndo) { _textView.Options.SetOptionValue(DefaultTextViewOptions.OutliningUndoOptionId, true); } } }
public TrackingTagSpan <T> CreateTagSpan(ITrackingSpan span, T tag) { return(m_storage.CreateTagSpan(span, tag)); }