Files
Upsilon-VsCode/UpsilonLanguageServer/UpsilonLanguageServer/DiagnosticsProvider.cs

116 lines
4.1 KiB
C#

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using LanguageServer.VsCode.Contracts;
using LanguageServer.VsCode.Server;
using Upsilon;
using Upsilon.Evaluator;
namespace UpsilonLanguageServer
{
public class DiagnosticProvider
{
public DiagnosticProvider()
{
}
public static async Task<IEnumerable<Diagnostic>> LintDocument(TextDocument document, SessionDocument session,
int maxNumberOfProblems)
{
var diag = new List<Diagnostic>();
var content = document.Content;
if (string.IsNullOrWhiteSpace(content))
{
diag.Add(new Diagnostic(DiagnosticSeverity.Hint,
new Range(new Position(0, 0), document.PositionAt(content?.Length ?? 0)),
"DLS", "DLS0001", "Empty document. Try typing something, such as \".net core\"."));
return diag;
}
var task = RealLint(document, maxNumberOfProblems, session, content, diag);
// either wait until the script is linted, or until a second has passed (timeout)
await Task.WhenAny(task, Task.Delay(1000));
return diag;
}
private static readonly ScriptOptions Options = new ScriptOptions()
{
ThrowExceptionOnError = false,
SaveDataComments = true
};
private static async Task RealLint(TextDocument document, int maxNumberOfProblems, SessionDocument session,
string content, List<Diagnostic> diag)
{
try
{
using (var script = Executor.ParseInput(content, Options))
{
session.SourceText = script.ScriptString;
if (script.Diagnostics.Errors.Count > 0)
{
foreach (var error in script.Diagnostics.Errors)
{
diag.Add(ConvertToVsCodeDiagnostic(error));
}
return;
}
var bound = script.Bind();
foreach (var error in script.Diagnostics.Errors)
{
diag.Add(ConvertToVsCodeDiagnostic(error));
}
foreach (var warning in script.Diagnostics.Warnings)
{
diag.Add(ConvertToVsCodeDiagnostic(warning));
}
if (script.Diagnostics.Errors.Count == 0)
{
session.Bound = bound;
}
}
}
catch (Exception e)
{
diag.Add(new Diagnostic(DiagnosticSeverity.Error,
new Range(new Position(0, 0), document.PositionAt(content?.Length ?? 0)),
"DLS", "DLS0001", e.ToString()));
}
}
private static Diagnostic ConvertToVsCodeDiagnostic(DiagnosticsMessage message)
{
var (startPosition, startPositionOnLine) = message.GetStartLine();
var (endPosition, endPositionOnLine) = message.GetEndLine();
var sourceString = message.Diagnostics.ScriptString;
if (endPosition >= sourceString.GetLineCount())
endPosition = sourceString.GetLineCount();
var range = new Range(startPosition, startPositionOnLine, endPosition,
endPositionOnLine);
DiagnosticSeverity severity;
switch (message.DiagnosticLevel)
{
case DiagnosticLevel.Error:
severity = DiagnosticSeverity.Error;
break;
case DiagnosticLevel.Warning:
severity = DiagnosticSeverity.Warning;
break;
default:
severity = DiagnosticSeverity.Information;
break;
}
return new Diagnostic(severity, range, message.AtError(), "ERR001", message.Message);
}
}
}