Skip to content

Commit

Permalink
renderDoc
Browse files Browse the repository at this point in the history
  • Loading branch information
mio-19 committed Jan 18, 2025
1 parent 4535fd1 commit df8f8b8
Showing 1 changed file with 56 additions and 1 deletion.
57 changes: 56 additions & 1 deletion syntax/shared/src/main/scala/chester/error/Problem.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package chester.error

import chester.utils.doc.{Doc, PrettierOptions, ToDoc}
import chester.utils.doc.*
import upickle.default.*

object Problem {
Expand Down Expand Up @@ -51,3 +51,58 @@ object ProblemUpickle {
implicit val problemRW: ReadWriter[Problem] =
readwriter[ProblemSer].bimap(ProblemSer.from, x => x)
}

extension (p: Problem) {
def renderDoc(using options: PrettierOptions, sourceReader: SourceReader): Doc = {
p.fullDescription match {
case Some(desc) => renderFullDescription(desc)(using options, sourceReader)
case None => renderToDocWithSource(p)(using options, sourceReader)
}
}
}

private def renderFullDescription(desc: FullDescription)(using options: PrettierOptions, sourceReader: SourceReader): Doc = {
val beginDoc = desc.begin.toDoc
val explanationsDoc = desc.explanations.map { elem =>
val elemDoc = elem.doc.toDoc
elem.sourcePos.flatMap(sourceReader.apply) match {
case Some(source) => elemDoc </> Doc.text(source)
case None => elemDoc
}
}
val endDoc = desc.end.toDoc

Doc.concat(
beginDoc,
Doc.line,
ssep(explanationsDoc, Doc.line),
Doc.line,
endDoc
)
}

private def renderToDocWithSource(p: Problem)(using options: PrettierOptions, sourceReader: SourceReader): Doc = {
val baseDoc = p.toDoc
p.sourcePos.flatMap(sourceReader.apply) match {
case Some(source) =>
baseDoc <> Doc.line <> Doc.text(source)
case None =>
baseDoc
}
}

case class SourceReader(readSource: SourcePos => Option[String]) {
def apply(pos: SourcePos): Option[String] = readSource(pos)
}

object SourceReader {
def fromFileContent(content: FileContent): SourceReader = {
SourceReader { pos =>
pos.getLinesInRange.map { lines =>
lines.map { case (_, line) => line }.mkString("\n")
}
}
}

def empty: SourceReader = SourceReader(_ => None)
}

0 comments on commit df8f8b8

Please sign in to comment.