@@ -23,12 +23,41 @@ open Microsoft.VisualStudio.FSharp.LanguageService
2323[<DiagnosticAnalyzer( FSharpCommonConstants.FSharpLanguageName) >]
2424type internal FSharpDocumentDiagnosticAnalyzer () =
2525 inherit DocumentDiagnosticAnalyzer()
26-
26+
27+ let fSharpErrorToRoslynDiagnostic ( document : Document , sourceText : SourceText , error : FSharpErrorInfo ) =
28+ let id = " FS" + error.ErrorNumber.ToString()
29+ let emptyString = LocalizableString.op_ Implicit( " " )
30+ let description = LocalizableString.op_ Implicit( error.Message)
31+ let severity = if error.Severity = FSharpErrorSeverity.Error then DiagnosticSeverity.Error else DiagnosticSeverity.Warning
32+ let descriptor = new DiagnosticDescriptor( id, emptyString, description, error.Subcategory, severity, true , emptyString, String.Empty, null )
33+
34+ let linePositionSpan = LinePositionSpan( LinePosition( error.StartLineAlternate - 1 , error.StartColumn), LinePosition( error.EndLineAlternate - 1 , error.EndColumn))
35+ let textSpan = sourceText.Lines.GetTextSpan( linePositionSpan)
36+ let correctedTextSpan = if textSpan.End < sourceText.Length then textSpan else TextSpan.FromBounds( sourceText.Length - 1 , sourceText.Length)
37+
38+ // F# compiler report errors at end of file if parsing fails. It should be corrected to match Roslyn boundaries
39+ Diagnostic.Create( descriptor, Location.Create( document.FilePath, correctedTextSpan , linePositionSpan))
40+
41+
2742 // We are constructing our own descriptors at run-time. Compiler service is already doing error formatting and localization.
28- override this.SupportedDiagnostics with get() = ImmutableArray< DiagnosticDescriptor>. Empty
43+ override this.SupportedDiagnostics
44+ with get() =
45+ let dummyDescriptor = DiagnosticDescriptor( " 0" , String.Empty, String.Empty, String.Empty, DiagnosticSeverity.Error, true , null , null )
46+ ImmutableArray.Create< DiagnosticDescriptor>( dummyDescriptor)
47+
48+
49+ override this.AnalyzeSyntaxAsync ( document : Document , cancellationToken : CancellationToken ): Task < ImmutableArray < Diagnostic >> =
50+ let computation = async {
51+ let! sourceText = document.GetTextAsync( cancellationToken) |> Async.AwaitTask
52+ let options = CommonRoslynHelpers.GetFSharpProjectOptionsForRoslynProject( document.Project)
53+ let! parseResults = FSharpChecker.Instance.ParseFileInProject( document.Name, sourceText.ToString(), options)
54+
55+ return ( parseResults.Errors |> Seq.map( fun ( error ) -> fSharpErrorToRoslynDiagnostic( document, sourceText, error))). ToImmutableArray()
56+ }
57+
58+ Async.StartAsTask( computation, TaskCreationOptions.None, cancellationToken)
59+ .ContinueWith( CommonRoslynHelpers.GetCompletedTaskResult, cancellationToken)
2960
30- override this.AnalyzeSyntaxAsync ( _ , _ ): Task < ImmutableArray < Diagnostic >> =
31- Task.FromResult( ImmutableArray< Diagnostic>. Empty)
3261
3362 override this.AnalyzeSemanticsAsync ( document : Document , cancellationToken : CancellationToken ): Task < ImmutableArray < Diagnostic >> =
3463 let computation = async {
@@ -41,22 +70,7 @@ type internal FSharpDocumentDiagnosticAnalyzer() =
4170 | FSharpCheckFileAnswer.Aborted -> failwith " Compilation isn't complete yet"
4271 | FSharpCheckFileAnswer.Succeeded( results) -> results.Errors
4372
44- let diagnostics = errors |> Seq.map( fun ( error ) ->
45- let id = " FS" + error.ErrorNumber.ToString()
46- let emptyString = LocalizableString.op_ Implicit( " " )
47- let description = LocalizableString.op_ Implicit( error.Message)
48- let severity = if error.Severity = FSharpErrorSeverity.Error then DiagnosticSeverity.Error else DiagnosticSeverity.Warning
49- let descriptor = new DiagnosticDescriptor( id, emptyString, description, error.Subcategory, severity, true , emptyString, String.Empty, null )
50-
51- let location = match ( error.StartLineAlternate - 1 , error.EndLineAlternate - 1 ) with
52- | (- 1 , _) -> Location.None
53- | (_, - 1 ) -> Location.None
54- | ( startl, endl) ->
55- let linePositionSpan = LinePositionSpan( LinePosition( startl, error.StartColumn), LinePosition( endl, error.EndColumn))
56- Location.Create( error.FileName, sourceText.Lines.GetTextSpan( linePositionSpan) , linePositionSpan)
57-
58- Diagnostic.Create( descriptor, location))
59- return Seq.toArray( diagnostics). ToImmutableArray()
73+ return ( errors |> Seq.map( fun ( error ) -> fSharpErrorToRoslynDiagnostic( document, sourceText, error))). ToImmutableArray()
6074 }
6175
6276 Async.StartAsTask( computation, TaskCreationOptions.None, cancellationToken)
0 commit comments