Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

190 lines (156 sloc) 7.702 kb
/* NSC -- new Scala compiler
* Copyright 2009-2013 Typesafe/Scala Solutions and LAMP/EPFL
* @author Martin Odersky
*/
package scala.tools.nsc
package interactive
import util.InterruptReq
import scala.reflect.internal.util.{ SourceFile, BatchSourceFile }
import io.{ AbstractFile, PlainFile, Pickler, CondPickler }
import util.EmptyAction
import scala.reflect.internal.util.{ RangePosition, OffsetPosition, TransparentPosition }
import io.Pickler._
import scala.collection.mutable
import mutable.ListBuffer
trait Picklers { self: Global =>
lazy val freshRunReq =
unitPickler
.wrapped { _ => new FreshRunReq } { x => () }
.labelled ("FreshRunReq")
.cond (_.isInstanceOf[FreshRunReq])
lazy val shutdownReq = singletonPickler(ShutdownReq)
def defaultThrowable[T <: Throwable]: CondPickler[T] = javaInstancePickler[T] cond { _ => true }
implicit lazy val throwable: Pickler[Throwable] =
freshRunReq | shutdownReq | defaultThrowable
implicit def abstractFile: Pickler[AbstractFile] =
pkl[String]
.wrapped[AbstractFile] { new PlainFile(_) } { _.path }
.asClass (classOf[PlainFile])
private val sourceFilesSeen = new mutable.HashMap[AbstractFile, Array[Char]] {
override def default(key: AbstractFile) = Array()
}
type Diff = (Int /*start*/, Int /*end*/, String /*replacement*/)
def delta(f: AbstractFile, cs: Array[Char]): Diff = {
val bs = sourceFilesSeen(f)
var start = 0
while (start < bs.length && start < cs.length && bs(start) == cs(start)) start += 1
var end = bs.length
var end2 = cs.length
while (end > start && end2 > start && bs(end - 1) == cs(end2 - 1)) { end -= 1; end2 -= 1 }
sourceFilesSeen(f) = cs
(start, end, cs.slice(start, end2).mkString(""))
}
def patch(f: AbstractFile, d: Diff): Array[Char] = {
val (start, end, replacement) = d
val patched = sourceFilesSeen(f).patch(start, replacement, end - start)
sourceFilesSeen(f) = patched
patched
}
implicit lazy val sourceFile: Pickler[SourceFile] =
(pkl[AbstractFile] ~ pkl[Diff]).wrapped[SourceFile] {
case f ~ d => new BatchSourceFile(f, patch(f, d))
} {
f => f.file ~ delta(f.file, f.content)
}.asClass (classOf[BatchSourceFile])
lazy val offsetPosition: CondPickler[OffsetPosition] =
(pkl[SourceFile] ~ pkl[Int])
.wrapped { case x ~ y => new OffsetPosition(x, y) } { p => p.source ~ p.point }
.asClass (classOf[OffsetPosition])
lazy val rangePosition: CondPickler[RangePosition] =
(pkl[SourceFile] ~ pkl[Int] ~ pkl[Int] ~ pkl[Int])
.wrapped { case source ~ start ~ point ~ end => new RangePosition(source, start, point, end) } { p => p.source ~ p.start ~ p.point ~ p.end }
.asClass (classOf[RangePosition])
lazy val transparentPosition: CondPickler[TransparentPosition] =
(pkl[SourceFile] ~ pkl[Int] ~ pkl[Int] ~ pkl[Int])
.wrapped { case source ~ start ~ point ~ end => new TransparentPosition(source, start, point, end) } { p => p.source ~ p.start ~ p.point ~ p.end }
.asClass (classOf[TransparentPosition])
lazy val noPosition = singletonPickler(NoPosition)
implicit lazy val position: Pickler[Position] = transparentPosition | rangePosition | offsetPosition | noPosition
implicit lazy val namePickler: Pickler[Name] =
pkl[String] .wrapped[Name] {
str => if ((str.length > 1) && (str endsWith "!")) newTypeName(str.init) else newTermName(str)
} {
name => if (name.isTypeName) name.toString+"!" else name.toString
}
implicit lazy val symPickler: Pickler[Symbol] = {
def ownerNames(sym: Symbol, buf: ListBuffer[Name]): ListBuffer[Name] = {
if (!sym.isRoot) {
ownerNames(sym.owner, buf)
buf += (if (sym.isModuleClass) sym.sourceModule else sym).name
if (!sym.isType && !sym.isStable) {
val sym1 = sym.owner.info.decl(sym.name)
if (sym1.isOverloaded) {
val index = sym1.alternatives.indexOf(sym)
assert(index >= 0, sym1+" not found in alternatives "+sym1.alternatives)
buf += newTermName(index.toString)
}
}
}
buf
}
def makeSymbol(root: Symbol, names: List[Name]): Symbol = names match {
case List() =>
root
case name :: rest =>
val sym = root.info.decl(name)
if (sym.isOverloaded) makeSymbol(sym.alternatives(rest.head.toString.toInt), rest.tail)
else makeSymbol(sym, rest)
}
pkl[List[Name]] .wrapped { makeSymbol(rootMirror.RootClass, _) } { ownerNames(_, new ListBuffer).toList }
}
implicit def workEvent: Pickler[WorkEvent] = {
(pkl[Int] ~ pkl[Long])
.wrapped { case id ~ ms => WorkEvent(id, ms) } { w => w.atNode ~ w.atMillis }
}
implicit def interruptReq: Pickler[InterruptReq] = {
val emptyIR: InterruptReq = new InterruptReq { type R = Unit; val todo = () => () }
pkl[Unit] .wrapped { _ => emptyIR } { _ => () }
}
implicit def reloadItem: CondPickler[ReloadItem] =
pkl[List[SourceFile]]
.wrapped { ReloadItem(_, new Response) } { _.sources }
.asClass (classOf[ReloadItem])
implicit def askTypeAtItem: CondPickler[AskTypeAtItem] =
pkl[Position]
.wrapped { new AskTypeAtItem(_, new Response) } { _.pos }
.asClass (classOf[AskTypeAtItem])
implicit def askTypeItem: CondPickler[AskTypeItem] =
(pkl[SourceFile] ~ pkl[Boolean])
.wrapped { case source ~ forceReload => new AskTypeItem(source, forceReload, new Response) } { w => w.source ~ w.forceReload }
.asClass (classOf[AskTypeItem])
implicit def askTypeCompletionItem: CondPickler[AskTypeCompletionItem] =
pkl[Position]
.wrapped { new AskTypeCompletionItem(_, new Response) } { _.pos }
.asClass (classOf[AskTypeCompletionItem])
implicit def askScopeCompletionItem: CondPickler[AskScopeCompletionItem] =
pkl[Position]
.wrapped { new AskScopeCompletionItem(_, new Response) } { _.pos }
.asClass (classOf[AskScopeCompletionItem])
implicit def askToDoFirstItem: CondPickler[AskToDoFirstItem] =
pkl[SourceFile]
.wrapped { new AskToDoFirstItem(_) } { _.source }
.asClass (classOf[AskToDoFirstItem])
implicit def askLinkPosItem: CondPickler[AskLinkPosItem] =
(pkl[Symbol] ~ pkl[SourceFile])
.wrapped { case sym ~ source => new AskLinkPosItem(sym, source, new Response) } { item => item.sym ~ item.source }
.asClass (classOf[AskLinkPosItem])
implicit def askDocCommentItem: CondPickler[AskDocCommentItem] =
(pkl[Symbol] ~ pkl[Symbol] ~ pkl[SourceFile])
.wrapped { case sym ~ site ~ source => new AskDocCommentItem(sym, site, source, new Response) } { item => item.sym ~ item.site ~ item.source }
.asClass (classOf[AskDocCommentItem])
implicit def askLoadedTypedItem: CondPickler[AskLoadedTypedItem] =
pkl[SourceFile]
.wrapped { source => new AskLoadedTypedItem(source, new Response) } { _.source }
.asClass (classOf[AskLoadedTypedItem])
implicit def askParsedEnteredItem: CondPickler[AskParsedEnteredItem] =
(pkl[SourceFile] ~ pkl[Boolean])
.wrapped { case source ~ keepLoaded => new AskParsedEnteredItem(source, keepLoaded, new Response) } { w => w.source ~ w.keepLoaded }
.asClass (classOf[AskParsedEnteredItem])
implicit def emptyAction: CondPickler[EmptyAction] =
pkl[Unit]
.wrapped { _ => new EmptyAction } { _ => () }
.asClass (classOf[EmptyAction])
implicit def action: Pickler[() => Unit] =
reloadItem | askTypeAtItem | askTypeItem | askTypeCompletionItem | askScopeCompletionItem |
askToDoFirstItem | askLinkPosItem | askDocCommentItem | askLoadedTypedItem | askParsedEnteredItem | emptyAction
}
Jump to Line
Something went wrong with that request. Please try again.