Skip to content

Commit

Permalink
Refactor FluentError classes and improve comments
Browse files Browse the repository at this point in the history
  • Loading branch information
Ygg01 committed Jun 4, 2024
1 parent c6aa001 commit 1a9b550
Showing 1 changed file with 64 additions and 35 deletions.
99 changes: 64 additions & 35 deletions Linguini.Bundle/Errors/FluentError.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@
using Linguini.Syntax.Ast;
using Linguini.Syntax.Parser.Error;

// ReSharper disable UnusedMember.Global
// ReSharper disable MemberCanBePrivate.Global

namespace Linguini.Bundle.Errors
{
/// <summary>
/// Base record for Linguini Fluent errors.
/// Provides base record for Linguini's Fluent related errors.
/// </summary>
public abstract record FluentError
{
Expand All @@ -24,10 +27,12 @@ public abstract record FluentError
return null;
}



/// <summary>
/// String represntation of the error.
/// String representation of the error.
/// </summary>
/// <returns></returns>
/// <returns>Error represented as string</returns>
public override string ToString() => $"Error (${ErrorKind()})";
}

Expand All @@ -48,18 +53,25 @@ public record ErrorSpan(int Row, int StartSpan, int EndSpan, int StartMark, int
/// </summary>
public record OverrideFluentError : FluentError
{
private readonly string _id;
private readonly EntryKind _kind;
private readonly string? _location;

/// <summary>
/// Id of term or message that was overriden.
/// </summary>
public string Id => _id;
public string Id { get; }

public OverrideFluentError(string id, EntryKind kind)
/// <summary>
/// Constructs an <see cref="OverrideFluentError"/>
/// </summary>
/// <param name="id">Duplicated identifier</param>
/// <param name="kind">Enumeration showing what kind of identifier was duplicate <c>MESSAGE | TERM | FUNCTION</c></param>
/// <param name="location">Location where the error originated. Due to backwards compatibility it defaults to null</param>
public OverrideFluentError(string id, EntryKind kind, string? location = null)
{
_id = id;
Id = id;
_kind = kind;
_location = location;
}

/// <inheritdoc/>
Expand All @@ -68,107 +80,121 @@ public override ErrorType ErrorKind()
return ErrorType.Overriding;
}


/// <inheritdoc/>
public override string ToString()
{
return $"For id:{_id} already exist entry of type: {_kind.ToString()}";
return $"For id:{Id} already exist entry of type: {_kind.ToString()}";
}
}

/// <summary>
///
/// </summary>
public record ResolverFluentError : FluentError
{
private readonly string _description;
private readonly ErrorType _kind;
private readonly string? _location;

private ResolverFluentError(string desc, ErrorType kind)
private ResolverFluentError(string desc, ErrorType kind, string? location)
{
_description = desc;
_kind = kind;
_location = location;
}

/// <inheritdoc/>
public override ErrorType ErrorKind()
{
return _kind;
}


/// <inheritdoc/>
public override string ToString()
{
return _description;
}

public static ResolverFluentError NoValue(ReadOnlyMemory<char> idName)
public static ResolverFluentError NoValue(ReadOnlyMemory<char> idName, string? location = null)
{
return new($"No value: {idName.Span.ToString()}", ErrorType.NoValue);
return new($"No value: {idName.Span.ToString()}", ErrorType.NoValue, location);
}

public static ResolverFluentError NoValue(string pattern)
public static ResolverFluentError NoValue(string pattern, string? location = null)
{
return new($"No value: {pattern}", ErrorType.NoValue);
return new($"No value: {pattern}", ErrorType.NoValue, location);
}

public static ResolverFluentError UnknownVariable(VariableReference outType)
public static ResolverFluentError UnknownVariable(VariableReference outType, string? location = null)
{
return new($"Unknown variable: ${outType.Id}", ErrorType.Reference);
return new($"Unknown variable: ${outType.Id}", ErrorType.Reference, location);
}

public static ResolverFluentError TooManyPlaceables()
public static ResolverFluentError TooManyPlaceables(string? location = null)
{
return new("Too many placeables", ErrorType.TooManyPlaceables);
return new("Too many placeables", ErrorType.TooManyPlaceables, location);
}

public static ResolverFluentError Reference(IInlineExpression self)
public static ResolverFluentError Reference(IInlineExpression self, string? location = null)
{
return self switch
{
FunctionReference funcRef => new($"Unknown function: {funcRef.Id}()", ErrorType.Reference),
FunctionReference funcRef => new($"Unknown function: {funcRef.Id}()", ErrorType.Reference, location),
MessageReference msgRef when msgRef.Attribute == null => new($"Unknown message: {msgRef.Id}",
ErrorType.Reference),
ErrorType.Reference, location),
MessageReference msgRef => new($"Unknown attribute: {msgRef.Id}.{msgRef.Attribute}",
ErrorType.Reference),
ErrorType.Reference, location),
TermReference termReference when termReference.Attribute == null => new(
$"Unknown term: -{termReference.Id}", ErrorType.Reference),
$"Unknown term: -{termReference.Id}", ErrorType.Reference, location),
TermReference termReference => new($"Unknown attribute: -{termReference.Id}.{termReference.Attribute}",
ErrorType.Reference),
VariableReference varRef => new($"Unknown variable: ${varRef.Id}", ErrorType.Reference),
ErrorType.Reference, location),
VariableReference varRef => new($"Unknown variable: ${varRef.Id}", ErrorType.Reference, location),
_ => throw new ArgumentException($"Expected reference got ${self.GetType()}")
};
}

public static ResolverFluentError Cyclic(Pattern pattern)
public static ResolverFluentError Cyclic(Pattern pattern, string? location = null)
{
return new($"Cyclic reference in {pattern.Stringify()} detected!", ErrorType.Cyclic);
return new($"Cyclic reference in {pattern.Stringify()} detected!", ErrorType.Cyclic, location);
}

public static ResolverFluentError MissingDefault()
public static ResolverFluentError MissingDefault(string? location = null)
{
return new("No default", ErrorType.MissingDefault);
return new("No default", ErrorType.MissingDefault, location);
}
}

public record ParserFluentError : FluentError
{
private readonly ParseError _error;
private readonly string? _location;

private ParserFluentError(ParseError error)
private ParserFluentError(ParseError error, string? location = null)
{
_error = error;
_location = location;
}

public static ParserFluentError ParseError(ParseError parseError)
{
return new(parseError);
}

/// <inheritdoc/>
public override ErrorType ErrorKind()
{
return ErrorType.Parser;
}

/// <inheritdoc/>
public override string ToString()
{
return _error.Message;
}

/// <inheritdoc/>
public override ErrorSpan? GetSpan()
{
if (_error.Slice == null)
Expand All @@ -179,6 +205,9 @@ public override string ToString()
}
}

/// <summary>
/// Enumeration showing which kind of Entry was duplicated.
/// </summary>
public enum EntryKind : byte
{
Message,
Expand All @@ -190,12 +219,12 @@ public static class EntryHelper
{
public static EntryKind ToKind(this IEntry self)
{
if (self is AstTerm)
return self switch
{
return EntryKind.Term;
}

return self is AstMessage ? EntryKind.Message : EntryKind.Func;
AstTerm => EntryKind.Term,
AstMessage => EntryKind.Message,
_ => EntryKind.Func
};
}
}

Expand All @@ -209,4 +238,4 @@ public enum ErrorType : byte
Overriding,
MissingDefault
}
}
}

0 comments on commit 1a9b550

Please sign in to comment.