Merge branch 'master' into java7
This commit is contained in:
commit
bef11beca5
12
build.xml
12
build.xml
|
@ -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" />
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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).
|
||||
*/
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
}
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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@ %*
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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 _ =>
|
||||
|
|
|
@ -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 { }
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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("&", i+1)
|
||||
case '<' =>
|
||||
val ch = buf(i+1).toChar
|
||||
if (ch == '-' || ch == ':' || ch == '%')
|
||||
parse("&", i+1)
|
||||
case '<' =>
|
||||
val ch = buf(i+1).toChar
|
||||
if (ch == '-' || ch == ':' || ch == '%')
|
||||
parse("<span class=\"kw\"><"+ch+"</span>", i+2)
|
||||
else
|
||||
else
|
||||
parse("<", i+1)
|
||||
case '>' =>
|
||||
if (buf(i+1) == ':')
|
||||
parse("<span class=\"kw\">>:</span>", i+2)
|
||||
else
|
||||
parse(">", i+1)
|
||||
case '=' =>
|
||||
if (buf(i+1) == '>')
|
||||
parse("<span class=\"kw\">=></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\">>:</span>", i+2)
|
||||
else
|
||||
parse(">", i+1)
|
||||
case '=' =>
|
||||
if (buf(i+1) == '>')
|
||||
parse("<span class=\"kw\">=></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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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||" ",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…</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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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?")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(_, _) =>
|
||||
|
|
|
@ -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 ==)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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 _ =>
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||
|
||||
|
|
|
@ -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 + "$")
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 "")
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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]]
|
||||
|
|
|
@ -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>. */
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 _ =>
|
||||
"???"
|
||||
}
|
||||
|
||||
}
|
|
@ -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))
|
||||
}
|
||||
|
||||
|
|
|
@ -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) =>
|
||||
*/
|
|
@ -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
Loading…
Reference in New Issue