Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ignored javadoc tool error #448

Merged
merged 1 commit into from
Nov 9, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ object ForkedJava {
try {
exitCode = Process(exe +: forkArgs, cwd) ! javacLogger
} finally {
javacLogger.flush(exitCode)
javacLogger.flush(program, exitCode)
}
// We return true or false, depending on success.
exitCode == 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,12 +220,16 @@ class JavaErrorParser(relativeDir: File = new File(new File(".").getAbsolutePath
*/
final def parseProblems(in: String, logger: sbt.util.Logger): Seq[Problem] =
parse(javacOutput, in) match {
case Success(result, _) => result
case Failure(_, n) =>
logger.warn(s"Unexpected javac output at:${n.pos.longString}.")
case Success(result, next) =>
if (!next.atEnd) {
logger.warn(s"Unexpected javac output: ${next.source}.")
}
result
case Failure(msg, n) =>
logger.warn(s"Unexpected javac output at ${n.pos.longString}: $msg.")
Seq.empty
case Error(_, n) =>
logger.warn(s"Unexpected javac output at:${n.pos.longString}.")
case Error(msg, n) =>
logger.warn(s"Unexpected javac output at ${n.pos.longString}: $msg.")
Seq.empty
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,50 +13,46 @@ package javac

import xsbti._
import java.io.File

import scala.collection.mutable.ListBuffer
import scala.sys.process.ProcessLogger

/**
* An adapted process logger which can feed semantic error events from Javac as well as just
* dump logs.
*
*
* @param log The logger where all input will go.
* @param log The logger where all non-semantic messages will go.
* @param reporter A reporter for semantic Javac error messages.
* @param cwd The current working directory of the Javac process, used when parsing Filenames.
*/
final class JavacLogger(log: sbt.util.Logger, reporter: Reporter, cwd: File) extends ProcessLogger {
import scala.collection.mutable.ListBuffer
import sbt.util.Level.{ Info, Error, Value => LogLevel }

private val msgs: ListBuffer[(LogLevel, String)] = new ListBuffer()
private var out: ListBuffer[String] = new ListBuffer()
private var err: ListBuffer[String] = new ListBuffer()

def out(s: => String): Unit =
synchronized { msgs += ((Info, s)); () }
synchronized { out += s }

def err(s: => String): Unit =
synchronized { msgs += ((Error, s)); () }
synchronized { err += s }

def buffer[T](f: => T): T = f

// Helper method to dump all semantic errors.
private def parseAndDumpSemanticErrors(): Unit = {
val input =
msgs collect {
case (Error, msg) => msg
} mkString "\n"
val parser = new JavaErrorParser(cwd)
parser.parseProblems(input, log).foreach(reporter.log)
}
def flush(exitCode: Int): Unit = flush("tool", exitCode)

def flush(exitCode: Int): Unit = {
parseAndDumpSemanticErrors()
// Here we only display things that wouldn't otherwise be output by the error reporter.
def flush(toolname: String, exitCode: Int): Unit = {
// TODO - NOTES may not be displayed correctly!
msgs collect {
case (Info, msg) => msg
} foreach { msg =>
log.info(msg)
synchronized {
val parser = new JavaErrorParser(cwd)

parser.parseProblems(err.mkString("\n"), log).foreach(reporter.log(_))
out.foreach(log.info(_))

if (exitCode != 0)
log.warn(s"$toolname exited with exit code $exitCode")

out.clear()
err.clear()
}
msgs.clear()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ final class LocalJavadoc() extends XJavadoc {
} finally {
warnOrError.close()
infoWriter.close()
javacLogger.flush(exitCode)
javacLogger.flush("javadoc", exitCode)
}
// We return true or false, depending on success.
exitCode == 0
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package sbt.internal.inc.javac

import sbt.util.{ Level, Logger }

class CollectingLogger extends Logger {
var messages: Map[Level.Value, Seq[String]] = Map.empty.withDefaultValue(Seq.empty)

override def trace(t: => Throwable): Unit = ???
override def success(message: => String): Unit = ???
override def log(level: Level.Value, message: => String): Unit =
synchronized {
messages = messages.updated(level, messages(level) :+ message)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package sbt
package internal
package inc
package javac

import xsbti.Reporter
import xsbti.Problem

class CollectingReporter extends Reporter {
var problems: Array[Problem] = Array[Problem]()

def reset() = problems = Array[Problem]()
def hasErrors() = ???
def hasWarnings(): Boolean = ???
def printSummary(): Unit = ???
def log(problem: xsbti.Problem): Unit = problems :+= problem
def comment(pos: xsbti.Position, msg: String): Unit = ???

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package sbt
package internal
package inc
package javac

import java.io.File

import sbt.util.Level

class JavaProcessLoggerSpec extends UnitSpec {
"The javac process logger" should "parse regular semantic errors" in logSemanticErrors()
it should "parse semantic errors passed in one by one" in logSeparateSemanticErrors()
it should "log errors that could not be parsed" in logUnparsableErrors()

def logSemanticErrors(): Unit = {
val reporter = new CollectingReporter()
val errorLogger = new CollectingLogger()
val javacLogger = new JavacLogger(errorLogger, reporter, cwd = new File("."))
javacLogger.err(
Seq(
"""Test.java:4: cannot find symbol
|symbol : method baz()
|location: class Foo
|return baz();
| ^
|""",
"""Test.java:8: warning: [deprecation] RMISecurityException(java.lang.String) in java.rmi.RMISecurityException has been deprecated
|throw new java.rmi.RMISecurityException("O NOES");
|^
|"""
).mkString("\n"))

javacLogger.flush("javac", 0)

errorLogger.messages shouldBe Map.empty
reporter.problems.length shouldBe 2
}

def logSeparateSemanticErrors(): Unit = {
val reporter = new CollectingReporter()
val errorLogger = new CollectingLogger()
val javacLogger = new JavacLogger(errorLogger, reporter, cwd = new File("."))
javacLogger.err("""Test.java:4: cannot find symbol
|symbol : method baz()
|location: class Foo
|return baz();
| ^
|""")
javacLogger.err(
"""Test.java:8: warning: [deprecation] RMISecurityException(java.lang.String) in java.rmi.RMISecurityException has been deprecated
|throw new java.rmi.RMISecurityException("O NOES");
|^
|""")

javacLogger.flush("javac", 0)

errorLogger.messages shouldBe Map.empty
reporter.problems.length shouldBe 2
}

def logUnparsableErrors(): Unit = {
val reporter = new CollectingReporter()
val errorLogger = new CollectingLogger()
val javacLogger = new JavacLogger(errorLogger, reporter, cwd = new File("."))
javacLogger.err("javadoc: error - invalid flag: -target")

javacLogger.flush("javadoc", -1)

errorLogger.messages(Level.Warn).length shouldBe 2
errorLogger
.messages(Level.Warn)(0)
.contains("javadoc: error - invalid flag: -target") shouldBe true
errorLogger.messages(Level.Warn)(1).contains("javadoc exited with exit code -1") shouldBe true
}
}