All Downloads are FREE. Search and download functionalities are using the official Maven repository.

parsley.internal.errors.ParseError.scala Maven / Gradle / Ivy

There is a newer version: 5.0.0-M6
Show newest version
/* SPDX-FileCopyrightText: © 2021 Parsley Contributors 
 * SPDX-License-Identifier: BSD-3-Clause
 */
package parsley.internal.errors

import parsley.errors.ErrorBuilder

private [internal] sealed trait ParseError {
    val offset: Int
    val col: Int
    val line: Int

    protected def format(line: String, beforeLines: List[String], afterLines: List[String], caret: Int)
                        (implicit builder: ErrorBuilder[_]): builder.ErrorInfoLines
    private [internal] final def format[Err](sourceName: Option[String])(implicit helper: LineBuilder, builder: ErrorBuilder[Err]): Err = {
        val Some((errLine, caret)) = helper.getLineWithCaret(offset)
        val beforeLines = helper.getLinesBefore(offset, builder.numLinesBefore)
        val afterLines = helper.getLinesAfter(offset, builder.numLinesAfter)
        val lines = format(errLine, beforeLines, afterLines, caret)
        builder.format(builder.pos(line, col), builder.source(sourceName), lines)
    }
}
// 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: 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(identity[Int], _._2.toCaretLength(this.col, line.length, afterLines.map(_.length)))
        builder.vanillaError(
            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))
    }
}
private [internal] case class FancyError(offset: Int, line: Int, col: Int, msgs: List[String], caretWidth: Int, lexicalError: Boolean) extends ParseError {
    def format(line: String, beforeLines: List[String], afterLines: List[String], caret: Int)(implicit builder: ErrorBuilder[_]): builder.ErrorInfoLines = {
        builder.specialisedError(
            builder.combineMessages(msgs.map(builder.message(_))),
            builder.lineInfo(line, beforeLines, afterLines, caret, math.min(caretWidth, line.length-caret)))
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy