Skip to content

Commit

Permalink
Make ParseError/ParseErrorException abstract and introduce RegExpConv…
Browse files Browse the repository at this point in the history
…ersionError/RegExpConversionErrorException
  • Loading branch information
adams85 committed Mar 24, 2024
1 parent 66e548c commit 1012ae5
Show file tree
Hide file tree
Showing 19 changed files with 84 additions and 61 deletions.
2 changes: 1 addition & 1 deletion src/Acornima.Extras/JavaScriptTextFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public abstract class JavaScriptTextFormatter : JavaScriptTextWriter
private readonly string _indent;
private int _indentionLevel;

public JavaScriptTextFormatter(TextWriter writer, JavaScriptTextFormatterOptions options) : base(writer, options)
protected JavaScriptTextFormatter(TextWriter writer, JavaScriptTextFormatterOptions options) : base(writer, options)
{
if (!string.IsNullOrWhiteSpace(options.Indent))
{
Expand Down
1 change: 0 additions & 1 deletion src/Acornima.Extras/JavaScriptTextWriter.WriteContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ public bool NodePropertyHasListValue
get => _nodePropertyListValueHelper is not null;
}


[MethodImpl(MethodImplOptions.AggressiveInlining)]
private Delegate EnsureNodePropertyAccessor()
{
Expand Down
12 changes: 6 additions & 6 deletions src/Acornima/Acornima.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All"/>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
<PackageReference Include="PolySharp" Version="1.14.1" PrivateAssets="all" />
</ItemGroup>

Expand All @@ -29,14 +29,14 @@
</ItemGroup>

<ItemGroup>
<None Include="../../README.md" Pack="true" PackagePath=""/>
<None Include="../../README.md" Pack="true" PackagePath="" />
</ItemGroup>

<ItemGroup>
<Compile Update="Properties\ParseErrorMessages.Designer.cs">
<DependentUpon>ParseErrorMessages.resx</DependentUpon>
<Compile Update="Properties\RegExpConversionErrorMessages.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>RegExpConversionErrorMessages.resx</DependentUpon>
</Compile>
<Compile Update="Properties\SyntaxErrorMessages.Designer.cs">
<DesignTime>True</DesignTime>
Expand All @@ -46,8 +46,8 @@
</ItemGroup>

<ItemGroup>
<EmbeddedResource Update="Properties\ParseErrorMessages.resx">
<LastGenOutput>ParseErrorMessages.Designer.cs</LastGenOutput>
<EmbeddedResource Update="Properties\RegExpConversionErrorMessages.resx">
<LastGenOutput>RegExpConversionErrorMessages.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Properties\SyntaxErrorMessages.resx">
Expand Down
9 changes: 2 additions & 7 deletions src/Acornima/ParseError.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@

namespace Acornima;

public class ParseError
public abstract class ParseError
{
internal delegate ParseError Factory(string description, int index, Position position, string? sourceFile);

internal static readonly Factory s_factory = (description, index, position, sourceFile) => new ParseError(description, index, position, sourceFile);

public string Description { get; }

public bool IsIndexDefined => Index >= 0;
Expand Down Expand Up @@ -48,8 +46,5 @@ public override string ToString()
: (IsPositionDefined ? $"{Description} ({SourceFile}:{LineNumber}:{Column + 1})" : $"{Description} ({SourceFile})");
}

public virtual ParseErrorException ToException()
{
return new ParseErrorException(this);
}
public abstract ParseErrorException ToException();
}
6 changes: 3 additions & 3 deletions src/Acornima/ParseErrorException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

namespace Acornima;

public class ParseErrorException : Exception
public abstract class ParseErrorException : Exception
{
public ParseErrorException(ParseError error, Exception? innerException = null)
: base((error ?? throw new ArgumentNullException(nameof(error))).ToString(), innerException)
protected ParseErrorException(ParseError error, Exception? innerException = null)
: base((error ?? throw new ArgumentNullException(nameof(error))).ToString(), innerException)
{
Error = error;
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions src/Acornima/RegExpConversionError.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Acornima;

public sealed class RegExpConversionError : ParseError
{
internal static readonly Factory s_factory = (description, index, position, sourceFile) => new RegExpConversionError(description, index, position, sourceFile);

public RegExpConversionError(string description, int index = -1, Position position = default, string? source = null)
: base(description, index, position, source) { }

public override ParseErrorException ToException()
{
return new RegExpConversionErrorException(this);
}
}
11 changes: 11 additions & 0 deletions src/Acornima/RegExpConversionErrorException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;

namespace Acornima;

public sealed class RegExpConversionErrorException : ParseErrorException
{
public RegExpConversionErrorException(RegExpConversionError error, Exception? innerException = null)
: base(error, innerException) { }

public new RegExpConversionError Error => (RegExpConversionError)base.Error;
}
20 changes: 12 additions & 8 deletions src/Acornima/RegExpParseMode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,29 @@ public enum RegExpParseMode
/// </summary>
Skip,
/// <summary>
/// Scan regular expressions and check that they are syntactically correct (throw <see cref="ParseErrorException"/> if an invalid regular expression is encountered)
/// but don't attempt to convert them to an equivalent <see cref="Regex"/>.
/// Scan regular expressions and check that they are syntactically correct but don't attempt to convert them to an equivalent <see cref="Regex"/>.
/// </summary>
/// <remarks>
/// In case an invalid regular expression is encountered, <see cref="SyntaxErrorException"/> is thrown.
/// </remarks>
Validate,
/// <summary>
/// Scan regular expressions, check that they are syntactically correct (throw <see cref="ParseErrorException"/> if an invalid regular expression is encountered)
/// and attempt to convert them to an equivalent <see cref="Regex"/> without the <see cref="RegexOptions.Compiled"/> option.
/// Scan regular expressions, check that they are syntactically correct and attempt to convert them to an equivalent <see cref="Regex"/>
/// without the <see cref="RegexOptions.Compiled"/> option.
/// </summary>
/// <remarks>
/// In the case of a valid regular expression for which an equivalent <see cref="Regex"/> cannot be constructed, either <see cref="ParseErrorException"/> is thrown
/// In case an invalid regular expression is encountered, <see cref="SyntaxErrorException"/> is thrown.<br/>
/// In the case of a valid regular expression for which an equivalent <see cref="Regex"/> cannot be constructed, either <see cref="RegExpConversionErrorException"/> is thrown
/// or a <see cref="Token"/> is created with the <see cref="Token.Value"/> property set to <see langword="null"/>, depending on the <see cref="TokenizerOptions.Tolerant"/> option.
/// </remarks>
AdaptToInterpreted,
/// <summary>
/// Scan regular expressions, check that they are syntactically correct (throw <see cref="ParseErrorException"/> if an invalid regular expression is encountered)
/// and attempt to convert them to an equivalent <see cref="Regex"/> with the <see cref="RegexOptions.Compiled"/> option.
/// Scan regular expressions, check that they are syntactically correct and attempt to convert them to an equivalent <see cref="Regex"/>
/// with the <see cref="RegexOptions.Compiled"/> option.
/// </summary>
/// <remarks>
/// In the case of a valid regular expression for which an equivalent <see cref="Regex"/> cannot be constructed, either <see cref="ParseErrorException"/> is thrown
/// In case an invalid regular expression is encountered, <see cref="SyntaxErrorException"/> is thrown.<br/>
/// In the case of a valid regular expression for which an equivalent <see cref="Regex"/> cannot be constructed, either <see cref="RegExpConversionErrorException"/> is thrown
/// or a <see cref="Token"/> is created with the <see cref="Token.Value"/> property set to <see langword="null"/>, depending on the <see cref="TokenizerOptions.Tolerant"/> option.
/// </remarks>
AdaptToCompiled,
Expand Down
10 changes: 5 additions & 5 deletions src/Acornima/RegExpParseResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ internal RegExpParseResult(Regex regex, ArrayList<Tokenizer.RegExpCapturingGroup
_capturingGroups = capturingGroups;
}

internal RegExpParseResult(ParseError? conversionError)
internal RegExpParseResult(RegExpConversionError? conversionError)
{
// NOTE: We can't use null to represent success for validation-only parsing (RegExpParseMode.Validation)
// NOTE: We can't use null to represent success for validation-only parsing (RegExpParseMode.Validate)
// because in that case default(RegExpParseResult) would indicate success.
// However, we can do that by using an instance of whatever type except for Regex and ParseError.
// However, we can do that by using an instance of whatever type except for Regex and RegExpConversionError.
_regexOrConversionError = conversionError ?? (object)nameof(Success);
}

public bool Success => _regexOrConversionError is not (null or ParseError);
public bool Success => _regexOrConversionError is not (null or RegExpConversionError);

public ParseError? ConversionError => _regexOrConversionError as ParseError;
public RegExpConversionError? ConversionError => _regexOrConversionError as RegExpConversionError;

public Regex? Regex => _regexOrConversionError as Regex;

Expand Down
2 changes: 1 addition & 1 deletion src/Acornima/Tokenizer.RegExpParser.Legacy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ public void HandleInvalidRangeQuantifier(ref ParsePatternContext context, ref Re
context.FollowingQuantifierError = null;
}

public bool AdjustEscapeSequence(ref ParsePatternContext context, ref RegExpParser parser, out ParseError? conversionError)
public bool AdjustEscapeSequence(ref ParsePatternContext context, ref RegExpParser parser, out RegExpConversionError? conversionError)
{
// https://tc39.es/ecma262/#prod-AtomEscape

Expand Down
4 changes: 2 additions & 2 deletions src/Acornima/Tokenizer.RegExpParser.Unicode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -617,7 +617,7 @@ public void HandleInvalidRangeQuantifier(ref ParsePatternContext context, ref Re
parser.ReportSyntaxError(startIndex, SyntaxErrorMessages.RegExpIncompleteQuantifier);
}

public bool AdjustEscapeSequence(ref ParsePatternContext context, ref RegExpParser parser, out ParseError? conversionError)
public bool AdjustEscapeSequence(ref ParsePatternContext context, ref RegExpParser parser, out RegExpConversionError? conversionError)
{
// https://tc39.es/ecma262/#prod-AtomEscape

Expand Down Expand Up @@ -880,7 +880,7 @@ public bool AdjustEscapeSequence(ref ParsePatternContext context, ref RegExpPars

if (codePointRanges is null)
{
conversionError = parser.ReportConversionFailure(startIndex, ParseErrorMessages.RegExpInconvertibleUnicodePropertyEscape);
conversionError = parser.ReportConversionFailure(startIndex, RegExpConversionErrorMessages.RegExpInconvertibleUnicodePropertyEscape);
return false;
}

Expand Down
Loading

0 comments on commit 1012ae5

Please sign in to comment.