scala.tools.nsc.interactive.tests.core.PresentationCompilerRequestsWorkingMode.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scala-compiler Show documentation
Show all versions of scala-compiler Show documentation
Compiler for the Scala Programming Language
package scala.tools.nsc
package interactive
package tests.core
import scala.reflect.internal.util.Position
import scala.reflect.internal.util.SourceFile
trait PresentationCompilerRequestsWorkingMode extends TestResources {
protected def synchronousRequests: Boolean
protected def askAllSources[T] = if (synchronousRequests) askAllSourcesSync[T] _ else askAllSourcesAsync[T] _
/** Perform an operation on all sources at all positions that match the given
* `marker`. For instance, askAllSources(TypeMarker)(askTypeAt)(println) would
* ask the type at all positions marked with `TypeMarker.marker` and println the result.
*/
private def askAllSourcesAsync[T](marker: TestMarker)(askAt: Position => Response[T])(f: (Position, T) => Unit) {
val positions = allPositionsOf(str = marker.marker)
val responses = for (pos <- positions) yield askAt(pos)
for ((pos, r) <- positions zip responses) withResponse(pos, r)(f)
}
/** Synchronous version of askAllSources. Each position is treated in turn, waiting for the
* response before going to the next one.
*/
private def askAllSourcesSync[T](marker: TestMarker)(askAt: Position => Response[T])(f: (Position, T) => Unit) {
val positions = allPositionsOf(str = marker.marker)
for (pos <- positions) withResponse(pos, askAt(pos))(f)
}
/** All positions of the given string in all source files. */
private def allPositionsOf(srcs: Seq[SourceFile] = sourceFiles, str: String): Seq[Position] =
for (s <- srcs; p <- positionsOf(s, str)) yield p
/** Return all positions of the given str in the given source file. */
private def positionsOf(source: SourceFile, str: String): Seq[Position] = {
val buf = new scala.collection.mutable.ListBuffer[Position]
var pos = source.content.indexOfSlice(str)
while (pos >= 0) {
buf += source.position(pos - 1) // we need the position before the first character of this marker
pos = source.content.indexOfSlice(str, pos + 1)
}
buf.toList
}
private def withResponse[T](pos: Position, response: Response[T])(f: (Position, T) => Unit) {
/** Return the filename:line:col version of this position. */
def showPos(pos: Position): String =
"%s:%d:%d".format(pos.source.file.name, pos.line, pos.column)
response.get(TIMEOUT) match {
case Some(Left(t)) =>
f(pos, t)
case None =>
println("TIMEOUT: " + showPos(pos))
case Some(r) =>
println("ERROR: " + r)
}
}
}