Skip to content

Commit

Permalink
Fixed missing wider caret for unexpectedless trivial errors (#137)
Browse files Browse the repository at this point in the history
* Persisted caret info from NoItem forward into TrivialError by using Either instead of Option

* Updated readme
  • Loading branch information
j-mie6 authored Dec 31, 2022
1 parent 0fd79fc commit 73f1e20
Show file tree
Hide file tree
Showing 4 changed files with 9 additions and 9 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ _An exception to this policy is made for any version `3.x.y`, which reaches EoL
| `3.3.0` | January 7th 2022 | EoL reached |
| `4.0.0` | November 30th 2022 | Enjoying indefinite support |

## Bug Reports [![Percentage of issues still open](https://isitmaintained.com/badge/open/j-mie6/Parsley.svg)](https://isitmaintained.com/project/j-mie6/Parsley "Percentage of issues still open") [![Maintainability](https://img.shields.io/codeclimate/maintainability/j-mie6/Parsley)](https://codeclimate.com/github/j-mie6/Parsley) [![Test Coverage](https://img.shields.io/codeclimate/coverage-letter/j-mie6/Parsley)](https://codeclimate.com/github/j-mie6/Parsley)
## Bug Reports [![Percentage of issues still open](https://isitmaintained.com/badge/open/j-mie6/Parsley.svg)](https://isitmaintained.com/project/j-mie6/Parsley "Percentage of issues still open") [![Maintainability](https://img.shields.io/codeclimate/maintainability/j-mie6/parsley)](https://codeclimate.com/github/j-mie6/Parsley) [![Test Coverage](https://img.shields.io/codeclimate/coverage-letter/j-mie6/parsley)](https://codeclimate.com/github/j-mie6/Parsley)

If you encounter a bug when using Parsley, try and minimise the example of the parser (and the input) that triggers the bug.
If possible, make a self contained example: this will help to identify the issue without too much issue.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ private [internal] sealed trait ParseError {
}
// The reasons here are lightweight, two errors can merge their messages, but messages do not get converted to hints
private [internal] case class TrivialError(offset: Int, line: Int, col: Int,
unexpected: Option[UnexpectItem], expecteds: Set[ExpectItem], reasons: Set[String], lexicalError: Boolean)
unexpected: Either[Int, UnexpectItem], expecteds: Set[ExpectItem], reasons: Set[String], lexicalError: Boolean)
extends ParseError {
def format(line: String, beforeLines: List[String], afterLines: List[String], caret: Int)(implicit builder: ErrorBuilder[_]): builder.ErrorInfoLines = {
val unexpectedTok = unexpected.map(_.formatUnexpect(lexicalError))
// FIXME: This should probably use the number of codepoints and not length
val caretSize = unexpectedTok.fold(1)(_._2.toCaretLength(this.col, line.length, afterLines.map(_.length)))
val caretSize = unexpectedTok.fold(identity[Int], _._2.toCaretLength(this.col, line.length, afterLines.map(_.length)))
builder.vanillaError(
builder.unexpected(unexpectedTok.map(_._1)),
builder.unexpected(unexpectedTok.toOption.map(_._1)),
builder.expected(builder.combineExpectedItems(expecteds.map(_.formatExpect))),
builder.combineMessages(reasons.map(builder.reason(_)).toSeq),
builder.lineInfo(line, beforeLines, afterLines, caret, caretSize))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,28 +110,28 @@ private [errors] object TrivialErrorBuilder {
protected [TrivialErrorBuilder] def pickRaw(other: Raw): BuilderUnexpectItem
protected [TrivialErrorBuilder] def pickOther(other: Other): Other
protected [TrivialErrorBuilder] def pickNoItem(other: NoItem): BuilderUnexpectItem
def toErrorItem(offset: Int)(implicit builder: ErrorItemBuilder): Option[UnexpectItem]
def toErrorItem(offset: Int)(implicit builder: ErrorItemBuilder): Either[Int, UnexpectItem]
}
private [TrivialErrorBuilder] final class Raw(val size: Int) extends BuilderUnexpectItem {
final def pickHigher(other: BuilderUnexpectItem): BuilderUnexpectItem = other.pickRaw(this)
final override def pickRaw(other: Raw): Raw = if (this.size > other.size) this else other
final override def pickOther(other: Other): Other = other
final override def pickNoItem(other: NoItem): Raw = this
def toErrorItem(offset: Int)(implicit builder: ErrorItemBuilder): Option[UnexpectItem] = Some(builder(offset, size))
def toErrorItem(offset: Int)(implicit builder: ErrorItemBuilder): Either[Int, UnexpectItem] = Right(builder(offset, size))
}
private [TrivialErrorBuilder] final class Other(val underlying: UnexpectItem) extends BuilderUnexpectItem {
final def pickHigher(other: BuilderUnexpectItem): BuilderUnexpectItem = other.pickOther(this)
final override def pickRaw(other: Raw): Other = this
final override def pickOther(other: Other): Other = if (this.underlying.higherPriority(other.underlying)) this else other
final override def pickNoItem(other: NoItem): Other = this
def toErrorItem(offset: Int)(implicit builder: ErrorItemBuilder): Option[UnexpectItem] = Some(underlying)
def toErrorItem(offset: Int)(implicit builder: ErrorItemBuilder): Either[Int, UnexpectItem] = Right(underlying)
}
private [TrivialErrorBuilder] class NoItem(val width: Int) extends BuilderUnexpectItem {
final def pickHigher(other: BuilderUnexpectItem): BuilderUnexpectItem = other.pickNoItem(this)
final override def pickRaw(other: Raw): Raw = other
final override def pickOther(other: Other): Other = other
final override def pickNoItem(other: NoItem): NoItem = if (this.width > other.width) this else other
def toErrorItem(offset: Int)(implicit builder: ErrorItemBuilder): Option[UnexpectItem] = None
def toErrorItem(offset: Int)(implicit builder: ErrorItemBuilder): Either[Int, UnexpectItem] = Left(width)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ private [instructions] object LogErrEnd {
case FancyError(offset, line, col, msgs, _, _) => s"generated specialised error (offset $offset, line $line, col $col) {" +: msgs :+ "}"
case TrivialError(offset, line, col, unexpected, expecteds, reasons, lexicalError) =>
Seq(s"generated vanilla error (offset $offset, line $line, col $col) {",
s" unexpected item = ${unexpected.fold("missing")(_.formatUnexpect(lexicalError)._1.toString)}",
s" unexpected item = ${unexpected.fold(_ => "missing", _.formatUnexpect(lexicalError)._1.toString)}",
s" expected item(s) = ${expecteds.map(_.formatExpect)}",
s" reasons =${if (reasons.isEmpty) " no reasons given" else ""}") ++
reasons.map(" " + _) :+
Expand Down

0 comments on commit 73f1e20

Please sign in to comment.