Merge branch 'master' into java7

This commit is contained in:
Paul Phillips 2011-11-23 15:10:30 -08:00
commit bef11beca5
184 changed files with 4567 additions and 3292 deletions

View File

@ -634,11 +634,13 @@ QUICK BUILD (QUICK)
<scalacfork
destdir="${build-quick.dir}/classes/library"
compilerpathref="locker.classpath"
params="${scalac.args.quick} -Xpluginsdir ${build-quick.dir}/misc/scala-devel/plugins -Xplugin-require:continuations -P:continuations:enable"
params="${scalac.args.quick} -Xplugin-require:continuations -P:continuations:enable"
srcdir="${src.dir}/continuations/library"
jvmargs="${scalacfork.jvmargs}">
<include name="**/*.scala"/>
<compilationpath refid="quick.compilation.path"/>
<compilerarg value="-Xpluginsdir"/>
<compilerarg file="${build-quick.dir}/misc/scala-devel/plugins"/>
</scalacfork>
<touch file="${build-quick.dir}/plugins.complete" verbose="no"/>
<stopwatch name="quick.plugins.timer" action="total"/>
@ -1147,11 +1149,13 @@ BOOTSTRAPPING BUILD (STRAP)
<scalacfork
destdir="${build-strap.dir}/classes/library"
compilerpathref="pack.classpath"
params="${scalac.args.all} -Xpluginsdir ${build-strap.dir}/misc/scala-devel/plugins -Xplugin-require:continuations -P:continuations:enable"
params="${scalac.args.all} -Xplugin-require:continuations -P:continuations:enable"
srcdir="${src.dir}/continuations/library"
jvmargs="${scalacfork.jvmargs}">
<include name="**/*.scala"/>
<compilationpath refid="strap.compilation.path"/>
<compilerarg value="-Xpluginsdir"/>
<compilerarg file="${build-strap.dir}/misc/scala-devel/plugins"/>
</scalacfork>
<touch file="${build-strap.dir}/plugins.complete" verbose="no"/>
<stopwatch name="strap.plugins.timer" action="total"/>
@ -1592,7 +1596,9 @@ BOOTRAPING TEST AND TEST SUITE
<partest showlog="yes" erroronfailed="yes" javacmd="${java.home}/bin/java"
timeout="2400000"
srcdir="${partest.srcdir}"
scalacopts="${scalac.args.optimise} -Xpluginsdir ${build-quick.dir}/misc/scala-devel/plugins -Xplugin-require:continuations -P:continuations:enable">
scalacopts="${scalac.args.optimise} -Xplugin-require:continuations -P:continuations:enable">
<compilerarg value="-Xpluginsdir"/>
<compilerarg file="${build-quick.dir}/misc/scala-devel/plugins"/>
<compilationpath>
<path refid="pack.classpath"/>
<fileset dir="${partest.dir}/files/lib" includes="*.jar" />

View File

@ -12,7 +12,7 @@ class ComputeServer(n: Int) {
private val openJobs = new Channel[Job]()
private def processor(i: Int): Unit = {
private def processor(i: Int) {
while (true) {
val job = openJobs.read
println("read a job")
@ -32,16 +32,17 @@ class ComputeServer(n: Int) {
() => reply.get
}
spawn(replicate(0, n) { processor })
//spawn(replicate(0, n) { processor })
spawn((0 until n).par foreach { processor })
}
object computeserver extends Application {
object computeserver extends App {
def kill(delay: Int) = new java.util.Timer().schedule(
new java.util.TimerTask {
override def run() = {
println("[killed]")
System.exit(0)
sys exit 0
}
},
delay) // in milliseconds

View File

@ -2,35 +2,39 @@ package examples
object oneplacebuffer {
import scala.concurrent.{MailBox, ops}
import scala.actors.Actor._
import scala.concurrent.ops
class OnePlaceBuffer {
private val m = new MailBox() {} // An internal mailbox
private case class Empty() // Types of messages we deal with
private case class Full(x: Int)
private case class Put(x: Int)
private case object Get
m send Empty() // Initialization
def write(x: Int) {
m receive {
case Empty() =>
println("put " + x)
m send Full(x)
private val m = actor {
var buf: Option[Int] = None
loop {
react {
case Put(x) if buf.isEmpty =>
println("put "+x);
buf = Some(x); reply()
case Get if !buf.isEmpty =>
val x = buf.get
println("get "+x)
buf = None; reply(x)
}
}
}
m.start()
def read: Int = m receive {
case Full(x) =>
println("get " + x)
m send Empty(); x
}
def write(x: Int) { m !? Put(x) }
def read(): Int = (m !? Get).asInstanceOf[Int]
}
def kill(delay: Int) = new java.util.Timer().schedule(
new java.util.TimerTask {
override def run() = {
override def run() {
println("[killed]")
exit(0)
sys exit 0
}
},
delay) // in milliseconds
@ -40,19 +44,19 @@ object oneplacebuffer {
val random = new java.util.Random()
def producer(n: Int) {
Thread.sleep(random.nextInt(1000))
buf.write(n)
Thread.sleep(random nextInt 1000)
buf write n
producer(n + 1)
}
def consumer {
Thread.sleep(random.nextInt(1000))
val n = buf.read
Thread.sleep(random nextInt 1000)
val n = buf.read()
consumer
}
ops.spawn(producer(0))
ops.spawn(consumer)
ops spawn producer(0)
ops spawn consumer
kill(10000)
}

View File

@ -26,7 +26,7 @@ extends Global(settings, reporter) {
phasesSet += analyzer.typerFactory
phasesSet += superAccessors // add super accessors
phasesSet += pickler // serialize symbol tables
phasesSet += refchecks // perform reference and override checking, translate nested objects
phasesSet += refChecks // perform reference and override checking, translate nested objects
for (phase <- TemplatePlugin.components(this)) {
phasesSet += phase

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -45,7 +45,7 @@ private[actors] object ThreadPoolConfig {
// on IBM J9 1.6 do not use ForkJoinPool
// XXX this all needs to go into Properties.
isJavaAtLeast("1.6") && ((javaVmVendor contains "Sun") || (javaVmVendor contains "Apple"))
isJavaAtLeast("1.6") && ((javaVmVendor contains "Oracle") || (javaVmVendor contains "Sun") || (javaVmVendor contains "Apple"))
})
catch {
case _: SecurityException => false

View File

@ -11,7 +11,7 @@ import pickling.ByteCodecs
/** AnnotationInfo and its helpers */
trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
import definitions.{ ThrowsClass, isMetaAnnotation }
import definitions.{ ThrowsClass, StaticAnnotationClass, isMetaAnnotation }
// Common annotation code between Symbol and Type.
// For methods altering the annotation list, on Symbol it mutates
@ -24,6 +24,7 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
def annotations: List[AnnotationInfo] // Annotations on this type.
def setAnnotations(annots: List[AnnotationInfo]): Self // Replace annotations with argument list.
def withAnnotations(annots: List[AnnotationInfo]): Self // Add annotations to this type.
def filterAnnotations(p: AnnotationInfo => Boolean): Self // Retain only annotations meeting the condition.
def withoutAnnotations: Self // Remove all annotations from this type.
/** Symbols of any @throws annotations on this symbol.
@ -35,9 +36,8 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
/** Test for, get, or remove an annotation */
def hasAnnotation(cls: Symbol) = annotations exists (_ matches cls)
def getAnnotation(cls: Symbol) = annotations find (_ matches cls)
def removeAnnotation(cls: Symbol): Self =
if (hasAnnotation(cls)) setAnnotations(annotations filterNot (_ matches cls))
else this
def removeAnnotation(cls: Symbol): Self = filterAnnotations(ann => !(ann matches cls))
final def withAnnotation(annot: AnnotationInfo): Self = withAnnotations(List(annot))
}
/** Arguments to classfile annotations (which are written to
@ -86,8 +86,7 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
}
/** Represents a nested classfile annotation */
case class NestedAnnotArg(annInfo: AnnotationInfo)
extends ClassfileAnnotArg {
case class NestedAnnotArg(annInfo: AnnotationInfo) extends ClassfileAnnotArg {
// The nested annotation should not have any Scala annotation arguments
assert(annInfo.args.isEmpty, annInfo.args)
override def toString = annInfo.toString
@ -95,7 +94,49 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
object NestedAnnotArg extends NestedAnnotArgExtractor
class AnnotationInfoBase
object AnnotationInfo extends AnnotationInfoExtractor {
def marker(atp: Type): AnnotationInfo =
apply(atp, Nil, Nil)
def lazily(lazyInfo: => AnnotationInfo) =
new LazyAnnotationInfo(lazyInfo)
def apply(atp: Type, args: List[Tree], assocs: List[(Name, ClassfileAnnotArg)]): AnnotationInfo =
new CompleteAnnotationInfo(atp, args, assocs)
def unapply(info: AnnotationInfo): Option[(Type, List[Tree], List[(Name, ClassfileAnnotArg)])] =
Some((info.atp, info.args, info.assocs))
}
class CompleteAnnotationInfo(
val atp: Type,
val args: List[Tree],
val assocs: List[(Name, ClassfileAnnotArg)]
) extends AnnotationInfo {
// Classfile annot: args empty. Scala annot: assocs empty.
assert(args.isEmpty || assocs.isEmpty, atp)
override def toString = (
atp +
(if (!args.isEmpty) args.mkString("(", ", ", ")") else "") +
(if (!assocs.isEmpty) (assocs map { case (x, y) => x+" = "+y } mkString ("(", ", ", ")")) else "")
)
}
/** Symbol annotations parsed in `Namer` (typeCompleter of
* definitions) have to be lazy (#1782)
*/
final class LazyAnnotationInfo(lazyInfo: => AnnotationInfo) extends AnnotationInfo {
private var forced = false
private lazy val forcedInfo = try lazyInfo finally forced = true
def atp: Type = forcedInfo.atp
def args: List[Tree] = forcedInfo.args
def assocs: List[(Name, ClassfileAnnotArg)] = forcedInfo.assocs
// We should always be able to print things without forcing them.
override def toString = if (forced) forcedInfo.toString else "@<?>"
}
/** Typed information about an annotation. It can be attached to either
* a symbol or an annotated type.
@ -113,12 +154,13 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
*
* `assocs` stores arguments to classfile annotations as name-value pairs.
*/
case class AnnotationInfo(atp: Type, args: List[Tree],
assocs: List[(Name, ClassfileAnnotArg)])
extends AnnotationInfoBase {
sealed abstract class AnnotationInfo {
def atp: Type
def args: List[Tree]
def assocs: List[(Name, ClassfileAnnotArg)]
// Classfile annot: args empty. Scala annot: assocs empty.
assert(args.isEmpty || assocs.isEmpty, atp)
// see annotationArgRewriter
lazy val isTrivial = atp.isTrivial && !hasArgWhich(_.isInstanceOf[This])
private var rawpos: Position = NoPosition
def pos = rawpos
@ -164,15 +206,11 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
def matches(clazz: Symbol) = symbol isNonBottomSubClass clazz
// All subtrees of all args are considered.
def hasArgWhich(p: Tree => Boolean) = args exists (_ exists p)
lazy val isTrivial: Boolean = atp.isTrivial && !hasArgWhich(_.isInstanceOf[This]) // see annotationArgRewriter
override def toString: String = atp +
(if (!args.isEmpty) args.mkString("(", ", ", ")") else "") +
(if (!assocs.isEmpty) (assocs map { case (x, y) => x+" = "+y } mkString ("(", ", ", ")")) else "")
/** Check whether the type or any of the arguments are erroneous */
def isErroneous = atp.isErroneous || args.exists(_.isErroneous)
def isStatic = symbol isNonBottomSubClass StaticAnnotationClass
/** Check whether any of the arguments mention a symbol */
def refsSymbol(sym: Symbol) = hasArgWhich(_.symbol == sym)
@ -198,18 +236,16 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
def argAtIndex(index: Int): Option[Tree] =
if (index < args.size) Some(args(index)) else None
override def hashCode = atp.## + args.## + assocs.##
override def equals(other: Any) = other match {
case x: AnnotationInfo => (atp == x.atp) && (args == x.args) && (assocs == x.assocs)
case _ => false
}
}
object AnnotationInfo extends AnnotationInfoExtractor
lazy val classfileAnnotArgManifest: ClassManifest[ClassfileAnnotArg] =
reflect.ClassManifest.classType(classOf[ClassfileAnnotArg])
/** Symbol annotations parsed in `Namer` (typeCompleter of
* definitions) have to be lazy (#1782)
*/
case class LazyAnnotationInfo(annot: () => AnnotationInfo)
extends AnnotationInfoBase
object UnmappableAnnotation extends AnnotationInfo(NoType, Nil, Nil)
object UnmappableAnnotation extends CompleteAnnotationInfo(NoType, Nil, Nil)
}

View File

@ -32,6 +32,11 @@ object ClassfileConstants {
*
* All interface methods must have their `ACC_ABSTRACT` and
* `ACC_PUBLIC` flags set.
*
* Note for future reference: see this thread on ACC_SUPER and
* how its enforcement differs on the android vm.
* https://groups.google.com/forum/?hl=en#!topic/jvm-languages/jVhzvq8-ZIk
*
*/ // Class Field Method
final val JAVA_ACC_PUBLIC = 0x0001 // X X X
final val JAVA_ACC_PRIVATE = 0x0002 // X X

View File

@ -81,6 +81,9 @@ trait Definitions extends reflect.api.StandardDefinitions {
def isNumericValueClass(sym: Symbol): Boolean =
numericWeight contains sym
def isGetClass(sym: Symbol) =
(sym.name == nme.getClass_) && (sym.paramss.isEmpty || sym.paramss.head.isEmpty)
private[Definitions] def fullNameStrings: List[String] = nme.ScalaValueNames map ("scala." + _)
private[Definitions] lazy val fullValueName: Set[Name] = {
val values = nme.ScalaValueNames flatMap (x => List(newTypeName("scala." + x), newTermName("scala." + x)))

View File

@ -331,12 +331,11 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
*/
def scopeTransform(owner: Symbol)(op: => Scope): Scope = op
def newScopeWith(elems: Symbol*) = {
def newScopeWith(elems: Symbol*): Scope = {
val scope = newScope
elems foreach scope.enter
scope
}
/** The empty scope (immutable).
*/

View File

@ -241,6 +241,7 @@ trait StdNames extends /*reflect.generic.StdNames with*/ NameManglers { self: Sy
val applyDynamic: NameType = "applyDynamic"
val isArray: NameType = "isArray"
val isDefinedAt: NameType = "isDefinedAt"
val _isDefinedAt: NameType = "_isDefinedAt"
val isEmpty: NameType = "isEmpty"
val isInstanceOf_ : NameType = "isInstanceOf"
val java: NameType = "java"
@ -248,8 +249,10 @@ trait StdNames extends /*reflect.generic.StdNames with*/ NameManglers { self: Sy
val length: NameType = "length"
val lengthCompare: NameType = "lengthCompare"
val lift_ : NameType = "lift"
val macro_ : NameType = "macro"
val main: NameType = "main"
val map: NameType = "map"
val missingCase: NameType = "missingCase"
val ne: NameType = "ne"
val newArray: NameType = "newArray"
val next: NameType = "next"

View File

@ -18,6 +18,7 @@ abstract class SymbolTable extends api.Universe
with Constants
with BaseTypeSeqs
with InfoTransformers
with transform.Transforms
with StdNames
with AnnotationInfos
with AnnotationCheckers

View File

@ -40,10 +40,25 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* EnclosingMethod attributes.
*/
val originalOwner = perRunCaches.newMap[Symbol, Symbol]()
abstract class AbsSymbolImpl extends AbsSymbol { this: Symbol =>
def newNestedSymbol(pos: Position, name: Name) = name match {
case n: TermName => newValue(pos, n)
case n: TypeName => newAliasType(pos, n)
}
def typeSig: Type = info
def typeSigIn(site: Type): Type = site.memberInfo(this)
def asType: Type = tpe
def asTypeIn(site: Type): Type = site.memberType(this)
def asTypeConstructor: Type = typeConstructor
def setInternalFlags(flag: Long): this.type = { setFlag(flag); this }
def setTypeSig(tpe: Type): this.type = { setInfo(tpe); this }
def setAnnotations(annots: AnnotationInfo*): this.type = { setAnnotations(annots.toList); this }
}
/** The class for all symbols */
abstract class Symbol(initOwner: Symbol, initPos: Position, initName: Name)
extends AbsSymbol
extends AbsSymbolImpl
with HasFlags
with Annotatable[Symbol] {
@ -248,16 +263,19 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Create a new getter for current symbol (which must be a field)
*/
final def newGetter: Symbol = {
val getter = owner.newMethod(focusPos(pos), nme.getterName(name)).setFlag(getterFlags(flags))
getter.privateWithin = privateWithin
getter.setInfo(MethodType(List(), tpe))
}
final def newGetter: Symbol = (
owner.newMethod(focusPos(pos), nme.getterName(name))
setFlag getterFlags(flags)
setPrivateWithin privateWithin
setInfo MethodType(Nil, tpe)
)
final def newErrorClass(name: TypeName) = {
val clazz = newClass(pos, name).setFlag(SYNTHETIC | IS_ERROR)
clazz.setInfo(ClassInfoType(List(), new ErrorScope(this), clazz))
clazz
val clazz = newClass(pos, name)
( clazz
setFlag (SYNTHETIC | IS_ERROR)
setInfo ClassInfoType(Nil, new ErrorScope(this), clazz)
)
}
final def newErrorSymbol(name: Name): Symbol = name match {
@ -338,6 +356,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def isModuleClass = isClass && hasFlag(MODULE)
final def isNumericValueClass = definitions.isNumericValueClass(this)
final def isOverloaded = hasFlag(OVERLOADED)
final def isOverridableMember = !(isClass || isEffectivelyFinal) && owner.isClass
final def isRefinementClass = isClass && name == tpnme.REFINE_CLASS_NAME
final def isSourceMethod = isMethod && !hasFlag(STABLE) // exclude all accessors!!!
final def isTypeParameter = isType && isParameter && !isSkolem
@ -362,9 +381,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
def isEffectiveRoot = isRoot || isEmptyPackageClass
final def isPossibleInRefinement = !isConstructor && !isOverridingSymbol
final def isStructuralRefinementMember = owner.isStructuralRefinement && isPossibleInRefinement && isPublic
/** Term symbols with the exception of static parts of Java classes and packages.
*/
final def isValue = isTerm && !(isModule && hasFlag(PACKAGE | JAVA))
@ -402,9 +418,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
// class C extends D( { class E { ... } ... } ). Here, E is a class local to a constructor
final def isClassLocalToConstructor = isClass && hasFlag(INCONSTRUCTOR)
final def isAnonymousClass = isClass && (name containsName tpnme.ANON_CLASS_NAME)
final def isAnonymousFunction = isSynthetic && (name containsName tpnme.ANON_FUN_NAME)
final def isAnonOrRefinementClass = isAnonymousClass || isRefinementClass
final def isAnonymousClass = isClass && (name containsName tpnme.ANON_CLASS_NAME)
final def isAnonymousFunction = isSynthetic && (name containsName tpnme.ANON_FUN_NAME)
final def isAnonOrRefinementClass = isAnonymousClass || isRefinementClass
// A package object or its module class
final def isPackageObjectOrClass = name == nme.PACKAGE || name == tpnme.PACKAGE
@ -595,6 +611,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def isStructuralRefinement: Boolean =
(isClass || isType || isModule) && info.normalize/*.underlying*/.isStructuralRefinement
final def isStructuralRefinementMember = owner.isStructuralRefinement && isPossibleInRefinement && isPublic
final def isPossibleInRefinement = !isConstructor && !isOverridingSymbol
/** Is this symbol a member of class `clazz`? */
def isMemberOf(clazz: Symbol) =
clazz.info.member(name).alternatives contains this
@ -843,6 +862,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
private[this] var _privateWithin: Symbol = _
def privateWithin = _privateWithin
def privateWithin_=(sym: Symbol) { _privateWithin = sym }
def setPrivateWithin(sym: Symbol): this.type = { privateWithin_=(sym) ; this }
/** Does symbol have a private or protected qualifier set? */
final def hasAccessBoundary = (privateWithin != null) && (privateWithin != NoSymbol)
@ -914,9 +934,12 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
/** Set initial info. */
def setInfo(info: Type): this.type = { info_=(info); this }
def setInfoOwnerAdjusted(info: Type): this.type = setInfo(info.atOwner(this))
def setInfo(info: Type): this.type = { info_=(info); this }
/** Modifies this symbol's info in place. */
def modifyInfo(f: Type => Type): this.type = setInfo(f(info))
/** Substitute second list of symbols for first in current info. */
def substInfo(syms0: List[Symbol], syms1: List[Symbol]) = modifyInfo(_.substSym(syms0, syms1))
def setInfoOwnerAdjusted(info: Type): this.type = setInfo(info atOwner this)
/** Set new info valid from start of this phase. */
final def updateInfo(info: Type): Symbol = {
@ -1107,7 +1130,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
val oldsyms = oldsymbuf.toList
val newsyms = newsymbuf.toList
for (sym <- newsyms) {
addMember(thistp, tp, sym.setInfo(sym.info.substThis(this, thistp).substSym(oldsyms, newsyms)))
addMember(thistp, tp, sym modifyInfo (_ substThisAndSym(this, thistp, oldsyms, newsyms)))
}
tp
}
@ -1118,12 +1141,12 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
def existentialBound: Type =
if (this.isClass)
polyType(this.typeParams, TypeBounds.upper(this.classBound))
polyType(this.typeParams, TypeBounds.upper(this.classBound))
else if (this.isAbstractType)
this.info
this.info
else if (this.isTerm)
TypeBounds.upper(intersectionType(List(this.tpe, SingletonClass.tpe)))
else
singletonBounds(this.tpe)
else
abort("unexpected alias type: "+this)
/** Reset symbol to initial state
@ -1157,41 +1180,31 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
// ----- annotations ------------------------------------------------------------
private var rawannots: List[AnnotationInfoBase] = Nil
def rawAnnotations = rawannots
// null is a marker that they still need to be obtained.
private var _annotations: List[AnnotationInfo] = Nil
/* Used in namer to check whether annotations were already assigned or not */
def hasAssignedAnnotations = rawannots.nonEmpty
def annotationsString = if (annotations.isEmpty) "" else annotations.mkString("(", ", ", ")")
/** After the typer phase (before, look at the definition's Modifiers), contains
* the annotations attached to member a definition (class, method, type, field).
*/
def annotations: List[AnnotationInfo] = {
// .initialize: the type completer of the symbol parses the annotations,
// see "def typeSig" in Namers
val annots1 = initialize.rawannots map {
case x: LazyAnnotationInfo => x.annot()
case x: AnnotationInfo => x
} filterNot (_.atp.isError)
rawannots = annots1
annots1
}
def setRawAnnotations(annots: List[AnnotationInfoBase]): this.type = {
this.rawannots = annots
def annotations: List[AnnotationInfo] = _annotations
def setAnnotations(annots: List[AnnotationInfo]): this.type = {
_annotations = annots
this
}
def setAnnotations(annots: List[AnnotationInfo]): this.type =
setRawAnnotations(annots)
def withAnnotations(annots: List[AnnotationInfo]): this.type =
setRawAnnotations(annots ::: rawannots)
setAnnotations(annots ::: annotations)
def withoutAnnotations: this.type =
setRawAnnotations(Nil)
setAnnotations(Nil)
def filterAnnotations(p: AnnotationInfo => Boolean): this.type =
setAnnotations(annotations filter p)
def addAnnotation(annot: AnnotationInfo): this.type =
setRawAnnotations(annot :: rawannots)
setAnnotations(annot :: annotations)
// Convenience for the overwhelmingly common case
def addAnnotation(sym: Symbol, args: Tree*): this.type =
@ -1270,9 +1283,12 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** A clone of this symbol, but with given owner. */
final def cloneSymbol(owner: Symbol): Symbol = {
val newSym = cloneSymbolImpl(owner)
newSym.privateWithin = privateWithin
newSym.setInfo(info.cloneInfo(newSym))
.setFlag(this.rawflags).setAnnotations(this.annotations)
( newSym
setPrivateWithin privateWithin
setInfo (info cloneInfo newSym)
setFlag this.rawflags
setAnnotations this.annotations
)
}
/** Internal method to clone a symbol's implementation without flags or type. */
@ -2218,7 +2234,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
def cloneSymbolImpl(owner: Symbol): Symbol =
new TypeSymbol(owner, pos, name) //.toTypeName)
new TypeSymbol(owner, pos, name)
incCounter(typeSymbolCount)
}
@ -2426,16 +2442,80 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def originalEnclosingMethod = this
}
private def cloneAndSubstInfos[T <: Symbol](syms: List[T])(f: T => Symbol): List[T] = {
val syms1 = syms map (s => f(s).asInstanceOf[T])
syms1 map (sym1 => sym1 setInfo sym1.info.substSym(syms, syms1))
/** Derives a new list of symbols from the given list by mapping the given
* list across the given function. Then fixes the info of all the new symbols
* by substituting the new symbols for the original symbols.
*
* @param syms the prototypical symbols
* @param symFn the function to create new symbols
* @return the new list of info-adjusted symbols
*/
def deriveSymbols(syms: List[Symbol], symFn: Symbol => Symbol): List[Symbol] = {
val syms1 = syms map symFn
syms1 map (_ substInfo (syms, syms1))
}
/** Derives a new Type by first deriving new symbols as in deriveSymbols,
* then performing the same oldSyms => newSyms substitution on `tpe` as is
* performed on the symbol infos in deriveSymbols.
*
* @param syms the prototypical symbols
* @param symFn the function to create new symbols
* @param tpe the prototypical type
* @return the new symbol-subsituted type
*/
def deriveType(syms: List[Symbol], symFn: Symbol => Symbol)(tpe: Type): Type = {
val syms1 = deriveSymbols(syms, symFn)
tpe.substSym(syms, syms1)
}
/** Derives a new Type by instantiating the given list of symbols as
* WildcardTypes.
*
* @param syms the symbols to replace
* @return the new type with WildcardType replacing those syms
*/
def deriveTypeWithWildcards(syms: List[Symbol])(tpe: Type): Type = {
if (syms.isEmpty) tpe
else tpe.instantiateTypeParams(syms, syms map (_ => WildcardType))
}
/** Convenience functions which derive symbols by cloning.
*/
def cloneSymbols(syms: List[Symbol]): List[Symbol] =
deriveSymbols(syms, _.cloneSymbol)
def cloneSymbolsAtOwner(syms: List[Symbol], owner: Symbol): List[Symbol] =
deriveSymbols(syms, _ cloneSymbol owner)
/** Clone symbols and apply the given function to each new symbol's info.
*
* @param syms the prototypical symbols
* @param infoFn the function to apply to the infos
* @return the newly created, info-adjusted symbols
*/
def cloneSymbolsAndModify(syms: List[Symbol], infoFn: Type => Type): List[Symbol] =
cloneSymbols(syms) map (_ modifyInfo infoFn)
/** Functions which perform the standard clone/substituting on the given symbols and type,
* then call the creator function with the new symbols and type as arguments.
*/
def createFromClonedSymbols[T](syms: List[Symbol], tpe: Type)(creator: (List[Symbol], Type) => T): T = {
val syms1 = cloneSymbols(syms)
creator(syms1, tpe.substSym(syms, syms1))
}
def createFromClonedSymbolsAtOwner[T](syms: List[Symbol], owner: Symbol, tpe: Type)(creator: (List[Symbol], Type) => T): T = {
val syms1 = cloneSymbolsAtOwner(syms, owner)
creator(syms1, tpe.substSym(syms, syms1))
}
def cloneSymbols[T <: Symbol](syms: List[T]): List[T] =
cloneAndSubstInfos(syms)(_.cloneSymbol)
def cloneSymbols[T <: Symbol](syms: List[T], owner: Symbol): List[T] =
cloneAndSubstInfos(syms)(_ cloneSymbol owner)
/** Create a new existential type skolem with the given owner and origin.
*/
def newExistentialSkolem(sym: Symbol, owner: Symbol, origin: AnyRef): TypeSkolem = {
val skolem = new TypeSkolem(owner, sym.pos, sym.name.toTypeName, origin)
( skolem
setInfo (sym.info cloneInfo skolem)
setFlag (sym.flags | EXISTENTIAL)
resetFlag PARAM
)
}
/** An exception for cyclic references of symbol definitions */
case class CyclicReference(sym: Symbol, info: Type)

View File

@ -46,10 +46,8 @@ abstract class TreeGen {
def mkMethodCall(receiver: Tree, method: Symbol, targs: List[Type], args: List[Tree]): Tree =
mkMethodCall(Select(receiver, method), targs, args)
def mkMethodCall(target: Tree, targs: List[Type], args: List[Tree]): Tree = {
val typeApplied = if (targs.isEmpty) target else TypeApply(target, targs map TypeTree)
Apply(typeApplied, args)
}
def mkMethodCall(target: Tree, targs: List[Type], args: List[Tree]): Tree =
Apply(mkTypeApply(target, targs map TypeTree), args)
/** Builds a reference to value whose type is given stable prefix.
* The type must be suitable for this. For example, it
@ -153,12 +151,14 @@ abstract class TreeGen {
/** Cast `tree` to type `pt` */
def mkCast(tree: Tree, pt: Type): Tree = {
debuglog("casting " + tree + ":" + tree.tpe + " to " + pt)
debuglog("casting " + tree + ":" + tree.tpe + " to " + pt + " at phase: " + phase)
assert(!tree.tpe.isInstanceOf[MethodType], tree)
assert(!pt.typeSymbol.isPackageClass)
assert(!pt.typeSymbol.isPackageObjectClass)
assert(pt eq pt.normalize, tree +" : "+ debugString(pt) +" ~>"+ debugString(pt.normalize)) //@MAT only called during erasure, which already takes care of that
atPos(tree.pos)(mkAsInstanceOf(tree, pt, false))
assert(!pt.typeSymbol.isPackageClass && !pt.typeSymbol.isPackageObjectClass, pt)
// @MAT only called during erasure, which already takes care of that
// @PP: "only called during erasure" is not very true these days.
// In addition, at least, are: typer, uncurry, explicitouter, cleanup.
assert(pt eq pt.normalize, tree +" : "+ debugString(pt) +" ~>"+ debugString(pt.normalize))
atPos(tree.pos)(mkAsInstanceOf(tree, pt, any = false, wrapInApply = true))
}
/** Builds a reference with stable type to given symbol */
@ -192,31 +192,33 @@ abstract class TreeGen {
}
}
private def mkTypeApply(value: Tree, tpe: Type, what: Symbol, wrapInApply: Boolean) = {
val tapp = TypeApply(mkAttributedSelect(value, what), List(TypeTree(tpe.normalize)))
if (wrapInApply) Apply(tapp, List()) else tapp
/** Builds a type application node if args.nonEmpty, returns fun otherwise. */
def mkTypeApply(fun: Tree, targs: List[Tree]): Tree =
if (targs.isEmpty) fun else TypeApply(fun, targs)
def mkTypeApply(target: Tree, method: Symbol, targs: List[Type]): Tree =
mkTypeApply(Select(target, method), targs map TypeTree)
def mkAttributedTypeApply(target: Tree, method: Symbol, targs: List[Type]): Tree =
mkTypeApply(mkAttributedSelect(target, method), targs map TypeTree)
private def mkSingleTypeApply(value: Tree, tpe: Type, what: Symbol, wrapInApply: Boolean) = {
val tapp = mkAttributedTypeApply(value, what, List(tpe.normalize))
if (wrapInApply) Apply(tapp, Nil) else tapp
}
private def typeTestSymbol(any: Boolean) = if (any) Any_isInstanceOf else Object_isInstanceOf
private def typeCastSymbol(any: Boolean) = if (any) Any_asInstanceOf else Object_asInstanceOf
/** Builds an instance test with given value and type. */
def mkIsInstanceOf(value: Tree, tpe: Type, any: Boolean = true, wrapInApply: Boolean = true): Tree =
mkTypeApply(value, tpe, (if (any) Any_isInstanceOf else Object_isInstanceOf), wrapInApply)
mkSingleTypeApply(value, tpe, typeTestSymbol(any), wrapInApply)
/** Builds a cast with given value and type. */
def mkAsInstanceOf(value: Tree, tpe: Type, any: Boolean = true, wrapInApply: Boolean = true): Tree =
mkTypeApply(value, tpe, (if (any) Any_asInstanceOf else Object_asInstanceOf), wrapInApply)
mkSingleTypeApply(value, tpe, typeCastSymbol(any), wrapInApply)
/** Cast `tree` to `pt`, unless tpe is a subtype of pt, or pt is Unit. */
def maybeMkAsInstanceOf(tree: Tree, pt: Type, tpe: Type, beforeRefChecks: Boolean = false): Tree =
if ((pt == UnitClass.tpe) || (tpe <:< pt)) {
log("no need to cast from " + tpe + " to " + pt)
tree
} else
atPos(tree.pos) {
if (beforeRefChecks)
TypeApply(mkAttributedSelect(tree, Any_asInstanceOf), List(TypeTree(pt)))
else
mkAsInstanceOf(tree, pt)
}
if ((pt == UnitClass.tpe) || (tpe <:< pt)) tree
else atPos(tree.pos)(mkAsInstanceOf(tree, pt, any = true, wrapInApply = !beforeRefChecks))
/** Apparently we smuggle a Type around as a Literal(Constant(tp))
* and the implementation of Constant#tpe is such that x.tpe becomes

View File

@ -9,7 +9,7 @@ package internal
import java.io.{ OutputStream, PrintWriter, StringWriter, Writer }
import Flags._
trait TreePrinters { self: SymbolTable =>
trait TreePrinters extends api.TreePrinters { self: SymbolTable =>
//nsc import treeInfo.{ IsTrue, IsFalse }
@ -33,17 +33,18 @@ trait TreePrinters { self: SymbolTable =>
case _ => t.toString
}
class TreePrinter(out: PrintWriter) {
class TreePrinter(out: PrintWriter) extends super.TreePrinter {
protected var indentMargin = 0
protected val indentStep = 2
protected var indentString = " " // 40
def flush() = out.flush()
typesPrinted = settings.printtypes.value
uniqueIds = settings.uniqid.value
protected def doPrintPositions = settings.Xprintpos.value
def indent() = indentMargin += indentStep
def undent() = indentMargin -= indentStep
protected def doPrintPositions = settings.Xprintpos.value
def printPosition(tree: Tree) = if (doPrintPositions) print(showPos(tree.pos))
def println() {
@ -64,11 +65,11 @@ trait TreePrinters { self: SymbolTable =>
def printColumn(ts: List[Tree], start: String, sep: String, end: String) {
print(start); indent; println()
printSeq(ts){print}{print(sep); println()}; undent; println(); print(end)
printSeq(ts){print(_)}{print(sep); println()}; undent; println(); print(end)
}
def printRow(ts: List[Tree], start: String, sep: String, end: String) {
print(start); printSeq(ts){print}{print(sep)}; print(end)
print(start); printSeq(ts){print(_)}{print(sep)}; print(end)
}
def printRow(ts: List[Tree], sep: String) { printRow(ts, "", sep, "") }
@ -116,11 +117,12 @@ trait TreePrinters { self: SymbolTable =>
case sym => f(sym)
}
private def ifSym(tree: Tree, p: Symbol => Boolean) = symFn(tree, p, false)
private def symNameInternal(tree: Tree, name: Name, decoded: Boolean): String = {
def nameFn(sym: Symbol) = {
val prefix = if (sym.isMixinConstructor) "/*%s*/".format(quotedName(sym.owner.name, decoded)) else ""
prefix + tree.symbol.nameString
val suffix = if (uniqueIds) "#"+sym.id else ""
prefix + tree.symbol.decodedName + suffix
}
symFn(tree, nameFn, quotedName(name, decoded))
}
@ -129,7 +131,7 @@ trait TreePrinters { self: SymbolTable =>
def symName(tree: Tree, name: Name) = symNameInternal(tree, name, false)
def printOpt(prefix: String, tree: Tree) {
if (!tree.isEmpty) { print(prefix); print(tree) }
if (!tree.isEmpty) { print(prefix, tree) }
}
def printModifiers(tree: Tree, mods: Modifiers): Unit = printFlags(
@ -147,20 +149,17 @@ trait TreePrinters { self: SymbolTable =>
}
def printAnnotations(tree: Tree) {
val annots =
if (tree.symbol.hasAssignedAnnotations) tree.symbol.annotations
else tree.asInstanceOf[MemberDef].mods.annotations
val annots = tree.symbol.annotations match {
case Nil => tree.asInstanceOf[MemberDef].mods.annotations
case anns => anns
}
annots foreach (annot => print("@"+annot+" "))
}
def print(str: String) { out.print(str) }
def print(name: Name) { print(quotedName(name)) }
private var currentOwner: Symbol = NoSymbol
private var selectorType: Type = NoType
def printRaw(tree: Tree) {
def printTree(tree: Tree) {
tree match {
case EmptyTree =>
print("<empty>")
@ -173,29 +172,26 @@ trait TreePrinters { self: SymbolTable =>
else if (ifSym(tree, _.isModuleClass)) "object"
else "class"
print(word + " " + symName(tree, name))
print(word, " ", symName(tree, name))
printTypeParams(tparams)
print(if (mods.isDeferred) " <: " else " extends "); print(impl)
print(if (mods.isDeferred) " <: " else " extends ", impl)
case PackageDef(packaged, stats) =>
printAnnotations(tree)
print("package "); print(packaged); printColumn(stats, " {", ";", "}")
print("package ", packaged); printColumn(stats, " {", ";", "}")
case ModuleDef(mods, name, impl) =>
printAnnotations(tree)
printModifiers(tree, mods); print("object " + symName(tree, name))
print(" extends "); print(impl)
printModifiers(tree, mods);
print("object " + symName(tree, name), " extends ", impl)
case ValDef(mods, name, tp, rhs) =>
printAnnotations(tree)
printModifiers(tree, mods)
print(if (mods.isMutable) "var " else "val ")
print(symName(tree, name))
print(if (mods.isMutable) "var " else "val ", symName(tree, name))
printOpt(": ", tp)
if (!mods.isDeferred) {
print(" = ")
if (rhs.isEmpty) print("_") else print(rhs)
}
if (!mods.isDeferred)
print(" = ", if (rhs.isEmpty) "_" else rhs)
case DefDef(mods, name, tparams, vparamss, tp, rhs) =>
printAnnotations(tree)
@ -225,16 +221,12 @@ trait TreePrinters { self: SymbolTable =>
if (isNotRemap(s)) from
else from + "=>" + quotedName(s.rename)
}
print("import "); print(backquotedPath(expr))
print(".")
print("import ", backquotedPath(expr), ".")
selectors match {
case List(s) =>
// If there is just one selector and it is not remapping a name, no braces are needed
if (isNotRemap(s)) {
print(selectorToString(s))
} else {
print("{"); print(selectorToString(s)); print("}")
}
if (isNotRemap(s)) print(selectorToString(s))
else print("{", selectorToString(s), "}")
// If there is more than one selector braces are always needed
case many =>
print(many.map(selectorToString).mkString("{", ", ", "}"))
@ -246,9 +238,9 @@ trait TreePrinters { self: SymbolTable =>
printRow(parents, " with ")
if (!body.isEmpty) {
if (self.name != nme.WILDCARD) {
print(" { "); print(self.name); printOpt(": ", self.tpt); print(" => ")
print(" { ", self.name); printOpt(": ", self.tpt); print(" => ")
} else if (!self.tpt.isEmpty) {
print(" { _ : "); print(self.tpt); print(" => ")
print(" { _ : ", self.tpt, " => ")
} else {
print(" {")
}
@ -276,39 +268,39 @@ trait TreePrinters { self: SymbolTable =>
patConstr(pat).tpe.finalResultType, selectorType, currentOwner))
print("???")
print(pat); printOpt(" if ", guard)
print(" => "); print(body)
print(" => ", body)
case Alternative(trees) =>
printRow(trees, "(", "| ", ")")
case Star(elem) =>
print("("); print(elem); print(")*")
print("(", elem, ")*")
case Bind(name, t) =>
print("("); print(symName(tree, name)); print(" @ "); print(t); print(")")
print("(", symName(tree, name), " @ ", t, ")")
case UnApply(fun, args) =>
print(fun); print(" <unapply> "); printRow(args, "(", ", ", ")")
print(fun, " <unapply> "); printRow(args, "(", ", ", ")")
case ArrayValue(elemtpt, trees) =>
print("Array["); print(elemtpt); printRow(trees, "]{", ", ", "}")
print("Array[", elemtpt); printRow(trees, "]{", ", ", "}")
case Function(vparams, body) =>
print("("); printValueParams(vparams); print(" => "); print(body); print(")")
if (settings.uniqid.value && tree.symbol != null) print("#"+tree.symbol.id)
print("("); printValueParams(vparams); print(" => ", body, ")")
if (uniqueIds && tree.symbol != null) print("#"+tree.symbol.id)
case Assign(lhs, rhs) =>
print(lhs); print(" = "); print(rhs)
print(lhs, " = ", rhs)
case If(cond, thenp, elsep) =>
print("if ("); print(cond); print(")"); indent; println()
print("if (", cond, ")"); indent; println()
print(thenp); undent
if (!elsep.isEmpty) {
println(); print("else"); indent; println(); print(elsep); undent
}
case Return(expr) =>
print("return "); print(expr)
print("return ", expr)
case Try(block, catches, finalizer) =>
print("try "); printBlock(block)
@ -316,13 +308,13 @@ trait TreePrinters { self: SymbolTable =>
printOpt(" finally ", finalizer)
case Throw(expr) =>
print("throw "); print(expr)
print("throw ", expr)
case New(tpe) =>
print("new "); print(tpe)
print("new ", tpe)
case Typed(expr, tp) =>
print("("); print(expr); print(": "); print(tp); print(")")
print("(", expr, ": ", tp, ")")
case TypeApply(fun, targs) =>
print(fun); printRow(targs, "[", ", ", "]")
@ -331,7 +323,7 @@ trait TreePrinters { self: SymbolTable =>
print(fun); printRow(vargs, "(", ", ", ")")
case ApplyDynamic(qual, vargs) =>
print("<apply-dynamic>("); print(qual); print("#"); print(tree.symbol.nameString)
print("<apply-dynamic>(", qual, "#", tree.symbol.nameString)
printRow(vargs, ", (", ", ", "))")
case Super(This(qual), mix) =>
@ -341,8 +333,7 @@ trait TreePrinters { self: SymbolTable =>
print("[" + mix + "]")
case Super(qual, mix) =>
print(qual)
print(".super")
print(qual, ".super")
if (!mix.isEmpty)
print("[" + mix + "]")
@ -354,7 +345,7 @@ trait TreePrinters { self: SymbolTable =>
print(qual)
case Select(qualifier, name) =>
print(backquotedPath(qualifier)); print("."); print(symName(tree, name))
print(backquotedPath(qualifier), ".", symName(tree, name))
case Ident(name) =>
print(symName(tree, name))
@ -363,29 +354,29 @@ trait TreePrinters { self: SymbolTable =>
print(x.escapedStringValue)
case tt: TypeTree =>
if ((tree.tpe eq null) || (settings.Xprintpos.value && tt.original != null)) {
if (tt.original != null) { print("<type: "); print(tt.original); print(">") }
if ((tree.tpe eq null) || (doPrintPositions && tt.original != null)) {
if (tt.original != null) print("<type: ", tt.original, ">")
else print("<type ?>")
} else if ((tree.tpe.typeSymbol ne null) && tree.tpe.typeSymbol.isAnonymousClass) {
print(tree.tpe.typeSymbol.toString())
print(tree.tpe.typeSymbol.toString)
} else {
print(tree.tpe.toString())
print(tree.tpe.toString)
}
case Annotated(Apply(Select(New(tpt), nme.CONSTRUCTOR), args), tree) =>
def printAnnot() {
print("@"); print(tpt)
print("@", tpt)
if (!args.isEmpty)
printRow(args, "(", ",", ")")
}
if (tree.isType) { print(tree); print(" "); printAnnot() }
else { print(tree); print(": "); printAnnot() }
print(tree, if (tree.isType) " " else ": ")
printAnnot()
case SingletonTypeTree(ref) =>
print(ref); print(".type")
print(ref, ".type")
case SelectFromTypeTree(qualifier, selector) =>
print(qualifier); print("#"); print(symName(tree, selector))
print(qualifier, "#", symName(tree, selector))
case CompoundTypeTree(templ) =>
print(templ)
@ -408,34 +399,26 @@ trait TreePrinters { self: SymbolTable =>
case tree =>
xprintRaw(this, tree)
xprintTree(this, tree)
}
if (settings.printtypes.value && tree.isTerm && !tree.isEmpty) {
print("{"); print(if (tree.tpe eq null) "<null>" else tree.tpe.toString()); print("}")
if (typesPrinted && tree.isTerm && !tree.isEmpty) {
print("{", if (tree.tpe eq null) "<null>" else tree.tpe.toString, "}")
}
}
def print(tree: Tree) {
printPosition(tree)
printRaw(
//nsc if (tree.isDef && tree.symbol != NoSymbol && tree.symbol.isInitialized) {
//nsc tree match {
//nsc case ClassDef(_, _, _, impl @ Template(ps, emptyValDef, body))
//nsc if (tree.symbol.thisSym != tree.symbol) =>
//nsc ClassDef(tree.symbol, Template(ps, ValDef(tree.symbol.thisSym), body))
//nsc case ClassDef(_, _, _, impl) => ClassDef(tree.symbol, impl)
//nsc case ModuleDef(_, _, impl) => ModuleDef(tree.symbol, impl)
//nsc case ValDef(_, _, _, rhs) => ValDef(tree.symbol, rhs)
//nsc case DefDef(_, _, _, vparamss, _, rhs) => DefDef(tree.symbol, vparamss, rhs)
//nsc case TypeDef(_, _, _, rhs) => TypeDef(tree.symbol, rhs)
//nsc case _ => tree
//nsc }
//nsc } else
tree)
def print(args: Any*): Unit = args foreach {
case tree: Tree =>
printPosition(tree)
printTree(tree)
case name: Name =>
print(quotedName(name))
case arg =>
out.print(arg.toString)
}
}
def xprintRaw(treePrinter: TreePrinter, tree: Tree) =
/** Hook for extensions */
def xprintTree(treePrinter: TreePrinter, tree: Tree) =
treePrinter.print(tree.productPrefix+tree.productIterator.mkString("(", ", ", ")"))
def newTreePrinter(writer: PrintWriter): TreePrinter = new TreePrinter(writer)

View File

@ -6,7 +6,6 @@
package scala.reflect
package internal
import java.io.{ PrintWriter, StringWriter }
import Flags._
import api.Modifier
@ -96,20 +95,19 @@ trait Trees extends api.Trees { self: SymbolTable =>
lazy val NoMods = Modifiers(0)
// --- extension methods --------------------------------------------------------
override def show(tree: Tree): String = {
val buffer = new StringWriter()
val printer = newTreePrinter(new PrintWriter(buffer))
printer.print(tree)
printer.flush()
buffer.toString
}
implicit def treeOps(tree: Tree): TreeOps = new TreeOps(tree)
class TreeOps(tree: Tree) {
def isErroneous = (tree.tpe ne null) && tree.tpe.isErroneous
def isTyped = (tree.tpe ne null) && !tree.tpe.isErroneous
/** Sets the tree's type to the result of the given function.
* If the type is null, it remains null - the function is not called.
*/
def modifyType(f: Type => Type): Tree =
if (tree.tpe eq null) tree
else tree setType f(tree.tpe)
/** If `pf` is defined for a given subtree, call super.traverse(pf(tree)),
* otherwise super.traverse(tree).
@ -248,12 +246,6 @@ trait Trees extends api.Trees { self: SymbolTable =>
def This(sym: Symbol): Tree = This(sym.name.toTypeName) setSymbol sym
def Select(qualifier: Tree, sym: Symbol): Select =
Select(qualifier, sym.name) setSymbol sym
def Ident(sym: Symbol): Ident =
Ident(sym.name) setSymbol sym
/** Block factory that flattens directly nested blocks.
*/
def Block(stats: Tree*): Block = stats match {
@ -338,37 +330,26 @@ trait Trees extends api.Trees { self: SymbolTable =>
override def toString = substituterString("Symbol", "Tree", from, to)
}
class TreeTypeSubstituter(val from: List[Symbol], val to: List[Type]) extends Traverser {
val typeSubst = new SubstTypeMap(from, to)
def isEmpty = from.isEmpty && to.isEmpty
class TypeMapTreeSubstituter(val typeMap: TypeMap) extends Traverser {
override def traverse(tree: Tree) {
if (tree.tpe ne null) tree.tpe = typeSubst(tree.tpe)
if (tree.isDef) {
val sym = tree.symbol
val info1 = typeSubst(sym.info)
if (info1 ne sym.info) sym.setInfo(info1)
}
if (tree.tpe ne null)
tree.tpe = typeMap(tree.tpe)
if (tree.isDef)
tree.symbol modifyInfo typeMap
super.traverse(tree)
}
override def apply[T <: Tree](tree: T): T = super.apply(tree.duplicate)
}
class TreeTypeSubstituter(val from: List[Symbol], val to: List[Type]) extends TypeMapTreeSubstituter(new SubstTypeMap(from, to)) {
def isEmpty = from.isEmpty && to.isEmpty
override def toString() = "TreeTypeSubstituter("+from+","+to+")"
}
lazy val EmptyTreeTypeSubstituter = new TreeTypeSubstituter(List(), List())
class TreeSymSubstTraverser(val from: List[Symbol], val to: List[Symbol]) extends Traverser {
val subst = new SubstSymMap(from, to)
override def traverse(tree: Tree) {
if (tree.tpe ne null) tree.tpe = subst(tree.tpe)
if (tree.isDef) {
val sym = tree.symbol
val info1 = subst(sym.info)
if (info1 ne sym.info) sym.setInfo(info1)
}
super.traverse(tree)
}
override def apply[T <: Tree](tree: T): T = super.apply(tree.duplicate)
class TreeSymSubstTraverser(val from: List[Symbol], val to: List[Symbol]) extends TypeMapTreeSubstituter(new SubstSymMap(from, to)) {
override def toString() = "TreeSymSubstTraverser/" + substituterString("Symbol", "Symbol", from, to)
}

View File

@ -234,9 +234,18 @@ trait Types extends api.Types { self: SymbolTable =>
super.tpe_=(NoType)
override def tpe_=(t: Type) = if (t != NoType) throw new UnsupportedOperationException("tpe_=("+t+") inapplicable for <empty>")
}
abstract class AbsTypeImpl extends AbsType { this: Type =>
def declaration(name: Name): Symbol = decl(name)
def nonPrivateDeclaration(name: Name): Symbol = nonPrivateDecl(name)
def allDeclarations = decls
def allMembers = members
def typeArguments = typeArgs
def erasedType = transformedType(this)
}
/** The base class for all types */
abstract class Type extends AbsType with Annotatable[Type] {
abstract class Type extends AbsTypeImpl with Annotatable[Type] {
/** Types for which asSeenFrom always is the identity, no matter what
* prefix or owner.
*/
@ -568,11 +577,8 @@ trait Types extends api.Types { self: SymbolTable =>
val tp1 = existentialAbstraction(m.capturedParams, tp)
val result: Type =
if (m.capturedSkolems.isEmpty) tp1
else {
val captured = cloneSymbols(m.capturedSkolems)
captured foreach (_ setFlag CAPTURED)
tp1.substSym(m.capturedSkolems, captured)
}
else deriveType(m.capturedSkolems, _.cloneSymbol setFlag CAPTURED)(tp1)
stopTimer(asSeenFromNanos, start)
result
}
@ -630,9 +636,15 @@ trait Types extends api.Types { self: SymbolTable =>
*/
def substThis(from: Symbol, to: Type): Type =
new SubstThisMap(from, to) apply this
def substThis(from: Symbol, to: Symbol): Type =
substThis(from, to.thisType)
def substSuper(from: Type, to: Type): Type =
new SubstSuperMap(from, to) apply this
/** Performs both substThis and substSym in one traversal.
*/
def substThisAndSym(from: Symbol, to: Type, symsFrom: List[Symbol], symsTo: List[Symbol]): Type = {
if (symsFrom eq symsTo) substThis(from, to)
else new SubstThisAndSymMap(from, to, symsFrom, symsTo) apply this
}
/** Returns all parts of this type which satisfy predicate `p` */
def filter(p: Type => Boolean): List[Type] = new FilterTypeCollector(p).collect(this).toList
@ -1010,11 +1022,10 @@ trait Types extends api.Types { self: SymbolTable =>
// overrides these.
def annotations: List[AnnotationInfo] = Nil
def withoutAnnotations: Type = this
def filterAnnotations(p: AnnotationInfo => Boolean): Type = this
def setAnnotations(annots: List[AnnotationInfo]): Type = annotatedType(annots, this)
def withAnnotations(annots: List[AnnotationInfo]): Type = annotatedType(annots, this)
final def withAnnotation(annot: AnnotationInfo): Type = withAnnotations(List(annot))
/** Remove any annotations from this type and from any
* types embedded in this type. */
def stripAnnotations = StripAnnotationsMap(this)
@ -1063,7 +1074,7 @@ trait Types extends api.Types { self: SymbolTable =>
/** A base class for types that represent a single value
* (single-types and this-types).
*/
abstract class SingletonType extends SubType with SimpleTypeProxy {
abstract class SingletonType extends SubType with SimpleTypeProxy with AbsSingletonType {
def supertype = underlying
override def isTrivial = false
override def isStable = true
@ -1113,7 +1124,16 @@ trait Types extends api.Types { self: SymbolTable =>
// override def isNullable: Boolean = true
override def kind = "WildcardType"
}
/** BoundedWildcardTypes, used only during type inference, are created in
* two places that I can find:
*
* 1. If the expected type of an expression is an existential type,
* its hidden symbols are replaced with bounded wildcards.
* 2. When an implicit conversion is being sought based in part on
* the name of a method in the converted type, a HasMethodMatching
* type is created: a MethodType with parameters typed as
* BoundedWildcardTypes.
*/
case class BoundedWildcardType(override val bounds: TypeBounds) extends Type {
override def isWildcard = true
override def safeToString: String = "?" + bounds
@ -1435,7 +1455,7 @@ trait Types extends api.Types { self: SymbolTable =>
override def isHigherKinded = (
parents.nonEmpty &&
(parents forall (_.isHigherKinded)) &&
!phase.erasedTypes // @MO to AM: please check this class!
!phase.erasedTypes
)
override def typeParams =
@ -1720,7 +1740,6 @@ trait Types extends api.Types { self: SymbolTable =>
private var relativeInfoCache: Type = _
private var normalized: Type = null
override def isStable: Boolean = {
sym == NothingClass ||
@ -1852,6 +1871,7 @@ A type's typeSymbol should never be inspected directly.
override def typeArgs: List[Type] = args
private def typeArgsOrDummies = if (!isHigherKinded) args else dummyArgs
// def hasFishyArgs = args == dummyArgs
private def argsMatchTypeParams = sameLength(sym.info.typeParams, args)
// @MAT was typeSymbol.unsafeTypeParams, but typeSymbol normalizes now
private def typeParamsDirect =
@ -1879,7 +1899,7 @@ A type's typeSymbol should never be inspected directly.
// A reference (in a Scala program) to a type that has type
// parameters, but where the reference does not include type
// arguments. Note that it doesn't matter whether the symbol refers
// to a java or scala symbol, it does matter whether it occurs in
// to a java or scala symbol, but it does matter whether it occurs in
// java or scala code. TypeRefs w/o type params that occur in java
// signatures/code are considered raw types, and are represented as
// existential types.
@ -1887,32 +1907,27 @@ A type's typeSymbol should never be inspected directly.
override def instantiateTypeParams(formals: List[Symbol], actuals: List[Type]): Type =
if (isHigherKinded) {
val substTps = formals.intersect(typeParams)
if (sameLength(substTps, typeParams))
if (sameLength(formals intersect typeParams, typeParams))
copyTypeRef(this, pre, sym, actuals)
else if (sameLength(formals, actuals)) // partial application (needed in infer when bunching type arguments from classes and methods together)
copyTypeRef(this, pre, sym, dummyArgs).subst(formals, actuals)
else ErrorType
// partial application (needed in infer when bunching type arguments from classes and methods together)
else
copyTypeRef(this, pre, sym, dummyArgs).instantiateTypeParams(formals, actuals)
}
else
super.instantiateTypeParams(formals, actuals)
/** @pre: sym.info.typeParams.length == typeArgs.length */
/** @pre: argsMatchTypeParams */
@inline private def betaReduce: Type = {
if (settings.debug.value)
assert(sym.info.typeParams.length == typeArgs.length, sym.info.typeParams + " and " + typeArgs)
// isHKSubType0 introduces synthetic type params so that
// betaReduce can first apply sym.info to typeArgs before calling
// asSeenFrom. asSeenFrom then skips synthetic type params, which
// are used to reduce HO subtyping to first-order subtyping, but
// which can't be instantiated from the given prefix and class.
transform(sym.info.resultType)
//
// this crashes pos/depmet_implicit_tpbetareduce.scala
// appliedType(sym.info, typeArgs).asSeenFrom(pre, sym.owner)
}
private def isBetaReducible = sym.isAliasType && argsMatchTypeParams
// @M: initialize (by sym.info call) needed (see test/files/pos/ticket0137.scala)
@inline private def etaExpand: Type = {
@ -1921,22 +1936,16 @@ A type's typeSymbol should never be inspected directly.
else typeFunAnon(tpars, copyTypeRef(this, pre, sym, tpars map (_.tpeHK))) // todo: also beta-reduce?
}
override def dealias: Type =
if (sym.isAliasType && sameLength(sym.info.typeParams, args)) {
betaReduce.dealias
} else this
override def dealias = if (isBetaReducible) betaReduce.dealias else this
private def normalize0: Type =
private def normalize0: Type = (
if (pre eq WildcardType) WildcardType // arises when argument-dependent types are approximated (see def depoly in implicits)
else if (isHigherKinded) etaExpand // eta-expand, subtyping relies on eta-expansion of higher-kinded types
else if (sym.isAliasType && sameLength(sym.info.typeParams, args))
betaReduce.normalize // beta-reduce, but don't do partial application -- cycles have been checked in typeRef
else if (sym.isRefinementClass)
sym.info.normalize // I think this is okay, but see #1241 (r12414), #2208, and typedTypeConstructor in Typers
else {
if(sym.isAliasType) ErrorType //println("!!error: "+(pre, sym, sym.info, sym.info.typeParams, args))
else super.normalize
}
else if (isBetaReducible) betaReduce.normalize // beta-reduce, but don't do partial application -- cycles have been checked in typeRef
else if (sym.isRefinementClass) sym.info.normalize // I think this is okay, but see #1241 (r12414), #2208, and typedTypeConstructor in Typers
else if (sym.isAliasType) ErrorType //println("!!error: "+(pre, sym, sym.info, sym.info.typeParams, args))
else super.normalize
)
// TODO: test case that is compiled in a specific order and in different runs
override def normalize: Type = {
@ -2062,7 +2071,7 @@ A type's typeSymbol should never be inspected directly.
sym.skipPackageObject.fullName + "."
else if (isStable && nme.isSingletonName(sym.name))
nme.dropSingletonName(sym.name) + "."
else
else
super.prefixString
)
override def kind = "TypeRef"
@ -2119,7 +2128,7 @@ A type's typeSymbol should never be inspected directly.
override def safeToString = paramString(this) + resultType
override def cloneInfo(owner: Symbol) = {
val vparams = cloneSymbols(params, owner)
val vparams = cloneSymbolsAtOwner(params, owner)
copyMethodType(this, vparams, resultType.substSym(params, vparams).cloneInfo(owner))
}
@ -2199,7 +2208,7 @@ A type's typeSymbol should never be inspected directly.
override def safeToString = typeParamsString(this) + resultType
override def cloneInfo(owner: Symbol) = {
val tparams = cloneSymbols(typeParams, owner)
val tparams = cloneSymbolsAtOwner(typeParams, owner)
PolyType(tparams, resultType.substSym(typeParams, tparams).cloneInfo(owner))
}
@ -2244,20 +2253,8 @@ A type's typeSymbol should never be inspected directly.
override def baseTypeSeq = underlying.baseTypeSeq map maybeRewrap
override def isHigherKinded = false
override def skolemizeExistential(owner: Symbol, origin: AnyRef) = {
def mkSkolem(tparam: Symbol): Symbol = {
val skolem = new TypeSkolem(
if (owner == NoSymbol) tparam.owner else owner,
tparam.pos, tparam.name.toTypeName, origin)
skolem.setInfo(tparam.info.cloneInfo(skolem))
.setFlag(tparam.flags | EXISTENTIAL)
.resetFlag(PARAM)
}
val skolems = quantified map mkSkolem
for (skolem <- skolems)
skolem setInfo skolem.info.substSym(quantified, skolems)
underlying.substSym(quantified, skolems)
}
override def skolemizeExistential(owner: Symbol, origin: AnyRef) =
deriveType(quantified, tparam => newExistentialSkolem(tparam, owner orElse tparam.owner, origin))(underlying)
private def wildcardArgsString(available: Set[Symbol], args: List[Type]): List[String] = args match {
case TypeRef(_, sym, _) :: args1 if (available contains sym) =>
@ -2288,10 +2285,8 @@ A type's typeSymbol should never be inspected directly.
if (settings.explaintypes.value) "("+str+")" else str
}
override def cloneInfo(owner: Symbol) = {
val tparams = cloneSymbols(quantified, owner)
ExistentialType(tparams, underlying.substSym(quantified, tparams))
}
override def cloneInfo(owner: Symbol) =
createFromClonedSymbolsAtOwner(quantified, owner, underlying)(ExistentialType(_, _))
override def atOwner(owner: Symbol) =
if (quantified exists (_.owner != owner)) cloneInfo(owner) else this
@ -2360,6 +2355,16 @@ A type's typeSymbol should never be inspected directly.
}
}
// Not used yet.
object HasTypeParams {
def unapply(tp: Type): Option[(List[Symbol], Type)] = tp match {
case AnnotatedType(_, tp, _) => unapply(tp)
case ExistentialType(tparams, qtpe) => Some((tparams, qtpe))
case PolyType(tparams, restpe) => Some((tparams, restpe))
case _ => None
}
}
//@M
// a TypeVar used to be a case class with only an origin and a constr
// then, constr became mutable (to support UndoLog, I guess),
@ -2709,8 +2714,14 @@ A type's typeSymbol should never be inspected directly.
override def safeToString = annotations.mkString(underlying + " @", " @", "")
override def filterAnnotations(p: AnnotationInfo => Boolean): Type = {
val (yes, no) = annotations partition p
if (yes.isEmpty) underlying
else if (no.isEmpty) this
else copy(annotations = yes)
}
override def setAnnotations(annots: List[AnnotationInfo]): Type =
if (annots.isEmpty) withoutAnnotations
if (annots.isEmpty) underlying
else copy(annotations = annots)
/** Add a number of annotations to this type */
@ -2718,7 +2729,11 @@ A type's typeSymbol should never be inspected directly.
if (annots.isEmpty) this
else copy(annots ::: this.annotations)
/** Remove any annotations from this type */
/** Remove any annotations from this type.
* TODO - is it allowed to nest AnnotatedTypes? If not then let's enforce
* that at creation. At the moment if they do ever turn up nested this
* recursively calls withoutAnnotations.
*/
override def withoutAnnotations = underlying.withoutAnnotations
/** Set the self symbol */
@ -2811,16 +2826,8 @@ A type's typeSymbol should never be inspected directly.
/** Rebind symbol `sym` to an overriding member in type `pre`. */
private def rebind(pre: Type, sym: Symbol): Symbol = {
val owner = sym.owner
if (owner.isClass && owner != pre.typeSymbol && !sym.isEffectivelyFinal && !sym.isClass) {
//Console.println("rebind "+pre+" "+sym)//DEBUG
val rebind = pre.nonPrivateMember(sym.name).suchThat(sym => sym.isType || sym.isStable)
if (rebind == NoSymbol) sym
else {
// Console.println("rebound "+pre+" "+sym+" to "+rebind)//DEBUG
rebind
}
} else sym
if (!sym.isOverridableMember || sym.owner == pre.typeSymbol) sym
else pre.nonPrivateMember(sym.name).suchThat(sym => sym.isType || sym.isStable) orElse sym
}
/** Convert a `super` prefix to a this-type if `sym` is abstract or final. */
@ -2878,7 +2885,8 @@ A type's typeSymbol should never be inspected directly.
val syms2 = result.decls.toList
val resultThis = result.typeSymbol.thisType
for (sym <- syms2)
sym.setInfo(sym.info.substThis(original.typeSymbol, resultThis).substSym(syms1, syms2))
sym modifyInfo (_ substThisAndSym(original.typeSymbol, resultThis, syms1, syms2))
result
}
@ -2886,57 +2894,44 @@ A type's typeSymbol should never be inspected directly.
* todo: see how we can clean this up a bit
*/
def typeRef(pre: Type, sym: Symbol, args: List[Type]): Type = {
// type alias selections are rebound in TypeMap ("coevolved", actually -- see #3731)
// e.g., when type parameters that are referenced by the alias are instantiated in
// the prefix. See pos/depmet_rebind_typealias.
def rebindTR(pre: Type, sym: Symbol) =
if (sym.isAbstractType) rebind(pre, sym) else sym
// type alias selections are rebound in TypeMap ("coevolved",
// actually -- see #3731) e.g., when type parameters that are
// referenced by the alias are instantiated in the prefix. See
// pos/depmet_rebind_typealias.
val sym1 = rebindTR(pre, sym)
val sym1 = if (sym.isAbstractType) rebind(pre, sym) else sym
// don't expand cyclical type alias
// we require that object is initialized, thus info.typeParams instead of typeParams.
if (sym1.isAliasType && sameLength(sym1.info.typeParams, args)) {
if (sym1.lockOK) TypeRef(pre, sym1, args) // don't expand type alias (cycles checked by lockOK)
else throw new TypeError("illegal cyclic reference involving " + sym1)
}
else {
val pre1 = removeSuper(pre, sym1)
if (pre1 ne pre)
typeRef(pre1, rebindTR(pre1, sym1), args)
else pre match {
case _: CompoundType if sym1.isClass =>
// sharpen prefix so that it is maximal and still contains the class.
pre.parents.reverse dropWhile (_.member(sym1.name) != sym1) match {
case Nil => TypeRef(pre, sym1, args)
case parent :: _ => typeRef(parent, sym1, args)
}
case _ =>
TypeRef(pre, sym1, args)
}
if (sym1.isAliasType && sameLength(sym1.info.typeParams, args) && !sym1.lockOK)
throw new TypeError("illegal cyclic reference involving " + sym1)
val pre1 = pre match {
case x: SuperType if sym1.isEffectivelyFinal || sym1.isDeferred =>
x.thistpe
case _: CompoundType if sym1.isClass =>
// sharpen prefix so that it is maximal and still contains the class.
pre.parents.reverse dropWhile (_.member(sym1.name) != sym1) match {
case Nil => pre
case parent :: _ => parent
}
case _ => pre
}
if (pre eq pre1) TypeRef(pre, sym1, args)
else if (sym1.isAbstractType && !sym1.isClass) typeRef(pre1, rebind(pre1, sym1), args)
else typeRef(pre1, sym1, args)
}
// Optimization to avoid creating unnecessary new typerefs.
def copyTypeRef(tp: Type, pre: Type, sym: Symbol, args: List[Type]): Type = tp match {
case TypeRef(pre0, sym0, args0) =>
if ((pre == pre0) && (sym.name == sym0.name)) {
case TypeRef(pre0, sym0, _) if pre == pre0 && sym0.name == sym.name =>
if (sym.isAliasType && sameLength(sym.info.typeParams, args) && !sym.lockOK)
throw new TypeError("illegal cyclic reference involving " + sym)
val sym1 = sym
// we require that object is initialized, thus info.typeParams instead of typeParams.
if (sym1.isAliasType && sameLength(sym1.info.typeParams, args)) {
if (sym1.lockOK) TypeRef(pre, sym1, args) // don't expand type alias (cycles checked by lockOK)
else throw new TypeError("illegal cyclic reference involving " + sym1)
}
else {
TypeRef(pre, sym1, args)
}
} else
typeRef(pre, sym, args)
TypeRef(pre, sym, args)
case _ =>
typeRef(pre, sym, args)
}
/** The canonical creator for implicit method types */
def JavaMethodType(params: List[Symbol], resultType: Type): JavaMethodType =
new JavaMethodType(params, resultType) // don't unique this!
@ -2944,7 +2939,7 @@ A type's typeSymbol should never be inspected directly.
/** Create a new MethodType of the same class as tp, i.e. keep JavaMethodType */
def copyMethodType(tp: Type, params: List[Symbol], restpe: Type): Type = tp match {
case _: JavaMethodType => JavaMethodType(params, restpe)
case _ => MethodType(params, restpe)
case _ => MethodType(params, restpe)
}
/** A creator for intersection type where intersections of a single type are
@ -3000,6 +2995,11 @@ A type's typeSymbol should never be inspected directly.
/** A creator for type parameterizations that strips empty type parameter lists.
* Use this factory method to indicate the type has kind * (it's a polymorphic value)
* until we start tracking explicit kinds equivalent to typeFun (except that the latter requires tparams nonEmpty).
*
* PP to AM: I've co-opted this for where I know tparams may well be empty, and
* expecting to get back `tpe` in such cases. Re being "forgiving" below,
* can we instead say this is the canonical creator for polyTypes which
* may or may not be poly? (It filched the standard "canonical creator" name.)
*/
def polyType(tparams: List[Symbol], tpe: Type): Type =
if (tparams nonEmpty) typeFun(tparams, tpe)
@ -3481,7 +3481,7 @@ A type's typeSymbol should never be inspected directly.
result ne sym.info
}
// map is not the identity --> do cloning properly
if (change) cloneSymbols(origSyms) map (s => s setInfo this(s.info))
if (change) cloneSymbolsAndModify(origSyms, TypeMap.this)
// fast path in case nothing changes due to map
else origSyms
}
@ -3557,8 +3557,7 @@ A type's typeSymbol should never be inspected directly.
val eparams = for ((tparam, i) <- tparams.zipWithIndex) yield {
clazz.newExistential(clazz.pos, newTypeName("?"+i)).setInfo(tparam.info.bounds)
}
for (tparam <- eparams) tparam setInfo tparam.info.substSym(tparams, eparams)
eparams
eparams map (_ substInfo (tparams, eparams))
}
// note: it's important to write the two tests in this order,
@ -3781,14 +3780,11 @@ A type's typeSymbol should never be inspected directly.
protected def renameBoundSyms(tp: Type): Type = tp match {
case MethodType(ps, restp) =>
val ps1 = cloneSymbols(ps)
copyMethodType(tp, ps1, renameBoundSyms(restp.substSym(ps, ps1)))
createFromClonedSymbols(ps, restp)((ps1, tp1) => copyMethodType(tp, ps1, renameBoundSyms(tp1)))
case PolyType(bs, restp) =>
val bs1 = cloneSymbols(bs)
PolyType(bs1, renameBoundSyms(restp.substSym(bs, bs1)))
createFromClonedSymbols(bs, restp)((ps1, tp1) => PolyType(ps1, renameBoundSyms(tp1)))
case ExistentialType(bs, restp) =>
val bs1 = cloneSymbols(bs)
ExistentialType(bs1, restp.substSym(bs, bs1))
createFromClonedSymbols(bs, restp)(ExistentialType(_, _))
case _ =>
tp
}
@ -3911,9 +3907,12 @@ A type's typeSymbol should never be inspected directly.
case _ => mapOver(tp)
}
}
class SubstSuperMap(from: Type, to: Type) extends TypeMap {
def apply(tp: Type): Type = if (tp eq from) to else mapOver(tp)
class SubstThisAndSymMap(fromThis: Symbol, toThis: Type, fromSyms: List[Symbol], toSyms: List[Symbol])
extends SubstSymMap(fromSyms, toSyms) {
override def apply(tp: Type): Type = tp match {
case ThisType(sym) if sym == fromThis => apply(toThis)
case _ => super.apply(tp)
}
}
class SubstWildcardMap(from: List[Symbol]) extends TypeMap {
@ -4124,29 +4123,41 @@ A type's typeSymbol should never be inspected directly.
}
}
/** A map to compute the most deeply nested owner that contains all the symbols
/** The most deeply nested owner that contains all the symbols
* of thistype or prefixless typerefs/singletype occurrences in given type.
*/
object commonOwnerMap extends TypeMap {
var result: Symbol = _
def init() = { result = NoSymbol }
def apply(tp: Type): Type = {
assert(tp ne null)
tp.normalize match {
case ThisType(sym) =>
register(sym)
case TypeRef(NoPrefix, sym, args) =>
register(sym.owner); args foreach apply
case SingleType(NoPrefix, sym) =>
register(sym.owner)
case _ =>
mapOver(tp)
}
tp
private def commonOwner(t: Type): Symbol = commonOwner(t :: Nil)
/** The most deeply nested owner that contains all the symbols
* of thistype or prefixless typerefs/singletype occurrences in given list
* of types.
*/
private def commonOwner(tps: List[Type]): Symbol = {
if (tps.isEmpty) NoSymbol
else {
commonOwnerMap.result = null
tps foreach (commonOwnerMap traverse _)
val result = if (commonOwnerMap.result ne null) commonOwnerMap.result else NoSymbol
debuglog(tps.mkString("commonOwner(", ", ", ") == " + result))
result
}
}
private object commonOwnerMap extends TypeTraverser {
var result: Symbol = _
private def register(sym: Symbol) {
while (result != NoSymbol && sym != result && !(sym isNestedIn result))
result = result.owner;
// First considered type is the trivial result.
if ((result eq null) || (sym eq NoSymbol))
result = sym
else
while ((result ne NoSymbol) && (result ne sym) && !(sym isNestedIn result))
result = result.owner
}
def traverse(tp: Type) = tp.normalize match {
case ThisType(sym) => register(sym)
case TypeRef(NoPrefix, sym, args) => register(sym.owner) ; args foreach traverse
case SingleType(NoPrefix, sym) => register(sym.owner)
case _ => mapOver(tp)
}
}
@ -4606,7 +4617,7 @@ A type's typeSymbol should never be inspected directly.
sym2 =>
var e1 = s1.lookupEntry(sym2.name)
(e1 ne null) && {
val substSym = sym2.info.substThis(sym2.owner, e1.sym.owner.thisType)
val substSym = sym2.info.substThis(sym2.owner, e1.sym.owner)
var isEqual = false
while (!isEqual && (e1 ne null)) {
isEqual = e1.sym.info =:= substSym
@ -5636,7 +5647,7 @@ A type's typeSymbol should never be inspected directly.
for (sym <- lubBase.nonPrivateMembers) {
// add a refinement symbol for all non-class members of lubBase
// which are refined by every type in ts.
if (!sym.isClass && !sym.isConstructor && (narrowts forall (t => refines(t, sym))))
if (!sym.isClass && !sym.isConstructor && !isGetClass(sym) && (narrowts forall (t => refines(t, sym))))
try {
val lsym = lubsym(sym)
if (lsym != NoSymbol) addMember(lubThisType, lubRefined, lubsym(sym))
@ -5823,26 +5834,6 @@ A type's typeSymbol should never be inspected directly.
if (ts exists (_.isNotNull)) res.notNull else res
}
/** The most deeply nested owner that contains all the symbols
* of thistype or prefixless typerefs/singletype occurrences in given type.
*/
private def commonOwner(t: Type): Symbol = {
commonOwnerMap.init
commonOwnerMap.apply(t)
commonOwnerMap.result
}
/** The most deeply nested owner that contains all the symbols
* of thistype or prefixless typerefs/singletype occurrences in given list
* of types.
*/
private def commonOwner(tps: List[Type]): Symbol = {
// debuglog("computing common owner of types " + tps)//DEBUG
commonOwnerMap.init
tps foreach { tp => commonOwnerMap.apply(tp); () }
commonOwnerMap.result
}
/** Compute lub (if `variance == 1`) or glb (if `variance == -1`) of given list
* of types `tps`. All types in `tps` are typerefs or singletypes
* with the same symbol.

View File

@ -833,16 +833,26 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
def newLazyTypeRef(i: Int): LazyType = new LazyTypeRef(i)
def newLazyTypeRefAndAlias(i: Int, j: Int): LazyType = new LazyTypeRefAndAlias(i, j)
/** Convert to a type error, that is printed gracefully instead of crashing.
*
* Similar in intent to what SymbolLoader does (but here we don't have access to
* error reporting, so we rely on the typechecker to report the error).
*/
def toTypeError(e: MissingRequirementError) =
new TypeError(e.msg)
/** A lazy type which when completed returns type at index `i`. */
private class LazyTypeRef(i: Int) extends LazyType {
private val definedAtRunId = currentRunId
private val p = phase
override def complete(sym: Symbol) : Unit = {
override def complete(sym: Symbol) : Unit = try {
val tp = at(i, () => readType(sym.isTerm)) // after NMT_TRANSITION, revert `() => readType(sym.isTerm)` to `readType`
if (p != phase) atPhase(p) (sym setInfo tp)
else sym setInfo tp
if (currentRunId != definedAtRunId) sym.setInfo(adaptToNewRunMap(tp))
} catch {
case e: MissingRequirementError => throw toTypeError(e)
}
override def load(sym: Symbol) { complete(sym) }
}
@ -851,7 +861,7 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
* of completed symbol to symbol at index `j`.
*/
private class LazyTypeRefAndAlias(i: Int, j: Int) extends LazyTypeRef(i) {
override def complete(sym: Symbol) {
override def complete(sym: Symbol) = try {
super.complete(sym)
var alias = at(j, readSymbol)
if (alias.isOverloaded) {
@ -860,6 +870,8 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
}
}
sym.asInstanceOf[TermSymbol].setAlias(alias)
} catch {
case e: MissingRequirementError => throw toTypeError(e)
}
}
}

View File

@ -88,9 +88,8 @@ trait Erasure {
apply(restpe)
case mt @ MethodType(params, restpe) =>
MethodType(
cloneSymbols(params) map (p => p.setInfo(apply(p.tpe))),
cloneSymbolsAndModify(params, ErasureMap.this),
if (restpe.typeSymbol == UnitClass) erasedTypeRef(UnitClass)
// else if (!settings.YdepMethTpes.value) apply(restpe)
// this replaces each typeref that refers to an argument
// by the type `p.tpe` of the actual argument p (p in params)
else apply(mt.resultType(params map (_.tpe))))
@ -247,7 +246,7 @@ trait Erasure {
if (sym.isClassConstructor)
tp match {
case MethodType(params, TypeRef(pre, sym1, args)) =>
MethodType(cloneSymbols(params) map (p => p.setInfo(erasure(sym, p.tpe))),
MethodType(cloneSymbolsAndModify(params, erasure(sym, _)),
typeRef(erasure(sym, pre), sym1, args))
}
else if (sym.name == nme.apply)

View File

@ -4,13 +4,36 @@ package transform
trait Transforms { self: SymbolTable =>
object refChecks extends { val global: Transforms.this.type = self } with RefChecks
object uncurry extends { val global: Transforms.this.type = self } with UnCurry
object erasure extends { val global: Transforms.this.type = self } with Erasure
/** We need to encode laziness by hand here because the three components refChecks, uncurry and erasure
* are overwritten by objects in Global.
* It would be best of objects could override lazy values. See SI-5187.
* In the absence of this, the Lazy functionality should probably be somewhere
* in the standard library. Or is it already?
*/
private class Lazy[T](op: => T) {
private var value: T = _
private var _isDefined = false
def isDefined = _isDefined
def force: T = {
if (!isDefined) { value = op; _isDefined = true }
value
}
}
private val refChecksLazy = new Lazy(new { val global: Transforms.this.type = self } with RefChecks)
private val uncurryLazy = new Lazy(new { val global: Transforms.this.type = self } with UnCurry)
private val erasureLazy = new Lazy(new { val global: Transforms.this.type = self } with Erasure)
def refChecks = refChecksLazy.force
def uncurry = uncurryLazy.force
def erasure = erasureLazy.force
def transformedType(sym: Symbol) =
erasure.transformInfo(sym,
uncurry.transformInfo(sym,
refChecks.transformInfo(sym, sym.info)))
def transformedType(tpe: Type) =
erasure.scalaErasure(uncurry.uncurry(tpe))
}

View File

@ -17,7 +17,7 @@ trait UnCurry {
case _ => false
}
protected val uncurry: TypeMap = new TypeMap {
val uncurry: TypeMap = new TypeMap {
def apply(tp0: Type): Type = {
// tp0.typeSymbolDirect.initialize
val tp = expandAlias(tp0)

View File

@ -64,7 +64,7 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
* ScalaSignature or ScalaLongSignature annotation.
*/
def unpickleClass(clazz: Symbol, module: Symbol, jclazz: jClass[_]): Unit = {
def markAbsent(tpe: Type) = List(clazz, module, module.moduleClass) foreach (_ setInfo tpe)
def markAbsent(tpe: Type) = setAllInfos(clazz, module, tpe)
def handleError(ex: Exception) = {
markAbsent(ErrorType)
if (settings.debug.value) ex.printStackTrace()
@ -126,7 +126,7 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
private class TypeParamCompleter(jtvar: jTypeVariable[_ <: GenericDeclaration]) extends LazyType {
override def load(sym: Symbol) = complete(sym)
override def complete(sym: Symbol) = {
sym setInfo TypeBounds(NothingClass.tpe, glb(jtvar.getBounds.toList map typeToScala map objToAny))
sym setInfo TypeBounds.upper(glb(jtvar.getBounds.toList map typeToScala map objToAny))
}
}
@ -351,11 +351,12 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
* not available, wrapped from the Java reflection info.
*/
def classToScala(jclazz: jClass[_]): Symbol = classCache.toScala(jclazz) {
if (jclazz.isMemberClass) {
if (jclazz.isMemberClass && !nme.isImplClassName(jclazz.getName)) {
val sym = sOwner(jclazz).info.decl(newTypeName(jclazz.getSimpleName))
assert(sym.isType, sym+"/"+jclazz+"/"+sOwner(jclazz)+"/"+jclazz.getSimpleName)
sym.asInstanceOf[ClassSymbol]
} else if (jclazz.isLocalClass) { // local classes not preserved by unpickling - treat as Java
} else if (jclazz.isLocalClass || invalidClassName(jclazz.getName)) {
// local classes and implementation classes not preserved by unpickling - treat as Java
jclassAsScala(jclazz)
} else if (jclazz.isArray) {
ArrayClass
@ -455,9 +456,11 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
private def jclassAsScala(jclazz: jClass[_]): Symbol = jclassAsScala(jclazz, sOwner(jclazz))
private def jclassAsScala(jclazz: jClass[_], owner: Symbol): Symbol = {
val clazz = owner.newClass(NoPosition, newTypeName(jclazz.getSimpleName))
val name = newTypeName(jclazz.getSimpleName)
val completer = (clazz: Symbol, module: Symbol) => new FromJavaClassCompleter(clazz, module, jclazz)
val (clazz, module) = createClassModule(owner, name, completer)
classCache enter (jclazz, clazz)
clazz setInfo new FromJavaClassCompleter(clazz, NoSymbol, jclazz)
clazz
}
/**
@ -522,4 +525,4 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
}
}
class ReflectError(msg: String) extends java.lang.Error(msg)
class ReflectError(msg: String) extends java.lang.Error(msg)

View File

@ -71,11 +71,12 @@ trait Loaders { self: SymbolTable =>
(clazz, module)
}
protected def initClassModule(clazz: Symbol, module: Symbol, completer: LazyType) = {
clazz.setInfo(completer)
module.setInfo(completer)
module.moduleClass.setInfo(completer)
protected def setAllInfos(clazz: Symbol, module: Symbol, info: Type) = {
List(clazz, module, module.moduleClass) foreach (_ setInfo info)
}
protected def initClassModule(clazz: Symbol, module: Symbol, completer: LazyType) =
setAllInfos(clazz, module, completer)
/** The type completer for packages.
*/
@ -88,6 +89,9 @@ trait Loaders { self: SymbolTable =>
}
}
/** Is the given name valid for a top-level class? We exclude names with embedded $-signs, because
* these are nested classes or anonymous classes,
*/
def invalidClassName(name: Name) = {
val dp = name pos '$'
0 < dp && dp < (name.length - 1)

View File

@ -38,6 +38,9 @@ class Mirror extends Universe with RuntimeTypes with TreeBuildUtil with ToolBoxe
override def classToType(jclazz: java.lang.Class[_]): Type = typeToScala(jclazz)
override def classToSymbol(jclazz: java.lang.Class[_]): Symbol = classToScala(jclazz)
override def typeToClass(tpe: Type): java.lang.Class[_] = typeToJavaClass(tpe)
override def symbolToClass(sym: Symbol): java.lang.Class[_] = classToJava(sym)
}
object Mirror extends Mirror

View File

@ -5,6 +5,9 @@ import collection.mutable.ListBuffer
trait RuntimeTypes extends Universe with api.RuntimeTypes {
/** To lift path dependent types into reflection, we use InstanceRefSymbols.
* Two of these are equal if they point to the same object reference. Todo: remove
*/
case class InstanceRefSymbol(value: AnyRef) extends TermSymbol(NoSymbol, NoPosition, nme.EMPTY)
object InstanceRefSymbol extends InstanceRefSymbolExtractor

View File

@ -1,12 +1,13 @@
package scala.reflect.runtime
package scala.reflect
package runtime
trait TreeBuildUtil extends Universe {
trait TreeBuildUtil extends Universe with api.TreeBuildUtil {
def staticClass(name: String): Symbol = definitions.getClass(newTypeName(name))
def staticModule(name: String): Symbol = definitions.getModule(newTermName(name))
def staticClass(fullname: String): Symbol = definitions.getClass(newTypeName(fullname))
def staticModule(fullname: String): Symbol = definitions.getModule(newTermName(fullname))
def thisModuleType(name: String) =
definitions.getModule(name).moduleClass.thisType
def thisModuleType(fullname: String) =
definitions.getModule(fullname).moduleClass.thisType
/** Selects type symbol with given name from the defined members of prefix type
*/
@ -40,9 +41,9 @@ trait TreeBuildUtil extends Universe {
selectIn(owner.info, idx)
}
def freeVar(name: String, info: Type, value: Any) = new FreeVar(name, info, value)
def newScopeWith(decls: List[Symbol]) = new Scope(decls)
def modifiersFromInternalFlags(flags: Long, privateWithin: Name, annotations: List[Tree]): Modifiers =
Modifiers(flags, privateWithin, annotations)
}

View File

@ -8,7 +8,7 @@ import internal.{SomePhase, NoPhase, Phase, TreeGen}
* It also provides methods to go from Java members to Scala members,
* using the code in JavaConversions.
*/
class Universe extends SymbolTable with internal.transform.Transforms {
class Universe extends SymbolTable {
type AbstractFileType = AbstractFile

View File

@ -8,6 +8,11 @@
package scala.tools.ant
import org.apache.tools.ant.Project
import scala.tools.nsc.Settings
import scala.tools.nsc.settings.FscSettings
/** An Ant task to compile with the fast Scala compiler (`fsc`).
*
* In addition to the attributes shared with the `Scalac` task, this task
@ -15,6 +20,8 @@ package scala.tools.ant
* - `reset`
* - `server`
* - `shutdown`
* - `ipv4`
* - `maxIdle`
*
* @author Stephane Micheloud
*/
@ -26,6 +33,10 @@ class FastScalac extends Scalac {
private var shutdownServer: Boolean = false
private var useIPv4: Boolean = false
private var idleMinutes: Option[Int] = None
/*============================================================================*\
** Properties setters **
\*============================================================================*/
@ -48,64 +59,95 @@ class FastScalac extends Scalac {
*/
def setShutdown(input: Boolean) { shutdownServer = input }
/** Sets the `ipv4` attribute. Used by [[http://ant.apache.org Ant]].
*
* @param input The value for `ipv4`.
*/
def setIPv4(input: Boolean) { useIPv4 = input }
/** Sets the `maxIdle` attribute. Used by [[http://ant.apache.org Ant]].
*
* @param input The value for `maxIdle`.
*/
def setMaxIdle(input: Int) { if (0 <= input) idleMinutes = Some(input) }
/*============================================================================*\
** The execute method **
\*============================================================================*/
override protected def newSettings(error: String=>Unit): Settings =
new FscSettings(error)
/** Performs the compilation. */
override def execute() = {
override def execute() {
val (settings, sourceFiles, javaOnly) = initialize
val s = settings
if (sourceFiles.isEmpty || javaOnly)
return
if (!sourceFiles.isEmpty && !javaOnly) {
def trim(xs: List[String]) = xs filter (x => x.length > 0)
val reset = settings.BooleanSetting("-reset", "Reset compile server caches")
val shutdown = settings.BooleanSetting("-shutdown", "Shutdown compile server")
// initialize fsc specific settings
val s = settings.asInstanceOf[FscSettings] // safe (newSettings)
s.reset.value = resetCaches
if (!serverAddr.isEmpty) s.server.value = serverAddr.get
s.shutdown.value = shutdownServer
s.preferIPv4.value = useIPv4
if (!idleMinutes.isEmpty) s.idleMins.value = idleMinutes.get
reset.value = resetCaches
shutdown.value = shutdownServer
val prefixSettings =
List(
/*scalac*/
s.jvmargs, s.defines
) flatMap (_.value)
/** XXX Since fsc is largely unmaintained, the set of options being
* individually assessed here is likely to bear little relationship to
* the current set of options. Most likely this manifests in confusing
* and very difficult to debug behavior in fsc. We should warn or fix.
*/
val stringSettings =
List(s.outdir, s.classpath, s.bootclasspath, s.extdirs, s.encoding) flatMap (x => List(x.name, x.value))
val stringSettings =
List(
/*scalac*/
s.bootclasspath, s.classpath, s.extdirs, s.dependencyfile, s.encoding,
s.outdir, s.sourcepath,
/*fsc*/
s.server
) filter (_.value != "") flatMap (x => List(x.name, x.value))
val serverOption =
serverAddr.toList flatMap (x => List("-server", x)) // '-server' option
val choiceSettings =
List(
/*scalac*/
s.debuginfo, s.target
) map (x => "%s:%s".format(x.name, x.value))
val choiceSettings =
List(s.debuginfo, s.target) map (x => "%s:%s".format(x.name, x.value))
val booleanSettings =
List(
/*scalac*/
s.debug, s.deprecation, s.explaintypes, s.nospecialization, s.nowarn,
s.optimise, s.unchecked, s.usejavacp, s.verbose,
/*fsc*/
s.preferIPv4, s.reset, s.shutdown
) filter (_.value) map (_.name)
val booleanSettings =
List(s.debug, s.deprecation, s.verbose, reset, shutdown) map (x => if (x.value) List(x.name) else Nil) flatten
val intSettings =
List(
/*fsc*/
s.idleMins
) filter (x => x.value != x.default) flatMap (x => List(x.name, x.value.toString))
val phaseSetting = {
val s = settings.log
if (s.value.isEmpty) Nil
else List("%s:%s".format(s.name, s.value.mkString(",")))
}
val phaseSetting = {
val s = settings.log
if (s.value.isEmpty) Nil
else List("%s:%s".format(s.name, s.value.mkString(",")))
}
val cmdOptions =
stringSettings ::: serverOption ::: choiceSettings ::: booleanSettings ::: phaseSetting
val cmdOptions =
prefixSettings ::: stringSettings ::: choiceSettings ::: booleanSettings ::: intSettings ::: phaseSetting
val args = (cmdOptions ::: (sourceFiles map (_.toString))).toArray
try {
if (scala.tools.nsc.CompileClient.process(args) && failonerror)
buildError("Compile failed; see the compiler error output for details.")
}
catch {
case exception: Throwable if exception.getMessage ne null =>
exception.printStackTrace()
buildError("Compile failed because of an internal compiler error (" +
exception.getMessage + "); see the error output for details.")
case exception =>
exception.printStackTrace()
buildError("Compile failed because of an internal compiler error " +
"(no error message provided); see the error output for details.")
}
val args = (cmdOptions ::: (sourceFiles map (_.toString))).toArray
log("FastScalac args="+args.mkString(" "), Project.MSG_DEBUG)
try {
if (!scala.tools.nsc.CompileClient.process(args) && failonerror)
buildError("Compile failed; see the compiler error output for details.")
}
catch {
case ex: Throwable =>
ex.printStackTrace()
val msg = if (ex.getMessage == null) "no error message provided" else ex.getMessage
buildError("Compile failed because of an internal compiler error (" + msg + "); see the error output for details.")
}
}
}

View File

@ -8,15 +8,18 @@
package scala.tools.ant
import java.io.{File,PrintWriter,BufferedWriter,FileWriter}
import java.io.{File, PrintWriter, BufferedWriter, FileWriter}
import org.apache.tools.ant.{ BuildException, Project, AntClassLoader }
import org.apache.tools.ant.taskdefs.Java
import org.apache.tools.ant.types.{Path, Reference}
import org.apache.tools.ant.util.{FileUtils, GlobPatternMapper,
SourceFileScanner}
SourceFileScanner, facade}
import org.apache.tools.ant.util.facade.{FacadeTaskHelper,
ImplementationSpecificArgument}
import scala.tools.nsc.{Global, Settings, CompilerCommand}
import scala.tools.nsc.io.{Path => SPath}
import scala.tools.nsc.reporters.{Reporter, ConsoleReporter}
/** An Ant task to compile with the new Scala compiler (NSC).
@ -33,6 +36,7 @@ import scala.tools.nsc.reporters.{Reporter, ConsoleReporter}
* - `bootclasspathref`,
* - `extdirs`,
* - `extdirsref`,
* - `dependencyfile`,
* - `encoding`,
* - `target`,
* - `force`,
@ -41,9 +45,13 @@ import scala.tools.nsc.reporters.{Reporter, ConsoleReporter}
* - `logphase`,
* - `debuginfo`,
* - `addparams`,
* - `explaintypes`,
* - `deprecation`,
* - `nobootcp`,
* - `nowarn`,
* - `optimise`,
* - `unchecked`,
* - `usejavacp`,
* - `failonerror`,
* - `scalacdebugging`,
* - `assemname`,
@ -54,7 +62,8 @@ import scala.tools.nsc.reporters.{Reporter, ConsoleReporter}
* - `classpath`,
* - `sourcepath`,
* - `bootclasspath`,
* - `extdirs`.
* - `extdirs`,
* - `compilerarg`.
*
* @author Gilles Dubochet, Stephane Micheloud
*/
@ -80,10 +89,11 @@ class Scalac extends ScalaMatchingTask with ScalacShared {
/** Defines valid values for properties that refer to compiler phases. */
object CompilerPhase extends PermissibleValue {
val values = List("namer", "typer", "pickler", "uncurry", "tailcalls",
"explicitouter", "erasure", "lambdalift",
"flatten", "constructors", "mixin", "icode", "jvm",
"terminal")
val values = List("namer", "typer", "pickler", "refchecks", "liftcode",
"uncurry", "tailcalls", "specialize", "explicitouter",
"erasure", "lazyvals", "lambdalift", "constructors",
"flatten", "mixin", "cleanup", "icode", "inliner",
"closelim", "dce", "jvm", "terminal")
}
/** Defines valid values for the `target` property. */
@ -116,6 +126,8 @@ class Scalac extends ScalaMatchingTask with ScalacShared {
/** The external extensions path to use for this compilation. */
protected var extdirs: Option[Path] = None
/** The dependency tracking file. */
protected var dependencyfile: Option[String] = None
/** The character encoding of the files to compile. */
protected var encoding: Option[String] = None
@ -138,12 +150,20 @@ class Scalac extends ScalaMatchingTask with ScalacShared {
protected var debugInfo: Option[String] = None
/** Instruct the compiler to use additional parameters */
protected var addParams: String = ""
/** Instruct the compiler to explain type errors in more detail. */
protected var explaintypes: Option[Boolean] = None
/** Instruct the compiler to generate deprecation information. */
protected var deprecation: Option[Boolean] = None
/** Instruct the compiler to not use the boot classpath for the scala jars. */
protected var nobootcp: Option[Boolean] = None
/** Instruct the compiler to generate no warnings. */
protected var nowarn: Option[Boolean] = None
/** Instruct the compiler to run optimizations. */
protected var optimise: Option[Boolean] = None
/** Instruct the compiler to generate unchecked information. */
protected var unchecked: Option[Boolean] = None
/** Instruct the compiler to use `java.class.path` in classpath resolution. */
protected var usejavacp: Option[Boolean] = None
/** Indicates whether compilation errors will fail the build; defaults to true. */
protected var failonerror: Boolean = true
@ -156,6 +176,9 @@ class Scalac extends ScalaMatchingTask with ScalacShared {
* (not only the number of files). */
protected var scalacDebugging: Boolean = false
/** Encapsulates implementation of specific command line arguments. */
protected var scalacCompilerArgs = new FacadeTaskHelper("compilerarg")
/** Helpers */
private def setOrAppend(old: Option[Path], arg: Path): Option[Path] = old match {
case Some(x) => x append arg ; Some(x)
@ -251,8 +274,7 @@ class Scalac extends ScalaMatchingTask with ScalacShared {
bootclasspath = setOrAppend(bootclasspath, input)
}
/** Sets the `bootclasspath` as a nested sourcepath Ant
* parameter.
/** Sets the `bootclasspath` as a nested bootclasspath Ant parameter.
* @return A source path to be configured. */
def createBootclasspath(): Path = createNewPath(bootclasspath _, p => bootclasspath = p)
@ -264,10 +286,11 @@ class Scalac extends ScalaMatchingTask with ScalacShared {
/** Sets the external extensions path attribute. Used by [[http://ant.apache.org Ant]].
* @param input The value of `extdirs`. */
def setExtdirs(input: Path) =
def setExtdirs(input: Path) {
extdirs = setOrAppend(extdirs, input)
}
/** Sets the `extdirs` as a nested sourcepath Ant parameter.
/** Sets the `extdirs` as a nested extdirs Ant parameter.
* @return An extensions path to be configured. */
def createExtdirs(): Path = createNewPath(extdirs _, p => extdirs = p)
@ -276,10 +299,17 @@ class Scalac extends ScalaMatchingTask with ScalacShared {
def setExtdirsref(input: Reference) =
createExtdirs().setRefid(input)
/** Sets the `dependencyfile` attribute. Used by [[http://ant.apache.org Ant]].
* @param input The value of `dependencyfile`. */
def setDependencyfile(input: String) {
dependencyfile = Some(input)
}
/** Sets the `encoding` attribute. Used by [[http://ant.apache.org Ant]].
* @param input The value of `encoding`. */
def setEncoding(input: String): Unit =
def setEncoding(input: String) {
encoding = Some(input)
}
/** Sets the `target` attribute. Used by [[http://ant.apache.org Ant]].
* @param input The value for `target`. */
@ -330,12 +360,30 @@ class Scalac extends ScalaMatchingTask with ScalacShared {
* @param input The value for `addparams`. */
def setAddparams(input: String) { addParams = input }
/** Set the `explaintypes` info attribute.
* @param input One of the flags `yes/no` or `on/off`. */
def setExplaintypes(input: String) {
explaintypes = Flag toBoolean input orElse buildError("Unknown explaintypes flag '" + input + "'")
}
/** Set the `deprecation` info attribute.
* @param input One of the flags `yes/no` or `on/off`. */
def setDeprecation(input: String) {
deprecation = Flag toBoolean input orElse buildError("Unknown deprecation flag '" + input + "'")
}
/** Set the `nobootcp` info attribute.
* @param input One of the flags `yes/no` or `on/off`. */
def setNobootcp(input: String) {
nobootcp = Flag toBoolean input orElse buildError("Unknown nobootcp flag '" + input + "'")
}
/** Set the `nowarn` info attribute.
* @param input One of the flags `yes/no` or `on/off`. */
def setNowarn(input: String) {
nowarn = Flag toBoolean input orElse buildError("Unknown nowarn flag '" + input + "'")
}
/** Set the `optimise` info attribute.
* @param input One of the flags `yes/no` or `on/off`. */
def setOptimise(input: String) {
@ -348,6 +396,12 @@ class Scalac extends ScalaMatchingTask with ScalacShared {
unchecked = Flag toBoolean input orElse buildError("Unknown unchecked flag '" + input + "'")
}
/** Set the `usejavacp` info attribute.
* @param input One of the flags `yes/no` or `on/off`. */
def setUsejavacp(input: String) {
usejavacp = Flag toBoolean input orElse buildError("Unknown usejavacp flag '" + input + "'")
}
/** Sets the `failonerror` attribute. Used by [[http://ant.apache.org Ant]].
* @param input The value for `failonerror`. */
def setFailonerror(input: Boolean) { failonerror = input }
@ -361,6 +415,14 @@ class Scalac extends ScalaMatchingTask with ScalacShared {
def setAssemname(input: String) { assemname = Some(input) }
def setAssemrefs(input: String) { assemrefs = Some(input) }
/** Sets the `compilerarg` as a nested compilerarg Ant parameter.
* @return A compiler argument to be configured. */
def createCompilerArg(): ImplementationSpecificArgument = {
val arg = new ImplementationSpecificArgument()
scalacCompilerArgs addImplementationArgument arg
arg
}
/*============================================================================*\
** Properties getters **
\*============================================================================*/
@ -457,7 +519,7 @@ class Scalac extends ScalaMatchingTask with ScalacShared {
/** Initializes settings and source files */
protected def initialize: (Settings, List[File], Boolean) = {
if (scalacDebugging)
log("Base directory is `%s`".format(scala.tools.nsc.io.Path("").normalize))
log("Base directory is `%s`".format(SPath("").normalize))
// Tests if all mandatory attributes are set and valid.
if (origin.isEmpty) buildError("Attribute 'srcdir' is not set.")
@ -522,6 +584,7 @@ class Scalac extends ScalaMatchingTask with ScalacShared {
if (!bootclasspath.isEmpty)
settings.bootclasspath.value = asString(getBootclasspath)
if (!extdirs.isEmpty) settings.extdirs.value = asString(getExtdirs)
if (!dependencyfile.isEmpty) settings.dependencyfile.value = dependencyfile.get
if (!encoding.isEmpty) settings.encoding.value = encoding.get
if (!backend.isEmpty) settings.target.value = backend.get
if (!logging.isEmpty && logging.get == "verbose")
@ -532,13 +595,22 @@ class Scalac extends ScalaMatchingTask with ScalacShared {
}
if (!logPhase.isEmpty) settings.log.value = logPhase
if (!debugInfo.isEmpty) settings.debuginfo.value = debugInfo.get
if (!explaintypes.isEmpty) settings.explaintypes.value = explaintypes.get
if (!deprecation.isEmpty) settings.deprecation.value = deprecation.get
if (!nobootcp.isEmpty) settings.nobootcp.value = nobootcp.get
if (!nowarn.isEmpty) settings.nowarn.value = nowarn.get
if (!optimise.isEmpty) settings.XO.value = optimise.get
if (!unchecked.isEmpty) settings.unchecked.value = unchecked.get
if (!usejavacp.isEmpty) settings.usejavacp.value = usejavacp.get
if (!assemname.isEmpty) settings.assemname.value = assemname.get
if (!assemrefs.isEmpty) settings.assemrefs.value = assemrefs.get
val jvmargs = scalacCompilerArgs.getArgs filter (_ startsWith "-J")
if (!jvmargs.isEmpty) settings.jvmargs.value = jvmargs.toList
val defines = scalacCompilerArgs.getArgs filter (_ startsWith "-D")
if (!defines.isEmpty) settings.defines.value = defines.toList
log("Scalac params = '" + addParams + "'", Project.MSG_DEBUG)
// let CompilerCommand processes all params
@ -550,8 +622,8 @@ class Scalac extends ScalaMatchingTask with ScalacShared {
command.settings.dependenciesFile.value match {
case "none" =>
case x =>
val depFilePath = scala.tools.nsc.io.Path(x)
command.settings.dependenciesFile.value = scala.tools.nsc.io.Path(getProject.getBaseDir).normalize resolve depFilePath path
val depFilePath = SPath(x)
command.settings.dependenciesFile.value = SPath(getProject.getBaseDir).normalize resolve depFilePath path
}
(command.settings, sourceFiles, javaOnly)
@ -588,7 +660,7 @@ class Scalac extends ScalaMatchingTask with ScalacShared {
java setClassname MainClass
// Write all settings to a temporary file
def writeSettings() : File = {
def writeSettings(): File = {
def escapeArgument(arg : String) = if (arg matches ".*\\s.*") '"' + arg + '"' else arg
val file = File.createTempFile("scalac-ant-",".args")
file.deleteOnExit()

View File

@ -12,34 +12,35 @@ package scala.tools.ant.sabbus
import java.net.URL
object Compilers extends collection.DefaultMap[String, Compiler] {
val debug = false
private val container = new collection.mutable.HashMap[String, Compiler]
def iterator = container.iterator
def get(id: String) = container.get(id)
override def size = container.size
def make(id: String, classpath: Array[URL], settings: Settings): Compiler = {
val runtime = Runtime.getRuntime
if (debug) println("Making compiler " + id)
if (debug) println(" memory before: " + (runtime.freeMemory/1048576.).formatted("%10.2f") + " MB")
if (debug) println(" memory before: " + freeMemoryString)
val comp = new Compiler(classpath, settings)
container += Pair(id, comp)
if (debug) println(" memory after: " + (runtime.freeMemory/1048576.).formatted("%10.2f") + " MB")
if (debug) println(" memory after: " + freeMemoryString)
comp
}
def break(id: String): Null = {
val runtime = Runtime.getRuntime
if (debug) println("Breaking compiler " + id)
if (debug) println(" memory before: " + (runtime.freeMemory/1048576.).formatted("%10.2f") + " MB")
if (debug) println(" memory before: " + freeMemoryString)
container -= id
System.gc
if (debug) println(" memory after: " + (runtime.freeMemory/1048576.).formatted("%10.2f") + " MB")
System.gc()
if (debug) println(" memory after: " + freeMemoryString)
null
}
private def freeMemoryString: String =
(Runtime.getRuntime.freeMemory/1048576.0).formatted("%10.2f") + " MB"
}

View File

@ -21,7 +21,7 @@ class Make extends Task with TaskArgs {
if (!compTarget.isEmpty) settings.target = compTarget.get
if (!compilationPath.isEmpty) settings.classpath = compilationPath.get
if (!sourcePath.isEmpty) settings.sourcepath = sourcePath.get
if (!params.isEmpty) settings.more = params.get
settings.extraParams = extraArgsFlat
Compilers.make(id.get, (compilerPath.get.list.map{ path => new File(path).toURI.toURL }), settings)
}
}

View File

@ -23,14 +23,16 @@ import scala.tools.nsc.util.ScalaClassLoader
* - `failonerror`,
* - `timeout`,
* - `jvmargs`,
* - `argfile`.
* - `argfile`,
* - `params`.
*
* It also takes the following parameters as nested elements:
* - `src` (for `srcdir`),
* - `classpath`,
* - `sourcepath`,
* - `bootclasspath`,
* - `extdirs`.
* - `extdirs`,
* - `compilerarg`.
*
* @author Gilles Dubochet
*/
@ -99,7 +101,7 @@ class ScalacFork extends ScalaMatchingTask with ScalacShared with TaskArgs {
compTarget foreach (settings.target = _)
compilationPath foreach (settings.classpath = _)
sourcePath foreach (settings.sourcepath = _)
params foreach (settings.more = _)
settings.extraParams = extraArgsFlat
if (isMSIL)
settings.sourcedir = sourceDir
@ -132,10 +134,17 @@ class ScalacFork extends ScalaMatchingTask with ScalacShared with TaskArgs {
java setClasspath compilerPath
java setClassname MainClass
// Encode scalac/javac args for use in a file to be read back via "@file.txt"
def encodeScalacArgsFile(t: Traversable[String]) = t map { s =>
if(s.find(c => c <= ' ' || "\"'\\".contains(c)).isDefined)
"\"" + s.flatMap(c => (if(c == '"' || c == '\\') "\\" else "") + c ) + "\""
else s
} mkString "\n"
// dump the arguments to a file and do "java @file"
val tempArgFile = io.File.makeTemp("scalacfork")
val tokens = settings.toArgs ++ (includedFiles map (_.getPath))
tempArgFile writeAll (tokens mkString " ")
tempArgFile writeAll encodeScalacArgsFile(tokens)
val paths = List(Some(tempArgFile.toAbsolute.path), argfile).flatten map (_.toString)
val res = execWithArgFiles(java, paths)

View File

@ -58,9 +58,9 @@ class Settings {
def optimise = optimiseBf
def optimise_=(b: Boolean) { optimiseBf = b }
private var moreBf: Option[String] = None
def more = moreBf.get
def more_=(s: String): this.type = { moreBf = Some(s); this }
private var extraParamsBf: Seq[String] = Seq()
def extraParams = extraParamsBf
def extraParams_=(s: Seq[String]): this.type = { extraParamsBf = s; this }
def toArgs: List[String] =
(if (!gBf.isEmpty) "-g:"+g :: Nil else Nil) :::
@ -74,7 +74,7 @@ class Settings {
(if (!encodingBf.isEmpty) "-encoding" :: encoding :: Nil else Nil) :::
(if (!targetBf.isEmpty) "-target:"+target :: Nil else Nil) :::
(if (optimiseBf) "-optimise" :: Nil else Nil) :::
(if (!moreBf.isEmpty) (more split ' ').toList else Nil)
extraParamsBf.toList
override def equals(that: Any): Boolean = that match {
case cs: Settings =>
@ -89,7 +89,7 @@ class Settings {
this.encodingBf == cs.encodingBf &&
this.targetBf == cs.targetBf &&
this.optimiseBf == cs.optimiseBf &&
this.moreBf == cs.moreBf
this.extraParamsBf == cs.extraParamsBf
case _ => false
}

View File

@ -12,6 +12,7 @@ package scala.tools.ant.sabbus
import java.io.File
import org.apache.tools.ant.Task
import org.apache.tools.ant.types.{Path, Reference}
import org.apache.tools.ant.types.Commandline.Argument
trait CompilationPathProperty {
this: Task =>
@ -41,12 +42,15 @@ trait TaskArgs extends CompilationPathProperty {
}
def setParams(input: String) {
params = params match {
case None => Some(input)
case Some(ps) => Some(ps + " " + input)
}
extraArgs ++= input.split(' ').map { s => val a = new Argument; a.setValue(s); a }
}
def createCompilerArg(): Argument = {
val a = new Argument
extraArgs :+= a
a
}
def setTarget(input: String) {
compTarget = Some(input)
}
@ -84,11 +88,16 @@ trait TaskArgs extends CompilationPathProperty {
}
protected var id: Option[String] = None
protected var params: Option[String] = None
protected var extraArgs: Seq[Argument] = Seq()
protected var compTarget: Option[String] = None
protected var sourcePath: Option[Path] = None
protected var compilerPath: Option[Path] = None
protected var destinationDir: Option[File] = None
def extraArgsFlat: Seq[String] = extraArgs flatMap { a =>
val parts = a.getParts
if(parts eq null) Seq[String]() else parts.toSeq
}
def isMSIL = compTarget exists (_ == "msil")
}

View File

@ -1,4 +1,4 @@
#!/bin/bash --posix
#!/usr/bin/env bash
#
##############################################################################
# Copyright 2002-2011, LAMP/EPFL
@ -8,6 +8,17 @@
# PARTICULAR PURPOSE.
##############################################################################
findScalaHome () {
# see #2092
local SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ] ; do SOURCE="$(readlink "$SOURCE")"; done
( cd -P "$( dirname "$SOURCE" )"/.. && pwd )
}
execCommand () {
[[ -n $SCALA_RUNNER_DEBUG ]] && echo "" && for arg in "$@@"; do echo "$arg"; done && echo "";
"$@@"
}
# Not sure what the right default is here: trying nonzero.
scala_exit_status=127
saved_stty=""
@ -15,7 +26,8 @@ saved_stty=""
# restore stty settings (echo in particular)
function restoreSttySettings() {
if [[ -n $SCALA_RUNNER_DEBUG ]]; then
echo "restoring stty: $saved_stty"
echo "restoring stty:"
echo "$saved_stty"
fi
stty $saved_stty
@ -23,10 +35,8 @@ function restoreSttySettings() {
}
function onExit() {
if [[ "$saved_stty" != "" ]]; then
restoreSttySettings
exit $scala_exit_status
fi
[[ "$saved_stty" != "" ]] && restoreSttySettings
exit $scala_exit_status
}
# to reenable echo if we are interrupted before completing.
@ -39,69 +49,60 @@ if [[ ! $? ]]; then
saved_stty=""
fi
if [[ -n $SCALA_RUNNER_DEBUG ]]; then
echo "saved stty: $saved_stty"
echo "saved stty:"
echo "$saved_stty"
fi
cygwin=false;
case "`uname`" in
CYGWIN*) cygwin=true ;;
esac
unset cygwin
if uname | grep -q ^CYGWIN; then
cygwin="$(uname)"
fi
# Finding the root folder for this Scala distribution
SOURCE=$0;
SCRIPT=`basename "$SOURCE"`;
while [ -h "$SOURCE" ]; do
SCRIPT=`basename "$SOURCE"`;
LOOKUP=`ls -ld "$SOURCE"`;
TARGET=`expr "$LOOKUP" : '.*-> \(.*\)$'`;
if expr "${TARGET:-.}/" : '/.*/$' > /dev/null; then
SOURCE=${TARGET:-.};
else
SOURCE=`dirname "$SOURCE"`/${TARGET:-.};
fi;
done;
SCALA_HOME="$(findScalaHome)"
SEP=":"
# see #2092
SCALA_HOME=`dirname "$SOURCE"`
SCALA_HOME=`cd "$SCALA_HOME"; pwd -P`
SCALA_HOME=`cd "$SCALA_HOME"/..; pwd`
# Possible additional command line options
CYGWIN_OPT=""
EMACS_OPT=""
[[ -n "$EMACS" ]] && EMACS_OPT="-Denv.emacs=$EMACS"
# Remove spaces from SCALA_HOME on windows
if $cygwin; then
SCALA_HOME=`cygpath --windows --short-name "$SCALA_HOME"`
SCALA_HOME=`cygpath --unix "$SCALA_HOME"`
if [[ -n "$cygwin" ]]; then
SCALA_HOME="$(shome="$(cygpath --windows --short-name "$SCALA_HOME")" ; cygpath --unix "$shome")"
# elif uname |grep -q ^MINGW; then
# SEP=";"
fi
# Constructing the extension classpath
TOOL_CLASSPATH="@classpath@"
if [ -z "$TOOL_CLASSPATH" ] ; then
if [[ -z "$TOOL_CLASSPATH" ]]; then
for ext in "$SCALA_HOME"/lib/* ; do
if [ -z "$TOOL_CLASSPATH" ] ; then
if [[ -z "$TOOL_CLASSPATH" ]]; then
TOOL_CLASSPATH="$ext"
else
TOOL_CLASSPATH="$TOOL_CLASSPATH:$ext"
TOOL_CLASSPATH="${TOOL_CLASSPATH}${SEP}${ext}"
fi
done
fi
CYGWIN_JLINE_TERMINAL=
if $cygwin; then
if [ "$OS" = "Windows_NT" ] && cygpath -m .>/dev/null 2>/dev/null ; then
if [[ -n "$cygwin" ]]; then
if [[ "$OS" = "Windows_NT" ]] && cygpath -m .>/dev/null 2>/dev/null ; then
format=mixed
else
format=windows
fi
SCALA_HOME=`cygpath --$format "$SCALA_HOME"`
TOOL_CLASSPATH=`cygpath --path --$format "$TOOL_CLASSPATH"`
SCALA_HOME="$(cygpath --$format "$SCALA_HOME")"
TOOL_CLASSPATH="$(cygpath --path --$format "$TOOL_CLASSPATH")"
case "$TERM" in
rxvt* | xterm*)
stty -icanon min 1 -echo
CYGWIN_JLINE_TERMINAL="-Djline.terminal=scala.tools.jline.UnixTerminal"
CYGWIN_OPT="-Djline.terminal=scala.tools.jline.UnixTerminal"
;;
esac
fi
[ -n "$JAVA_OPTS" ] || JAVA_OPTS="@javaflags@"
[[ -n "$JAVA_OPTS" ]] || JAVA_OPTS="@javaflags@"
# break out -D and -J options and add them to JAVA_OPTS as well
# so they reach the underlying JVM in time to do some good. The
@ -109,11 +110,21 @@ fi
declare -a java_args
declare -a scala_args
# default to the boot classpath for speed.
CPSELECT="-Xbootclasspath/a:"
USEJAVACP=false
# default to the boot classpath for speed, except on cygwin/mingw.
unset usebootcp
if [[ -z $cygwin ]]; then
usebootcp="true"
fi
while [ $# -gt 0 ]; do
classpathArgs () {
if [[ -n $usebootcp ]]; then
echo "-Xbootclasspath/a:$TOOL_CLASSPATH"
else
echo "-classpath $TOOL_CLASSPATH"
fi
}
while [[ $# -gt 0 ]]; do
case "$1" in
-D*)
# pass to scala as well: otherwise we lose it sometimes when we
@ -130,12 +141,19 @@ while [ $# -gt 0 ]; do
shift
;;
-toolcp)
TOOL_CLASSPATH="$TOOL_CLASSPATH:$2"
TOOL_CLASSPATH="${TOOL_CLASSPATH}${SEP}${2}"
shift 2
;;
-nobootcp)
CPSELECT="-classpath "
USEJAVACP=true
unset usebootcp
shift
;;
-usebootcp)
usebootcp="true"
shift
;;
-debug)
SCALA_RUNNER_DEBUG=1
shift
;;
*)
@ -148,18 +166,22 @@ done
# reset "$@@" to the remaining args
set -- "${scala_args[@@]}"
if [ -z "$JAVACMD" -a -n "$JAVA_HOME" -a -x "$JAVA_HOME/bin/java" ]; then
if [[ -z "$JAVACMD" && -n "$JAVA_HOME" && -x "$JAVA_HOME/bin/java" ]]; then
JAVACMD="$JAVA_HOME/bin/java"
fi
"${JAVACMD:=java}" \
# note that variables which may intentionally be empty must not
# be quoted: otherwise an empty string will appear as a command line
# argument, and java will think that is the program to run.
execCommand \
"${JAVACMD:=java}" \
$JAVA_OPTS \
"${java_args[@@]}" \
${CPSELECT}${TOOL_CLASSPATH} \
-Dscala.usejavacp="$USEJAVACP" \
$(classpathArgs) \
-Dscala.home="$SCALA_HOME" \
-Denv.emacs="$EMACS" \
$CYGWIN_JLINE_TERMINAL \
-Dscala.usejavacp=true \
$EMACS_OPT \
$CYGWIN_OPT \
@properties@ @class@ @toolflags@ "$@@"
# record the exit status lest it be overwritten:

View File

@ -8,9 +8,28 @@ rem # There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
rem # PARTICULAR PURPOSE.
rem ##########################################################################
setlocal enableextensions enabledelayedexpansion
set _LINE_TOOLCP=
:another_param
if "%1%"=="-toolcp" (
set _LINE_TOOLCP=%2%
shift
shift
goto another_param
)
set _LINE_PARAMS=%1
:param_loop
shift
if [%1]==[] goto param_afterloop
set _LINE_PARAMS=%_LINE_PARAMS% %1
goto param_loop
:param_afterloop
if "%OS%" NEQ "Windows_NT" (
echo "Sorry, your version of Windows is too old to run Scala."
goto :eof
echo "Warning, your version of Windows is not supported. Attempting to start scala anyway."
)
@@setlocal
@ -19,7 +38,7 @@ call :set_home
rem We use the value of the JAVACMD environment variable if defined
set _JAVACMD=%JAVACMD%
if "%_JAVACMD%"=="" (
if not defined _JAVACMD (
if not "%JAVA_HOME%"=="" (
if exist "%JAVA_HOME%\bin\java.exe" set "_JAVACMD=%JAVA_HOME%\bin\java.exe"
)
@ -29,15 +48,17 @@ if "%_JAVACMD%"=="" set _JAVACMD=java
rem We use the value of the JAVA_OPTS environment variable if defined
set _JAVA_OPTS=%JAVA_OPTS%
if "%_JAVA_OPTS%"=="" set _JAVA_OPTS=@javaflags@
if not defined _JAVA_OPTS set _JAVA_OPTS=@javaflags@
set _TOOL_CLASSPATH=@classpath@
if "%_TOOL_CLASSPATH%"=="" (
for %%f in ("%_SCALA_HOME%\lib\*") do call :add_cpath "%%f"
for /d %%f in ("%_SCALA_HOME%\lib\*") do call :add_cpath "%%f"
for %%f in ("!_SCALA_HOME!\lib\*") do call :add_cpath "%%f"
for /d %%f in ("!_SCALA_HOME!\lib\*") do call :add_cpath "%%f"
)
set _PROPS=-Dscala.home="%_SCALA_HOME%" -Denv.emacs="%EMACS%" -Dscala.usejavacp=true @properties@
if not "%_LINE_TOOLCP%"=="" call :add_cpath "%_LINE_TOOLCP%"
set _PROPS=-Dscala.home="!_SCALA_HOME!" -Denv.emacs="%EMACS%" -Dscala.usejavacp=true @properties@
rem echo "%_JAVACMD%" %_JAVA_OPTS% %_PROPS% -cp "%_TOOL_CLASSPATH%" @class@ @toolflags@ %*
"%_JAVACMD%" %_JAVA_OPTS% %_PROPS% -cp "%_TOOL_CLASSPATH%" @class@ @toolflags@ %*

View File

@ -417,7 +417,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
} with Pickler
// phaseName = "refchecks"
object refChecks extends {
override object refChecks extends {
val global: Global.this.type = Global.this
val runsAfter = List[String]("pickler")
val runsRightAfter = None
@ -431,7 +431,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
} with LiftCode
// phaseName = "uncurry"
object uncurry extends {
override object uncurry extends {
val global: Global.this.type = Global.this
val runsAfter = List[String]("refchecks", "liftcode")
val runsRightAfter = None
@ -459,7 +459,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
} with SpecializeTypes
// phaseName = "erasure"
object erasure extends {
override object erasure extends {
val global: Global.this.type = Global.this
val runsAfter = List[String]("explicitouter")
val runsRightAfter = Some("explicitouter")
@ -716,6 +716,34 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
private var curRun: Run = null
private var curRunId = 0
/** A hook that lets subclasses of `Global` define whether a package or class should be kept loaded for the
* next compiler run. If the parameter `sym` is a class or object, and `clearOnNextRun(sym)` returns `true`,
* then the symbol is unloaded and reset to its state before the last compiler run. If the parameter `sym` is
* a package, and clearOnNextRun(sym)` returns `true`, the package is recursively searched for
* classes to drop.
*
* Example: Let's say I want a compiler that drops all classes corresponding to the current project
* between runs. Then `keepForNextRun` of a toplevel class or object should return `true` if the
* class or object does not form part of the current project, `false` otherwise. For a package,
* clearOnNextRun should return `true` if no class in that package forms part of the current project,
* `false` otherwise.
*
* @param sym A class symbol, object symbol, package, or package class.
*/
def clearOnNextRun(sym: Symbol) = false
/* To try out clearOnNext run on the scala.tools.nsc project itself
* replace `false` above with the following code
settings.Xexperimental.value && { sym.isRoot || {
sym.fullName match {
case "scala" | "scala.tools" | "scala.tools.nsc" => true
case _ => sym.owner.fullName.startsWith("scala.tools.nsc")
}
}}
* Then, fsc -Xexperimental clears the nsc porject between successive runs of `fsc`.
*/
/** Remove the current run when not needed anymore. Used by the build
* manager to save on the memory foot print. The current run holds on
* to all compilation units, which in turn hold on to trees.
@ -795,6 +823,46 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
parserPhase
}
/** Reset all classes contained in current project, as determined by
* the clearOnNextRun hook
*/
def resetProjectClasses(root: Symbol): Unit = try {
def unlink(sym: Symbol) =
if (sym != NoSymbol) root.info.decls.unlink(sym)
if (settings.verbose.value) inform("[reset] recursing in "+root)
val toReload = mutable.Set[String]()
for (sym <- root.info.decls) {
if (sym.isInitialized && clearOnNextRun(sym))
if (sym.isPackage) {
resetProjectClasses(sym.moduleClass)
openPackageModule(sym.moduleClass)
} else {
unlink(sym)
unlink(root.info.decls.lookup(
if (sym.isTerm) sym.name.toTypeName else sym.name.toTermName))
toReload += sym.fullName
// note: toReload could be set twice with the same name
// but reinit must happen only once per name. That's why
// the following classPath.findClass { ... } code cannot be moved here.
}
}
for (fullname <- toReload)
classPath.findClass(fullname) match {
case Some(classRep) =>
if (settings.verbose.value) inform("[reset] reinit "+fullname)
loaders.initializeFromClassPath(root, classRep)
case _ =>
}
} catch {
case ex: Throwable =>
// this handler should not be nessasary, but it seems that `fsc`
// eats exceptions if they appear here. Need to find out the cause for
// this and fix it.
inform("[reset] exception happened: "+ex);
ex.printStackTrace();
throw ex
}
// --------------- Miscellania -------------------------------
@ -1103,6 +1171,11 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
// Clear any sets or maps created via perRunCaches.
perRunCaches.clearAll()
// Reset project
atPhase(namerPhase) {
resetProjectClasses(definitions.RootClass)
}
}
/** Compile list of abstract files. */
@ -1217,7 +1290,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
def printAllUnits() {
print("[[syntax trees at end of " + phase + "]]")
atPhase(phase.next) { currentRun.units foreach treePrinter.print }
atPhase(phase.next) { currentRun.units foreach (treePrinter.print(_)) }
}
private def findMemberFromRoot(fullName: Name): Symbol = {

View File

@ -7,13 +7,28 @@ package scala.tools.nsc
import java.net.URL
import scala.tools.util.PathResolver
import io.{ File }
import util.{ ClassPath, ScalaClassLoader }
import Properties.{ versionString, copyrightString }
import interpreter.{ ILoop }
import GenericRunnerCommand._
object JarRunner extends CommonRunner {
def runJar(settings: GenericRunnerSettings, jarPath: String, arguments: Seq[String]): Either[Throwable, Boolean] = {
val jar = new io.Jar(jarPath)
val mainClass = jar.mainClass getOrElse sys.error("Cannot find main class for jar: " + jarPath)
val jarURLs = ClassPath expandManifestPath jarPath
val urls = if (jarURLs.isEmpty) File(jarPath).toURL +: settings.classpathURLs else jarURLs
if (settings.Ylogcp.value) {
Console.err.println("Running jar with these URLs as the classpath:")
urls foreach println
}
runAndCatch(urls, mainClass, arguments)
}
}
/** An object that runs Scala code. It has three possible
* sources for the code to run: pre-compiled code, a script file,
* or interactive entry.
@ -56,11 +71,7 @@ class MainGenericRunner {
case AsScript =>
ScriptRunner.runScriptAndCatch(settings, thingToRun, command.arguments)
case AsJar =>
ObjectRunner.runAndCatch(
File(thingToRun).toURL +: settings.classpathURLs,
new io.Jar(thingToRun).mainClass getOrElse sys.error("Cannot find main class for jar: " + thingToRun),
command.arguments
)
JarRunner.runJar(settings, thingToRun, command.arguments)
case Error =>
Right(false)
case _ =>

View File

@ -11,12 +11,7 @@ import util.ScalaClassLoader
import java.lang.reflect.InvocationTargetException
import util.Exceptional.unwrap
/** An object that runs another object specified by name.
*
* @author Lex Spoon
* @version 1.1, 2007/7/13
*/
object ObjectRunner {
trait CommonRunner {
/** Check whether a class with the specified name
* exists on the specified class path. */
def classExists(urls: List[URL], objectName: String): Boolean =
@ -41,3 +36,10 @@ object ObjectRunner {
catch { case e => Left(unwrap(e)) }
}
}
/** An object that runs another object specified by name.
*
* @author Lex Spoon
* @version 1.1, 2007/7/13
*/
object ObjectRunner extends CommonRunner { }

View File

@ -22,4 +22,9 @@ object Properties extends scala.util.PropertiesTrait {
// derived values
def isEmacsShell = propOrEmpty("env.emacs") != ""
def fileEndings = fileEndingString.split("""\|""").toList
// System property java.home is the JRE root.
// Environment variable JAVA_HOME is (supposed to be) the jdk root.
// We need the latter to find javac, tools.jar, etc.
def jdkHome = envOrElse("JAVA_HOME", javaHome)
}

View File

@ -52,7 +52,7 @@ trait TreeDSL {
def fn(lhs: Tree, op: Name, args: Tree*) = Apply(Select(lhs, op), args.toList)
def fn(lhs: Tree, op: Symbol, args: Tree*) = Apply(Select(lhs, op), args.toList)
class TreeMethods(target: Tree) {
/** logical/comparison ops **/
def OR(other: Tree) =
@ -114,10 +114,7 @@ trait TreeDSL {
*
* See ticket #2168 for one illustration of AS vs. AS_ANY.
*/
def AS(tpe: Type) = TypeApply(Select(target, Any_asInstanceOf), List(TypeTree(tpe)))
def AS_ANY(tpe: Type) = gen.mkAsInstanceOf(target, tpe)
def AS_ATTR(tpe: Type) = gen.mkAttributedCast(target, tpe)
def AS(tpe: Type) = gen.mkAsInstanceOf(target, tpe, any = true, wrapInApply = false)
def IS(tpe: Type) = gen.mkIsInstanceOf(target, tpe, true)
def IS_OBJ(tpe: Type) = gen.mkIsInstanceOf(target, tpe, false)

View File

@ -46,6 +46,18 @@ abstract class TreeGen extends reflect.internal.TreeGen {
case Match(selector, cases) => atPos(tree.pos)(Match(mkUnchecked(selector), cases))
case _ => tree
}
def withDefaultCase(matchExpr: Tree, defaultAction: Tree/*scrutinee*/ => Tree): Tree = matchExpr match {
case Match(scrutinee, cases) =>
if (cases exists treeInfo.isDefaultCase) matchExpr
else {
val defaultCase = CaseDef(Ident(nme.WILDCARD), EmptyTree, defaultAction(scrutinee))
Match(scrutinee, cases :+ defaultCase)
}
case _ =>
matchExpr
// [Martin] Adriaan: please fill in virtpatmat transformation here
}
def mkCached(cvar: Symbol, expr: Tree): Tree = {
val cvarRef = mkUnattributedRef(cvar)

View File

@ -16,56 +16,52 @@ trait TreePrinters extends reflect.internal.TreePrinters { this: Global =>
class TreePrinter(out: PrintWriter) extends super.TreePrinter(out) {
override def print(tree: Tree) {
printPosition(tree)
printRaw(
if (tree.isDef && tree.symbol != NoSymbol && tree.symbol.isInitialized) {
tree match {
case ClassDef(_, _, _, impl @ Template(ps, emptyValDef, body))
if (tree.symbol.thisSym != tree.symbol) =>
ClassDef(tree.symbol, Template(ps, ValDef(tree.symbol.thisSym), body))
case ClassDef(_, _, _, impl) => ClassDef(tree.symbol, impl)
case ModuleDef(_, _, impl) => ModuleDef(tree.symbol, impl)
case ValDef(_, _, _, rhs) => ValDef(tree.symbol, rhs)
case DefDef(_, _, _, vparamss, _, rhs) => DefDef(tree.symbol, vparamss, rhs)
case TypeDef(_, _, _, rhs) => TypeDef(tree.symbol, rhs)
case _ => tree
}
} else tree)
}
def print(unit: CompilationUnit) {
print("// Scala source: " + unit.source + "\n")
if (unit.body == null) print("<null>")
else { print(unit.body); println() }
println()
flush()
override def print(args: Any*): Unit = args foreach {
case tree: Tree =>
printPosition(tree)
printTree(
if (tree.isDef && tree.symbol != NoSymbol && tree.symbol.isInitialized) {
tree match {
case ClassDef(_, _, _, impl @ Template(ps, emptyValDef, body))
if (tree.symbol.thisSym != tree.symbol) =>
ClassDef(tree.symbol, Template(ps, ValDef(tree.symbol.thisSym), body))
case ClassDef(_, _, _, impl) => ClassDef(tree.symbol, impl)
case ModuleDef(_, _, impl) => ModuleDef(tree.symbol, impl)
case ValDef(_, _, _, rhs) => ValDef(tree.symbol, rhs)
case DefDef(_, _, _, vparamss, _, rhs) => DefDef(tree.symbol, vparamss, rhs)
case TypeDef(_, _, _, rhs) => TypeDef(tree.symbol, rhs)
case _ => tree
}
} else tree)
case unit: CompilationUnit =>
print("// Scala source: " + unit.source + "\n")
if (unit.body == null) print("<null>")
else { print(unit.body); println() }
println()
out.flush()
case arg =>
super.print(arg)
}
}
// overflow cases missing from TreePrinter in reflect.api
override def xprintRaw(treePrinter: super.TreePrinter, tree: Tree) = tree match {
override def xprintTree(treePrinter: super.TreePrinter, tree: Tree) = tree match {
case DocDef(comment, definition) =>
treePrinter.print(comment.raw)
treePrinter.println()
treePrinter.print(definition)
case AssignOrNamedArg(lhs, rhs) =>
treePrinter.print(lhs)
treePrinter.print(" = ")
treePrinter.print(rhs)
treePrinter.print(lhs, " = ", rhs)
case TypeTreeWithDeferredRefCheck() =>
treePrinter.print("<tree with deferred refcheck>")
case SelectFromArray(qualifier, name, _) =>
treePrinter.print(qualifier)
treePrinter.print(".<arr>")
treePrinter.print(treePrinter.symName(tree, name))
treePrinter.print(qualifier, ".<arr>", treePrinter.symName(tree, name))
case _ =>
super.xprintRaw(treePrinter, tree)
super.xprintTree(treePrinter, tree)
}
/** A tree printer which is stingier about vertical whitespace and unnecessary
@ -74,7 +70,7 @@ trait TreePrinters extends reflect.internal.TreePrinters { this: Global =>
class CompactTreePrinter(out: PrintWriter) extends TreePrinter(out) {
override def printRow(ts: List[Tree], start: String, sep: String, end: String) {
print(start)
printSeq(ts)(print)(print(sep))
printSeq(ts)(print(_))(print(sep))
print(end)
}
@ -94,21 +90,21 @@ trait TreePrinters extends reflect.internal.TreePrinters { this: Global =>
def maybenot(tvalue: Boolean) = if (tvalue) "" else "!"
print("%s(" format maybenot(t1._2))
printRaw(t1._1)
printTree(t1._1)
print(") %s %s(".format(op, maybenot(t2._2)))
printRaw(t2._1)
printTree(t2._1)
print(")")
}
override def printRaw(tree: Tree): Unit = {
override def printTree(tree: Tree): Unit = {
// routing supercalls through this for debugging ease
def s() = super.printRaw(tree)
def s() = super.printTree(tree)
tree match {
// labels used for jumps - does not map to valid scala code
case LabelDef(name, params, rhs) =>
print("labeldef %s(%s) = ".format(name, params mkString ","))
printRaw(rhs)
printTree(rhs)
case Ident(name) =>
print(decodedSymName(tree, name))
@ -121,37 +117,37 @@ trait TreePrinters extends reflect.internal.TreePrinters { this: Global =>
printLogicalAnd(target -> true, arg -> true)
else (target, arg) match {
case (_: Ident, _: Literal | _: Ident) =>
printRaw(target)
printTree(target)
print(" ")
printRaw(Ident(method))
printTree(Ident(method))
print(" ")
printRaw(arg)
printTree(arg)
case _ => s()
}
// target.unary_! ==> !target
case Select(qualifier, name) if (name.decode startsWith "unary_") =>
print(name.decode drop 6)
printRaw(qualifier)
printTree(qualifier)
case Select(qualifier, name) =>
printRaw(qualifier)
printTree(qualifier)
print(".")
print(quotedName(name, true))
// target.toString() ==> target.toString
case Apply(fn, Nil) => printRaw(fn)
case Apply(fn, Nil) => printTree(fn)
// if a Block only continues one actual statement, just print it.
case Block(stats, expr) =>
allStatements(tree) match {
case List(x) => printRaw(x)
case List(x) => printTree(x)
case xs => s()
}
// We get a lot of this stuff
case If( IsTrue(), x, _) => printRaw(x)
case If(IsFalse(), _, x) => printRaw(x)
case If( IsTrue(), x, _) => printTree(x)
case If(IsFalse(), _, x) => printTree(x)
case If(cond, IsTrue(), elsep) => printLogicalOr(cond -> true, elsep -> true)
case If(cond, IsFalse(), elsep) => printLogicalAnd(cond -> false, elsep -> true)
@ -161,7 +157,7 @@ trait TreePrinters extends reflect.internal.TreePrinters { this: Global =>
// If thenp or elsep has only one statement, it doesn't need more than one line.
case If(cond, thenp, elsep) =>
def ifIndented(x: Tree) = {
indent ; println() ; printRaw(x) ; undent
indent ; println() ; printTree(x) ; undent
}
val List(thenStmts, elseStmts) = List(thenp, elsep) map allStatements
@ -169,16 +165,16 @@ trait TreePrinters extends reflect.internal.TreePrinters { this: Global =>
thenStmts match {
case List(x: If) => ifIndented(x)
case List(x) => printRaw(x)
case _ => printRaw(thenp)
case List(x) => printTree(x)
case _ => printTree(thenp)
}
if (elseStmts.nonEmpty) {
print(" else")
indent ; println()
elseStmts match {
case List(x) => printRaw(x)
case _ => printRaw(elsep)
case List(x) => printTree(x)
case _ => printTree(elsep)
}
undent ; println()
}
@ -192,10 +188,7 @@ trait TreePrinters extends reflect.internal.TreePrinters { this: Global =>
* the natural course of events.
*/
class SafeTreePrinter(out: PrintWriter) extends TreePrinter(out) {
override def print(tree: Tree) {
printPosition(tree)
printRaw(tree)
}
private def default(t: Tree) = t.getClass.getName.reverse.takeWhile(_ != '.').reverse
private def params(trees: List[Tree]): String = trees map safe mkString ", "
@ -209,7 +202,7 @@ trait TreePrinters extends reflect.internal.TreePrinters { this: Global =>
case _ => "(?: %s)".format(default(tree))
}
override def printRaw(tree: Tree) { print(safe(tree)) }
override def printTree(tree: Tree) { print(safe(tree)) }
}
class TreeMatchTemplate {
@ -286,15 +279,8 @@ trait TreePrinters extends reflect.internal.TreePrinters { this: Global =>
}
}
private def asStringInternal(t: Tree, f: PrintWriter => TreePrinter): String = {
val buffer = new StringWriter()
val printer = f(new PrintWriter(buffer))
printer.print(t)
printer.flush()
buffer.toString
}
def asString(t: Tree): String = asStringInternal(t, newStandardTreePrinter)
def asCompactString(t: Tree): String = asStringInternal(t, newCompactTreePrinter)
def asString(t: Tree): String = show(t, newStandardTreePrinter)
def asCompactString(t: Tree): String = show(t, newCompactTreePrinter)
def newStandardTreePrinter(writer: PrintWriter): TreePrinter = new TreePrinter(writer)
def newStandardTreePrinter(stream: OutputStream): TreePrinter = newStandardTreePrinter(new PrintWriter(stream))

View File

@ -2687,13 +2687,14 @@ self =>
if (mods.isCase) {
val arity = if (vparamss.isEmpty || vparamss.head.isEmpty) 0 else vparamss.head.size
productConstr :: serializableConstr :: {
if (arity == 0 || settings.YnoProductN.value) Nil
else List(
AppliedTypeTree(
productConstrN(arity),
vparamss.head map (vd => vd.tpt.duplicate setPos vd.tpt.pos.focus)
)
)
Nil
// if (arity == 0 || settings.YnoProductN.value) Nil
// else List(
// AppliedTypeTree(
// productConstrN(arity),
// vparamss.head map (vd => vd.tpt.duplicate setPos vd.tpt.pos.focus)
// )
// )
}
}
else Nil

View File

@ -28,6 +28,7 @@ trait ScannersCommon {
def warning(off: Int, msg: String): Unit
def error (off: Int, msg: String): Unit
def incompleteInputError(off: Int, msg: String): Unit
def deprecationWarning(off: Int, msg: String): Unit
}
def createKeywordArray(keywords: Seq[(Name, Int)], defaultToken: Int): (Int, Array[Int]) = {
@ -339,7 +340,18 @@ trait Scanners extends ScannersCommon {
if (ch == 'x' || ch == 'X') {
nextChar()
base = 16
} else {
}
else {
// !!! Let's deprecate this too, shall we?
// Can it really be worth it given the endless supply of newbies
// who have no hope whatsoever of intuiting that 012 != 12?
// Leading zero meaning octal is a relic of a darker time.
//
// Pre-fabricated future logic / warning:
//
// deprecationWarning("Treating numbers with a leading zero as octal is deprecated.")
// if (!opt.future)
// base = 8
base = 8
}
getNumber()
@ -797,12 +809,28 @@ trait Scanners extends ScannersCommon {
/** Convert current strVal, base to double value
*/
def floatVal(negated: Boolean): Double = {
val limit: Double =
if (token == DOUBLELIT) Double.MaxValue else Float.MaxValue
try {
val value: Double = java.lang.Double.valueOf(strVal).doubleValue()
def isDeprecatedForm = {
val idx = strVal indexOf '.'
(idx == strVal.length - 1) || (
(idx >= 0)
&& (idx + 1 < strVal.length)
&& (!Character.isDigit(strVal charAt (idx + 1)))
)
}
if (value > limit)
syntaxError("floating point number too large")
if (isDeprecatedForm) {
if (opt.future)
syntaxError("malformed floating point number: to be part of a number, a dot must be immediately followed by a digit")
else
deprecationWarning("This lexical syntax is deprecated. From scala 2.11, a dot will only be considered part of a number if it is immediately followed by a digit.")
}
if (negated) -value else value
} catch {
case _: NumberFormatException =>
@ -823,7 +851,7 @@ trait Scanners extends ScannersCommon {
protected def getNumber() {
def isDigit(c: Char) = java.lang.Character isDigit c
val base1 = if (base < 10) 10 else base
// read 8,9's even if format is octal, produce a malformed number error afterwards.
// read 8,9's even if format is octal, produce a malformed number error afterwards.
while (digit2int(ch, base1) >= 0) {
putChar(ch)
nextChar()
@ -915,6 +943,8 @@ trait Scanners extends ScannersCommon {
*/
def syntaxError(msg: String): Unit = syntaxError(offset, msg)
def deprecationWarning(msg: String): Unit = deprecationWarning(offset, msg)
/** signal an error where the input ended in the middle of a token */
def incompleteInputError(msg: String) {
incompleteInputError(offset, msg)
@ -1091,7 +1121,8 @@ trait Scanners extends ScannersCommon {
override val decodeUni: Boolean = !settings.nouescape.value
// suppress warnings, throw exception on errors
def warning(off: Offset, msg: String): Unit = {}
def warning(off: Offset, msg: String): Unit = ()
def deprecationWarning(off: Offset, msg: String): Unit = ()
def error (off: Offset, msg: String): Unit = throw new MalformedInput(off, msg)
def incompleteInputError(off: Offset, msg: String): Unit = throw new MalformedInput(off, msg)
}
@ -1101,8 +1132,9 @@ trait Scanners extends ScannersCommon {
class UnitScanner(unit: CompilationUnit, patches: List[BracePatch]) extends SourceFileScanner(unit.source) {
def this(unit: CompilationUnit) = this(unit, List())
override def warning(off: Offset, msg: String) = unit.warning(unit.position(off), msg)
override def error (off: Offset, msg: String) = unit.error(unit.position(off), msg)
override def warning(off: Offset, msg: String) = unit.warning(unit.position(off), msg)
override def deprecationWarning(off: Offset, msg: String) = unit.deprecationWarning(unit.position(off), msg)
override def error (off: Offset, msg: String) = unit.error(unit.position(off), msg)
override def incompleteInputError(off: Offset, msg: String) = unit.incompleteInputError(unit.position(off), msg)
private var bracePatches: List[BracePatch] = patches

View File

@ -798,8 +798,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
}
def genMethod(m: IMethod) {
if (m.symbol.isStaticConstructor) return
if ((m.symbol.name == nme.getClass_) && m.params.isEmpty) return
if (m.symbol.isStaticConstructor || definitions.isGetClass(m.symbol)) return
debuglog("Generating method " + m.symbol.fullName)
method = m
@ -861,7 +860,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
}
addGenericSignature(jmethod, m.symbol, clasz.symbol)
val (excs, others) = splitAnnotations(m.symbol.annotations, ThrowsClass)
val (excs, others) = m.symbol.annotations partition (_.symbol == ThrowsClass)
addExceptionsAttribute(jmethod, excs)
addAnnotations(jmethod, others)
addParamAnnotations(jmethod, m.params.map(_.sym.annotations))
@ -889,16 +888,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
}
}
/** Return a pair of lists of annotations, first one containing all
* annotations for the given symbol, and the rest.
*/
private def splitAnnotations(annotations: List[AnnotationInfo], annotSym: Symbol): (List[AnnotationInfo], List[AnnotationInfo]) = {
annotations.partition { a => a match {
case AnnotationInfo(tp, _, _) if tp.typeSymbol == annotSym => true
case _ => false
}}
}
private def isClosureApply(sym: Symbol): Boolean = {
(sym.name == nme.apply) &&
sym.owner.isSynthetic &&
@ -1051,7 +1040,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
if (!m.isDeferred)
addGenericSignature(mirrorMethod, m, module)
val (throws, others) = splitAnnotations(m.annotations, ThrowsClass)
val (throws, others) = m.annotations partition (_.symbol == ThrowsClass)
addExceptionsAttribute(mirrorMethod, throws)
addAnnotations(mirrorMethod, others)
addParamAnnotations(mirrorMethod, m.info.params.map(_.annotations))

View File

@ -1,7 +1,7 @@
/* NSC -- new Scala compiler
* Copyright 2007-2011 LAMP/EPFL
* @author David Bernard, Manohar Jonnalagedda
*/
/* NSC -- new Scala compiler
* Copyright 2007-2011 LAMP/EPFL
* @author David Bernard, Manohar Jonnalagedda
*/
package scala.tools.nsc.doc
package html

View File

@ -1,7 +1,7 @@
/* NSC -- new Scala compiler
* Copyright 2007-2011 LAMP/EPFL
* @author David Bernard, Manohar Jonnalagedda
*/
/* NSC -- new Scala compiler
* Copyright 2007-2011 LAMP/EPFL
* @author David Bernard, Manohar Jonnalagedda
*/
package scala.tools.nsc.doc.html

View File

@ -1,58 +1,58 @@
/* NSC -- new Scala compiler
* Copyright 2010-2011 LAMP/EPFL
* @author Stephane Micheloud
*/
package scala.tools.nsc.doc.html
import xml.NodeSeq
/** Highlight the syntax of Scala code appearing in a `{{{` wiki block
* (see method `HtmlPage.blockToHtml`).
*
* @author Stephane Micheloud
* @version 1.0
*/
private[html] object SyntaxHigh {
/** Reserved words, sorted alphabetically
/* NSC -- new Scala compiler
* Copyright 2010-2011 LAMP/EPFL
* @author Stephane Micheloud
*/
package scala.tools.nsc.doc.html
import xml.NodeSeq
/** Highlight the syntax of Scala code appearing in a `{{{` wiki block
* (see method `HtmlPage.blockToHtml`).
*
* @author Stephane Micheloud
* @version 1.0
*/
private[html] object SyntaxHigh {
/** Reserved words, sorted alphabetically
* (see [[scala.reflect.internal.StdNames]]) */
val reserved = Array(
"abstract", "case", "catch", "class", "def",
"do", "else", "extends", "false", "final", "finally",
"for", "if", "implicit", "import", "lazy", "match",
"new", "null", "object", "override", "package",
"private", "protected", "return", "sealed", "super",
"this", "throw", "trait", "true", "try", "type",
"val", "var", "while", "with", "yield")
/** Annotations, sorted alphabetically */
val annotations = Array(
"BeanProperty", "SerialVersionUID",
"beanGetter", "beanSetter", "bridge", "cloneable",
"deprecated", "deprecatedName",
"elidable", "field", "getter", "inline",
"migration", "native", "noinline", "param",
"remote", "setter", "specialized", "strictfp", "switch",
"tailrec", "throws", "transient",
"unchecked", "uncheckedStable", "uncheckedVariance",
"varargs", "volatile")
/** Standard library classes/objects, sorted alphabetically */
val standards = Array (
"Any", "AnyRef", "AnyVal", "App", "Application", "Array",
"Boolean", "Byte", "Char", "Class", "Console", "Double",
"Enumeration", "Float", "Function", "Int",
"List", "Long", "Manifest", "Map",
"None", "Nothing", "Null", "Object", "Option",
"Pair", "Predef",
"Seq", "Set", "Short", "Some", "String", "Symbol",
"Triple", "Unit")
def apply(data: String): NodeSeq = {
val buf = data.getBytes
val out = new StringBuilder
"private", "protected", "return", "sealed", "super",
"this", "throw", "trait", "true", "try", "type",
"val", "var", "while", "with", "yield")
/** Annotations, sorted alphabetically */
val annotations = Array(
"BeanProperty", "SerialVersionUID",
"beanGetter", "beanSetter", "bridge", "cloneable",
"deprecated", "deprecatedName",
"elidable", "field", "getter", "inline",
"migration", "native", "noinline", "param",
"remote", "setter", "specialized", "strictfp", "switch",
"tailrec", "throws", "transient",
"unchecked", "uncheckedStable", "uncheckedVariance",
"varargs", "volatile")
/** Standard library classes/objects, sorted alphabetically */
val standards = Array (
"Any", "AnyRef", "AnyVal", "App", "Application", "Array",
"Boolean", "Byte", "Char", "Class", "Console", "Double",
"Enumeration", "Float", "Function", "Int",
"List", "Long", "Manifest", "Map",
"None", "Nothing", "Null", "Object", "Option",
"Pair", "Predef",
"Seq", "Set", "Short", "Some", "String", "Symbol",
"Triple", "Unit")
def apply(data: String): NodeSeq = {
val buf = data.getBytes
val out = new StringBuilder
def compare(offset: Int, key: String): Int = {
var i = offset
var j = 0
@ -85,132 +85,132 @@ private[html] object SyntaxHigh {
else return m
}
-1
}
def comment(i: Int): String = {
val out = new StringBuilder("/")
def line(i: Int): Int =
if (i == buf.length || buf(i) == '\n') i
else {
out append buf(i).toChar
line(i+1)
}
var level = 0
def multiline(i: Int, star: Boolean): Int = {
if (i == buf.length) return i
val ch = buf(i).toChar
out append ch
ch match {
case '*' =>
if (star) level += 1
multiline(i+1, !star)
case '/' =>
if (star) {
if (level > 0) level -= 1
if (level == 0) i else multiline(i+1, true)
} else
multiline(i+1, false)
case _ =>
multiline(i+1, false)
}
}
if (buf(i) == '/') line(i) else multiline(i, true)
out.toString
}
/* e.g. `val endOfLine = '\u000A'`*/
def charlit(j: Int): String = {
val out = new StringBuilder("'")
def charlit0(i: Int, bslash: Boolean): Int = {
if (i == buf.length) i
else if (i > j+6) { out setLength 0; j }
else {
val ch = buf(i).toChar
out append ch
ch match {
case '\\' =>
charlit0(i+1, true)
case '\'' if !bslash =>
i
case _ =>
if (bslash && '0' <= ch && ch <= '9') charlit0(i+1, true)
else charlit0(i+1, false)
}
}
}
charlit0(j, false)
out.toString
}
def strlit(i: Int): String = {
val out = new StringBuilder("\"")
def strlit0(i: Int, bslash: Boolean): Int = {
if (i == buf.length) return i
val ch = buf(i).toChar
out append ch
ch match {
case '\\' =>
strlit0(i+1, true)
case '"' if !bslash =>
i
case _ =>
strlit0(i+1, false)
}
}
strlit0(i, false)
out.toString
}
def numlit(i: Int): String = {
val out = new StringBuilder
def intg(i: Int): Int = {
if (i == buf.length) return i
val ch = buf(i).toChar
ch match {
case '.' =>
out append ch
frac(i+1)
case _ =>
if (Character.isDigit(ch)) {
out append ch
intg(i+1)
} else i
}
}
def frac(i: Int): Int = {
if (i == buf.length) return i
val ch = buf(i).toChar
ch match {
case 'e' | 'E' =>
out append ch
expo(i+1, false)
case _ =>
if (Character.isDigit(ch)) {
out append ch
frac(i+1)
} else i
}
}
def expo(i: Int, signed: Boolean): Int = {
if (i == buf.length) return i
val ch = buf(i).toChar
ch match {
case '+' | '-' if !signed =>
out append ch
expo(i+1, true)
case _ =>
if (Character.isDigit(ch)) {
out append ch
expo(i+1, signed)
} else i
}
}
intg(i)
out.toString
}
}
def comment(i: Int): String = {
val out = new StringBuilder("/")
def line(i: Int): Int =
if (i == buf.length || buf(i) == '\n') i
else {
out append buf(i).toChar
line(i+1)
}
var level = 0
def multiline(i: Int, star: Boolean): Int = {
if (i == buf.length) return i
val ch = buf(i).toChar
out append ch
ch match {
case '*' =>
if (star) level += 1
multiline(i+1, !star)
case '/' =>
if (star) {
if (level > 0) level -= 1
if (level == 0) i else multiline(i+1, true)
} else
multiline(i+1, false)
case _ =>
multiline(i+1, false)
}
}
if (buf(i) == '/') line(i) else multiline(i, true)
out.toString
}
/* e.g. `val endOfLine = '\u000A'`*/
def charlit(j: Int): String = {
val out = new StringBuilder("'")
def charlit0(i: Int, bslash: Boolean): Int = {
if (i == buf.length) i
else if (i > j+6) { out setLength 0; j }
else {
val ch = buf(i).toChar
out append ch
ch match {
case '\\' =>
charlit0(i+1, true)
case '\'' if !bslash =>
i
case _ =>
if (bslash && '0' <= ch && ch <= '9') charlit0(i+1, true)
else charlit0(i+1, false)
}
}
}
charlit0(j, false)
out.toString
}
def strlit(i: Int): String = {
val out = new StringBuilder("\"")
def strlit0(i: Int, bslash: Boolean): Int = {
if (i == buf.length) return i
val ch = buf(i).toChar
out append ch
ch match {
case '\\' =>
strlit0(i+1, true)
case '"' if !bslash =>
i
case _ =>
strlit0(i+1, false)
}
}
strlit0(i, false)
out.toString
}
def numlit(i: Int): String = {
val out = new StringBuilder
def intg(i: Int): Int = {
if (i == buf.length) return i
val ch = buf(i).toChar
ch match {
case '.' =>
out append ch
frac(i+1)
case _ =>
if (Character.isDigit(ch)) {
out append ch
intg(i+1)
} else i
}
}
def frac(i: Int): Int = {
if (i == buf.length) return i
val ch = buf(i).toChar
ch match {
case 'e' | 'E' =>
out append ch
expo(i+1, false)
case _ =>
if (Character.isDigit(ch)) {
out append ch
frac(i+1)
} else i
}
}
def expo(i: Int, signed: Boolean): Int = {
if (i == buf.length) return i
val ch = buf(i).toChar
ch match {
case '+' | '-' if !signed =>
out append ch
expo(i+1, true)
case _ =>
if (Character.isDigit(ch)) {
out append ch
expo(i+1, signed)
} else i
}
}
intg(i)
out.toString
}
def parse(pre: String, i: Int): Int = {
out append pre
out append pre
if (i == buf.length) return i
buf(i) match {
case '\n' =>
@ -218,69 +218,69 @@ private[html] object SyntaxHigh {
case ' ' =>
parse(" ", i+1)
case '&' =>
parse("&amp;", i+1)
case '<' =>
val ch = buf(i+1).toChar
if (ch == '-' || ch == ':' || ch == '%')
parse("&amp;", i+1)
case '<' =>
val ch = buf(i+1).toChar
if (ch == '-' || ch == ':' || ch == '%')
parse("<span class=\"kw\">&lt;"+ch+"</span>", i+2)
else
else
parse("&lt;", i+1)
case '>' =>
if (buf(i+1) == ':')
parse("<span class=\"kw\">&gt;:</span>", i+2)
else
parse("&gt;", i+1)
case '=' =>
if (buf(i+1) == '>')
parse("<span class=\"kw\">=&gt;</span>", i+2)
else
parse(buf(i).toChar.toString, i+1)
case '/' =>
if (buf(i+1) == '/' || buf(i+1) == '*') {
val c = comment(i+1)
parse("<span class=\"cmt\">"+c+"</span>", i+c.length)
} else
parse(buf(i).toChar.toString, i+1)
case '\'' =>
val s = charlit(i+1)
if (s.length > 0)
parse("<span class=\"lit\">"+s+"</span>", i+s.length)
else
parse(buf(i).toChar.toString, i+1)
case '"' =>
val s = strlit(i+1)
parse("<span class=\"lit\">"+s+"</span>", i+s.length)
case '@' =>
val k = lookup(annotations, i+1)
if (k >= 0)
parse("<span class=\"ano\">@"+annotations(k)+"</span>", i+annotations(k).length+1)
else
parse(buf(i).toChar.toString, i+1)
if (buf(i+1) == ':')
parse("<span class=\"kw\">&gt;:</span>", i+2)
else
parse("&gt;", i+1)
case '=' =>
if (buf(i+1) == '>')
parse("<span class=\"kw\">=&gt;</span>", i+2)
else
parse(buf(i).toChar.toString, i+1)
case '/' =>
if (buf(i+1) == '/' || buf(i+1) == '*') {
val c = comment(i+1)
parse("<span class=\"cmt\">"+c+"</span>", i+c.length)
} else
parse(buf(i).toChar.toString, i+1)
case '\'' =>
val s = charlit(i+1)
if (s.length > 0)
parse("<span class=\"lit\">"+s+"</span>", i+s.length)
else
parse(buf(i).toChar.toString, i+1)
case '"' =>
val s = strlit(i+1)
parse("<span class=\"lit\">"+s+"</span>", i+s.length)
case '@' =>
val k = lookup(annotations, i+1)
if (k >= 0)
parse("<span class=\"ano\">@"+annotations(k)+"</span>", i+annotations(k).length+1)
else
parse(buf(i).toChar.toString, i+1)
case _ =>
if (i == 0 || !Character.isJavaIdentifierPart(buf(i-1).toChar)) {
if (Character.isDigit(buf(i)) ||
(buf(i) == '.' && Character.isDigit(buf(i+1)))) {
val s = numlit(i)
parse("<span class=\"num\">"+s+"</span>", i+s.length)
} else {
if (Character.isDigit(buf(i)) ||
(buf(i) == '.' && Character.isDigit(buf(i+1)))) {
val s = numlit(i)
parse("<span class=\"num\">"+s+"</span>", i+s.length)
} else {
val k = lookup(reserved, i)
if (k >= 0)
if (k >= 0)
parse("<span class=\"kw\">"+reserved(k)+"</span>", i+reserved(k).length)
else {
val k = lookup(standards, i)
if (k >= 0)
parse("<span class=\"std\">"+standards(k)+"</span>", i+standards(k).length)
else
parse(buf(i).toChar.toString, i+1)
}
else {
val k = lookup(standards, i)
if (k >= 0)
parse("<span class=\"std\">"+standards(k)+"</span>", i+standards(k).length)
else
parse(buf(i).toChar.toString, i+1)
}
}
} else
} else
parse(buf(i).toChar.toString, i+1)
}
}
i
}
parse("", 0)
xml.Unparsed(out.toString)
}
}
}
parse("", 0)
xml.Unparsed(out.toString)
}
}

View File

@ -1,7 +1,7 @@
/* NSC -- new Scala compiler
* Copyright 2007-2011 LAMP/EPFL
* @author David Bernard, Manohar Jonnalagedda
*/
/* NSC -- new Scala compiler
* Copyright 2007-2011 LAMP/EPFL
* @author David Bernard, Manohar Jonnalagedda
*/
package scala.tools.nsc.doc.html.page

View File

@ -12,18 +12,18 @@
NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d=this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},enableSelection:function(){return this.attr("unselectable","off").css("MozUserSelect","")},disableSelection:function(){return this.attr("unselectable","on").css("MozUserSelect",
"none")},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this,"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",
1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==undefined)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position");if(b=="absolute"||b=="relative"||b=="fixed"){b=parseInt(a.css("zIndex"));if(!isNaN(b)&&b!=0)return b}a=a.parent()}}return 0}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){var b=a.nodeName.toLowerCase(),d=c.attr(a,"tabindex");return(/input|select|textarea|button|object/.test(b)?
!a.disabled:"a"==b||"area"==b?a.href||!isNaN(d):!isNaN(d))&&!c(a)["area"==b?"parents":"closest"](":hidden").length},tabbable:function(a){var b=c.attr(a,"tabindex");return(isNaN(b)||b>=0)&&c(a).is(":focusable")}})}})(jQuery);
!a.disabled:"a"==b||"area"==b?a.href||!isNaN(d):!isNaN(d))&&!c(a)["area"==b?"parents":"closest"](":hidden").length},tabbable:function(a){var b=c.attr(a,"tabindex");return(isNaN(b)||b>=0)&&c(a).is(":focusable")}})}})(jQuery);
(function(b){var j=b.fn.remove;b.fn.remove=function(a,c){return this.each(function(){if(!c)if(!a||b.filter(a,[this]).length)b("*",this).add(this).each(function(){b(this).triggerHandler("remove")});return j.call(b(this),a,c)})};b.widget=function(a,c,d){var e=a.split(".")[0],g;a=a.split(".")[1];g=e+"-"+a;if(!d){d=c;c=b.Widget}b.expr[":"][g]=function(f){return!!b.data(f,a)};b[e]=b[e]||{};b[e][a]=function(f,i){arguments.length&&this._createWidget(f,i)};var h=new c;h.options=b.extend({},h.options);b[e][a].prototype=
b.extend(true,h,{namespace:e,widgetName:a,widgetEventPrefix:b[e][a].prototype.widgetEventPrefix||a,widgetBaseClass:g,base:c.prototype},d);b.widget.bridge(a,b[e][a])};b.widget.bridge=function(a,c){b.fn[a]=function(d){var e=typeof d==="string",g=Array.prototype.slice.call(arguments,1),h=this;d=!e&&g.length?b.extend.apply(null,[true,d].concat(g)):d;if(e&&d.substring(0,1)==="_")return h;e?this.each(function(){var f=b.data(this,a),i=f&&b.isFunction(f[d])?f[d].apply(f,g):f;if(i!==f&&i!==undefined){h=i;
return false}}):this.each(function(){var f=b.data(this,a);if(f){d&&f.option(d);f._init()}else b.data(this,a,new c(d,this))});return h}};b.Widget=function(a,c){arguments.length&&this._createWidget(a,c)};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(a,c){this.element=b(c).data(this.widgetName,this);this.options=b.extend(true,{},this.options,b.metadata&&b.metadata.get(c)[this.widgetName],a);var d=this;this.element.bind("remove."+this.widgetName,
function(){d.destroy()});this._create();this._init()},_create:function(){},_init:function(){},_super:function(a){return this.base[a].apply(this,Array.prototype.slice.call(arguments,1))},_superApply:function(a,c){return this.base[a].apply(this,c)},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},widget:function(){return this.element},
option:function(a,c){var d=a,e=this;if(arguments.length===0)return b.extend({},e.options);if(typeof a==="string"){if(c===undefined)return this.options[a];d={};d[a]=c}b.each(d,function(g,h){e._setOption(g,h)});return e},_setOption:function(a,c){this.options[a]=c;if(a==="disabled")this.widget()[c?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",c);return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",
true)},_trigger:function(a,c,d){var e=this.options[a];c=b.Event(c);c.type=(a===this.widgetEventPrefix?a:this.widgetEventPrefix+a).toLowerCase();d=d||{};if(c.originalEvent){a=b.event.props.length;for(var g;a;){g=b.event.props[--a];c[g]=c.originalEvent[g]}}this.element.trigger(c,d);return!(b.isFunction(e)&&e.call(this.element[0],c,d)===false||c.isDefaultPrevented())}}})(jQuery);
true)},_trigger:function(a,c,d){var e=this.options[a];c=b.Event(c);c.type=(a===this.widgetEventPrefix?a:this.widgetEventPrefix+a).toLowerCase();d=d||{};if(c.originalEvent){a=b.event.props.length;for(var g;a;){g=b.event.props[--a];c[g]=c.originalEvent[g]}}this.element.trigger(c,d);return!(b.isFunction(e)&&e.call(this.element[0],c,d)===false||c.isDefaultPrevented())}}})(jQuery);
(function(c){c.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var a=this;this.element.bind("mousedown."+this.widgetName,function(b){return a._mouseDown(b)}).bind("click."+this.widgetName,function(b){if(a._preventClickEvent){a._preventClickEvent=false;b.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(a){a.originalEvent=a.originalEvent||{};if(!a.originalEvent.mouseHandled){this._mouseStarted&&
this._mouseUp(a);this._mouseDownEvent=a;var b=this,e=a.which==1,f=typeof this.options.cancel=="string"?c(a.target).parents().add(a.target).filter(this.options.cancel).length:false;if(!e||f||!this._mouseCapture(a))return true;this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet)this._mouseDelayTimer=setTimeout(function(){b.mouseDelayMet=true},this.options.delay);if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a)){this._mouseStarted=this._mouseStart(a)!==false;if(!this._mouseStarted){a.preventDefault();
return true}}this._mouseMoveDelegate=function(d){return b._mouseMove(d)};this._mouseUpDelegate=function(d){return b._mouseUp(d)};c(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);c.browser.safari||a.preventDefault();return a.originalEvent.mouseHandled=true}},_mouseMove:function(a){if(c.browser.msie&&!a.button)return this._mouseUp(a);if(this._mouseStarted){this._mouseDrag(a);return a.preventDefault()}if(this._mouseDistanceMet(a)&&
this._mouseDelayMet(a))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,a)!==false)?this._mouseDrag(a):this._mouseUp(a);return!this._mouseStarted},_mouseUp:function(a){c(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;this._preventClickEvent=a.target==this._mouseDownEvent.target;this._mouseStop(a)}return false},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-
a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery);
a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery);
(function(d){d.widget("ui.draggable",d.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:true,appendTo:"parent",axis:false,connectToSortable:false,containment:false,cursor:"auto",cursorAt:false,grid:false,handle:false,helper:"original",iframeFix:false,opacity:false,refreshPositions:false,revert:false,revertDuration:500,scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,snap:false,snapMode:"both",snapTolerance:20,stack:false,zIndex:false},_create:function(){if(this.options.helper==
"original"&&!/^(?:r|a|f)/.test(this.element.css("position")))this.element[0].style.position="relative";this.options.addClasses&&this.element.addClass("ui-draggable");this.options.disabled&&this.element.addClass("ui-draggable-disabled");this._mouseInit()},destroy:function(){if(this.element.data("draggable")){this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy();return this}},_mouseCapture:function(a){var b=
this.options;if(this.helper||b.disabled||d(a.target).is(".ui-resizable-handle"))return false;this.handle=this._getHandle(a);if(!this.handle)return false;return true},_mouseStart:function(a){var b=this.options;this.helper=this._createHelper(a);this._cacheHelperProportions();if(d.ui.ddmanager)d.ui.ddmanager.current=this;this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.positionAbs=this.element.offset();this.offset={top:this.offset.top-
@ -58,7 +58,7 @@ width:c.outerWidth(),height:c.outerHeight(),top:f.top,left:f.left})})},drag:func
o<l+e){if(f.snapMode!="inner"){var p=Math.abs(j-o)<=e,q=Math.abs(l-m)<=e,r=Math.abs(i-n)<=e,s=Math.abs(k-g)<=e;if(p)b.position.top=c._convertPositionTo("relative",{top:j-c.helperProportions.height,left:0}).top-c.margins.top;if(q)b.position.top=c._convertPositionTo("relative",{top:l,left:0}).top-c.margins.top;if(r)b.position.left=c._convertPositionTo("relative",{top:0,left:i-c.helperProportions.width}).left-c.margins.left;if(s)b.position.left=c._convertPositionTo("relative",{top:0,left:k}).left-c.margins.left}var t=
p||q||r||s;if(f.snapMode!="outer"){p=Math.abs(j-m)<=e;q=Math.abs(l-o)<=e;r=Math.abs(i-g)<=e;s=Math.abs(k-n)<=e;if(p)b.position.top=c._convertPositionTo("relative",{top:j,left:0}).top-c.margins.top;if(q)b.position.top=c._convertPositionTo("relative",{top:l-c.helperProportions.height,left:0}).top-c.margins.top;if(r)b.position.left=c._convertPositionTo("relative",{top:0,left:i}).left-c.margins.left;if(s)b.position.left=c._convertPositionTo("relative",{top:0,left:k-c.helperProportions.width}).left-c.margins.left}if(!c.snapElements[h].snapping&&
(p||q||r||s||t))c.options.snap.snap&&c.options.snap.snap.call(c.element,a,d.extend(c._uiHash(),{snapItem:c.snapElements[h].item}));c.snapElements[h].snapping=p||q||r||s||t}else{c.snapElements[h].snapping&&c.options.snap.release&&c.options.snap.release.call(c.element,a,d.extend(c._uiHash(),{snapItem:c.snapElements[h].item}));c.snapElements[h].snapping=false}}}});d.ui.plugin.add("draggable","stack",{start:function(){var a=d(this).data("draggable").options;a=d.makeArray(d(a.stack)).sort(function(c,f){return(parseInt(d(c).css("zIndex"),
10)||0)-(parseInt(d(f).css("zIndex"),10)||0)});if(a.length){var b=parseInt(a[0].style.zIndex)||0;d(a).each(function(c){this.style.zIndex=b+c});this[0].style.zIndex=b+a.length}}});d.ui.plugin.add("draggable","zIndex",{start:function(a,b){a=d(b.helper);b=d(this).data("draggable").options;if(a.css("zIndex"))b._zIndex=a.css("zIndex");a.css("zIndex",b.zIndex)},stop:function(a,b){a=d(this).data("draggable").options;a._zIndex&&d(b.helper).css("zIndex",a._zIndex)}})})(jQuery);
10)||0)-(parseInt(d(f).css("zIndex"),10)||0)});if(a.length){var b=parseInt(a[0].style.zIndex)||0;d(a).each(function(c){this.style.zIndex=b+c});this[0].style.zIndex=b+a.length}}});d.ui.plugin.add("draggable","zIndex",{start:function(a,b){a=d(b.helper);b=d(this).data("draggable").options;if(a.css("zIndex"))b._zIndex=a.css("zIndex");a.css("zIndex",b.zIndex)},stop:function(a,b){a=d(this).data("draggable").options;a._zIndex&&d(b.helper).css("zIndex",a._zIndex)}})})(jQuery);
(function(d){d.widget("ui.droppable",{widgetEventPrefix:"drop",options:{accept:"*",activeClass:false,addClasses:true,greedy:false,hoverClass:false,scope:"default",tolerance:"intersect"},_create:function(){var a=this.options,b=a.accept;this.isover=0;this.isout=1;this.accept=d.isFunction(b)?b:function(c){return c.is(b)};this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight};d.ui.ddmanager.droppables[a.scope]=d.ui.ddmanager.droppables[a.scope]||[];d.ui.ddmanager.droppables[a.scope].push(this);
a.addClasses&&this.element.addClass("ui-droppable")},destroy:function(){for(var a=d.ui.ddmanager.droppables[this.options.scope],b=0;b<a.length;b++)a[b]==this&&a.splice(b,1);this.element.removeClass("ui-droppable ui-droppable-disabled").removeData("droppable").unbind(".droppable");return this},_setOption:function(a,b){if(a=="accept")this.accept=d.isFunction(b)?b:function(c){return c.is(b)};d.Widget.prototype._setOption.apply(this,arguments)},_activate:function(a){var b=d.ui.ddmanager.current;this.options.activeClass&&
this.element.addClass(this.options.activeClass);b&&this._trigger("activate",a,this.ui(b))},_deactivate:function(a){var b=d.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass);b&&this._trigger("deactivate",a,this.ui(b))},_over:function(a){var b=d.ui.ddmanager.current;if(!(!b||(b.currentItem||b.element)[0]==this.element[0]))if(this.accept.call(this.element[0],b.currentItem||b.element)){this.options.hoverClass&&this.element.addClass(this.options.hoverClass);
@ -69,7 +69,7 @@ switch(c){case "fit":return i<e&&g<k&&j<f&&h<l;case "intersect":return i<e+a.hel
e<=k||g>=i&&g<=k||e<i&&g>k);default:return false}};d.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(a,b){var c=d.ui.ddmanager.droppables[a.options.scope]||[],e=b?b.type:null,g=(a.currentItem||a.element).find(":data(droppable)").andSelf(),f=0;a:for(;f<c.length;f++)if(!(c[f].options.disabled||a&&!c[f].accept.call(c[f].element[0],a.currentItem||a.element))){for(var h=0;h<g.length;h++)if(g[h]==c[f].element[0]){c[f].proportions.height=0;continue a}c[f].visible=c[f].element.css("display")!=
"none";if(c[f].visible){c[f].offset=c[f].element.offset();c[f].proportions={width:c[f].element[0].offsetWidth,height:c[f].element[0].offsetHeight};e=="mousedown"&&c[f]._activate.call(c[f],b)}}},drop:function(a,b){var c=false;d.each(d.ui.ddmanager.droppables[a.options.scope]||[],function(){if(this.options){if(!this.options.disabled&&this.visible&&d.ui.intersect(a,this,this.options.tolerance))c=c||this._drop.call(this,b);if(!this.options.disabled&&this.visible&&this.accept.call(this.element[0],a.currentItem||
a.element)){this.isout=1;this.isover=0;this._deactivate.call(this,b)}}});return c},drag:function(a,b){a.options.refreshPositions&&d.ui.ddmanager.prepareOffsets(a,b);d.each(d.ui.ddmanager.droppables[a.options.scope]||[],function(){if(!(this.options.disabled||this.greedyChild||!this.visible)){var c=d.ui.intersect(a,this,this.options.tolerance);if(c=!c&&this.isover==1?"isout":c&&this.isover==0?"isover":null){var e;if(this.options.greedy){var g=this.element.parents(":data(droppable):eq(0)");if(g.length){e=
d.data(g[0],"droppable");e.greedyChild=c=="isover"?1:0}}if(e&&c=="isover"){e.isover=0;e.isout=1;e._out.call(e,b)}this[c]=1;this[c=="isout"?"isover":"isout"]=0;this[c=="isover"?"_over":"_out"].call(this,b);if(e&&c=="isout"){e.isout=0;e.isover=1;e._over.call(e,b)}}}})}}})(jQuery);
d.data(g[0],"droppable");e.greedyChild=c=="isover"?1:0}}if(e&&c=="isover"){e.isover=0;e.isout=1;e._out.call(e,b)}this[c]=1;this[c=="isout"?"isover":"isout"]=0;this[c=="isover"?"_over":"_out"].call(this,b);if(e&&c=="isout"){e.isout=0;e.isover=1;e._over.call(e,b)}}}})}}})(jQuery);
(function(e){e.widget("ui.resizable",e.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1E3},_create:function(){var b=this,a=this.options;this.element.addClass("ui-resizable");e.extend(this,{_aspectRatio:!!a.aspectRatio,aspectRatio:a.aspectRatio,originalElement:this.element,
_proportionallyResizeElements:[],_helper:a.helper||a.ghost||a.animate?a.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){/relative/.test(this.element.css("position"))&&e.browser.opera&&this.element.css({position:"relative",top:"auto",left:"auto"});this.element.wrap(e('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),
top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=
@ -102,7 +102,7 @@ a.parentData.left+a.position.left;a.offset.top=a.parentData.top+a.position.top;c
a.size.height>=a.parentData.height){a.size.height=a.parentData.height-d;if(b)a.size.width=a.size.height*a.aspectRatio}},stop:function(){var b=e(this).data("resizable"),a=b.options,c=b.containerOffset,d=b.containerPosition,f=b.containerElement,g=e(b.helper),h=g.offset(),i=g.outerWidth()-b.sizeDiff.width;g=g.outerHeight()-b.sizeDiff.height;b._helper&&!a.animate&&/relative/.test(f.css("position"))&&e(this).css({left:h.left-d.left-c.left,width:i,height:g});b._helper&&!a.animate&&/static/.test(f.css("position"))&&
e(this).css({left:h.left-d.left-c.left,width:i,height:g})}});e.ui.plugin.add("resizable","ghost",{start:function(){var b=e(this).data("resizable"),a=b.options,c=b.size;b.ghost=b.originalElement.clone();b.ghost.css({opacity:0.25,display:"block",position:"relative",height:c.height,width:c.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof a.ghost=="string"?a.ghost:"");b.ghost.appendTo(b.helper)},resize:function(){var b=e(this).data("resizable");b.ghost&&b.ghost.css({position:"relative",
height:b.size.height,width:b.size.width})},stop:function(){var b=e(this).data("resizable");b.ghost&&b.helper&&b.helper.get(0).removeChild(b.ghost.get(0))}});e.ui.plugin.add("resizable","grid",{resize:function(){var b=e(this).data("resizable"),a=b.options,c=b.size,d=b.originalSize,f=b.originalPosition,g=b.axis;a.grid=typeof a.grid=="number"?[a.grid,a.grid]:a.grid;var h=Math.round((c.width-d.width)/(a.grid[0]||1))*(a.grid[0]||1);a=Math.round((c.height-d.height)/(a.grid[1]||1))*(a.grid[1]||1);if(/^(se|s|e)$/.test(g)){b.size.width=
d.width+h;b.size.height=d.height+a}else if(/^(ne)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}else{if(/^(sw)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a}else{b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}b.position.left=f.left-h}}});var m=function(b){return parseInt(b,10)||0},l=function(b){return!isNaN(parseInt(b,10))}})(jQuery);
d.width+h;b.size.height=d.height+a}else if(/^(ne)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}else{if(/^(sw)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a}else{b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}b.position.left=f.left-h}}});var m=function(b){return parseInt(b,10)||0},l=function(b){return!isNaN(parseInt(b,10))}})(jQuery);
(function(e){e.widget("ui.selectable",e.ui.mouse,{options:{appendTo:"body",autoRefresh:true,distance:0,filter:"*",tolerance:"touch"},_create:function(){var c=this;this.element.addClass("ui-selectable");this.dragged=false;var f;this.refresh=function(){f=e(c.options.filter,c.element[0]);f.each(function(){var d=e(this),b=d.offset();e.data(this,"selectable-item",{element:this,$element:d,left:b.left,top:b.top,right:b.left+d.outerWidth(),bottom:b.top+d.outerHeight(),startselected:false,selected:d.hasClass("ui-selected"),
selecting:d.hasClass("ui-selecting"),unselecting:d.hasClass("ui-unselecting")})})};this.refresh();this.selectees=f.addClass("ui-selectee");this._mouseInit();this.helper=e("<div class='ui-selectable-helper'></div>")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item");this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy();return this},_mouseStart:function(c){var f=this;this.opos=[c.pageX,
c.pageY];if(!this.options.disabled){var d=this.options;this.selectees=e(d.filter,this.element[0]);this._trigger("start",c);e(d.appendTo).append(this.helper);this.helper.css({left:c.clientX,top:c.clientY,width:0,height:0});d.autoRefresh&&this.refresh();this.selectees.filter(".ui-selected").each(function(){var b=e.data(this,"selectable-item");b.startselected=true;if(!c.metaKey){b.$element.removeClass("ui-selected");b.selected=false;b.$element.addClass("ui-unselecting");b.unselecting=true;f._trigger("unselecting",
@ -110,7 +110,7 @@ c,{unselecting:b.element})}});e(c.target).parents().andSelf().each(function(){va
this.options,b=this.opos[0],g=this.opos[1],h=c.pageX,i=c.pageY;if(b>h){var j=h;h=b;b=j}if(g>i){j=i;i=g;g=j}this.helper.css({left:b,top:g,width:h-b,height:i-g});this.selectees.each(function(){var a=e.data(this,"selectable-item");if(!(!a||a.element==f.element[0])){var k=false;if(d.tolerance=="touch")k=!(a.left>h||a.right<b||a.top>i||a.bottom<g);else if(d.tolerance=="fit")k=a.left>b&&a.right<h&&a.top>g&&a.bottom<i;if(k){if(a.selected){a.$element.removeClass("ui-selected");a.selected=false}if(a.unselecting){a.$element.removeClass("ui-unselecting");
a.unselecting=false}if(!a.selecting){a.$element.addClass("ui-selecting");a.selecting=true;f._trigger("selecting",c,{selecting:a.element})}}else{if(a.selecting)if(c.metaKey&&a.startselected){a.$element.removeClass("ui-selecting");a.selecting=false;a.$element.addClass("ui-selected");a.selected=true}else{a.$element.removeClass("ui-selecting");a.selecting=false;if(a.startselected){a.$element.addClass("ui-unselecting");a.unselecting=true}f._trigger("unselecting",c,{unselecting:a.element})}if(a.selected)if(!c.metaKey&&
!a.startselected){a.$element.removeClass("ui-selected");a.selected=false;a.$element.addClass("ui-unselecting");a.unselecting=true;f._trigger("unselecting",c,{unselecting:a.element})}}}});return false}},_mouseStop:function(c){var f=this;this.dragged=false;e(".ui-unselecting",this.element[0]).each(function(){var d=e.data(this,"selectable-item");d.$element.removeClass("ui-unselecting");d.unselecting=false;d.startselected=false;f._trigger("unselected",c,{unselected:d.element})});e(".ui-selecting",this.element[0]).each(function(){var d=
e.data(this,"selectable-item");d.$element.removeClass("ui-selecting").addClass("ui-selected");d.selecting=false;d.selected=true;d.startselected=true;f._trigger("selected",c,{selected:d.element})});this._trigger("stop",c);this.helper.remove();return false}});e.extend(e.ui.selectable,{version:"1.9m2"})})(jQuery);
e.data(this,"selectable-item");d.$element.removeClass("ui-selecting").addClass("ui-selected");d.selecting=false;d.selected=true;d.startselected=true;f._trigger("selected",c,{selected:d.element})});this._trigger("stop",c);this.helper.remove();return false}});e.extend(e.ui.selectable,{version:"1.9m2"})})(jQuery);
(function(d){d.widget("ui.sortable",d.ui.mouse,{widgetEventPrefix:"sort",options:{appendTo:"parent",axis:false,connectWith:false,containment:false,cursor:"auto",cursorAt:false,dropOnEmpty:true,forcePlaceholderSize:false,forceHelperSize:false,grid:false,handle:false,helper:"original",items:"> *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1E3},_create:function(){this.containerCache={};this.element.addClass("ui-sortable");
this.refresh();this.floating=this.items.length?/left|right/.test(this.items[0].item.css("float")):false;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var a=this.items.length-1;a>=0;a--)this.items[a].item.removeData("sortable-item");return this},_setOption:function(a,b){if(a==="disabled"){this.options[a]=b;this.widget()[b?"addClass":"removeClass"]("ui-sortable-disabled")}else this._superApply("_setOption",
arguments)},_mouseCapture:function(a,b){if(this.reverting)return false;if(this.options.disabled||this.options.type=="static")return false;this._refreshItems(a);var c=null,e=this;d(a.target).parents().each(function(){if(d.data(this,"sortable-item")==e){c=d(this);return false}});if(d.data(a.target,"sortable-item")==e)c=d(a.target);if(!c)return false;if(this.options.handle&&!b){var f=false;d(this.options.handle,c).find("*").andSelf().each(function(){if(this==a.target)f=true});if(!f)return false}this.currentItem=
@ -155,7 +155,7 @@ this.currentItem[0].parentNode&&this.placeholder.before(this.currentItem);this._
this.domPosition.parent!=this.currentItem.parent()[0])&&!b)c.push(function(f){this._trigger("update",f,this._uiHash())});if(!d.ui.contains(this.element[0],this.currentItem[0])){b||c.push(function(f){this._trigger("remove",f,this._uiHash())});for(e=this.containers.length-1;e>=0;e--)if(d.ui.contains(this.containers[e].element[0],this.currentItem[0])&&!b){c.push(function(f){return function(g){f._trigger("receive",g,this._uiHash(this))}}.call(this,this.containers[e]));c.push(function(f){return function(g){f._trigger("update",
g,this._uiHash(this))}}.call(this,this.containers[e]))}}for(e=this.containers.length-1;e>=0;e--){b||c.push(function(f){return function(g){f._trigger("deactivate",g,this._uiHash(this))}}.call(this,this.containers[e]));if(this.containers[e].containerCache.over){c.push(function(f){return function(g){f._trigger("out",g,this._uiHash(this))}}.call(this,this.containers[e]));this.containers[e].containerCache.over=0}}this._storedCursor&&d("body").css("cursor",this._storedCursor);this._storedOpacity&&this.helper.css("opacity",
this._storedOpacity);if(this._storedZIndex)this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex);this.dragging=false;if(this.cancelHelperRemoval){if(!b){this._trigger("beforeStop",a,this._uiHash());for(e=0;e<c.length;e++)c[e].call(this,a);this._trigger("stop",a,this._uiHash())}return false}b||this._trigger("beforeStop",a,this._uiHash());this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.helper[0]!=this.currentItem[0]&&this.helper.remove();this.helper=null;if(!b){for(e=
0;e<c.length;e++)c[e].call(this,a);this._trigger("stop",a,this._uiHash())}this.fromOutside=false;return true},_trigger:function(){d.Widget.prototype._trigger.apply(this,arguments)===false&&this.cancel()},_uiHash:function(a){var b=a||this;return{helper:b.helper,placeholder:b.placeholder||d([]),position:b.position,originalPosition:b.originalPosition,offset:b.positionAbs,item:b.currentItem,sender:a?a.element:null}}});d.extend(d.ui.sortable,{version:"1.9m2"})})(jQuery);
0;e<c.length;e++)c[e].call(this,a);this._trigger("stop",a,this._uiHash())}this.fromOutside=false;return true},_trigger:function(){d.Widget.prototype._trigger.apply(this,arguments)===false&&this.cancel()},_uiHash:function(a){var b=a||this;return{helper:b.helper,placeholder:b.placeholder||d([]),position:b.position,originalPosition:b.originalPosition,offset:b.positionAbs,item:b.currentItem,sender:a?a.element:null}}});d.extend(d.ui.sortable,{version:"1.9m2"})})(jQuery);
jQuery.effects||function(f){function k(c){var a;if(c&&c.constructor==Array&&c.length==3)return c;if(a=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(c))return[parseInt(a[1],10),parseInt(a[2],10),parseInt(a[3],10)];if(a=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(c))return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55];if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(c))return[parseInt(a[1],
16),parseInt(a[2],16),parseInt(a[3],16)];if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(c))return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)];if(/rgba\(0, 0, 0, 0\)/.exec(c))return l.transparent;return l[f.trim(c).toLowerCase()]}function q(c,a){var b;do{b=f.curCSS(c,a);if(b!=""&&b!="transparent"||f.nodeName(c,"body"))break;a="backgroundColor"}while(c=c.parentNode);return k(b)}function m(){var c=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle,
a={},b,d;if(c&&c.length&&c[0]&&c[c[0]])for(var e=c.length;e--;){b=c[e];if(typeof c[b]=="string"){d=b.replace(/\-(\w)/g,function(g,h){return h.toUpperCase()});a[d]=c[b]}}else for(b in c)if(typeof c[b]==="string")a[b]=c[b];return a}function n(c){var a,b;for(a in c){b=c[a];if(b==null||f.isFunction(b)||a in r||/scrollbar/.test(a)||!/color/i.test(a)&&isNaN(parseFloat(b)))delete c[a]}return c}function s(c,a){var b={_:0},d;for(d in a)if(c[d]!=a[d])b[d]=a[d];return b}function j(c,a,b,d){if(typeof c=="object"){d=
@ -176,26 +176,26 @@ b},easeInQuint:function(c,a,b,d,e){return d*(a/=e)*a*a*a*a+b},easeOutQuint:funct
a)+1)+b},easeInElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h<Math.abs(d)){h=d;c=g/4}else c=g/(2*Math.PI)*Math.asin(d/h);return-(h*Math.pow(2,10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g))+b},easeOutElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h<Math.abs(d)){h=d;c=g/4}else c=g/(2*Math.PI)*Math.asin(d/h);return h*Math.pow(2,-10*a)*Math.sin((a*e-c)*2*Math.PI/g)+d+b},easeInOutElastic:function(c,
a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e/2)==2)return b+d;g||(g=e*0.3*1.5);if(h<Math.abs(d)){h=d;c=g/4}else c=g/(2*Math.PI)*Math.asin(d/h);if(a<1)return-0.5*h*Math.pow(2,10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g)+b;return h*Math.pow(2,-10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g)*0.5+d+b},easeInBack:function(c,a,b,d,e,g){if(g==undefined)g=1.70158;return d*(a/=e)*a*((g+1)*a-g)+b},easeOutBack:function(c,a,b,d,e,g){if(g==undefined)g=1.70158;return d*((a=a/e-1)*a*((g+1)*a+g)+1)+b},easeInOutBack:function(c,
a,b,d,e,g){if(g==undefined)g=1.70158;if((a/=e/2)<1)return d/2*a*a*(((g*=1.525)+1)*a-g)+b;return d/2*((a-=2)*a*(((g*=1.525)+1)*a+g)+2)+b},easeInBounce:function(c,a,b,d,e){return d-f.easing.easeOutBounce(c,e-a,0,d,e)+b},easeOutBounce:function(c,a,b,d,e){return(a/=e)<1/2.75?d*7.5625*a*a+b:a<2/2.75?d*(7.5625*(a-=1.5/2.75)*a+0.75)+b:a<2.5/2.75?d*(7.5625*(a-=2.25/2.75)*a+0.9375)+b:d*(7.5625*(a-=2.625/2.75)*a+0.984375)+b},easeInOutBounce:function(c,a,b,d,e){if(a<e/2)return f.easing.easeInBounce(c,a*2,0,
d,e)*0.5+b;return f.easing.easeOutBounce(c,a*2-e,0,d,e)*0.5+d*0.5+b}})}(jQuery);
d,e)*0.5+b;return f.easing.easeOutBounce(c,a*2-e,0,d,e)*0.5+d*0.5+b}})}(jQuery);
(function(b){b.effects.blind=function(c){return this.queue(function(){var a=b(this),g=["position","top","left"],f=b.effects.setMode(a,c.options.mode||"hide"),d=c.options.direction||"vertical";b.effects.save(a,g);a.show();var e=b.effects.createWrapper(a).css({overflow:"hidden"}),h=d=="vertical"?"height":"width";d=d=="vertical"?e.height():e.width();f=="show"&&e.css(h,0);var i={};i[h]=f=="show"?d:0;e.animate(i,c.duration,c.options.easing,function(){f=="hide"&&a.hide();b.effects.restore(a,g);b.effects.removeWrapper(a);
c.callback&&c.callback.apply(a[0],arguments);a.dequeue()})})}})(jQuery);
c.callback&&c.callback.apply(a[0],arguments);a.dequeue()})})}})(jQuery);
(function(e){e.effects.bounce=function(b){return this.queue(function(){var a=e(this),l=["position","top","left"],h=e.effects.setMode(a,b.options.mode||"effect"),d=b.options.direction||"up",c=b.options.distance||20,m=b.options.times||5,i=b.duration||250;/show|hide/.test(h)&&l.push("opacity");e.effects.save(a,l);a.show();e.effects.createWrapper(a);var f=d=="up"||d=="down"?"top":"left";d=d=="up"||d=="left"?"pos":"neg";c=b.options.distance||(f=="top"?a.outerHeight({margin:true})/3:a.outerWidth({margin:true})/
3);if(h=="show")a.css("opacity",0).css(f,d=="pos"?-c:c);if(h=="hide")c/=m*2;h!="hide"&&m--;if(h=="show"){var g={opacity:1};g[f]=(d=="pos"?"+=":"-=")+c;a.animate(g,i/2,b.options.easing);c/=2;m--}for(g=0;g<m;g++){var j={},k={};j[f]=(d=="pos"?"-=":"+=")+c;k[f]=(d=="pos"?"+=":"-=")+c;a.animate(j,i/2,b.options.easing).animate(k,i/2,b.options.easing);c=h=="hide"?c*2:c/2}if(h=="hide"){g={opacity:0};g[f]=(d=="pos"?"-=":"+=")+c;a.animate(g,i/2,b.options.easing,function(){a.hide();e.effects.restore(a,l);e.effects.removeWrapper(a);
b.callback&&b.callback.apply(this,arguments)})}else{j={};k={};j[f]=(d=="pos"?"-=":"+=")+c;k[f]=(d=="pos"?"+=":"-=")+c;a.animate(j,i/2,b.options.easing).animate(k,i/2,b.options.easing,function(){e.effects.restore(a,l);e.effects.removeWrapper(a);b.callback&&b.callback.apply(this,arguments)})}a.queue("fx",function(){a.dequeue()});a.dequeue()})}})(jQuery);
b.callback&&b.callback.apply(this,arguments)})}else{j={};k={};j[f]=(d=="pos"?"-=":"+=")+c;k[f]=(d=="pos"?"+=":"-=")+c;a.animate(j,i/2,b.options.easing).animate(k,i/2,b.options.easing,function(){e.effects.restore(a,l);e.effects.removeWrapper(a);b.callback&&b.callback.apply(this,arguments)})}a.queue("fx",function(){a.dequeue()});a.dequeue()})}})(jQuery);
(function(b){b.effects.clip=function(e){return this.queue(function(){var a=b(this),i=["position","top","left","height","width"],f=b.effects.setMode(a,e.options.mode||"hide"),c=e.options.direction||"vertical";b.effects.save(a,i);a.show();var d=b.effects.createWrapper(a).css({overflow:"hidden"});d=a[0].tagName=="IMG"?d:a;var g={size:c=="vertical"?"height":"width",position:c=="vertical"?"top":"left"};c=c=="vertical"?d.height():d.width();if(f=="show"){d.css(g.size,0);d.css(g.position,c/2)}var h={};h[g.size]=
f=="show"?c:0;h[g.position]=f=="show"?0:c/2;d.animate(h,{queue:false,duration:e.duration,easing:e.options.easing,complete:function(){f=="hide"&&a.hide();b.effects.restore(a,i);b.effects.removeWrapper(a);e.callback&&e.callback.apply(a[0],arguments);a.dequeue()}})})}})(jQuery);
f=="show"?c:0;h[g.position]=f=="show"?0:c/2;d.animate(h,{queue:false,duration:e.duration,easing:e.options.easing,complete:function(){f=="hide"&&a.hide();b.effects.restore(a,i);b.effects.removeWrapper(a);e.callback&&e.callback.apply(a[0],arguments);a.dequeue()}})})}})(jQuery);
(function(c){c.effects.drop=function(d){return this.queue(function(){var a=c(this),h=["position","top","left","opacity"],e=c.effects.setMode(a,d.options.mode||"hide"),b=d.options.direction||"left";c.effects.save(a,h);a.show();c.effects.createWrapper(a);var f=b=="up"||b=="down"?"top":"left";b=b=="up"||b=="left"?"pos":"neg";var g=d.options.distance||(f=="top"?a.outerHeight({margin:true})/2:a.outerWidth({margin:true})/2);if(e=="show")a.css("opacity",0).css(f,b=="pos"?-g:g);var i={opacity:e=="show"?1:
0};i[f]=(e=="show"?b=="pos"?"+=":"-=":b=="pos"?"-=":"+=")+g;a.animate(i,{queue:false,duration:d.duration,easing:d.options.easing,complete:function(){e=="hide"&&a.hide();c.effects.restore(a,h);c.effects.removeWrapper(a);d.callback&&d.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery);
0};i[f]=(e=="show"?b=="pos"?"+=":"-=":b=="pos"?"-=":"+=")+g;a.animate(i,{queue:false,duration:d.duration,easing:d.options.easing,complete:function(){e=="hide"&&a.hide();c.effects.restore(a,h);c.effects.removeWrapper(a);d.callback&&d.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery);
(function(j){j.effects.explode=function(a){return this.queue(function(){var c=a.options.pieces?Math.round(Math.sqrt(a.options.pieces)):3,d=a.options.pieces?Math.round(Math.sqrt(a.options.pieces)):3;a.options.mode=a.options.mode=="toggle"?j(this).is(":visible")?"hide":"show":a.options.mode;var b=j(this).show().css("visibility","hidden"),g=b.offset();g.top-=parseInt(b.css("marginTop"),10)||0;g.left-=parseInt(b.css("marginLeft"),10)||0;for(var h=b.outerWidth(true),i=b.outerHeight(true),e=0;e<c;e++)for(var f=
0;f<d;f++)b.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-f*(h/d),top:-e*(i/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:h/d,height:i/c,left:g.left+f*(h/d)+(a.options.mode=="show"?(f-Math.floor(d/2))*(h/d):0),top:g.top+e*(i/c)+(a.options.mode=="show"?(e-Math.floor(c/2))*(i/c):0),opacity:a.options.mode=="show"?0:1}).animate({left:g.left+f*(h/d)+(a.options.mode=="show"?0:(f-Math.floor(d/2))*(h/d)),top:g.top+
e*(i/c)+(a.options.mode=="show"?0:(e-Math.floor(c/2))*(i/c)),opacity:a.options.mode=="show"?1:0},a.duration||500);setTimeout(function(){a.options.mode=="show"?b.css({visibility:"visible"}):b.css({visibility:"visible"}).hide();a.callback&&a.callback.apply(b[0]);b.dequeue();j("div.ui-effects-explode").remove()},a.duration||500)})}})(jQuery);
(function(b){b.effects.fade=function(a){return this.queue(function(){var c=b(this),d=b.effects.setMode(c,a.options.mode||"hide");c.animate({opacity:d},{queue:false,duration:a.duration,easing:a.options.easing,complete:function(){a.callback&&a.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery);
e*(i/c)+(a.options.mode=="show"?0:(e-Math.floor(c/2))*(i/c)),opacity:a.options.mode=="show"?1:0},a.duration||500);setTimeout(function(){a.options.mode=="show"?b.css({visibility:"visible"}):b.css({visibility:"visible"}).hide();a.callback&&a.callback.apply(b[0]);b.dequeue();j("div.ui-effects-explode").remove()},a.duration||500)})}})(jQuery);
(function(b){b.effects.fade=function(a){return this.queue(function(){var c=b(this),d=b.effects.setMode(c,a.options.mode||"hide");c.animate({opacity:d},{queue:false,duration:a.duration,easing:a.options.easing,complete:function(){a.callback&&a.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery);
(function(c){c.effects.fold=function(a){return this.queue(function(){var b=c(this),j=["position","top","left"],d=c.effects.setMode(b,a.options.mode||"hide"),g=a.options.size||15,h=!!a.options.horizFirst,k=a.duration?a.duration/2:c.fx.speeds._default/2;c.effects.save(b,j);b.show();var e=c.effects.createWrapper(b).css({overflow:"hidden"}),f=d=="show"!=h,l=f?["width","height"]:["height","width"];f=f?[e.width(),e.height()]:[e.height(),e.width()];var i=/([0-9]+)%/.exec(g);if(i)g=parseInt(i[1],10)/100*
f[d=="hide"?0:1];if(d=="show")e.css(h?{height:0,width:g}:{height:g,width:0});h={};i={};h[l[0]]=d=="show"?f[0]:g;i[l[1]]=d=="show"?f[1]:0;e.animate(h,k,a.options.easing).animate(i,k,a.options.easing,function(){d=="hide"&&b.hide();c.effects.restore(b,j);c.effects.removeWrapper(b);a.callback&&a.callback.apply(b[0],arguments);b.dequeue()})})}})(jQuery);
f[d=="hide"?0:1];if(d=="show")e.css(h?{height:0,width:g}:{height:g,width:0});h={};i={};h[l[0]]=d=="show"?f[0]:g;i[l[1]]=d=="show"?f[1]:0;e.animate(h,k,a.options.easing).animate(i,k,a.options.easing,function(){d=="hide"&&b.hide();c.effects.restore(b,j);c.effects.removeWrapper(b);a.callback&&a.callback.apply(b[0],arguments);b.dequeue()})})}})(jQuery);
(function(b){b.effects.highlight=function(c){return this.queue(function(){var a=b(this),e=["backgroundImage","backgroundColor","opacity"],d=b.effects.setMode(a,c.options.mode||"show"),f={backgroundColor:a.css("backgroundColor")};if(d=="hide")f.opacity=0;b.effects.save(a,e);a.show().css({backgroundImage:"none",backgroundColor:c.options.color||"#ffff99"}).animate(f,{queue:false,duration:c.duration,easing:c.options.easing,complete:function(){d=="hide"&&a.hide();b.effects.restore(a,e);d=="show"&&!b.support.opacity&&
this.style.removeAttribute("filter");c.callback&&c.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery);
this.style.removeAttribute("filter");c.callback&&c.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery);
(function(d){d.effects.pulsate=function(a){return this.queue(function(){var b=d(this),c=d.effects.setMode(b,a.options.mode||"show");times=(a.options.times||5)*2-1;duration=a.duration?a.duration/2:d.fx.speeds._default/2;isVisible=b.is(":visible");animateTo=0;if(!isVisible){b.css("opacity",0).show();animateTo=1}if(c=="hide"&&isVisible||c=="show"&&!isVisible)times--;for(c=0;c<times;c++){b.animate({opacity:animateTo},duration,a.options.easing);animateTo=(animateTo+1)%2}b.animate({opacity:animateTo},duration,
a.options.easing,function(){animateTo==0&&b.hide();a.callback&&a.callback.apply(this,arguments)});b.queue("fx",function(){b.dequeue()}).dequeue()})}})(jQuery);
a.options.easing,function(){animateTo==0&&b.hide();a.callback&&a.callback.apply(this,arguments)});b.queue("fx",function(){b.dequeue()}).dequeue()})}})(jQuery);
(function(c){c.effects.puff=function(b){return this.queue(function(){var a=c(this),e=c.effects.setMode(a,b.options.mode||"hide"),g=parseInt(b.options.percent,10)||150,h=g/100,i={height:a.height(),width:a.width()};c.extend(b.options,{fade:true,mode:e,percent:e=="hide"?g:100,from:e=="hide"?i:{height:i.height*h,width:i.width*h}});a.effect("scale",b.options,b.duration,b.callback);a.dequeue()})};c.effects.scale=function(b){return this.queue(function(){var a=c(this),e=c.extend(true,{},b.options),g=c.effects.setMode(a,
b.options.mode||"effect"),h=parseInt(b.options.percent,10)||(parseInt(b.options.percent,10)==0?0:g=="hide"?0:100),i=b.options.direction||"both",f=b.options.origin;if(g!="effect"){e.origin=f||["middle","center"];e.restore=true}f={height:a.height(),width:a.width()};a.from=b.options.from||(g=="show"?{height:0,width:0}:f);h={y:i!="horizontal"?h/100:1,x:i!="vertical"?h/100:1};a.to={height:f.height*h.y,width:f.width*h.x};if(b.options.fade){if(g=="show"){a.from.opacity=0;a.to.opacity=1}if(g=="hide"){a.from.opacity=
1;a.to.opacity=0}}e.from=a.from;e.to=a.to;e.mode=g;a.effect("size",e,b.duration,b.callback);a.dequeue()})};c.effects.size=function(b){return this.queue(function(){var a=c(this),e=["position","top","left","width","height","overflow","opacity"],g=["position","top","left","overflow","opacity"],h=["width","height","overflow"],i=["fontSize"],f=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],k=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],p=c.effects.setMode(a,
@ -203,13 +203,13 @@ b.options.mode||"effect"),n=b.options.restore||false,m=b.options.scale||"both",l
d.to.y){e=e.concat(f);a.from=c.effects.setTransition(a,f,d.from.y,a.from);a.to=c.effects.setTransition(a,f,d.to.y,a.to)}if(d.from.x!=d.to.x){e=e.concat(k);a.from=c.effects.setTransition(a,k,d.from.x,a.from);a.to=c.effects.setTransition(a,k,d.to.x,a.to)}}if(m=="content"||m=="both")if(d.from.y!=d.to.y){e=e.concat(i);a.from=c.effects.setTransition(a,i,d.from.y,a.from);a.to=c.effects.setTransition(a,i,d.to.y,a.to)}c.effects.save(a,n?e:g);a.show();c.effects.createWrapper(a);a.css("overflow","hidden").css(a.from);
if(m=="content"||m=="both"){f=f.concat(["marginTop","marginBottom"]).concat(i);k=k.concat(["marginLeft","marginRight"]);h=e.concat(f).concat(k);a.find("*[width]").each(function(){child=c(this);n&&c.effects.save(child,h);var o={height:child.height(),width:child.width()};child.from={height:o.height*d.from.y,width:o.width*d.from.x};child.to={height:o.height*d.to.y,width:o.width*d.to.x};if(d.from.y!=d.to.y){child.from=c.effects.setTransition(child,f,d.from.y,child.from);child.to=c.effects.setTransition(child,
f,d.to.y,child.to)}if(d.from.x!=d.to.x){child.from=c.effects.setTransition(child,k,d.from.x,child.from);child.to=c.effects.setTransition(child,k,d.to.x,child.to)}child.css(child.from);child.animate(child.to,b.duration,b.options.easing,function(){n&&c.effects.restore(child,h)})})}a.animate(a.to,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){a.to.opacity===0&&a.css("opacity",a.from.opacity);p=="hide"&&a.hide();c.effects.restore(a,n?e:g);c.effects.removeWrapper(a);b.callback&&
b.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery);
b.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery);
(function(d){d.effects.shake=function(a){return this.queue(function(){var b=d(this),j=["position","top","left"];d.effects.setMode(b,a.options.mode||"effect");var c=a.options.direction||"left",e=a.options.distance||20,l=a.options.times||3,f=a.duration||a.options.duration||140;d.effects.save(b,j);b.show();d.effects.createWrapper(b);var g=c=="up"||c=="down"?"top":"left",h=c=="up"||c=="left"?"pos":"neg";c={};var i={},k={};c[g]=(h=="pos"?"-=":"+=")+e;i[g]=(h=="pos"?"+=":"-=")+e*2;k[g]=(h=="pos"?"-=":"+=")+
e*2;b.animate(c,f,a.options.easing);for(e=1;e<l;e++)b.animate(i,f,a.options.easing).animate(k,f,a.options.easing);b.animate(i,f,a.options.easing).animate(c,f/2,a.options.easing,function(){d.effects.restore(b,j);d.effects.removeWrapper(b);a.callback&&a.callback.apply(this,arguments)});b.queue("fx",function(){b.dequeue()});b.dequeue()})}})(jQuery);
e*2;b.animate(c,f,a.options.easing);for(e=1;e<l;e++)b.animate(i,f,a.options.easing).animate(k,f,a.options.easing);b.animate(i,f,a.options.easing).animate(c,f/2,a.options.easing,function(){d.effects.restore(b,j);d.effects.removeWrapper(b);a.callback&&a.callback.apply(this,arguments)});b.queue("fx",function(){b.dequeue()});b.dequeue()})}})(jQuery);
(function(c){c.effects.slide=function(d){return this.queue(function(){var a=c(this),h=["position","top","left"],e=c.effects.setMode(a,d.options.mode||"show"),b=d.options.direction||"left";c.effects.save(a,h);a.show();c.effects.createWrapper(a).css({overflow:"hidden"});var f=b=="up"||b=="down"?"top":"left";b=b=="up"||b=="left"?"pos":"neg";var g=d.options.distance||(f=="top"?a.outerHeight({margin:true}):a.outerWidth({margin:true}));if(e=="show")a.css(f,b=="pos"?-g:g);var i={};i[f]=(e=="show"?b=="pos"?
"+=":"-=":b=="pos"?"-=":"+=")+g;a.animate(i,{queue:false,duration:d.duration,easing:d.options.easing,complete:function(){e=="hide"&&a.hide();c.effects.restore(a,h);c.effects.removeWrapper(a);d.callback&&d.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery);
"+=":"-=":b=="pos"?"-=":"+=")+g;a.animate(i,{queue:false,duration:d.duration,easing:d.options.easing,complete:function(){e=="hide"&&a.hide();c.effects.restore(a,h);c.effects.removeWrapper(a);d.callback&&d.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery);
(function(e){e.effects.transfer=function(a){return this.queue(function(){var b=e(this),c=e(a.options.to),d=c.offset();c={top:d.top,left:d.left,height:c.innerHeight(),width:c.innerWidth()};d=b.offset();var f=e('<div class="ui-effects-transfer"></div>').appendTo(document.body).addClass(a.options.className).css({top:d.top,left:d.left,height:b.innerHeight(),width:b.innerWidth(),position:"absolute"}).animate(c,a.duration,a.options.easing,function(){f.remove();a.callback&&a.callback.apply(b[0],arguments);
b.dequeue()})})}})(jQuery);
b.dequeue()})})}})(jQuery);
(function(d){d.widget("ui.accordion",{options:{active:0,animated:"slide",autoHeight:true,clearStyle:false,collapsible:false,event:"click",fillSpace:false,header:"> li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:false,navigationFilter:function(){return this.href.toLowerCase()==location.href.toLowerCase()}},_create:function(){var a=this.options,b=this;this.running=0;this.element.addClass("ui-accordion ui-widget ui-helper-reset");
this.element.children("li").addClass("ui-accordion-li-fix");this.headers=this.element.find(a.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){d(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){d(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){d(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){d(this).removeClass("ui-state-focus")});this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");
if(a.navigation){var c=this.element.find("a").filter(a.navigationFilter);if(c.length){var f=c.closest(".ui-accordion-header");this.active=f.length?f:c.closest(".ui-accordion-content").prev()}}this.active=this._findActive(this.active||a.active).toggleClass("ui-state-default").toggleClass("ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top");this.active.next().addClass("ui-accordion-content-active");this._createIcons();this.resize();this.element.attr("role","tablist");this.headers.attr("role",
@ -226,7 +226,7 @@ toHide:b,complete:i,down:g,autoHeight:e.autoHeight||e.fillSpace}:{toShow:a,toHid
duration:h||700})});f[j](c)}else{if(e.collapsible&&f)a.toggle();else{b.hide();a.show()}i(true)}b.prev().attr("aria-expanded","false").attr("tabIndex","-1").blur();a.prev().attr("aria-expanded","true").attr("tabIndex","0").focus()},_completed:function(a){var b=this.options;this.running=a?0:--this.running;if(!this.running){b.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""});this.toHide.removeClass("ui-accordion-content-active");this._trigger("change",null,this.data)}}});d.extend(d.ui.accordion,
{version:"1.9m2",animations:{slide:function(a,b){a=d.extend({easing:"swing",duration:300},a,b);if(a.toHide.size())if(a.toShow.size()){var c=a.toShow.css("overflow"),f=0,g={},e={},k;b=a.toShow;k=b[0].style.width;b.width(parseInt(b.parent().width(),10)-parseInt(b.css("paddingLeft"),10)-parseInt(b.css("paddingRight"),10)-(parseInt(b.css("borderLeftWidth"),10)||0)-(parseInt(b.css("borderRightWidth"),10)||0));d.each(["height","paddingTop","paddingBottom"],function(i,h){e[h]="hide";i=(""+d.css(a.toShow[0],
h)).match(/^([\d+-.]+)(.*)$/);g[h]={value:i[1],unit:i[2]||"px"}});a.toShow.css({height:0,overflow:"hidden"}).show();a.toHide.filter(":hidden").each(a.complete).end().filter(":visible").animate(e,{step:function(i,h){if(h.prop=="height")f=h.end-h.start===0?0:(h.now-h.start)/(h.end-h.start);a.toShow[0].style[h.prop]=f*g[h.prop].value+g[h.prop].unit},duration:a.duration,easing:a.easing,complete:function(){a.autoHeight||a.toShow.css("height","");a.toShow.css("width",k);a.toShow.css({overflow:c});a.complete()}})}else a.toHide.animate({height:"hide"},
a);else a.toShow.animate({height:"show"},a)},bounceslide:function(a){this.slide(a,{easing:a.down?"easeOutBounce":"swing",duration:a.down?1E3:200})}}})})(jQuery);
a);else a.toShow.animate({height:"show"},a)},bounceslide:function(a){this.slide(a,{easing:a.down?"easeOutBounce":"swing",duration:a.down?1E3:200})}}})})(jQuery);
(function(e){e.widget("ui.autocomplete",{options:{minLength:1,delay:300},_create:function(){var a=this,d=this.element[0].ownerDocument;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){var b=e.ui.keyCode;switch(c.keyCode){case b.PAGE_UP:a._move("previousPage",c);break;case b.PAGE_DOWN:a._move("nextPage",c);break;case b.UP:a._move("previous",c);c.preventDefault();
break;case b.DOWN:a._move("next",c);c.preventDefault();break;case b.ENTER:case b.NUMPAD_ENTER:a.menu.active&&c.preventDefault();case b.TAB:if(!a.menu.active)return;a.menu.select(c);break;case b.ESCAPE:a.element.val(a.term);a.close(c);break;case b.LEFT:case b.RIGHT:case b.SHIFT:case b.CONTROL:case b.ALT:case b.COMMAND:case b.COMMAND_RIGHT:case b.INSERT:case b.CAPS_LOCK:case b.END:case b.HOME:break;default:clearTimeout(a.searching);a.searching=setTimeout(function(){a.search(null,c)},a.options.delay);
break}}).bind("focus.autocomplete",function(){a.selectedItem=null;a.previous=a.element.val()}).bind("blur.autocomplete",function(c){clearTimeout(a.searching);a.closing=setTimeout(function(){a.close(c);a._change(c)},150)});this._initSource();this.response=function(){return a._response.apply(a,arguments)};this.menu=e("<ul></ul>").addClass("ui-autocomplete").appendTo("body",d).mousedown(function(){setTimeout(function(){clearTimeout(a.closing)},13)}).menu({input:e(),focus:function(c,b){b=b.item.data("item.autocomplete");
@ -236,7 +236,7 @@ destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr(
this._trigger("open")}else this.close();this.element.removeClass("ui-autocomplete-loading")},close:function(a){clearTimeout(this.closing);if(this.menu.element.is(":visible")){this._trigger("close",a);this.menu.element.hide();this.menu.deactivate()}},_change:function(a){this.previous!==this.element.val()&&this._trigger("change",a,{item:this.selectedItem})},_normalize:function(a){if(a.length&&a[0].label&&a[0].value)return a;return e.map(a,function(d){if(typeof d==="string")return{label:d,value:d};return e.extend({label:d.label||
d.value,value:d.value||d.label},d)})},_suggest:function(a){var d=this.menu.element.empty().zIndex(this.element.zIndex()+1),c;this._renderMenu(d,a);this.menu.deactivate();this.menu.refresh();this.menu.element.show().position({my:"left top",at:"left bottom",of:this.element,collision:"none"});a=d.width("").width();c=this.element.width();d.width(Math.max(a,c))},_renderMenu:function(a,d){var c=this;e.each(d,function(b,f){c._renderItem(a,f)})},_renderItem:function(a,d){return e("<li></li>").data("item.autocomplete",
d).append("<a>"+d.label+"</a>").appendTo(a)},_move:function(a,d){if(this.menu.element.is(":visible"))if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term);this.menu.deactivate()}else this.menu[a](d);else this.search(null,d)},widget:function(){return this.menu.element}});e.extend(e.ui.autocomplete,{escapeRegex:function(a){return a.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi,"\\$1")},filter:function(a,d){var c=new RegExp(e.ui.autocomplete.escapeRegex(d),
"i");return e.grep(a,function(b){return c.test(b.label||b.value||b)})}})})(jQuery);
"i");return e.grep(a,function(b){return c.test(b.label||b.value||b)})}})})(jQuery);
(function(a){var g,i=function(b){a(":ui-button",b.target.form).each(function(){var c=a(this).data("button");setTimeout(function(){c.refresh()},1)})},h=function(b){var c=b.name,d=b.form,e=a([]);if(c)e=d?a(d).find("[name='"+c+"']"):a("[name='"+c+"']",b.ownerDocument).filter(function(){return!this.form});return e};a.widget("ui.button",{options:{text:true,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset.button").bind("reset.button",i);this._determineButtonType();
this.hasTitle=!!this.buttonElement.attr("title");var b=this,c=this.options,d=this.type==="checkbox"||this.type==="radio",e="ui-state-hover"+(!d?" ui-state-active":"");if(c.label===null)c.label=this.buttonElement.html();if(this.element.is(":disabled"))c.disabled=true;this.buttonElement.addClass("ui-button ui-widget ui-state-default ui-corner-all").attr("role","button").bind("mouseenter.button",function(){if(!c.disabled){a(this).addClass("ui-state-hover");this===g&&a(this).addClass("ui-state-active")}}).bind("mouseleave.button",
function(){c.disabled||a(this).removeClass(e)}).bind("focus.button",function(){a(this).addClass("ui-state-focus")}).bind("blur.button",function(){a(this).removeClass("ui-state-focus")});d&&this.element.bind("change.button",function(){b.refresh()});if(this.type==="checkbox")this.buttonElement.bind("click.button",function(){if(c.disabled)return false;a(this).toggleClass("ui-state-active");b.buttonElement.attr("aria-pressed",b.element[0].checked)});else if(this.type==="radio")this.buttonElement.bind("click.button",
@ -247,7 +247,7 @@ this.hasTitle||this.buttonElement.removeAttr("title");this._super("destroy")},_s
true):a(this).button("widget").removeClass("ui-state-active").attr("aria-pressed",false)});else if(this.type==="checkbox")this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed",true):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed",false)},_resetButton:function(){if(this.type==="input")this.options.label&&this.element.val(this.options.label);else{var b=this.buttonElement.removeClass("ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only"),
c=a("<span></span>").addClass("ui-button-text").html(this.options.label).appendTo(b.empty()).text(),d=this.options.icons,e=d.primary&&d.secondary;if(d.primary||d.secondary){b.addClass("ui-button-text-icon"+(e?"s":d.primary?"-primary":"-secondary"));d.primary&&b.prepend("<span class='ui-button-icon-primary ui-icon "+d.primary+"'></span>");d.secondary&&b.append("<span class='ui-button-icon-secondary ui-icon "+d.secondary+"'></span>");if(!this.options.text){b.addClass(e?"ui-button-icons-only":"ui-button-icon-only").removeClass("ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary");
this.hasTitle||b.attr("title",c)}}else b.addClass("ui-button-text-only")}}});a.widget("ui.buttonset",{_create:function(){this.element.addClass("ui-buttonset");this._init()},_init:function(){this.refresh()},_setOption:function(b,c){b==="disabled"&&this.buttons.button("option",b,c);this._superApply("_setOption",arguments)},refresh:function(){this.buttons=this.element.find(":button, :submit, :reset, :checkbox, :radio, a, :data(button)").filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass("ui-corner-left").end().filter(":last").addClass("ui-corner-right").end().end()},
destroy:function(){this.element.removeClass("ui-buttonset");this.buttons.map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy");this._super("destroy")}})})(jQuery);
destroy:function(){this.element.removeClass("ui-buttonset");this.buttons.map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy");this._super("destroy")}})})(jQuery);
(function(d){function K(){this.debug=false;this._curInst=null;this._keyEvent=false;this._disabledInputs=[];this._inDialog=this._datepickerShowing=false;this._mainDivId="ui-datepicker-div";this._inlineClass="ui-datepicker-inline";this._appendClass="ui-datepicker-append";this._triggerClass="ui-datepicker-trigger";this._dialogClass="ui-datepicker-dialog";this._disableClass="ui-datepicker-disabled";this._unselectableClass="ui-datepicker-unselectable";this._currentClass="ui-datepicker-current-day";this._dayOverClass=
"ui-datepicker-days-cell-over";this.regional=[];this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su",
"Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:false,showMonthAfterYear:false,yearSuffix:""};this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:false,hideIfNoPrevNext:false,navigationAsDateFormat:false,gotoCurrent:false,changeMonth:false,changeYear:false,yearRange:"c-10:c+10",showOtherMonths:false,selectOtherMonths:false,showWeek:false,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",
@ -315,7 +315,7 @@ a.drawYear+(c=="Y"?b:0),f=a.drawMonth+(c=="M"?b:0);b=Math.min(a.selectedDay,this
c=this._daylightSavingAdjust(new Date(c,e+(b<0?b:f[0]*f[1]),1));b<0&&c.setDate(this._getDaysInMonth(c.getFullYear(),c.getMonth()));return this._isInRange(a,c)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!a||b.getTime()<=a.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a,
"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,e){if(!b){a.currentDay=a.selectedDay;a.currentMonth=a.selectedMonth;a.currentYear=a.selectedYear}b=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(e,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),b,this._getFormatConfig(a))}});d.fn.datepicker=
function(a){if(!d.datepicker.initialized){d(document).mousedown(d.datepicker._checkExternalClick).find("body").append(d.datepicker.dpDiv);d.datepicker.initialized=true}var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));
return this.each(function(){typeof a=="string"?d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this].concat(b)):d.datepicker._attachDatepicker(this,a)})};d.datepicker=new K;d.datepicker.initialized=false;d.datepicker.uuid=(new Date).getTime();d.datepicker.version="1.9m2";window["DP_jQuery_"+y]=d})(jQuery);
return this.each(function(){typeof a=="string"?d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this].concat(b)):d.datepicker._attachDatepicker(this,a)})};d.datepicker=new K;d.datepicker.initialized=false;d.datepicker.uuid=(new Date).getTime();d.datepicker.version="1.9m2";window["DP_jQuery_"+y]=d})(jQuery);
(function(c){c.widget("ui.dialog",{options:{autoOpen:true,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false,position:"center",resizable:true,show:null,stack:true,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");var a=this,b=a.options,d=b.title||a.originalTitle||"&#160;",e=c.ui.dialog.getTitleId(a.element),g=(a.uiDialog=c("<div></div>")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+
b.dialogClass).css({zIndex:b.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(i){if(b.closeOnEscape&&i.keyCode&&i.keyCode===c.ui.keyCode.ESCAPE){a.close(i);i.preventDefault()}}).attr({role:"dialog","aria-labelledby":e}).mousedown(function(i){a.moveToTop(false,i)});a.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g);var f=(a.uiDialogTitlebar=c("<div></div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g),
h=c('<a href="#"></a>').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){h.addClass("ui-state-hover")},function(){h.removeClass("ui-state-hover")}).focus(function(){h.addClass("ui-state-focus")}).blur(function(){h.removeClass("ui-state-focus")}).click(function(i){a.close(i);return false}).appendTo(f);(a.uiDialogTitlebarCloseText=c("<span></span>")).addClass("ui-icon ui-icon-closethick").text(b.closeText).appendTo(h);c("<span></span>").addClass("ui-dialog-title").attr("id",
@ -336,7 +336,7 @@ this._minHeight())}});c.extend(c.ui.dialog,{version:"1.9m2",uuid:0,maxZ:0,getTit
c(document).bind(c.ui.dialog.overlay.events,function(d){return c(d.target).zIndex()>=c.ui.dialog.overlay.maxZ})},1);c(document).bind("keydown.dialog-overlay",function(d){if(a.options.closeOnEscape&&d.keyCode&&d.keyCode===c.ui.keyCode.ESCAPE){a.close(d);d.preventDefault()}});c(window).bind("resize.dialog-overlay",c.ui.dialog.overlay.resize)}var b=(this.oldInstances.pop()||c("<div></div>").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),height:this.height()});c.fn.bgiframe&&
b.bgiframe();this.instances.push(b);return b},destroy:function(a){this.oldInstances.push(this.instances.splice(c.inArray(a,this.instances),1)[0]);this.instances.length===0&&c([document,window]).unbind(".dialog-overlay");a.remove();var b=0;c.each(this.instances,function(){b=Math.max(b,this.css("z-index"))});this.maxZ=b},height:function(){var a,b;if(c.browser.msie&&c.browser.version<7){a=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);b=Math.max(document.documentElement.offsetHeight,
document.body.offsetHeight);return a<b?c(window).height()+"px":a+"px"}else return c(document).height()+"px"},width:function(){var a,b;if(c.browser.msie&&c.browser.version<7){a=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth);b=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth);return a<b?c(window).width()+"px":a+"px"}else return c(document).width()+"px"},resize:function(){var a=c([]);c.each(c.ui.dialog.overlay.instances,function(){a=a.add(this)});a.css({width:0,
height:0}).css({width:c.ui.dialog.overlay.width(),height:c.ui.dialog.overlay.height()})}});c.extend(c.ui.dialog.overlay.prototype,{destroy:function(){c.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);
height:0}).css({width:c.ui.dialog.overlay.width(),height:c.ui.dialog.overlay.height()})}});c.extend(c.ui.dialog.overlay.prototype,{destroy:function(){c.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);
(function(c){c.widget("ui.menu",{_create:function(){var a=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).bind("click.menu",function(b){if(a.options.disabled)return false;if(c(b.target).closest(".ui-menu-item a").length){b.preventDefault();a.select(b)}});this.refresh();if(!this.options.input)this.options.input=this.element.attr("tabIndex",0);this.options.input.bind("keydown.menu",function(b){if(!a.options.disabled)switch(b.keyCode){case c.ui.keyCode.PAGE_UP:a.previousPage();
b.preventDefault();b.stopImmediatePropagation();break;case c.ui.keyCode.PAGE_DOWN:a.nextPage();b.preventDefault();b.stopImmediatePropagation();break;case c.ui.keyCode.UP:a.previous();b.preventDefault();b.stopImmediatePropagation();break;case c.ui.keyCode.DOWN:a.next();b.preventDefault();b.stopImmediatePropagation();break;case c.ui.keyCode.ENTER:a.select();b.preventDefault();b.stopImmediatePropagation();break}})},destroy:function(){c.Widget.prototype.destroy.apply(this,arguments);this.element.removeClass("ui-menu ui-widget ui-widget-content ui-corner-all").removeAttr("tabIndex").removeAttr("role").removeAttr("aria-activedescendant");
this.element.children(".ui-menu-item").removeClass("ui-menu-item").removeAttr("role").children("a").removeClass("ui-corner-all").removeAttr("tabIndex").unbind(".menu")},refresh:function(){var a=this;this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem").children("a").addClass("ui-corner-all").attr("tabIndex",-1).bind("mouseenter.menu",function(b){a.options.disabled||a.activate(b,c(this).parent())}).bind("mouseleave.menu",function(){a.options.disabled||
@ -344,16 +344,16 @@ a.deactivate()})},activate:function(a,b){this.deactivate();if(this._hasScroll())
this._trigger("blur");this.active=null}},next:function(a){this._move("next",".ui-menu-item:first",a)},previous:function(a){this._move("prev",".ui-menu-item:last",a)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(a,b,d){if(this.active){a=this.active[a+"All"](".ui-menu-item").eq(0);a.length?this.activate(d,a):this.activate(d,this.element.children(b))}else this.activate(d,
this.element.children(b))},nextPage:function(a){if(this._hasScroll())if(!this.active||this.last())this.activate(a,this.element.children(":first"));else{var b=this.active.offset().top,d=this.element.height(),e=this.element.children("li").filter(function(){var f=c(this).offset().top-b-d+c(this).height();return f<10&&f>-10});e.length||(e=this.element.children(":last"));this.activate(a,e)}else this.activate(a,this.element.children(!this.active||this.last()?":first":":last"))},previousPage:function(a){if(this._hasScroll())if(!this.active||
this.first())this.activate(a,this.element.children(":last"));else{var b=this.active.offset().top,d=this.element.height();result=this.element.children("li").filter(function(){var e=c(this).offset().top-b+d-c(this).height();return e<10&&e>-10});result.length||(result=this.element.children(":first"));this.activate(a,result)}else this.activate(a,this.element.children(!this.active||this.first()?":last":":first"))},_hasScroll:function(){return this.element.height()<this.element.attr("scrollHeight")},select:function(a){this._trigger("select",
a,{item:this.active})}})})(jQuery);
a,{item:this.active})}})})(jQuery);
(function(c){c.ui=c.ui||{};var m=/left|center|right/,n=/top|center|bottom/,p=c.fn.position,q=c.fn.offset;c.fn.position=function(a){if(!a||!a.of)return p.apply(this,arguments);a=c.extend({},a);var b=c(a.of),d=(a.collision||"flip").split(" "),e=a.offset?a.offset.split(" "):[0,0],g,h,i;if(a.of.nodeType===9){g=b.width();h=b.height();i={top:0,left:0}}else if(a.of.scrollTo&&a.of.document){g=b.width();h=b.height();i={top:b.scrollTop(),left:b.scrollLeft()}}else if(a.of.preventDefault){a.at="left top";g=h=
0;i={top:a.of.pageY,left:a.of.pageX}}else{g=b.outerWidth();h=b.outerHeight();i=b.offset()}c.each(["my","at"],function(){var f=(a[this]||"").split(" ");if(f.length===1)f=m.test(f[0])?f.concat(["center"]):n.test(f[0])?["center"].concat(f):["center","center"];f[0]=m.test(f[0])?f[0]:"center";f[1]=n.test(f[1])?f[1]:"center";a[this]=f});if(d.length===1)d[1]=d[0];e[0]=parseInt(e[0],10)||0;if(e.length===1)e[1]=e[0];e[1]=parseInt(e[1],10)||0;if(a.at[0]==="right")i.left+=g;else if(a.at[0]==="center")i.left+=
g/2;if(a.at[1]==="bottom")i.top+=h;else if(a.at[1]==="center")i.top+=h/2;i.left+=e[0];i.top+=e[1];return this.each(function(){var f=c(this),k=f.outerWidth(),l=f.outerHeight(),j=c.extend({},i);if(a.my[0]==="right")j.left-=k;else if(a.my[0]==="center")j.left-=k/2;if(a.my[1]==="bottom")j.top-=l;else if(a.my[1]==="center")j.top-=l/2;j.left=parseInt(j.left);j.top=parseInt(j.top);c.each(["left","top"],function(o,r){c.ui.position[d[o]]&&c.ui.position[d[o]][r](j,{targetWidth:g,targetHeight:h,elemWidth:k,
elemHeight:l,offset:e,my:a.my,at:a.at})});c.fn.bgiframe&&f.bgiframe();f.offset(c.extend(j,{using:a.using}))})};c.ui.position={fit:{left:function(a,b){var d=c(window);b=a.left+b.elemWidth-d.width()-d.scrollLeft();a.left=b>0?a.left-b:Math.max(0,a.left)},top:function(a,b){var d=c(window);b=a.top+b.elemHeight-d.height()-d.scrollTop();a.top=b>0?a.top-b:Math.max(0,a.top)}},flip:{left:function(a,b){if(b.at[0]!=="center"){var d=c(window);d=a.left+b.elemWidth-d.width()-d.scrollLeft();var e=b.my[0]==="left"?
-b.elemWidth:b.my[0]==="right"?b.elemWidth:0,g=-2*b.offset[0];a.left+=a.left<0?e+b.targetWidth+g:d>0?e-b.targetWidth+g:0}},top:function(a,b){if(b.at[1]!=="center"){var d=c(window);d=a.top+b.elemHeight-d.height()-d.scrollTop();var e=b.my[1]==="top"?-b.elemHeight:b.my[1]==="bottom"?b.elemHeight:0,g=b.at[1]==="top"?b.targetHeight:-b.targetHeight,h=-2*b.offset[1];a.top+=a.top<0?e+b.targetHeight+h:d>0?e+g+h:0}}}};if(!c.offset.setOffset){c.offset.setOffset=function(a,b){if(/static/.test(c.curCSS(a,"position")))a.style.position=
"relative";var d=c(a),e=d.offset(),g=parseInt(c.curCSS(a,"top",true),10)||0,h=parseInt(c.curCSS(a,"left",true),10)||0;e={top:b.top-e.top+g,left:b.left-e.left+h};"using"in b?b.using.call(a,e):d.css(e)};c.fn.offset=function(a){var b=this[0];if(!b||!b.ownerDocument)return null;if(a)return this.each(function(){c.offset.setOffset(this,a)});return q.call(this)}}})(jQuery);
"relative";var d=c(a),e=d.offset(),g=parseInt(c.curCSS(a,"top",true),10)||0,h=parseInt(c.curCSS(a,"left",true),10)||0;e={top:b.top-e.top+g,left:b.left-e.left+h};"using"in b?b.using.call(a,e):d.css(e)};c.fn.offset=function(a){var b=this[0];if(!b||!b.ownerDocument)return null;if(a)return this.each(function(){c.offset.setOffset(this,a)});return q.call(this)}}})(jQuery);
(function(b){b.widget("ui.progressbar",{options:{value:0},_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this._valueMin(),"aria-valuemax":this._valueMax(),"aria-valuenow":this._value()});this.valueDiv=b("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element);this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow");
this.valueDiv.remove();this._superApply("destroy",arguments)},value:function(a){if(a===undefined)return this._value();this._setOption("value",a);return this},_setOption:function(a,c){switch(a){case "value":this.options.value=c;this._refreshValue();this._trigger("change");break}this._superApply("_setOption",arguments)},_value:function(){var a=this.options.value;if(typeof a!=="number")a=0;if(a<this._valueMin())a=this._valueMin();if(a>this._valueMax())a=this._valueMax();return a},_valueMin:function(){return 0},
_valueMax:function(){return 100},_refreshValue:function(){var a=this.value();this.valueDiv[a===this._valueMax()?"addClass":"removeClass"]("ui-corner-right").width(a+"%");this.element.attr("aria-valuenow",a)}});b.extend(b.ui.progressbar,{version:"1.9m2"})})(jQuery);
_valueMax:function(){return 100},_refreshValue:function(){var a=this.value();this.valueDiv[a===this._valueMax()?"addClass":"removeClass"]("ui-corner-right").width(a+"%");this.element.attr("aria-valuenow",a)}});b.extend(b.ui.progressbar,{version:"1.9m2"})})(jQuery);
(function(d){d.widget("ui.slider",d.ui.mouse,{widgetEventPrefix:"slide",options:{animate:false,distance:0,max:100,min:0,orientation:"horizontal",range:false,step:1,value:0,values:null},_create:function(){var a=this,b=this.options;this._mouseSliding=this._keySliding=false;this._animateOff=true;this._handleIndex=null;this._detectOrientation();this._mouseInit();this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget ui-widget-content ui-corner-all");b.disabled&&this.element.addClass("ui-slider-disabled ui-disabled");
this.range=d([]);if(b.range){if(b.range===true){this.range=d("<div></div>");if(!b.values)b.values=[this._valueMin(),this._valueMin()];if(b.values.length&&b.values.length!==2)b.values=[b.values[0],b.values[0]]}else this.range=d("<div></div>");this.range.appendTo(this.element).addClass("ui-slider-range");if(b.range==="min"||b.range==="max")this.range.addClass("ui-slider-range-"+b.range);this.range.addClass("ui-widget-header")}d(".ui-slider-handle",this.element).length===0&&d("<a href='#'></a>").appendTo(this.element).addClass("ui-slider-handle");
if(b.values&&b.values.length)for(;d(".ui-slider-handle",this.element).length<b.values.length;)d("<a href='#'></a>").appendTo(this.element).addClass("ui-slider-handle");this.handles=d(".ui-slider-handle",this.element).addClass("ui-state-default ui-corner-all");this.handle=this.handles.eq(0);this.handles.add(this.range).filter("a").click(function(c){c.preventDefault()}).hover(function(){b.disabled||d(this).addClass("ui-state-hover")},function(){d(this).removeClass("ui-state-hover")}).focus(function(){if(b.disabled)d(this).blur();
@ -372,7 +372,7 @@ this.orientation);this._refreshValue();break;case "value":this._animateOff=true;
0;c<b.length;c+=1)b[c]=this._trimAlignValue(b[c]);return b}},_trimAlignValue:function(a){if(a<this._valueMin())return this._valueMin();if(a>this._valueMax())return this._valueMax();var b=this.options.step>0?this.options.step:1,c=a%b;a=a-c;if(Math.abs(c)*2>=b)a+=c>0?b:-b;return parseFloat(a.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var a=this.options.range,b=this.options,c=this,e=!this._animateOff?b.animate:false,
f,g={},h,i,j,k;if(this.options.values&&this.options.values.length)this.handles.each(function(l){f=(c.values(l)-c._valueMin())/(c._valueMax()-c._valueMin())*100;g[c.orientation==="horizontal"?"left":"bottom"]=f+"%";d(this).stop(1,1)[e?"animate":"css"](g,b.animate);if(c.options.range===true)if(c.orientation==="horizontal"){if(l===0)c.range.stop(1,1)[e?"animate":"css"]({left:f+"%"},b.animate);if(l===1)c.range[e?"animate":"css"]({width:f-h+"%"},{queue:false,duration:b.animate})}else{if(l===0)c.range.stop(1,
1)[e?"animate":"css"]({bottom:f+"%"},b.animate);if(l===1)c.range[e?"animate":"css"]({height:f-h+"%"},{queue:false,duration:b.animate})}h=f});else{i=this.value();j=this._valueMin();k=this._valueMax();f=k!==j?(i-j)/(k-j)*100:0;g[c.orientation==="horizontal"?"left":"bottom"]=f+"%";this.handle.stop(1,1)[e?"animate":"css"](g,b.animate);if(a==="min"&&this.orientation==="horizontal")this.range.stop(1,1)[e?"animate":"css"]({width:f+"%"},b.animate);if(a==="max"&&this.orientation==="horizontal")this.range[e?
"animate":"css"]({width:100-f+"%"},{queue:false,duration:b.animate});if(a==="min"&&this.orientation==="vertical")this.range.stop(1,1)[e?"animate":"css"]({height:f+"%"},b.animate);if(a==="max"&&this.orientation==="vertical")this.range[e?"animate":"css"]({height:100-f+"%"},{queue:false,duration:b.animate})}}});d.extend(d.ui.slider,{version:"1.9m2"})})(jQuery);
"animate":"css"]({width:100-f+"%"},{queue:false,duration:b.animate});if(a==="min"&&this.orientation==="vertical")this.range.stop(1,1)[e?"animate":"css"]({height:f+"%"},b.animate);if(a==="max"&&this.orientation==="vertical")this.range[e?"animate":"css"]({height:100-f+"%"},{queue:false,duration:b.animate})}}});d.extend(d.ui.slider,{version:"1.9m2"})})(jQuery);
(function(d){function s(){return++u}function v(){return++w}var u=0,w=0;d.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:false,cookie:null,collapsible:false,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"<div></div>",remove:null,select:null,show:null,spinner:"<em>Loading&#8230;</em>",tabTemplate:'<li><a href="#{href}"><span>#{label}</span></a></li>'},_create:function(){this._tabify(true)},_setOption:function(c,e){if(c=="selected")this.options.collapsible&&
e==this.options.selected||this.select(e);else{this.options[c]=e;this._tabify()}},_tabId:function(c){return c.title&&c.title.replace(/\s/g,"_").replace(/[^A-Za-z0-9\-_:\.]/g,"")||this.options.idPrefix+s()},_sanitizeSelector:function(c){return c.replace(/:/g,"\\:")},_cookie:function(){var c=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+v());return d.cookie.apply(null,[c].concat(d.makeArray(arguments)))},_ui:function(c,e){return{tab:c,panel:e,index:this.anchors.index(c)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var c=
d(this);c.html(c.data("label.tabs")).removeData("label.tabs")})},_tabify:function(c){function e(g,f){g.css({display:""});!d.support.opacity&&f.opacity&&g[0].style.removeAttribute("filter")}this.list=this.element.find("ol,ul").eq(0);this.lis=d("li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return d("a",this)[0]});this.panels=d([]);var a=this,b=this.options,h=/^#.+/;this.anchors.each(function(g,f){var j=d(f).attr("href"),l=j.split("#")[0],p;if(l&&(l===location.toString().split("#")[0]||
@ -393,9 +393,9 @@ null,this._ui(a.find("a")[0],b[0]));return this},enable:function(c){var e=this.o
select:function(c){if(typeof c=="string")c=this.anchors.index(this.anchors.filter("[href$="+c+"]"));else if(c===null)c=-1;if(c==-1&&this.options.collapsible)c=this.options.selected;this.anchors.eq(c).trigger(this.options.event+".tabs");return this},load:function(c){var e=this,a=this.options,b=this.anchors.eq(c)[0],h=d.data(b,"load.tabs");this.abort();if(!h||this.element.queue("tabs").length!==0&&d.data(b,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(c).addClass("ui-state-processing");
if(a.spinner){var i=d("span",b);i.data("label.tabs",i.html()).html(a.spinner)}this.xhr=d.ajax(d.extend({},a.ajaxOptions,{url:h,success:function(k,n){d(e._sanitizeSelector(b.hash)).html(k);e._cleanup();a.cache&&d.data(b,"cache.tabs",true);e._trigger("load",null,e._ui(e.anchors[c],e.panels[c]));try{a.ajaxOptions.success(k,n)}catch(m){}},error:function(k,n){e._cleanup();e._trigger("load",null,e._ui(e.anchors[c],e.panels[c]));try{a.ajaxOptions.error(k,n,c,b)}catch(m){}}}));e.element.dequeue("tabs");return this}},
abort:function(){this.element.queue([]);this.panels.stop(false,true);this.element.queue("tabs",this.element.queue("tabs").splice(-2,2));if(this.xhr){this.xhr.abort();delete this.xhr}this._cleanup();return this},url:function(c,e){this.anchors.eq(c).removeData("cache.tabs").data("load.tabs",e);return this},length:function(){return this.anchors.length}});d.extend(d.ui.tabs,{version:"1.9m2"});d.extend(d.ui.tabs.prototype,{rotation:null,rotate:function(c,e){var a=this,b=this.options,h=a._rotate||(a._rotate=
function(i){clearTimeout(a.rotation);a.rotation=setTimeout(function(){var k=b.selected;a.select(++k<a.anchors.length?k:0)},c);i&&i.stopPropagation()});e=a._unrotate||(a._unrotate=!e?function(i){i.clientX&&a.rotate(null)}:function(){t=b.selected;h()});if(c){this.element.bind("tabsshow",h);this.anchors.bind(b.event+".tabs",e);h()}else{clearTimeout(a.rotation);this.element.unbind("tabsshow",h);this.anchors.unbind(b.event+".tabs",e);delete this._rotate;delete this._unrotate}return this}})})(jQuery);
function(i){clearTimeout(a.rotation);a.rotation=setTimeout(function(){var k=b.selected;a.select(++k<a.anchors.length?k:0)},c);i&&i.stopPropagation()});e=a._unrotate||(a._unrotate=!e?function(i){i.clientX&&a.rotate(null)}:function(){t=b.selected;h()});if(c){this.element.bind("tabsshow",h);this.anchors.bind(b.event+".tabs",e);h()}else{clearTimeout(a.rotation);this.element.unbind("tabsshow",h);this.anchors.unbind(b.event+".tabs",e);delete this._rotate;delete this._unrotate}return this}})})(jQuery);
(function(b){b(document.body).is("[role]")||b(document.body).attr("role","application");var f=0;b.widget("ui.tooltip",{options:{tooltipClass:"ui-widget-content",content:function(){return b(this).attr("title")},position:{my:"left center",at:"right center",offset:"15 0"}},_init:function(){var c=this;this.tooltip=b("<div></div>").attr("id","ui-tooltip-"+f++).attr("role","tooltip").attr("aria-hidden","true").addClass("ui-tooltip ui-widget ui-corner-all").addClass(this.options.tooltipClass).appendTo(document.body).hide();
this.tooltipContent=b("<div></div>").addClass("ui-tooltip-content").appendTo(this.tooltip);this.opacity=this.tooltip.css("opacity");this.element.bind("focus.tooltip mouseenter.tooltip",function(a){c.open(a)}).bind("blur.tooltip mouseleave.tooltip",function(a){c.close(a)})},enable:function(){this.options.disabled=false},disable:function(){this.options.disabled=true},destroy:function(){this.tooltip.remove();b.Widget.prototype.destroy.apply(this,arguments)},widget:function(){return this.tooltip},open:function(c){var a=
this.element;if(!(this.current&&this.current[0]==a[0])){var d=this;this.current=a;this.currentTitle=a.attr("title");var e=this.options.content.call(a[0],function(g){d.current==a&&d._show(c,a,g)});e&&d._show(c,a,e)}},_show:function(c,a,d){if(d){a.attr("title","");if(!this.options.disabled){this.tooltipContent.html(d);this.tooltip.css({top:0,left:0}).show().position(b.extend(this.options.position,{of:a})).hide();this.tooltip.attr("aria-hidden","false");a.attr("aria-describedby",this.tooltip.attr("id"));
if(this.tooltip.is(":animated"))this.tooltip.stop().show().fadeTo("normal",this.opacity);else this.tooltip.is(":visible")?this.tooltip.fadeTo("normal",this.opacity):this.tooltip.fadeIn();this._trigger("open",c)}}},close:function(c){if(this.current){var a=this.current.attr("title",this.currentTitle);this.current=null;if(!this.options.disabled){a.removeAttr("aria-describedby");this.tooltip.attr("aria-hidden","true");this.tooltip.is(":animated")?this.tooltip.stop().fadeTo("normal",0,function(){b(this).hide().css("opacity",
"")}):this.tooltip.stop().fadeOut();this._trigger("close",c)}}}})})(jQuery);
"")}):this.tooltip.stop().fadeOut();this._trigger("close",c)}}}})})(jQuery);

View File

@ -301,6 +301,10 @@ trait NonTemplateMemberEntity extends MemberEntity {
* It corresponds to a real member, and provides a simplified, yet compatible signature for that member. */
def isUseCase: Boolean
/** If this symbol is a use case, the useCaseOf will contain the member it was derived from, containing the full
* signature and the complete parameter descriptions. */
def useCaseOf: Option[MemberEntity]
/** Whether this member is a bridge member. A bridge member does only exist for binary compatibility reasons
* and should not appear in ScalaDoc. */
def isBridge: Boolean

View File

@ -453,16 +453,18 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
/** */
def makeMember(aSym: Symbol, inTpl: => DocTemplateImpl): List[MemberImpl] = {
def makeMember0(bSym: Symbol): Option[MemberImpl] = {
def makeMember0(bSym: Symbol, _useCaseOf: Option[MemberImpl]): Option[MemberImpl] = {
if (bSym.isGetter && bSym.isLazy)
Some(new NonTemplateMemberImpl(bSym, inTpl) with Val {
override lazy val comment = // The analyser does not duplicate the lazy val's DocDef when it introduces its accessor.
thisFactory.comment(bSym.accessed, inTpl) // This hack should be removed after analyser is fixed.
override def isLazyVal = true
override def useCaseOf = _useCaseOf
})
else if (bSym.isGetter && bSym.accessed.isMutable)
Some(new NonTemplateMemberImpl(bSym, inTpl) with Val {
override def isVar = true
override def useCaseOf = _useCaseOf
})
else if (bSym.isMethod && !bSym.hasAccessorFlag && !bSym.isConstructor && !bSym.isModule) {
val cSym = { // This unsightly hack closes issue #4086.
@ -478,25 +480,30 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
}
Some(new NonTemplateParamMemberImpl(cSym, inTpl) with HigherKindedImpl with Def {
override def isDef = true
override def useCaseOf = _useCaseOf
})
}
else if (bSym.isConstructor)
Some(new NonTemplateParamMemberImpl(bSym, inTpl) with Constructor {
override def isConstructor = true
def isPrimary = sym.isPrimaryConstructor
override def useCaseOf = _useCaseOf
})
else if (bSym.isGetter) // Scala field accessor or Java field
Some(new NonTemplateMemberImpl(bSym, inTpl) with Val {
override def isVal = true
override def useCaseOf = _useCaseOf
})
else if (bSym.isAbstractType)
Some(new NonTemplateMemberImpl(bSym, inTpl) with TypeBoundsImpl with HigherKindedImpl with AbstractType {
override def isAbstractType = true
override def useCaseOf = _useCaseOf
})
else if (bSym.isAliasType)
Some(new NonTemplateMemberImpl(bSym, inTpl) with HigherKindedImpl with AliasType {
override def isAliasType = true
def alias = makeTypeInTemplateContext(sym.tpe.dealias, inTpl, sym)
override def useCaseOf = _useCaseOf
})
else if (bSym.isPackage)
inTpl match { case inPkg: PackageImpl => makePackage(bSym, inPkg) }
@ -510,9 +517,16 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
Nil
else {
val allSyms = useCases(aSym, inTpl.sym) map { case (bSym, bComment, bPos) =>
addCommentBody(bSym, inTpl, bComment, bPos)
docComments.put(bSym, DocComment(bComment, bPos)) // put the comment in the list, don't parse it yet, closes SI-4898
bSym
}
(allSyms :+ aSym) flatMap { makeMember0(_) }
val member = makeMember0(aSym, None)
if (allSyms.isEmpty)
member.toList
else
// Use cases replace the original definitions - SI-5054
allSyms flatMap { makeMember0(_, member) }
}
}

View File

@ -12,6 +12,7 @@ import scala.tools.nsc.ast._
import scala.tools.nsc.reporters._
import scala.tools.nsc.io._
import scala.tools.nsc.scratchpad.{Executor, SourceInserter}
import scala.tools.nsc.interpreter.AbstractFileClassLoader
import java.io.{File, FileWriter}
/** Interface of interactive compiler to a client such as an IDE
@ -23,7 +24,7 @@ object REPL {
Properties.copyrightString
val prompt = "> "
var reporter: ConsoleReporter = _
private def replError(msg: String) {
@ -117,35 +118,85 @@ object REPL {
comp.askParsedEntered(toSourceFile(file), false, structureResult)
show(structureResult)
}
/** This is the method for implement worksheet functionality
/** Write instrumented source file to disk.
* @param iFullName The full name of the first top-level object in source
* @param iContents An Array[Char] containing the instrumented source
* @return The name of the instrumented source file
*/
def instrument(source: SourceFile, line: Int): Option[Array[Char]] = {
def writeInstrumented(iFullName: String, iContents: Array[Char]): String = {
val iSimpleName = iFullName drop ((iFullName lastIndexOf '.') + 1)
val iSourceName = iSimpleName + "$instrumented.scala"
val ifile = new FileWriter(iSourceName)
ifile.write(iContents)
ifile.close()
iSourceName
}
/** Compile instrumented source file
* @param iSourceName The name of the instrumented source file
* @param arguments Further argumenrs to pass to the compiler
* @return Optionallu, if no -d option is given, the virtual directory
* contained the generated bytecode classes
*/
def compileInstrumented(iSourceName: String, arguments: List[String]): Option[AbstractFile] = {
println("compiling "+iSourceName)
val command = new CompilerCommand(iSourceName :: arguments, reporter.error(scala.tools.nsc.util.NoPosition, _))
val virtualDirectoryOpt =
if (arguments contains "-d")
None
else {
val vdir = new VirtualDirectory("(memory)", None)
command.settings.outputDirs setSingleOutput vdir
Some(vdir)
}
val compiler = new scala.tools.nsc.Global(command.settings, reporter)
val run = new compiler.Run()
println("compiling: "+command.files)
run compile command.files
virtualDirectoryOpt
}
/** Run instrumented bytecode file
* @param vdir Optionally, the virtual directory containing the generated bytecode classes
* @param iFullName The full name of the generated object
* @param stripped The contents original source file without any right hand column comments.
* @return The generated file content containing original source in the left column
* and outputs in the right column
*/
def runInstrumented(vdirOpt: Option[AbstractFile], iFullName: String, stripped: Array[Char]): Array[Char] = {
val defaultClassLoader = getClass.getClassLoader
val classLoader = vdirOpt match {
case Some(vdir) => new AbstractFileClassLoader(vdir, defaultClassLoader)
case None => defaultClassLoader
}
println("running "+iFullName)
val si = new SourceInserter(stripped)
Executor.execute(iFullName, si, classLoader)
println("done")
si.currentContents
}
/** The method for implementing worksheet functionality.
* @param arguments a file name, followed by optional command line arguments that are passed
* to the compiler that processes the instrumented source.
* @param line A line number that controls uop to which line results should be produced
* If line = -1, results are produced for all expressions in the worksheet.
* @return The generated file content containing original source in the left column
* and outputs in the right column, or None if the presentation compiler
* does not respond to askInstrumented.
*/
def instrument(arguments: List[String], line: Int): Option[Array[Char]] = {
val source = toSourceFile(arguments.head)
// strip right hand side comment column and any trailing spaces from all lines
val strippedSource = new BatchSourceFile(source.file, SourceInserter.stripRight(source.content))
comp.askReload(List(strippedSource), reloadResult)
// todo: Display strippedSource in place of source
comp.askInstrumented(strippedSource, line, instrumentedResult)
using(instrumentedResult) { case (iFullName, iContents) =>
// iFullName: The full name of the first top-level object in source
// iContents: An Array[Char] containing the instrumented source
// Create a file from iContents so that it can be compiled
// The name here is <simple name of object>+"$instrumented.scala", but
// it could be anything.
val iSimpleName = iFullName drop ((iFullName lastIndexOf '.') + 1)
val iSourceName = iSimpleName + "$instrumented.scala"
val ifile = new FileWriter(iSourceName)
ifile.write(iContents)
ifile.close()
println("compiling "+iSourceName)
// Compile instrumented source
scala.tools.nsc.Main.process(Array(iSourceName, "-verbose", "-d", "/classes"))
// Run instrumented source, inserting all output into stripped source
println("running "+iSimpleName)
val si = new SourceInserter(strippedSource.content)
Executor.execute(iSimpleName, si)
println("done")
si.currentContents
using(instrumentedResult) {
case (iFullName, iContents) =>
val iSourceName = writeInstrumented(iFullName, iContents)
val vdirOpt = compileInstrumented(iSourceName, arguments.tail)
runInstrumented(vdirOpt, iFullName, strippedSource.content)
}
}
@ -170,17 +221,29 @@ object REPL {
doComplete(makePos(file, off1, off2))
case List("complete", file, off1) =>
doComplete(makePos(file, off1, off1))
case List("instrument", file) =>
println(instrument(toSourceFile(file), -1).map(_.mkString))
case List("instrument", file, line) =>
println(instrument(toSourceFile(file), line.toInt).map(_.mkString))
case "instrument" :: arguments =>
println(instrument(arguments, -1).map(_.mkString))
case "instrumentTo" :: line :: arguments =>
println(instrument(arguments, line.toInt).map(_.mkString))
case List("quit") =>
comp.askShutdown()
exit(1) // Don't use sys yet as this has to run on 2.8.2 also.
case List("structure", file) =>
doStructure(file)
case _ =>
println("unrecongized command")
print("""Available commands:
| reload <file_1> ... <file_n>
| reloadAndAskType <file> <sleep-ms>
| typed <file>
| typeat <file> <start-pos> <end-pos>
| typeat <file> <pos>
| complete <file> <start-pos> <end-pos>
| compile <file> <pos>
| instrument <file> <arg>*
| instrumentTo <line-num> <file> <arg>*
| structure <file>
| quit
|""".stripMargin)
}
}
}

View File

@ -81,7 +81,11 @@ private[tests] trait CoreTestDefs
else {
reporter.println("\naskHyperlinkPos for `" + tree.symbol.name + "` at " + format(pos) + " " + pos.source.file.name)
val r = new Response[Position]
val sourceFile = sourceFiles.find(tree.symbol.sourceFile.path == _.path) match {
// `tree.symbol.sourceFile` was discovered to be null when testing -Yvirtpatmat on the akka presentation test, where a position had shifted to point to `Int`
// askHyperlinkPos for `Int` at (73,19) pi.scala --> class Int in package scala has null sourceFile!
val treePath = if (tree.symbol.sourceFile ne null) tree.symbol.sourceFile.path else null
val treeName = if (tree.symbol.sourceFile ne null) tree.symbol.sourceFile.name else null
val sourceFile = sourceFiles.find(_.path == treePath) match {
case Some(source) =>
compiler.askLinkPos(tree.symbol, source, r)
r.get match {
@ -93,7 +97,7 @@ private[tests] trait CoreTestDefs
ex.printStackTrace()
}
case None =>
reporter.println("[error] could not locate sourcefile `" + tree.symbol.sourceFile.name + "`." +
reporter.println("[error] could not locate sourcefile `" + treeName + "`." +
"Hint: Does the looked up definition come form a binary?")
}
}

View File

@ -17,9 +17,10 @@ import scala.collection.mutable.ListBuffer
import scala.concurrent.ops
import util.{ ClassPath, Exceptional, stringFromWriter, stringFromStream }
import interpreter._
import io.{ File, Sources }
import io.{ File, Sources, Directory }
import scala.reflect.NameTransformer._
import util.ScalaClassLoader._
import util.ScalaClassLoader
import ScalaClassLoader._
import scala.tools.util._
/** The Scala interactive shell. It provides a read-eval-print loop
@ -374,7 +375,17 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
}
}
protected def newJavap() = new JavapClass(intp.classLoader, new IMain.ReplStrippingWriter(intp)) {
private def addToolsJarToLoader() = {
val javaHome = Directory(sys.env("JAVA_HOME"))
val tools = javaHome / "lib" / "tools.jar"
if (tools.isFile) {
echo("Found tools.jar, adding for use by javap.")
ScalaClassLoader.fromURLs(Seq(tools.toURL), intp.classLoader)
}
else intp.classLoader
}
protected def newJavap() = new JavapClass(addToolsJarToLoader(), new IMain.ReplStrippingWriter(intp)) {
override def tryClass(path: String): Array[Byte] = {
val hd :: rest = path split '.' toList;
// If there are dots in the name, the first segment is the

View File

@ -40,7 +40,15 @@ class Jar(file: File) extends Iterable[JarEntry] {
lazy val jarFile = new JarFile(file.jfile)
lazy val manifest = withJarInput(s => Option(s.getManifest))
def mainClass = manifest map (f => f(Name.MAIN_CLASS))
/** The manifest-defined classpath String if available. */
def classPathString: Option[String] =
for (m <- manifest ; cp <- m.attrs get Name.CLASS_PATH) yield cp
def classPathElements: List[String] = classPathString match {
case Some(s) => s split "\\s+" toList
case _ => Nil
}
def withJarInput[T](f: JarInputStream => T): T = {
val in = new JarInputStream(file.inputStream())

View File

@ -919,6 +919,7 @@ trait JavaScanners extends ast.parser.ScannersCommon {
def warning(pos: Int, msg: String) = unit.warning(pos, msg)
def error (pos: Int, msg: String) = unit. error(pos, msg)
def incompleteInputError(pos: Int, msg: String) = unit.incompleteInputError(pos, msg)
def deprecationWarning(pos: Int, msg: String) = unit.deprecationWarning(pos, msg)
implicit def p2g(pos: Position): Int = if (pos.isDefined) pos.point else -1
implicit def g2p(pos: Int): Position = new OffsetPosition(unit.source, pos)
}

View File

@ -24,7 +24,10 @@ trait ParallelMatching extends ast.TreeDSL
self: ExplicitOuter =>
import global.{ typer => _, _ }
import definitions.{ AnyRefClass, NothingClass, IntClass, BooleanClass, SomeClass, OptionClass, getProductArgs, productProj }
import definitions.{
AnyRefClass, NothingClass, IntClass, BooleanClass, SomeClass, OptionClass,
getProductArgs, productProj, Object_eq, Any_asInstanceOf
}
import CODE._
import Types._
import Debug._
@ -132,7 +135,7 @@ trait ParallelMatching extends ast.TreeDSL
def castedTo(headType: Type) =
if (tpe =:= headType) this
else new Scrutinee(createVar(headType, lhs => id AS_ANY lhs.tpe))
else new Scrutinee(createVar(headType, lhs => gen.mkAsInstanceOf(id, lhs.tpe)))
override def toString() = "(%s: %s)".format(id, tpe)
}
@ -673,8 +676,8 @@ trait ParallelMatching extends ast.TreeDSL
// the val definition's type, or a casted Ident if not.
private def newValIdent(lhs: Symbol, rhs: Symbol) =
if (rhs.tpe <:< lhs.tpe) Ident(rhs)
else Ident(rhs) AS lhs.tpe
else gen.mkTypeApply(Ident(rhs), Any_asInstanceOf, List(lhs.tpe))
protected def newValDefinition(lhs: Symbol, rhs: Symbol) =
typer typedValDef ValDef(lhs, newValIdent(lhs, rhs))
@ -854,10 +857,11 @@ trait ParallelMatching extends ast.TreeDSL
case ThisType(clazz) => THIS(clazz)
case pre => REF(pre.prefix, pre.termSymbol)
})
outerAccessor(tpe2test.typeSymbol) match {
case NoSymbol => ifDebug(cunit.warning(scrut.pos, "no outer acc for " + tpe2test.typeSymbol)) ; cond
case outerAcc => cond AND (((scrut AS_ANY tpe2test) DOT outerAcc)() OBJ_EQ theRef)
case outerAcc =>
val casted = gen.mkAsInstanceOf(scrut, tpe2test, any = true, wrapInApply = true)
cond AND ((casted DOT outerAcc)() OBJ_EQ theRef)
}
}
}

View File

@ -1,8 +1,10 @@
package scala.tools.nsc.scratchpad
import java.io.{PrintStream, OutputStreamWriter, Writer}
import scala.runtime.ScalaRunTime.replStringOf
import scala.runtime.ScalaRunTime.stringOf
import java.lang.reflect.InvocationTargetException
import scala.reflect.ReflectionUtils._
object Executor {
@ -10,19 +12,10 @@ object Executor {
private var currentWriter: CommentWriter = null
def ultimateCause(ex: Throwable): Throwable = ex match {
case ex: InvocationTargetException =>
ultimateCause(ex.getCause)
case ex: ExceptionInInitializerError =>
ultimateCause(ex.getCause)
case ex =>
ex
}
/** Execute module with given name, redirecting all output to given
* source inserter. Catch all exceptions and print stacktrace of underlying causes.
*/
def execute(name: String, si: SourceInserter) {
def execute(name: String, si: SourceInserter, classLoader: ClassLoader = getClass.getClassLoader) {
val oldSysOut = System.out
val oldSysErr = System.err
val oldConsOut = Console.out
@ -35,11 +28,10 @@ object Executor {
Console.setOut(newOut)
Console.setErr(newOut)
try {
val clazz = Class.forName(name+"$")
clazz.getField("$MODULE").get(null)
singletonInstance(name, classLoader)
} catch {
case ex: Throwable =>
ultimateCause(ex) match {
unwrapThrowable(ex) match {
case _: StopException => ;
case cause => cause.printStackTrace()
}
@ -57,7 +49,7 @@ object Executor {
def $stop() = throw new StopException
def $show(x: Any): String = replStringOf(x, scala.Int.MaxValue)
def $show(x: Any): String = stringOf(x, scala.Int.MaxValue)
}
class StopException extends Exception

View File

@ -21,7 +21,6 @@ object SourceInserter {
(prefixes mkString "\n").toArray
}
}
class SourceInserter(contents: Array[Char], start: Int = 0, tabInc: Int = 8) extends Writer {
private var buf = contents
@ -57,7 +56,7 @@ class SourceInserter(contents: Array[Char], start: Int = 0, tabInc: Int = 8) ext
private def insertChar(ch: Char) = {
// Console.err.print("["+ch+"]")
buf(offset) = ch.toChar
buf(offset) = ch
offset += 1
ch match {
case LF => col = 0

View File

@ -23,6 +23,7 @@ trait AestheticSettings {
def deprecation = settings.deprecation.value
def experimental = settings.Xexperimental.value
def fatalWarnings = settings.fatalWarnings.value
def future = settings.future.value
def logClasspath = settings.Ylogcp.value
def printStats = settings.Ystatistics.value
def richExes = settings.YrichExes.value || sys.props.traceSourcePath.isSet

View File

@ -77,18 +77,18 @@ abstract class SymbolLoaders {
enterClassAndModule(root, name, new SourcefileLoader(src))
}
/** Initialize symbol `root` from class path representation `classRep`
/** Initialize toplevel class and module symbols in `owner` from class path representation `classRep`
*/
def initializeFromClassPath(root: Symbol, classRep: ClassPath[platform.BinaryRepr]#ClassRep) {
def initializeFromClassPath(owner: Symbol, classRep: ClassPath[platform.BinaryRepr]#ClassRep) {
((classRep.binary, classRep.source) : @unchecked) match {
case (Some(bin), Some(src)) if platform.needCompile(bin, src) =>
if (settings.verbose.value) inform("[symloader] picked up newer source file for " + src.path)
global.loaders.enterToplevelsFromSource(root, classRep.name, src)
global.loaders.enterToplevelsFromSource(owner, classRep.name, src)
case (None, Some(src)) =>
if (settings.verbose.value) inform("[symloader] no class, picked up source file for " + src.path)
global.loaders.enterToplevelsFromSource(root, classRep.name, src)
global.loaders.enterToplevelsFromSource(owner, classRep.name, src)
case (Some(bin), _) =>
global.loaders.enterClassAndModule(root, classRep.name, platform.newClassLoader(bin))
global.loaders.enterClassAndModule(owner, classRep.name, platform.newClassLoader(bin))
}
}

View File

@ -905,10 +905,7 @@ abstract class ClassfileParser {
case None =>
throw new RuntimeException("Scala class file does not contain Scala annotation")
}
debuglog("[class] << " + sym.fullName + (
if (sym.rawAnnotations.isEmpty) ""
else sym.rawAnnotations.mkString("(", ", ", ")"))
)
debuglog("[class] << " + sym.fullName + sym.annotationsString)
}
else
in.skip(attrLen)
@ -1230,9 +1227,7 @@ abstract class ClassfileParser {
class LazyAliasType(alias: Symbol) extends LazyType {
override def complete(sym: Symbol) {
alias.initialize
val tparams1 = cloneSymbols(alias.typeParams)
sym.setInfo(typeFun(tparams1, alias.tpe.substSym(alias.typeParams, tparams1)))
sym setInfo createFromClonedSymbols(alias.initialize.typeParams, alias.tpe)(typeFun)
}
}

View File

@ -106,10 +106,6 @@ abstract class Pickler extends SubComponent {
sym.isParameter ||
isLocal(sym.owner))
private def staticAnnotations(annots: List[AnnotationInfo]) =
annots filter(ann =>
ann.symbol isNonBottomSubClass definitions.StaticAnnotationClass)
// Phase 1 methods: Populate entries/index ------------------------------------
/** Store entry e in index at next available position unless
@ -156,9 +152,10 @@ abstract class Pickler extends SubComponent {
}
putChildren(sym, children.toList sortBy (_.sealedSortName))
}
for (annot <- staticAnnotations(sym.annotations.reverse))
for (annot <- sym.annotations filter (ann => ann.isStatic && !ann.isErroneous) reverse)
putAnnotation(sym, annot)
} else if (sym != NoSymbol) {
}
else if (sym != NoSymbol) {
putEntry(if (sym.isModuleClass) sym.name.toTermName else sym.name)
if (!sym.owner.isRoot) putSymbol(sym.owner)
}
@ -220,7 +217,7 @@ abstract class Pickler extends SubComponent {
case AnnotatedType(annotations, underlying, selfsym) =>
putType(underlying)
if (settings.selfInAnnots.value) putSymbol(selfsym)
putAnnotations(staticAnnotations(annotations))
putAnnotations(annotations filter (_.isStatic))
case _ =>
throw new FatalError("bad type: " + tp + "(" + tp.getClass + ")")
}
@ -616,17 +613,15 @@ abstract class Pickler extends SubComponent {
else if (c.tag == EnumTag) writeRef(c.symbolValue)
LITERAL + c.tag // also treats UnitTag, NullTag; no value required
case AnnotatedType(annotations, tp, selfsym) =>
val staticAnnots = staticAnnotations(annotations)
if (staticAnnots isEmpty) {
writeBody(tp) // write the underlying type if there are no annotations
} else {
if (settings.selfInAnnots.value && selfsym != NoSymbol)
writeRef(selfsym)
writeRef(tp)
writeRefs(staticAnnots)
ANNOTATEDtpe
annotations filter (_.isStatic) match {
case Nil => writeBody(tp) // write the underlying type if there are no annotations
case staticAnnots =>
if (settings.selfInAnnots.value && selfsym != NoSymbol)
writeRef(selfsym)
writeRef(tp)
writeRefs(staticAnnots)
ANNOTATEDtpe
}
// annotations attached to a symbol (i.e. annots on terms)
case (target: Symbol, annot@AnnotationInfo(_, _, _)) =>
writeRef(target)

View File

@ -245,7 +245,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
def mkNewPolyCache = gen.mkSoftRef(NEW(TypeTree(EmptyMethodCacheClass.tpe)))
val reflPolyCacheSym: Symbol = addStaticVariableToClass("reflPoly$Cache", SoftReferenceClass.tpe, mkNewPolyCache, false)
def getPolyCache = fn(safeREF(reflPolyCacheSym), nme.get) AS_ATTR MethodCacheClass.tpe
def getPolyCache = gen.mkCast(fn(safeREF(reflPolyCacheSym), nme.get), MethodCacheClass.tpe)
addStaticMethodToClass("reflMethod$Method", List(ClassClass.tpe), MethodClass.tpe)
{ case Pair(reflMethodSym, List(forReceiverSym)) =>
@ -405,7 +405,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
def fixResult(tree: Tree, mustBeUnit: Boolean = false) =
if (mustBeUnit || resultSym == UnitClass) BLOCK(tree, REF(BoxedUnit_UNIT)) // boxed unit
else if (resultSym == ObjectClass) tree // no cast necessary
else tree AS_ATTR boxedResType // cast to expected type
else gen.mkCast(tree, boxedResType) // cast to expected type
/** Normal non-Array call */
def genDefaultCall = {

View File

@ -400,11 +400,12 @@ abstract class Constructors extends Transform with ast.TreeDSL {
/** Create a getter or a setter and enter into `clazz` scope
*/
def addAccessor(sym: Symbol, name: TermName, flags: Long) = {
val m = clazz.newMethod(sym.pos, name)
.setFlag(flags & ~LOCAL & ~PRIVATE)
m.privateWithin = clazz
clazz.info.decls.enter(m)
m
val m = (
clazz.newMethod(sym.pos, name)
setFlag (flags & ~LOCAL & ~PRIVATE)
setPrivateWithin clazz
)
clazz.info.decls enter m
}
def addGetter(sym: Symbol): Symbol = {

View File

@ -490,7 +490,7 @@ abstract class Erasure extends AddInterfaces
log("Attempted to cast to Unit: " + tree)
tree.duplicate setType pt
}
else tree AS_ATTR pt
else gen.mkAttributedCast(tree, pt)
}
private def isUnboxedValueMember(sym: Symbol) =
@ -1002,7 +1002,7 @@ abstract class Erasure extends AddInterfaces
if (isAccessible(qualSym) && !qualSym.isPackageClass && !qualSym.isPackageObjectClass) {
// insert cast to prevent illegal access error (see #4283)
// util.trace("insert erasure cast ") (*/
treeCopy.Select(tree, qual AS_ATTR qual.tpe.widen, name) //)
treeCopy.Select(tree, gen.mkAttributedCast(qual, qual.tpe.widen), name) //)
} else tree
} else tree

View File

@ -359,7 +359,7 @@ abstract class ExplicitOuter extends InfoTransform
localTyper typed {
(DEF(outerAcc) withPos currentClass.pos) === {
// Need to cast for nested outer refs in presence of self-types. See ticket #3274.
transformer.transform(path) AS_ANY outerAcc.info.resultType
gen.mkCast(transformer.transform(path), outerAcc.info.resultType)
}
}
}

View File

@ -112,7 +112,7 @@ abstract class LambdaLift extends InfoTransform {
// would have the signature
// closure: (x$1: Int)() => Int
if (sym.isParameter && sym.owner.info.paramss.exists(_ contains sym))
sym.owner.setInfo(sym.owner.info.cloneInfo(sym.owner))
sym.owner modifyInfo (_ cloneInfo sym.owner)
}
changedFreeVars = true
debuglog("" + sym + " is free in " + enclosure);

View File

@ -12,7 +12,8 @@ import scala.collection.{ mutable, immutable }
import scala.collection.mutable.ListBuffer
import scala.tools.nsc.util.FreshNameCreator
/** Translate expressions of the form reflect.Code.lift(exp)
/**
* Translate expressions of the form reflect.Code.lift(exp)
* to the reified "reflect trees" representation of exp.
* Also: mutable variables that are accessed from a local function are wrapped in refs.
*
@ -21,9 +22,9 @@ import scala.tools.nsc.util.FreshNameCreator
*/
abstract class LiftCode extends Transform with TypingTransformers {
import global._ // the global environment
import definitions._ // standard classes and methods
import typer.{typed, atOwner} // methods to type trees
import global._ // the global environment
import definitions._ // standard classes and methods
import typer.{ typed, atOwner } // methods to type trees
val symbols: global.type = global
@ -32,12 +33,12 @@ abstract class LiftCode extends Transform with TypingTransformers {
def newTransformer(unit: CompilationUnit): Transformer =
new Codifier(unit)
class Codifier(unit: CompilationUnit) extends TypingTransformer(unit) {
val reifyDebug = settings.Yreifydebug.value
val debugTrace = util.trace when reifyDebug
/** Set of mutable local variables that are free in some inner method. */
private val freeMutableVars: mutable.Set[Symbol] = new mutable.HashSet
private val converted: mutable.Set[Symbol] = new mutable.HashSet // debug
@ -49,7 +50,7 @@ abstract class LiftCode extends Transform with TypingTransformers {
super.transformUnit(unit)
}
for (v <- freeMutableVars) //!!! remove
assert(converted contains v, "unconverted: "+v+" in "+v.owner+" in unit "+unit)
assert(converted contains v, "unconverted: " + v + " in " + v.owner + " in unit " + unit)
}
override def transform(tree: Tree): Tree = {
@ -75,10 +76,10 @@ abstract class LiftCode extends Transform with TypingTransformers {
}
sym resetFlag MUTABLE
sym removeAnnotation VolatileAttr
converted += sym// dereference boxed variables
converted += sym // dereference boxed variables
treeCopy.ValDef(tree, mods &~ MUTABLE, name, tpt1, rhs1)
case Ident(name) if freeMutableVars(sym) =>
localTyper.typedPos(tree.pos) {
localTyper.typedPos(tree.pos) {
Select(tree setType sym.tpe, nme.elem)
}
case _ =>
@ -86,335 +87,14 @@ abstract class LiftCode extends Transform with TypingTransformers {
}
}
/** todo: Treat embedded Code blocks by merging them into containing block
*
*/
class Reifier() {
final val mirrorFullName = "scala.reflect.runtime.Mirror"
final val mirrorShortName = "$mr"
final val mirrorPrefix = mirrorShortName + "."
final val scalaPrefix = "scala."
final val localPrefix = "$local"
final val memoizerName = "$memo"
private val reifiableSyms = mutable.ArrayBuffer[Symbol]() // the symbols that are reified with the tree
private val symIndex = mutable.HashMap[Symbol, Int]() // the index of a reifiable symbol in `reifiableSyms`
private var boundSyms = Set[Symbol]() // set of all symbols that are bound in tree to be reified
/** Generate tree of the form
*
* { val $mr = scala.reflect.runtime.Mirror
* val $memo = new scala.reflext.runtime.Memoizer
* $local1 = new TypeSymbol(owner1, NoPosition, name1)
* ...
* $localN = new TermSymbol(ownerN, NoPositiion, nameN)
* $local1.setInfo(tpe1)
* ...
* $localN.setInfo(tpeN)
* $localN.setAnnotations(annotsN)
* rtree
* }
*
* where
*
* - `$localI` are free type symbols in the environment, as well as local symbols
* of refinement types.
* - `tpeI` are the info's of `symI`
* - `rtree` is code that generates `tree` at runtime, maintaining all attributes.
*/
def reifyTopLevel(tree: Tree): Tree = {
val rtree = reify(tree)
Block(mirrorAlias :: reifySymbolTableSetup, rtree)
}
private def isLocatable(sym: Symbol) =
sym.isPackageClass || sym.owner.isClass || sym.isTypeParameter && sym.paramPos >= 0
private def registerReifiableSymbol(sym: Symbol): Unit =
if (!(symIndex contains sym)) {
sym.owner.ownersIterator.find(!isLocatable(_)) match {
case Some(outer) => registerReifiableSymbol(outer)
case None =>
}
symIndex(sym) = reifiableSyms.length
reifiableSyms += sym
}
// helper methods
private def localName(sym: Symbol) = localPrefix + symIndex(sym)
private def call(fname: String, args: Tree*): Tree =
Apply(termPath(fname), args.toList)
private def mirrorSelect(name: String): Tree =
termPath(mirrorPrefix + name)
private def mirrorCall(name: String, args: Tree*): Tree =
call(mirrorPrefix + name, args: _*)
private def mirrorFactoryCall(value: Product, args: Tree*): Tree =
mirrorCall(value.productPrefix, args: _*)
private def scalaFactoryCall(name: String, args: Tree*): Tree =
call(scalaPrefix + name + ".apply", args: _*)
private def mkList(args: List[Tree]): Tree =
scalaFactoryCall("collection.immutable.List", args: _*)
/** Reify a case object defined in Mirror
*/
private def reifyCaseObject(value: Product) = mirrorSelect(value.productPrefix)
/** Reify an instance of a case class defined in Mirror
*/
private def reifyCaseClassInstance(value: Product) =
mirrorFactoryCall(value, (value.productIterator map reify).toList: _*)
private def reifyAggregate(name: String, args: Any*) =
scalaFactoryCall(name, (args map reify).toList: _*)
/** Reify a list
*/
private def reifyList(xs: List[Any]): Tree =
mkList(xs map reify)
/** Reify a name */
private def reifyName(name: Name) =
mirrorCall(if (name.isTypeName) "newTypeName" else "newTermName", Literal(Constant(name.toString)))
private def isFree(sym: Symbol) =
!(symIndex contains sym)
/** Reify a reference to a symbol
*/
private def reifySymRef(sym: Symbol): Tree = {
symIndex get sym match {
case Some(idx) =>
Ident(localName(sym))
case None =>
if (sym == NoSymbol)
mirrorSelect("NoSymbol")
else if (sym.isModuleClass)
Select(reifySymRef(sym.sourceModule), "moduleClass")
else if (sym.isStatic && sym.isClass)
mirrorCall("staticClass", reify(sym.fullName))
else if (sym.isStatic && sym.isModule)
mirrorCall("staticModule", reify(sym.fullName))
else if (isLocatable(sym))
if (sym.isTypeParameter)
mirrorCall("selectParam", reify(sym.owner), reify(sym.paramPos))
else {
if (reifyDebug) println("locatable: "+sym+" "+sym.isPackageClass+" "+sym.owner+" "+sym.isTypeParameter)
val rowner = reify(sym.owner)
val rname = reify(sym.name.toString)
if (sym.isType)
mirrorCall("selectType", rowner, rname)
else if (sym.isMethod && sym.owner.isClass && sym.owner.info.decl(sym.name).isOverloaded) {
val index = sym.owner.info.decl(sym.name).alternatives indexOf sym
assert(index >= 0, sym)
mirrorCall("selectOverloadedMethod", rowner, rname, reify(index))
} else
mirrorCall("selectTerm", rowner, rname)
}
else {
if (sym.isTerm) {
if (reifyDebug) println("Free: "+sym)
mirrorCall("freeVar", reify(sym.name.toString), reify(sym.tpe), Ident(sym))
} else {
if (reifyDebug) println("Late local: "+sym)
registerReifiableSymbol(sym)
reifySymRef(sym)
}
}
}
}
/** reify the creation of a symbol
*/
private def reifySymbolDef(sym: Symbol): Tree = {
if (reifyDebug) println("reify sym def "+sym)
var rsym: Tree = New(
typePath(mirrorPrefix + (if (sym.isType) "TypeSymbol" else "TermSymbol")),
List(List(reify(sym.owner), reify(sym.pos), reify(sym.name))))
if (sym.flags != 0L)
rsym = Apply(Select(rsym, "setFlag"), List(Literal(Constant(sym.flags))))
ValDef(NoMods, localName(sym), TypeTree(), rsym)
}
/** Generate code to add type and annotation info to a reified symbol
*/
private def fillInSymbol(sym: Symbol): Tree = {
val rset = Apply(Select(reifySymRef(sym), "setInfo"), List(reifyType(sym.info)))
if (sym.annotations.isEmpty) rset
else Apply(Select(rset, "setAnnotations"), List(reify(sym.annotations)))
}
/** Reify a scope */
private def reifyScope(scope: Scope): Tree = {
scope foreach registerReifiableSymbol
mirrorCall("newScopeWith", scope.toList map reifySymRef: _*)
}
/** Reify a list of symbols that need to be created */
private def reifySymbols(syms: List[Symbol]): Tree = {
syms foreach registerReifiableSymbol
mkList(syms map reifySymRef)
}
/** Reify a type that defines some symbols */
private def reifyTypeBinder(value: Product, bound: List[Symbol], underlying: Type): Tree =
mirrorFactoryCall(value, reifySymbols(bound), reify(underlying))
/** Reify a type */
private def reifyType(tpe0: Type): Tree = {
val tpe = tpe0.normalize
val tsym = tpe.typeSymbol
if (tsym.isClass && tpe == tsym.typeConstructor && tsym.isStatic)
Select(reifySymRef(tpe.typeSymbol), "typeConstructor")
else tpe match {
case NoType | NoPrefix =>
reifyCaseObject(tpe.asInstanceOf[Product])
case tpe @ ThisType(clazz) =>
if (clazz.isModuleClass && clazz.isStatic) mirrorCall("thisModuleType", reify(clazz.fullName))
else reifyCaseClassInstance(tpe)
case SuperType(_, _) | SingleType(_, _) | ConstantType(_) |
TypeRef(_, _, _) | AnnotatedType(_, _, _) |
TypeBounds(_, _) | NullaryMethodType(_) | OverloadedType(_, _) =>
reifyCaseClassInstance(tpe.asInstanceOf[Product])
case t @ RefinedType(parents, decls) =>
registerReifiableSymbol(tpe.typeSymbol)
mirrorFactoryCall(t, reify(parents), reify(decls), reify(t.typeSymbol))
case t @ ClassInfoType(parents, decls, clazz) =>
registerReifiableSymbol(clazz)
mirrorFactoryCall(t, reify(parents), reify(decls), reify(t.typeSymbol))
case t @ ExistentialType(tparams, underlying) =>
reifyTypeBinder(t, tparams, underlying)
case t @ PolyType(tparams, underlying) =>
reifyTypeBinder(t, tparams, underlying)
case t @ MethodType(params, restpe) =>
reifyTypeBinder(t, params, restpe)
case _ =>
abort("cannot reify type " + tpe + " of class " + tpe.getClass)
}
}
/** Reify a tree */
private def reifyTree(tree: Tree): Tree = tree match {
case EmptyTree =>
reifyCaseObject(tree)
case This(_) if !(boundSyms contains tree.symbol) =>
reifyFree(tree)
case Ident(_) if !(boundSyms contains tree.symbol) =>
reifyFree(tree)
case TypeTree() if (tree.tpe != null) =>
mirrorCall("TypeTree", reifyType(tree.tpe))
case _ =>
if (tree.isDef) boundSyms += tree.symbol
reifyCaseClassInstance(tree.asInstanceOf[Product])
/*
if (tree.isDef || tree.isInstanceOf[Function])
registerReifiableSymbol(tree.symbol)
if (tree.hasSymbol)
rtree = Apply(Select(rtree, "setSymbol"), List(reifySymRef(tree.symbol)))
Apply(Select(rtree, "setType"), List(reifyType(tree.tpe)))
*/
}
/** Reify a free reference. The result will be either a mirror reference
* to a global value, or else a mirror Literal.
*/
private def reifyFree(tree: Tree): Tree =
mirrorCall("Ident", reifySymRef(tree.symbol))
/** Reify an arbitary value */
private def reify(value: Any): Tree = {
value match {
case tree: Tree =>
reifyTree(tree)
case sym: Symbol =>
reifySymRef(sym)
case tpe: Type =>
reifyType(tpe)
case xs: List[_] =>
scalaFactoryCall("collection.immutable.List", xs map reify: _*)
case xs: Array[_] =>
scalaFactoryCall("Array", xs map reify: _*)
case scope: Scope =>
reifyScope(scope)
case x: Name =>
reifyName(x)
case pos: Position => // todo: consider whether we should also reify positions
reifyCaseObject(NoPosition)
case Constant(_) | AnnotationInfo(_, _, _) | Modifiers(_, _, _) =>
reifyCaseClassInstance(value.asInstanceOf[Product])
case arg: ClassfileAnnotArg =>
reifyCaseClassInstance(arg.asInstanceOf[Product])
case x: Product if x.getClass.getName startsWith "scala.Tuple" =>
reifyCaseClassInstance(x)
case () => Literal(Constant(()))
case x: String => Literal(Constant(x))
case x: Boolean => Literal(Constant(x))
case x: Byte => Literal(Constant(x))
case x: Short => Literal(Constant(x))
case x: Char => Literal(Constant(x))
case x: Int => Literal(Constant(x))
case x: Long => Literal(Constant(x))
case x: Float => Literal(Constant(x))
case x: Double => Literal(Constant(x))
case _ => cannotReify(value)
}
}
/** An (unreified) path that refers to definition with given fully qualified name
* @param mkName Creator for last portion of name (either TermName or TypeName)
*/
private def path(fullname: String, mkName: String => Name): Tree = {
val parts = fullname split "\\."
val prefixParts = parts.init
val lastName = mkName(parts.last)
if (prefixParts.isEmpty) Ident(lastName)
else {
val prefixTree = ((Ident(prefixParts.head): Tree) /: prefixParts.tail)(Select(_, _))
Select(prefixTree, lastName)
}
}
/** An (unreified) path that refers to term definition with given fully qualified name */
private def termPath(fullname: String): Tree = path(fullname, newTermName)
/** An (unreified) path that refers to type definition with given fully qualified name */
private def typePath(fullname: String): Tree = path(fullname, newTypeName)
private def mirrorAlias =
ValDef(NoMods, mirrorShortName, TypeTree(), termPath(mirrorFullName))
/** Generate code that generates a symbol table of all symbols registered in `reifiableSyms`
*/
private def reifySymbolTableSetup: List[Tree] = {
val symDefs, fillIns = new mutable.ArrayBuffer[Tree]
var i = 0
while (i < reifiableSyms.length) {
// fillInSymbol might create new reifiableSyms, that's why this is done iteratively
symDefs += reifySymbolDef(reifiableSyms(i))
fillIns += fillInSymbol(reifiableSyms(i))
i += 1
}
symDefs.toList ++ fillIns.toList
}
private def cannotReify(value: Any): Nothing =
abort("don't know how to reify " + value + " of class " + value.getClass)
}
def codify(tree: Tree): Tree = debugTrace("codified " + tree + " -> ") {
val targetType = definitions.CodeClass.primaryConstructor.info.paramTypes.head
val reifier = new Reifier()
val arg = gen.mkAsInstanceOf(reifier.reifyTopLevel(tree), targetType, wrapInApply = false)
New(TypeTree(appliedType(definitions.CodeClass.typeConstructor, List(tree.tpe))),
val treetpe =
if (tree.tpe.typeSymbol.isAnonymousClass) tree.tpe.typeSymbol.classBound
else tree.tpe
New(TypeTree(appliedType(definitions.CodeClass.typeConstructor, List(treetpe.widen))),
List(List(arg)))
}
@ -455,7 +135,7 @@ abstract class LiftCode extends Transform with TypingTransformers {
else
traverse(arg)
}
/** The rhs of a closure represents escape. */
case Function(vparams, body) =>
vparams foreach traverse
@ -486,4 +166,356 @@ abstract class LiftCode extends Transform with TypingTransformers {
}
}
}
/**
* Given a tree or type, generate a tree that when executed at runtime produces the original tree or type.
* For instance: Given
*
* var x = 1; Code(x + 1)
*
* The `x + 1` expression is reified to
*
* $mr.Apply($mr.Select($mr.Ident($mr.freeVar("x". <Int>, x), "+"), List($mr.Literal($mr.Constant(1))))))
*
* Or, the term name 'abc' is reified to:
*
* $mr.Apply($mr.Select($mr.Ident("newTermName")), List(Literal(Constant("abc")))))
*
* todo: Treat embedded Code blocks by merging them into containing block
*
*/
class Reifier() {
final val mirrorFullName = "scala.reflect.mirror"
final val mirrorShortName = "$mr"
final val mirrorPrefix = mirrorShortName + "."
final val scalaPrefix = "scala."
final val localPrefix = "$local"
final val memoizerName = "$memo"
val reifyDebug = settings.Yreifydebug.value
private val reifiableSyms = mutable.ArrayBuffer[Symbol]() // the symbols that are reified with the tree
private val symIndex = mutable.HashMap[Symbol, Int]() // the index of a reifiable symbol in `reifiableSyms`
private var boundSyms = Set[Symbol]() // set of all symbols that are bound in tree to be reified
/**
* Generate tree of the form
*
* { val $mr = scala.reflect.runtime.Mirror
* $local1 = new TypeSymbol(owner1, NoPosition, name1)
* ...
* $localN = new TermSymbol(ownerN, NoPositiion, nameN)
* $local1.setInfo(tpe1)
* ...
* $localN.setInfo(tpeN)
* $localN.setAnnotations(annotsN)
* rtree
* }
*
* where
*
* - `$localI` are free type symbols in the environment, as well as local symbols
* of refinement types.
* - `tpeI` are the info's of `symI`
* - `rtree` is code that generates `data` at runtime, maintaining all attributes.
* - `data` is typically a tree or a type.
*/
def reifyTopLevel(data: Any): Tree = {
val rtree = reify(data)
Block(mirrorAlias :: reifySymbolTableSetup, rtree)
}
private def isLocatable(sym: Symbol) =
sym.isPackageClass || sym.owner.isClass || sym.isTypeParameter && sym.paramPos >= 0
private def registerReifiableSymbol(sym: Symbol): Unit =
if (!(symIndex contains sym)) {
sym.owner.ownersIterator.find(!isLocatable(_)) match {
case Some(outer) => registerReifiableSymbol(outer)
case None =>
}
symIndex(sym) = reifiableSyms.length
reifiableSyms += sym
}
// helper methods
private def localName(sym: Symbol) = localPrefix + symIndex(sym)
private def call(fname: String, args: Tree*): Tree =
Apply(termPath(fname), args.toList)
private def mirrorSelect(name: String): Tree =
termPath(mirrorPrefix + name)
private def mirrorCall(name: String, args: Tree*): Tree =
call(mirrorPrefix + name, args: _*)
private def mirrorFactoryCall(value: Product, args: Tree*): Tree =
mirrorCall(value.productPrefix, args: _*)
private def scalaFactoryCall(name: String, args: Tree*): Tree =
call(scalaPrefix + name + ".apply", args: _*)
private def mkList(args: List[Tree]): Tree =
scalaFactoryCall("collection.immutable.List", args: _*)
/**
* Reify a case object defined in Mirror
*/
private def reifyCaseObject(value: Product) = mirrorSelect(value.productPrefix)
/**
* Reify an instance of a case class defined in Mirror
*/
private def reifyCaseClassInstance(value: Product) =
mirrorFactoryCall(value, (value.productIterator map reify).toList: _*)
private def reifyAggregate(name: String, args: Any*) =
scalaFactoryCall(name, (args map reify).toList: _*)
/**
* Reify a list
*/
private def reifyList(xs: List[Any]): Tree =
mkList(xs map reify)
/** Reify a name */
private def reifyName(name: Name) =
mirrorCall(if (name.isTypeName) "newTypeName" else "newTermName", Literal(Constant(name.toString)))
private def isFree(sym: Symbol) =
!(symIndex contains sym)
/**
* Reify a reference to a symbol
*/
private def reifySymRef(sym: Symbol): Tree = {
symIndex get sym match {
case Some(idx) =>
Ident(localName(sym))
case None =>
if (sym == NoSymbol)
mirrorSelect("NoSymbol")
else if (sym.isModuleClass)
Select(reifySymRef(sym.sourceModule), "moduleClass")
else if (sym.isStatic && sym.isClass)
mirrorCall("staticClass", reify(sym.fullName))
else if (sym.isStatic && sym.isModule)
mirrorCall("staticModule", reify(sym.fullName))
else if (isLocatable(sym))
if (sym.isTypeParameter)
mirrorCall("selectParam", reify(sym.owner), reify(sym.paramPos))
else {
if (reifyDebug) println("locatable: " + sym + " " + sym.isPackageClass + " " + sym.owner + " " + sym.isTypeParameter)
val rowner = reify(sym.owner)
val rname = reify(sym.name.toString)
if (sym.isType)
mirrorCall("selectType", rowner, rname)
else if (sym.isMethod && sym.owner.isClass && sym.owner.info.decl(sym.name).isOverloaded) {
val index = sym.owner.info.decl(sym.name).alternatives indexOf sym
assert(index >= 0, sym)
mirrorCall("selectOverloadedMethod", rowner, rname, reify(index))
} else
mirrorCall("selectTerm", rowner, rname)
}
else {
if (sym.isTerm) {
if (reifyDebug) println("Free: " + sym)
mirrorCall("freeVar", reify(sym.name.toString), reify(sym.tpe), Ident(sym))
} else {
if (reifyDebug) println("Late local: " + sym)
registerReifiableSymbol(sym)
reifySymRef(sym)
}
}
}
}
/**
* reify the creation of a symbol
*/
private def reifySymbolDef(sym: Symbol): Tree = {
if (reifyDebug) println("reify sym def " + sym)
var rsym: Tree =
Apply(
Select(reify(sym.owner), "newNestedSymbol"),
List(reify(sym.pos), reify(sym.name)))
if (sym.flags != 0L)
rsym = Apply(Select(rsym, "setInternalFlags"), List(Literal(Constant(sym.flags))))
ValDef(NoMods, localName(sym), TypeTree(), rsym)
}
/**
* Generate code to add type and annotation info to a reified symbol
*/
private def fillInSymbol(sym: Symbol): Tree = {
val rset = Apply(Select(reifySymRef(sym), "setTypeSig"), List(reifyType(sym.info)))
if (sym.annotations.isEmpty) rset
else Apply(Select(rset, "setAnnotations"), List(reify(sym.annotations)))
}
/** Reify a scope */
private def reifyScope(scope: Scope): Tree = {
scope foreach registerReifiableSymbol
mirrorCall("newScopeWith", scope.toList map reifySymRef: _*)
}
/** Reify a list of symbols that need to be created */
private def reifySymbols(syms: List[Symbol]): Tree = {
syms foreach registerReifiableSymbol
mkList(syms map reifySymRef)
}
/** Reify a type that defines some symbols */
private def reifyTypeBinder(value: Product, bound: List[Symbol], underlying: Type): Tree =
mirrorFactoryCall(value, reifySymbols(bound), reify(underlying))
/** Reify a type */
private def reifyType(tpe0: Type): Tree = {
val tpe = tpe0.normalize
val tsym = tpe.typeSymbol
if (tsym.isClass && tpe == tsym.typeConstructor && tsym.isStatic)
Select(reifySymRef(tpe.typeSymbol), "asTypeConstructor")
else tpe match {
case NoType | NoPrefix =>
reifyCaseObject(tpe.asInstanceOf[Product])
case tpe @ ThisType(clazz) =>
if (clazz.isModuleClass && clazz.isStatic) mirrorCall("thisModuleType", reify(clazz.fullName))
else reifyCaseClassInstance(tpe)
case SuperType(_, _) | SingleType(_, _) | ConstantType(_) |
TypeRef(_, _, _) | AnnotatedType(_, _, _) |
TypeBounds(_, _) | NullaryMethodType(_) | OverloadedType(_, _) =>
reifyCaseClassInstance(tpe.asInstanceOf[Product])
case t @ RefinedType(parents, decls) =>
registerReifiableSymbol(tpe.typeSymbol)
mirrorFactoryCall(t, reify(parents), reify(decls), reify(t.typeSymbol))
case t @ ClassInfoType(parents, decls, clazz) =>
registerReifiableSymbol(clazz)
mirrorFactoryCall(t, reify(parents), reify(decls), reify(t.typeSymbol))
case t @ ExistentialType(tparams, underlying) =>
reifyTypeBinder(t, tparams, underlying)
case t @ PolyType(tparams, underlying) =>
reifyTypeBinder(t, tparams, underlying)
case t @ MethodType(params, restpe) =>
reifyTypeBinder(t, params, restpe)
case _ =>
cannotReify(tpe)
}
}
/** Reify a tree */
private def reifyTree(tree: Tree): Tree = tree match {
case EmptyTree =>
reifyCaseObject(tree)
case This(_) if !(boundSyms contains tree.symbol) =>
reifyFree(tree)
case Ident(_) if !(boundSyms contains tree.symbol) =>
reifyFree(tree)
case TypeTree() if (tree.tpe != null) =>
mirrorCall("TypeTree", reifyType(tree.tpe))
case _ =>
if (tree.isDef) boundSyms += tree.symbol
reifyCaseClassInstance(tree.asInstanceOf[Product])
/*
if (tree.isDef || tree.isInstanceOf[Function])
registerReifiableSymbol(tree.symbol)
if (tree.hasSymbol)
rtree = Apply(Select(rtree, "setSymbol"), List(reifySymRef(tree.symbol)))
Apply(Select(rtree, "setType"), List(reifyType(tree.tpe)))
*/
}
/**
* Reify a free reference. The result will be either a mirror reference
* to a global value, or else a mirror Literal.
*/
private def reifyFree(tree: Tree): Tree =
mirrorCall("Ident", reifySymRef(tree.symbol))
/** Reify an arbitary value */
private def reify(value: Any): Tree = {
value match {
case tree: Tree =>
reifyTree(tree)
case sym: Symbol =>
reifySymRef(sym)
case tpe: Type =>
reifyType(tpe)
case xs: List[_] =>
scalaFactoryCall("collection.immutable.List", xs map reify: _*)
case xs: Array[_] =>
scalaFactoryCall("Array", xs map reify: _*)
case scope: Scope =>
reifyScope(scope)
case x: Name =>
reifyName(x)
case pos: Position => // todo: consider whether we should also reify positions
reifyCaseObject(NoPosition)
case Constant(_) | AnnotationInfo(_, _, _) =>
reifyCaseClassInstance(value.asInstanceOf[Product])
case Modifiers(flags, qual, annots) =>
mirrorCall("modifiersFromInternalFlags", reify(flags), reify(qual), reify(annots))
case arg: ClassfileAnnotArg =>
reifyCaseClassInstance(arg.asInstanceOf[Product])
case x: Product if x.getClass.getName startsWith "scala.Tuple" =>
reifyCaseClassInstance(x)
case () => Literal(Constant(()))
case x: String => Literal(Constant(x))
case x: Boolean => Literal(Constant(x))
case x: Byte => Literal(Constant(x))
case x: Short => Literal(Constant(x))
case x: Char => Literal(Constant(x))
case x: Int => Literal(Constant(x))
case x: Long => Literal(Constant(x))
case x: Float => Literal(Constant(x))
case x: Double => Literal(Constant(x))
case _ => cannotReify(value)
}
}
/**
* An (unreified) path that refers to definition with given fully qualified name
* @param mkName Creator for last portion of name (either TermName or TypeName)
*/
private def path(fullname: String, mkName: String => Name): Tree = {
val parts = fullname split "\\."
val prefixParts = parts.init
val lastName = mkName(parts.last)
if (prefixParts.isEmpty) Ident(lastName)
else {
val prefixTree = ((Ident(prefixParts.head): Tree) /: prefixParts.tail)(Select(_, _))
Select(prefixTree, lastName)
}
}
/** An (unreified) path that refers to term definition with given fully qualified name */
private def termPath(fullname: String): Tree = path(fullname, newTermName)
/** An (unreified) path that refers to type definition with given fully qualified name */
private def typePath(fullname: String): Tree = path(fullname, newTypeName)
private def mirrorAlias =
ValDef(NoMods, mirrorShortName, TypeTree(), termPath(mirrorFullName))
/**
* Generate code that generates a symbol table of all symbols registered in `reifiableSyms`
*/
private def reifySymbolTableSetup: List[Tree] = {
val symDefs, fillIns = new mutable.ArrayBuffer[Tree]
var i = 0
while (i < reifiableSyms.length) {
// fillInSymbol might create new reifiableSyms, that's why this is done iteratively
symDefs += reifySymbolDef(reifiableSyms(i))
fillIns += fillInSymbol(reifiableSyms(i))
i += 1
}
symDefs.toList ++ fillIns.toList
}
private def cannotReify(value: Any): Nothing =
abort("don't know how to reify " + value + " of class " + value.getClass)
}
}

View File

@ -6,10 +6,48 @@
package scala.tools.nsc
package transform
import scala.tools.nsc.symtab.Flags
import scala.collection.{ mutable, immutable }
/** Specialize code on types.
*
* Make sure you've read the thesis:
*
* Iulian Dragos: Compiling Scala for Performance (chapter 4)
*
* There are some things worth noting, (possibly) not mentioned there:
* 0) Make sure you understand the meaning of various `SpecializedInfo` descriptors
* defined below.
*
* 1) Specializing traits by introducing bridges in specialized methods
* of the specialized trait may introduce problems during mixin composition.
* Concretely, it may cause cyclic calls and result in a stack overflow.
* See ticket #4351.
* This was solved by introducing an `Abstract` specialized info descriptor.
* Instead of generating a bridge in the trait, an abstract method is generated.
*
* 2) Specialized private members sometimes have to be switched to protected.
* In some cases, even this is not enough. Example:
*
* {{{
* class A[@specialized T](protected val d: T) {
* def foo(that: A[T]) = that.d
* }
* }}}
*
* Specialization will generate a specialized class and a specialized method:
*
* {{{
* class A$mcI$sp(protected val d: Int) extends A[Int] {
* def foo(that: A[Int]) = foo$mcI$sp(that)
* def foo(that: A[Int]) = that.d
* }
* }}}
*
* Above, `A$mcI$sp` cannot access `d`, so the method cannot be typechecked.
*/
abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
import global._
@ -409,10 +447,10 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
// log("producing type params: " + cloned.map(t => (t, t.tpe.bounds.hi)))
for ((orig, cln) <- syms zip cloned) {
cln.removeAnnotation(SpecializedClass)
if (env.contains(orig)) cln.setInfo(TypeBounds(cln.info.bounds.lo, AnyRefClass.tpe))
if (env.contains(orig))
cln modifyInfo (info => TypeBounds(info.bounds.lo, AnyRefClass.tpe))
}
for (sym <- cloned) sym.setInfo(sym.info.substSym(syms, cloned))
cloned
cloned map (_ substInfo (syms, cloned))
}
/** Maps AnyRef bindings from a raw environment (holding AnyRefs) into type parameters from
@ -472,7 +510,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
// log("new tparams " + newClassTParams.zip(newClassTParams map {s => (s.tpe, s.tpe.bounds.hi)}) + ", in env: " + env)
def applyContext(tpe: Type) =
subst(env, tpe).subst(survivedParams, newClassTParams map (_.tpe))
subst(env, tpe).instantiateTypeParams(survivedParams, newClassTParams map (_.tpe))
/** Return a list of specialized parents to be re-mixed in a specialized subclass.
* Assuming env = [T -> Int] and
@ -529,8 +567,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
*/
def enterMember(sym: Symbol): Symbol = {
typeEnv(sym) = fullEnv ++ typeEnv(sym) // append the full environment
sym.setInfo(sym.info.substThis(clazz, ThisType(cls)).subst(oldClassTParams, newClassTParams map (_.tpe)))
sym modifyInfo (_.substThis(clazz, cls).instantiateTypeParams(oldClassTParams, newClassTParams map (_.tpe)))
// we remove any default parameters. At this point, they have been all
// resolved by the type checker. Later on, erasure re-typechecks everything and
// chokes if it finds default parameters for specialized members, even though
@ -631,7 +668,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
setFlag (OVERRIDE | SPECIALIZED)
resetFlag (DEFERRED | CASEACCESSOR | PARAMACCESSOR | LAZY)
)
sym1 setInfo sym1.info.asSeenFrom(clazz.tpe, sym1.owner)
sym1 modifyInfo (_ asSeenFrom (clazz.tpe, sym1.owner))
}
val specVal = specializedOverload(cls, m, env)
@ -756,10 +793,10 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
typeEnv(specMember) = outerEnv ++ env
val tps1 = produceTypeParameters(tps, specMember, env)
tps1 foreach (tp => tp.setInfo(tp.info.subst(keys, vals)))
tps1 foreach (_ modifyInfo (_.instantiateTypeParams(keys, vals)))
// the cloneInfo is necessary so that method parameter symbols are cloned at the new owner
val methodType = sym.info.resultType.subst(keys ++ tps, vals ++ tps1.map(_.tpe)).cloneInfo(specMember)
val methodType = sym.info.resultType.instantiateTypeParams(keys ++ tps, vals ++ tps1.map(_.tpe)).cloneInfo(specMember)
specMember setInfo polyType(tps1, methodType)
debuglog("expanded member: " + sym + ": " + sym.info +
@ -786,9 +823,12 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
def specializeOn(tparams: List[Symbol]): List[Symbol] =
for (spec0 <- specializations(tparams)) yield {
val spec = mapAnyRefsInOrigCls(spec0, owner)
if (sym.isPrivate)
if (sym.isPrivate/* || sym.isProtected*/) {
//sym.privateWithin = sym.enclosingPackage
sym.resetFlag(PRIVATE).setFlag(PROTECTED)
log("-->d SETTING PRIVATE WITHIN TO " + sym.enclosingPackage + " for " + sym)
}
sym.resetFlag(FINAL)
val specMember = subst(outerEnv)(specializedOverload(owner, sym, spec))
typeEnv(specMember) = typeEnv(sym) ++ outerEnv ++ spec
@ -822,9 +862,9 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
specMember.name = specializedName(sym, env)
(specMember
setInfo subst(env, specMember.info.asSeenFrom(owner.thisType, sym.owner))
setFlag (SPECIALIZED)
resetFlag (DEFERRED | CASEACCESSOR | ACCESSOR | LAZY)
modifyInfo (info => subst(env, info.asSeenFrom(owner.thisType, sym.owner)))
setFlag (SPECIALIZED)
resetFlag (DEFERRED | CASEACCESSOR | ACCESSOR | LAZY)
)
}
@ -1015,12 +1055,11 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
(new FullTypeMap(keys, values))(tpe)
}
private def subst(env: TypeEnv)(decl: Symbol): Symbol = {
decl setInfo (subst(env, decl.info) match {
case MethodType(args, _) if decl.isConstructor => MethodType(args, decl.owner.tpe)
case tpe => tpe
})
}
private def subst(env: TypeEnv)(decl: Symbol): Symbol =
decl modifyInfo (info =>
if (decl.isConstructor) MethodType(subst(env, info).params, decl.owner.tpe)
else subst(env, info)
)
/** Checks if the type parameter symbol is not specialized
* and is used as type parameters when extending a class with a specialized
@ -1044,35 +1083,32 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
}
case _ => //log("nope")
}
private def unspecializableClass(tp: Type) = (
definitions.isRepeatedParamType(tp) // ???
|| tp.typeSymbol.isJavaDefined
|| tp.typeSymbol.isPackageClass
)
/** Type transformation. It is applied to all symbols, compiled or loaded.
* If it is a 'no-specialization' run, it is applied only to loaded symbols.
*/
override def transformInfo(sym: Symbol, tpe: Type): Type = {
if (settings.nospecialization.value && currentRun.compiles(sym)) tpe
else tpe match {
case PolyType(targs, ClassInfoType(base, decls, clazz))
if clazz != RepeatedParamClass
&& clazz != JavaRepeatedParamClass
&& !clazz.isJavaDefined =>
val parents = base map specializedType
debuglog("transformInfo (poly) " + clazz + " with parents1: " + parents + " ph: " + phase)
else tpe.resultType match {
case cinfo @ ClassInfoType(parents, decls, clazz) if !unspecializableClass(cinfo) =>
val tparams = tpe.typeParams
if (tparams.isEmpty)
atPhase(phase.next)(parents map (_.typeSymbol.info))
polyType(targs, ClassInfoType(
parents,
new Scope(specializeClass(clazz, typeEnv(clazz)) ++ specialOverrides(clazz)),
clazz)
)
case ClassInfoType(base, decls, clazz) if !clazz.isPackageClass && !clazz.isJavaDefined =>
atPhase(phase.next)(base map (_.typeSymbol.info))
// side effecting? parents is not used except to log.
val parents = base map specializedType
debuglog("transformInfo " + clazz + " with parents1: " + parents + " ph: " + phase)
ClassInfoType(
base map specializedType,
new Scope(specializeClass(clazz, typeEnv(clazz)) ++ specialOverrides(clazz)),
clazz
val parents1 = parents map specializedType
debuglog("transformInfo %s %s with parents1 %s ph: %s".format(
if (tparams.nonEmpty) " (poly)" else "",
clazz, parents1, phase)
)
val newScope = new Scope(specializeClass(clazz, typeEnv(clazz)) ++ specialOverrides(clazz))
// If tparams.isEmpty, this is just the ClassInfoType.
polyType(tparams, ClassInfoType(parents1, newScope, clazz))
case _ =>
tpe
}
@ -1253,9 +1289,6 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
} else None
}
def maybeTypeApply(fun: Tree, targs: List[Tree]) =
if (targs.isEmpty) fun else TypeApply(fun, targs)
curTree = tree
tree match {
case Apply(Select(New(tpt), nme.CONSTRUCTOR), args) =>
@ -1294,7 +1327,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
"residual: %s, tparams: %s, env: %s".format(residualTargs, symbol.info.typeParams, env))
)
val tree1 = maybeTypeApply(Select(qual1, specMember), residualTargs)
val tree1 = gen.mkTypeApply(Select(qual1, specMember), residualTargs)
log("rewrote " + tree + " to " + tree1)
localTyper.typedOperator(atPos(tree.pos)(tree1)) // being polymorphic, it must be a method
@ -1437,7 +1470,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
case fwd @ Forward(_) =>
log("forward: " + fwd + ", " + ddef)
val rhs1 = forwardCall(tree.pos, gen.mkAttributedRef(symbol.owner.thisType, fwd.target), vparamss)
debuglog("completed forwarder to specialized overload: " + fwd.target + ": " + rhs1)
log("-->d completed forwarder to specialized overload: " + fwd.target + ": " + rhs1)
localTyper.typed(treeCopy.DefDef(tree, mods, name, tparams, vparamss, tpt, rhs1))
case SpecializedAccessor(target) =>
@ -1506,6 +1539,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
val meth = addBody(tree, source)
val d = new Duplicator
log("-->d DUPLICATING: " + meth)
d.retyped(
localTyper.context1.asInstanceOf[d.Context],
meth,
@ -1536,7 +1570,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
// create fresh symbols for value parameters to hold the skolem types
val vparamss1 = List(for (vdef <- vparamss.head; param = vdef.symbol) yield {
ValDef(param.cloneSymbol(symbol).setInfo(param.info.substSym(oldtparams, newtparams)))
ValDef(param cloneSymbol symbol substInfo (oldtparams, newtparams))
})
// replace value and type parameters of the old method with the new ones

View File

@ -133,7 +133,7 @@ abstract class TailCalls extends Transform {
label setInfo MethodType(thisParam :: method.tpe.params, method.tpe.finalResultType)
}
if (isEligible)
label setInfo label.tpe.substSym(method.tpe.typeParams, tparams)
label substInfo (method.tpe.typeParams, tparams)
}
def enclosingType = method.enclClass.typeOfThis

View File

@ -80,6 +80,12 @@ abstract class UnCurry extends InfoTransform
private val newMembers = mutable.ArrayBuffer[Tree]()
private val repeatedParams = mutable.Map[Symbol, List[ValDef]]()
@inline private def withInPattern[T](value: Boolean)(body: => T): T = {
inPattern = value
try body
finally inPattern = !value
}
private lazy val serialVersionUIDAnnotation =
AnnotationInfo(SerialVersionUIDAttr.tpe, List(Literal(Constant(0))), List())
@ -210,7 +216,7 @@ abstract class UnCurry extends InfoTransform
/* Transform a function node (x_1,...,x_n) => body of type FunctionN[T_1, .., T_N, R] to
*
* class $anon() extends Object() with FunctionN[T_1, .., T_N, R] with ScalaObject {
* class $anon() extends AbstractFunctionN[T_1, .., T_N, R] with Serializable {
* def apply(x_1: T_1, ..., x_N: T_n): R = body
* }
* new $anon()
@ -219,10 +225,14 @@ abstract class UnCurry extends InfoTransform
* body = expr match { case P_i if G_i => E_i }_i=1..n
* to:
*
* class $anon() extends Object() with PartialFunction[T, R] with ScalaObject {
* class $anon() extends AbstractPartialFunction[T, R] with Serializable {
* def apply(x: T): R = (expr: @unchecked) match {
* { case P_i if G_i => E_i }_i=1..n
* def isDefinedAt(x: T): boolean = (x: @unchecked) match {
* case P_1 if G_1 => E_1
* ...
* case P_n if G_n => true
* case _ => this.missingCase(x)
* }
* def isDefinedAtCurrent(x: T): boolean = (x: @unchecked) match {
* case P_1 if G_1 => true
* ...
* case P_n if G_n => true
@ -231,9 +241,10 @@ abstract class UnCurry extends InfoTransform
* }
* new $anon()
*
* However, if one of the patterns P_i if G_i is a default pattern, generate instead
* However, if one of the patterns P_i if G_i is a default pattern,
* drop the last default clause in tghe definition of `apply` and generate for `isDefinedAtCurrent` instead
*
* def isDefinedAt(x: T): boolean = true
* def isDefinedAtCurrent(x: T): boolean = true
*/
def transformFunction(fun: Function): Tree = {
val fun1 = deEta(fun)
@ -258,12 +269,21 @@ abstract class UnCurry extends InfoTransform
fun.vparams foreach (_.symbol.owner = applyMethod)
new ChangeOwnerTraverser(fun.symbol, applyMethod) traverse fun.body
def missingCaseCall(scrutinee: Tree): Tree = Apply(Select(This(anonClass), nme.missingCase), List(scrutinee))
def applyMethodDef() = {
val body = if (isPartial) gen.mkUncheckedMatch(fun.body) else fun.body
val body =
if (isPartial) gen.mkUncheckedMatch(gen.withDefaultCase(fun.body, missingCaseCall))
else fun.body
DefDef(Modifiers(FINAL), nme.apply, Nil, List(fun.vparams), TypeTree(restpe), body) setSymbol applyMethod
}
def isDefinedAtMethodDef() = {
val m = anonClass.newMethod(fun.pos, nme.isDefinedAt) setFlag FINAL
val isDefinedAtName = {
if (anonClass.info.member(nme._isDefinedAt) != NoSymbol) nme._isDefinedAt
else nme.isDefinedAt
}
val m = anonClass.newMethod(fun.pos, isDefinedAtName) setFlag FINAL
m setInfo MethodType(m newSyntheticValueParams formals, BooleanClass.tpe)
anonClass.info.decls enter m
val vparam = fun.vparams.head.symbol
@ -281,7 +301,8 @@ abstract class UnCurry extends InfoTransform
if (cases exists treeInfo.isDefaultCase) Literal(Constant(true))
else Match(substTree(selector.duplicate), (cases map transformCase) :+ defaultCase)
)
case Apply(Apply(TypeApply(Select(tgt, n), targs), args_scrut), args_pm) if opt.virtPatmat && (n == nme.runOrElse) => // TODO: check tgt.tpe.typeSymbol isNonBottomSubclass MatchingStrategyClass
// TODO: check tgt.tpe.typeSymbol isNonBottomSubclass MatchingStrategyClass
case Apply(Apply(TypeApply(Select(tgt, nme.runOrElse), targs), args_scrut), args_pm) if opt.virtPatmat =>
object noOne extends Transformer {
override val treeCopy = newStrictTreeCopier // must duplicate everything
val one = tgt.tpe member "caseResult".toTermName
@ -299,7 +320,11 @@ abstract class UnCurry extends InfoTransform
else if (IntClass.tpe <:< a.tpe) Literal(Constant(0))
else if (LongClass.tpe <:< a.tpe) Literal(Constant(0L))
else if (CharClass.tpe <:< a.tpe) Literal(Constant(0.toChar))
else NULL AS a.tpe // must cast, at least when a.tpe <:< NothingClass.tpe
else {
val tpA = a.tpe.normalize
if (NullClass.tpe <:< tpA) NULL
else gen.mkCast(NULL, tpA) // must cast, at least when a.tpe <:< NothingClass.tpe
}
Apply(fun.duplicate, List(zero))
case _ =>
super.transform(tree)
@ -512,9 +537,7 @@ abstract class UnCurry extends InfoTransform
}
*/
case UnApply(fn, args) =>
inPattern = false
val fn1 = transform(fn)
inPattern = true
val fn1 = withInPattern(false)(transform(fn))
val args1 = transformTrees(fn.symbol.name match {
case nme.unapply => args
case nme.unapplySeq => transformArgs(tree.pos, fn.symbol, args, analyzer.unapplyTypeListFromReturnTypeSeq(fn.tpe))
@ -542,9 +565,7 @@ abstract class UnCurry extends InfoTransform
else super.transform(tree)
case CaseDef(pat, guard, body) =>
inPattern = true
val pat1 = transform(pat)
inPattern = false
val pat1 = withInPattern(true)(transform(pat))
treeCopy.CaseDef(tree, pat1, transform(guard), transform(body))
case fun @ Function(_, _) =>

View File

@ -327,7 +327,7 @@ abstract class Duplicators extends Analyzer {
tree
case _ =>
log("default: " + tree + " - " + (if (tree.symbol ne null) tree.symbol.isLazy else ""))
log("default: " + tree)
if (tree.hasSymbol && tree.symbol != NoSymbol && (tree.symbol.owner == definitions.AnyClass)) {
tree.symbol = NoSymbol // maybe we can find a more specific member in a subclass of Any (see AnyVal members, like ==)
}

View File

@ -297,8 +297,7 @@ trait Implicits {
case _ => tp
}
def stripped(tp: Type): Type = {
val tparams = freeTypeParametersNoSkolems.collect(tp)
tp.subst(tparams, tparams map (t => WildcardType))
deriveTypeWithWildcards(freeTypeParametersNoSkolems.collect(tp))(tp)
}
def sum(xs: List[Int]) = (0 /: xs)(_ + _)
def complexity(tp: Type): Int = tp.normalize match {
@ -371,11 +370,7 @@ trait Implicits {
/** The type parameters to instantiate */
val undetParams = if (isView) List() else context.outer.undetparams
def approximate(tp: Type) =
if (undetParams.isEmpty) tp
else tp.instantiateTypeParams(undetParams, undetParams map (_ => WildcardType))
def approximate(tp: Type) = deriveTypeWithWildcards(undetParams)(tp)
val wildPt = approximate(pt)
/** Try to construct a typed tree from given implicit info with given
@ -1086,12 +1081,10 @@ trait Implicits {
manifestFactoryCall("arrayType", args.head, findManifest(args.head))
} else if (sym.isClass) {
val classarg0 = gen.mkClassOf(tp1)
val classarg = (
if (tp.isInstanceOf[ExistentialType])
TypeApply(Select(classarg0, Any_asInstanceOf), List(TypeTree(ClassType(tp))))
else
classarg0
)
val classarg = tp match {
case _: ExistentialType => gen.mkCast(classarg0, ClassType(tp))
case _ => classarg0
}
val suffix = classarg :: (args map findSubManifest)
manifestFactoryCall(
"classType", tp,
@ -1110,7 +1103,7 @@ trait Implicits {
// a manifest should have been found by normal searchImplicit
EmptyTree
}
case RefinedType(parents, decls) =>
case RefinedType(parents, decls) => // !!! not yet: if !full || decls.isEmpty =>
// refinement is not generated yet
if (hasLength(parents, 1)) findManifest(parents.head)
else if (full) manifestFactoryCall("intersectionType", tp, parents map findSubManifest: _*)
@ -1119,7 +1112,14 @@ trait Implicits {
mot(tp1.skolemizeExistential, from, to)
case _ =>
EmptyTree
}
/* !!! the following is almost right, but we have to splice nested manifest
* !!! types into this type. This requires a substantial extension of
* !!! reifiers.
val reifier = new liftcode.Reifier()
val rtree = reifier.reifyTopLevel(tp1)
manifestFactoryCall("apply", tp, rtree)
*/
}
}
mot(tp, Nil, Nil)

View File

@ -304,25 +304,29 @@ trait Infer {
)
}
else {
if(sym1.isTerm)
if (sym1.isTerm)
sym1.cookJavaRawInfo() // xform java rawtypes into existentials
var owntype = try{
pre.memberType(sym1)
} catch {
case ex: MalformedType =>
if (settings.debug.value) ex.printStackTrace
val sym2 = underlyingSymbol(sym1)
val itype = pre.memberType(sym2)
new AccessError(tree, sym, pre,
"\n because its instance type "+itype+
(if ("malformed type: "+itype.toString==ex.msg) " is malformed"
else " contains a "+ex.msg)).emit()
ErrorType
val owntype = {
try pre.memberType(sym1)
catch {
case ex: MalformedType =>
if (settings.debug.value) ex.printStackTrace
val sym2 = underlyingSymbol(sym1)
val itype = pre.memberType(sym2)
new AccessError(tree, sym, pre,
"\n because its instance type "+itype+
(if ("malformed type: "+itype.toString==ex.msg) " is malformed"
else " contains a "+ex.msg)).emit()
ErrorType
}
}
tree setSymbol sym1 setType {
pre match {
case _: SuperType => owntype map (tp => if (tp eq pre) site.symbol.thisType else tp)
case _ => owntype
}
}
if (pre.isInstanceOf[SuperType])
owntype = owntype.substSuper(pre, site.symbol.thisType)
tree setSymbol sym1 setType owntype
}
}
@ -649,7 +653,8 @@ trait Infer {
targ.baseType(SeqClass)
else if (targ.typeSymbol == JavaRepeatedParamClass)
targ.baseType(ArrayClass)
else if (targ.typeSymbol.isModuleClass || (opt.experimental && tvar.constr.avoidWiden))
// checks opt.virtPatmat directly so one need not run under -Xexperimental to use virtpatmat
else if (targ.typeSymbol.isModuleClass || ((opt.experimental || opt.virtPatmat) && tvar.constr.avoidWiden))
targ // this infers Foo.type instead of "object Foo" (see also widenIfNecessary)
else
targ.widen
@ -904,8 +909,7 @@ trait Infer {
case NullaryMethodType(restpe) => // strip nullary method type, which used to be done by the polytype case below
isApplicable(undetparams, restpe, argtpes0, pt)
case PolyType(tparams, restpe) =>
val tparams1 = cloneSymbols(tparams)
isApplicable(tparams1 ::: undetparams, restpe.substSym(tparams, tparams1), argtpes0, pt)
createFromClonedSymbols(tparams, restpe)((tps1, restpe1) => isApplicable(tps1 ::: undetparams, restpe1, argtpes0, pt))
case ErrorType =>
true
case _ =>
@ -1277,7 +1281,7 @@ trait Infer {
case Nil => Nil
case xs =>
// #3890
val xs1 = treeSubst.typeSubst mapOver xs
val xs1 = treeSubst.typeMap mapOver xs
if (xs ne xs1)
new TreeSymSubstTraverser(xs, xs1) traverseTrees fn :: args

View File

@ -74,7 +74,7 @@ trait MethodSynthesis {
def finishGetterSetter(typer: Typer, stat: Tree): List[Tree] = stat match {
case vd @ ValDef(mods, name, tpt, rhs) if !noFinishGetterSetter(vd) =>
// If we don't save the annotations, they seem to wander off.
val annotations = stat.symbol.annotations
val annotations = stat.symbol.initialize.annotations
val trees = (
allValDefDerived(vd)
map (acc => atPos(vd.pos.focus)(acc derive annotations))

View File

@ -130,9 +130,8 @@ trait Namers extends MethodSynthesis {
)
def setPrivateWithin[Sym <: Symbol](tree: Tree, sym: Sym, mods: Modifiers): Sym = {
if (!sym.isPrivateLocal && mods.hasAccessBoundary)
sym.privateWithin = typer.qualifyingClass(tree, mods.privateWithin, true)
sym
if (sym.isPrivateLocal || !mods.hasAccessBoundary) sym
else sym setPrivateWithin typer.qualifyingClass(tree, mods.privateWithin, true)
}
def setPrivateWithin(tree: MemberDef, sym: Symbol): Symbol =
setPrivateWithin(tree, sym, tree.mods)
@ -1190,14 +1189,15 @@ trait Namers extends MethodSynthesis {
// parse the annotations only once.
if (!annotated.isInitialized) tree match {
case defn: MemberDef =>
val ainfos = defn.mods.annotations filter { _ != null } map { ann =>
val ainfos = defn.mods.annotations filterNot (_ eq null) map { ann =>
// need to be lazy, #1782
LazyAnnotationInfo(() => typer.typedAnnotation(ann))
AnnotationInfo lazily (typer typedAnnotation ann)
}
if (ainfos.nonEmpty) {
annotated setAnnotations ainfos
if (annotated.isTypeSkolem)
annotated.deSkolemize setAnnotations ainfos
}
if (!ainfos.isEmpty)
annotated.setRawAnnotations(ainfos)
if (annotated.isTypeSkolem)
annotated.deSkolemize.setRawAnnotations(ainfos)
case _ =>
}
}

View File

@ -364,7 +364,8 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
overrideError("cannot be used here - classes can only override abstract types");
} else if (other.isFinal) { // (1.2)
overrideError("cannot override final member");
} else if (!other.isDeferred && !member.isAnyOverride) {
// synthetic exclusion needed for (at least) default getters.
} else if (!other.isDeferred && !member.isAnyOverride && !member.isSynthetic) {
overrideError("needs `override' modifier");
} else if (other.isAbstractOverride && other.isIncompleteIn(clazz) && !member.isAbstractOverride) {
overrideError("needs `abstract override' modifiers")
@ -1561,15 +1562,12 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
}
val existentialParams = new ListBuffer[Symbol]
doTypeTraversal(tree) { // check all bounds, except those that are
// existential type parameters
doTypeTraversal(tree) { // check all bounds, except those that are existential type parameters
case ExistentialType(tparams, tpe) =>
existentialParams ++= tparams
case t: TypeRef =>
val exparams = existentialParams.toList
val wildcards = exparams map (_ => WildcardType)
checkTypeRef(t.subst(exparams, wildcards), tree.pos)
case _ =>
checkTypeRef(deriveTypeWithWildcards(existentialParams.toList)(t), tree.pos)
case _ =>
}
tree

View File

@ -54,10 +54,9 @@ trait SyntheticMethods extends ast.TreeDSL {
case tp => tp
}
def makeMethodPublic(method: Symbol): Symbol = {
method.privateWithin = NoSymbol
method resetFlag AccessFlags
}
def makeMethodPublic(method: Symbol): Symbol = (
method setPrivateWithin NoSymbol resetFlag AccessFlags
)
def methodArg(method: Symbol, idx: Int): Tree = Ident(method.paramss.head(idx))
@ -283,7 +282,7 @@ trait SyntheticMethods extends ast.TreeDSL {
def equalsClassMethod: Tree = createMethod(nme.equals_, List(AnyClass.tpe), BooleanClass.tpe) { m =>
val arg0 = methodArg(m, 0)
val thatTest = gen.mkIsInstanceOf(arg0, clazzTypeToTest(clazz), true, false)
val thatCast = arg0 AS_ATTR clazz.tpe
val thatCast = gen.mkCast(arg0, clazz.tpe)
def argsBody: Tree = {
val otherName = context.unit.freshTermName(clazz.name + "$")

View File

@ -368,8 +368,8 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
val tp1 = apply(tree.tpe)
if (hiddenSymbols.isEmpty) tree setType tp1
else if (hiddenSymbols exists (_.isErroneous)) setError(tree)
else if (isFullyDefined(pt)) tree setType pt //todo: eliminate
else if (tp1.typeSymbol.isAnonymousClass) // todo: eliminate
else if (isFullyDefined(pt)) tree setType pt
else if (tp1.typeSymbol.isAnonymousClass)
check(owner, scope, pt, tree setType tp1.typeSymbol.classBound)
else if (owner == NoSymbol)
tree setType packSymbols(hiddenSymbols.reverse, tp1)
@ -999,7 +999,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
//
// val x = expr
context.unit.warning(tree.pos, "recovering from existential Skolem type error in tree \n" + tree + "\nwith type " + tree.tpe + "\n expected type = " + pt + "\n context = " + context.tree)
adapt(tree, mode, pt.subst(pt.existentialSkolems, pt.existentialSkolems map (_ => WildcardType)))
adapt(tree, mode, deriveTypeWithWildcards(pt.existentialSkolems)(pt))
} else
throw ex
}
@ -1492,15 +1492,15 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
*/
def typedValDef(vdef: ValDef): ValDef = {
// attributes(vdef)
val sym = vdef.symbol
val sym = vdef.symbol.initialize
val typer1 = constrTyperIf(sym.isParameter && sym.owner.isConstructor)
val typedMods = removeAnnotations(vdef.mods)
// complete lazy annotations
val annots = sym.annotations
var tpt1 = checkNoEscaping.privates(sym, typer1.typedType(vdef.tpt))
checkNonCyclic(vdef, tpt1)
if (sym.hasAnnotation(definitions.VolatileAttr)) {
if (!sym.isMutable)
error(vdef.pos, "values cannot be volatile")
@ -1650,7 +1650,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
silent(_.typedTypeConstructor(stringParser(repl).typ())) match {
case tpt: Tree =>
val alias = enclClass.newAliasType(useCase.pos, name.toTypeName)
val tparams = cloneSymbols(tpt.tpe.typeSymbol.typeParams, alias)
val tparams = cloneSymbolsAtOwner(tpt.tpe.typeSymbol.typeParams, alias)
alias setInfo typeFun(tparams, appliedType(tpt.tpe, tparams map (_.tpe)))
context.scope.enter(alias)
case _ =>
@ -1676,8 +1676,8 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
* @return ...
*/
def typedDefDef(ddef: DefDef): DefDef = {
val meth = ddef.symbol
val meth = ddef.symbol.initialize
reenterTypeParams(ddef.tparams)
reenterValueParams(ddef.vparamss)
@ -1753,7 +1753,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
private def typedTypeDef0(tdef: TypeDef): TypeDef = {
tdef.symbol.initialize
reenterTypeParams(tdef.tparams)
val tparams1 = tdef.tparams mapConserve {typedTypeDef(_)}
val tparams1 = tdef.tparams mapConserve typedTypeDef
val typedMods = removeAnnotations(tdef.mods)
// complete lazy annotations
val annots = tdef.symbol.annotations
@ -1851,23 +1851,23 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
def matchesVisibleMember(member: Symbol) = visibleMembers exists { vis =>
(member.name == vis.name) &&
(member.tpe <:< vis.tpe.substThis(vis.owner, ThisType(classDef.symbol)))
(member.tpe <:< vis.tpe.substThis(vis.owner, classDef.symbol))
}
// The block is an anonymous class definitions/instantiation pair
// -> members that are hidden by the type of the block are made private
( classDecls filter (member =>
val toHide = (
classDecls filter (member =>
member.isTerm
&& member.isPossibleInRefinement
&& member.isPublic
&& !matchesVisibleMember(member)
) map (member => member
resetFlag (PROTECTED | LOCAL)
setFlag (PRIVATE | SYNTHETIC_PRIVATE)
setPrivateWithin NoSymbol
)
foreach { member =>
member resetFlag (PROTECTED | LOCAL)
member setFlag (PRIVATE | SYNTHETIC_PRIVATE)
syntheticPrivates += member
member.privateWithin = NoSymbol
}
)
syntheticPrivates ++= toHide
case _ =>
}
}
@ -1913,12 +1913,8 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
if (!context.savedTypeBounds.isEmpty) {
body1.tpe = context.restoreTypeBounds(body1.tpe)
if (isFullyDefined(pt) && !(body1.tpe <:< pt)) {
body1 =
typed {
atPos(body1.pos) {
TypeApply(Select(body1, Any_asInstanceOf), List(TypeTree(pt))) // @M no need for pt.normalize here, is done in erasure
}
}
// @M no need for pt.normalize here, is done in erasure
body1 = typedPos(body1.pos)(gen.mkCast(body1, pt))
}
}
// body1 = checkNoEscaping.locals(context.scope, pt, body1)
@ -2246,6 +2242,12 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
// now fixed by using isWeaklyCompatible in exprTypeArgs
// TODO: understand why exactly -- some types were not inferred anymore (`ant clean quick.bin` failed)
// (I had expected inferMethodAlternative to pick up the slack introduced by using WildcardType here)
//
// @PP responds: I changed it to pass WildcardType instead of pt and only one line in
// trunk (excluding scalacheck, which had another) failed to compile. It was this line in
// Types: "refs = Array(Map(), Map())". I determined that inference fails if there are at
// least two invariant type parameters. See the test case I checked in to help backstop:
// pos/isApplicableSafe.scala.
isApplicableSafe(context.undetparams, followApply(pre.memberType(alt)), argtypes, pt)
}
if (sym.isOverloaded) {
@ -2489,18 +2491,18 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
if (args.length > MaxTupleArity)
error(fun.pos, "too many arguments for unapply pattern, maximum = "+MaxTupleArity)
def freshArgType(tp: Type): (Type, List[Symbol]) = tp match {
//
def freshArgType(tp: Type): (List[Symbol], Type) = tp match {
case MethodType(param :: _, _) =>
(param.tpe, Nil)
case PolyType(tparams, restype) =>
val tparams1 = cloneSymbols(tparams)
(freshArgType(restype)._1.substSym(tparams, tparams1), tparams1)
(Nil, param.tpe)
case PolyType(tparams, restpe) =>
createFromClonedSymbols(tparams, freshArgType(restpe)._2)((ps, t) => ((ps, t)))
case OverloadedType(_, _) =>
error(fun.pos, "cannot resolve overloaded unapply")
(ErrorType, Nil)
(Nil, ErrorType)
case _ =>
error(fun.pos, "an unapply method must accept a single argument.")
(ErrorType, Nil)
(Nil, ErrorType)
}
val unapp = unapplyMember(otpe)
@ -2510,20 +2512,15 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
if (!isApplicableSafe(Nil, unappType, List(pt), WildcardType)) {
//Console.println("UNAPP: need to typetest, arg.tpe = "+arg.tpe+", unappType = "+unappType)
val (unappFormal, freeVars) = freshArgType(unappType.skolemizeExistential(context.owner, tree))
val context1 = context.makeNewScope(context.tree, context.owner)
freeVars foreach context1.scope.enter
val (freeVars, unappFormal) = freshArgType(unappType.skolemizeExistential(context.owner, tree))
val unapplyContext = context.makeNewScope(context.tree, context.owner)
freeVars foreach unapplyContext.scope.enter
val typer1 = newTyper(context1)
val typer1 = newTyper(unapplyContext)
val pattp = typer1.infer.inferTypedPattern(tree.pos, unappFormal, arg.tpe)
// turn any unresolved type variables in freevars into existential skolems
val skolems = freeVars map { fv =>
val skolem = new TypeSkolem(context1.owner, fun.pos, fv.name.toTypeName, fv)
skolem.setInfo(fv.info.cloneInfo(skolem))
.setFlag(fv.flags | EXISTENTIAL).resetFlag(PARAM)
skolem
}
val skolems = freeVars map (fv => newExistentialSkolem(fv, unapplyContext.owner, fv))
arg.tpe = pattp.substSym(freeVars, skolems)
argDummy setInfo arg.tpe
}
@ -2696,11 +2693,11 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
error(arg.pos, "classfile annotation arguments have to be supplied as named arguments")
(nme.ERROR, None)
}
for (name <- names) {
if (!name.annotations.contains(AnnotationInfo(AnnotationDefaultAttr.tpe, List(), List())) &&
!name.hasDefaultFlag)
error(ann.pos, "annotation " + annType.typeSymbol.fullName + " is missing argument " + name.name)
for (sym <- names) {
// make sure the flags are up to date before erroring (jvm/t3415 fails otherwise)
sym.initialize
if (!sym.hasAnnotation(AnnotationDefaultAttr) && !sym.hasDefaultFlag)
error(ann.pos, "annotation " + annType.typeSymbol.fullName + " is missing argument " + sym.name)
}
if (hasError) annotationError
@ -2790,7 +2787,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
* also replaced, except for term symbols of an Ident tree, where
* only the type of the Ident is changed.
*/
protected def existentialTransform(rawSyms: List[Symbol], tp: Type) = {
protected def existentialTransform[T](rawSyms: List[Symbol], tp: Type)(creator: (List[Symbol], Type) => T): T = {
val typeParams: List[Symbol] = rawSyms map { sym =>
val name = sym.name match {
case x: TypeName => x
@ -2806,28 +2803,19 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
// tpeHK for when they are: "if a type constructor is expected/allowed,
// tpeHK must be called instead of tpe."
val typeParamTypes = typeParams map (_.tpeHK)
(
typeParams map (tparam => tparam setInfo tparam.info.subst(rawSyms, typeParamTypes)),
tp.subst(rawSyms, typeParamTypes)
)
def doSubst(info: Type) = info.subst(rawSyms, typeParamTypes)
creator(typeParams map (_ modifyInfo doSubst), doSubst(tp))
}
/** Compute an existential type from raw hidden symbols `syms` and type `tp`
*/
def packSymbols(hidden: List[Symbol], tp: Type): Type =
if (hidden.isEmpty) tp
else {
// Console.println("original type: "+tp)
// Console.println("hidden symbols: "+hidden)
val (tparams, tp1) = existentialTransform(hidden, tp)
// Console.println("tparams: "+tparams+", result: "+tp1)
val res = existentialAbstraction(tparams, tp1)
// Console.println("final result: "+res)
res
}
else existentialTransform(hidden, tp)(existentialAbstraction)
def isCapturedExistential(sym: Symbol) =
((sym hasFlag EXISTENTIAL) && (sym hasFlag CAPTURED)) // todo refine this
def isCapturedExistential(sym: Symbol) =
sym hasAllFlags (EXISTENTIAL | CAPTURED) // todo refine this
def packCaptured(tpe: Type): Type = {
val captured = mutable.Set[Symbol]()
@ -2925,12 +2913,9 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
def skolemizeTypeParams(tparams: List[TypeDef]): List[TypeDef] = {
class Deskolemizer extends LazyType {
override val typeParams = tparams map (_.symbol)
val typeSkolems = typeParams map (_.newTypeSkolem) map (_ setInfo this)
def substitute() = {
// Replace the symbols
(tparams, typeSkolems).zipped foreach (_.symbol = _)
tparams
}
val typeSkolems = typeParams map (_.newTypeSkolem setInfo this)
// Replace the symbols
def substitute() = (tparams, typeSkolems).zipped map (_ setSymbol _)
override def complete(sym: Symbol) {
// The info of a skolem is the skolemized info of the
// actual type parameter of the skolem
@ -2963,9 +2948,9 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
if (vd.symbol.tpe.isVolatile)
error(vd.pos, "illegal abstraction from value with volatile type "+vd.symbol.tpe)
val tpt1 = typedType(tree.tpt, mode)
val (typeParams, tpe) = existentialTransform(tree.whereClauses map (_.symbol), tpt1.tpe)
//println(tpe + ": " + tpe.getClass )
TypeTree(ExistentialType(typeParams, tpe)) setOriginal tree
existentialTransform(tree.whereClauses map (_.symbol), tpt1.tpe)((tparams, tp) =>
TypeTree(ExistentialType(tparams, tp)) setOriginal tree
)
}
// lifted out of typed1 because it's needed in typedImplicit0
@ -3053,26 +3038,24 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
if (!settings.selfInAnnots.value)
NoSymbol
else
arg1.tpe.selfsym match {
case NoSymbol =>
/* Implementation limitation: Currently this
* can cause cyclical reference errors even
* when the self symbol is not referenced at all.
* Surely at least some of these cases can be
* fixed by proper use of LazyType's. Lex tinkered
* on this but did not succeed, so is leaving
* it alone for now. Example code with the problem:
* class peer extends Annotation
* class NPE[T <: NPE[T] @peer]
*
* (Note: -Yself-in-annots must be on to see the problem)
* */
val sym =
context.owner.newLocalDummy(ann.pos)
.newValue(ann.pos, nme.self)
sym.setInfo(arg1.tpe.withoutAnnotations)
sym
case sym => sym
arg1.tpe.selfsym orElse {
/* Implementation limitation: Currently this
* can cause cyclical reference errors even
* when the self symbol is not referenced at all.
* Surely at least some of these cases can be
* fixed by proper use of LazyType's. Lex tinkered
* on this but did not succeed, so is leaving
* it alone for now. Example code with the problem:
* class peer extends Annotation
* class NPE[T <: NPE[T] @peer]
*
* (Note: -Yself-in-annots must be on to see the problem)
* */
( context.owner
newLocalDummy (ann.pos)
newValue (ann.pos, nme.self)
setInfo (arg1.tpe.withoutAnnotations)
)
}
val ainfo = typedAnnotation(ann, annotMode, selfsym)
@ -3226,7 +3209,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
val owntype = elimAnonymousClass(owntype0)
if (needAdapt) cases1 = cases1 map (adaptCase(_, owntype))
val translated = (new MatchTranslator(this)).X(treeCopy.Match(tree, selector1, cases1), owntype)
val translated = (new MatchTranslator(this)).translateMatch(treeCopy.Match(tree, selector1, cases1), owntype)
typed1(translated, mode, WildcardType) setType owntype // TODO: get rid of setType owntype -- it should all typecheck
}

View File

@ -13,6 +13,7 @@ import io.{ File, Directory, Path, Jar, AbstractFile, ClassAndJarInfo }
import scala.tools.util.StringOps.splitWhere
import Jar.isJarOrZip
import File.pathSeparator
import java.net.MalformedURLException
/** <p>
* This module provides star expansion of '-classpath' option arguments, behaves the same as
@ -110,11 +111,22 @@ object ClassPath {
case dir => dir filter (_.isClassContainer) map (x => new java.io.File(dir.file, x.name) getPath) toList
}
}
/** Expand manifest jar classpath entries: these are either urls, or paths
* relative to the location of the jar.
*/
def expandManifestPath(jarPath: String): List[URL] = {
val file = File(jarPath)
if (!file.isFile) return Nil
val baseDir = file.parent
new Jar(file).classPathElements map (elem =>
specToURL(elem) getOrElse (baseDir / elem).toURL
)
}
/** A useful name filter. */
def isTraitImplementation(name: String) = name endsWith "$class.class"
import java.net.MalformedURLException
def specToURL(spec: String): Option[URL] =
try Some(new URL(spec))
catch { case _: MalformedURLException => None }

View File

@ -11,7 +11,7 @@ import java.lang.reflect.{ Constructor, Modifier, Method }
import java.io.{ File => JFile }
import java.net.{ URLClassLoader => JURLClassLoader }
import java.net.URL
import scala.reflect.unwrapForHandler
import scala.reflect.ReflectionUtils.unwrapHandler
import ScalaClassLoader._
import scala.util.control.Exception.{ catching }
// import Exceptional.unwrap
@ -88,7 +88,7 @@ trait ScalaClassLoader extends JClassLoader {
throw new NoSuchMethodException(objectName + ".main is not static")
try asContext(method.invoke(null, Array(arguments.toArray: AnyRef): _*)) // !!! : AnyRef shouldn't be necessary
catch unwrapForHandler({ case ex => throw ex })
catch unwrapHandler({ case ex => throw ex })
}
/** A list comprised of this classloader followed by all its

View File

@ -16,7 +16,14 @@ abstract class CPSAnnotationChecker extends CPSUtils {
* Checks whether @cps annotations conform
*/
object checker extends AnnotationChecker {
private def addPlusMarker(tp: Type) = tp withAnnotation newPlusMarker()
private def addMinusMarker(tp: Type) = tp withAnnotation newMinusMarker()
private def cleanPlus(tp: Type) =
removeAttribs(tp, MarkerCPSAdaptPlus, MarkerCPSTypes)
private def cleanPlusWith(tp: Type)(newAnnots: AnnotationInfo*) =
cleanPlus(tp) withAnnotations newAnnots.toList
/** Check annotations to decide whether tpe1 <:< tpe2 */
def annotationsConform(tpe1: Type, tpe2: Type): Boolean = {
if (!cpsEnabled) return true
@ -27,78 +34,74 @@ abstract class CPSAnnotationChecker extends CPSUtils {
if (tpe1.typeSymbol eq NothingClass)
return true
val annots1 = filterAttribs(tpe1,MarkerCPSTypes)
val annots2 = filterAttribs(tpe2,MarkerCPSTypes)
val annots1 = cpsParamAnnotation(tpe1)
val annots2 = cpsParamAnnotation(tpe2)
// @plus and @minus should only occur at the left, and never together
// TODO: insert check
val adaptPlusAnnots1 = filterAttribs(tpe1,MarkerCPSAdaptPlus)
val adaptMinusAnnots1 = filterAttribs(tpe1,MarkerCPSAdaptMinus)
// @minus @cps is the same as no annotations
if (!adaptMinusAnnots1.isEmpty)
if (hasMinusMarker(tpe1))
return annots2.isEmpty
// to handle answer type modification, we must make @plus <:< @cps
if (!adaptPlusAnnots1.isEmpty && annots1.isEmpty)
if (hasPlusMarker(tpe1) && annots1.isEmpty)
return true
// @plus @cps will fall through and compare the @cps type args
// @cps parameters must match exactly
if ((annots1 corresponds annots2) { _.atp <:< _.atp })
return true
false
(annots1 corresponds annots2)(_.atp <:< _.atp)
}
/** Refine the computed least upper bound of a list of types.
* All this should do is add annotations. */
override def annotationsLub(tpe: Type, ts: List[Type]): Type = {
if (!cpsEnabled) return tpe
val annots1 = filterAttribs(tpe, MarkerCPSTypes)
val annots2 = ts flatMap (filterAttribs(_, MarkerCPSTypes))
val annots1 = cpsParamAnnotation(tpe)
val annots2 = ts flatMap cpsParamAnnotation
if (annots2.nonEmpty) {
val cpsLub = AnnotationInfo(global.lub(annots1:::annots2 map (_.atp)), Nil, Nil)
val cpsLub = newMarker(global.lub(annots1:::annots2 map (_.atp)))
val tpe1 = if (annots1.nonEmpty) removeAttribs(tpe, MarkerCPSTypes) else tpe
tpe1.withAnnotation(cpsLub)
} else tpe
}
else tpe
}
/** Refine the bounds on type parameters to the given type arguments. */
override def adaptBoundsToAnnotations(bounds: List[TypeBounds], tparams: List[Symbol], targs: List[Type]): List[TypeBounds] = {
if (!cpsEnabled) return bounds
val anyAtCPS = AnnotationInfo(appliedType(MarkerCPSTypes.tpe, List(NothingClass.tpe, AnyClass.tpe)), Nil, Nil)
val anyAtCPS = newCpsParamsMarker(NothingClass.tpe, AnyClass.tpe)
if (isFunctionType(tparams.head.owner.tpe) || tparams.head.owner == PartialFunctionClass) {
vprintln("function bound: " + tparams.head.owner.tpe + "/"+bounds+"/"+targs)
if (targs.last.hasAnnotation(MarkerCPSTypes))
if (hasCpsParamTypes(targs.last))
bounds.reverse match {
case res::b if !res.hi.hasAnnotation(MarkerCPSTypes) =>
case res::b if !hasCpsParamTypes(res.hi) =>
(TypeBounds(res.lo, res.hi.withAnnotation(anyAtCPS))::b).reverse
case _ => bounds
}
else
bounds
} else if (tparams.head.owner == ByNameParamClass) {
}
else if (tparams.head.owner == ByNameParamClass) {
vprintln("byname bound: " + tparams.head.owner.tpe + "/"+bounds+"/"+targs)
if (targs.head.hasAnnotation(MarkerCPSTypes) && !bounds.head.hi.hasAnnotation(MarkerCPSTypes))
TypeBounds(bounds.head.lo, bounds.head.hi.withAnnotation(anyAtCPS))::Nil
val TypeBounds(lo, hi) = bounds.head
if (hasCpsParamTypes(targs.head) && !hasCpsParamTypes(hi))
TypeBounds(lo, hi withAnnotation anyAtCPS) :: Nil
else bounds
} else
bounds
}
override def canAdaptAnnotations(tree: Tree, mode: Int, pt: Type): Boolean = {
if (!cpsEnabled) return false
vprintln("can adapt annotations? " + tree + " / " + tree.tpe + " / " + Integer.toHexString(mode) + " / " + pt)
val annots1 = filterAttribs(tree.tpe,MarkerCPSTypes)
val annots2 = filterAttribs(pt,MarkerCPSTypes)
val annots1 = cpsParamAnnotation(tree.tpe)
val annots2 = cpsParamAnnotation(pt)
if ((mode & global.analyzer.PATTERNmode) != 0) {
//println("can adapt pattern annotations? " + tree + " / " + tree.tpe + " / " + Integer.toHexString(mode) + " / " + pt)
@ -124,15 +127,14 @@ abstract class CPSAnnotationChecker extends CPSUtils {
}
*/
if ((mode & global.analyzer.EXPRmode) != 0) {
if ((annots1 corresponds annots2) { case (a1,a2) => a1.atp <:< a2.atp }) {
if ((annots1 corresponds annots2)(_.atp <:< _.atp)) {
vprintln("already same, can't adapt further")
return false
}
if (annots1.isEmpty && !annots2.isEmpty && ((mode & global.analyzer.BYVALmode) == 0)) {
//println("can adapt annotations? " + tree + " / " + tree.tpe + " / " + Integer.toHexString(mode) + " / " + pt)
val adapt = AnnotationInfo(MarkerCPSAdaptPlus.tpe, Nil, Nil)
if (!tree.tpe.annotations.contains(adapt)) {
if (!hasPlusMarker(tree.tpe)) {
// val base = tree.tpe <:< removeAllCPSAnnotations(pt)
// val known = global.analyzer.isFullyDefined(pt)
// println(same + "/" + base + "/" + known)
@ -144,7 +146,7 @@ abstract class CPSAnnotationChecker extends CPSUtils {
//}
}
} else if (!annots1.isEmpty && ((mode & global.analyzer.BYVALmode) != 0)) {
if (!tree.tpe.hasAnnotation(MarkerCPSAdaptMinus)) {
if (!hasMinusMarker(tree.tpe)) {
vprintln("yes we can!! (byval)")
return true
}
@ -152,19 +154,18 @@ abstract class CPSAnnotationChecker extends CPSUtils {
}
false
}
override def adaptAnnotations(tree: Tree, mode: Int, pt: Type): Tree = {
if (!cpsEnabled) return tree
vprintln("adapt annotations " + tree + " / " + tree.tpe + " / " + Integer.toHexString(mode) + " / " + pt)
val annots1 = filterAttribs(tree.tpe,MarkerCPSTypes)
val annots2 = filterAttribs(pt,MarkerCPSTypes)
val annots1 = cpsParamAnnotation(tree.tpe)
val annots2 = cpsParamAnnotation(pt)
if ((mode & global.analyzer.PATTERNmode) != 0) {
if (!annots1.isEmpty) {
return tree.setType(removeAllCPSAnnotations(tree.tpe))
return tree modifyType removeAllCPSAnnotations
}
}
@ -185,8 +186,6 @@ abstract class CPSAnnotationChecker extends CPSUtils {
// add a marker annotation that will make tree.tpe behave as pt, subtyping wise
// tree will look like having any possible annotation
//println("adapt annotations " + tree + " / " + tree.tpe + " / " + Integer.toHexString(mode) + " / " + pt)
val adapt = AnnotationInfo(MarkerCPSAdaptPlus.tpe, Nil, Nil)
//val same = annots2 forall { case AnnotationInfo(atp: TypeRef, _, _) => atp.typeArgs(0) =:= atp.typeArgs(1) }
// TBD: use same or not? see infer0.scala/infer1.scala
@ -196,9 +195,9 @@ abstract class CPSAnnotationChecker extends CPSUtils {
//val known = global.analyzer.isFullyDefined(pt)
if (/*same &&*/ !tree.tpe.annotations.contains(adapt)) {
if (/*same &&*/ !hasPlusMarker(tree.tpe)) {
//if (known)
return tree.setType(tree.tpe.withAnnotations(adapt::annots2)) // needed for #1807
return tree modifyType (_ withAnnotations newPlusMarker() :: annots2) // needed for #1807
//else
// return tree.setType(tree.tpe.withAnnotations(adapt::Nil))
}
@ -206,16 +205,14 @@ abstract class CPSAnnotationChecker extends CPSUtils {
} else if (!annots1.isEmpty && ((mode & global.analyzer.BYVALmode) != 0)) { // dropping annotation
// add a marker annotation that will make tree.tpe behave as pt, subtyping wise
// tree will look like having no annotation
if (!tree.tpe.hasAnnotation(MarkerCPSAdaptMinus)) {
val adapt = AnnotationInfo(MarkerCPSAdaptMinus.tpe, Nil, Nil)
return tree.setType(tree.tpe.withAnnotations(adapt::Nil))
if (!hasMinusMarker(tree.tpe)) {
return tree modifyType addMinusMarker
}
}
}
tree
}
def updateAttributesFromChildren(tpe: Type, childAnnots: List[AnnotationInfo], byName: List[Tree]): Type = {
tpe match {
// Would need to push annots into each alternative of overloaded type
@ -226,7 +223,7 @@ abstract class CPSAnnotationChecker extends CPSUtils {
OverloadedType(pre, alts.map((sym: Symbol) => updateAttributes(pre.memberType(sym), annots)))
*/
case _ =>
assert(childAnnots forall (_.atp.typeSymbol == MarkerCPSTypes), childAnnots)
assert(childAnnots forall (_ matches MarkerCPSTypes), childAnnots)
/*
[] + [] = []
plus + [] = plus
@ -243,56 +240,50 @@ abstract class CPSAnnotationChecker extends CPSUtils {
synth cps + cps = synth cps! <- unify
*/
val plus = tpe.hasAnnotation(MarkerCPSAdaptPlus) || (tpe.hasAnnotation(MarkerCPSTypes) &&
byName.nonEmpty && byName.forall(_.tpe.hasAnnotation(MarkerCPSAdaptPlus)))
val plus = hasPlusMarker(tpe) || (
hasCpsParamTypes(tpe)
&& byName.nonEmpty
&& (byName forall (t => hasPlusMarker(t.tpe)))
)
// move @plus annotations outward from by-name children
if (childAnnots.isEmpty) {
if (childAnnots.isEmpty) return {
if (plus) { // @plus or @plus @cps
for (t <- byName) {
//println("removeAnnotation " + t + " / " + t.tpe)
t.setType(removeAttribs(t.tpe, MarkerCPSAdaptPlus, MarkerCPSTypes))
}
return tpe.withAnnotation(AnnotationInfo(MarkerCPSAdaptPlus.tpe, Nil, Nil))
} else
return tpe
byName foreach (_ modifyType cleanPlus)
addPlusMarker(tpe)
}
else tpe
}
val annots1 = filterAttribs(tpe, MarkerCPSTypes)
val annots1 = cpsParamAnnotation(tpe)
if (annots1.isEmpty) { // nothing or @plus
val synth = MarkerCPSSynth.tpe
val annots2 = List(linearize(childAnnots))
removeAttribs(tpe,MarkerCPSAdaptPlus).withAnnotations(AnnotationInfo(synth, Nil, Nil)::annots2)
} else {
cleanPlusWith(tpe)(newSynthMarker(), linearize(childAnnots))
}
else {
val annot1 = single(annots1)
if (plus) { // @plus @cps
val synth = AnnotationInfo(MarkerCPSSynth.tpe, Nil, Nil)
val annot2 = linearize(childAnnots)
if (!(annot2.atp <:< annot1.atp))
throw new TypeError(annot2 + " is not a subtype of " + annot1)
val res = removeAttribs(tpe, MarkerCPSAdaptPlus, MarkerCPSTypes).withAnnotations(List(synth, annot2))
for (t <- byName) {
//println("removeAnnotation " + t + " / " + t.tpe)
t.setType(removeAttribs(t.tpe, MarkerCPSAdaptPlus, MarkerCPSTypes))
if (annot2.atp <:< annot1.atp) {
try cleanPlusWith(tpe)(newSynthMarker(), annot2)
finally byName foreach (_ modifyType cleanPlus)
}
res
} else if (tpe.hasAnnotation(MarkerCPSSynth)) { // @synth @cps
val annot2 = linearize(childAnnots)
if (!(annot2.atp <:< annot1.atp))
throw new TypeError(annot2 + " is not a subtype of " + annot1)
removeAttribs(tpe, MarkerCPSTypes).withAnnotation(annot2)
} else { // @cps
removeAttribs(tpe, MarkerCPSTypes).withAnnotation(linearize(childAnnots:::annots1))
else throw new TypeError(annot2 + " is not a subtype of " + annot1)
}
else if (hasSynthMarker(tpe)) { // @synth @cps
val annot2 = linearize(childAnnots)
if (annot2.atp <:< annot1.atp)
cleanPlusWith(tpe)(annot2)
else
throw new TypeError(annot2 + " is not a subtype of " + annot1)
}
else // @cps
cleanPlusWith(tpe)(linearize(childAnnots:::annots1))
}
}
}
def transArgList(fun: Tree, args: List[Tree]): List[List[Tree]] = {
val formals = fun.tpe.paramTypes
val overshoot = args.length - formals.length
@ -329,7 +320,7 @@ abstract class CPSAnnotationChecker extends CPSUtils {
def transChildrenInOrder(tree: Tree, tpe: Type, childTrees: List[Tree], byName: List[Tree]) = {
val children = childTrees.flatMap { t =>
if (t.tpe eq null) Nil else {
val types = filterAttribs(t.tpe, MarkerCPSTypes)
val types = cpsParamAnnotation(t.tpe)
// TODO: check that it has been adapted and if so correctly
if (types.isEmpty) Nil else List(single(types))
}
@ -348,10 +339,10 @@ abstract class CPSAnnotationChecker extends CPSUtils {
override def addAnnotations(tree: Tree, tpe: Type): Type = {
if (!cpsEnabled) {
if (tpe.annotations.nonEmpty && tpe.hasAnnotation(MarkerCPSTypes))
if (hasCpsParamTypes(tpe))
global.reporter.error(tree.pos, "this code must be compiled with the Scala continuations plugin enabled")
return tpe
}
}
// if (tree.tpe.hasAnnotation(MarkerCPSAdaptPlus))
// println("addAnnotation " + tree + "/" + tpe)
@ -397,7 +388,7 @@ abstract class CPSAnnotationChecker extends CPSUtils {
// we cannot safely annotate these. so we just ignore these cases and
// clean up later in the Apply/TypeApply trees.
if (qual.tpe.hasAnnotation(MarkerCPSTypes)) {
if (hasCpsParamTypes(qual.tpe)) {
// however there is one special case:
// if it's a method without parameters, just apply it. normally done in adapt, but
// we have to do it here so we don't lose the cps information (wouldn't trigger our
@ -425,10 +416,10 @@ abstract class CPSAnnotationChecker extends CPSUtils {
case Try(block, catches, finalizer) =>
val tpe1 = transChildrenInOrder(tree, tpe, Nil, block::catches:::(catches collect { case CaseDef(_, _, body) => body }))
val annots = filterAttribs(tpe1, MarkerCPSTypes)
val annots = cpsParamAnnotation(tpe1)
if (annots.nonEmpty) {
val ann = single(annots)
val atp0::atp1::Nil = ann.atp.normalize.typeArgs
val (atp0, atp1) = annTypes(ann)
if (!(atp0 =:= atp1))
throw new TypeError("only simple cps types allowed in try/catch blocks (found: " + tpe1 + ")")
if (!finalizer.isEmpty) // no finalizers allowed. see explanation in SelectiveCPSTransform
@ -445,8 +436,8 @@ abstract class CPSAnnotationChecker extends CPSUtils {
// ValDef symbols must *not* have annotations!
if (hasAnswerTypeAnn(tree.symbol.info)) { // is it okay to modify sym here?
vprintln("removing annotation from sym " + tree.symbol + "/" + tree.symbol.tpe + "/" + tpt)
tpt.setType(removeAllCPSAnnotations(tpt.tpe))
tree.symbol.setInfo(removeAllCPSAnnotations(tree.symbol.info))
tpt modifyType removeAllCPSAnnotations
tree.symbol modifyInfo removeAllCPSAnnotations
}
tpe

View File

@ -13,100 +13,94 @@ trait CPSUtils {
val verbose: Boolean = System.getProperty("cpsVerbose", "false") == "true"
def vprintln(x: =>Any): Unit = if (verbose) println(x)
lazy val MarkerCPSSym = definitions.getClass("scala.util.continuations.cpsSym")
lazy val MarkerCPSTypes = definitions.getClass("scala.util.continuations.cpsParam")
lazy val MarkerCPSSynth = definitions.getClass("scala.util.continuations.cpsSynth")
lazy val MarkerCPSAdaptPlus = definitions.getClass("scala.util.continuations.cpsPlus")
lazy val MarkerCPSSym = definitions.getClass("scala.util.continuations.cpsSym")
lazy val MarkerCPSTypes = definitions.getClass("scala.util.continuations.cpsParam")
lazy val MarkerCPSSynth = definitions.getClass("scala.util.continuations.cpsSynth")
lazy val MarkerCPSAdaptPlus = definitions.getClass("scala.util.continuations.cpsPlus")
lazy val MarkerCPSAdaptMinus = definitions.getClass("scala.util.continuations.cpsMinus")
lazy val Context = definitions.getClass("scala.util.continuations.ControlContext")
lazy val ModCPS = definitions.getModule("scala.util.continuations")
lazy val MethShiftUnit = definitions.getMember(ModCPS, "shiftUnit")
lazy val MethShiftUnitR = definitions.getMember(ModCPS, "shiftUnitR")
lazy val MethShift = definitions.getMember(ModCPS, "shift")
lazy val MethShiftR = definitions.getMember(ModCPS, "shiftR")
lazy val MethReify = definitions.getMember(ModCPS, "reify")
lazy val MethReifyR = definitions.getMember(ModCPS, "reifyR")
lazy val MethShiftUnit = definitions.getMember(ModCPS, "shiftUnit")
lazy val MethShiftUnitR = definitions.getMember(ModCPS, "shiftUnitR")
lazy val MethShift = definitions.getMember(ModCPS, "shift")
lazy val MethShiftR = definitions.getMember(ModCPS, "shiftR")
lazy val MethReify = definitions.getMember(ModCPS, "reify")
lazy val MethReifyR = definitions.getMember(ModCPS, "reifyR")
lazy val allCPSAnnotations = List(MarkerCPSSym, MarkerCPSTypes, MarkerCPSSynth,
MarkerCPSAdaptPlus, MarkerCPSAdaptMinus)
// TODO - needed? Can these all use the same annotation info?
protected def newSynthMarker() = newMarker(MarkerCPSSynth)
protected def newPlusMarker() = newMarker(MarkerCPSAdaptPlus)
protected def newMinusMarker() = newMarker(MarkerCPSAdaptMinus)
protected def newMarker(tpe: Type): AnnotationInfo = AnnotationInfo marker tpe
protected def newMarker(sym: Symbol): AnnotationInfo = AnnotationInfo marker sym.tpe
protected def newCpsParamsMarker(tp1: Type, tp2: Type) =
newMarker(appliedType(MarkerCPSTypes.tpe, List(tp1, tp2)))
// annotation checker
def filterAttribs(tpe:Type, cls:Symbol) =
tpe.annotations.filter(_.atp.typeSymbol == cls)
protected def annTypes(ann: AnnotationInfo): (Type, Type) = {
val tp0 :: tp1 :: Nil = ann.atp.normalize.typeArgs
((tp0, tp1))
}
protected def hasMinusMarker(tpe: Type) = tpe hasAnnotation MarkerCPSAdaptMinus
protected def hasPlusMarker(tpe: Type) = tpe hasAnnotation MarkerCPSAdaptPlus
protected def hasSynthMarker(tpe: Type) = tpe hasAnnotation MarkerCPSSynth
protected def hasCpsParamTypes(tpe: Type) = tpe hasAnnotation MarkerCPSTypes
protected def cpsParamTypes(tpe: Type) = tpe getAnnotation MarkerCPSTypes map annTypes
def removeAttribs(tpe:Type, cls:Symbol*) =
tpe.withoutAnnotations.withAnnotations(tpe.annotations.filterNot(cls contains _.atp.typeSymbol))
def filterAttribs(tpe:Type, cls:Symbol) =
tpe.annotations filter (_ matches cls)
def removeAttribs(tpe: Type, classes: Symbol*) =
tpe filterAnnotations (ann => !(classes exists (ann matches _)))
def removeAllCPSAnnotations(tpe: Type) = removeAttribs(tpe, allCPSAnnotations:_*)
def cpsParamAnnotation(tpe: Type) = filterAttribs(tpe, MarkerCPSTypes)
def linearize(ann: List[AnnotationInfo]): AnnotationInfo = {
ann.reduceLeft { (a, b) =>
val atp0::atp1::Nil = a.atp.normalize.typeArgs
val btp0::btp1::Nil = b.atp.normalize.typeArgs
val (u0,v0) = (atp0, atp1)
val (u1,v1) = (btp0, btp1)
/*
val (u0,v0) = (a.atp.typeArgs(0), a.atp.typeArgs(1))
val (u1,v1) = (b.atp.typeArgs(0), b.atp.typeArgs(1))
vprintln("check lin " + a + " andThen " + b)
*/
vprintln("check lin " + a + " andThen " + b)
if (!(v1 <:< u0))
ann reduceLeft { (a, b) =>
val (u0,v0) = annTypes(a)
val (u1,v1) = annTypes(b)
// vprintln("check lin " + a + " andThen " + b)
if (v1 <:< u0)
newCpsParamsMarker(u1, v0)
else
throw new TypeError("illegal answer type modification: " + a + " andThen " + b)
// TODO: improve error message (but it is not very common)
AnnotationInfo(appliedType(MarkerCPSTypes.tpe, List(u1,v0)),Nil,Nil)
}
}
// anf transform
def getExternalAnswerTypeAnn(tp: Type) = {
tp.annotations.find(a => a.atp.typeSymbol == MarkerCPSTypes) match {
case Some(AnnotationInfo(atp, _, _)) =>
val atp0::atp1::Nil = atp.normalize.typeArgs
Some((atp0, atp1))
case None =>
if (tp.hasAnnotation(MarkerCPSAdaptPlus))
global.warning("trying to instantiate type " + tp + " to unknown cps type")
None
cpsParamTypes(tp) orElse {
if (hasPlusMarker(tp))
global.warning("trying to instantiate type " + tp + " to unknown cps type")
None
}
}
def getAnswerTypeAnn(tp: Type): Option[(Type, Type)] =
cpsParamTypes(tp) filterNot (_ => hasPlusMarker(tp))
def getAnswerTypeAnn(tp: Type) = {
tp.annotations.find(a => a.atp.typeSymbol == MarkerCPSTypes) match {
case Some(AnnotationInfo(atp, _, _)) =>
if (!tp.hasAnnotation(MarkerCPSAdaptPlus)) {//&& !tp.hasAnnotation(MarkerCPSAdaptMinus))
val atp0::atp1::Nil = atp.normalize.typeArgs
Some((atp0, atp1))
} else
None
case None => None
}
}
def hasAnswerTypeAnn(tp: Type) = {
tp.hasAnnotation(MarkerCPSTypes) && !tp.hasAnnotation(MarkerCPSAdaptPlus) /*&&
!tp.hasAnnotation(MarkerCPSAdaptMinus)*/
}
def hasSynthAnn(tp: Type) = {
tp.annotations.exists(a => a.atp.typeSymbol == MarkerCPSSynth)
}
def hasAnswerTypeAnn(tp: Type) =
hasCpsParamTypes(tp) && !hasPlusMarker(tp)
def updateSynthFlag(tree: Tree) = { // remove annotations if *we* added them (@synth present)
if (hasSynthAnn(tree.tpe)) {
if (hasSynthMarker(tree.tpe)) {
log("removing annotation from " + tree)
tree.setType(removeAllCPSAnnotations(tree.tpe))
tree modifyType removeAllCPSAnnotations
} else
tree
}
type CPSInfo = Option[(Type,Type)]
def linearize(a: CPSInfo, b: CPSInfo)(implicit unit: CompilationUnit, pos: Position): CPSInfo = {
@ -124,7 +118,4 @@ trait CPSUtils {
case _ => None
}
}
// cps transform
}
}

View File

@ -301,7 +301,7 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
log("cps type conversion (has: " + cpsA + "/" + spc + "/" + expr.tpe + ")")
log("cps type conversion (expected: " + cpsR.get + "): " + expr)
if (!expr.tpe.hasAnnotation(MarkerCPSAdaptPlus))
if (!hasPlusMarker(expr.tpe))
unit.warning(tree.pos, "expression " + tree + " is cps-transformed unexpectedly")
try {
@ -331,9 +331,9 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
} else {
// all is well
if (expr.tpe.hasAnnotation(MarkerCPSAdaptPlus)) {
if (hasPlusMarker(expr.tpe)) {
unit.warning(tree.pos, "expression " + expr + " of type " + expr.tpe + " is not expected to have a cps type")
expr.setType(removeAllCPSAnnotations(expr.tpe))
expr modifyType removeAllCPSAnnotations
}
// TODO: sanity check that types agree

View File

@ -24,6 +24,10 @@ trait PartialFunction[-A, +B] extends (A => B) {
* @return `'''true'''`, iff `x` is in the domain of this function, `'''false'''` otherwise.
*/
def isDefinedAt(x: A): Boolean
//protected def missingCase[A1 <: A, B1 >: B]: PartialFunction[A1, B1] = PartialFunction.empty
protected def missingCase(x: A): B = throw new MatchError(x)
/** Composes this partial function with a fallback partial function which
* gets applied where this partial function is not defined.
@ -37,12 +41,15 @@ trait PartialFunction[-A, +B] extends (A => B) {
*/
def orElse[A1 <: A, B1 >: B](that: PartialFunction[A1, B1]) : PartialFunction[A1, B1] =
new runtime.AbstractPartialFunction[A1, B1] {
def isDefinedAt(x: A1): Boolean =
PartialFunction.this.isDefinedAt(x) || that.isDefinedAt(x)
def apply(x: A1): B1 =
if (PartialFunction.this.isDefinedAt(x)) PartialFunction.this.apply(x)
else that.apply(x)
}
def isDefinedAt(x: A1): Boolean =
PartialFunction.this.isDefinedAt(x) || that.isDefinedAt(x)
def apply(x: A1): B1 =
if (PartialFunction.this.isDefinedAt(x)) PartialFunction.this.apply(x)
else that.apply(x)
}
def orElseFast[A1 <: A, B1 >: B](that: PartialFunction[A1, B1]) : PartialFunction[A1, B1] =
orElse(that)
/** Composes this partial function with a transformation function that
* gets applied to results of this partial function.
@ -84,11 +91,12 @@ trait PartialFunction[-A, +B] extends (A => B) {
object PartialFunction {
private[this] final val empty_pf: PartialFunction[Any, Nothing] = new runtime.AbstractPartialFunction[Any, Nothing] {
def isDefinedAt(x: Any) = false
def apply(x: Any): Nothing = sys.error("undefined")
def apply(x: Any): Nothing = throw new MatchError(x)
override def orElse[A1, B1](that: PartialFunction[A1, B1]): PartialFunction[A1, B1] = that
override def orElseFast[A1, B1](that: PartialFunction[A1, B1]): PartialFunction[A1, B1] = that
override def lift = (x: Any) => None
}
def empty[A, B] : PartialFunction[A, B] = empty_pf.asInstanceOf[PartialFunction[A, B]]
def empty[A, B] : PartialFunction[A, B] = empty_pf
/** Creates a Boolean test based on a value and a partial function.
* It behaves like a 'match' statement with an implied 'case _ => false'

View File

@ -1,10 +1,10 @@
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2010-2011, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2010-2011, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
package scala.collection
package mutable

View File

@ -1,326 +1,326 @@
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
package scala.collection.mutable
import collection.AbstractIterator
import collection.Iterator
import collection.generic._
import annotation.tailrec
/** A buffer that stores elements in an unrolled linked list.
*
* Unrolled linked lists store elements in linked fixed size
* arrays.
*
* Unrolled buffers retain locality and low memory overhead
* properties of array buffers, but offer much more efficient
* element addition, since they never reallocate and copy the
* internal array.
*
* However, they provide `O(n/m)` complexity random access,
* where `n` is the number of elements, and `m` the size of
* internal array chunks.
*
* Ideal to use when:
* - elements are added to the buffer and then all of the
* elements are traversed sequentially
* - two unrolled buffers need to be concatenated (see `concat`)
*
* Better than singly linked lists for random access, but
* should still be avoided for such a purpose.
*
* @define coll unrolled buffer
* @define Coll UnrolledBuffer
* @author Aleksandar Prokopec
*
*/
@SerialVersionUID(1L)
class UnrolledBuffer[T](implicit val manifest: ClassManifest[T])
extends collection.mutable.AbstractBuffer[T]
with collection.mutable.Buffer[T]
with collection.mutable.BufferLike[T, UnrolledBuffer[T]]
with GenericClassManifestTraversableTemplate[T, UnrolledBuffer]
with collection.mutable.Builder[T, UnrolledBuffer[T]]
with Serializable
{
import UnrolledBuffer.Unrolled
@transient private var headptr = newUnrolled
@transient private var lastptr = headptr
@transient private var sz = 0
private[collection] def headPtr = headptr
private[collection] def headPtr_=(head: Unrolled[T]) = headptr = head
private[collection] def lastPtr = lastptr
private[collection] def lastPtr_=(last: Unrolled[T]) = lastptr = last
private[collection] def size_=(s: Int) = sz = s
protected[this] override def newBuilder = new UnrolledBuffer[T]
protected def newUnrolled = new Unrolled[T](this)
private[collection] def calcNextLength(sz: Int) = sz
def classManifestCompanion = UnrolledBuffer
/** Concatenates the targer unrolled buffer to this unrolled buffer.
*
* The specified buffer `that` is cleared after this operation. This is
* an O(1) operation.
*
* @param that the unrolled buffer whose elements are added to this buffer
*/
def concat(that: UnrolledBuffer[T]) = {
// bind the two together
if (!lastptr.bind(that.headptr)) lastptr = that.lastPtr
// update size
sz += that.sz
// `that` is no longer usable, so clear it
// here we rely on the fact that `clear` allocates
// new nodes instead of modifying the previous ones
that.clear
// return a reference to this
this
}
def +=(elem: T) = {
lastptr = lastptr.append(elem)
sz += 1
this
}
def clear() {
headptr = newUnrolled
lastptr = headptr
sz = 0
}
def iterator: Iterator[T] = new AbstractIterator[T] {
var pos: Int = -1
var node: Unrolled[T] = headptr
scan()
private def scan() {
pos += 1
while (pos >= node.size) {
pos = 0
node = node.next
if (node eq null) return
}
}
def hasNext = node ne null
def next = if (hasNext) {
val r = node.array(pos)
scan()
r
} else Iterator.empty.next
}
// this should be faster than the iterator
override def foreach[U](f: T => U) = headptr.foreach(f)
def result = this
def length = sz
def apply(idx: Int) =
if (idx >= 0 && idx < sz) headptr(idx)
else throw new IndexOutOfBoundsException(idx.toString)
def update(idx: Int, newelem: T) =
if (idx >= 0 && idx < sz) headptr(idx) = newelem
else throw new IndexOutOfBoundsException(idx.toString)
def remove(idx: Int) =
if (idx >= 0 && idx < sz) {
sz -= 1
headptr.remove(idx, this)
} else throw new IndexOutOfBoundsException(idx.toString)
def +=:(elem: T) = {
headptr = headptr prepend elem
sz += 1
this
}
def insertAll(idx: Int, elems: collection.Traversable[T]) =
if (idx >= 0 && idx <= sz) {
headptr.insertAll(idx, elems, this)
sz += elems.size
} else throw new IndexOutOfBoundsException(idx.toString)
private def writeObject(out: java.io.ObjectOutputStream) {
out.defaultWriteObject
out writeInt sz
for (elem <- this) out writeObject elem
}
private def readObject(in: java.io.ObjectInputStream) {
in.defaultReadObject
val num = in.readInt
headPtr = newUnrolled
lastPtr = headPtr
sz = 0
var i = 0
while (i < num) {
this += in.readObject.asInstanceOf[T]
i += 1
}
}
override def stringPrefix = "UnrolledBuffer"
}
object UnrolledBuffer extends ClassManifestTraversableFactory[UnrolledBuffer] {
/** $genericCanBuildFromInfo */
implicit def canBuildFrom[T](implicit m: ClassManifest[T]): CanBuildFrom[Coll, T, UnrolledBuffer[T]] =
new GenericCanBuildFrom[T]
def newBuilder[T](implicit m: ClassManifest[T]): Builder[T, UnrolledBuffer[T]] = new UnrolledBuffer[T]
val waterline = 50
val waterlineDelim = 100
private[collection] val unrolledlength = 32
/** Unrolled buffer node.
*/
class Unrolled[T: ClassManifest] private[collection] (var size: Int, var array: Array[T], var next: Unrolled[T], val buff: UnrolledBuffer[T] = null) {
private[collection] def this() = this(0, new Array[T](unrolledlength), null, null)
private[collection] def this(b: UnrolledBuffer[T]) = this(0, new Array[T](unrolledlength), null, b)
private def nextlength = if (buff eq null) unrolledlength else buff.calcNextLength(array.length)
// adds and returns itself or the new unrolled if full
@tailrec final def append(elem: T): Unrolled[T] = if (size < array.length) {
array(size) = elem
size += 1
this
} else {
next = new Unrolled[T](0, new Array[T](nextlength), null, buff)
next append elem
}
def foreach[U](f: T => U) {
var unrolled = this
var i = 0
while (unrolled ne null) {
val chunkarr = unrolled.array
val chunksz = unrolled.size
while (i < chunksz) {
val elem = chunkarr(i)
f(elem)
i += 1
}
i = 0
unrolled = unrolled.next
}
}
@tailrec final def apply(idx: Int): T =
if (idx < size) array(idx) else next.apply(idx - size)
@tailrec final def update(idx: Int, newelem: T): Unit =
if (idx < size) array(idx) = newelem else next.update(idx - size, newelem)
@tailrec final def locate(idx: Int): Unrolled[T] =
if (idx < size) this else next.locate(idx - size)
def prepend(elem: T) = if (size < array.length) {
// shift the elements of the array right
// then insert the element
shiftright()
array(0) = elem
size += 1
this
} else {
// allocate a new node and store element
// then make it point to this
val newhead = new Unrolled[T](buff)
newhead append elem
newhead.next = this
newhead
}
// shifts right assuming enough space
private def shiftright() {
var i = size - 1
while (i >= 0) {
array(i + 1) = array(i)
i -= 1
}
}
// returns pointer to new last if changed
@tailrec final def remove(idx: Int, buffer: UnrolledBuffer[T]): T =
if (idx < size) {
// remove the element
// then try to merge with the next bucket
val r = array(idx)
shiftleft(idx)
size -= 1
if (tryMergeWithNext()) buffer.lastPtr = this
r
} else next.remove(idx - size, buffer)
// shifts left elements after `leftb` (overwrites `leftb`)
private def shiftleft(leftb: Int) {
var i = leftb
while (i < (size - 1)) {
array(i) = array(i + 1)
i += 1
}
nullout(i, i + 1)
}
protected def tryMergeWithNext() = if (next != null && (size + next.size) < (array.length * waterline / waterlineDelim)) {
// copy the next array, then discard the next node
Array.copy(next.array, 0, array, size, next.size)
size = size + next.size
next = next.next
if (next eq null) true else false // checks if last node was thrown out
} else false
@tailrec final def insertAll(idx: Int, t: collection.Traversable[T], buffer: UnrolledBuffer[T]): Unit = if (idx < size) {
// divide this node at the appropriate position and insert all into head
// update new next
val newnextnode = new Unrolled[T](0, new Array(array.length), null, buff)
Array.copy(array, idx, newnextnode.array, 0, size - idx)
newnextnode.size = size - idx
newnextnode.next = next
// update this
nullout(idx, size)
size = idx
next = null
// insert everything from iterable to this
var curr = this
for (elem <- t) curr = curr append elem
curr.next = newnextnode
// try to merge the last node of this with the newnextnode
if (curr.tryMergeWithNext()) buffer.lastPtr = curr
} else insertAll(idx - size, t, buffer)
private def nullout(from: Int, until: Int) {
var idx = from
while (idx < until) {
array(idx) = null.asInstanceOf[T] // TODO find a way to assign a default here!!
idx += 1
}
}
// assumes this is the last node
// `thathead` and `thatlast` are head and last node
// of the other unrolled list, respectively
def bind(thathead: Unrolled[T]) = {
assert(next eq null)
next = thathead
tryMergeWithNext()
}
override def toString = array.take(size).mkString("Unrolled[" + array.length + "](", ", ", ")") + " -> " + (if (next ne null) next.toString else "")
}
}
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
package scala.collection.mutable
import collection.AbstractIterator
import collection.Iterator
import collection.generic._
import annotation.tailrec
/** A buffer that stores elements in an unrolled linked list.
*
* Unrolled linked lists store elements in linked fixed size
* arrays.
*
* Unrolled buffers retain locality and low memory overhead
* properties of array buffers, but offer much more efficient
* element addition, since they never reallocate and copy the
* internal array.
*
* However, they provide `O(n/m)` complexity random access,
* where `n` is the number of elements, and `m` the size of
* internal array chunks.
*
* Ideal to use when:
* - elements are added to the buffer and then all of the
* elements are traversed sequentially
* - two unrolled buffers need to be concatenated (see `concat`)
*
* Better than singly linked lists for random access, but
* should still be avoided for such a purpose.
*
* @define coll unrolled buffer
* @define Coll UnrolledBuffer
* @author Aleksandar Prokopec
*
*/
@SerialVersionUID(1L)
class UnrolledBuffer[T](implicit val manifest: ClassManifest[T])
extends collection.mutable.AbstractBuffer[T]
with collection.mutable.Buffer[T]
with collection.mutable.BufferLike[T, UnrolledBuffer[T]]
with GenericClassManifestTraversableTemplate[T, UnrolledBuffer]
with collection.mutable.Builder[T, UnrolledBuffer[T]]
with Serializable
{
import UnrolledBuffer.Unrolled
@transient private var headptr = newUnrolled
@transient private var lastptr = headptr
@transient private var sz = 0
private[collection] def headPtr = headptr
private[collection] def headPtr_=(head: Unrolled[T]) = headptr = head
private[collection] def lastPtr = lastptr
private[collection] def lastPtr_=(last: Unrolled[T]) = lastptr = last
private[collection] def size_=(s: Int) = sz = s
protected[this] override def newBuilder = new UnrolledBuffer[T]
protected def newUnrolled = new Unrolled[T](this)
private[collection] def calcNextLength(sz: Int) = sz
def classManifestCompanion = UnrolledBuffer
/** Concatenates the targer unrolled buffer to this unrolled buffer.
*
* The specified buffer `that` is cleared after this operation. This is
* an O(1) operation.
*
* @param that the unrolled buffer whose elements are added to this buffer
*/
def concat(that: UnrolledBuffer[T]) = {
// bind the two together
if (!lastptr.bind(that.headptr)) lastptr = that.lastPtr
// update size
sz += that.sz
// `that` is no longer usable, so clear it
// here we rely on the fact that `clear` allocates
// new nodes instead of modifying the previous ones
that.clear
// return a reference to this
this
}
def +=(elem: T) = {
lastptr = lastptr.append(elem)
sz += 1
this
}
def clear() {
headptr = newUnrolled
lastptr = headptr
sz = 0
}
def iterator: Iterator[T] = new AbstractIterator[T] {
var pos: Int = -1
var node: Unrolled[T] = headptr
scan()
private def scan() {
pos += 1
while (pos >= node.size) {
pos = 0
node = node.next
if (node eq null) return
}
}
def hasNext = node ne null
def next = if (hasNext) {
val r = node.array(pos)
scan()
r
} else Iterator.empty.next
}
// this should be faster than the iterator
override def foreach[U](f: T => U) = headptr.foreach(f)
def result = this
def length = sz
def apply(idx: Int) =
if (idx >= 0 && idx < sz) headptr(idx)
else throw new IndexOutOfBoundsException(idx.toString)
def update(idx: Int, newelem: T) =
if (idx >= 0 && idx < sz) headptr(idx) = newelem
else throw new IndexOutOfBoundsException(idx.toString)
def remove(idx: Int) =
if (idx >= 0 && idx < sz) {
sz -= 1
headptr.remove(idx, this)
} else throw new IndexOutOfBoundsException(idx.toString)
def +=:(elem: T) = {
headptr = headptr prepend elem
sz += 1
this
}
def insertAll(idx: Int, elems: collection.Traversable[T]) =
if (idx >= 0 && idx <= sz) {
headptr.insertAll(idx, elems, this)
sz += elems.size
} else throw new IndexOutOfBoundsException(idx.toString)
private def writeObject(out: java.io.ObjectOutputStream) {
out.defaultWriteObject
out writeInt sz
for (elem <- this) out writeObject elem
}
private def readObject(in: java.io.ObjectInputStream) {
in.defaultReadObject
val num = in.readInt
headPtr = newUnrolled
lastPtr = headPtr
sz = 0
var i = 0
while (i < num) {
this += in.readObject.asInstanceOf[T]
i += 1
}
}
override def stringPrefix = "UnrolledBuffer"
}
object UnrolledBuffer extends ClassManifestTraversableFactory[UnrolledBuffer] {
/** $genericCanBuildFromInfo */
implicit def canBuildFrom[T](implicit m: ClassManifest[T]): CanBuildFrom[Coll, T, UnrolledBuffer[T]] =
new GenericCanBuildFrom[T]
def newBuilder[T](implicit m: ClassManifest[T]): Builder[T, UnrolledBuffer[T]] = new UnrolledBuffer[T]
val waterline = 50
val waterlineDelim = 100
private[collection] val unrolledlength = 32
/** Unrolled buffer node.
*/
class Unrolled[T: ClassManifest] private[collection] (var size: Int, var array: Array[T], var next: Unrolled[T], val buff: UnrolledBuffer[T] = null) {
private[collection] def this() = this(0, new Array[T](unrolledlength), null, null)
private[collection] def this(b: UnrolledBuffer[T]) = this(0, new Array[T](unrolledlength), null, b)
private def nextlength = if (buff eq null) unrolledlength else buff.calcNextLength(array.length)
// adds and returns itself or the new unrolled if full
@tailrec final def append(elem: T): Unrolled[T] = if (size < array.length) {
array(size) = elem
size += 1
this
} else {
next = new Unrolled[T](0, new Array[T](nextlength), null, buff)
next append elem
}
def foreach[U](f: T => U) {
var unrolled = this
var i = 0
while (unrolled ne null) {
val chunkarr = unrolled.array
val chunksz = unrolled.size
while (i < chunksz) {
val elem = chunkarr(i)
f(elem)
i += 1
}
i = 0
unrolled = unrolled.next
}
}
@tailrec final def apply(idx: Int): T =
if (idx < size) array(idx) else next.apply(idx - size)
@tailrec final def update(idx: Int, newelem: T): Unit =
if (idx < size) array(idx) = newelem else next.update(idx - size, newelem)
@tailrec final def locate(idx: Int): Unrolled[T] =
if (idx < size) this else next.locate(idx - size)
def prepend(elem: T) = if (size < array.length) {
// shift the elements of the array right
// then insert the element
shiftright()
array(0) = elem
size += 1
this
} else {
// allocate a new node and store element
// then make it point to this
val newhead = new Unrolled[T](buff)
newhead append elem
newhead.next = this
newhead
}
// shifts right assuming enough space
private def shiftright() {
var i = size - 1
while (i >= 0) {
array(i + 1) = array(i)
i -= 1
}
}
// returns pointer to new last if changed
@tailrec final def remove(idx: Int, buffer: UnrolledBuffer[T]): T =
if (idx < size) {
// remove the element
// then try to merge with the next bucket
val r = array(idx)
shiftleft(idx)
size -= 1
if (tryMergeWithNext()) buffer.lastPtr = this
r
} else next.remove(idx - size, buffer)
// shifts left elements after `leftb` (overwrites `leftb`)
private def shiftleft(leftb: Int) {
var i = leftb
while (i < (size - 1)) {
array(i) = array(i + 1)
i += 1
}
nullout(i, i + 1)
}
protected def tryMergeWithNext() = if (next != null && (size + next.size) < (array.length * waterline / waterlineDelim)) {
// copy the next array, then discard the next node
Array.copy(next.array, 0, array, size, next.size)
size = size + next.size
next = next.next
if (next eq null) true else false // checks if last node was thrown out
} else false
@tailrec final def insertAll(idx: Int, t: collection.Traversable[T], buffer: UnrolledBuffer[T]): Unit = if (idx < size) {
// divide this node at the appropriate position and insert all into head
// update new next
val newnextnode = new Unrolled[T](0, new Array(array.length), null, buff)
Array.copy(array, idx, newnextnode.array, 0, size - idx)
newnextnode.size = size - idx
newnextnode.next = next
// update this
nullout(idx, size)
size = idx
next = null
// insert everything from iterable to this
var curr = this
for (elem <- t) curr = curr append elem
curr.next = newnextnode
// try to merge the last node of this with the newnextnode
if (curr.tryMergeWithNext()) buffer.lastPtr = curr
} else insertAll(idx - size, t, buffer)
private def nullout(from: Int, until: Int) {
var idx = from
while (idx < until) {
array(idx) = null.asInstanceOf[T] // TODO find a way to assign a default here!!
idx += 1
}
}
// assumes this is the last node
// `thathead` and `thatlast` are head and last node
// of the other unrolled list, respectively
def bind(thathead: Unrolled[T]) = {
assert(next eq null)
next = thathead
tryMergeWithNext()
}
override def toString = array.take(size).mkString("Unrolled[" + array.length + "](", ", ", ")") + " -> " + (if (next ne null) next.toString else "")
}
}

View File

@ -42,14 +42,14 @@ package object parallel {
private[parallel] def getTaskSupport: TaskSupport =
if (util.Properties.isJavaAtLeast("1.6")) {
val vendor = util.Properties.javaVmVendor
if ((vendor contains "Sun") || (vendor contains "Apple")) new ForkJoinTaskSupport
if ((vendor contains "Oracle") || (vendor contains "Sun") || (vendor contains "Apple")) new ForkJoinTaskSupport
else new ThreadPoolTaskSupport
} else new ThreadPoolTaskSupport
val tasksupport = getTaskSupport
/* implicit conversions */
implicit def factory2ops[From, Elem, To](bf: CanBuildFrom[From, Elem, To]) = new FactoryOps[From, Elem, To] {
def isParallel = bf.isInstanceOf[Parallel]
def asParallel = bf.asInstanceOf[CanCombineFrom[From, Elem, To]]

View File

@ -13,7 +13,7 @@ package scala.reflect
/** This type is required by the compiler and <b>should not be used in client code</b>. */
class Code[T: Manifest](val tree: scala.reflect.mirror.Tree) {
val manifest = implicitly[Manifest[T]]
override def toString = "Code(manifest = " + manifest + ")"
override def toString = "Code(tree = "+tree+", manifest = "+manifest+")"
}
/** This type is required by the compiler and <b>should not be used in client code</b>. */

View File

@ -202,7 +202,7 @@ object Manifest {
private class SingletonTypeManifest[T <: AnyRef](value: AnyRef) extends Manifest[T] {
lazy val erasure = value.getClass
override lazy val tpe = mirror.SingleType(mirror.NoPrefix, InstanceRefSymbol(value))
override lazy val tpe = mirror.SingleType(mirror.NoPrefix, InstanceRefSymbol(value)) // todo: change to freevar
override lazy val toString = value.toString + ".type"
}
@ -284,4 +284,24 @@ object Manifest {
override lazy val tpe = mirror.RefinedType((parents map (_.tpe)).toList, newScope)
override def toString = parents.mkString(" with ")
}
/** A generic manifest factory from a reflect.Type. Except where
* mandated by performance considerations, we should replace most
* other manifest factories by this one. There's just one thing
* that needs to be done first: A Manifest's type can refer
* to type variables that are controlled by manifests. In that
* case the reified type needs to contain the type passed in the manifest
* instead of the reference to the manifest. Note that splicing manifests
* into manfifests is completely analogous to splicing code blocks into
* code blocks. Manifest[T] and Code[T] are really the same thing, only one
* works for types, the other for trees.
* Another complication is that once we generate manifests from types, we really
* should have reflection as a standard component shipped with the standard library,
* instead of in scala-compiler.jar.
*/
def apply[T](_tpe: mirror.Type): Manifest[T] = new Manifest[T] {
override lazy val tpe = _tpe
override def erasure = mirror.typeToClass(_tpe.erasedType)
override def toString = _tpe.toString
}
}

View File

@ -1,113 +0,0 @@
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
package scala.reflect
/** This type is required by the compiler and <b>should not be used in client code</b>. */
object Print extends Function1[Any, String] {
def apply(any: Any): String = any match {
case x: Code[_] =>
apply(x.tree)
case x: Tree =>
apply(x)
case x: Symbol =>
apply(x)
case x: Type =>
apply(x)
case _ =>
"UnknownAny"
}
def apply(tree: Tree): String = tree match {
case reflect.Ident(sym) =>
Print(sym)
case reflect.Select(qual, sym) =>
Print(qual) + "." + Print(sym)
case reflect.Literal(value) => value match {
case s:String => "\"" + s + "\""
case _ => value.toString
}
case reflect.Apply(fun, args) =>
Print(fun) + args.map(Print).mkString("(", ", ", ")")
case reflect.TypeApply(fun, args) =>
Print(fun) + args.map(Print).mkString("[", ", ", "]")
case reflect.Function(params, body) =>
params.map(Print).mkString("(", ", ", ")") + " => " + Print(body)
case reflect.This(sym) =>
Print(sym)+".this"
case reflect.Block(stats, expr) =>
(stats ::: List(expr)).map(Print).mkString("{\n", ";\n", "\n}")
case reflect.New(tpt) =>
"new " + Print(tpt)
case reflect.If(condition, trueCase, falseCase) =>
"if (" + Print(condition) + ") " + Print(trueCase) + " else " + Print(falseCase)
case reflect.Assign(destination: Tree, source: Tree) =>
Print(destination) + " = " + Print(source)
case reflect.Target(sym, body) =>
"target " + Print(sym) + " {\n" + Print(body) + "\n}"
case reflect.Goto(target) =>
"goto " + Print(target)
case _ =>
"???"
}
def apply(symbol: Symbol): String = symbol match {
case reflect.Class(name) =>
name.substring(name.lastIndexOf('.') + 1)
case reflect.Method(name, datatype) =>
name.substring(name.lastIndexOf('.') +1)
case reflect.Field(name, datatype) =>
name.substring(name.lastIndexOf('.') + 1)
case reflect.TypeField(name, datatype) =>
name.substring(name.lastIndexOf('.') + 1)
case reflect.LocalValue(owner, name, datatype) =>
name.substring(name.lastIndexOf('.') + 1)
case reflect.LocalMethod(owner, name, datatype) =>
name.substring(name.lastIndexOf('.') + 1)
case reflect.NoSymbol =>
"NoSymbol"
case reflect.RootSymbol =>
"RootSymbol"
case reflect.LabelSymbol(name) =>
name
case _ =>
"???"
}
def apply(datatype: Type): String = datatype match {
case reflect.NoPrefix =>
"NoPrefix"
case reflect.NoType =>
"NoType"
case reflect.NamedType(name) =>
"(named: " + name + ")"
case reflect.PrefixedType(prefix, symbol) =>
"(" + Print(prefix) + "." + Print(symbol) + ")"
case reflect.SingleType(prefix, symbol) =>
"(" + Print(prefix) + "." + Print(symbol) + ")"
case reflect.ThisType(clazz) =>
"(" + Print(clazz) + ".this.type)"
case reflect.AppliedType(datatype, args) =>
Print(datatype) + args.map(Print).mkString("[", ", ", "]")
case reflect.TypeBounds(lo, hi) =>
"[" + Print(lo) + " ... " + Print(hi) + "]"
case reflect.MethodType(formals, resultType) =>
formals.map(Print).mkString("(", ", ", ")") + " => " + Print(resultType)
case reflect.NullaryMethodType(resultType) =>
" => " + Print(resultType)
case reflect.PolyType(typeParams, typeBounds, resultType) =>
val z = (typeParams, typeBounds).zipped map ((tp, tb) => "[" + Print(tb._1) + " :> " + Print(tp) + " :> " + Print(tb._2) + "]")
z.mkString("[", ", ", "]") + " -> " + Print(resultType)
case _ =>
"???"
}
}

View File

@ -9,7 +9,7 @@ import java.lang.reflect.{ InvocationTargetException, UndeclaredThrowableExcepti
/** A few java-reflection oriented utility functions useful during reflection bootstrapping.
*/
trait ReflectionUtils {
object ReflectionUtils {
// Unwraps some chained exceptions which arise during reflective calls.
def unwrapThrowable(x: Throwable): Throwable = x match {
case _: InvocationTargetException | // thrown by reflectively invoked method or constructor
@ -23,7 +23,7 @@ trait ReflectionUtils {
}
// Transforms an exception handler into one which will only receive the unwrapped
// exceptions (for the values of wrap covered in unwrapThrowable.)
def unwrapForHandler[T](pf: PartialFunction[Throwable, T]): PartialFunction[Throwable, T] = {
def unwrapHandler[T](pf: PartialFunction[Throwable, T]): PartialFunction[Throwable, T] = {
case ex if pf isDefinedAt unwrapThrowable(ex) => pf(unwrapThrowable(ex))
}

View File

@ -1,85 +0,0 @@
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
package scala.reflect
/** This type is required by the compiler and <b>should not be used in client code</b>. */
abstract class Symbol {
val owner: Symbol
val name: String
val tpe: Type
}
/** This type is required by the compiler and <b>should not be used in client code</b>. */
abstract class GlobalSymbol(val fullname: String) extends Symbol {
private val pointIndex = fullname.lastIndexOf(".")
val owner: Symbol =
if (pointIndex < 0) RootSymbol
else Class(fullname.substring(0, pointIndex))
val name: String =
if (pointIndex < 0) fullname
else fullname.substring(pointIndex+1, fullname.length())
}
/** This type is required by the compiler and <b>should not be used in client code</b>. */
abstract class LocalSymbol extends Symbol
/** This type is required by the compiler and <b>should not be used in client code</b>. */
case class Class(override val fullname: String) extends GlobalSymbol(fullname) {
val tpe = NamedType(fullname)
}
/** This type is required by the compiler and <b>should not be used in client code</b>. */
case class Method(override val fullname: String, tpe: Type) extends GlobalSymbol(fullname)
/** This type is required by the compiler and <b>should not be used in client code</b>. */
case class Field(override val fullname: String, tpe: Type) extends GlobalSymbol(fullname)
/** This type is required by the compiler and <b>should not be used in client code</b>. */
case class TypeField(override val fullname: String, tpe: Type) extends GlobalSymbol(fullname)
/** This type is required by the compiler and <b>should not be used in client code</b>. */case class LocalValue(owner: Symbol, name: String, tpe: Type) extends LocalSymbol
/** This type is required by the compiler and <b>should not be used in client code</b>. */
case class LocalMethod(owner: Symbol, name: String, tpe: Type) extends LocalSymbol
/** This type is required by the compiler and <b>should not be used in client code</b>. */
case object NoSymbol extends Symbol {
val owner = null
val name = null
val tpe = NoType
}
/** This type is required by the compiler and <b>should not be used in client code</b>. */
case object RootSymbol extends Symbol {
val owner = NoSymbol
val name = "<root>"
val tpe = NoPrefix
}
/** This type is required by the compiler and <b>should not be used in client code</b>. */
case class LabelSymbol(val name: String) extends Symbol {
val owner = NoSymbol
val tpe = NamedType("scala.Unit")
}
/* Standard pattern match:
case reflect.Class(fullname) =>
case reflect.Method(fullname, tpe) =>
case reflect.Field(fullname, tpe) =>
case reflect.TypeField(fullname, tpe) =>
case reflect.LocalValue(owner, name, tpe) =>
case reflect.LocalMethod(owner, name, tpe) =>
case reflect.NoSymbol =>
case reflect.RootSymbol =>
case reflect.LabelSymbol(name) =>
*/

View File

@ -1,52 +0,0 @@
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
package scala.reflect
/** This type is required by the compiler and <b>should not be used in client code</b>. */
abstract class Tree
/** This type is required by the compiler and <b>should not be used in client code</b>. */
case class Ident(sym: Symbol) extends Tree
/** This type is required by the compiler and <b>should not be used in client code</b>. */
case class Select(qual: Tree, sym: Symbol) extends Tree
/** This type is required by the compiler and <b>should not be used in client code</b>. */
case class Literal(value: Any) extends Tree
/** This type is required by the compiler and <b>should not be used in client code</b>. */
case class Apply(fun: Tree, args: List[Tree]) extends Tree
/** This type is required by the compiler and <b>should not be used in client code</b>. */
case class TypeApply(fun: Tree, args: List[Type]) extends Tree
/** This type is required by the compiler and <b>should not be used in client code</b>. */
case class Function(params: List[Symbol], body: Tree) extends Tree
/** This type is required by the compiler and <b>should not be used in client code</b>. */
case class This(sym: Symbol) extends Tree
/** This type is required by the compiler and <b>should not be used in client code</b>. */
case class Block(stats: List[Tree], expr: Tree) extends Tree
/** This type is required by the compiler and <b>should not be used in client code</b>. */
case class New(sym: Tree) extends Tree
/** This type is required by the compiler and <b>should not be used in client code</b>. */
case class If(condition: Tree, trueCase: Tree, falseCase: Tree) extends Tree
/** This type is required by the compiler and <b>should not be used in client code</b>. */
case class Assign(destination: Tree, source: Tree) extends Tree
/** This type is required by the compiler and <b>should not be used in client code</b>. */
case class Target(sym: LabelSymbol, body: Tree) extends Tree
/** This type is required by the compiler and <b>should not be used in client code</b>. */
case class Goto(target: LabelSymbol) extends Tree
/** This type is required by the compiler and <b>should not be used in client code</b>. */
case class ValDef(sym: Symbol, rhs: Tree) extends Tree
//Monomorphic
/** This type is required by the compiler and <b>should not be used in client code</b>. */
case class ClassDef(sym: Symbol, tpe: Type, impl: Template) extends Tree
/** This type is required by the compiler and <b>should not be used in client code</b>. */
case class DefDef(sym: Symbol, vparamss: List[List[Tree]], ret: Type, rhs: Tree) extends Tree
/** This type is required by the compiler and <b>should not be used in client code</b>. */
case class Super(psym: Symbol) extends Tree
/** This type is required by the compiler and <b>should not be used in client code</b>. */
case class Template(parents: List[Type], body: List[Tree]) extends Tree

Some files were not shown because too many files have changed in this diff Show More