91 lines
3.2 KiB
C#
91 lines
3.2 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 async Task RealLint(TextDocument document, int maxNumberOfProblems, SessionDocument session,
|
|
string content, List<Diagnostic> diag)
|
|
{
|
|
try
|
|
{
|
|
using (var script = new Script(content))
|
|
{
|
|
session.SourceText = script.ScriptString;
|
|
if (script.Diagnostics.Messages.Count > 0)
|
|
{
|
|
foreach (var error in script.Diagnostics.Messages)
|
|
{
|
|
diag.Add(ConvertToVsCodeDiagnostic(error));
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
var bound = script.Bind();
|
|
foreach (var error in script.Diagnostics.Messages)
|
|
{
|
|
diag.Add(ConvertToVsCodeDiagnostic(error));
|
|
}
|
|
|
|
if (script.Diagnostics.Messages.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 error)
|
|
{
|
|
var (startPosition, startPositionOnLine) = error.GetStartLine();
|
|
var (endPosition, endPositionOnLine) = error.GetEndLine();
|
|
var sourceString = error.Diagnostics.ScriptString;
|
|
if (endPosition >= sourceString.GetLineCount())
|
|
endPosition = sourceString.GetLineCount();
|
|
|
|
var range = new Range(startPosition, startPositionOnLine, endPosition,
|
|
endPositionOnLine);
|
|
return new Diagnostic(DiagnosticSeverity.Error, range, error.AtError(), "ERR001", error.Message);
|
|
}
|
|
}
|
|
}
|