135 lines
4.2 KiB
C#
135 lines
4.2 KiB
C#
using System.Collections.Generic;
|
|
using Upsilon.BaseTypes;
|
|
using Upsilon.Parser;
|
|
using Upsilon.Text;
|
|
|
|
namespace Upsilon
|
|
{
|
|
public class Diagnostics
|
|
{
|
|
public SourceText ScriptString { get; }
|
|
public readonly List<DiagnosticsMessage> Messages = new List<DiagnosticsMessage>();
|
|
|
|
public Diagnostics(SourceText scriptString)
|
|
{
|
|
ScriptString = scriptString;
|
|
}
|
|
|
|
public void Log(DiagnosticLevel level, string message, TextSpan location)
|
|
{
|
|
Messages.Add(new DiagnosticsMessage(this, level, message, location));
|
|
}
|
|
|
|
public void LogError(string message, TextSpan location)
|
|
{
|
|
Log(DiagnosticLevel.Error, message, location);
|
|
}
|
|
|
|
public void LogBadCharacter(TextSpan location, SyntaxKind expectedToken, SyntaxKind currentKind)
|
|
{
|
|
LogError($"Invalid character found. Expected: '{expectedToken}', Got: '{currentKind}'", location);
|
|
}
|
|
|
|
public void LogBadCharacter(TextSpan location, SyntaxKind expectedToken)
|
|
{
|
|
LogError($"Invalid character found. Expected: '{expectedToken}'", location);
|
|
}
|
|
|
|
public void LogUnknownVariable(TextSpan span, string variable)
|
|
{
|
|
LogError($"Unknown variable '{variable}'", span);
|
|
}
|
|
|
|
public void LogNullReferenceError(TextSpan span)
|
|
{
|
|
LogError($"Null Reference Encountered", span);
|
|
}
|
|
|
|
public void LogUnknownType(TextSpan eSpan)
|
|
{
|
|
LogError($"Unknown Type found", eSpan);
|
|
}
|
|
|
|
public void LogUnknownBinaryOperator(TextSpan eSpan, SyntaxKind text, Type leftType, Type rightType)
|
|
{
|
|
LogError($"No binary operator {text} found for types '{leftType}' and '{rightType}'", eSpan);
|
|
}
|
|
|
|
public void LogUnknownUnaryOperator(TextSpan eSpan, SyntaxKind text, Type inType)
|
|
{
|
|
LogError($"No unary operator {text} found for type '{inType}'", eSpan);
|
|
}
|
|
|
|
public void LogCannotConvert(Type actualType, Type expectedType, TextSpan span)
|
|
{
|
|
LogError($"Cannot convert type '{actualType}' to '{expectedType}'", span);
|
|
}
|
|
}
|
|
|
|
public class DiagnosticsMessage
|
|
{
|
|
public Diagnostics Diagnostics { get; }
|
|
private readonly DiagnosticLevel _diagnosticLevel;
|
|
public string Message { get; }
|
|
public TextSpan Span { get; }
|
|
|
|
public DiagnosticsMessage(Diagnostics diagnostics, DiagnosticLevel diagnosticLevel, string message, TextSpan span)
|
|
{
|
|
_diagnosticLevel = diagnosticLevel;
|
|
Diagnostics = diagnostics;
|
|
Message = message;
|
|
Span = span;
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
var linePos = Diagnostics.ScriptString.GetLinePosition(Span.Start);
|
|
return $"{Message} at ({linePos.Line}, {linePos.Pos})\n{Diagnostics.ScriptString.GetSpan(Span)}";
|
|
}
|
|
|
|
public string GetDiagnosticPosition()
|
|
{
|
|
var linePos = Diagnostics.ScriptString.GetLinePosition(Span.Start);
|
|
return $"({linePos.Line},{linePos.Pos})";
|
|
}
|
|
|
|
public string LineBeforeError()
|
|
{
|
|
var linePos = Diagnostics.ScriptString.GetLinePosition(Span.Start);
|
|
var lineIndex = Diagnostics.ScriptString.GetLineStartPos(linePos.Line);
|
|
return Diagnostics.ScriptString.GetSpan(lineIndex, linePos.Pos);
|
|
}
|
|
|
|
public string BeforeError(int i = 5)
|
|
{
|
|
return Diagnostics.ScriptString.GetSpan(Span.Start - i, i);
|
|
}
|
|
|
|
public string AtError()
|
|
{
|
|
return Diagnostics.ScriptString.GetSpan(Span);
|
|
}
|
|
|
|
public string LineAfterError()
|
|
{
|
|
var linePos = Diagnostics.ScriptString.GetLinePosition(Span.Start);
|
|
var lineInfo = Diagnostics.ScriptString.GetLineInfo(linePos.Line);
|
|
|
|
return Diagnostics.ScriptString.GetSpan(Span.End, lineInfo.End - Span.End);
|
|
}
|
|
|
|
public string AfterError(int i = 5)
|
|
{
|
|
return Diagnostics.ScriptString.GetSpan(Span.Start + Span.Length, i);
|
|
}
|
|
|
|
}
|
|
|
|
public enum DiagnosticLevel
|
|
{
|
|
Information,
|
|
Warning,
|
|
Error,
|
|
}
|
|
|
|
} |