This project is read-only.
1
Vote

Roslyn Diagnostic + Visual Studio Colorisation

description

Issue

Does any know where I can location an "simple" example of colourisation of a token based on a Roslyn diagnostic. Yep I can make them Info, Warning, Error or Hidden. So let say want to use Hidden so it doesn't appear in the Errors list/window, but is accessible so I could do something with it later.

Now I've got these hidden diagnostic, now I would like to affect the colourisation of the text in the IDE.

This is what I've tried so for.
Private Sub CreateVisuals(ByVal line As ITextViewLine)
  Try
    'grab a reference to the lines in the current TextView 
    Dim textViewLines = _view?.TextViewLines
    If textViewLines Is Nothing Then Exit Sub 
    If line Is Nothing Then Exit Sub 
    Dim lineStart As Integer = line.Start
    Dim lineEnd As Integer = line.End
    Dim q = textViewLines.FirstOrDefault
    If q Is Nothing Then Exit Sub
    Dim qq = q.Snapshot.GetOpenDocumentInCurrentContextWithChanges
    If qq Is Nothing Then Exit Sub
    Dim sm = qq.GetSemanticModelAsync.Result '..GetSemanticModelAsync.Result
    '   Dim di = sm.GetSyntaxDiagnostics.ToArray
    If sm Is Nothing Then Exit Sub
    Dim diags = sm.GetDiagnostics.ToArray
I have tried GetSyntaxDiagnostic
   If diags.Any() = False Then Exit Sub
    For Each d In diags
      ' This is the ID if the Diagnostic I want to color.
      'If d.Id<>"SFD000" Then Continue For
      Dim charSpan As New SnapshotSpan(_view.TextSnapshot,
                      Span.FromBounds(d.Location.SourceSpan.Start, d.Location.SourceSpan.End))
      Dim g As Geometry = textViewLines.GetMarkerGeometry(charSpan)
      If g IsNot Nothing Then
        Dim drawing As New GeometryDrawing(_brush, _pen, g) : drawing.Freeze()
        Dim drawingImage As New DrawingImage(drawing) : drawingImage.Freeze()
        Dim image As New Image()
        image.Source = drawingImage
        'Align the image with the top of the bounds of the text geometry
        Canvas.SetLeft(image, g.Bounds.Left)
        Canvas.SetTop(image, g.Bounds.Top)
        _layer?.AddAdornment(AdornmentPositioningBehavior.TextRelative,
                             charSpan, Nothing, image, Nothing)
      End If
    Next
  Catch ex As Exception
    Debug.Print(ex.ToString)
  End Try 
End Sub
I get the diagnostic issue by the compiler, but not mine. Why?

The Example can be either C# or VB.net.

I've asked about this issue on StackOverflow.

Reply

SLaks replied with the following response.
This can only be done with IDiagnosticService (which is how Roslyn classifies error tags & unnecessary > > > code).

That interface is internal, so you're out of luck (unless you want to use a lot of Reflection).

You can file an issue on CodePlex & ask them to make IDiagnosticService public.

You can also ask them to make AbstractDiagnosticsTagProducer<TTag> public; it will do exactly what
you're looking for, letting you plug in a filter and a tag creator.
For more information, look at that class in a decompiler.

Conclusion

Since this is approach is actively be used by people implementing Diagnostic Analyzers,, under the guise that could implement colourisation later (via hidden). is seems a shame that it's not currently possible. Without resorting to doing the analysis twice (diagnostic + colourisation) or using Reflection.

Solution?

One option would be to provide additional Enumerations
Custom shown in error window
Custom_Hidden not shown in error window.

then create an overload that can accept a styling parameter, which is used instead of the currently use styling.
context.ReportDiagnostic(
   Diagnostic.Create(
        diagn_ID, category, message,
        DiagnosticSeverity.Hidden,
        DiagnosticSeverity.Hidden, True,
        0, description, helplink, loc, additional_loc, tags,
        styling
 )
)

comments