Skip to content

Commit

Permalink
Gracefully handle parse errors
Browse files Browse the repository at this point in the history
This commit changes error handling for parsing source files so that
users get nicely formatted error messages instead of a large stack trace.
  • Loading branch information
olafurpg committed Sep 27, 2018
1 parent a1a5c90 commit c3e904f
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 12 deletions.
24 changes: 22 additions & 2 deletions src/main/scala/com/github/tkawachi/doctest/ScaladocExtractor.scala
@@ -1,5 +1,8 @@
package com.github.tkawachi.doctest

import java.io.File
import java.nio.file.Files
import java.nio.file.Path
import scala.meta._
import scala.meta.contrib._

Expand All @@ -12,8 +15,25 @@ object ScaladocExtractor {
Set(DocToken.CodeBlock, DocToken.Description, DocToken.Example)

def extract(scalaSource: String): List[ScaladocComment] = {

val code = scalaSource.parse[Source].get
extractFromInput(Input.String(scalaSource))
}
def extractFromFile(file: Path, encoding: String): List[ScaladocComment] = {
val text = new String(Files.readAllBytes(file), encoding)
// Workaround from https://github.com/scalameta/scalameta/issues/443#issuecomment-314797969
val trimmedText = text.replace("\r\n", "\n")
val input = Input.VirtualFile(file.toString, trimmedText)
extractFromInput(input)
}
def extractFromInput(scalaSource: Input): List[ScaladocComment] = {
scalaSource.parse[Source] match {
case Parsed.Success(tree) =>
extractFromTree(tree)
case error @ Parsed.Error(_, _, _) =>
println(error.toString())
Nil
}
}
def extractFromTree(code: Tree): List[ScaladocComment] = {
val comments = AssociatedComments(code)

object NamedMember {
Expand Down
@@ -1,10 +1,10 @@
package com.github.tkawachi.doctest

import java.io.File

import scala.io.Source
import java.nio.file.Files
import org.apache.commons.io.FilenameUtils
import org.apache.commons.lang3.StringEscapeUtils.unescapeHtml4
import scala.meta.Input

object ScaladocTestGenerator {

Expand All @@ -17,9 +17,8 @@ object ScaladocTestGenerator {
* Generates test source code from scala source file.
*/
def apply(srcFile: File, srcEncoding: String, testGen: TestGen, decodeHtmlEnabled: Boolean, onlyCodeBlocksMode: Boolean): Seq[TestSource] = {
val src = Source.fromFile(srcFile, srcEncoding).mkString
val basename = FilenameUtils.getBaseName(srcFile.getName)
ScaladocExtractor.extract(src)
ScaladocExtractor.extractFromFile(srcFile.toPath, srcEncoding)
.map(comment => if (decodeHtmlEnabled) decodeHtml(comment) else comment)
.flatMap { comment =>
val docTest = if (onlyCodeBlocksMode)
Expand Down
@@ -1,17 +1,18 @@
package com.github.tkawachi.doctest

import java.io.ByteArrayOutputStream
import java.io.PrintStream
import java.nio.charset.StandardCharsets
import java.nio.file.Paths
import scala.meta.Input
import utest._

import scala.io.Source

object ScaladocExtractorSpec extends TestSuite {

val tests = this{

import ScaladocExtractor.extract

def extractFromFile(path: String) =
extract(Source.fromFile(path).mkString)
ScaladocExtractor.extractFromFile(Paths.get(path), StandardCharsets.UTF_8.name())

"extracts from Test.scala" - {
val actual = extractFromFile("src/test/resources/Test.scala")
Expand Down Expand Up @@ -132,11 +133,28 @@ object ScaladocExtractorSpec extends TestSuite {
|}
""".stripMargin

val actual = extract(source)
val actual = ScaladocExtractor.extract(source)
val expected = Nil
assert(expected == actual)
}

"parse errors are printed to stdout" - {
val input = Input.VirtualFile("filename.scala", "object Main {")
val out = new ByteArrayOutputStream()
val obtained = Console.withOut(new PrintStream(out)) {
ScaladocExtractor.extractFromInput(input)
}
assert(obtained == Nil)
val obtainedOut = out.toString(StandardCharsets.UTF_8.name).trim
val expectedOut =
"""
|filename.scala:1: error: } expected but end of file found
|object Main {
| ^
""".stripMargin.trim
assert(obtainedOut == expectedOut)
}

"extracts from CodeExamples.scala" - {
val actual = extractFromFile("src/test/resources/CodeExamples.scala")
val expected =
Expand Down

0 comments on commit c3e904f

Please sign in to comment.