diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2012-06-08 02:36:10 +0200 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2012-06-08 15:32:28 +0200 |
commit | 0b2f1bcf75d31c59b25e19eebcb80f39c155365b (patch) | |
tree | 8d9dfc50ef01ca48c068b232af7e67a723325388 /src/compiler | |
parent | 13213e3df0384b1fd815c0798758a22284572cdb (diff) | |
download | scala-0b2f1bcf75d31c59b25e19eebcb80f39c155365b.tar.gz scala-0b2f1bcf75d31c59b25e19eebcb80f39c155365b.tar.bz2 scala-0b2f1bcf75d31c59b25e19eebcb80f39c155365b.zip |
Introduces scala-reflect.jar
Diffstat (limited to 'src/compiler')
85 files changed, 0 insertions, 26856 deletions
diff --git a/src/compiler/scala/reflect/api/JavaUniverse.scala b/src/compiler/scala/reflect/api/JavaUniverse.scala deleted file mode 100644 index 8bf62a357c..0000000000 --- a/src/compiler/scala/reflect/api/JavaUniverse.scala +++ /dev/null @@ -1,19 +0,0 @@ -package scala.reflect -package api - -// [Martin] Moved to compiler because it needs to see runtime.Universe -// The two will be united in scala-reflect anyway. -trait JavaUniverse extends Universe with Mirrors with TagInterop { self => - - type RuntimeClass = java.lang.Class[_] - - override type Mirror >: Null <: JavaMirror - - trait JavaMirror extends MirrorOf[self.type] with RuntimeMirror { - val classLoader: ClassLoader - override def toString = s"JavaMirror with ${runtime.ReflectionUtils.show(classLoader)}" - } - - def runtimeMirror(cl: ClassLoader): Mirror -} - diff --git a/src/compiler/scala/reflect/api/TagInterop.scala b/src/compiler/scala/reflect/api/TagInterop.scala deleted file mode 100644 index e10b89d1c6..0000000000 --- a/src/compiler/scala/reflect/api/TagInterop.scala +++ /dev/null @@ -1,38 +0,0 @@ -package scala.reflect -package api - -import scala.reflect.base.TypeCreator -import scala.reflect.base.{Universe => BaseUniverse} - -// [Martin] Moved to compiler because it needs to see runtime.Universe -// The two will be united in scala-reflect anyway. -trait TagInterop { self: JavaUniverse => - - // [Eugene++] would be great if we could approximate the interop without any mirrors - // todo. think how to implement that - - override def concreteTypeTagToManifest[T: ClassTag](mirror0: Any, tag: base.Universe # ConcreteTypeTag[T]): Manifest[T] = { - // [Eugene++] implement more sophisticated logic - // Martin said it'd be okay to simply copypaste `Implicits.manifestOfType` - val mirror = mirror0.asInstanceOf[Mirror] - val runtimeClass = mirror.runtimeClass(tag.in(mirror).tpe) - Manifest.classType(runtimeClass).asInstanceOf[Manifest[T]] - } - - override def manifestToConcreteTypeTag[T](mirror0: Any, manifest: Manifest[T]): base.Universe # ConcreteTypeTag[T] = - ConcreteTypeTag(mirror0.asInstanceOf[Mirror], new TypeCreator { - def apply[U <: BaseUniverse with Singleton](mirror: MirrorOf[U]): U # Type = { - mirror.universe match { - case ju: JavaUniverse => - val jm = mirror.asInstanceOf[ju.Mirror] - val sym = jm.reflectClass(manifest.erasure).symbol - val tpe = - if (manifest.typeArguments.isEmpty) sym.asType - else ju.appliedType(sym.asTypeConstructor, manifest.typeArguments map (targ => ju.manifestToConcreteTypeTag(jm, targ)) map (_.in(jm).tpe)) - tpe.asInstanceOf[U # Type] - case u => - u.manifestToConcreteTypeTag(mirror.asInstanceOf[u.Mirror], manifest).in(mirror).tpe - } - } - }) -} diff --git a/src/compiler/scala/reflect/internal/AbstractFileApi.scala b/src/compiler/scala/reflect/internal/AbstractFileApi.scala deleted file mode 100644 index 9f37f4536f..0000000000 --- a/src/compiler/scala/reflect/internal/AbstractFileApi.scala +++ /dev/null @@ -1,7 +0,0 @@ -package scala.reflect -package internal - -trait AbstractFileApi { - def path: String - def canonicalPath: String -} diff --git a/src/compiler/scala/reflect/internal/AnnotationCheckers.scala b/src/compiler/scala/reflect/internal/AnnotationCheckers.scala deleted file mode 100644 index 449b0ca0bc..0000000000 --- a/src/compiler/scala/reflect/internal/AnnotationCheckers.scala +++ /dev/null @@ -1,121 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2007-2011 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.reflect -package internal - -/** Additions to the type checker that can be added at - * run time. Typically these are added by - * compiler plugins. */ -trait AnnotationCheckers { - self: SymbolTable => - - - /** An additional checker for annotations on types. - * Typically these are registered by compiler plugins - * with the addAnnotationChecker method. */ - abstract class AnnotationChecker { - /** Check the annotations on two types conform. */ - def annotationsConform(tpe1: Type, tpe2: Type): Boolean - - /** Refine the computed least upper bound of a list of types. - * All this should do is add annotations. */ - def annotationsLub(tp: Type, ts: List[Type]): Type = tp - - /** Refine the computed greatest lower bound of a list of types. - * All this should do is add annotations. */ - def annotationsGlb(tp: Type, ts: List[Type]): Type = tp - - /** Refine the bounds on type parameters to the given type arguments. */ - def adaptBoundsToAnnotations(bounds: List[TypeBounds], - tparams: List[Symbol], targs: List[Type]): List[TypeBounds] = bounds - - /** Modify the type that has thus far been inferred - * for a tree. All this should do is add annotations. */ - def addAnnotations(tree: Tree, tpe: Type): Type = tpe - - /** Decide whether this annotation checker can adapt a tree - * that has an annotated type to the given type tp, taking - * into account the given mode (see method adapt in trait Typers).*/ - def canAdaptAnnotations(tree: Tree, mode: Int, pt: Type): Boolean = false - - /** Adapt a tree that has an annotated type to the given type tp, - * taking into account the given mode (see method adapt in trait Typers). - * An implementation cannot rely on canAdaptAnnotations being called - * before. If the implementing class cannot do the adaptiong, it - * should return the tree unchanged.*/ - def adaptAnnotations(tree: Tree, mode: Int, pt: Type): Tree = tree - } - - // Syncnote: Annotation checkers inaccessible to reflection, so no sync in var necessary. - /** The list of annotation checkers that have been registered */ - private var annotationCheckers: List[AnnotationChecker] = Nil - - /** Register an annotation checker. Typically these - * are added by compiler plugins. */ - def addAnnotationChecker(checker: AnnotationChecker) { - if (!(annotationCheckers contains checker)) - annotationCheckers = checker :: annotationCheckers - } - - /** Remove all annotation checkers */ - def removeAllAnnotationCheckers() { - annotationCheckers = Nil - } - - /** Check that the annotations on two types conform. To do - * so, consult all registered annotation checkers. */ - def annotationsConform(tp1: Type, tp2: Type): Boolean = { - /* Finish quickly if there are no annotations */ - if (tp1.annotations.isEmpty && tp2.annotations.isEmpty) - true - else - annotationCheckers.forall( - _.annotationsConform(tp1,tp2)) - } - - /** Refine the computed least upper bound of a list of types. - * All this should do is add annotations. */ - def annotationsLub(tpe: Type, ts: List[Type]): Type = { - annotationCheckers.foldLeft(tpe)((tpe, checker) => - checker.annotationsLub(tpe, ts)) - } - - /** Refine the computed greatest lower bound of a list of types. - * All this should do is add annotations. */ - def annotationsGlb(tpe: Type, ts: List[Type]): Type = { - annotationCheckers.foldLeft(tpe)((tpe, checker) => - checker.annotationsGlb(tpe, ts)) - } - - /** Refine the bounds on type parameters to the given type arguments. */ - def adaptBoundsToAnnotations(bounds: List[TypeBounds], - tparams: List[Symbol], targs: List[Type]): List[TypeBounds] = { - annotationCheckers.foldLeft(bounds)((bounds, checker) => - checker.adaptBoundsToAnnotations(bounds, tparams, targs)) - } - - /** Let all annotations checkers add extra annotations - * to this tree's type. */ - def addAnnotations(tree: Tree, tpe: Type): Type = { - annotationCheckers.foldLeft(tpe)((tpe, checker) => - checker.addAnnotations(tree, tpe)) - } - - /** Find out whether any annotation checker can adapt a tree - * to a given type. Called by Typers.adapt. */ - def canAdaptAnnotations(tree: Tree, mode: Int, pt: Type): Boolean = { - annotationCheckers.exists(_.canAdaptAnnotations(tree, mode, pt)) - } - - /** Let registered annotation checkers adapt a tree - * to a given type (called by Typers.adapt). Annotation checkers - * that cannot do the adaption should pass the tree through - * unchanged. */ - def adaptAnnotations(tree: Tree, mode: Int, pt: Type): Tree = { - annotationCheckers.foldLeft(tree)((tree, checker) => - checker.adaptAnnotations(tree, mode, pt)) - } -} diff --git a/src/compiler/scala/reflect/internal/AnnotationInfos.scala b/src/compiler/scala/reflect/internal/AnnotationInfos.scala deleted file mode 100644 index c283ae408e..0000000000 --- a/src/compiler/scala/reflect/internal/AnnotationInfos.scala +++ /dev/null @@ -1,293 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2007-2011 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.reflect -package internal - -import util._ -import pickling.ByteCodecs - -/** AnnotationInfo and its helpers */ -trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable => - import definitions.{ ThrowsClass, StaticAnnotationClass, isMetaAnnotation } - - // Common annotation code between Symbol and Type. - // For methods altering the annotation list, on Symbol it mutates - // the Symbol's field directly. For Type, a new AnnotatedType is - // created which wraps the original type. - trait Annotatable[Self] { - /** The annotations on this type. */ - 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. - */ - def throwsAnnotations(): List[Symbol] = annotations collect { - case AnnotationInfo(tp, Literal(Constant(tpe: Type)) :: Nil, _) if tp.typeSymbol == ThrowsClass => tpe.typeSymbol - } - - /** 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 = filterAnnotations(ann => !(ann matches cls)) - final def withAnnotation(annot: AnnotationInfo): Self = withAnnotations(List(annot)) - } - - /** Arguments to classfile annotations (which are written to - * bytecode as java annotations) are either: - * - * - constants - * - arrays of constants - * - or nested classfile annotations - */ - abstract class ClassfileAnnotArg extends Product - implicit val ClassfileAnnotArgTag = ClassTag[ClassfileAnnotArg](classOf[ClassfileAnnotArg]) - - /** Represents a compile-time Constant (`Boolean`, `Byte`, `Short`, - * `Char`, `Int`, `Long`, `Float`, `Double`, `String`, `java.lang.Class` or - * an instance of a Java enumeration value). - */ - case class LiteralAnnotArg(const: Constant) - extends ClassfileAnnotArg with LiteralAnnotArgApi { - override def toString = const.escapedStringValue - } - implicit val LiteralAnnotArgTag = ClassTag[LiteralAnnotArg](classOf[LiteralAnnotArg]) - - object LiteralAnnotArg extends LiteralAnnotArgExtractor - - /** Represents an array of classfile annotation arguments */ - case class ArrayAnnotArg(args: Array[ClassfileAnnotArg]) - extends ClassfileAnnotArg with ArrayAnnotArgApi { - override def toString = args.mkString("[", ", ", "]") - } - implicit val ArrayAnnotArgTag = ClassTag[ArrayAnnotArg](classOf[ArrayAnnotArg]) - - object ArrayAnnotArg extends ArrayAnnotArgExtractor - - /** A specific annotation argument that encodes an array of bytes as an - * array of `Long`. The type of the argument declared in the annotation - * must be `String`. This specialised class is used to encode Scala - * signatures for reasons of efficiency, both in term of class-file size - * and in term of compiler performance. - */ - case class ScalaSigBytes(bytes: Array[Byte]) extends ClassfileAnnotArg { - override def toString = (bytes map { byte => (byte & 0xff).toHexString }).mkString("[ ", " ", " ]") - lazy val encodedBytes = ByteCodecs.encode(bytes) // TODO remove after migration to ASM-based GenJVM complete - def isLong: Boolean = (encodedBytes.length > 65535) // TODO remove after migration to ASM-based GenJVM complete - lazy val sevenBitsMayBeZero: Array[Byte] = { - mapToNextModSevenBits(scala.reflect.internal.pickling.ByteCodecs.encode8to7(bytes)) - } - def fitsInOneString: Boolean = { - val numZeros = (sevenBitsMayBeZero count { b => b == 0 }) - val res = (sevenBitsMayBeZero.length + numZeros) <= 65535 - assert(this.isLong == !res, "As things stand, can't just swap in `fitsInOneString()` for `isLong()`") - res - } - def sigAnnot: Type = - if (this.isLong) - definitions.ScalaLongSignatureAnnotation.tpe - else - definitions.ScalaSignatureAnnotation.tpe - - private def mapToNextModSevenBits(src: Array[Byte]): Array[Byte] = { - var i = 0 - val srclen = src.length - while (i < srclen) { - val in = src(i) - src(i) = (if (in == 0x7f) 0.toByte else (in + 1).toByte) - i += 1 - } - src - } - - } - - /** Represents a nested classfile annotation */ - case class NestedAnnotArg(annInfo: AnnotationInfo) extends ClassfileAnnotArg with NestedAnnotArgApi { - // The nested annotation should not have any Scala annotation arguments - assert(annInfo.args.isEmpty, annInfo.args) - override def toString = annInfo.toString - } - implicit val NestedAnnotArgTag = ClassTag[NestedAnnotArg](classOf[NestedAnnotArg]) - - object NestedAnnotArg extends NestedAnnotArgExtractor - - 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) - - // necessary for reification, see Reifiers.scala for more info - private var orig: Tree = EmptyTree - def original = orig - def setOriginal(t: Tree): this.type = { - orig = t - this setPos t.pos - this - } - - 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 { - val result = lazyInfo - if (result.pos == NoPosition) result setPos pos - result - } finally forced = true - - def atp: Type = forcedInfo.atp - def args: List[Tree] = forcedInfo.args - def assocs: List[(Name, ClassfileAnnotArg)] = forcedInfo.assocs - def original: Tree = forcedInfo.original - def setOriginal(t: Tree): this.type = { forcedInfo.setOriginal(t); this } - - // We should always be able to print things without forcing them. - override def toString = if (forced) forcedInfo.toString else "@<?>" - - override def pos: Position = if (forced) forcedInfo.pos else NoPosition - } - - /** Typed information about an annotation. It can be attached to either - * a symbol or an annotated type. - * - * Annotations are written to the classfile as Java annotations - * if `atp` conforms to `ClassfileAnnotation` (the classfile parser adds - * this interface to any Java annotation class). - * - * Annotations are pickled (written to scala symtab attribute in the - * classfile) if `atp` inherits form `StaticAnnotation`. - * - * `args` stores arguments to Scala annotations, represented as typed - * trees. Note that these trees are not transformed by any phases - * following the type-checker. - * - * `assocs` stores arguments to classfile annotations as name-value pairs. - */ - sealed abstract class AnnotationInfo extends AnnotationInfoApi { - def atp: Type - def args: List[Tree] - def assocs: List[(Name, ClassfileAnnotArg)] - - // necessary for reification, see Reifiers.scala for more info - def original: Tree - def setOriginal(t: Tree): this.type - - // see annotationArgRewriter - lazy val isTrivial = atp.isTrivial && !hasArgWhich(_.isInstanceOf[This]) - - private var rawpos: Position = NoPosition - def pos = rawpos - def setPos(pos: Position): this.type = { // Syncnote: Setpos inaccessible to reflection, so no sync in rawpos necessary. - rawpos = pos - this - } - - /** Annotations annotating annotations are confusing so I drew - * an example. Given the following code: - * - * class A { - * @(deprecated @setter) @(inline @getter) - * var x: Int = 0 - * } - * - * For the setter `x_=` in A, annotations contains one AnnotationInfo = - * List(deprecated @setter) - * The single AnnotationInfo in that list, i.e. `@(deprecated @setter)`, has metaAnnotations = - * List(setter) - * - * Similarly, the getter `x` in A has an @inline annotation, which has - * metaAnnotations = List(getter). - */ - def symbol = atp.typeSymbol - - /** These are meta-annotations attached at the use site; they - * only apply to this annotation usage. For instance, in - * `@(deprecated @setter @field) val ...` - * metaAnnotations = List(setter, field). - */ - def metaAnnotations: List[AnnotationInfo] = atp match { - case AnnotatedType(metas, _, _) => metas - case _ => Nil - } - - /** The default kind of members to which this annotation is attached. - * For instance, for scala.deprecated defaultTargets = - * List(getter, setter, beanGetter, beanSetter). - */ - def defaultTargets = symbol.annotations map (_.symbol) filter isMetaAnnotation - // Test whether the typeSymbol of atp conforms to the given class. - def matches(clazz: Symbol) = symbol isNonBottomSubClass clazz - // All subtrees of all args are considered. - def hasArgWhich(p: Tree => Boolean) = args exists (_ exists p) - - /** 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) - - /** Change all ident's with Symbol "from" to instead use symbol "to" */ - def substIdentSyms(from: Symbol, to: Symbol) = - AnnotationInfo(atp, args map (_ substituteSymbols (List(from), List(to))), assocs) setPos pos - - def stringArg(index: Int) = constantAtIndex(index) map (_.stringValue) - def intArg(index: Int) = constantAtIndex(index) map (_.intValue) - def symbolArg(index: Int) = argAtIndex(index) collect { - case Apply(fun, Literal(str) :: Nil) if fun.symbol == definitions.Symbol_apply => - newTermName(str.stringValue) - } - - // !!! when annotation arguments are not literals, but any sort of - // expression, there is a fair chance they will turn up here not as - // Literal(const) but some arbitrary AST. - def constantAtIndex(index: Int): Option[Constant] = - argAtIndex(index) collect { case Literal(x) => x } - - 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 - } - } - - implicit val AnnotationInfoTag = ClassTag[AnnotationInfo](classOf[AnnotationInfo]) - - object UnmappableAnnotation extends CompleteAnnotationInfo(NoType, Nil, Nil) -} diff --git a/src/compiler/scala/reflect/internal/BaseTypeSeqs.scala b/src/compiler/scala/reflect/internal/BaseTypeSeqs.scala deleted file mode 100644 index e07f1bac49..0000000000 --- a/src/compiler/scala/reflect/internal/BaseTypeSeqs.scala +++ /dev/null @@ -1,260 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ -package scala.reflect -package internal - -// todo implement in terms of BitSet -import scala.collection.{ mutable, immutable } -import math.max -import util.Statistics._ - -/** A base type sequence (BaseTypeSeq) is an ordered sequence spanning all the base types - * of a type. It characterized by the following two laws: - * - * (1) Each element of `tp.baseTypeSeq` is a basetype of `tp` - * (2) For each basetype `bt1` of `tp` there is an element `bt` in `tp.baseTypeSeq` such that - * - * bt.typeSymbol = bt1.typeSymbol - * bt <: bt1 - * - * (3) The type symbols of different elements are different. - * - * Elements in the sequence are ordered by Symbol.isLess. - * @note base type sequences were called closures up to 2.7.1. The name has been changed - * to avoid confusion with function closures. - */ -trait BaseTypeSeqs { - this: SymbolTable => - import definitions._ - - protected def newBaseTypeSeq(parents: List[Type], elems: Array[Type]) = - new BaseTypeSeq(parents, elems) - - /** Note: constructor is protected to force everyone to use the factory method newBaseTypeSeq instead. - * This is necessary because when run from reflection every base type sequence needs to have a - * SynchronizedBaseTypeSeq as mixin. - */ - class BaseTypeSeq protected[BaseTypeSeqs] (private[BaseTypeSeqs] val parents: List[Type], private[BaseTypeSeqs] val elems: Array[Type]) { - self => - incCounter(baseTypeSeqCount) - incCounter(baseTypeSeqLenTotal, elems.length) - - /** The number of types in the sequence */ - def length: Int = elems.length - - // #3676 shows why we can't store NoType in elems to mark cycles - // (while NoType is in there to indicate a cycle in this BTS, during the execution of - // the mergePrefixAndArgs below, the elems get copied without the pending map, - // so that NoType's are seen instead of the original type --> spurious compile error) - private val pending = new mutable.BitSet(length) - - /** The type at i'th position in this sequence; lazy types are returned evaluated. */ - def apply(i: Int): Type = - if(pending contains i) { - pending.clear() - throw CyclicInheritance - } else - elems(i) match { - case rtp @ RefinedType(variants, decls) => - // can't assert decls.isEmpty; see t0764 - //if (!decls.isEmpty) assert(false, "computing closure of "+this+":"+this.isInstanceOf[RefinedType]+"/"+closureCache(j)) - //Console.println("compute closure of "+this+" => glb("+variants+")") - pending += i - try { - mergePrefixAndArgs(variants, -1, lubDepth(variants)) match { - case Some(tp0) => - pending(i) = false - elems(i) = tp0 - tp0 - case None => - typeError( - "no common type instance of base types "+(variants mkString ", and ")+" exists.") - } - } catch { - case CyclicInheritance => - typeError( - "computing the common type instance of base types "+(variants mkString ", and ")+" leads to a cycle.") - } - case tp => - tp - } - - def rawElem(i: Int) = elems(i) - - /** The type symbol of the type at i'th position in this sequence; - * no evaluation needed. - */ - def typeSymbol(i: Int): Symbol = { - elems(i) match { - case RefinedType(v :: vs, _) => v.typeSymbol - case tp => tp.typeSymbol - } - } - - /** Return all evaluated types in this sequence as a list */ - def toList: List[Type] = elems.toList - - def copy(head: Type, offset: Int): BaseTypeSeq = { - val arr = new Array[Type](elems.length + offset) - compat.Platform.arraycopy(elems, 0, arr, offset, elems.length) - arr(0) = head - newBaseTypeSeq(parents, arr) - } - - /** Compute new base type sequence with `tp` prepended to this sequence */ - def prepend(tp: Type): BaseTypeSeq = copy(tp, 1) - - /** Compute new base type sequence with `tp` replacing the head of this sequence */ - def updateHead(tp: Type): BaseTypeSeq = copy(tp, 0) - - /** Compute new base type sequence where every element is mapped - * with function `f`. Lazy types are mapped but not evaluated */ - def map(f: Type => Type): BaseTypeSeq = { - // inlined `elems map f` for performance - val len = length - var arr = new Array[Type](len) - var i = 0 - while (i < len) { - arr(i) = f(elems(i)) - i += 1 - } - newBaseTypeSeq(parents, arr) - } - - def lateMap(f: Type => Type): BaseTypeSeq = new MappedBaseTypeSeq(this, f) - - def exists(p: Type => Boolean): Boolean = elems exists p - - lazy val maxDepth: Int = maxDepthOfElems - - protected def maxDepthOfElems = { - var d = 0 - for (i <- 0 until length) d = max(d, maxDpth(elems(i))) - d - } - - /** The maximum depth of type `tp` */ - protected def maxDpth(tp: Type): Int = tp match { - case TypeRef(pre, sym, args) => - max(maxDpth(pre), maxDpth(args) + 1) - case RefinedType(parents, decls) => - max(maxDpth(parents), maxDpth(decls.toList.map(_.info)) + 1) - case TypeBounds(lo, hi) => - max(maxDpth(lo), maxDpth(hi)) - case MethodType(paramtypes, result) => - maxDpth(result) - case NullaryMethodType(result) => - maxDpth(result) - case PolyType(tparams, result) => - max(maxDpth(result), maxDpth(tparams map (_.info)) + 1) - case ExistentialType(tparams, result) => - max(maxDpth(result), maxDpth(tparams map (_.info)) + 1) - case _ => - 1 - } - - /** The maximum depth of all types `tps` */ - private def maxDpth(tps: Seq[Type]): Int = { - var d = 0 - for (tp <- tps) d = max(d, maxDpth(tp)) - d - } - - override def toString = elems.mkString("BTS(", ",", ")") - - private def typeError(msg: String): Nothing = - throw new TypeError( - "the type intersection "+(parents mkString " with ")+" is malformed"+ - "\n --- because ---\n"+msg) - } - - /** A merker object for a base type sequence that's no yet computed. - * used to catch inheritance cycles - */ - val undetBaseTypeSeq: BaseTypeSeq = newBaseTypeSeq(List(), Array()) - - /** Create a base type sequence consisting of a single type */ - def baseTypeSingletonSeq(tp: Type): BaseTypeSeq = newBaseTypeSeq(List(), Array(tp)) - - /** Create the base type sequence of a compound type wuth given tp.parents */ - def compoundBaseTypeSeq(tp: Type): BaseTypeSeq = { - val tsym = tp.typeSymbol - val parents = tp.parents -// Console.println("computing baseTypeSeq of " + tsym.tpe + " " + parents)//DEBUG - val buf = new mutable.ListBuffer[Type] - buf += tsym.tpe - var btsSize = 1 - if (parents.nonEmpty) { - val nparents = parents.length - val pbtss = new Array[BaseTypeSeq](nparents) - val index = new Array[Int](nparents) - var i = 0 - for (p <- parents) { - pbtss(i) = - if (p.baseTypeSeq eq undetBaseTypeSeq) AnyClass.info.baseTypeSeq - else p.baseTypeSeq - index(i) = 0 - i += 1 - } - def nextTypeSymbol(i: Int): Symbol = { - val j = index(i) - val pbts = pbtss(i) - if (j < pbts.length) pbts.typeSymbol(j) else AnyClass - } - def nextRawElem(i: Int): Type = { - val j = index(i) - val pbts = pbtss(i) - if (j < pbts.length) pbts.rawElem(j) else AnyClass.tpe - } - var minSym: Symbol = NoSymbol - while (minSym != AnyClass) { - minSym = nextTypeSymbol(0) - i = 1 - while (i < nparents) { - val nextSym = nextTypeSymbol(i) - if (nextSym isLess minSym) - minSym = nextSym - i += 1 - } - var minTypes: List[Type] = List() - i = 0 - while (i < nparents) { - if (nextTypeSymbol(i) == minSym) { - nextRawElem(i) match { - case RefinedType(variants, decls) => - for (tp <- variants) - if (!(minTypes exists (tp =:= _))) minTypes = tp :: minTypes - case tp => - if (!(minTypes exists (tp =:= _))) minTypes = tp :: minTypes - } - index(i) = index(i) + 1 - } - i += 1 - } - buf += intersectionType(minTypes) - btsSize += 1 - } - } - val elems = new Array[Type](btsSize) - buf.copyToArray(elems, 0) -// Console.println("computed baseTypeSeq of " + tsym.tpe + " " + parents + ": "+elems.toString)//DEBUG - newBaseTypeSeq(parents, elems) - } - - class MappedBaseTypeSeq(orig: BaseTypeSeq, f: Type => Type) extends BaseTypeSeq(orig.parents map f, orig.elems) { - override def apply(i: Int) = f(orig.apply(i)) - override def rawElem(i: Int) = f(orig.rawElem(i)) - override def typeSymbol(i: Int) = orig.typeSymbol(i) - override def toList = orig.toList map f - override def copy(head: Type, offset: Int) = (orig map f).copy(head, offset) - override def map(g: Type => Type) = lateMap(g) - override def lateMap(g: Type => Type) = orig.lateMap(x => g(f(x))) - override def exists(p: Type => Boolean) = elems exists (x => p(f(x))) - override protected def maxDepthOfElems: Int = (elems map (x => maxDpth(f(x)))).max - override def toString = elems.mkString("MBTS(", ",", ")") - } - - val CyclicInheritance = new Throwable -} diff --git a/src/compiler/scala/reflect/internal/BuildUtils.scala b/src/compiler/scala/reflect/internal/BuildUtils.scala deleted file mode 100644 index 3bde57ded8..0000000000 --- a/src/compiler/scala/reflect/internal/BuildUtils.scala +++ /dev/null @@ -1,69 +0,0 @@ -package scala.reflect -package internal - -import Flags._ - -trait BuildUtils extends base.BuildUtils { self: SymbolTable => - - class BuildImpl extends BuildBase { - - def selectType(owner: Symbol, name: String): TypeSymbol = { - val result = owner.info.decl(newTypeName(name)) - if (result ne NoSymbol) result.asTypeSymbol - else MissingRequirementError.notFound("type %s in %s".format(name, owner.fullName)) - } - - def selectTerm(owner: Symbol, name: String): TermSymbol = { - val sym = owner.info.decl(newTermName(name)) - val result = - if (sym.isOverloaded) sym.suchThat(!_.isMethod) - else sym - if (result ne NoSymbol) result.asTermSymbol - else MissingRequirementError.notFound("term %s in %s".format(name, owner.fullName)) - } - - def selectOverloadedMethod(owner: Symbol, name: String, index: Int): MethodSymbol = { - val result = owner.info.decl(newTermName(name)).alternatives(index) - if (result ne NoSymbol) result.asMethodSymbol - else MissingRequirementError.notFound("overloaded method %s #%d in %s".format(name, index, owner.fullName)) - } - - def newFreeTerm(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTermSymbol = - newFreeTermSymbol(newTermName(name), info, value, flags, origin) - - def newFreeType(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTypeSymbol = - newFreeTypeSymbol(newTypeName(name), info, value, (if (flags == 0L) PARAM else flags) | DEFERRED, origin) - - def newFreeExistential(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTypeSymbol = - newFreeTypeSymbol(newTypeName(name), info, value, (if (flags == 0L) EXISTENTIAL else flags) | DEFERRED, origin) - - def newNestedSymbol(owner: Symbol, name: Name, pos: Position, flags: Long, isClass: Boolean): Symbol = - owner.newNestedSymbol(name, pos, flags, isClass) - - def setAnnotations[S <: Symbol](sym: S, annots: List[AnnotationInfo]): S = - sym.setAnnotations(annots) - - def setTypeSignature[S <: Symbol](sym: S, tpe: Type): S = - sym.setTypeSignature(tpe) - - def flagsFromBits(bits: Long): FlagSet = bits - - def emptyValDef: ValDef = self.emptyValDef - - def This(sym: Symbol): Tree = self.This(sym) - - def Select(qualifier: Tree, sym: Symbol): Select = self.Select(qualifier, sym) - - def Ident(sym: Symbol): Ident = self.Ident(sym) - - def TypeTree(tp: Type): TypeTree = self.TypeTree(tp) - - def thisPrefix(sym: Symbol): Type = sym.thisPrefix - - def setType[T <: Tree](tree: T, tpe: Type): T = { tree.setType(tpe); tree } - - def setSymbol[T <: Tree](tree: T, sym: Symbol): T = { tree.setSymbol(sym); tree } - } - - val build: BuildBase = new BuildImpl -} diff --git a/src/compiler/scala/reflect/internal/CapturedVariables.scala b/src/compiler/scala/reflect/internal/CapturedVariables.scala deleted file mode 100644 index 77909d9157..0000000000 --- a/src/compiler/scala/reflect/internal/CapturedVariables.scala +++ /dev/null @@ -1,36 +0,0 @@ -package scala.reflect -package internal - -import Flags._ - -trait CapturedVariables { self: SymbolTable => - - import definitions._ - - /** Mark a variable as captured; i.e. force boxing in a *Ref type. - */ - def captureVariable(vble: Symbol): Unit = vble setFlag CAPTURED - - /** Mark given identifier as a reference to a captured variable itself - * suppressing dereferencing with the `elem` field. - */ - def referenceCapturedVariable(vble: Symbol): Tree = ReferenceToBoxed(Ident(vble)) - - /** Convert type of a captured variable to *Ref type. - */ - def capturedVariableType(vble: Symbol): Type = - capturedVariableType(vble, NoType, false) - - /** Convert type of a captured variable to *Ref type. - */ - def capturedVariableType(vble: Symbol, tpe: Type = NoType, erasedTypes: Boolean = false): Type = { - val tpe1 = if (tpe == NoType) vble.tpe else tpe - val symClass = tpe1.typeSymbol - def refType(valueRef: Map[Symbol, Symbol], objectRefClass: Symbol) = - if (isPrimitiveValueClass(symClass) && symClass != UnitClass) valueRef(symClass).tpe - else if (erasedTypes) objectRefClass.tpe - else appliedType(objectRefClass, tpe) - if (vble.hasAnnotation(VolatileAttr)) refType(volatileRefClass, VolatileObjectRefClass) - else refType(refClass, ObjectRefClass) - } -} diff --git a/src/compiler/scala/reflect/internal/Chars.scala b/src/compiler/scala/reflect/internal/Chars.scala deleted file mode 100644 index 50ec71094a..0000000000 --- a/src/compiler/scala/reflect/internal/Chars.scala +++ /dev/null @@ -1,98 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2006-2011 LAMP/EPFL - * @author Martin Odersky - */ -package scala.reflect -package internal - -import annotation.{ tailrec, switch } -import java.lang.{ Character => JCharacter } -import language.postfixOps - -/** Contains constants and classifier methods for characters */ -trait Chars { - // Be very careful touching these. - // Apparently trivial changes to the way you write these constants - // will cause Scanners.scala to go from a nice efficient switch to - // a ghastly nested if statement which will bring the type checker - // to its knees. See ticket #1456 - // Martin: (this should be verified now that the pattern rules have been redesigned). - final val LF = '\u000A' - final val FF = '\u000C' - final val CR = '\u000D' - final val SU = '\u001A' - - /** Convert a character digit to an Int according to given base, - * -1 if no success - */ - def digit2int(ch: Char, base: Int): Int = { - val num = ( - if (ch <= '9') ch - '0' - else if ('a' <= ch && ch <= 'z') ch - 'a' + 10 - else if ('A' <= ch && ch <= 'Z') ch - 'A' + 10 - else -1 - ) - if (0 <= num && num < base) num else -1 - } - /** Buffer for creating '\ u XXXX' strings. */ - private[this] val char2uescapeArray = Array[Char]('\\', 'u', 0, 0, 0, 0) - - /** Convert a character to a backslash-u escape */ - def char2uescape(c: Char): String = { - @inline def hexChar(ch: Int): Char = - ( if (ch < 10) '0' else 'A' - 10 ) + ch toChar - - char2uescapeArray(2) = hexChar((c >> 12) ) - char2uescapeArray(3) = hexChar((c >> 8) % 16) - char2uescapeArray(4) = hexChar((c >> 4) % 16) - char2uescapeArray(5) = hexChar((c ) % 16) - - new String(char2uescapeArray) - } - - /** Is character a line break? */ - @inline def isLineBreakChar(c: Char) = (c: @switch) match { - case LF|FF|CR|SU => true - case _ => false - } - - /** Is character a whitespace character (but not a new line)? */ - def isWhitespace(c: Char) = - c == ' ' || c == '\t' || c == CR - - /** Can character form part of a doc comment variable $xxx? */ - def isVarPart(c: Char) = - '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' - - /** Can character start an alphanumeric Scala identifier? */ - def isIdentifierStart(c: Char): Boolean = - (c == '_') || (c == '$') || Character.isUnicodeIdentifierStart(c) - - /** Can character form part of an alphanumeric Scala identifier? */ - def isIdentifierPart(c: Char) = - (c == '$') || Character.isUnicodeIdentifierPart(c) - - /** Is character a math or other symbol in Unicode? */ - def isSpecial(c: Char) = { - val chtp = Character.getType(c) - chtp == Character.MATH_SYMBOL.toInt || chtp == Character.OTHER_SYMBOL.toInt - } - - private final val otherLetters = Set[Char]('\u0024', '\u005F') // '$' and '_' - private final val letterGroups = { - import JCharacter._ - Set[Byte](LOWERCASE_LETTER, UPPERCASE_LETTER, OTHER_LETTER, TITLECASE_LETTER, LETTER_NUMBER) - } - def isScalaLetter(ch: Char) = letterGroups(JCharacter.getType(ch).toByte) || otherLetters(ch) - - /** Can character form part of a Scala operator name? */ - def isOperatorPart(c : Char) : Boolean = (c: @switch) match { - case '~' | '!' | '@' | '#' | '%' | - '^' | '*' | '+' | '-' | '<' | - '>' | '?' | ':' | '=' | '&' | - '|' | '/' | '\\' => true - case c => isSpecial(c) - } -} - -object Chars extends Chars { } diff --git a/src/compiler/scala/reflect/internal/ClassfileConstants.scala b/src/compiler/scala/reflect/internal/ClassfileConstants.scala deleted file mode 100644 index 3346e9cccb..0000000000 --- a/src/compiler/scala/reflect/internal/ClassfileConstants.scala +++ /dev/null @@ -1,390 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.reflect -package internal - -import annotation.switch - -object ClassfileConstants { - - final val JAVA_MAGIC = 0xCAFEBABE - final val JAVA_MAJOR_VERSION = 45 - final val JAVA_MINOR_VERSION = 3 - - /** (see http://java.sun.com/docs/books/jvms/second_edition/jvms-clarify.html) - * - * If the `ACC_INTERFACE` flag is set, the `ACC_ABSTRACT` flag must also - * be set (ch. 2.13.1). - * - * A class file cannot have both its `ACC_FINAL` and `ACC_ABSTRACT` flags - * set (ch. 2.8.2). - * - * A field may have at most one of its `ACC_PRIVATE`, `ACC_PROTECTED`, - * `ACC_PUBLIC` flags set (ch. 2.7.4). - * - * A field may not have both its `ACC_FINAL` and `ACC_VOLATILE` flags set - * (ch. 2.9.1). - * - * If a method has its `ACC_ABSTRACT` flag set it must not have any of its - * `ACC_FINAL`, `ACC_NATIVE`, `ACC_PRIVATE`, `ACC_STATIC`, `ACC_STRICT`, - * or `ACC_SYNCHRONIZED` flags set (ch. 2.13.3.2). - * - * 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 - final val JAVA_ACC_PROTECTED = 0x0004 // X X - final val JAVA_ACC_STATIC = 0x0008 // X X - final val JAVA_ACC_FINAL = 0x0010 // X X X - final val JAVA_ACC_SUPER = 0x0020 // X - final val JAVA_ACC_SYNCHRONIZED = 0x0020 // X - final val JAVA_ACC_VOLATILE = 0x0040 // X - final val JAVA_ACC_BRIDGE = 0x0040 // X - final val JAVA_ACC_TRANSIENT = 0x0080 // X - final val JAVA_ACC_VARARGS = 0x0080 // X - final val JAVA_ACC_NATIVE = 0x0100 // X - final val JAVA_ACC_INTERFACE = 0x0200 // X - final val JAVA_ACC_ABSTRACT = 0x0400 // X X - final val JAVA_ACC_STRICT = 0x0800 // X - final val JAVA_ACC_SYNTHETIC = 0x1000 // X X X - final val JAVA_ACC_ANNOTATION = 0x2000 // X - final val JAVA_ACC_ENUM = 0x4000 // X X - - // tags describing the type of a literal in the constant pool - final val CONSTANT_UTF8 = 1 - final val CONSTANT_UNICODE = 2 - final val CONSTANT_INTEGER = 3 - final val CONSTANT_FLOAT = 4 - final val CONSTANT_LONG = 5 - final val CONSTANT_DOUBLE = 6 - final val CONSTANT_CLASS = 7 - final val CONSTANT_STRING = 8 - final val CONSTANT_FIELDREF = 9 - final val CONSTANT_METHODREF = 10 - final val CONSTANT_INTFMETHODREF = 11 - final val CONSTANT_NAMEANDTYPE = 12 - - // tags describing the type of a literal in attribute values - final val BYTE_TAG = 'B' - final val CHAR_TAG = 'C' - final val DOUBLE_TAG = 'D' - final val FLOAT_TAG = 'F' - final val INT_TAG = 'I' - final val LONG_TAG = 'J' - final val SHORT_TAG = 'S' - final val BOOL_TAG = 'Z' - final val STRING_TAG = 's' - final val ENUM_TAG = 'e' - final val CLASS_TAG = 'c' - final val ARRAY_TAG = '[' - final val VOID_TAG = 'V' - final val TVAR_TAG = 'T' - final val OBJECT_TAG = 'L' - final val ANNOTATION_TAG = '@' - final val SCALA_NOTHING = "scala.runtime.Nothing$" - final val SCALA_NULL = "scala.runtime.Null$" - - - // tags describing the type of newarray - final val T_BOOLEAN = 4 - final val T_CHAR = 5 - final val T_FLOAT = 6 - final val T_DOUBLE = 7 - final val T_BYTE = 8 - final val T_SHORT = 9 - final val T_INT = 10 - final val T_LONG = 11 - - // JVM mnemonics - final val nop = 0x00 - final val aconst_null = 0x01 - final val iconst_m1 = 0x02 - - final val iconst_0 = 0x03 - final val iconst_1 = 0x04 - final val iconst_2 = 0x05 - final val iconst_3 = 0x06 - final val iconst_4 = 0x07 - final val iconst_5 = 0x08 - - final val lconst_0 = 0x09 - final val lconst_1 = 0x0a - final val fconst_0 = 0x0b - final val fconst_1 = 0x0c - final val fconst_2 = 0x0d - final val dconst_0 = 0x0e - final val dconst_1 = 0x0f - - final val bipush = 0x10 - final val sipush = 0x11 - final val ldc = 0x12 - final val ldc_w = 0x13 - final val ldc2_w = 0x14 - - final val iload = 0x15 - final val lload = 0x16 - final val fload = 0x17 - final val dload = 0x18 - final val aload = 0x19 - - final val iload_0 = 0x1a - final val iload_1 = 0x1b - final val iload_2 = 0x1c - final val iload_3 = 0x1d - final val lload_0 = 0x1e - final val lload_1 = 0x1f - final val lload_2 = 0x20 - final val lload_3 = 0x21 - final val fload_0 = 0x22 - final val fload_1 = 0x23 - final val fload_2 = 0x24 - final val fload_3 = 0x25 - final val dload_0 = 0x26 - final val dload_1 = 0x27 - final val dload_2 = 0x28 - final val dload_3 = 0x29 - final val aload_0 = 0x2a - final val aload_1 = 0x2b - final val aload_2 = 0x2c - final val aload_3 = 0x2d - final val iaload = 0x2e - final val laload = 0x2f - final val faload = 0x30 - final val daload = 0x31 - final val aaload = 0x32 - final val baload = 0x33 - final val caload = 0x34 - final val saload = 0x35 - - final val istore = 0x36 - final val lstore = 0x37 - final val fstore = 0x38 - final val dstore = 0x39 - final val astore = 0x3a - final val istore_0 = 0x3b - final val istore_1 = 0x3c - final val istore_2 = 0x3d - final val istore_3 = 0x3e - final val lstore_0 = 0x3f - final val lstore_1 = 0x40 - final val lstore_2 = 0x41 - final val lstore_3 = 0x42 - final val fstore_0 = 0x43 - final val fstore_1 = 0x44 - final val fstore_2 = 0x45 - final val fstore_3 = 0x46 - final val dstore_0 = 0x47 - final val dstore_1 = 0x48 - final val dstore_2 = 0x49 - final val dstore_3 = 0x4a - final val astore_0 = 0x4b - final val astore_1 = 0x4c - final val astore_2 = 0x4d - final val astore_3 = 0x4e - final val iastore = 0x4f - final val lastore = 0x50 - final val fastore = 0x51 - final val dastore = 0x52 - final val aastore = 0x53 - final val bastore = 0x54 - final val castore = 0x55 - final val sastore = 0x56 - - final val pop = 0x57 - final val pop2 = 0x58 - final val dup = 0x59 - final val dup_x1 = 0x5a - final val dup_x2 = 0x5b - final val dup2 = 0x5c - final val dup2_x1 = 0x5d - final val dup2_x2 = 0x5e - final val swap = 0x5f - - final val iadd = 0x60 - final val ladd = 0x61 - final val fadd = 0x62 - final val dadd = 0x63 - final val isub = 0x64 - final val lsub = 0x65 - final val fsub = 0x66 - final val dsub = 0x67 - final val imul = 0x68 - final val lmul = 0x69 - final val fmul = 0x6a - final val dmul = 0x6b - final val idiv = 0x6c - final val ldiv = 0x6d - final val fdiv = 0x6e - final val ddiv = 0x6f - final val irem = 0x70 - final val lrem = 0x71 - final val frem = 0x72 - final val drem = 0x73 - - final val ineg = 0x74 - final val lneg = 0x75 - final val fneg = 0x76 - final val dneg = 0x77 - - final val ishl = 0x78 - final val lshl = 0x79 - final val ishr = 0x7a - final val lshr = 0x7b - final val iushr = 0x7c - final val lushr = 0x7d - final val iand = 0x7e - final val land = 0x7f - final val ior = 0x80 - final val lor = 0x81 - final val ixor = 0x82 - final val lxor = 0x83 - final val iinc = 0x84 - - final val i2l = 0x85 - final val i2f = 0x86 - final val i2d = 0x87 - final val l2i = 0x88 - final val l2f = 0x89 - final val l2d = 0x8a - final val f2i = 0x8b - final val f2l = 0x8c - final val f2d = 0x8d - final val d2i = 0x8e - final val d2l = 0x8f - final val d2f = 0x90 - final val i2b = 0x91 - final val i2c = 0x92 - final val i2s = 0x93 - - final val lcmp = 0x94 - final val fcmpl = 0x95 - final val fcmpg = 0x96 - final val dcmpl = 0x97 - final val dcmpg = 0x98 - - final val ifeq = 0x99 - final val ifne = 0x9a - final val iflt = 0x9b - final val ifge = 0x9c - final val ifgt = 0x9d - final val ifle = 0x9e - final val if_icmpeq = 0x9f - final val if_icmpne = 0xa0 - final val if_icmplt = 0xa1 - final val if_icmpge = 0xa2 - final val if_icmpgt = 0xa3 - final val if_icmple = 0xa4 - final val if_acmpeq = 0xa5 - final val if_acmpne = 0xa6 - final val goto = 0xa7 - final val jsr = 0xa8 - final val ret = 0xa9 - final val tableswitch = 0xaa - final val lookupswitch = 0xab - final val ireturn = 0xac - final val lreturn = 0xad - final val freturn = 0xae - final val dreturn = 0xaf - final val areturn = 0xb0 - final val return_ = 0xb1 - - final val getstatic = 0xb2 - final val putstatic = 0xb3 - final val getfield = 0xb4 - final val putfield = 0xb5 - - final val invokevirtual = 0xb6 - final val invokespecial = 0xb7 - final val invokestatic = 0xb8 - final val invokeinterface = 0xb9 - final val xxxunusedxxxx = 0xba - - final val new_ = 0xbb - final val newarray = 0xbc - final val anewarray = 0xbd - final val arraylength = 0xbe - final val athrow = 0xbf - final val checkcast = 0xc0 - final val instanceof = 0xc1 - final val monitorenter = 0xc2 - final val monitorexit = 0xc3 - final val wide = 0xc4 - final val multianewarray = 0xc5 - final val ifnull = 0xc6 - final val ifnonnull = 0xc7 - final val goto_w = 0xc8 - final val jsr_w = 0xc9 - - // reserved opcodes - final val breakpoint = 0xca - final val impdep1 = 0xfe - final val impdep2 = 0xff - - abstract class FlagTranslation { - import Flags._ - - private var isAnnotation = false - private var isClass = false - private def initFields(flags: Int) = { - isAnnotation = (flags & JAVA_ACC_ANNOTATION) != 0 - isClass = false - } - private def translateFlag(jflag: Int): Long = (jflag: @switch) match { - case JAVA_ACC_PRIVATE => PRIVATE - case JAVA_ACC_PROTECTED => PROTECTED - case JAVA_ACC_FINAL => FINAL - case JAVA_ACC_SYNTHETIC => SYNTHETIC - case JAVA_ACC_STATIC => STATIC - case JAVA_ACC_ABSTRACT => if (isAnnotation) 0L else if (isClass) ABSTRACT else DEFERRED - case JAVA_ACC_INTERFACE => if (isAnnotation) 0L else TRAIT | INTERFACE | ABSTRACT - case _ => 0L - } - private def translateFlags(jflags: Int, baseFlags: Long): Long = { - var res: Long = JAVA | baseFlags - /** fast, elegant, maintainable, pick any two... */ - res |= translateFlag(jflags & JAVA_ACC_PRIVATE) - res |= translateFlag(jflags & JAVA_ACC_PROTECTED) - res |= translateFlag(jflags & JAVA_ACC_FINAL) - res |= translateFlag(jflags & JAVA_ACC_SYNTHETIC) - res |= translateFlag(jflags & JAVA_ACC_STATIC) - res |= translateFlag(jflags & JAVA_ACC_ABSTRACT) - res |= translateFlag(jflags & JAVA_ACC_INTERFACE) - res - } - - def classFlags(jflags: Int): Long = { - initFields(jflags) - isClass = true - translateFlags(jflags, 0) - } - def fieldFlags(jflags: Int): Long = { - initFields(jflags) - translateFlags(jflags, if ((jflags & JAVA_ACC_FINAL) == 0) MUTABLE else 0) - } - def methodFlags(jflags: Int): Long = { - initFields(jflags) - translateFlags(jflags, if ((jflags & JAVA_ACC_BRIDGE) != 0) BRIDGE else 0) - } - } - object FlagTranslation extends FlagTranslation { } - - def toScalaMethodFlags(flags: Int): Long = FlagTranslation methodFlags flags - def toScalaClassFlags(flags: Int): Long = FlagTranslation classFlags flags - def toScalaFieldFlags(flags: Int): Long = FlagTranslation fieldFlags flags - - @deprecated("Use another method in this object", "2.10.0") - def toScalaFlags(flags: Int, isClass: Boolean = false, isField: Boolean = false): Long = ( - if (isClass) toScalaClassFlags(flags) - else if (isField) toScalaFieldFlags(flags) - else toScalaMethodFlags(flags) - ) -} diff --git a/src/compiler/scala/reflect/internal/Constants.scala b/src/compiler/scala/reflect/internal/Constants.scala deleted file mode 100644 index 820dfe0868..0000000000 --- a/src/compiler/scala/reflect/internal/Constants.scala +++ /dev/null @@ -1,240 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.reflect -package internal - -import java.lang.Integer.toOctalString -import annotation.switch - -trait Constants extends api.Constants { - self: SymbolTable => - - import definitions._ - - final val NoTag = 0 - final val UnitTag = 1 - final val BooleanTag = 2 - final val ByteTag = 3 - final val ShortTag = 4 - final val CharTag = 5 - final val IntTag = 6 - final val LongTag = 7 - final val FloatTag = 8 - final val DoubleTag = 9 - final val StringTag = 10 - final val NullTag = 11 - final val ClazzTag = 12 - // For supporting java enumerations inside java annotations (see ClassfileParser) - final val EnumTag = 13 - - case class Constant(value: Any) extends ConstantApi { - val tag: Int = value match { - case null => NullTag - case x: Unit => UnitTag - case x: Boolean => BooleanTag - case x: Byte => ByteTag - case x: Short => ShortTag - case x: Int => IntTag - case x: Long => LongTag - case x: Float => FloatTag - case x: Double => DoubleTag - case x: String => StringTag - case x: Char => CharTag - case x: Type => ClazzTag - case x: Symbol => EnumTag - case _ => throw new Error("bad constant value: " + value + " of class " + value.getClass) - } - - def isByteRange: Boolean = isIntRange && Byte.MinValue <= intValue && intValue <= Byte.MaxValue - def isShortRange: Boolean = isIntRange && Short.MinValue <= intValue && intValue <= Short.MaxValue - def isCharRange: Boolean = isIntRange && Char.MinValue <= intValue && intValue <= Char.MaxValue - def isIntRange: Boolean = ByteTag <= tag && tag <= IntTag - def isLongRange: Boolean = ByteTag <= tag && tag <= LongTag - def isFloatRange: Boolean = ByteTag <= tag && tag <= FloatTag - def isNumeric: Boolean = ByteTag <= tag && tag <= DoubleTag - def isNonUnitAnyVal = BooleanTag <= tag && tag <= DoubleTag - def isAnyVal = UnitTag <= tag && tag <= DoubleTag - - def tpe: Type = tag match { - case UnitTag => UnitClass.tpe - case BooleanTag => BooleanClass.tpe - case ByteTag => ByteClass.tpe - case ShortTag => ShortClass.tpe - case CharTag => CharClass.tpe - case IntTag => IntClass.tpe - case LongTag => LongClass.tpe - case FloatTag => FloatClass.tpe - case DoubleTag => DoubleClass.tpe - case StringTag => StringClass.tpe - case NullTag => NullClass.tpe - case ClazzTag => ClassType(value.asInstanceOf[Type]) - case EnumTag => - // given (in java): "class A { enum E { VAL1 } }" - // - symbolValue: the symbol of the actual enumeration value (VAL1) - // - .owner: the ModuleClasSymbol of the enumeration (object E) - // - .linkedClassOfClass: the ClassSymbol of the enumeration (class E) - symbolValue.owner.linkedClassOfClass.tpe - } - - /** We need the equals method to take account of tags as well as values. - */ - override def equals(other: Any): Boolean = other match { - case that: Constant => - this.tag == that.tag && - (this.value == that.value || this.isNaN && that.isNaN) - case _ => false - } - - def isNaN = value match { - case f: Float => f.isNaN - case d: Double => d.isNaN - case _ => false - } - - def booleanValue: Boolean = - if (tag == BooleanTag) value.asInstanceOf[Boolean] - else throw new Error("value " + value + " is not a boolean"); - - def byteValue: Byte = tag match { - case ByteTag => value.asInstanceOf[Byte] - case ShortTag => value.asInstanceOf[Short].toByte - case CharTag => value.asInstanceOf[Char].toByte - case IntTag => value.asInstanceOf[Int].toByte - case LongTag => value.asInstanceOf[Long].toByte - case FloatTag => value.asInstanceOf[Float].toByte - case DoubleTag => value.asInstanceOf[Double].toByte - case _ => throw new Error("value " + value + " is not a Byte") - } - - def shortValue: Short = tag match { - case ByteTag => value.asInstanceOf[Byte].toShort - case ShortTag => value.asInstanceOf[Short] - case CharTag => value.asInstanceOf[Char].toShort - case IntTag => value.asInstanceOf[Int].toShort - case LongTag => value.asInstanceOf[Long].toShort - case FloatTag => value.asInstanceOf[Float].toShort - case DoubleTag => value.asInstanceOf[Double].toShort - case _ => throw new Error("value " + value + " is not a Short") - } - - def charValue: Char = tag match { - case ByteTag => value.asInstanceOf[Byte].toChar - case ShortTag => value.asInstanceOf[Short].toChar - case CharTag => value.asInstanceOf[Char] - case IntTag => value.asInstanceOf[Int].toChar - case LongTag => value.asInstanceOf[Long].toChar - case FloatTag => value.asInstanceOf[Float].toChar - case DoubleTag => value.asInstanceOf[Double].toChar - case _ => throw new Error("value " + value + " is not a Char") - } - - def intValue: Int = tag match { - case ByteTag => value.asInstanceOf[Byte].toInt - case ShortTag => value.asInstanceOf[Short].toInt - case CharTag => value.asInstanceOf[Char].toInt - case IntTag => value.asInstanceOf[Int] - case LongTag => value.asInstanceOf[Long].toInt - case FloatTag => value.asInstanceOf[Float].toInt - case DoubleTag => value.asInstanceOf[Double].toInt - case _ => throw new Error("value " + value + " is not an Int") - } - - def longValue: Long = tag match { - case ByteTag => value.asInstanceOf[Byte].toLong - case ShortTag => value.asInstanceOf[Short].toLong - case CharTag => value.asInstanceOf[Char].toLong - case IntTag => value.asInstanceOf[Int].toLong - case LongTag => value.asInstanceOf[Long] - case FloatTag => value.asInstanceOf[Float].toLong - case DoubleTag => value.asInstanceOf[Double].toLong - case _ => throw new Error("value " + value + " is not a Long") - } - - def floatValue: Float = tag match { - case ByteTag => value.asInstanceOf[Byte].toFloat - case ShortTag => value.asInstanceOf[Short].toFloat - case CharTag => value.asInstanceOf[Char].toFloat - case IntTag => value.asInstanceOf[Int].toFloat - case LongTag => value.asInstanceOf[Long].toFloat - case FloatTag => value.asInstanceOf[Float] - case DoubleTag => value.asInstanceOf[Double].toFloat - case _ => throw new Error("value " + value + " is not a Float") - } - - def doubleValue: Double = tag match { - case ByteTag => value.asInstanceOf[Byte].toDouble - case ShortTag => value.asInstanceOf[Short].toDouble - case CharTag => value.asInstanceOf[Char].toDouble - case IntTag => value.asInstanceOf[Int].toDouble - case LongTag => value.asInstanceOf[Long].toDouble - case FloatTag => value.asInstanceOf[Float].toDouble - case DoubleTag => value.asInstanceOf[Double] - case _ => throw new Error("value " + value + " is not a Double") - } - - /** Convert constant value to conform to given type. - */ - def convertTo(pt: Type): Constant = { - val target = pt.typeSymbol - if (target == tpe.typeSymbol) - this - else if (target == ByteClass && isByteRange) - Constant(byteValue) - else if (target == ShortClass && isShortRange) - Constant(shortValue) - else if (target == CharClass && isCharRange) - Constant(charValue) - else if (target == IntClass && isIntRange) - Constant(intValue) - else if (target == LongClass && isLongRange) - Constant(longValue) - else if (target == FloatClass && isFloatRange) - Constant(floatValue) - else if (target == DoubleClass && isNumeric) - Constant(doubleValue) - else - null - } - - def stringValue: String = - if (value == null) "null" - else if (tag == ClazzTag) signature(typeValue) - else value.toString() - - @switch def escapedChar(ch: Char): String = ch match { - case '\b' => "\\b" - case '\t' => "\\t" - case '\n' => "\\n" - case '\f' => "\\f" - case '\r' => "\\r" - case '"' => "\\\"" - case '\'' => "\\\'" - case '\\' => "\\\\" - case _ => if (ch.isControl) "\\0" + toOctalString(ch) else String.valueOf(ch) - } - - def escapedStringValue: String = { - def escape(text: String): String = text flatMap escapedChar - tag match { - case NullTag => "null" - case StringTag => "\"" + escape(stringValue) + "\"" - case ClazzTag => "classOf[" + signature(typeValue) + "]" - case CharTag => "'" + escapedChar(charValue) + "'" - case LongTag => longValue.toString() + "L" - case EnumTag => symbolValue.name.toString() - case _ => String.valueOf(value) - } - } - def typeValue: Type = value.asInstanceOf[Type] - def symbolValue: Symbol = value.asInstanceOf[Symbol] - - override def hashCode: Int = value.## * 41 + 17 - } - - object Constant extends ConstantExtractor - - implicit val ConstantTag = ClassTag[Constant](classOf[Constant]) -} diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala deleted file mode 100644 index d55b38224d..0000000000 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ /dev/null @@ -1,1241 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.reflect -package internal - -import annotation.{ switch, meta } -import scala.collection.{ mutable, immutable } -import Flags._ -import PartialFunction._ -import scala.reflect.base.{Universe => BaseUniverse} - -trait Definitions extends api.StandardDefinitions { - self: SymbolTable => - - import rootMirror.{getModule, getClassByName, getRequiredClass, getRequiredModule, getRequiredPackage, getClassIfDefined, getModuleIfDefined, getPackageObject, getPackageObjectIfDefined, requiredClass, requiredModule} - - object definitions extends DefinitionsClass - - // [Eugene] find a way to make these non-lazy - lazy val ByteTpe = definitions.ByteClass.asType - lazy val ShortTpe = definitions.ShortClass.asType - lazy val CharTpe = definitions.CharClass.asType - lazy val IntTpe = definitions.IntClass.asType - lazy val LongTpe = definitions.LongClass.asType - lazy val FloatTpe = definitions.FloatClass.asType - lazy val DoubleTpe = definitions.DoubleClass.asType - lazy val BooleanTpe = definitions.BooleanClass.asType - lazy val UnitTpe = definitions.UnitClass.asType - lazy val AnyTpe = definitions.AnyClass.asType - lazy val ObjectTpe = definitions.ObjectClass.asType - lazy val AnyValTpe = definitions.AnyValClass.asType - lazy val AnyRefTpe = definitions.AnyRefClass.asType - lazy val NothingTpe = definitions.NothingClass.asType - lazy val NullTpe = definitions.NullClass.asType - lazy val StringTpe = definitions.StringClass.asType - - /** Since both the value parameter types and the result type may - * require access to the type parameter symbols, we model polymorphic - * creation as a function from those symbols to (formal types, result type). - * The Option is to distinguish between nullary methods and empty-param-list - * methods. - */ - private type PolyMethodCreator = List[Symbol] => (Option[List[Type]], Type) - - private def enterNewClass(owner: Symbol, name: TypeName, parents: List[Type], flags: Long = 0L): ClassSymbol = { - val clazz = owner.newClassSymbol(name, NoPosition, flags) - clazz setInfoAndEnter ClassInfoType(parents, newScope, clazz) - } - private def newMethod(owner: Symbol, name: TermName, formals: List[Type], restpe: Type, flags: Long = 0L): MethodSymbol = { - val msym = owner.newMethod(name.encode, NoPosition, flags) - val params = msym.newSyntheticValueParams(formals) - msym setInfo MethodType(params, restpe) - } - private def enterNewMethod(owner: Symbol, name: TermName, formals: List[Type], restpe: Type, flags: Long = 0L): MethodSymbol = - owner.info.decls enter newMethod(owner, name, formals, restpe, flags) - - // the scala value classes - trait ValueClassDefinitions { - self: DefinitionsClass => - - import ClassfileConstants._ - - private val nameToWeight = Map[Name, Int]( - tpnme.Byte -> 2, - tpnme.Char -> 3, - tpnme.Short -> 4, - tpnme.Int -> 12, - tpnme.Long -> 24, - tpnme.Float -> 48, - tpnme.Double -> 96 - ) - - private val nameToTag = Map[Name, Char]( - tpnme.Byte -> BYTE_TAG, - tpnme.Char -> CHAR_TAG, - tpnme.Short -> SHORT_TAG, - tpnme.Int -> INT_TAG, - tpnme.Long -> LONG_TAG, - tpnme.Float -> FLOAT_TAG, - tpnme.Double -> DOUBLE_TAG, - tpnme.Boolean -> BOOL_TAG, - tpnme.Unit -> VOID_TAG - ) - - private def catastrophicFailure() = - abort("Could not find value classes! This is a catastrophic failure. scala " + - scala.util.Properties.versionString) - - private def valueClassSymbol(name: TypeName): ClassSymbol = { - getMember(ScalaPackageClass, name) match { - case x: ClassSymbol => x - case _ => catastrophicFailure() - } - } - private def valueClassCompanion(name: TermName): ModuleSymbol = { - getMember(ScalaPackageClass, name) match { - case x: ModuleSymbol => x - case _ => catastrophicFailure() - } - } - private def valueCompanionMember(className: Name, methodName: TermName): TermSymbol = - getMemberMethod(valueClassCompanion(className.toTermName).moduleClass, methodName) - - private def classesMap[T](f: Name => T) = symbolsMap(ScalaValueClassesNoUnit, f) - private def symbolsMap[T](syms: List[Symbol], f: Name => T): Map[Symbol, T] = mapFrom(syms)(x => f(x.name)) - private def symbolsMapFilt[T](syms: List[Symbol], p: Name => Boolean, f: Name => T) = symbolsMap(syms filter (x => p(x.name)), f) - - private def boxedName(name: Name) = sn.Boxed(name.toTypeName) - - lazy val abbrvTag = symbolsMap(ScalaValueClasses, nameToTag) withDefaultValue OBJECT_TAG - lazy val numericWeight = symbolsMapFilt(ScalaValueClasses, nameToWeight.keySet, nameToWeight) - lazy val boxedModule = classesMap(x => getModule(boxedName(x))) - lazy val boxedClass = classesMap(x => getClassByName(boxedName(x))) - lazy val refClass = classesMap(x => getRequiredClass("scala.runtime." + x + "Ref")) - lazy val volatileRefClass = classesMap(x => getRequiredClass("scala.runtime.Volatile" + x + "Ref")) - lazy val boxMethod = classesMap(x => valueCompanionMember(x, nme.box)) - lazy val unboxMethod = classesMap(x => valueCompanionMember(x, nme.unbox)) - - def isNumericSubClass(sub: Symbol, sup: Symbol) = ( - (numericWeight contains sub) - && (numericWeight contains sup) - && (numericWeight(sup) % numericWeight(sub) == 0) - ) - - /** Is symbol a numeric value class? */ - def isNumericValueClass(sym: Symbol) = ScalaNumericValueClasses contains sym - - def isGetClass(sym: Symbol) = - (sym.name == nme.getClass_) && flattensToEmpty(sym.paramss) - - lazy val UnitClass = valueClassSymbol(tpnme.Unit) - lazy val ByteClass = valueClassSymbol(tpnme.Byte) - lazy val ShortClass = valueClassSymbol(tpnme.Short) - lazy val CharClass = valueClassSymbol(tpnme.Char) - lazy val IntClass = valueClassSymbol(tpnme.Int) - lazy val LongClass = valueClassSymbol(tpnme.Long) - lazy val FloatClass = valueClassSymbol(tpnme.Float) - lazy val DoubleClass = valueClassSymbol(tpnme.Double) - lazy val BooleanClass = valueClassSymbol(tpnme.Boolean) - lazy val Boolean_and = getMemberMethod(BooleanClass, nme.ZAND) - lazy val Boolean_or = getMemberMethod(BooleanClass, nme.ZOR) - lazy val Boolean_not = getMemberMethod(BooleanClass, nme.UNARY_!) - - lazy val ScalaNumericValueClasses = ScalaValueClasses filterNot Set[Symbol](UnitClass, BooleanClass) - - def ScalaValueClassesNoUnit = ScalaValueClasses filterNot (_ eq UnitClass) - def ScalaValueClasses: List[ClassSymbol] = List( - UnitClass, - BooleanClass, - ByteClass, - ShortClass, - CharClass, - IntClass, - LongClass, - FloatClass, - DoubleClass - ) - def ScalaValueClassCompanions: List[Symbol] = ScalaValueClasses map (_.companionSymbol) - def ScalaPrimitiveValueClasses: List[ClassSymbol] = ScalaValueClasses - } - - abstract class DefinitionsClass extends DefinitionsApi with ValueClassDefinitions { - private var isInitialized = false - def isDefinitionsInitialized = isInitialized - - // symbols related to packages - var emptypackagescope: Scope = null //debug - - // It becomes tricky to create dedicated objects for other symbols because - // of initialization order issues. - lazy val JavaLangPackage = getRequiredPackage(sn.JavaLang) - lazy val JavaLangPackageClass = JavaLangPackage.moduleClass.asClassSymbol - lazy val ScalaPackage = getRequiredPackage(nme.scala_) - lazy val ScalaPackageClass = ScalaPackage.moduleClass.asClassSymbol - lazy val RuntimePackage = getRequiredPackage("scala.runtime") - lazy val RuntimePackageClass = RuntimePackage.moduleClass.asClassSymbol - - lazy val JavaLangEnumClass = requiredClass[java.lang.Enum[_]] - - // convenient one-argument parameter lists - lazy val anyparam = List(AnyClass.tpe) - lazy val anyvalparam = List(AnyValClass.typeConstructor) - lazy val anyrefparam = List(AnyRefClass.typeConstructor) - - // private parameter conveniences - private def booltype = BooleanClass.tpe - private def inttype = IntClass.tpe - private def stringtype = StringClass.tpe - - def javaTypeToValueClass(jtype: Class[_]): Symbol = jtype match { - case java.lang.Void.TYPE => UnitClass - case java.lang.Byte.TYPE => ByteClass - case java.lang.Character.TYPE => CharClass - case java.lang.Short.TYPE => ShortClass - case java.lang.Integer.TYPE => IntClass - case java.lang.Long.TYPE => LongClass - case java.lang.Float.TYPE => FloatClass - case java.lang.Double.TYPE => DoubleClass - case java.lang.Boolean.TYPE => BooleanClass - case _ => NoSymbol - } - def valueClassToJavaType(sym: Symbol): Class[_] = sym match { - case UnitClass => java.lang.Void.TYPE - case ByteClass => java.lang.Byte.TYPE - case CharClass => java.lang.Character.TYPE - case ShortClass => java.lang.Short.TYPE - case IntClass => java.lang.Integer.TYPE - case LongClass => java.lang.Long.TYPE - case FloatClass => java.lang.Float.TYPE - case DoubleClass => java.lang.Double.TYPE - case BooleanClass => java.lang.Boolean.TYPE - case _ => null - } - - private def fixupAsAnyTrait(tpe: Type): Type = tpe match { - case ClassInfoType(parents, decls, clazz) => - if (parents.head.typeSymbol == AnyClass) tpe - else { - assert(parents.head.typeSymbol == ObjectClass, parents) - ClassInfoType(AnyClass.tpe :: parents.tail, decls, clazz) - } - case PolyType(tparams, restpe) => - PolyType(tparams, fixupAsAnyTrait(restpe)) -// case _ => tpe - } - - // top types - lazy val AnyClass = enterNewClass(ScalaPackageClass, tpnme.Any, Nil, ABSTRACT) - lazy val AnyRefClass = newAlias(ScalaPackageClass, tpnme.AnyRef, ObjectClass.tpe) - lazy val ObjectClass = getRequiredClass(sn.Object.toString) - - // Note: this is not the type alias AnyRef, it's a companion-like - // object used by the @specialize annotation. - lazy val AnyRefModule = getMemberModule(ScalaPackageClass, nme.AnyRef) - @deprecated("Use AnyRefModule", "2.10.0") - def Predef_AnyRef = AnyRefModule - - lazy val AnyValClass: ClassSymbol = (ScalaPackageClass.info member tpnme.AnyVal orElse { - val anyval = enterNewClass(ScalaPackageClass, tpnme.AnyVal, List(AnyClass.tpe, NotNullClass.tpe), ABSTRACT) - val av_constr = anyval.newClassConstructor(NoPosition) - anyval.info.decls enter av_constr - anyval - }).asInstanceOf[ClassSymbol] - - // bottom types - lazy val RuntimeNothingClass = getClassByName(fulltpnme.RuntimeNothing) - lazy val RuntimeNullClass = getClassByName(fulltpnme.RuntimeNull) - - sealed abstract class BottomClassSymbol(name: TypeName, parent: Symbol) extends ClassSymbol(ScalaPackageClass, NoPosition, name) { - locally { - this initFlags ABSTRACT | FINAL - this setInfoAndEnter ClassInfoType(List(parent.tpe), newScope, this) - } - final override def isBottomClass = true - } - final object NothingClass extends BottomClassSymbol(tpnme.Nothing, AnyClass) { - override def isSubClass(that: Symbol) = true - } - final object NullClass extends BottomClassSymbol(tpnme.Null, AnyRefClass) { - override def isSubClass(that: Symbol) = ( - (that eq AnyClass) - || (that ne NothingClass) && (that isSubClass ObjectClass) - ) - } - - // exceptions and other throwables - lazy val ClassCastExceptionClass = requiredClass[ClassCastException] - lazy val IndexOutOfBoundsExceptionClass = getClassByName(sn.IOOBException) - lazy val InvocationTargetExceptionClass = getClassByName(sn.InvTargetException) - lazy val MatchErrorClass = requiredClass[MatchError] - lazy val NonLocalReturnControlClass = requiredClass[scala.runtime.NonLocalReturnControl[_]] - lazy val NullPointerExceptionClass = getClassByName(sn.NPException) - lazy val ThrowableClass = getClassByName(sn.Throwable) - lazy val UninitializedErrorClass = requiredClass[UninitializedFieldError] - - // fundamental reference classes - lazy val PartialFunctionClass = requiredClass[PartialFunction[_,_]] - lazy val AbstractPartialFunctionClass = requiredClass[scala.runtime.AbstractPartialFunction[_,_]] - lazy val SymbolClass = requiredClass[scala.Symbol] - lazy val StringClass = requiredClass[java.lang.String] - lazy val StringModule = StringClass.linkedClassOfClass - lazy val ClassClass = requiredClass[java.lang.Class[_]] - def Class_getMethod = getMemberMethod(ClassClass, nme.getMethod_) - lazy val DynamicClass = requiredClass[Dynamic] - - // fundamental modules - lazy val SysPackage = getPackageObject("scala.sys") - def Sys_error = getMemberMethod(SysPackage, nme.error) - - // Modules whose members are in the default namespace - // [Eugene++] ScalaPackage and JavaLangPackage are never ever shared between mirrors - // as a result, `Int` becomes `scala.Int` and `String` becomes `java.lang.String` - // I could just change `isOmittablePrefix`, but there's more to it, so I'm leaving this as a todo for now - lazy val UnqualifiedModules = List(PredefModule, ScalaPackage, JavaLangPackage) - // Those modules and their module classes - lazy val UnqualifiedOwners = UnqualifiedModules.toSet ++ UnqualifiedModules.map(_.moduleClass) - - lazy val PredefModule = requiredModule[scala.Predef.type] - lazy val PredefModuleClass = PredefModule.moduleClass - - def Predef_classOf = getMemberMethod(PredefModule, nme.classOf) - def Predef_identity = getMemberMethod(PredefModule, nme.identity) - def Predef_conforms = getMemberMethod(PredefModule, nme.conforms) - def Predef_wrapRefArray = getMemberMethod(PredefModule, nme.wrapRefArray) - def Predef_??? = getMemberMethod(PredefModule, nme.???) - def Predef_implicitly = getMemberMethod(PredefModule, nme.implicitly) - - /** Is `sym` a member of Predef with the given name? - * Note: DON't replace this by sym == Predef_conforms/etc, as Predef_conforms is a `def` - * which does a member lookup (it can't be a lazy val because we might reload Predef - * during resident compilations). - */ - def isPredefMemberNamed(sym: Symbol, name: Name) = ( - (sym.name == name) && (sym.owner == PredefModule.moduleClass) - ) - - /** Specialization. - */ - lazy val SpecializableModule = requiredModule[Specializable] - lazy val GroupOfSpecializable = getMemberClass(SpecializableModule, tpnme.Group) - - lazy val ConsoleModule = requiredModule[scala.Console.type] - lazy val ScalaRunTimeModule = requiredModule[scala.runtime.ScalaRunTime.type] - lazy val SymbolModule = requiredModule[scala.Symbol.type] - lazy val Symbol_apply = getMemberMethod(SymbolModule, nme.apply) - - def SeqFactory = getMember(ScalaRunTimeModule, nme.Seq) // [Eugene++] obsolete? - def arrayApplyMethod = getMemberMethod(ScalaRunTimeModule, nme.array_apply) - def arrayUpdateMethod = getMemberMethod(ScalaRunTimeModule, nme.array_update) - def arrayLengthMethod = getMemberMethod(ScalaRunTimeModule, nme.array_length) - def arrayCloneMethod = getMemberMethod(ScalaRunTimeModule, nme.array_clone) - def ensureAccessibleMethod = getMemberMethod(ScalaRunTimeModule, nme.ensureAccessible) - def scalaRuntimeSameElements = getMemberMethod(ScalaRunTimeModule, nme.sameElements) - def arrayClassMethod = getMemberMethod(ScalaRunTimeModule, nme.arrayClass) - def arrayElementClassMethod = getMemberMethod(ScalaRunTimeModule, nme.arrayElementClass) - - // classes with special meanings - lazy val StringAddClass = requiredClass[scala.runtime.StringAdd] - lazy val ArrowAssocClass = getRequiredClass("scala.Predef.ArrowAssoc") // SI-5731 - lazy val StringAdd_+ = getMemberMethod(StringAddClass, nme.PLUS) - lazy val NotNullClass = getRequiredClass("scala.NotNull") - lazy val ScalaNumberClass = requiredClass[scala.math.ScalaNumber] - lazy val TraitSetterAnnotationClass = requiredClass[scala.runtime.TraitSetter] - lazy val DelayedInitClass = requiredClass[scala.DelayedInit] - def delayedInitMethod = getMemberMethod(DelayedInitClass, nme.delayedInit) - // a dummy value that communicates that a delayedInit call is compiler-generated - // from phase UnCurry to phase Constructors - // !!! This is not used anywhere (it was checked in that way.) - // def delayedInitArgVal = EmptyPackageClass.newValue(NoPosition, nme.delayedInitArg) - // .setInfo(UnitClass.tpe) - - lazy val TypeConstraintClass = requiredClass[scala.annotation.TypeConstraint] - lazy val SingletonClass = enterNewClass(ScalaPackageClass, tpnme.Singleton, anyparam, ABSTRACT | TRAIT | FINAL) - lazy val SerializableClass = requiredClass[scala.Serializable] - lazy val JavaSerializableClass = requiredClass[java.io.Serializable] modifyInfo fixupAsAnyTrait - lazy val ComparableClass = requiredClass[java.lang.Comparable[_]] modifyInfo fixupAsAnyTrait - lazy val JavaCloneableClass = requiredClass[java.lang.Cloneable] - lazy val JavaNumberClass = requiredClass[java.lang.Number] - lazy val RemoteInterfaceClass = requiredClass[java.rmi.Remote] - lazy val RemoteExceptionClass = requiredClass[java.rmi.RemoteException] - - lazy val ByNameParamClass = specialPolyClass(tpnme.BYNAME_PARAM_CLASS_NAME, COVARIANT)(_ => AnyClass.tpe) - lazy val EqualsPatternClass = specialPolyClass(tpnme.EQUALS_PATTERN_NAME, 0L)(_ => AnyClass.tpe) - lazy val JavaRepeatedParamClass = specialPolyClass(tpnme.JAVA_REPEATED_PARAM_CLASS_NAME, COVARIANT)(tparam => arrayType(tparam.tpe)) - lazy val RepeatedParamClass = specialPolyClass(tpnme.REPEATED_PARAM_CLASS_NAME, COVARIANT)(tparam => seqType(tparam.tpe)) - - def isByNameParamType(tp: Type) = tp.typeSymbol == ByNameParamClass - def isScalaRepeatedParamType(tp: Type) = tp.typeSymbol == RepeatedParamClass - def isJavaRepeatedParamType(tp: Type) = tp.typeSymbol == JavaRepeatedParamClass - def isRepeatedParamType(tp: Type) = isScalaRepeatedParamType(tp) || isJavaRepeatedParamType(tp) - def isCastSymbol(sym: Symbol) = sym == Any_asInstanceOf || sym == Object_asInstanceOf - - def isJavaVarArgsMethod(m: Symbol) = m.isMethod && isJavaVarArgs(m.info.params) - def isJavaVarArgs(params: Seq[Symbol]) = params.nonEmpty && isJavaRepeatedParamType(params.last.tpe) - def isScalaVarArgs(params: Seq[Symbol]) = params.nonEmpty && isScalaRepeatedParamType(params.last.tpe) - def isVarArgsList(params: Seq[Symbol]) = params.nonEmpty && isRepeatedParamType(params.last.tpe) - def isVarArgTypes(formals: Seq[Type]) = formals.nonEmpty && isRepeatedParamType(formals.last) - - def hasRepeatedParam(tp: Type): Boolean = tp match { - case MethodType(formals, restpe) => isScalaVarArgs(formals) || hasRepeatedParam(restpe) - case PolyType(_, restpe) => hasRepeatedParam(restpe) - case _ => false - } - - def isPrimitiveArray(tp: Type) = tp match { - case TypeRef(_, ArrayClass, arg :: Nil) => isPrimitiveValueClass(arg.typeSymbol) - case _ => false - } - def isReferenceArray(tp: Type) = tp match { - case TypeRef(_, ArrayClass, arg :: Nil) => arg <:< AnyRefClass.tpe - case _ => false - } - def isArrayOfSymbol(tp: Type, elem: Symbol) = tp match { - case TypeRef(_, ArrayClass, arg :: Nil) => arg.typeSymbol == elem - case _ => false - } - - lazy val MatchingStrategyClass = getRequiredClass("scala.MatchingStrategy") - - // collections classes - lazy val ConsClass = requiredClass[scala.collection.immutable.::[_]] - lazy val IterableClass = requiredClass[scala.collection.Iterable[_]] - lazy val IteratorClass = requiredClass[scala.collection.Iterator[_]] - lazy val ListClass = requiredClass[scala.collection.immutable.List[_]] - lazy val SeqClass = requiredClass[scala.collection.Seq[_]] - lazy val StringBuilderClass = requiredClass[scala.collection.mutable.StringBuilder] - lazy val TraversableClass = requiredClass[scala.collection.Traversable[_]] - - lazy val ListModule = requiredModule[scala.collection.immutable.List.type] - lazy val List_apply = getMemberMethod(ListModule, nme.apply) - lazy val NilModule = requiredModule[scala.collection.immutable.Nil.type] - lazy val SeqModule = requiredModule[scala.collection.Seq.type] - lazy val IteratorModule = requiredModule[scala.collection.Iterator.type] - lazy val Iterator_apply = getMemberMethod(IteratorModule, nme.apply) - - // arrays and their members - lazy val ArrayModule = requiredModule[scala.Array.type] - lazy val ArrayModule_overloadedApply = getMemberMethod(ArrayModule, nme.apply) - lazy val ArrayClass = getRequiredClass("scala.Array") // requiredClass[scala.Array[_]] - lazy val Array_apply = getMemberMethod(ArrayClass, nme.apply) - lazy val Array_update = getMemberMethod(ArrayClass, nme.update) - lazy val Array_length = getMemberMethod(ArrayClass, nme.length) - lazy val Array_clone = getMemberMethod(ArrayClass, nme.clone_) - - // reflection / structural types - lazy val SoftReferenceClass = requiredClass[java.lang.ref.SoftReference[_]] - lazy val WeakReferenceClass = requiredClass[java.lang.ref.WeakReference[_]] - lazy val MethodClass = getClassByName(sn.MethodAsObject) - def methodClass_setAccessible = getMemberMethod(MethodClass, nme.setAccessible) - lazy val EmptyMethodCacheClass = requiredClass[scala.runtime.EmptyMethodCache] - lazy val MethodCacheClass = requiredClass[scala.runtime.MethodCache] - def methodCache_find = getMemberMethod(MethodCacheClass, nme.find_) - def methodCache_add = getMemberMethod(MethodCacheClass, nme.add_) - - // scala.reflect - lazy val ReflectPackage = requiredModule[scala.reflect.`package`.type] - def ReflectBasis = getMemberValue(ReflectPackage, nme.basis) - lazy val ReflectRuntimePackage = getPackageObjectIfDefined("scala.reflect.runtime") // defined in scala-reflect.jar, so we need to be careful - def ReflectRuntimeUniverse = if (ReflectRuntimePackage != NoSymbol) getMemberValue(ReflectRuntimePackage, nme.universe) else NoSymbol - def ReflectRuntimeCurrentMirror = if (ReflectRuntimePackage != NoSymbol) getMemberMethod(ReflectRuntimePackage, nme.currentMirror) else NoSymbol - - lazy val PartialManifestClass = requiredClass[scala.reflect.ClassManifest[_]] - lazy val PartialManifestModule = requiredModule[scala.reflect.ClassManifest.type] - lazy val FullManifestClass = requiredClass[scala.reflect.Manifest[_]] - lazy val FullManifestModule = requiredModule[scala.reflect.Manifest.type] - lazy val OptManifestClass = requiredClass[scala.reflect.OptManifest[_]] - lazy val NoManifest = requiredModule[scala.reflect.NoManifest.type] - - lazy val ExprsClass = getClassIfDefined("scala.reflect.api.Exprs") // defined in scala-reflect.jar, so we need to be careful - lazy val ExprClass = if (ExprsClass != NoSymbol) getMemberClass(ExprsClass, tpnme.Expr) else NoSymbol - def ExprSplice = if (ExprsClass != NoSymbol) getMemberMethod(ExprClass, nme.splice) else NoSymbol - def ExprValue = if (ExprsClass != NoSymbol) getMemberMethod(ExprClass, nme.value) else NoSymbol - lazy val ExprModule = if (ExprsClass != NoSymbol) getMemberModule(ExprsClass, nme.Expr) else NoSymbol - - lazy val ArrayTagClass = requiredClass[scala.reflect.ArrayTag[_]] - lazy val ClassTagModule = requiredModule[scala.reflect.ClassTag[_]] - lazy val ClassTagClass = requiredClass[scala.reflect.ClassTag[_]] - lazy val TypeTagsClass = requiredClass[scala.reflect.base.TypeTags] - lazy val TypeTagClass = getMemberClass(TypeTagsClass, tpnme.TypeTag) - lazy val TypeTagModule = getMemberModule(TypeTagsClass, nme.TypeTag) - lazy val ConcreteTypeTagClass = getMemberClass(TypeTagsClass, tpnme.ConcreteTypeTag) - lazy val ConcreteTypeTagModule = getMemberModule(TypeTagsClass, nme.ConcreteTypeTag) - - lazy val BaseUniverseClass = requiredClass[scala.reflect.base.Universe] - lazy val ApiUniverseClass = getClassIfDefined("scala.reflect.api.Universe") // defined in scala-reflect.jar, so we need to be careful - def ApiUniverseReify = if (ApiUniverseClass != NoSymbol) getMemberMethod(ApiUniverseClass, nme.reify) else NoSymbol - lazy val JavaUniverseClass = getClassIfDefined("scala.reflect.api.JavaUniverse") // defined in scala-reflect.jar, so we need to be careful - - lazy val MirrorOfClass = requiredClass[scala.reflect.base.MirrorOf[_]] - - lazy val TypeCreatorClass = requiredClass[scala.reflect.base.TypeCreator] - lazy val TreeCreatorClass = requiredClass[scala.reflect.base.TreeCreator] - - lazy val MacroContextClass = getClassIfDefined("scala.reflect.makro.Context") // defined in scala-reflect.jar, so we need to be careful - def MacroContextPrefix = if (MacroContextClass != NoSymbol) getMemberMethod(MacroContextClass, nme.prefix) else NoSymbol - def MacroContextPrefixType = if (MacroContextClass != NoSymbol) getMemberType(MacroContextClass, tpnme.PrefixType) else NoSymbol - def MacroContextUniverse = if (MacroContextClass != NoSymbol) getMemberMethod(MacroContextClass, nme.universe) else NoSymbol - def MacroContextMirror = if (MacroContextClass != NoSymbol) getMemberMethod(MacroContextClass, nme.mirror) else NoSymbol - def MacroContextReify = if (MacroContextClass != NoSymbol) getMemberMethod(MacroContextClass, nme.reify) else NoSymbol - lazy val MacroImplAnnotation = requiredClass[scala.reflect.makro.internal.macroImpl] - lazy val MacroInternalPackage = getPackageObject("scala.reflect.makro.internal") - def MacroInternal_materializeArrayTag = getMemberMethod(MacroInternalPackage, nme.materializeArrayTag) - def MacroInternal_materializeClassTag = getMemberMethod(MacroInternalPackage, nme.materializeClassTag) - def MacroInternal_materializeTypeTag = getMemberMethod(MacroInternalPackage, nme.materializeTypeTag) - def MacroInternal_materializeConcreteTypeTag = getMemberMethod(MacroInternalPackage, nme.materializeConcreteTypeTag) - - lazy val ScalaSignatureAnnotation = requiredClass[scala.reflect.ScalaSignature] - lazy val ScalaLongSignatureAnnotation = requiredClass[scala.reflect.ScalaLongSignature] - - // Option classes - lazy val OptionClass: ClassSymbol = requiredClass[Option[_]] - lazy val SomeClass: ClassSymbol = requiredClass[Some[_]] - lazy val NoneModule: ModuleSymbol = requiredModule[scala.None.type] - lazy val SomeModule: ModuleSymbol = requiredModule[scala.Some.type] - - def compilerTypeFromTag(tt: BaseUniverse # TypeTag[_]): Type = tt.in(rootMirror).tpe - def compilerSymbolFromTag(tt: BaseUniverse # TypeTag[_]): Symbol = tt.in(rootMirror).tpe.typeSymbol - - // The given symbol represents either String.+ or StringAdd.+ - def isStringAddition(sym: Symbol) = sym == String_+ || sym == StringAdd_+ - def isArrowAssoc(sym: Symbol) = ArrowAssocClass.tpe.decls.toList contains sym - - // The given symbol is a method with the right name and signature to be a runnable java program. - def isJavaMainMethod(sym: Symbol) = (sym.name == nme.main) && (sym.info match { - case MethodType(p :: Nil, restpe) => isArrayOfSymbol(p.tpe, StringClass) && restpe.typeSymbol == UnitClass - case _ => false - }) - // The given class has a main method. - def hasJavaMainMethod(sym: Symbol): Boolean = - (sym.tpe member nme.main).alternatives exists isJavaMainMethod - def hasJavaMainMethod(path: String): Boolean = - hasJavaMainMethod(getModuleIfDefined(path)) - - def isOptionType(tp: Type) = tp.typeSymbol isSubClass OptionClass - def isSomeType(tp: Type) = tp.typeSymbol eq SomeClass - def isNoneType(tp: Type) = tp.typeSymbol eq NoneModule - - // Product, Tuple, Function, AbstractFunction - private def mkArityArray(name: String, arity: Int, countFrom: Int): Array[ClassSymbol] = { - val list = countFrom to arity map (i => getRequiredClass("scala." + name + i)) - list.toArray - } - def prepend[S >: ClassSymbol : ClassTag](elem0: S, elems: Array[ClassSymbol]): Array[S] = elem0 +: elems - - private def aritySpecificType[S <: Symbol](symbolArray: Array[S], args: List[Type], others: Type*): Type = { - val arity = args.length - if (arity >= symbolArray.length) NoType - else appliedType(symbolArray(arity), args ++ others: _*) - } - - val MaxTupleArity, MaxProductArity, MaxFunctionArity = 22 - lazy val ProductClass: Array[ClassSymbol] = prepend(UnitClass, mkArityArray("Product", MaxProductArity, 1)) - lazy val TupleClass: Array[Symbol] = prepend(NoSymbol, mkArityArray("Tuple", MaxTupleArity, 1)) - lazy val FunctionClass = mkArityArray("Function", MaxFunctionArity, 0) - lazy val AbstractFunctionClass = mkArityArray("runtime.AbstractFunction", MaxFunctionArity, 0) - - /** Creators for TupleN, ProductN, FunctionN. */ - def tupleType(elems: List[Type]) = aritySpecificType(TupleClass, elems) - def productType(elems: List[Type]) = aritySpecificType(ProductClass, elems) - def functionType(formals: List[Type], restpe: Type) = aritySpecificType(FunctionClass, formals, restpe) - def abstractFunctionType(formals: List[Type], restpe: Type) = aritySpecificType(AbstractFunctionClass, formals, restpe) - - def wrapArrayMethodName(elemtp: Type): TermName = elemtp.typeSymbol match { - case ByteClass => nme.wrapByteArray - case ShortClass => nme.wrapShortArray - case CharClass => nme.wrapCharArray - case IntClass => nme.wrapIntArray - case LongClass => nme.wrapLongArray - case FloatClass => nme.wrapFloatArray - case DoubleClass => nme.wrapDoubleArray - case BooleanClass => nme.wrapBooleanArray - case UnitClass => nme.wrapUnitArray - case _ => - if ((elemtp <:< AnyRefClass.tpe) && !isPhantomClass(elemtp.typeSymbol)) nme.wrapRefArray - else nme.genericWrapArray - } - - @deprecated("Use isTupleType", "2.10.0") - def isTupleTypeOrSubtype(tp: Type) = isTupleType(tp) - - def tupleField(n: Int, j: Int) = getMemberValue(TupleClass(n), nme.productAccessorName(j)) - // NOTE: returns true for NoSymbol since it's included in the TupleClass array -- is this intensional? - def isTupleSymbol(sym: Symbol) = TupleClass contains unspecializedSymbol(sym) - def isProductNClass(sym: Symbol) = ProductClass contains sym - - def unspecializedSymbol(sym: Symbol): Symbol = { - if (sym hasFlag SPECIALIZED) { - // add initialization from its generic class constructor - val genericName = nme.unspecializedName(sym.name) - val member = sym.owner.info.decl(genericName.toTypeName) - member - } - else sym - } - - // Checks whether the given type is true for the given condition, - // or if it is a specialized subtype of a type for which it is true. - // - // Origins notes: - // An issue was introduced with specialization in that the implementation - // of "isTupleType" in Definitions relied upon sym == TupleClass(elems.length). - // This test is untrue for specialized tuples, causing mysterious behavior - // because only some tuples are specialized. - def isPossiblySpecializedType(tp: Type)(cond: Type => Boolean) = { - cond(tp) || (tp match { - case TypeRef(pre, sym, args) if sym hasFlag SPECIALIZED => - cond(tp baseType unspecializedSymbol(sym)) - case _ => - false - }) - } - // No normalization. - def isTupleTypeDirect(tp: Type) = isPossiblySpecializedType(tp) { - case TypeRef(_, sym, args) if args.nonEmpty => - val len = args.length - len <= MaxTupleArity && sym == TupleClass(len) - case _ => false - } - def isTupleType(tp: Type) = isTupleTypeDirect(tp.normalize) - - lazy val ProductRootClass: ClassSymbol = requiredClass[scala.Product] - def Product_productArity = getMemberMethod(ProductRootClass, nme.productArity) - def Product_productElement = getMemberMethod(ProductRootClass, nme.productElement) - def Product_iterator = getMemberMethod(ProductRootClass, nme.productIterator) - def Product_productPrefix = getMemberMethod(ProductRootClass, nme.productPrefix) - def Product_canEqual = getMemberMethod(ProductRootClass, nme.canEqual_) - // def Product_productElementName = getMemberMethod(ProductRootClass, nme.productElementName) - - def productProj(z:Symbol, j: Int): TermSymbol = getMemberValue(z, nme.productAccessorName(j)) - def productProj(n: Int, j: Int): TermSymbol = productProj(ProductClass(n), j) - - /** returns true if this type is exactly ProductN[T1,...,Tn], not some subclass */ - def isExactProductType(tp: Type): Boolean = isProductNClass(tp.typeSymbol) - - /** if tpe <: ProductN[T1,...,TN], returns List(T1,...,TN) else Nil */ - def getProductArgs(tpe: Type): List[Type] = tpe.baseClasses find isProductNClass match { - case Some(x) => tpe.baseType(x).typeArgs - case _ => Nil - } - - def unapplyUnwrap(tpe:Type) = tpe.finalResultType.normalize match { - case RefinedType(p :: _, _) => p.normalize - case tp => tp - } - - def functionApply(n: Int) = getMemberMethod(FunctionClass(n), nme.apply) - - def abstractFunctionForFunctionType(tp: Type) = - if (isFunctionType(tp)) abstractFunctionType(tp.typeArgs.init, tp.typeArgs.last) - else NoType - - def isFunctionType(tp: Type): Boolean = tp.normalize match { - case TypeRef(_, sym, args) if args.nonEmpty => - val arity = args.length - 1 // -1 is the return type - arity <= MaxFunctionArity && sym == FunctionClass(arity) - case _ => - false - } - - def isPartialFunctionType(tp: Type): Boolean = { - val sym = tp.typeSymbol - (sym eq PartialFunctionClass) || (sym eq AbstractPartialFunctionClass) - } - - def isSeqType(tp: Type) = elementType(SeqClass, tp.normalize) != NoType - - def elementType(container: Symbol, tp: Type): Type = tp match { - case TypeRef(_, `container`, arg :: Nil) => arg - case _ => NoType - } - - def arrayType(arg: Type) = appliedType(ArrayClass, arg) - def byNameType(arg: Type) = appliedType(ByNameParamClass, arg) - def iteratorOfType(tp: Type) = appliedType(IteratorClass, tp) - def javaRepeatedType(arg: Type) = appliedType(JavaRepeatedParamClass, arg) - def optionType(tp: Type) = appliedType(OptionClass, tp) - def scalaRepeatedType(arg: Type) = appliedType(RepeatedParamClass, arg) - def seqType(arg: Type) = appliedType(SeqClass, arg) - def someType(tp: Type) = appliedType(SomeClass, tp) - - def StringArray = arrayType(StringClass.tpe) - lazy val ObjectArray = arrayType(ObjectClass.tpe) - - def ClassType(arg: Type) = - if (phase.erasedTypes || forMSIL) ClassClass.tpe - else appliedType(ClassClass, arg) - - def vmClassType(arg: Type): Type = ClassType(arg) - def vmSignature(sym: Symbol, info: Type): String = signature(info) // !!! - - /** Given a class symbol C with type parameters T1, T2, ... Tn - * which have upper/lower bounds LB1/UB1, LB1/UB2, ..., LBn/UBn, - * returns an existential type of the form - * - * C[E1, ..., En] forSome { E1 >: LB1 <: UB1 ... en >: LBn <: UBn }. - */ - def classExistentialType(clazz: Symbol): Type = - newExistentialType(clazz.typeParams, clazz.tpe) - - /** Given type U, creates a Type representing Class[_ <: U]. - */ - def boundedClassType(upperBound: Type) = - appliedTypeAsUpperBounds(ClassClass.typeConstructor, List(upperBound)) - - /** To avoid unchecked warnings on polymorphic classes, translate - * a Foo[T] into a Foo[_] for use in the pattern matcher. - */ - @deprecated("Use classExistentialType", "2.10.0") - def typeCaseType(clazz: Symbol): Type = classExistentialType(clazz) - - // - // .NET backend - // - - lazy val ComparatorClass = getRequiredClass("scala.runtime.Comparator") - // System.ValueType - lazy val ValueTypeClass: ClassSymbol = getClassByName(sn.ValueType) - // System.MulticastDelegate - lazy val DelegateClass: ClassSymbol = getClassByName(sn.Delegate) - var Delegate_scalaCallers: List[Symbol] = List() // Syncnote: No protection necessary yet as only for .NET where reflection is not supported. - // Symbol -> (Symbol, Type): scalaCaller -> (scalaMethodSym, DelegateType) - // var Delegate_scalaCallerInfos: HashMap[Symbol, (Symbol, Type)] = _ - lazy val Delegate_scalaCallerTargets: mutable.HashMap[Symbol, Symbol] = mutable.HashMap() - - def isCorrespondingDelegate(delegateType: Type, functionType: Type): Boolean = { - isSubType(delegateType, DelegateClass.tpe) && - (delegateType.member(nme.apply).tpe match { - case MethodType(delegateParams, delegateReturn) => - isFunctionType(functionType) && - (functionType.normalize match { - case TypeRef(_, _, args) => - (delegateParams.map(pt => { - if (pt.tpe == AnyClass.tpe) definitions.ObjectClass.tpe else pt}) - ::: List(delegateReturn)) == args - case _ => false - }) - case _ => false - }) - } - - // members of class scala.Any - lazy val Any_== = enterNewMethod(AnyClass, nme.EQ, anyparam, booltype, FINAL) - lazy val Any_!= = enterNewMethod(AnyClass, nme.NE, anyparam, booltype, FINAL) - lazy val Any_equals = enterNewMethod(AnyClass, nme.equals_, anyparam, booltype) - lazy val Any_hashCode = enterNewMethod(AnyClass, nme.hashCode_, Nil, inttype) - lazy val Any_toString = enterNewMethod(AnyClass, nme.toString_, Nil, stringtype) - lazy val Any_## = enterNewMethod(AnyClass, nme.HASHHASH, Nil, inttype, FINAL) - - // Any_getClass requires special handling. The return type is determined on - // a per-call-site basis as if the function being called were actually: - // - // // Assuming `target.getClass()` - // def getClass[T](target: T): Class[_ <: T] - // - // Since getClass is not actually a polymorphic method, this requires compiler - // participation. At the "Any" level, the return type is Class[_] as it is in - // java.lang.Object. Java also special cases the return type. - lazy val Any_getClass = enterNewMethod(AnyClass, nme.getClass_, Nil, getMemberMethod(ObjectClass, nme.getClass_).tpe.resultType, DEFERRED) - lazy val Any_isInstanceOf = newT1NullaryMethod(AnyClass, nme.isInstanceOf_, FINAL)(_ => booltype) - lazy val Any_asInstanceOf = newT1NullaryMethod(AnyClass, nme.asInstanceOf_, FINAL)(_.typeConstructor) - - // A type function from T => Class[U], used to determine the return - // type of getClass calls. The returned type is: - // - // 1. If T is a value type, Class[T]. - // 2. If T is a phantom type (Any or AnyVal), Class[_]. - // 3. If T is a local class, Class[_ <: |T|]. - // 4. Otherwise, Class[_ <: T]. - // - // Note: AnyVal cannot be Class[_ <: AnyVal] because if the static type of the - // receiver is AnyVal, it implies the receiver is boxed, so the correct - // class object is that of java.lang.Integer, not Int. - // - // TODO: If T is final, return type could be Class[T]. Should it? - def getClassReturnType(tp: Type): Type = { - val sym = tp.typeSymbol - - if (phase.erasedTypes) ClassClass.tpe - else if (isPrimitiveValueClass(sym)) ClassType(tp.widen) - else { - val eparams = typeParamsToExistentials(ClassClass, ClassClass.typeParams) - val upperBound = ( - if (isPhantomClass(sym)) AnyClass.tpe - else if (sym.isLocalClass) erasure.intersectionDominator(tp.parents) - else tp.widen - ) - - existentialAbstraction( - eparams, - ClassType((eparams.head setInfo TypeBounds.upper(upperBound)).tpe) - ) - } - } - - /** Remove references to class Object (other than the head) in a list of parents */ - def removeLaterObjects(tps: List[Type]): List[Type] = tps match { - case Nil => Nil - case x :: xs => x :: xs.filterNot(_.typeSymbol == ObjectClass) - } - /** Remove all but one reference to class Object from a list of parents. */ - def removeRedundantObjects(tps: List[Type]): List[Type] = tps match { - case Nil => Nil - case x :: xs => - if (x.typeSymbol == ObjectClass) - x :: xs.filterNot(_.typeSymbol == ObjectClass) - else - x :: removeRedundantObjects(xs) - } - /** Order a list of types with non-trait classes before others. */ - def classesFirst(tps: List[Type]): List[Type] = { - val (classes, others) = tps partition (t => t.typeSymbol.isClass && !t.typeSymbol.isTrait) - if (classes.isEmpty || others.isEmpty || (tps startsWith classes)) tps - else classes ::: others - } - /** The following transformations applied to a list of parents. - * If any parent is a class/trait, all parents which normalize to - * Object are discarded. Otherwise, all parents which normalize - * to Object except the first one found are discarded. - */ - def normalizedParents(parents: List[Type]): List[Type] = { - if (parents exists (t => (t.typeSymbol ne ObjectClass) && t.typeSymbol.isClass)) - parents filterNot (_.typeSymbol eq ObjectClass) - else - removeRedundantObjects(parents) - } - - def typeStringNoPackage(tp: Type) = - "" + tp stripPrefix tp.typeSymbol.enclosingPackage.fullName + "." - - def briefParentsString(parents: List[Type]) = - normalizedParents(parents) map typeStringNoPackage mkString " with " - - def parentsString(parents: List[Type]) = - normalizedParents(parents) mkString " with " - - def typeParamsString(tp: Type) = tp match { - case PolyType(tparams, _) => tparams map (_.defString) mkString ("[", ",", "]") - case _ => "" - } - def valueParamsString(tp: Type) = tp match { - case MethodType(params, _) => params map (_.defString) mkString ("(", ",", ")") - case _ => "" - } - - // members of class java.lang.{ Object, String } - lazy val Object_## = enterNewMethod(ObjectClass, nme.HASHHASH, Nil, inttype, FINAL) - lazy val Object_== = enterNewMethod(ObjectClass, nme.EQ, anyrefparam, booltype, FINAL) - lazy val Object_!= = enterNewMethod(ObjectClass, nme.NE, anyrefparam, booltype, FINAL) - lazy val Object_eq = enterNewMethod(ObjectClass, nme.eq, anyrefparam, booltype, FINAL) - lazy val Object_ne = enterNewMethod(ObjectClass, nme.ne, anyrefparam, booltype, FINAL) - lazy val Object_isInstanceOf = newT1NoParamsMethod(ObjectClass, nme.isInstanceOf_Ob, FINAL | SYNTHETIC)(_ => booltype) - lazy val Object_asInstanceOf = newT1NoParamsMethod(ObjectClass, nme.asInstanceOf_Ob, FINAL | SYNTHETIC)(_.typeConstructor) - lazy val Object_synchronized = newPolyMethod(1, ObjectClass, nme.synchronized_, FINAL)(tps => - (Some(List(tps.head.typeConstructor)), tps.head.typeConstructor) - ) - lazy val String_+ = enterNewMethod(StringClass, nme.raw.PLUS, anyparam, stringtype, FINAL) - - def Object_getClass = getMemberMethod(ObjectClass, nme.getClass_) - def Object_clone = getMemberMethod(ObjectClass, nme.clone_) - def Object_finalize = getMemberMethod(ObjectClass, nme.finalize_) - def Object_notify = getMemberMethod(ObjectClass, nme.notify_) - def Object_notifyAll = getMemberMethod(ObjectClass, nme.notifyAll_) - def Object_equals = getMemberMethod(ObjectClass, nme.equals_) - def Object_hashCode = getMemberMethod(ObjectClass, nme.hashCode_) - def Object_toString = getMemberMethod(ObjectClass, nme.toString_) - - // boxed classes - lazy val ObjectRefClass = requiredClass[scala.runtime.ObjectRef[_]] - lazy val VolatileObjectRefClass = requiredClass[scala.runtime.VolatileObjectRef[_]] - lazy val RuntimeStaticsModule = getRequiredModule("scala.runtime.Statics") - lazy val BoxesRunTimeModule = getRequiredModule("scala.runtime.BoxesRunTime") - lazy val BoxesRunTimeClass = BoxesRunTimeModule.moduleClass - lazy val BoxedNumberClass = getClassByName(sn.BoxedNumber) - lazy val BoxedCharacterClass = getClassByName(sn.BoxedCharacter) - lazy val BoxedBooleanClass = getClassByName(sn.BoxedBoolean) - lazy val BoxedByteClass = requiredClass[java.lang.Byte] - lazy val BoxedShortClass = requiredClass[java.lang.Short] - lazy val BoxedIntClass = requiredClass[java.lang.Integer] - lazy val BoxedLongClass = requiredClass[java.lang.Long] - lazy val BoxedFloatClass = requiredClass[java.lang.Float] - lazy val BoxedDoubleClass = requiredClass[java.lang.Double] - - lazy val Boxes_isNumberOrBool = getDecl(BoxesRunTimeClass, nme.isBoxedNumberOrBoolean) - lazy val Boxes_isNumber = getDecl(BoxesRunTimeClass, nme.isBoxedNumber) - - lazy val BoxedUnitClass = requiredClass[scala.runtime.BoxedUnit] - lazy val BoxedUnitModule = getRequiredModule("scala.runtime.BoxedUnit") - def BoxedUnit_UNIT = getMemberValue(BoxedUnitModule, nme.UNIT) - def BoxedUnit_TYPE = getMemberValue(BoxedUnitModule, nme.TYPE_) - - // Annotation base classes - lazy val AnnotationClass = requiredClass[scala.annotation.Annotation] - lazy val ClassfileAnnotationClass = requiredClass[scala.annotation.ClassfileAnnotation] - lazy val StaticAnnotationClass = requiredClass[scala.annotation.StaticAnnotation] - - // Annotations - lazy val BridgeClass = requiredClass[scala.annotation.bridge] - lazy val ElidableMethodClass = requiredClass[scala.annotation.elidable] - lazy val ImplicitNotFoundClass = requiredClass[scala.annotation.implicitNotFound] - lazy val MigrationAnnotationClass = requiredClass[scala.annotation.migration] - lazy val ScalaStrictFPAttr = requiredClass[scala.annotation.strictfp] - lazy val SerializableAttr = requiredClass[scala.annotation.serializable] // @serializable is deprecated - lazy val SwitchClass = requiredClass[scala.annotation.switch] - lazy val TailrecClass = requiredClass[scala.annotation.tailrec] - lazy val VarargsClass = requiredClass[scala.annotation.varargs] - lazy val uncheckedStableClass = requiredClass[scala.annotation.unchecked.uncheckedStable] - lazy val uncheckedVarianceClass = requiredClass[scala.annotation.unchecked.uncheckedVariance] - - lazy val BeanPropertyAttr = requiredClass[scala.beans.BeanProperty] - lazy val BooleanBeanPropertyAttr = requiredClass[scala.beans.BooleanBeanProperty] - lazy val CloneableAttr = requiredClass[scala.cloneable] - lazy val DeprecatedAttr = requiredClass[scala.deprecated] - lazy val DeprecatedNameAttr = requiredClass[scala.deprecatedName] - lazy val NativeAttr = requiredClass[scala.native] - lazy val RemoteAttr = requiredClass[scala.remote] - lazy val ScalaInlineClass = requiredClass[scala.inline] - lazy val ScalaNoInlineClass = requiredClass[scala.noinline] - lazy val SerialVersionUIDAttr = requiredClass[scala.SerialVersionUID] - lazy val SpecializedClass = requiredClass[scala.specialized] - lazy val ThrowsClass = requiredClass[scala.throws] - lazy val TransientAttr = requiredClass[scala.transient] - lazy val UncheckedClass = requiredClass[scala.unchecked] - lazy val UnspecializedClass = requiredClass[scala.annotation.unspecialized] - lazy val VolatileAttr = requiredClass[scala.volatile] - - // Meta-annotations - lazy val BeanGetterTargetClass = requiredClass[meta.beanGetter] - lazy val BeanSetterTargetClass = requiredClass[meta.beanSetter] - lazy val FieldTargetClass = requiredClass[meta.field] - lazy val GetterTargetClass = requiredClass[meta.getter] - lazy val ParamTargetClass = requiredClass[meta.param] - lazy val SetterTargetClass = requiredClass[meta.setter] - lazy val ClassTargetClass = requiredClass[meta.companionClass] - lazy val ObjectTargetClass = requiredClass[meta.companionObject] - lazy val MethodTargetClass = requiredClass[meta.companionMethod] // TODO: module, moduleClass? package, packageObject? - lazy val LanguageFeatureAnnot = requiredClass[meta.languageFeature] - - // Language features - lazy val languageFeatureModule = getRequiredModule("scala.languageFeature") - lazy val experimentalModule = getMemberModule(languageFeatureModule, nme.experimental) - lazy val MacrosFeature = getLanguageFeature("macros", experimentalModule) - lazy val DynamicsFeature = getLanguageFeature("dynamics") - lazy val PostfixOpsFeature = getLanguageFeature("postfixOps") - lazy val ReflectiveCallsFeature = getLanguageFeature("reflectiveCalls") - lazy val ImplicitConversionsFeature = getLanguageFeature("implicitConversions") - lazy val HigherKindsFeature = getLanguageFeature("higherKinds") - lazy val ExistentialsFeature = getLanguageFeature("existentials") - - def isMetaAnnotation(sym: Symbol): Boolean = metaAnnotations(sym) || ( - // Trying to allow for deprecated locations - sym.isAliasType && isMetaAnnotation(sym.info.typeSymbol) - ) - lazy val metaAnnotations = Set[Symbol]( - FieldTargetClass, ParamTargetClass, - GetterTargetClass, SetterTargetClass, - BeanGetterTargetClass, BeanSetterTargetClass - ) - - lazy val AnnotationDefaultAttr: ClassSymbol = { - val attr = enterNewClass(RuntimePackageClass, tpnme.AnnotationDefaultATTR, List(AnnotationClass.tpe)) - // This attribute needs a constructor so that modifiers in parsed Java code make sense - attr.info.decls enter attr.newClassConstructor(NoPosition) - attr - } - - private def fatalMissingSymbol(owner: Symbol, name: Name, what: String = "member") = { - throw new FatalError(owner + " does not have a " + what + " " + name) - } - - def getLanguageFeature(name: String, owner: Symbol = languageFeatureModule): Symbol = - // [Eugene++] `getMemberClass` leads to crashes in mixin: - // "object languageFeature does not have a member class implicitConversions" - // that's because by that time `implicitConversions` becomes a module - // getMemberClass(owner, newTypeName(name)) - getMember(owner, newTypeName(name)) - - def termMember(owner: Symbol, name: String): Symbol = owner.info.member(newTermName(name)) - def typeMember(owner: Symbol, name: String): Symbol = owner.info.member(newTypeName(name)) - - def findNamedMember(fullName: Name, root: Symbol): Symbol = { - val segs = nme.segments(fullName.toString, fullName.isTermName) - if (segs.isEmpty || segs.head != root.simpleName) NoSymbol - else findNamedMember(segs.tail, root) - } - def findNamedMember(segs: List[Name], root: Symbol): Symbol = - if (segs.isEmpty) root - else findNamedMember(segs.tail, root.info member segs.head) - - def getMember(owner: Symbol, name: Name): Symbol = { - getMemberIfDefined(owner, name) orElse { - if (phase.flatClasses && name.isTypeName && !owner.isPackageObjectOrClass) { - val pkg = owner.owner - val flatname = nme.flattenedName(owner.name, name) - getMember(pkg, flatname) - } - else fatalMissingSymbol(owner, name) - } - } - def getMemberValue(owner: Symbol, name: Name): TermSymbol = { - // [Eugene++] should be a ClassCastException instead? - getMember(owner, name.toTermName) match { - case x: TermSymbol => x - case _ => fatalMissingSymbol(owner, name, "member value") - } - } - def getMemberModule(owner: Symbol, name: Name): ModuleSymbol = { - // [Eugene++] should be a ClassCastException instead? - getMember(owner, name.toTermName) match { - case x: ModuleSymbol => x - case _ => fatalMissingSymbol(owner, name, "member object") - } - } - def getMemberType(owner: Symbol, name: Name): TypeSymbol = { - // [Eugene++] should be a ClassCastException instead? - getMember(owner, name.toTypeName) match { - case x: TypeSymbol => x - case _ => fatalMissingSymbol(owner, name, "member type") - } - } - def getMemberClass(owner: Symbol, name: Name): ClassSymbol = { - // [Eugene++] should be a ClassCastException instead? - val y = getMember(owner, name.toTypeName) - getMember(owner, name.toTypeName) match { - case x: ClassSymbol => x - case _ => fatalMissingSymbol(owner, name, "member class") - } - } - def getMemberMethod(owner: Symbol, name: Name): TermSymbol = { - // [Eugene++] is this a bug? - // - // System.err.println(result.getClass) - // System.err.println(result.flags) - // System.err.println("isMethod = " + result.isMethod) - // System.err.println("isTerm = " + result.isTerm) - // System.err.println("isValue = " + result.isValue) - // result.asMethodSymbol - // - // prints this: - // - // quick.lib: - // [javac] Compiling 1 source file to C:\Projects\KeplerUnderRefactoring\build\quick\classes\library - // [scalacfork] Compiling 769 files to C:\Projects\KeplerUnderRefactoring\build\quick\classes\library - // [scalacfork] class scala.reflect.internal.Symbols$TermSymbol - // [scalacfork] 8589934592 - // [scalacfork] isMethod = false - // [scalacfork] isTerm = true - // [scalacfork] isValue = true - // [scalacfork] - // [scalacfork] while compiling: C:\Projects\KeplerUnderRefactoring\src\library\scala\LowPriorityImplicits.scala - // [scalacfork] current phase: cleanup - // [scalacfork] library version: version 2.10.0-20120507-185519-665d1d9127 - // [scalacfork] compiler version: version 2.10.0-20120507-185519-665d1d9127 - // [scalacfork] reconstructed args: -Xmacros -classpath C:\\Projects\\KeplerUnderRefactoring\\build\\quick\\classes\\library;C:\\Projects\\KeplerUnderRefactoring\\lib\\forkjoin.jar -d C:\\Projects\\KeplerUnderRefactoring\\build\\quick\\classes\\library -sourcepath C:\\Projects\\KeplerUnderRefactoring\\src\\library - // [scalacfork] - // [scalacfork] unhandled exception while transforming LowPriorityImplicits.scala - // [scalacfork] error: - // [scalacfork] while compiling: C:\Projects\KeplerUnderRefactoring\src\library\scala\LowPriorityImplicits.scala - // [scalacfork] current phase: cleanup - // [scalacfork] library version: version 2.10.0-20120507-185519-665d1d9127 - // [scalacfork] compiler version: version 2.10.0-20120507-185519-665d1d9127 - // [scalacfork] reconstructed args: -Xmacros -classpath C:\\Projects\\KeplerUnderRefactoring\\build\\quick\\classes\\library;C:\\Projects\\KeplerUnderRefactoring\\lib\\forkjoin.jar -d C:\\Projects\\KeplerUnderRefactoring\\build\\quick\\classes\\library -sourcepath C:\\Projects\\KeplerUnderRefactoring\\src\\library - // [scalacfork] - // [scalacfork] uncaught exception during compilation: java.lang.ClassCastException - // [scalacfork] error: java.lang.ClassCastException: value apply - // [scalacfork] at scala.reflect.base.Symbols$SymbolBase$class.asMethodSymbol(Symbols.scala:118) - // [scalacfork] at scala.reflect.internal.Symbols$SymbolContextApiImpl.asMethodSymbol(Symbols.scala:63) - // [scalacfork] at scala.reflect.internal.Definitions$DefinitionsClass.Symbol_apply(Definitions.scala:381) - - // [Eugene++] should be a ClassCastException instead? - getMember(owner, name.toTermName) match { - // case x: MethodSymbol => x - case x: TermSymbol => x - case _ => fatalMissingSymbol(owner, name, "method") - } - } - - def getMemberIfDefined(owner: Symbol, name: Name): Symbol = - owner.info.nonPrivateMember(name) - - /** Using getDecl rather than getMember may avoid issues with - * OverloadedTypes turning up when you don't want them, if you - * know the method in question is uniquely declared in the given owner. - */ - def getDecl(owner: Symbol, name: Name): Symbol = { - getDeclIfDefined(owner, name) orElse fatalMissingSymbol(owner, name, "decl") - } - def getDeclIfDefined(owner: Symbol, name: Name): Symbol = - owner.info.nonPrivateDecl(name) - - def packageExists(packageName: String): Boolean = - getModuleIfDefined(packageName).isPackage - - private def newAlias(owner: Symbol, name: TypeName, alias: Type): AliasTypeSymbol = - owner.newAliasType(name) setInfoAndEnter alias - - private def specialPolyClass(name: TypeName, flags: Long)(parentFn: Symbol => Type): ClassSymbol = { - val clazz = enterNewClass(ScalaPackageClass, name, Nil) - val tparam = clazz.newSyntheticTypeParam("T0", flags) - val parents = List(AnyRefClass.tpe, parentFn(tparam)) - - clazz setInfo GenPolyType(List(tparam), ClassInfoType(parents, newScope, clazz)) - } - - def newPolyMethod(typeParamCount: Int, owner: Symbol, name: TermName, flags: Long)(createFn: PolyMethodCreator): MethodSymbol = { - val msym = owner.newMethod(name.encode, NoPosition, flags) - val tparams = msym.newSyntheticTypeParams(typeParamCount) - val mtpe = createFn(tparams) match { - case (Some(formals), restpe) => MethodType(msym.newSyntheticValueParams(formals), restpe) - case (_, restpe) => NullaryMethodType(restpe) - } - - msym setInfoAndEnter genPolyType(tparams, mtpe) - } - - /** T1 means one type parameter. - */ - def newT1NullaryMethod(owner: Symbol, name: TermName, flags: Long)(createFn: Symbol => Type): MethodSymbol = { - newPolyMethod(1, owner, name, flags)(tparams => (None, createFn(tparams.head))) - } - def newT1NoParamsMethod(owner: Symbol, name: TermName, flags: Long)(createFn: Symbol => Type): MethodSymbol = { - newPolyMethod(1, owner, name, flags)(tparams => (Some(Nil), createFn(tparams.head))) - } - - lazy val boxedClassValues = boxedClass.values.toSet[Symbol] - lazy val isUnbox = unboxMethod.values.toSet[Symbol] - lazy val isBox = boxMethod.values.toSet[Symbol] - - /** Is symbol a phantom class for which no runtime representation exists? */ - lazy val isPhantomClass = Set[Symbol](AnyClass, AnyValClass, NullClass, NothingClass) - - /** Is the symbol that of a parent which is added during parsing? */ - lazy val isPossibleSyntheticParent = ProductClass.toSet[Symbol] + ProductRootClass + SerializableClass - - private lazy val boxedValueClassesSet = boxedClass.values.toSet[Symbol] + BoxedUnitClass - - /** Is symbol a value class? */ - def isPrimitiveValueClass(sym: Symbol) = ScalaValueClasses contains sym - def isNonUnitValueClass(sym: Symbol) = isPrimitiveValueClass(sym) && (sym != UnitClass) - def isSpecializableClass(sym: Symbol) = isPrimitiveValueClass(sym) || (sym == AnyRefClass) - def isPrimitiveValueType(tp: Type) = isPrimitiveValueClass(tp.typeSymbol) - - /** Is symbol a boxed value class, e.g. java.lang.Integer? */ - def isBoxedValueClass(sym: Symbol) = boxedValueClassesSet(sym) - - /** If symbol is a value class (boxed or not), return the unboxed - * value class. Otherwise, NoSymbol. - */ - def unboxedValueClass(sym: Symbol): Symbol = - if (isPrimitiveValueClass(sym)) sym - else if (sym == BoxedUnitClass) UnitClass - else boxedClass.map(kvp => (kvp._2: Symbol, kvp._1)).getOrElse(sym, NoSymbol) - - /** Is type's symbol a numeric value class? */ - def isNumericValueType(tp: Type): Boolean = tp match { - case TypeRef(_, sym, _) => isNumericValueClass(sym) - case _ => false - } - - // todo: reconcile with javaSignature!!! - def signature(tp: Type): String = { - def erasure(tp: Type): Type = tp match { - case st: SubType => erasure(st.supertype) - case RefinedType(parents, _) => erasure(parents.head) - case _ => tp - } - def flatNameString(sym: Symbol, separator: Char): String = - if (sym == NoSymbol) "" // be more resistant to error conditions, e.g. neg/t3222.scala - else if (sym.owner.isPackageClass) sym.javaClassName - else flatNameString(sym.owner, separator) + nme.NAME_JOIN_STRING + sym.simpleName - def signature1(etp: Type): String = { - if (etp.typeSymbol == ArrayClass) "[" + signature1(erasure(etp.normalize.typeArgs.head)) - else if (isPrimitiveValueClass(etp.typeSymbol)) abbrvTag(etp.typeSymbol).toString() - else "L" + flatNameString(etp.typeSymbol, '/') + ";" - } - val etp = erasure(tp) - if (etp.typeSymbol == ArrayClass) signature1(etp) - else flatNameString(etp.typeSymbol, '.') - } - - /** Surgery on the value classes. Without this, AnyVals defined in source - * files end up with an AnyRef parent. It is likely there is a better way - * to evade that AnyRef. - */ - private def setParents(sym: Symbol, parents: List[Type]): Symbol = sym.rawInfo match { - case ClassInfoType(_, scope, clazz) => - sym setInfo ClassInfoType(parents, scope, clazz) - case _ => - sym - } - - def init() { - if (isInitialized) return - - val forced = List( // force initialization of every symbol that is entered as a side effect - AnnotationDefaultAttr, // #2264 - RepeatedParamClass, - JavaRepeatedParamClass, - ByNameParamClass, - AnyClass, - AnyRefClass, - AnyValClass, - NullClass, - NothingClass, - SingletonClass, - EqualsPatternClass, - Any_==, - Any_!=, - Any_equals, - Any_hashCode, - Any_toString, - Any_getClass, - Any_isInstanceOf, - Any_asInstanceOf, - Any_##, - Object_eq, - Object_ne, - Object_==, - Object_!=, - Object_##, - Object_synchronized, - Object_isInstanceOf, - Object_asInstanceOf, - String_+, - ComparableClass, - JavaSerializableClass - ) - - isInitialized = true - } //init - - var nbScalaCallers: Int = 0 - def newScalaCaller(delegateType: Type): MethodSymbol = { - assert(forMSIL, "scalaCallers can only be created if target is .NET") - // object: reference to object on which to call (scala-)method - val paramTypes: List[Type] = List(ObjectClass.tpe) - val name = newTermName("$scalaCaller$$" + nbScalaCallers) - // tparam => resultType, which is the resultType of PolyType, i.e. the result type after applying the - // type parameter =-> a MethodType in this case - // TODO: set type bounds manually (-> MulticastDelegate), see newTypeParam - val newCaller = enterNewMethod(DelegateClass, name, paramTypes, delegateType, FINAL | STATIC) - // val newCaller = newPolyMethod(DelegateClass, name, - // tparam => MethodType(paramTypes, tparam.typeConstructor)) setFlag (FINAL | STATIC) - Delegate_scalaCallers = Delegate_scalaCallers ::: List(newCaller) - nbScalaCallers += 1 - newCaller - } - - // def addScalaCallerInfo(scalaCaller: Symbol, methSym: Symbol, delType: Type) { - // assert(Delegate_scalaCallers contains scalaCaller) - // Delegate_scalaCallerInfos += (scalaCaller -> (methSym, delType)) - // } - - def addScalaCallerInfo(scalaCaller: Symbol, methSym: Symbol) { - assert(Delegate_scalaCallers contains scalaCaller) - Delegate_scalaCallerTargets += (scalaCaller -> methSym) - } - } -} diff --git a/src/compiler/scala/reflect/internal/ExistentialsAndSkolems.scala b/src/compiler/scala/reflect/internal/ExistentialsAndSkolems.scala deleted file mode 100644 index f1fe4fc118..0000000000 --- a/src/compiler/scala/reflect/internal/ExistentialsAndSkolems.scala +++ /dev/null @@ -1,50 +0,0 @@ -/* NSC -- new scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.reflect -package internal - -import scala.collection.{ mutable, immutable } -import util._ - -/** The name of this trait defines the eventual intent better than - * it does the initial contents. - */ -trait ExistentialsAndSkolems { - self: SymbolTable => - - /** Map a list of type parameter symbols to skolemized symbols, which - * can be deskolemized to the original type parameter. (A skolem is a - * representation of a bound variable when viewed inside its scope.) - * !!!Adriaan: this does not work for hk types. - */ - def deriveFreshSkolems(tparams: List[Symbol]): List[Symbol] = { - class Deskolemizer extends LazyType { - override val typeParams = tparams - val typeSkolems = typeParams map (_.newTypeSkolem setInfo this) - override def complete(sym: Symbol) { - // The info of a skolem is the skolemized info of the - // actual type parameter of the skolem - sym setInfo sym.deSkolemize.info.substSym(typeParams, typeSkolems) - } - } - (new Deskolemizer).typeSkolems - } - - /** Convert to corresponding type parameters all skolems of method - * parameters which appear in `tparams`. - */ - def deskolemizeTypeParams(tparams: List[Symbol])(tp: Type): Type = { - class DeSkolemizeMap extends TypeMap { - def apply(tp: Type): Type = tp match { - case TypeRef(pre, sym, args) if sym.isTypeSkolem && (tparams contains sym.deSkolemize) => - mapOver(typeRef(NoPrefix, sym.deSkolemize, args)) - case _ => - mapOver(tp) - } - } - new DeSkolemizeMap mapOver tp - } -} diff --git a/src/compiler/scala/reflect/internal/FatalError.scala b/src/compiler/scala/reflect/internal/FatalError.scala deleted file mode 100644 index c843308480..0000000000 --- a/src/compiler/scala/reflect/internal/FatalError.scala +++ /dev/null @@ -1,6 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ -package scala.reflect.internal -case class FatalError(msg: String) extends Exception(msg) diff --git a/src/compiler/scala/reflect/internal/FlagSets.scala b/src/compiler/scala/reflect/internal/FlagSets.scala deleted file mode 100644 index 0354d2513c..0000000000 --- a/src/compiler/scala/reflect/internal/FlagSets.scala +++ /dev/null @@ -1,66 +0,0 @@ -package scala.reflect -package internal - -import language.implicitConversions - -trait FlagSets extends api.FlagSets { self: SymbolTable => - - type FlagSet = Long - implicit val FlagSetTag = ClassTag[FlagSet](classOf[FlagSet]) - - implicit def addFlagOps(left: FlagSet): FlagOps = - new FlagOpsImpl(left) - - private class FlagOpsImpl(left: Long) extends FlagOps { - def | (right: Long): Long = left | right - def & (right: Long): Long = left & right - def containsAll (right: Long): Boolean = (right & ~left) == 0 - } - - val NoFlags: FlagSet = 0L - - trait FlagValues extends FlagValuesApi - - object Flag extends FlagValues { - val TRAIT : FlagSet = Flags.TRAIT - val MODULE : FlagSet = Flags.MODULE - val MUTABLE : FlagSet = Flags.MUTABLE - val PACKAGE : FlagSet = Flags.PACKAGE - val METHOD : FlagSet = Flags.METHOD - val MACRO : FlagSet = Flags.MACRO - val DEFERRED : FlagSet = Flags.DEFERRED - val ABSTRACT : FlagSet = Flags.ABSTRACT - val FINAL : FlagSet = Flags.FINAL - val SEALED : FlagSet = Flags.SEALED - val IMPLICIT : FlagSet = Flags.IMPLICIT - val LAZY : FlagSet = Flags.LAZY - val OVERRIDE : FlagSet = Flags.OVERRIDE - val PRIVATE : FlagSet = Flags.PRIVATE - val PROTECTED : FlagSet = Flags.PROTECTED - val CASE : FlagSet = Flags.CASE - val ABSOVERRIDE : FlagSet = Flags.ABSOVERRIDE - val BYNAMEPARAM : FlagSet = Flags.BYNAMEPARAM - val PARAM : FlagSet = Flags.PARAM - val PARAMACCESSOR : FlagSet = Flags.PARAMACCESSOR - val CASEACCESSOR : FlagSet = Flags.CASEACCESSOR - val COVARIANT : FlagSet = Flags.COVARIANT - val CONTRAVARIANT : FlagSet = Flags.CONTRAVARIANT - val DEFAULTPARAM : FlagSet = Flags.DEFAULTPARAM - val INTERFACE : FlagSet = Flags.INTERFACE - - def union(flags: FlagSet*): FlagSet = { - var acc = 0L - for (flag <- flags) acc |= flag - acc - } - - def intersection(flags: FlagSet*): FlagSet = { - var acc = -1L - for (flag <- flags) acc &= flag - acc - } - - def containsAll(superset: FlagSet, subset: FlagSet): Boolean = - (subset & ~superset) == 0 - } -} diff --git a/src/compiler/scala/reflect/internal/Flags.scala b/src/compiler/scala/reflect/internal/Flags.scala deleted file mode 100644 index 37e5a23819..0000000000 --- a/src/compiler/scala/reflect/internal/Flags.scala +++ /dev/null @@ -1,483 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.reflect -package internal - -import scala.collection.{ mutable, immutable } - -// Flags at each index of a flags Long. Those marked with /M are used in -// Parsers/JavaParsers and therefore definitely appear on Modifiers; but the -// absence of /M on the other flags does not imply they aren't. -// -// Generated by mkFlagsTable() at Thu Feb 02 20:31:52 PST 2012 -// -// 0: PROTECTED/M -// 1: OVERRIDE/M -// 2: PRIVATE/M -// 3: ABSTRACT/M -// 4: DEFERRED/M -// 5: FINAL/M -// 6: METHOD -// 7: INTERFACE/M -// 8: MODULE -// 9: IMPLICIT/M -// 10: SEALED/M -// 11: CASE/M -// 12: MUTABLE/M -// 13: PARAM/M -// 14: PACKAGE -// 15: MACRO/M -// 16: BYNAMEPARAM/M CAPTURED COVARIANT/M -// 17: CONTRAVARIANT/M INCONSTRUCTOR LABEL -// 18: ABSOVERRIDE/M -// 19: LOCAL/M -// 20: JAVA/M -// 21: SYNTHETIC -// 22: STABLE -// 23: STATIC/M -// 24: CASEACCESSOR/M -// 25: DEFAULTPARAM/M TRAIT/M -// 26: BRIDGE -// 27: ACCESSOR -// 28: SUPERACCESSOR -// 29: PARAMACCESSOR/M -// 30: MODULEVAR -// 31: LAZY/M -// 32: IS_ERROR -// 33: OVERLOADED -// 34: LIFTED -// 35: EXISTENTIAL MIXEDIN -// 36: EXPANDEDNAME -// 37: IMPLCLASS PRESUPER/M -// 38: TRANS_FLAG -// 39: LOCKED -// 40: SPECIALIZED -// 41: DEFAULTINIT/M -// 42: VBRIDGE -// 43: VARARGS -// 44: TRIEDCOOKING -// 45: -// 46: -// 47: -// 48: -// 49: -// 50: -// 51: lateDEFERRED -// 52: lateFINAL -// 53: lateMETHOD -// 54: lateINTERFACE -// 55: lateMODULE -// 56: notPROTECTED -// 57: notOVERRIDE -// 58: notPRIVATE -// 59: -// 60: -// 61: -// 62: -// 63: - -/** Flags set on Modifiers instances in the parsing stage. - */ -class ModifierFlags { - final val IMPLICIT = 1 << 9 - final val FINAL = 1 << 5 // May not be overridden. Note that java final implies much more than scala final. - final val PRIVATE = 1 << 2 - final val PROTECTED = 1 << 0 - - final val SEALED = 1 << 10 - final val OVERRIDE = 1 << 1 - final val CASE = 1 << 11 - final val ABSTRACT = 1 << 3 // abstract class, or used in conjunction with abstract override. - // Note difference to DEFERRED! - final val DEFERRED = 1 << 4 // was `abstract' for members | trait is virtual - final val INTERFACE = 1 << 7 // symbol is an interface (i.e. a trait which defines only abstract methods) - final val MUTABLE = 1 << 12 // symbol is a mutable variable. - final val PARAM = 1 << 13 // symbol is a (value or type) parameter to a method - final val MACRO = 1 << 15 // symbol is a macro definition - - final val COVARIANT = 1 << 16 // symbol is a covariant type variable - final val BYNAMEPARAM = 1 << 16 // parameter is by name - final val CONTRAVARIANT = 1 << 17 // symbol is a contravariant type variable - final val ABSOVERRIDE = 1 << 18 // combination of abstract & override - final val LOCAL = 1 << 19 // symbol is local to current class (i.e. private[this] or protected[this] - // pre: PRIVATE or PROTECTED are also set - final val JAVA = 1 << 20 // symbol was defined by a Java class - final val STATIC = 1 << 23 // static field, method or class - final val CASEACCESSOR = 1 << 24 // symbol is a case parameter (or its accessor, or a GADT skolem) - final val TRAIT = 1 << 25 // symbol is a trait - final val DEFAULTPARAM = 1 << 25 // the parameter has a default value - final val PARAMACCESSOR = 1 << 29 // for field definitions generated for primary constructor - // parameters (no matter if it's a 'val' parameter or not) - // for parameters of a primary constructor ('val' or not) - // for the accessor methods generated for 'val' or 'var' parameters - final val LAZY = 1L << 31 // symbol is a lazy val. can't have MUTABLE unless transformed by typer - final val PRESUPER = 1L << 37 // value is evaluated before super call - final val DEFAULTINIT = 1L << 41 // symbol is initialized to the default value: used by -Xcheckinit - - // Overridden. - def flagToString(flag: Long): String = "" - - final val PrivateLocal = PRIVATE | LOCAL - final val ProtectedLocal = PROTECTED | LOCAL - final val AccessFlags = PRIVATE | PROTECTED | LOCAL -} -object ModifierFlags extends ModifierFlags - -/** All flags and associated operatins */ -class Flags extends ModifierFlags { - final val METHOD = 1 << 6 // a method - final val MODULE = 1 << 8 // symbol is module or class implementing a module - final val PACKAGE = 1 << 14 // symbol is a java package - - final val CAPTURED = 1 << 16 // variable is accessed from nested function. Set by LambdaLift. - final val LABEL = 1 << 17 // method symbol is a label. Set by TailCall - final val INCONSTRUCTOR = 1 << 17 // class symbol is defined in this/superclass constructor. - final val SYNTHETIC = 1 << 21 // symbol is compiler-generated - final val STABLE = 1 << 22 // functions that are assumed to be stable - // (typically, access methods for valdefs) - // or classes that do not contain abstract types. - final val BRIDGE = 1 << 26 // function is a bridge method. Set by Erasure - final val ACCESSOR = 1 << 27 // a value or variable accessor (getter or setter) - - final val SUPERACCESSOR = 1 << 28 // a super accessor - final val MODULEVAR = 1 << 30 // for variables: is the variable caching a module value - - final val IS_ERROR = 1L << 32 // symbol is an error symbol - final val OVERLOADED = 1L << 33 // symbol is overloaded - final val LIFTED = 1L << 34 // class has been lifted out to package level - // local value has been lifted out to class level - // todo: make LIFTED = latePRIVATE? - final val MIXEDIN = 1L << 35 // term member has been mixed in - final val EXISTENTIAL = 1L << 35 // type is an existential parameter or skolem - final val EXPANDEDNAME = 1L << 36 // name has been expanded with class suffix - final val IMPLCLASS = 1L << 37 // symbol is an implementation class - final val TRANS_FLAG = 1L << 38 // transient flag guaranteed to be reset after each phase. - - final val LOCKED = 1L << 39 // temporary flag to catch cyclic dependencies - final val SPECIALIZED = 1L << 40 // symbol is a generated specialized member - final val VBRIDGE = 1L << 42 // symbol is a varargs bridge - - final val VARARGS = 1L << 43 // symbol is a Java-style varargs method - final val TRIEDCOOKING = 1L << 44 // ``Cooking'' has been tried on this symbol - // A Java method's type is ``cooked'' by transforming raw types to existentials - - final val SYNCHRONIZED = 1L << 45 // symbol is a method which should be marked ACC_SYNCHRONIZED - // ------- shift definitions ------------------------------------------------------- - - final val InitialFlags = 0x0001FFFFFFFFFFFFL // flags that are enabled from phase 1. - final val LateFlags = 0x00FE000000000000L // flags that override flags in 0x1FC. - final val AntiFlags = 0x7F00000000000000L // flags that cancel flags in 0x07F - final val LateShift = 47L - final val AntiShift = 56L - - // Flags which sketchily share the same slot - val OverloadedFlagsMask = 0L | BYNAMEPARAM | CONTRAVARIANT | DEFAULTPARAM | EXISTENTIAL | IMPLCLASS - - // ------- late flags (set by a transformer phase) --------------------------------- - // - // Summary of when these are claimed to be first used. - // You can get this output with scalac -Xshow-phases -Ydebug. - // - // refchecks 7 [START] <latemethod> - // specialize 13 [START] <latefinal> <notprivate> - // explicitouter 14 [START] <notprotected> - // erasure 15 [START] <latedeferred> <lateinterface> - // mixin 20 [START] <latemodule> <notoverride> - // - // lateMETHOD set in RefChecks#transformInfo. - // lateFINAL set in Symbols#makeNotPrivate. - // notPRIVATE set in Symbols#makeNotPrivate, IExplicitOuter#transform, Inliners. - // notPROTECTED set in ExplicitOuter#transform. - // lateDEFERRED set in AddInterfaces, Mixin, etc. - // lateINTERFACE set in AddInterfaces#transformMixinInfo. - // lateMODULE set in Mixin#transformInfo. - // notOVERRIDE set in Mixin#preTransform. - - final val lateDEFERRED = (DEFERRED: Long) << LateShift - final val lateFINAL = (FINAL: Long) << LateShift - final val lateINTERFACE = (INTERFACE: Long) << LateShift - final val lateMETHOD = (METHOD: Long) << LateShift - final val lateMODULE = (MODULE: Long) << LateShift - - final val notOVERRIDE = (OVERRIDE: Long) << AntiShift - final val notPRIVATE = (PRIVATE: Long) << AntiShift - final val notPROTECTED = (PROTECTED: Long) << AntiShift - - // ------- masks ----------------------------------------------------------------------- - - /** To be a little clearer to people who aren't habitual bit twiddlers. - */ - final val AllFlags = -1L - - /** These flags can be set when class or module symbol is first created. - * They are the only flags to survive a call to resetFlags(). - */ - final val TopLevelCreationFlags = - MODULE | PACKAGE | FINAL | JAVA - - // TODO - there's no call to slap four flags onto every package. - final val PackageFlags = TopLevelCreationFlags - - // FINAL not included here due to possibility of object overriding. - // In fact, FINAL should not be attached regardless. We should be able - // to reconstruct whether an object was marked final in source. - final val ModuleFlags = MODULE - - /** These modifiers can be set explicitly in source programs. This is - * used only as the basis for the default flag mask (which ones to display - * when printing a normal message.) - */ - final val ExplicitFlags = - PRIVATE | PROTECTED | ABSTRACT | FINAL | SEALED | - OVERRIDE | CASE | IMPLICIT | ABSOVERRIDE | LAZY - - /** The two bridge flags */ - final val BridgeFlags = BRIDGE | VBRIDGE - final val BridgeAndPrivateFlags = BridgeFlags | PRIVATE - - /** These modifiers appear in TreePrinter output. */ - final val PrintableFlags = - ExplicitFlags | BridgeFlags | LOCAL | SYNTHETIC | STABLE | CASEACCESSOR | MACRO | - ACCESSOR | SUPERACCESSOR | PARAMACCESSOR | STATIC | SPECIALIZED | SYNCHRONIZED - - /** When a symbol for a field is created, only these flags survive - * from Modifiers. Others which may be applied at creation time are: - * PRIVATE, LOCAL. - */ - final val FieldFlags = - MUTABLE | CASEACCESSOR | PARAMACCESSOR | STATIC | FINAL | PRESUPER | LAZY - - /** Masks for getters and setters, where the flags are derived from those - * on the field's modifiers. Both getters and setters get the ACCESSOR flag. - * Getters of immutable values also get STABLE. - */ - final val GetterFlags = ~(PRESUPER | MUTABLE) - final val SetterFlags = ~(PRESUPER | MUTABLE | STABLE | CASEACCESSOR) - - /** When a symbol for a default getter is created, it inherits these - * flags from the method with the default. Other flags applied at creation - * time are SYNTHETIC, DEFAULTPARAM, and possibly OVERRIDE, and maybe PRESUPER. - */ - final val DefaultGetterFlags = PRIVATE | PROTECTED | FINAL - - /** When a symbol for a method parameter is created, only these flags survive - * from Modifiers. Others which may be applied at creation time are: - * SYNTHETIC. - */ - final val ValueParameterFlags = BYNAMEPARAM | IMPLICIT | DEFAULTPARAM - final val BeanPropertyFlags = DEFERRED | OVERRIDE | STATIC - final val VarianceFlags = COVARIANT | CONTRAVARIANT - - /** These appear to be flags which should be transferred from owner symbol - * to a newly created constructor symbol. - */ - final val ConstrFlags = JAVA - - /** Module flags inherited by their module-class */ - final val ModuleToClassFlags = AccessFlags | TopLevelCreationFlags | CASE | SYNTHETIC - - def getterFlags(fieldFlags: Long): Long = ACCESSOR + ( - if ((fieldFlags & MUTABLE) != 0) fieldFlags & ~MUTABLE & ~PRESUPER - else fieldFlags & ~PRESUPER | STABLE - ) - - def setterFlags(fieldFlags: Long): Long = - getterFlags(fieldFlags) & ~STABLE & ~CASEACCESSOR - - // ------- pickling and unpickling of flags ----------------------------------------------- - - // The flags from 0x001 to 0x800 are different in the raw flags - // and in the pickled format. - - private final val IMPLICIT_PKL = (1 << 0) - private final val FINAL_PKL = (1 << 1) - private final val PRIVATE_PKL = (1 << 2) - private final val PROTECTED_PKL = (1 << 3) - private final val SEALED_PKL = (1 << 4) - private final val OVERRIDE_PKL = (1 << 5) - private final val CASE_PKL = (1 << 6) - private final val ABSTRACT_PKL = (1 << 7) - private final val DEFERRED_PKL = (1 << 8) - private final val METHOD_PKL = (1 << 9) - private final val MODULE_PKL = (1 << 10) - private final val INTERFACE_PKL = (1 << 11) - - private final val PKL_MASK = 0x00000FFF - - final val PickledFlags = 0xFFFFFFFFL - - private def rawPickledCorrespondence = Array( - (IMPLICIT, IMPLICIT_PKL), - (FINAL, FINAL_PKL), - (PRIVATE, PRIVATE_PKL), - (PROTECTED, PROTECTED_PKL), - (SEALED, SEALED_PKL), - (OVERRIDE, OVERRIDE_PKL), - (CASE, CASE_PKL), - (ABSTRACT, ABSTRACT_PKL), - (DEFERRED, DEFERRED_PKL), - (METHOD, METHOD_PKL), - (MODULE, MODULE_PKL), - (INTERFACE, INTERFACE_PKL) - ) - private val rawFlags: Array[Int] = rawPickledCorrespondence map (_._1) - private val pickledFlags: Array[Int] = rawPickledCorrespondence map (_._2) - - private def r2p(flags: Int): Int = { - var result = 0 - var i = 0 - while (i < rawFlags.length) { - if ((flags & rawFlags(i)) != 0) - result |= pickledFlags(i) - - i += 1 - } - result - } - private def p2r(flags: Int): Int = { - var result = 0 - var i = 0 - while (i < rawFlags.length) { - if ((flags & pickledFlags(i)) != 0) - result |= rawFlags(i) - - i += 1 - } - result - } - - // ------ displaying flags -------------------------------------------------------- - - // Generated by mkFlagToStringMethod() at Thu Feb 02 20:31:52 PST 2012 - @annotation.switch override def flagToString(flag: Long): String = flag match { - case PROTECTED => "protected" // (1L << 0) - case OVERRIDE => "override" // (1L << 1) - case PRIVATE => "private" // (1L << 2) - case ABSTRACT => "abstract" // (1L << 3) - case DEFERRED => "<deferred>" // (1L << 4) - case FINAL => "final" // (1L << 5) - case METHOD => "<method>" // (1L << 6) - case INTERFACE => "<interface>" // (1L << 7) - case MODULE => "<module>" // (1L << 8) - case IMPLICIT => "implicit" // (1L << 9) - case SEALED => "sealed" // (1L << 10) - case CASE => "case" // (1L << 11) - case MUTABLE => "<mutable>" // (1L << 12) - case PARAM => "<param>" // (1L << 13) - case PACKAGE => "<package>" // (1L << 14) - case MACRO => "<macro>" // (1L << 15) - case BYNAMEPARAM => "<bynameparam/captured/covariant>" // (1L << 16) - case CONTRAVARIANT => "<contravariant/inconstructor/label>" // (1L << 17) - case ABSOVERRIDE => "absoverride" // (1L << 18) - case LOCAL => "<local>" // (1L << 19) - case JAVA => "<java>" // (1L << 20) - case SYNTHETIC => "<synthetic>" // (1L << 21) - case STABLE => "<stable>" // (1L << 22) - case STATIC => "<static>" // (1L << 23) - case CASEACCESSOR => "<caseaccessor>" // (1L << 24) - case DEFAULTPARAM => "<defaultparam/trait>" // (1L << 25) - case BRIDGE => "<bridge>" // (1L << 26) - case ACCESSOR => "<accessor>" // (1L << 27) - case SUPERACCESSOR => "<superaccessor>" // (1L << 28) - case PARAMACCESSOR => "<paramaccessor>" // (1L << 29) - case MODULEVAR => "<modulevar>" // (1L << 30) - case LAZY => "lazy" // (1L << 31) - case IS_ERROR => "<is_error>" // (1L << 32) - case OVERLOADED => "<overloaded>" // (1L << 33) - case LIFTED => "<lifted>" // (1L << 34) - case EXISTENTIAL => "<existential/mixedin>" // (1L << 35) - case EXPANDEDNAME => "<expandedname>" // (1L << 36) - case IMPLCLASS => "<implclass/presuper>" // (1L << 37) - case TRANS_FLAG => "<trans_flag>" // (1L << 38) - case LOCKED => "<locked>" // (1L << 39) - case SPECIALIZED => "<specialized>" // (1L << 40) - case DEFAULTINIT => "<defaultinit>" // (1L << 41) - case VBRIDGE => "<vbridge>" // (1L << 42) - case VARARGS => "<varargs>" // (1L << 43) - case TRIEDCOOKING => "<triedcooking>" // (1L << 44) - case SYNCHRONIZED => "<synchronized>" // (1L << 45) - case 0x400000000000L => "" // (1L << 46) - case 0x800000000000L => "" // (1L << 47) - case 0x1000000000000L => "" // (1L << 48) - case 0x2000000000000L => "" // (1L << 49) - case 0x4000000000000L => "" // (1L << 50) - case `lateDEFERRED` => "<latedeferred>" // (1L << 51) - case `lateFINAL` => "<latefinal>" // (1L << 52) - case `lateMETHOD` => "<latemethod>" // (1L << 53) - case `lateINTERFACE` => "<lateinterface>" // (1L << 54) - case `lateMODULE` => "<latemodule>" // (1L << 55) - case `notPROTECTED` => "<notprotected>" // (1L << 56) - case `notOVERRIDE` => "<notoverride>" // (1L << 57) - case `notPRIVATE` => "<notprivate>" // (1L << 58) - case 0x800000000000000L => "" // (1L << 59) - case 0x1000000000000000L => "" // (1L << 60) - case 0x2000000000000000L => "" // (1L << 61) - case 0x4000000000000000L => "" // (1L << 62) - case 0x8000000000000000L => "" // (1L << 63) - case _ => "" - } - - private def accessString(flags: Long, privateWithin: String)= ( - if (privateWithin == "") { - if ((flags & PrivateLocal) == PrivateLocal) "private[this]" - else if ((flags & ProtectedLocal) == ProtectedLocal) "protected[this]" - else if ((flags & PRIVATE) != 0) "private" - else if ((flags & PROTECTED) != 0) "protected" - else "" - } - else if ((flags & PROTECTED) != 0) "protected[" + privateWithin + "]" - else "private[" + privateWithin + "]" - ) - - @deprecated("Use flagString on the flag-carrying member", "2.10.0") - def flagsToString(flags: Long, privateWithin: String): String = { - val access = accessString(flags, privateWithin) - val nonAccess = flagsToString(flags & ~AccessFlags) - - List(nonAccess, access) filterNot (_ == "") mkString " " - } - - @deprecated("Use flagString on the flag-carrying member", "2.10.0") - def flagsToString(flags: Long): String = { - // Fast path for common case - if (flags == 0L) "" else { - var sb: StringBuilder = null - var i = 0 - while (i <= MaxBitPosition) { - val mask = rawFlagPickledOrder(i) - if ((flags & mask) != 0L) { - val s = flagToString(mask) - if (s.length > 0) { - if (sb eq null) sb = new StringBuilder append s - else if (sb.length == 0) sb append s - else sb append " " append s - } - } - i += 1 - } - if (sb eq null) "" else sb.toString - } - } - - def rawFlagsToPickled(flags: Long): Long = - (flags & ~PKL_MASK) | r2p(flags.toInt & PKL_MASK) - - def pickledToRawFlags(pflags: Long): Long = - (pflags & ~PKL_MASK) | p2r(pflags.toInt & PKL_MASK) - - // List of the raw flags, in pickled order - final val MaxBitPosition = 62 - - final val pickledListOrder: List[Long] = { - val all = 0 to MaxBitPosition map (1L << _) - val front = rawFlags map (_.toLong) - - front.toList ++ (all filterNot (front contains _)) - } - final val rawFlagPickledOrder: Array[Long] = pickledListOrder.toArray -} - -object Flags extends Flags { } diff --git a/src/compiler/scala/reflect/internal/HasFlags.scala b/src/compiler/scala/reflect/internal/HasFlags.scala deleted file mode 100644 index c7c0882209..0000000000 --- a/src/compiler/scala/reflect/internal/HasFlags.scala +++ /dev/null @@ -1,169 +0,0 @@ -package scala.reflect -package internal - -import Flags._ - -/** Common code utilized by Modifiers (which carry the flags associated - * with Trees) and Symbol. - */ -trait HasFlags { - type AccessBoundaryType - type AnnotationType - - /** Though both Symbol and Modifiers widen this method to public, it's - * defined protected here to give us the option in the future to route - * flag methods through accessors and disallow raw flag manipulation. - * And after that, perhaps, on some magical day: a typesafe enumeration. - */ - protected def flags: Long - - /** Access level encoding: there are three scala flags (PRIVATE, PROTECTED, - * and LOCAL) which combine with value privateWithin (the "foo" in private[foo]) - * to define from where an entity can be accessed. The meanings are as follows: - * - * PRIVATE access restricted to class only. - * PROTECTED access restricted to class and subclasses only. - * LOCAL can only be set in conjunction with PRIVATE or PROTECTED. - * Further restricts access to the same object instance. - * - * In addition, privateWithin can be used to set a visibility barrier. - * When set, everything contained in the named enclosing package or class - * has access. It is incompatible with PRIVATE or LOCAL, but is additive - * with PROTECTED (i.e. if either the flags or privateWithin allow access, - * then it is allowed.) - * - * The java access levels translate as follows: - * - * java private: hasFlag(PRIVATE) && !hasAccessBoundary - * java package: !hasFlag(PRIVATE | PROTECTED) && (privateWithin == enclosing package) - * java protected: hasFlag(PROTECTED) && (privateWithin == enclosing package) - * java public: !hasFlag(PRIVATE | PROTECTED) && !hasAccessBoundary - */ - def privateWithin: AccessBoundaryType - - /** A list of annotations attached to this entity. - */ - def annotations: List[AnnotationType] - - /** Whether this entity has a "privateWithin" visibility barrier attached. - */ - def hasAccessBoundary: Boolean - - /** Whether this entity has ANY of the flags in the given mask. - */ - def hasFlag(flag: Long): Boolean - - /** Whether this entity has ALL of the flags in the given mask. - */ - def hasAllFlags(mask: Long): Boolean - - /** Whether this entity has NONE of the flags in the given mask. - */ - def hasNoFlags(mask: Long): Boolean = !hasFlag(mask) - - /** The printable representation of this entity's flags and access boundary, - * restricted to flags in the given mask. - */ - def flagString: String = flagString(flagMask) - def flagString(mask: Long): String = calculateFlagString(flags & mask) - - /** The default mask determining which flags to display. - */ - def flagMask: Long = AllFlags - - /** The string representation of a single bit, seen from this - * flag carrying entity. - */ - def resolveOverloadedFlag(flag: Long): String = Flags.flagToString(flag) - - // Tests which come through cleanly: both Symbol and Modifiers use these - // identically, testing for a single flag. - def hasAbstractFlag = hasFlag(ABSTRACT) - def hasAccessorFlag = hasFlag(ACCESSOR) - def hasDefault = hasAllFlags(DEFAULTPARAM | PARAM) - def hasLocalFlag = hasFlag(LOCAL) - def hasModuleFlag = hasFlag(MODULE) - def hasPackageFlag = hasFlag(PACKAGE) - def hasStableFlag = hasFlag(STABLE) - def hasStaticFlag = hasFlag(STATIC) - def isAbstractOverride = hasFlag(ABSOVERRIDE) - def isAnyOverride = hasFlag(OVERRIDE | ABSOVERRIDE) - def isCase = hasFlag(CASE) - def isCaseAccessor = hasFlag(CASEACCESSOR) - def isDeferred = hasFlag(DEFERRED) - def isFinal = hasFlag(FINAL) - def isImplicit = hasFlag(IMPLICIT) - def isInterface = hasFlag(INTERFACE) - def isJavaDefined = hasFlag(JAVA) - def isLabel = hasAllFlags(LABEL | METHOD) && !hasAccessorFlag - def isLazy = hasFlag(LAZY) - def isLifted = hasFlag(LIFTED) - def isMutable = hasFlag(MUTABLE) - def isOverride = hasFlag(OVERRIDE) - def isParamAccessor = hasFlag(PARAMACCESSOR) - def isPrivate = hasFlag(PRIVATE) - def isPackage = hasFlag(PACKAGE) - def isPrivateLocal = hasAllFlags(PrivateLocal) - def isProtected = hasFlag(PROTECTED) - def isProtectedLocal = hasAllFlags(ProtectedLocal) - def isPublic = hasNoFlags(PRIVATE | PROTECTED) && !hasAccessBoundary - def isSealed = hasFlag(SEALED) - def isSuperAccessor = hasFlag(SUPERACCESSOR) - def isSynthetic = hasFlag(SYNTHETIC) - def isTrait = hasFlag(TRAIT) && !hasFlag(PARAM) - - def flagBitsToString(bits: Long): String = { - // Fast path for common case - if (bits == 0L) "" else { - var sb: StringBuilder = null - var i = 0 - while (i <= MaxBitPosition) { - val flag = Flags.rawFlagPickledOrder(i) - if ((bits & flag) != 0L) { - val s = resolveOverloadedFlag(flag) - if (s.length > 0) { - if (sb eq null) sb = new StringBuilder append s - else if (sb.length == 0) sb append s - else sb append " " append s - } - } - i += 1 - } - if (sb eq null) "" else sb.toString - } - } - - def accessString: String = { - val pw = if (hasAccessBoundary) privateWithin.toString else "" - - if (pw == "") { - if (hasAllFlags(PrivateLocal)) "private[this]" - else if (hasAllFlags(ProtectedLocal)) "protected[this]" - else if (hasFlag(PRIVATE)) "private" - else if (hasFlag(PROTECTED)) "protected" - else "" - } - else if (hasFlag(PROTECTED)) "protected[" + pw + "]" - else "private[" + pw + "]" - } - protected def calculateFlagString(basis: Long): String = { - val access = accessString - val nonAccess = flagBitsToString(basis & ~AccessFlags) - - if (access == "") nonAccess - else if (nonAccess == "") access - else nonAccess + " " + access - } - - // Backward compat section - @deprecated( "Use isTrait", "2.10.0") - def hasTraitFlag = hasFlag(TRAIT) - @deprecated("Use hasDefault", "2.10.0") - def hasDefaultFlag = hasFlag(DEFAULTPARAM) - @deprecated("Use isValueParameter or isTypeParameter", "2.10.0") - def isParameter = hasFlag(PARAM) - @deprecated("Use flagString", "2.10.0") - def defaultFlagString = flagString - @deprecated("Use flagString(mask)", "2.10.0") - def hasFlagsToString(mask: Long): String = flagString(mask) -} diff --git a/src/compiler/scala/reflect/internal/Importers.scala b/src/compiler/scala/reflect/internal/Importers.scala deleted file mode 100644 index 431d9819a5..0000000000 --- a/src/compiler/scala/reflect/internal/Importers.scala +++ /dev/null @@ -1,451 +0,0 @@ -package scala.reflect -package internal -import scala.collection.mutable.WeakHashMap - -// todo: move importers to a mirror -trait Importers { self: SymbolTable => - - // [Eugene] possible to make this less cast-heavy? - def mkImporter(from0: api.Universe): Importer { val from: from0.type } = ( - if (self eq from0) { - new Importer { - val from = from0 - val reverse = this.asInstanceOf[from.Importer{ val from: self.type }] - def importSymbol(sym: from.Symbol) = sym.asInstanceOf[self.Symbol] - def importType(tpe: from.Type) = tpe.asInstanceOf[self.Type] - def importTree(tree: from.Tree) = tree.asInstanceOf[self.Tree] - } - } else { - // todo. fix this loophole - assert(from0.isInstanceOf[SymbolTable], "`from` should be an instance of scala.reflect.internal.SymbolTable") - new StandardImporter { val from = from0.asInstanceOf[SymbolTable] } - } - ).asInstanceOf[Importer { val from: from0.type }] - - abstract class StandardImporter extends Importer { - - val from: SymbolTable - - lazy val symMap: WeakHashMap[from.Symbol, Symbol] = new WeakHashMap - lazy val tpeMap: WeakHashMap[from.Type, Type] = new WeakHashMap - - // fixups and maps prevent stackoverflows in importer - var pendingSyms = 0 - var pendingTpes = 0 - lazy val fixups = collection.mutable.MutableList[Function0[Unit]]() - def addFixup(fixup: => Unit): Unit = fixups += (() => fixup) - def tryFixup(): Unit = { - if (pendingSyms == 0 && pendingTpes == 0) { - val fixups = this.fixups.toList - this.fixups.clear() - fixups foreach { _() } - } - } - - object reverse extends from.StandardImporter { - val from: self.type = self - for ((fromsym, mysym) <- StandardImporter.this.symMap) symMap += ((mysym, fromsym)) - for ((fromtpe, mytpe) <- StandardImporter.this.tpeMap) tpeMap += ((mytpe, fromtpe)) - } - - // todo. careful import of positions - def importPosition(pos: from.Position): Position = - pos.asInstanceOf[Position] - - def importSymbol(sym0: from.Symbol): Symbol = { - def doImport(sym: from.Symbol): Symbol = { - if (symMap.contains(sym)) - return symMap(sym) - - val myowner = importSymbol(sym.owner) - val mypos = importPosition(sym.pos) - val myname = importName(sym.name).toTermName - val myflags = sym.flags - def linkReferenced(mysym: TermSymbol, x: from.TermSymbol, op: from.Symbol => Symbol): Symbol = { - symMap(x) = mysym - mysym.referenced = op(x.referenced) - mysym - } - val mysym = sym match { - case x: from.MethodSymbol => - linkReferenced(myowner.newMethod(myname, mypos, myflags), x, importSymbol) - case x: from.ModuleSymbol => - linkReferenced(myowner.newModuleSymbol(myname, mypos, myflags), x, importSymbol) - case x: from.FreeTermSymbol => - newFreeTermSymbol(importName(x.name).toTermName, importType(x.info), x.value, x.flags, x.origin) - case x: from.FreeTypeSymbol => - newFreeTypeSymbol(importName(x.name).toTypeName, importType(x.info), x.value, x.flags, x.origin) - case x: from.TermSymbol => - linkReferenced(myowner.newValue(myname, mypos, myflags), x, importSymbol) - case x: from.TypeSkolem => - val origin = x.unpackLocation match { - case null => null - case y: from.Tree => importTree(y) - case y: from.Symbol => importSymbol(y) - } - myowner.newTypeSkolemSymbol(myname.toTypeName, origin, mypos, myflags) - case x: from.ModuleClassSymbol => - val mysym = myowner.newModuleClass(myname.toTypeName, mypos, myflags) - symMap(x) = mysym - mysym.sourceModule = importSymbol(x.sourceModule) - mysym - case x: from.ClassSymbol => - val mysym = myowner.newClassSymbol(myname.toTypeName, mypos, myflags) - symMap(x) = mysym - if (sym.thisSym != sym) { - mysym.typeOfThis = importType(sym.typeOfThis) - mysym.thisSym setName importName(sym.thisSym.name) - } - mysym - case x: from.TypeSymbol => - myowner.newTypeSymbol(myname.toTypeName, mypos, myflags) - } - symMap(sym) = mysym - mysym setFlag Flags.LOCKED - mysym setInfo { - val mytypeParams = sym.typeParams map importSymbol - new LazyPolyType(mytypeParams) { - override def complete(s: Symbol) { - val result = sym.info match { - case from.PolyType(_, res) => res - case result => result - } - s setInfo GenPolyType(mytypeParams, importType(result)) - s setAnnotations (sym.annotations map importAnnotationInfo) - } - } - } - mysym resetFlag Flags.LOCKED - } // end doImport - - def importOrRelink: Symbol = { - val sym = sym0 // makes sym visible in the debugger - if (sym == null) - null - else if (sym == from.NoSymbol) - NoSymbol - else if (sym.isRoot) - rootMirror.RootClass // !!! replace with actual mirror when we move importers to the mirror - else { - val name = sym.name - val owner = sym.owner - var scope = if (owner.isClass && !owner.isRefinementClass) owner.info else from.NoType - var existing = scope.decl(name) - if (sym.isModuleClass) - existing = existing.moduleClass - - if (!existing.exists) scope = from.NoType - - val myname = importName(name) - val myowner = importSymbol(owner) - val myscope = if (scope != from.NoType && !(myowner hasFlag Flags.LOCKED)) myowner.info else NoType - var myexisting = if (myscope != NoType) myowner.info.decl(myname) else NoSymbol // cannot load myexisting in general case, because it creates cycles for methods - if (sym.isModuleClass) - myexisting = importSymbol(sym.sourceModule).moduleClass - - if (!sym.isOverloaded && myexisting.isOverloaded) { - myexisting = - if (sym.isMethod) { - val localCopy = doImport(sym) - myexisting filter (_.tpe matches localCopy.tpe) - } else { - myexisting filter (!_.isMethod) - } - assert(!myexisting.isOverloaded, - "import failure: cannot determine unique overloaded method alternative from\n "+ - (myexisting.alternatives map (_.defString) mkString "\n")+"\n that matches "+sym+":"+sym.tpe) - } - - val mysym = { - if (sym.isOverloaded) { - myowner.newOverloaded(myowner.thisType, sym.alternatives map importSymbol) - } else if (sym.isTypeParameter && sym.paramPos >= 0 && !(myowner hasFlag Flags.LOCKED)) { - assert(myowner.typeParams.length > sym.paramPos, - "import failure: cannot determine parameter "+sym+" (#"+sym.paramPos+") in "+ - myowner+typeParamsString(myowner.rawInfo)+"\n original symbol was: "+ - sym.owner+from.typeParamsString(sym.owner.info)) - myowner.typeParams(sym.paramPos) - } else { - if (myexisting != NoSymbol) { - myexisting - } else { - val mysym = doImport(sym) - - if (myscope != NoType) { - assert(myowner.info.decls.lookup(myname) == NoSymbol, myname+" "+myowner.info.decl(myname)+" "+myexisting) - myowner.info.decls enter mysym - } - - mysym - } - } - } - - mysym - } - } // end importOrRelink - - val sym = sym0 - if (symMap contains sym) { - symMap(sym) - } else { - pendingSyms += 1 - - try { - symMap getOrElseUpdate (sym, importOrRelink) - } finally { - pendingSyms -= 1 - tryFixup() - } - } - } - - def importType(tpe: from.Type): Type = { - def doImport(tpe: from.Type): Type = tpe match { - case from.TypeRef(pre, sym, args) => - TypeRef(importType(pre), importSymbol(sym), args map importType) - case from.ThisType(clazz) => - ThisType(importSymbol(clazz)) - case from.SingleType(pre, sym) => - SingleType(importType(pre), importSymbol(sym)) - case from.MethodType(params, restpe) => - MethodType(params map importSymbol, importType(restpe)) - case from.PolyType(tparams, restpe) => - PolyType(tparams map importSymbol, importType(restpe)) - case from.NullaryMethodType(restpe) => - NullaryMethodType(importType(restpe)) - case from.ConstantType(constant @ from.Constant(_)) => - ConstantType(importConstant(constant)) - case from.SuperType(thistpe, supertpe) => - SuperType(importType(thistpe), importType(supertpe)) - case from.TypeBounds(lo, hi) => - TypeBounds(importType(lo), importType(hi)) - case from.BoundedWildcardType(bounds) => - BoundedWildcardType(importTypeBounds(bounds)) - case from.ClassInfoType(parents, decls, clazz) => - val myclazz = importSymbol(clazz) - val myscope = if (myclazz.isPackageClass) newPackageScope(myclazz) else newScope - val myclazzTpe = ClassInfoType(parents map importType, myscope, myclazz) - myclazz setInfo GenPolyType(myclazz.typeParams, myclazzTpe) // needed so that newly created symbols find their scope - decls foreach importSymbol // will enter itself into myclazz - myclazzTpe - case from.RefinedType(parents, decls) => - RefinedType(parents map importType, importScope(decls), importSymbol(tpe.typeSymbol)) - case from.ExistentialType(tparams, restpe) => - newExistentialType(tparams map importSymbol, importType(restpe)) - case from.OverloadedType(pre, alts) => - OverloadedType(importType(pre), alts map importSymbol) - case from.AntiPolyType(pre, targs) => - AntiPolyType(importType(pre), targs map importType) - case x: from.TypeVar => - TypeVar(importType(x.origin), importTypeConstraint(x.constr0), x.typeArgs map importType, x.params map importSymbol) - case from.NotNullType(tpe) => - NotNullType(importType(tpe)) - case from.AnnotatedType(annots, tpe, selfsym) => - AnnotatedType(annots map importAnnotationInfo, importType(tpe), importSymbol(selfsym)) - case from.ErrorType => - ErrorType - case from.WildcardType => - WildcardType - case from.NoType => - NoType - case from.NoPrefix => - NoPrefix - case null => - null - } // end doImport - - def importOrRelink: Type = - doImport(tpe) - - if (tpeMap contains tpe) { - tpeMap(tpe) - } else { - pendingTpes += 1 - - try { - tpeMap getOrElseUpdate (tpe, importOrRelink) - } finally { - pendingTpes -= 1 - tryFixup() - } - } - } - - def importTypeBounds(bounds: from.TypeBounds) = importType(bounds).asInstanceOf[TypeBounds] - - def importAnnotationInfo(ann: from.AnnotationInfo): AnnotationInfo = { - val atp1 = importType(ann.atp) - val args1 = ann.args map importTree - val assocs1 = ann.assocs map { case (name, arg) => (importName(name), importAnnotArg(arg)) } - val original1 = importTree(ann.original) - AnnotationInfo(atp1, args1, assocs1) setOriginal original1 - } - - def importAnnotArg(arg: from.ClassfileAnnotArg): ClassfileAnnotArg = arg match { - case from.LiteralAnnotArg(constant @ from.Constant(_)) => - LiteralAnnotArg(importConstant(constant)) - case from.ArrayAnnotArg(args) => - ArrayAnnotArg(args map importAnnotArg) - case from.ScalaSigBytes(bytes) => - ScalaSigBytes(bytes) - case from.NestedAnnotArg(annInfo) => - NestedAnnotArg(importAnnotationInfo(annInfo)) - } - - def importTypeConstraint(constr: from.TypeConstraint): TypeConstraint = { - val result = new TypeConstraint(constr.loBounds map importType, constr.hiBounds map importType) - result.inst = importType(constr.inst) - result - } - - // !!! todo: override to cater for PackageScopes - def importScope(decls: from.Scope): Scope = - newScopeWith(decls.toList map importSymbol: _*) - - def importName(name: from.Name): Name = - if (name.isTypeName) newTypeName(name.toString) else newTermName(name.toString) - def importTypeName(name: from.TypeName): TypeName = importName(name).toTypeName - def importTermName(name: from.TermName): TermName = importName(name).toTermName - - def importModifiers(mods: from.Modifiers): Modifiers = - new Modifiers(mods.flags, importName(mods.privateWithin), mods.annotations map importTree) - - def importImportSelector(sel: from.ImportSelector): ImportSelector = - new ImportSelector(importName(sel.name), sel.namePos, if (sel.rename != null) importName(sel.rename) else null, sel.renamePos) - - def importTree(tree: from.Tree): Tree = { - val mytree = tree match { - case from.ClassDef(mods, name, tparams, impl) => - new ClassDef(importModifiers(mods), importName(name).toTypeName, tparams map importTypeDef, importTemplate(impl)) - case from.PackageDef(pid, stats) => - new PackageDef(importRefTree(pid), stats map importTree) - case from.ModuleDef(mods, name, impl) => - new ModuleDef(importModifiers(mods), importName(name).toTermName, importTemplate(impl)) - case from.emptyValDef => - emptyValDef - case from.ValDef(mods, name, tpt, rhs) => - new ValDef(importModifiers(mods), importName(name).toTermName, importTree(tpt), importTree(rhs)) - case from.DefDef(mods, name, tparams, vparamss, tpt, rhs) => - new DefDef(importModifiers(mods), importName(name).toTermName, tparams map importTypeDef, mmap(vparamss)(importValDef), importTree(tpt), importTree(rhs)) - case from.TypeDef(mods, name, tparams, rhs) => - new TypeDef(importModifiers(mods), importName(name).toTypeName, tparams map importTypeDef, importTree(rhs)) - case from.LabelDef(name, params, rhs) => - new LabelDef(importName(name).toTermName, params map importIdent, importTree(rhs)) - case from.Import(expr, selectors) => - new Import(importTree(expr), selectors map importImportSelector) - case from.Template(parents, self, body) => - new Template(parents map importTree, importValDef(self), body map importTree) - case from.Block(stats, expr) => - new Block(stats map importTree, importTree(expr)) - case from.CaseDef(pat, guard, body) => - new CaseDef(importTree(pat), importTree(guard), importTree(body)) - case from.Alternative(trees) => - new Alternative(trees map importTree) - case from.Star(elem) => - new Star(importTree(elem)) - case from.Bind(name, body) => - new Bind(importName(name), importTree(body)) - case from.UnApply(fun, args) => - new UnApply(importTree(fun), args map importTree) - case from.ArrayValue(elemtpt ,elems) => - new ArrayValue(importTree(elemtpt), elems map importTree) - case from.Function(vparams, body) => - new Function(vparams map importValDef, importTree(body)) - case from.Assign(lhs, rhs) => - new Assign(importTree(lhs), importTree(rhs)) - case from.AssignOrNamedArg(lhs, rhs) => - new AssignOrNamedArg(importTree(lhs), importTree(rhs)) - case from.If(cond, thenp, elsep) => - new If(importTree(cond), importTree(thenp), importTree(elsep)) - case from.Match(selector, cases) => - new Match(importTree(selector), cases map importCaseDef) - case from.Return(expr) => - new Return(importTree(expr)) - case from.Try(block, catches, finalizer) => - new Try(importTree(block), catches map importCaseDef, importTree(finalizer)) - case from.Throw(expr) => - new Throw(importTree(expr)) - case from.New(tpt) => - new New(importTree(tpt)) - case from.Typed(expr, tpt) => - new Typed(importTree(expr), importTree(tpt)) - case from.TypeApply(fun, args) => - new TypeApply(importTree(fun), args map importTree) - case from.Apply(fun, args) => tree match { - case _: from.ApplyToImplicitArgs => - new ApplyToImplicitArgs(importTree(fun), args map importTree) - case _: from.ApplyImplicitView => - new ApplyImplicitView(importTree(fun), args map importTree) - case _ => - new Apply(importTree(fun), args map importTree) - } - case from.ApplyDynamic(qual, args) => - new ApplyDynamic(importTree(qual), args map importTree) - case from.Super(qual, mix) => - new Super(importTree(qual), importTypeName(mix)) - case from.This(qual) => - new This(importName(qual).toTypeName) - case from.Select(qual, name) => - new Select(importTree(qual), importName(name)) - case from.Ident(name) => - new Ident(importName(name)) - case from.ReferenceToBoxed(ident) => - new ReferenceToBoxed(importTree(ident) match { case ident: Ident => ident }) - case from.Literal(constant @ from.Constant(_)) => - new Literal(importConstant(constant)) - case from.TypeTree() => - new TypeTree() - case from.Annotated(annot, arg) => - new Annotated(importTree(annot), importTree(arg)) - case from.SingletonTypeTree(ref) => - new SingletonTypeTree(importTree(ref)) - case from.SelectFromTypeTree(qual, name) => - new SelectFromTypeTree(importTree(qual), importName(name).toTypeName) - case from.CompoundTypeTree(templ) => - new CompoundTypeTree(importTemplate(templ)) - case from.AppliedTypeTree(tpt, args) => - new AppliedTypeTree(importTree(tpt), args map importTree) - case from.TypeBoundsTree(lo, hi) => - new TypeBoundsTree(importTree(lo), importTree(hi)) - case from.ExistentialTypeTree(tpt, whereClauses) => - new ExistentialTypeTree(importTree(tpt), whereClauses map importTree) - case from.EmptyTree => - EmptyTree - case null => - null - } - addFixup({ - if (mytree != null) { - val mysym = if (tree.hasSymbol) importSymbol(tree.symbol) else NoSymbol - val mytpe = importType(tree.tpe) - - mytree match { - case mytt: TypeTree => - val tt = tree.asInstanceOf[from.TypeTree] - if (mytree.hasSymbol) mytt.symbol = mysym - if (tt.wasEmpty) mytt.defineType(mytpe) else mytt.setType(mytpe) - if (tt.original != null) mytt.setOriginal(importTree(tt.original)) - case _ => - if (mytree.hasSymbol) mytree.symbol = importSymbol(tree.symbol) - mytree.tpe = importType(tree.tpe) - } - } - }) - tryFixup() - mytree - } - - def importValDef(tree: from.ValDef): ValDef = importTree(tree).asInstanceOf[ValDef] - def importTypeDef(tree: from.TypeDef): TypeDef = importTree(tree).asInstanceOf[TypeDef] - def importTemplate(tree: from.Template): Template = importTree(tree).asInstanceOf[Template] - def importRefTree(tree: from.RefTree): RefTree = importTree(tree).asInstanceOf[RefTree] - def importIdent(tree: from.Ident): Ident = importTree(tree).asInstanceOf[Ident] - def importCaseDef(tree: from.CaseDef): CaseDef = importTree(tree).asInstanceOf[CaseDef] - def importConstant(constant: from.Constant): Constant = new Constant(constant.tag match { - case ClazzTag => importType(constant.value.asInstanceOf[from.Type]) - case EnumTag => importSymbol(constant.value.asInstanceOf[from.Symbol]) - case _ => constant.value - }) - } -}
\ No newline at end of file diff --git a/src/compiler/scala/reflect/internal/InfoTransformers.scala b/src/compiler/scala/reflect/internal/InfoTransformers.scala deleted file mode 100644 index e53f714c0c..0000000000 --- a/src/compiler/scala/reflect/internal/InfoTransformers.scala +++ /dev/null @@ -1,51 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.reflect -package internal - -trait InfoTransformers { - self: SymbolTable => - - /* Syncnote: This should not need to be protected, as reflection does not run in multiple phases. - */ - abstract class InfoTransformer { - var prev: InfoTransformer = this - var next: InfoTransformer = this - - val pid: Phase#Id - val changesBaseClasses: Boolean - def transform(sym: Symbol, tpe: Type): Type - - def insert(that: InfoTransformer) { - assert(this.pid != that.pid, this.pid) - - if (that.pid < this.pid) { - prev insert that - } else if (next.pid <= that.pid && next.pid != NoPhase.id) { - next insert that - } else { - log("Inserting info transformer %s following %s".format(phaseOf(that.pid), phaseOf(this.pid))) - that.next = next - that.prev = this - next.prev = that - this.next = that - } - } - - /** The InfoTransformer whose (pid == from). - * If no such exists, the InfoTransformer with the next - * higher pid. - */ - def nextFrom(from: Phase#Id): InfoTransformer = - if (from == this.pid) this - else if (from < this.pid) - if (prev.pid < from) this - else prev.nextFrom(from); - else if (next.pid == NoPhase.id) next - else next.nextFrom(from) - } -} - diff --git a/src/compiler/scala/reflect/internal/Kinds.scala b/src/compiler/scala/reflect/internal/Kinds.scala deleted file mode 100644 index b736a9192f..0000000000 --- a/src/compiler/scala/reflect/internal/Kinds.scala +++ /dev/null @@ -1,232 +0,0 @@ -/* NSC -- new scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.reflect -package internal - -import scala.collection.{ mutable, immutable } -import scala.reflect.internal.util.StringOps.{ countAsString, countElementsAsString } - -trait Kinds { - self: SymbolTable => - - import definitions._ - - private type SymPair = ((Symbol, Symbol)) // ((Argument, Parameter)) - - case class KindErrors( - arity: List[SymPair] = Nil, - variance: List[SymPair] = Nil, - strictness: List[SymPair] = Nil - ) { - def isEmpty = arity.isEmpty && variance.isEmpty && strictness.isEmpty - - def arityError(syms: SymPair) = copy(arity = arity :+ syms) - def varianceError(syms: SymPair) = copy(variance = variance :+ syms) - def strictnessError(syms: SymPair) = copy(strictness = strictness :+ syms) - - def ++(errs: KindErrors) = KindErrors( - arity ++ errs.arity, - variance ++ errs.variance, - strictness ++ errs.strictness - ) - // @M TODO this method is duplicated all over the place (varianceString) - private def varStr(s: Symbol): String = - if (s.isCovariant) "covariant" - else if (s.isContravariant) "contravariant" - else "invariant"; - - private def qualify(a0: Symbol, b0: Symbol): String = if (a0.toString != b0.toString) "" else { - if((a0 eq b0) || (a0.owner eq b0.owner)) "" - else { - var a = a0; var b = b0 - while (a.owner.name == b.owner.name) { a = a.owner; b = b.owner} - if (a.locationString ne "") " (" + a.locationString.trim + ")" else "" - } - } - private def kindMessage(a: Symbol, p: Symbol)(f: (String, String) => String): String = - f(a+qualify(a,p), p+qualify(p,a)) - - // Normally it's nicer to print nothing rather than '>: Nothing <: Any' all over - // the place, but here we need it for the message to make sense. - private def strictnessMessage(a: Symbol, p: Symbol) = - kindMessage(a, p)("%s's bounds%s are stricter than %s's declared bounds%s".format( - _, a.info, _, p.info match { - case tb @ TypeBounds(_, _) if tb.isEmptyBounds => " >: Nothing <: Any" - case tb => "" + tb - }) - ) - - private def varianceMessage(a: Symbol, p: Symbol) = - kindMessage(a, p)("%s is %s, but %s is declared %s".format(_, varStr(a), _, varStr(p))) - - private def arityMessage(a: Symbol, p: Symbol) = - kindMessage(a, p)("%s has %s, but %s has %s".format( - _, countElementsAsString(a.typeParams.length, "type parameter"), - _, countAsString(p.typeParams.length)) - ) - - private def buildMessage(xs: List[SymPair], f: (Symbol, Symbol) => String) = ( - if (xs.isEmpty) "" - else xs map f.tupled mkString ("\n", ", ", "") - ) - - def errorMessage(targ: Type, tparam: Symbol): String = ( - (targ+"'s type parameters do not match "+tparam+"'s expected parameters:") - + buildMessage(arity, arityMessage) - + buildMessage(variance, varianceMessage) - + buildMessage(strictness, strictnessMessage) - ) - } - val NoKindErrors = KindErrors(Nil, Nil, Nil) - - // TODO: this desperately needs to be cleaned up - // plan: split into kind inference and subkinding - // every Type has a (cached) Kind - def kindsConform(tparams: List[Symbol], targs: List[Type], pre: Type, owner: Symbol): Boolean = - checkKindBounds0(tparams, targs, pre, owner, false).isEmpty - - /** Check whether `sym1`'s variance conforms to `sym2`'s variance. - * - * If `sym2` is invariant, `sym1`'s variance is irrelevant. Otherwise they must be equal. - */ - private def variancesMatch(sym1: Symbol, sym2: Symbol) = ( - sym2.variance==0 - || sym1.variance==sym2.variance - ) - - /** Check well-kindedness of type application (assumes arities are already checked) -- @M - * - * This check is also performed when abstract type members become concrete (aka a "type alias") -- then tparams.length==1 - * (checked one type member at a time -- in that case, prefix is the name of the type alias) - * - * Type application is just like value application: it's "contravariant" in the sense that - * the type parameters of the supplied type arguments must conform to the type parameters of - * the required type parameters: - * - their bounds must be less strict - * - variances must match (here, variances are absolute, the variance of a type parameter does not influence the variance of its higher-order parameters) - * - @M TODO: are these conditions correct,sufficient&necessary? - * - * e.g. class Iterable[t, m[+x <: t]] --> the application Iterable[Int, List] is okay, since - * List's type parameter is also covariant and its bounds are weaker than <: Int - */ - def checkKindBounds0( - tparams: List[Symbol], - targs: List[Type], - pre: Type, - owner: Symbol, - explainErrors: Boolean - ): List[(Type, Symbol, KindErrors)] = { - - // instantiate type params that come from outside the abstract type we're currently checking - def transform(tp: Type, clazz: Symbol): Type = tp.asSeenFrom(pre, clazz) - - // check that the type parameters hkargs to a higher-kinded type conform to the - // expected params hkparams - def checkKindBoundsHK( - hkargs: List[Symbol], - arg: Symbol, - param: Symbol, - paramowner: Symbol, - underHKParams: List[Symbol], - withHKArgs: List[Symbol] - ): KindErrors = { - - var kindErrors: KindErrors = NoKindErrors - def bindHKParams(tp: Type) = tp.substSym(underHKParams, withHKArgs) - // @M sometimes hkargs != arg.typeParams, the symbol and the type may - // have very different type parameters - val hkparams = param.typeParams - - def kindCheck(cond: Boolean, f: KindErrors => KindErrors) { - if (!cond) - kindErrors = f(kindErrors) - } - - if (settings.debug.value) { - log("checkKindBoundsHK expected: "+ param +" with params "+ hkparams +" by definition in "+ paramowner) - log("checkKindBoundsHK supplied: "+ arg +" with params "+ hkargs +" from "+ owner) - log("checkKindBoundsHK under params: "+ underHKParams +" with args "+ withHKArgs) - } - - if (!sameLength(hkargs, hkparams)) { - // Any and Nothing are kind-overloaded - if (arg == AnyClass || arg == NothingClass) NoKindErrors - // shortcut: always set error, whether explainTypesOrNot - else return kindErrors.arityError(arg -> param) - } - else foreach2(hkargs, hkparams) { (hkarg, hkparam) => - if (hkparam.typeParams.isEmpty && hkarg.typeParams.isEmpty) { // base-case: kind * - kindCheck(variancesMatch(hkarg, hkparam), _ varianceError (hkarg -> hkparam)) - // instantiateTypeParams(tparams, targs) - // higher-order bounds, may contain references to type arguments - // substSym(hkparams, hkargs) - // these types are going to be compared as types of kind * - // - // Their arguments use different symbols, but are - // conceptually the same. Could also replace the types by - // polytypes, but can't just strip the symbols, as ordering - // is lost then. - val declaredBounds = transform(hkparam.info.instantiateTypeParams(tparams, targs).bounds, paramowner) - val declaredBoundsInst = transform(bindHKParams(declaredBounds), owner) - val argumentBounds = transform(hkarg.info.bounds, owner) - - kindCheck(declaredBoundsInst <:< argumentBounds, _ strictnessError (hkarg -> hkparam)) - - debuglog( - "checkKindBoundsHK base case: " + hkparam + - " declared bounds: " + declaredBounds + - " after instantiating earlier hkparams: " + declaredBoundsInst + "\n" + - "checkKindBoundsHK base case: "+ hkarg + - " has bounds: " + argumentBounds - ) - } - else { - debuglog("checkKindBoundsHK recursing to compare params of "+ hkparam +" with "+ hkarg) - kindErrors ++= checkKindBoundsHK( - hkarg.typeParams, - hkarg, - hkparam, - paramowner, - underHKParams ++ hkparam.typeParams, - withHKArgs ++ hkarg.typeParams - ) - } - if (!explainErrors && !kindErrors.isEmpty) - return kindErrors - } - if (explainErrors) kindErrors - else NoKindErrors - } - - if (settings.debug.value && (tparams.nonEmpty || targs.nonEmpty)) log( - "checkKindBounds0(" + tparams + ", " + targs + ", " + pre + ", " - + owner + ", " + explainErrors + ")" - ) - - flatMap2(tparams, targs) { (tparam, targ) => - // Prevent WildcardType from causing kind errors, as typevars may be higher-order - if (targ == WildcardType) Nil else { - // force symbol load for #4205 - targ.typeSymbolDirect.info - // @M must use the typeParams of the *type* targ, not of the *symbol* of targ!! - val tparamsHO = targ.typeParams - if (targ.isHigherKinded || tparam.typeParams.nonEmpty) { - // NOTE: *not* targ.typeSymbol, which normalizes - val kindErrors = checkKindBoundsHK( - tparamsHO, targ.typeSymbolDirect, tparam, - tparam.owner, tparam.typeParams, tparamsHO - ) - if (kindErrors.isEmpty) Nil else { - if (explainErrors) List((targ, tparam, kindErrors)) - // Return as soon as an error is seen if there's nothing to explain. - else return List((NoType, NoSymbol, NoKindErrors)) - } - } - else Nil - } - } - } -}
\ No newline at end of file diff --git a/src/compiler/scala/reflect/internal/Mirrors.scala b/src/compiler/scala/reflect/internal/Mirrors.scala deleted file mode 100644 index e3680b14d5..0000000000 --- a/src/compiler/scala/reflect/internal/Mirrors.scala +++ /dev/null @@ -1,243 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.reflect -package internal - -import Flags._ - -trait Mirrors extends api.Mirrors { - self: SymbolTable => - - override type Mirror >: Null <: RootsBase - - abstract class RootsBase(rootOwner: Symbol) extends MirrorOf[Mirrors.this.type] { thisMirror => - - protected[scala] def rootLoader: LazyType - - val RootClass: ClassSymbol - val RootPackage: ModuleSymbol - val EmptyPackageClass: ClassSymbol - val EmptyPackage: ModuleSymbol - - def findMemberFromRoot(fullName: Name): Symbol = { - val segs = nme.segments(fullName.toString, fullName.isTermName) - if (segs.isEmpty) NoSymbol - else definitions.findNamedMember(segs.tail, RootClass.info member segs.head) - } - - /** Todo: organize similar to mkStatic in reflect.Base */ - private def getModuleOrClass(path: Name, len: Int): Symbol = { - val point = path lastPos('.', len - 1) - val owner = - if (point > 0) getModuleOrClass(path.toTermName, point) - else RootClass - val name = path subName (point + 1, len) - val sym = owner.info member name - val result = if (path.isTermName) sym.suchThat(_ hasFlag MODULE) else sym - if (result != NoSymbol) result - else { - if (settings.debug.value) { log(sym.info); log(sym.info.members) }//debug - mirrorMissingHook(owner, name) orElse symbolTableMissingHook(owner, name) orElse { - MissingRequirementError.notFound((if (path.isTermName) "object " else "class ")+path+" in "+thisMirror) - } - } - } - - protected def mirrorMissingHook(owner: Symbol, name: Name): Symbol = NoSymbol - - protected def symbolTableMissingHook(owner: Symbol, name: Name): Symbol = self.missingHook(owner, name) - - /** If you're looking for a class, pass a type name. - * If a module, a term name. - */ - private def getModuleOrClass(path: Name): Symbol = getModuleOrClass(path, path.length) - - override def staticClass(fullName: String): ClassSymbol = getRequiredClass(fullName) - - // todo: get rid of most creation methods and keep just staticClass/Module/Package - - def getClassByName(fullname: Name): ClassSymbol = { - var result = getModuleOrClass(fullname.toTypeName) - while (result.isAliasType) result = result.info.typeSymbol - result match { - case x: ClassSymbol => x - case _ => MissingRequirementError.notFound("class " + fullname) - } - } - - override def staticModule(fullName: String): ModuleSymbol = getRequiredModule(fullName) - - def getModule(fullname: Name): ModuleSymbol = - // [Eugene++] should be a ClassCastException instead? - getModuleOrClass(fullname.toTermName) match { - case x: ModuleSymbol => x - case _ => MissingRequirementError.notFound("object " + fullname) - } - - def getPackage(fullname: Name): ModuleSymbol = getModule(fullname) - - def getRequiredPackage(fullname: String): ModuleSymbol = - getPackage(newTermNameCached(fullname)) - - @deprecated("Use getClassByName", "2.10.0") - def getClass(fullname: Name): ClassSymbol = getClassByName(fullname) - - def getRequiredClass(fullname: String): ClassSymbol = - getClassByName(newTypeNameCached(fullname)) match { - case x: ClassSymbol => x - case _ => MissingRequirementError.notFound("class " + fullname) - } - - def getRequiredModule(fullname: String): ModuleSymbol = - getModule(newTermNameCached(fullname)) - - def erasureName[T: ClassTag] : String = { - /** We'd like the String representation to be a valid - * scala type, so we have to decode the jvm's secret language. - */ - def erasureString(clazz: Class[_]): String = { - if (clazz.isArray) "Array[" + erasureString(clazz.getComponentType) + "]" - else clazz.getName - } - erasureString(classTag[T].runtimeClass) - } - - def requiredClass[T: ClassTag] : ClassSymbol = - getRequiredClass(erasureName[T]) - - // TODO: What syntax do we think should work here? Say you have an object - // like scala.Predef. You can't say requiredModule[scala.Predef] since there's - // no accompanying Predef class, and if you say requiredModule[scala.Predef.type] - // the name found via the erasure is scala.Predef$. For now I am - // removing the trailing $, but I think that classTag should have - // a method which returns a usable name, one which doesn't expose this - // detail of the backend. - def requiredModule[T: ClassTag] : ModuleSymbol = - getRequiredModule(erasureName[T] stripSuffix "$") - - def getClassIfDefined(fullname: String): Symbol = - getClassIfDefined(newTypeName(fullname)) - - def getClassIfDefined(fullname: Name): Symbol = - wrapMissing(getClassByName(fullname.toTypeName)) - - def getModuleIfDefined(fullname: String): Symbol = - getModuleIfDefined(newTermName(fullname)) - - def getModuleIfDefined(fullname: Name): Symbol = - wrapMissing(getModule(fullname.toTermName)) - - def getPackageObject(fullname: String): ModuleSymbol = - (getModule(newTermName(fullname)).info member nme.PACKAGE) match { - case x: ModuleSymbol => x - case _ => MissingRequirementError.notFound("package object " + fullname) - } - - def getPackageObjectIfDefined(fullname: String): Symbol = { - val module = getModuleIfDefined(newTermName(fullname)) - if (module == NoSymbol) NoSymbol - else { - val packageObject = module.info member nme.PACKAGE - packageObject match { - case x: ModuleSymbol => x - case _ => NoSymbol - } - } - } - - @inline private def wrapMissing(body: => Symbol): Symbol = - try body - catch { case _: MissingRequirementError => NoSymbol } - - /** getModule2/getClass2 aren't needed at present but may be again, - * so for now they're mothballed. - */ - // def getModule2(name1: Name, name2: Name) = { - // try getModuleOrClass(name1.toTermName) - // catch { case ex1: FatalError => - // try getModuleOrClass(name2.toTermName) - // catch { case ex2: FatalError => throw ex1 } - // } - // } - // def getClass2(name1: Name, name2: Name) = { - // try { - // val result = getModuleOrClass(name1.toTypeName) - // if (result.isAliasType) getClass(name2) else result - // } - // catch { case ex1: FatalError => - // try getModuleOrClass(name2.toTypeName) - // catch { case ex2: FatalError => throw ex1 } - // } - // } - - def init() { - // Still fiddling with whether it's cleaner to do some of this setup here - // or from constructors. The latter approach tends to invite init order issues. - - EmptyPackageClass setInfo ClassInfoType(Nil, newPackageScope(EmptyPackageClass), EmptyPackageClass) - EmptyPackage setInfo EmptyPackageClass.tpe - - connectModuleToClass(EmptyPackage, EmptyPackageClass) - connectModuleToClass(RootPackage, RootClass) - - RootClass.info.decls enter EmptyPackage - RootClass.info.decls enter RootPackage - } - } - - abstract class Roots(rootOwner: Symbol) extends RootsBase(rootOwner) { thisMirror => - - // TODO - having these as objects means they elude the attempt to - // add synchronization in SynchronizedSymbols. But we should either - // flip on object overrides or find some other accomodation, because - // lazy vals are unnecessarily expensive relative to objects and it - // is very beneficial for a handful of bootstrap symbols to have - // first class identities - sealed trait WellKnownSymbol extends Symbol { - this initFlags TopLevelCreationFlags - } - // Features common to RootClass and RootPackage, the roots of all - // type and term symbols respectively. - sealed trait RootSymbol extends WellKnownSymbol { - final override def isRootSymbol = true - override def owner = rootOwner - override def typeOfThis = thisSym.tpe - } - - // This is the package _root_. The actual root cannot be referenced at - // the source level, but _root_ is essentially a function => <root>. - final object RootPackage extends ModuleSymbol(rootOwner, NoPosition, nme.ROOTPKG) with RootSymbol { - this setInfo NullaryMethodType(RootClass.tpe) - RootClass.sourceModule = this - - override def isRootPackage = true - } - // This is <root>, the actual root of everything except the package _root_. - // <root> and _root_ (RootPackage and RootClass) should be the only "well known" - // symbols owned by NoSymbol. All owner chains should go through RootClass, - // although it is probable that some symbols are created as direct children - // of NoSymbol to ensure they will not be stumbled upon. (We should designate - // a better encapsulated place for that.) - final object RootClass extends PackageClassSymbol(rootOwner, NoPosition, tpnme.ROOT) with RootSymbol { - this setInfo rootLoader - - override def isRoot = true - override def isEffectiveRoot = true - override def isStatic = true - override def isNestedClass = false - override def ownerOfNewSymbols = EmptyPackageClass - } - // The empty package, which holds all top level types without given packages. - final object EmptyPackage extends ModuleSymbol(RootClass, NoPosition, nme.EMPTY_PACKAGE_NAME) with WellKnownSymbol { - override def isEmptyPackage = true - } - final object EmptyPackageClass extends PackageClassSymbol(RootClass, NoPosition, tpnme.EMPTY_PACKAGE_NAME) with WellKnownSymbol { - override def isEffectiveRoot = true - override def isEmptyPackageClass = true - } - } -} diff --git a/src/compiler/scala/reflect/internal/MissingRequirementError.scala b/src/compiler/scala/reflect/internal/MissingRequirementError.scala deleted file mode 100644 index fbbbcc1928..0000000000 --- a/src/compiler/scala/reflect/internal/MissingRequirementError.scala +++ /dev/null @@ -1,24 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.reflect -package internal - -class MissingRequirementError private (msg: String) extends FatalError(msg) { - import MissingRequirementError.suffix - def req: String = if (msg endsWith suffix) msg dropRight suffix.length else msg -} - -object MissingRequirementError { - private val suffix = " not found." - def signal(msg: String): Nothing = throw new MissingRequirementError(msg) - def notFound(req: String): Nothing = signal(req + suffix) - def unapply(x: Throwable): Option[String] = x match { - case x: MissingRequirementError => Some(x.req) - case _ => None - } -} - - diff --git a/src/compiler/scala/reflect/internal/Names.scala b/src/compiler/scala/reflect/internal/Names.scala deleted file mode 100644 index 18671871ae..0000000000 --- a/src/compiler/scala/reflect/internal/Names.scala +++ /dev/null @@ -1,527 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.reflect -package internal - -import scala.io.Codec -import java.security.MessageDigest -import language.implicitConversions - -/** The class Names ... - * - * @author Martin Odersky - * @version 1.0, 05/02/2005 - */ -trait Names extends api.Names { - implicit def promoteTermNamesAsNecessary(name: Name): TermName = name.toTermName - -// Operations ------------------------------------------------------------- - - private final val HASH_SIZE = 0x8000 - private final val HASH_MASK = 0x7FFF - private final val NAME_SIZE = 0x20000 - - final val nameDebug = false - - /** Memory to store all names sequentially. */ - var chrs: Array[Char] = new Array[Char](NAME_SIZE) - private var nc = 0 - - /** Hashtable for finding term names quickly. */ - private val termHashtable = new Array[TermName](HASH_SIZE) - - /** Hashtable for finding type names quickly. */ - private val typeHashtable = new Array[TypeName](HASH_SIZE) - - /** The hashcode of a name. */ - private def hashValue(cs: Array[Char], offset: Int, len: Int): Int = - if (len > 0) - (len * (41 * 41 * 41) + - cs(offset) * (41 * 41) + - cs(offset + len - 1) * 41 + - cs(offset + (len >> 1))) - else 0; - - /** Is (the ASCII representation of) name at given index equal to - * cs[offset..offset+len-1]? - */ - private def equals(index: Int, cs: Array[Char], offset: Int, len: Int): Boolean = { - var i = 0 - while ((i < len) && (chrs(index + i) == cs(offset + i))) - i += 1; - i == len - } - - /** Enter characters into chrs array. */ - private def enterChars(cs: Array[Char], offset: Int, len: Int) { - var i = 0 - while (i < len) { - if (nc + i == chrs.length) { - val newchrs = new Array[Char](chrs.length * 2) - compat.Platform.arraycopy(chrs, 0, newchrs, 0, chrs.length) - chrs = newchrs - } - chrs(nc + i) = cs(offset + i) - i += 1 - } - if (len == 0) nc += 1 - else nc = nc + len - } - - /** Create a term name from the characters in cs[offset..offset+len-1]. */ - def newTermName(cs: Array[Char], offset: Int, len: Int): TermName = - newTermName(cs, offset, len, cachedString = null) - - def newTermName(cs: Array[Char]): TermName = newTermName(cs, 0, cs.length) - def newTypeName(cs: Array[Char]): TypeName = newTypeName(cs, 0, cs.length) - - /** Create a term name from the characters in cs[offset..offset+len-1]. - * TODO - have a mode where name validation is performed at creation time - * (e.g. if a name has the string "$class" in it, then fail if that - * string is not at the very end.) - */ - protected def newTermName(cs: Array[Char], offset: Int, len: Int, cachedString: String): TermName = { - val h = hashValue(cs, offset, len) & HASH_MASK - var n = termHashtable(h) - while ((n ne null) && (n.length != len || !equals(n.start, cs, offset, len))) - n = n.next - - if (n ne null) n - else { - // The logic order here is future-proofing against the possibility - // that name.toString will become an eager val, in which case the call - // to enterChars cannot follow the construction of the TermName. - val ncStart = nc - enterChars(cs, offset, len) - if (cachedString ne null) new TermName_S(ncStart, len, h, cachedString) - else new TermName_R(ncStart, len, h) - } - } - protected def newTypeName(cs: Array[Char], offset: Int, len: Int, cachedString: String): TypeName = - newTermName(cs, offset, len, cachedString).toTypeName - - /** Create a term name from string. */ - def newTermName(s: String): TermName = newTermName(s.toCharArray(), 0, s.length(), null) - - /** Create a type name from string. */ - def newTypeName(s: String): TypeName = newTermName(s).toTypeName - - /** Create a term name from the UTF8 encoded bytes in bs[offset..offset+len-1]. */ - def newTermName(bs: Array[Byte], offset: Int, len: Int): TermName = { - val chars = Codec.fromUTF8(bs, offset, len) - newTermName(chars, 0, chars.length) - } - - def newTermNameCached(s: String): TermName = - newTermName(s.toCharArray(), 0, s.length(), cachedString = s) - - def newTypeNameCached(s: String): TypeName = - newTypeName(s.toCharArray(), 0, s.length(), cachedString = s) - - /** Create a type name from the characters in cs[offset..offset+len-1]. */ - def newTypeName(cs: Array[Char], offset: Int, len: Int): TypeName = - newTermName(cs, offset, len, cachedString = null).toTypeName - - /** Create a type name from the UTF8 encoded bytes in bs[offset..offset+len-1]. */ - def newTypeName(bs: Array[Byte], offset: Int, len: Int): TypeName = - newTermName(bs, offset, len).toTypeName - - def nameChars: Array[Char] = chrs - @deprecated("", "2.9.0") def view(s: String): TermName = newTermName(s) - -// Classes ---------------------------------------------------------------------- - - /** The name class. - * TODO - resolve schizophrenia regarding whether to treat Names as Strings - * or Strings as Names. Give names the key functions the absence of which - * make people want Strings all the time. - */ - sealed abstract class Name(protected val index: Int, protected val len: Int) extends NameApi with Function1[Int, Char] { - type ThisNameType >: Null <: Name - protected[this] def thisName: ThisNameType - - /** Index into name table */ - def start: Int = index - - /** The next name in the same hash bucket. */ - def next: ThisNameType - - /** The length of this name. */ - final def length: Int = len - final def isEmpty = length == 0 - final def nonEmpty = !isEmpty - - def nameKind: String - def isTermName: Boolean - def isTypeName: Boolean - def toTermName: TermName - def toTypeName: TypeName - def companionName: Name - def bothNames: List[Name] = List(toTermName, toTypeName) - - /** Return the subname with characters from from to to-1. */ - def subName(from: Int, to: Int): ThisNameType - - /** Return a new name of the same variety. */ - def newName(str: String): ThisNameType - - /** Return a new name based on string transformation. */ - def mapName(f: String => String): ThisNameType = newName(f(toString)) - - /** Copy bytes of this name to buffer cs, starting at position `offset`. */ - final def copyChars(cs: Array[Char], offset: Int) = - compat.Platform.arraycopy(chrs, index, cs, offset, len) - - /** @return the ascii representation of this name */ - final def toChars: Array[Char] = { - val cs = new Array[Char](len) - copyChars(cs, 0) - cs - } - - /** Write to UTF8 representation of this name to given character array. - * Start copying to index `to`. Return index of next free byte in array. - * Array must have enough remaining space for all bytes - * (i.e. maximally 3*length bytes). - */ - final def copyUTF8(bs: Array[Byte], offset: Int): Int = { - val bytes = Codec.toUTF8(chrs, index, len) - compat.Platform.arraycopy(bytes, 0, bs, offset, bytes.length) - offset + bytes.length - } - - /** @return the hash value of this name */ - final override def hashCode(): Int = index - - // Presently disabled. - // override def equals(other: Any) = paranoidEquals(other) - private def paranoidEquals(other: Any): Boolean = { - val cmp = this eq other.asInstanceOf[AnyRef] - if (cmp || !nameDebug) - return cmp - - other match { - case x: String => - Console.println("Compared " + debugString + " and String '" + x + "'") - case x: Name => - if (this.isTermName != x.isTermName) { - val panic = this.toTermName == x.toTermName - Console.println("Compared '%s' and '%s', one term, one type.%s".format(this, x, - if (panic) " And they contain the same name string!" - else "" - )) - } - case _ => - } - false - } - - /** @return the i'th Char of this name */ - final def apply(i: Int): Char = chrs(index + i) - - /** @return the index of first occurrence of char c in this name, length if not found */ - final def pos(c: Char): Int = pos(c, 0) - - /** @return the index of first occurrence of char c in this name, length if not found */ - final def pos(s: String): Int = pos(s, 0) - - /** Returns the index of the first occurrence of character c in - * this name from start, length if not found. - * - * @param c the character - * @param start ... - * @return the index of the first occurrence of c - */ - final def pos(c: Char, start: Int): Int = { - var i = start - while (i < len && chrs(index + i) != c) i += 1 - i - } - - /** Returns the index of the first occurrence of nonempty string s - * in this name from start, length if not found. - * - * @param s the string - * @param start ... - * @return the index of the first occurrence of s - */ - final def pos(s: String, start: Int): Int = { - var i = pos(s.charAt(0), start) - while (i + s.length() <= len) { - var j = 1 - while (s.charAt(j) == chrs(index + i + j)) { - j += 1 - if (j == s.length()) return i - } - i = pos(s.charAt(0), i + 1) - } - len - } - - /** Returns the index of last occurrence of char c in this - * name, -1 if not found. - * - * @param c the character - * @return the index of the last occurrence of c - */ - final def lastPos(c: Char): Int = lastPos(c, len - 1) - - final def lastPos(s: String): Int = lastPos(s, len - s.length) - - /** Returns the index of the last occurrence of char c in this - * name from start, -1 if not found. - * - * @param c the character - * @param start ... - * @return the index of the last occurrence of c - */ - final def lastPos(c: Char, start: Int): Int = { - var i = start - while (i >= 0 && chrs(index + i) != c) i -= 1 - i - } - - /** Returns the index of the last occurrence of string s in this - * name from start, -1 if not found. - * - * @param s the string - * @param start ... - * @return the index of the last occurrence of s - */ - final def lastPos(s: String, start: Int): Int = { - var i = lastPos(s.charAt(0), start) - while (i >= 0) { - var j = 1; - while (s.charAt(j) == chrs(index + i + j)) { - j += 1 - if (j == s.length()) return i; - } - i = lastPos(s.charAt(0), i - 1) - } - -s.length() - } - - /** Does this name start with prefix? */ - final def startsWith(prefix: Name): Boolean = startsWith(prefix, 0) - - /** Does this name start with prefix at given start index? */ - final def startsWith(prefix: Name, start: Int): Boolean = { - var i = 0 - while (i < prefix.length && start + i < len && - chrs(index + start + i) == chrs(prefix.start + i)) - i += 1; - i == prefix.length - } - - /** Does this name end with suffix? */ - final def endsWith(suffix: Name): Boolean = endsWith(suffix, len) - - /** Does this name end with suffix just before given end index? */ - final def endsWith(suffix: Name, end: Int): Boolean = { - var i = 1 - while (i <= suffix.length && i <= end && - chrs(index + end - i) == chrs(suffix.start + suffix.length - i)) - i += 1; - i > suffix.length - } - - final def containsName(subname: String): Boolean = containsName(newTermName(subname)) - final def containsName(subname: Name): Boolean = { - var start = 0 - val last = len - subname.length - while (start <= last && !startsWith(subname, start)) start += 1 - start <= last - } - final def containsChar(ch: Char): Boolean = { - var i = index - val max = index + len - while (i < max) { - if (chrs(i) == ch) - return true - i += 1 - } - false - } - - /** Some thoroughly self-explanatory convenience functions. They - * assume that what they're being asked to do is known to be valid. - */ - final def startChar: Char = apply(0) - final def endChar: Char = apply(len - 1) - final def startsWith(char: Char): Boolean = len > 0 && startChar == char - final def startsWith(name: String): Boolean = startsWith(newTermName(name)) - final def endsWith(char: Char): Boolean = len > 0 && endChar == char - final def endsWith(name: String): Boolean = endsWith(newTermName(name)) - - def dropRight(n: Int): ThisNameType = subName(0, len - n) - def drop(n: Int): ThisNameType = subName(n, len) - def stripSuffix(suffix: Name): ThisNameType = - if (this endsWith suffix) dropRight(suffix.length) else thisName - - def indexOf(ch: Char) = { - val idx = pos(ch) - if (idx == length) -1 else idx - } - def indexOf(ch: Char, fromIndex: Int) = { - val idx = pos(ch, fromIndex) - if (idx == length) -1 else idx - } - def lastIndexOf(ch: Char) = lastPos(ch) - def lastIndexOf(ch: Char, fromIndex: Int) = lastPos(ch, fromIndex) - - /** Replace all occurrences of `from` by `to` in - * name; result is always a term name. - */ - def replace(from: Char, to: Char): Name = { - val cs = new Array[Char](len) - var i = 0 - while (i < len) { - val ch = this(i) - cs(i) = if (ch == from) to else ch - i += 1 - } - newTermName(cs, 0, len) - } - - /** TODO - reconcile/fix that encode returns a Name but - * decode returns a String. - */ - - /** !!! Duplicative but consistently named. - */ - def decoded: String = decode - def encoded: String = "" + encode - // def decodedName: ThisNameType = newName(decoded) - def encodedName: ThisNameType = encode - - /** Replace operator symbols by corresponding \$op_name. */ - def encode: ThisNameType = { - val str = toString - val res = NameTransformer.encode(str) - if (res == str) thisName else newName(res) - } - - /** Replace \$op_name by corresponding operator symbol. */ - def decode: String = { - if (this containsChar '$') { - val str = toString - val res = NameTransformer.decode(str) - if (res == str) str - else res - } - else toString - } - - /** TODO - find some efficiency. */ - def append(ch: Char) = newName("" + this + ch) - def append(suffix: String) = newName("" + this + suffix) - def append(suffix: Name) = newName("" + this + suffix) - def prepend(ch: Char) = newName("" + ch + this) - def prepend(prefix: String) = newName("" + prefix + this) - def prepend(prefix: Name) = newName("" + prefix + this) - - def decodedName: ThisNameType = newName(decode) - def isOperatorName: Boolean = decode != toString - def longString: String = nameKind + " " + decode - def debugString = { val s = decode ; if (isTypeName) s + "!" else s } - } - - implicit val NameTag = ClassTag[Name](classOf[Name]) - - /** A name that contains no operator chars nor dollar signs. - * TODO - see if it's any faster to do something along these lines. - * Cute: now that exhaustivity kind of works, the mere presence of - * this trait causes TermName and TypeName to stop being exhaustive. - * Commented out. - */ - // trait AlphaNumName extends Name { - // final override def encode = thisName - // final override def decodedName = thisName - // final override def decode = toString - // final override def isOperatorName = false - // } - - /** TermName_S and TypeName_S have fields containing the string version of the name. - * TermName_R and TypeName_R recreate it each time toString is called. - */ - private class TermName_S(index0: Int, len0: Int, hash: Int, override val toString: String) extends TermName(index0, len0, hash) { - protected def createCompanionName(h: Int): TypeName = new TypeName_S(index, len, h, toString) - override def newName(str: String): TermName = newTermNameCached(str) - } - private class TypeName_S(index0: Int, len0: Int, hash: Int, override val toString: String) extends TypeName(index0, len0, hash) { - protected def createCompanionName(h: Int): TermName = new TermName_S(index, len, h, toString) - override def newName(str: String): TypeName = newTypeNameCached(str) - } - - private class TermName_R(index0: Int, len0: Int, hash: Int) extends TermName(index0, len0, hash) { - protected def createCompanionName(h: Int): TypeName = new TypeName_R(index, len, h) - override def toString = new String(chrs, index, len) - } - - private class TypeName_R(index0: Int, len0: Int, hash: Int) extends TypeName(index0, len0, hash) { - protected def createCompanionName(h: Int): TermName = new TermName_R(index, len, h) - override def toString = new String(chrs, index, len) - } - - sealed abstract class TermName(index0: Int, len0: Int, hash: Int) extends Name(index0, len0) { - type ThisNameType = TermName - protected[this] def thisName: TermName = this - - var next: TermName = termHashtable(hash) - termHashtable(hash) = this - def isTermName: Boolean = true - def isTypeName: Boolean = false - def toTermName: TermName = this - def toTypeName: TypeName = { - val h = hashValue(chrs, index, len) & HASH_MASK - var n = typeHashtable(h) - while ((n ne null) && n.start != index) - n = n.next - - if (n ne null) n - else createCompanionName(h) - } - def newName(str: String): TermName = newTermName(str) - def companionName: TypeName = toTypeName - def subName(from: Int, to: Int): TermName = - newTermName(chrs, start + from, to - from) - - def nameKind = "term" - protected def createCompanionName(h: Int): TypeName - } - - implicit val TermNameTag = ClassTag[TermName](classOf[TermName]) - - sealed abstract class TypeName(index0: Int, len0: Int, hash: Int) extends Name(index0, len0) { - type ThisNameType = TypeName - protected[this] def thisName: TypeName = this - - var next: TypeName = typeHashtable(hash) - typeHashtable(hash) = this - def isTermName: Boolean = false - def isTypeName: Boolean = true - def toTermName: TermName = { - val h = hashValue(chrs, index, len) & HASH_MASK - var n = termHashtable(h) - while ((n ne null) && n.start != index) - n = n.next - - if (n ne null) n - else createCompanionName(h) - } - def toTypeName: TypeName = this - def newName(str: String): TypeName = newTypeName(str) - def companionName: TermName = toTermName - def subName(from: Int, to: Int): TypeName = - newTypeName(chrs, start + from, to - from) - - def nameKind = "type" - override def decode = if (nameDebug) super.decode + "!" else super.decode - protected def createCompanionName(h: Int): TermName - } - - implicit val TypeNameTag = ClassTag[TypeName](classOf[TypeName]) -} diff --git a/src/compiler/scala/reflect/internal/Phase.scala b/src/compiler/scala/reflect/internal/Phase.scala deleted file mode 100644 index 68dc5ce783..0000000000 --- a/src/compiler/scala/reflect/internal/Phase.scala +++ /dev/null @@ -1,66 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.reflect -package internal - -abstract class Phase(val prev: Phase) { - if ((prev ne null) && (prev ne NoPhase)) - prev.nx = this - - type Id = Int - val id: Id = if (prev eq null) 0 else prev.id + 1 - - /** New flags visible after this phase has completed */ - def nextFlags: Long = 0l - - /** New flags visible once this phase has started */ - def newFlags: Long = 0l - - val fmask = ( - if (prev eq null) Flags.InitialFlags - else prev.flagMask | prev.nextFlags | newFlags - ) - def flagMask: Long = fmask - - private var nx: Phase = this - - def next: Phase = nx - def hasNext = next != this - def iterator = Iterator.iterate(this)(_.next) takeWhile (p => p.next != p) - - def name: String - def description: String = name - // Will running with -Ycheck:name work? - def checkable: Boolean = true - def specialized: Boolean = false - def erasedTypes: Boolean = false - def flatClasses: Boolean = false - def refChecked: Boolean = false - - /** This is used only in unsafeTypeParams, and at this writing is - * overridden to false in parser, namer, typer, and erasure. (And NoPhase.) - */ - def keepsTypeParams = true - def run(): Unit - - override def toString() = name - override def hashCode = id.## + name.## - override def equals(other: Any) = other match { - case x: Phase => id == x.id && name == x.name - case _ => false - } -} - -object NoPhase extends Phase(null) { - def name = "<no phase>" - override def keepsTypeParams = false - def run() { throw new Error("NoPhase.run") } -} - -object SomePhase extends Phase(NoPhase) { - def name = "<some phase>" - def run() { throw new Error("SomePhase.run") } -} diff --git a/src/compiler/scala/reflect/internal/Positions.scala b/src/compiler/scala/reflect/internal/Positions.scala deleted file mode 100644 index 6ae9b40fcb..0000000000 --- a/src/compiler/scala/reflect/internal/Positions.scala +++ /dev/null @@ -1,63 +0,0 @@ -package scala.reflect -package internal - -trait Positions extends api.Positions { self: SymbolTable => - - type Position = scala.reflect.internal.util.Position - val NoPosition = scala.reflect.internal.util.NoPosition - implicit val PositionTag = ClassTag[Position](classOf[Position]) - - /** A position that wraps a set of trees. - * The point of the wrapping position is the point of the default position. - * If some of the trees are ranges, returns a range position enclosing all ranges - * Otherwise returns default position. - */ - def wrappingPos(default: Position, trees: List[Tree]): Position = default - - /** A position that wraps the non-empty set of trees. - * The point of the wrapping position is the point of the first trees' position. - * If all some the trees are non-synthetic, returns a range position enclosing the non-synthetic trees - * Otherwise returns a synthetic offset position to point. - */ - def wrappingPos(trees: List[Tree]): Position = trees.head.pos - - /** Ensure that given tree has no positions that overlap with - * any of the positions of `others`. This is done by - * shortening the range or assigning TransparentPositions - * to some of the nodes in `tree`. - */ - def ensureNonOverlapping(tree: Tree, others: List[Tree]) {} - - trait PosAssigner extends Traverser { - var pos: Position - } - protected[this] lazy val posAssigner: PosAssigner = new DefaultPosAssigner - - protected class DefaultPosAssigner extends PosAssigner { - var pos: Position = _ - override def traverse(t: Tree) { - if (t eq EmptyTree) () - else if (t.pos == NoPosition) { - t.setPos(pos) - super.traverse(t) // TODO: bug? shouldn't the traverse be outside of the if? - // @PP: it's pruning whenever it encounters a node with a - // position, which I interpret to mean that (in the author's - // mind at least) either the children of a positioned node will - // already be positioned, or the children of a positioned node - // do not merit positioning. - // - // Whatever the author's rationale, it does seem like a bad idea - // to press on through a positioned node to find unpositioned - // children beneath it and then to assign whatever happens to - // be in `pos` to such nodes. There are supposed to be some - // position invariants which I can't imagine surviving that. - } - } - } - - def atPos[T <: Tree](pos: Position)(tree: T): T = { - posAssigner.pos = pos - posAssigner.traverse(tree) - tree - } -}
\ No newline at end of file diff --git a/src/compiler/scala/reflect/internal/Required.scala b/src/compiler/scala/reflect/internal/Required.scala deleted file mode 100644 index abbe8fbfb7..0000000000 --- a/src/compiler/scala/reflect/internal/Required.scala +++ /dev/null @@ -1,17 +0,0 @@ -package scala.reflect -package internal - -import settings.MutableSettings - -trait Required { self: SymbolTable => - - type AbstractFileType >: Null <: AbstractFileApi - - def picklerPhase: Phase - - def settings: MutableSettings - - def forInteractive: Boolean - - def forScaladoc: Boolean -} diff --git a/src/compiler/scala/reflect/internal/Scopes.scala b/src/compiler/scala/reflect/internal/Scopes.scala deleted file mode 100644 index ceacd2afb0..0000000000 --- a/src/compiler/scala/reflect/internal/Scopes.scala +++ /dev/null @@ -1,359 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.reflect -package internal - -trait Scopes extends api.Scopes { self: SymbolTable => - - class ScopeEntry(val sym: Symbol, val owner: Scope) { - /** the next entry in the hash bucket - */ - var tail: ScopeEntry = null - - /** the next entry in this scope - */ - var next: ScopeEntry = null - - override def hashCode(): Int = sym.name.start - override def toString(): String = sym.toString() - } - - /** - * @param sym ... - * @param owner ... - * @return ... - */ - private def newScopeEntry(sym: Symbol, owner: Scope): ScopeEntry = { - val e = new ScopeEntry(sym, owner) - e.next = owner.elems - owner.elems = e - e - } - - object Scope { - def unapplySeq(decls: Scope): Some[Seq[Symbol]] = Some(decls.toList) - } - - /** Note: constructor is protected to force everyone to use the factory methods newScope or newNestedScope instead. - * This is necessary because when run from reflection every scope needs to have a - * SynchronizedScope as mixin. - */ - class Scope protected[Scopes] (initElems: ScopeEntry = null) extends Iterable[Symbol] { - - protected[Scopes] def this(base: Scope) = { - this(base.elems) - nestinglevel = base.nestinglevel + 1 - } - - private[scala] var elems: ScopeEntry = initElems - - /** The number of times this scope is nested in another - */ - private var nestinglevel = 0 - - /** the hash table - */ - private var hashtable: Array[ScopeEntry] = null - - /** a cache for all elements, to be used by symbol iterator. - */ - private var elemsCache: List[Symbol] = null - - /** size and mask of hash tables - * todo: make hashtables grow? - */ - private val HASHSIZE = 0x80 - private val HASHMASK = 0x7f - - /** the threshold number of entries from which a hashtable is constructed. - */ - private val MIN_HASH = 8 - - if (size >= MIN_HASH) createHash() - - /** Returns a new scope with the same content as this one. */ - def cloneScope: Scope = newScopeWith(this.toList: _*) - - /** is the scope empty? */ - override def isEmpty: Boolean = elems eq null - - /** the number of entries in this scope */ - override def size: Int = { - var s = 0 - var e = elems - while (e ne null) { - s += 1 - e = e.next - } - s - } - - /** enter a scope entry - * - * @param e ... - */ - protected def enter(e: ScopeEntry) { - elemsCache = null - if (hashtable ne null) - enterInHash(e) - else if (size >= MIN_HASH) - createHash() - } - - private def enterInHash(e: ScopeEntry): Unit = { - val i = e.sym.name.start & HASHMASK - e.tail = hashtable(i) - hashtable(i) = e - } - - /** enter a symbol - * - * @param sym ... - */ - def enter[T <: Symbol](sym: T): T = { enter(newScopeEntry(sym, this)); sym } - - /** enter a symbol, asserting that no symbol with same name exists in scope - * - * @param sym ... - */ - def enterUnique(sym: Symbol) { - assert(lookup(sym.name) == NoSymbol, (sym.fullLocationString, lookup(sym.name).fullLocationString)) - enter(sym) - } - - private def createHash() { - hashtable = new Array[ScopeEntry](HASHSIZE) - enterAllInHash(elems) - } - - private def enterAllInHash(e: ScopeEntry, n: Int = 0) { - if (e ne null) { - if (n < maxRecursions) { - enterAllInHash(e.next, n + 1) - enterInHash(e) - } else { - var entries: List[ScopeEntry] = List() - var ee = e - while (ee ne null) { - entries = ee :: entries - ee = ee.next - } - entries foreach enterInHash - } - } - } - - def rehash(sym: Symbol, newname: Name) { - if (hashtable ne null) { - val index = sym.name.start & HASHMASK - var e1 = hashtable(index) - var e: ScopeEntry = null - if (e1 != null) { - if (e1.sym == sym) { - hashtable(index) = e1.tail - e = e1 - } else { - while (e1.tail != null && e1.tail.sym != sym) e1 = e1.tail - if (e1.tail != null) { - e = e1.tail - e1.tail = e.tail - } - } - } - if (e != null) { - val newindex = newname.start & HASHMASK - e.tail = hashtable(newindex) - hashtable(newindex) = e - } - } - } - - /** remove entry - * - * @param e ... - */ - def unlink(e: ScopeEntry) { - if (elems == e) { - elems = e.next - } else { - var e1 = elems - while (e1.next != e) e1 = e1.next - e1.next = e.next - } - if (hashtable ne null) { - val index = e.sym.name.start & HASHMASK - var e1 = hashtable(index) - if (e1 == e) { - hashtable(index) = e.tail - } else { - while (e1.tail != e) e1 = e1.tail; - e1.tail = e.tail - } - } - elemsCache = null - } - - /** remove symbol */ - def unlink(sym: Symbol) { - var e = lookupEntry(sym.name) - while (e ne null) { - if (e.sym == sym) unlink(e); - e = lookupNextEntry(e) - } - } - - /** lookup a symbol - * - * @param name ... - * @return ... - */ - def lookup(name: Name): Symbol = { - val e = lookupEntry(name) - if (e eq null) NoSymbol else e.sym - } - - /** Returns an iterator yielding every symbol with given name in this scope. - */ - def lookupAll(name: Name): Iterator[Symbol] = new Iterator[Symbol] { - var e = lookupEntry(name) - def hasNext: Boolean = e ne null - def next(): Symbol = { val r = e.sym; e = lookupNextEntry(e); r } - } - - /** lookup a symbol entry matching given name. - * @note from Martin: I believe this is a hotspot or will be one - * in future versions of the type system. I have reverted the previous - * change to use iterators as too costly. - */ - def lookupEntry(name: Name): ScopeEntry = { - var e: ScopeEntry = null - if (hashtable ne null) { - e = hashtable(name.start & HASHMASK) - while ((e ne null) && e.sym.name != name) { - e = e.tail - } - } else { - e = elems - while ((e ne null) && e.sym.name != name) { - e = e.next - } - } - e - } - - /** lookup next entry with same name as this one - * @note from Martin: I believe this is a hotspot or will be one - * in future versions of the type system. I have reverted the previous - * change to use iterators as too costly. - */ - def lookupNextEntry(entry: ScopeEntry): ScopeEntry = { - var e = entry - if (hashtable ne null) - do { e = e.tail } while ((e ne null) && e.sym.name != entry.sym.name) - else - do { e = e.next } while ((e ne null) && e.sym.name != entry.sym.name); - e - } - - /** Return all symbols as a list in the order they were entered in this scope. - */ - override def toList: List[Symbol] = { - if (elemsCache eq null) { - elemsCache = Nil - var e = elems - while ((e ne null) && e.owner == this) { - elemsCache = e.sym :: elemsCache - e = e.next - } - } - elemsCache - } - - /** Return the nesting level of this scope, i.e. the number of times this scope - * was nested in another */ - def nestingLevel = nestinglevel - - /** Return all symbols as an iterator in the order they were entered in this scope. - */ - def iterator: Iterator[Symbol] = toList.iterator - -/* - /** Does this scope contain an entry for `sym`? - */ - def contains(sym: Symbol): Boolean = lookupAll(sym.name) contains sym - - /** A scope that contains all symbols of this scope and that also contains `sym`. - */ - def +(sym: Symbol): Scope = - if (contains(sym)) this - else { - val result = cloneScope - result enter sym - result - } - - /** A scope that contains all symbols of this scope except `sym`. - */ - def -(sym: Symbol): Scope = - if (!contains(sym)) this - else { - val result = cloneScope - result unlink sym - result - } -*/ - override def foreach[U](p: Symbol => U): Unit = toList foreach p - - override def filter(p: Symbol => Boolean): Scope = - if (!(toList forall p)) newScopeWith(toList filter p: _*) else this - - override def mkString(start: String, sep: String, end: String) = - toList.map(_.defString).mkString(start, sep, end) - - override def toString(): String = mkString("Scope{\n ", ";\n ", "\n}") - - } - - implicit val ScopeTag = ClassTag[Scope](classOf[Scope]) - - /** Create a new scope */ - def newScope: Scope = new Scope() - - /** Create a new scope nested in another one with which it shares its elements */ - def newNestedScope(outer: Scope): Scope = new Scope(outer) - - /** Create a new scope with given initial elements */ - def newScopeWith(elems: Symbol*): Scope = { - val scope = newScope - elems foreach scope.enter - scope - } - - /** Create new scope for the members of package `pkg` */ - def newPackageScope(pkgClass: Symbol): Scope = newScope - - /** Transform scope of members of `owner` using operation `op` - * This is overridden by the reflective compiler to avoid creating new scopes for packages - */ - def scopeTransform(owner: Symbol)(op: => Scope): Scope = op - - - /** The empty scope (immutable). - */ - object EmptyScope extends Scope { - override def enter(e: ScopeEntry) { - abort("EmptyScope.enter") - } - } - - /** The error scope. - */ - class ErrorScope(owner: Symbol) extends Scope - - private final val maxRecursions = 1000 - -} - diff --git a/src/compiler/scala/reflect/internal/StdAttachments.scala b/src/compiler/scala/reflect/internal/StdAttachments.scala deleted file mode 100644 index 4ea9b27da9..0000000000 --- a/src/compiler/scala/reflect/internal/StdAttachments.scala +++ /dev/null @@ -1,12 +0,0 @@ -package scala.reflect -package internal - -trait StdAttachments { - self: SymbolTable => - - case object BackquotedIdentifierAttachment - - case class CompoundTypeTreeOriginalAttachment(parents: List[Tree], stats: List[Tree]) - - case class MacroExpansionAttachment(original: Tree) -}
\ No newline at end of file diff --git a/src/compiler/scala/reflect/internal/StdCreators.scala b/src/compiler/scala/reflect/internal/StdCreators.scala deleted file mode 100644 index 3e6b7c1ab4..0000000000 --- a/src/compiler/scala/reflect/internal/StdCreators.scala +++ /dev/null @@ -1,21 +0,0 @@ -package scala.reflect -package internal - -import scala.reflect.base.{TreeCreator, TypeCreator} -import scala.reflect.base.{Universe => BaseUniverse} - -trait StdCreators { - self: SymbolTable => - - case class FixedMirrorTreeCreator(mirror: MirrorOf[StdCreators.this.type], tree: Tree) extends TreeCreator { - def apply[U <: BaseUniverse with Singleton](m: MirrorOf[U]): U # Tree = - if (m eq mirror) tree.asInstanceOf[U # Tree] - else throw new IllegalArgumentException(s"Expr defined in $mirror cannot be migrated to other mirrors.") - } - - case class FixedMirrorTypeCreator(mirror: MirrorOf[StdCreators.this.type], tpe: Type) extends TypeCreator { - def apply[U <: BaseUniverse with Singleton](m: MirrorOf[U]): U # Type = - if (m eq mirror) tpe.asInstanceOf[U # Type] - else throw new IllegalArgumentException(s"Type tag defined in $mirror cannot be migrated to other mirrors.") - } -}
\ No newline at end of file diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala deleted file mode 100644 index 6f68b8f63a..0000000000 --- a/src/compiler/scala/reflect/internal/StdNames.scala +++ /dev/null @@ -1,1218 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.reflect -package internal - -import java.security.MessageDigest -import Chars.isOperatorPart -import annotation.switch -import language.implicitConversions -import scala.collection.immutable -import scala.io.Codec - -trait StdNames { - self: SymbolTable => - - def encode(str: String): TermName = newTermNameCached(NameTransformer.encode(str)) - - implicit def lowerTermNames(n: TermName): String = n.toString - - /** Tensions: would like the keywords to be the very first names entered into the names - * storage so their ids count from 0, which simplifies the parser. Switched to abstract - * classes to avoid all the indirection which is generated with implementation-containing - * traits. Since all these classes use eager vals, that means the constructor with the - * keywords must run first. If it's the top in the superclass chain, then CommonNames - * must inherit from it, which means TypeNames would inherit keywords as well. - * - * Solution: Keywords extends CommonNames and uses early defs to beat the - * CommonNames constructor out of the starting gate. This is its builder. - */ - private class KeywordSetBuilder { - private var kws: Set[TermName] = Set() - def apply(s: String): TermName = { - val result = newTermNameCached(s) - kws = kws + result - result - } - def result: Set[TermName] = { - val result = kws - kws = null - result - } - } - - private final object compactify extends (String => String) { - val md5 = MessageDigest.getInstance("MD5") - - /** - * COMPACTIFY - * - * The hashed name has the form (prefix + marker + md5 + marker + suffix), where - * - prefix/suffix.length = MaxNameLength / 4 - * - md5.length = 32 - * - * We obtain the formula: - * - * FileNameLength = 2*(MaxNameLength / 4) + 2.marker.length + 32 + 6 - * - * (+6 for ".class"). MaxNameLength can therefore be computed as follows: - */ - val marker = "$$$$" - val MaxNameLength = math.min( - settings.maxClassfileName.value - 6, - 2 * (settings.maxClassfileName.value - 6 - 2*marker.length - 32) - ) - def toMD5(s: String, edge: Int): String = { - val prefix = s take edge - val suffix = s takeRight edge - - val cs = s.toArray - val bytes = Codec toUTF8 cs - md5 update bytes - val md5chars = (md5.digest() map (b => (b & 0xFF).toHexString)).mkString - - prefix + marker + md5chars + marker + suffix - } - def apply(s: String): String = ( - if (s.length <= MaxNameLength) s - else toMD5(s, MaxNameLength / 4) - ) - } - - abstract class CommonNames extends NamesApi { - type NameType >: Null <: Name - protected implicit def createNameType(name: String): NameType - - def flattenedName(segments: Name*): NameType = - compactify(segments mkString NAME_JOIN_STRING) - - val MODULE_SUFFIX_STRING: String = NameTransformer.MODULE_SUFFIX_STRING - val NAME_JOIN_STRING: String = NameTransformer.NAME_JOIN_STRING - val SINGLETON_SUFFIX: String = ".type" - - val ANON_CLASS_NAME: NameType = "$anon" - val ANON_FUN_NAME: NameType = "$anonfun" - val EMPTY: NameType = "" - val EMPTY_PACKAGE_NAME: NameType = "<empty>" - val IMPL_CLASS_SUFFIX = "$class" - val IMPORT: NameType = "<import>" - val MODULE_SUFFIX_NAME: NameType = MODULE_SUFFIX_STRING - val MODULE_VAR_SUFFIX: NameType = "$module" - val NAME_JOIN_NAME: NameType = NAME_JOIN_STRING - val PACKAGE: NameType = "package" - val ROOT: NameType = "<root>" - val SPECIALIZED_SUFFIX: NameType = "$sp" - - // value types (and AnyRef) are all used as terms as well - // as (at least) arguments to the @specialize annotation. - final val Boolean: NameType = "Boolean" - final val Byte: NameType = "Byte" - final val Char: NameType = "Char" - final val Double: NameType = "Double" - final val Float: NameType = "Float" - final val Int: NameType = "Int" - final val Long: NameType = "Long" - final val Short: NameType = "Short" - final val Unit: NameType = "Unit" - - final val ScalaValueNames: scala.List[NameType] = - scala.List(Byte, Char, Short, Int, Long, Float, Double, Boolean, Unit) - - // some types whose companions we utilize - final val AnyRef: NameType = "AnyRef" - final val Array: NameType = "Array" - final val List: NameType = "List" - final val Seq: NameType = "Seq" - final val Symbol: NameType = "Symbol" - final val ClassTag: NameType = "ClassTag" - final val TypeTag : NameType = "TypeTag" - final val ConcreteTypeTag: NameType = "ConcreteTypeTag" - final val Expr: NameType = "Expr" - final val String: NameType = "String" - - // fictions we use as both types and terms - final val ERROR: NameType = "<error>" - final val NO_NAME: NameType = "<none>" // formerly NOSYMBOL - final val WILDCARD: NameType = "_" - } - - /** This should be the first trait in the linearization. */ - // abstract class Keywords extends CommonNames { - abstract class Keywords extends { - private val kw = new KeywordSetBuilder - - final val ABSTRACTkw: TermName = kw("abstract") - final val CASEkw: TermName = kw("case") - final val CLASSkw: TermName = kw("class") - final val CATCHkw: TermName = kw("catch") - final val DEFkw: TermName = kw("def") - final val DOkw: TermName = kw("do") - final val ELSEkw: TermName = kw("else") - final val EXTENDSkw: TermName = kw("extends") - final val FALSEkw: TermName = kw("false") - final val FINALkw: TermName = kw("final") - final val FINALLYkw: TermName = kw("finally") - final val FORkw: TermName = kw("for") - final val FORSOMEkw: TermName = kw("forSome") - final val IFkw: TermName = kw("if") - final val IMPLICITkw: TermName = kw("implicit") - final val IMPORTkw: TermName = kw("import") - final val LAZYkw: TermName = kw("lazy") - final val MACROkw: TermName = kw("macro") - final val MATCHkw: TermName = kw("match") - final val NEWkw: TermName = kw("new") - final val NULLkw: TermName = kw("null") - final val OBJECTkw: TermName = kw("object") - final val OVERRIDEkw: TermName = kw("override") - final val PACKAGEkw: TermName = kw("package") - final val PRIVATEkw: TermName = kw("private") - final val PROTECTEDkw: TermName = kw("protected") - final val RETURNkw: TermName = kw("return") - final val SEALEDkw: TermName = kw("sealed") - final val SUPERkw: TermName = kw("super") - final val THENkw: TermName = kw("then") - final val THISkw: TermName = kw("this") - final val THROWkw: TermName = kw("throw") - final val TRAITkw: TermName = kw("trait") - final val TRUEkw: TermName = kw("true") - final val TRYkw: TermName = kw("try") - final val TYPEkw: TermName = kw("type") - final val VALkw: TermName = kw("val") - final val VARkw: TermName = kw("var") - final val WITHkw: TermName = kw("with") - final val WHILEkw: TermName = kw("while") - final val YIELDkw: TermName = kw("yield") - final val DOTkw: TermName = kw(".") - final val USCOREkw: TermName = kw("_") - final val COLONkw: TermName = kw(":") - final val EQUALSkw: TermName = kw("=") - final val ARROWkw: TermName = kw("=>") - final val LARROWkw: TermName = kw("<-") - final val SUBTYPEkw: TermName = kw("<:") - final val VIEWBOUNDkw: TermName = kw("<%") - final val SUPERTYPEkw: TermName = kw(">:") - final val HASHkw: TermName = kw("#") - final val ATkw: TermName = kw("@") - - final val keywords = kw.result - } with CommonNames { - final val javaKeywords = new JavaKeywords() - } - - abstract class TypeNames extends Keywords with TypeNamesApi { - type NameType = TypeName - protected implicit def createNameType(name: String): TypeName = newTypeNameCached(name) - - final val BYNAME_PARAM_CLASS_NAME: NameType = "<byname>" - final val EQUALS_PATTERN_NAME: NameType = "<equals>" - final val JAVA_REPEATED_PARAM_CLASS_NAME: NameType = "<repeated...>" - final val LOCAL_CHILD: NameType = "<local child>" - final val REFINE_CLASS_NAME: NameType = "<refinement>" - final val REPEATED_PARAM_CLASS_NAME: NameType = "<repeated>" - final val WILDCARD_STAR: NameType = "_*" - final val REIFY_TREECREATOR_PREFIX: NameType = "$treecreator" - final val REIFY_TYPECREATOR_PREFIX: NameType = "$typecreator" - - final val Any: NameType = "Any" - final val AnyVal: NameType = "AnyVal" - final val ExprApi: NameType = "ExprApi" - final val Mirror: NameType = "Mirror" - final val Nothing: NameType = "Nothing" - final val Null: NameType = "Null" - final val Object: NameType = "Object" - final val PartialFunction: NameType = "PartialFunction" - final val PrefixType: NameType = "PrefixType" - final val Product: NameType = "Product" - final val Serializable: NameType = "Serializable" - final val Singleton: NameType = "Singleton" - final val Throwable: NameType = "Throwable" - - final val Annotation: NameType = "Annotation" - final val ClassfileAnnotation: NameType = "ClassfileAnnotation" - final val Enum: NameType = "Enum" - final val Group: NameType = "Group" - final val Tree: NameType = "Tree" - final val Type : NameType = "Type" - final val TypeTree: NameType = "TypeTree" - - // Annotation simple names, used in Namer - final val BeanPropertyAnnot: NameType = "BeanProperty" - final val BooleanBeanPropertyAnnot: NameType = "BooleanBeanProperty" - final val bridgeAnnot: NameType = "bridge" - - // Classfile Attributes - final val AnnotationDefaultATTR: NameType = "AnnotationDefault" - final val BridgeATTR: NameType = "Bridge" - final val ClassfileAnnotationATTR: NameType = "RuntimeInvisibleAnnotations" // RetentionPolicy.CLASS. Currently not used (Apr 2009). - final val CodeATTR: NameType = "Code" - final val ConstantValueATTR: NameType = "ConstantValue" - final val DeprecatedATTR: NameType = "Deprecated" - final val ExceptionsATTR: NameType = "Exceptions" - final val InnerClassesATTR: NameType = "InnerClasses" - final val LineNumberTableATTR: NameType = "LineNumberTable" - final val LocalVariableTableATTR: NameType = "LocalVariableTable" - final val RuntimeAnnotationATTR: NameType = "RuntimeVisibleAnnotations" // RetentionPolicy.RUNTIME - final val RuntimeParamAnnotationATTR: NameType = "RuntimeVisibleParameterAnnotations" // RetentionPolicy.RUNTIME (annotations on parameters) - final val ScalaATTR: NameType = "Scala" - final val ScalaSignatureATTR: NameType = "ScalaSig" - final val SignatureATTR: NameType = "Signature" - final val SourceFileATTR: NameType = "SourceFile" - final val SyntheticATTR: NameType = "Synthetic" - - def dropSingletonName(name: Name): TypeName = (name dropRight SINGLETON_SUFFIX.length).toTypeName - def singletonName(name: Name): TypeName = (name append SINGLETON_SUFFIX).toTypeName - def implClassName(name: Name): TypeName = (name append IMPL_CLASS_SUFFIX).toTypeName - def interfaceName(implname: Name): TypeName = (implname dropRight IMPL_CLASS_SUFFIX.length).toTypeName - } - - abstract class TermNames extends Keywords with TermNamesApi { - type NameType = TermName - protected implicit def createNameType(name: String): TermName = newTermNameCached(name) - - /** Base strings from which synthetic names are derived. */ - val BITMAP_PREFIX = "bitmap$" - val CHECK_IF_REFUTABLE_STRING = "check$ifrefutable$" - val DEFAULT_GETTER_STRING = "$default$" - val DEFAULT_GETTER_INIT_STRING = "$lessinit$greater" // CONSTRUCTOR.encoded, less is more - val DO_WHILE_PREFIX = "doWhile$" - val EVIDENCE_PARAM_PREFIX = "evidence$" - val EXCEPTION_RESULT_PREFIX = "exceptionResult" - val EXPAND_SEPARATOR_STRING = "$$" - val INTERPRETER_IMPORT_WRAPPER = "$iw" - val INTERPRETER_LINE_PREFIX = "line" - val INTERPRETER_VAR_PREFIX = "res" - val INTERPRETER_WRAPPER_SUFFIX = "$object" - val LOCALDUMMY_PREFIX = "<local " // owner of local blocks - val PROTECTED_PREFIX = "protected$" - val PROTECTED_SET_PREFIX = PROTECTED_PREFIX + "set" - val SUPER_PREFIX_STRING = "super$" - val TRAIT_SETTER_SEPARATOR_STRING = "$_setter_$" - val WHILE_PREFIX = "while$" - - // Compiler internal names - val ANYNAME: NameType = "<anyname>" - val CONSTRUCTOR: NameType = "<init>" - val EQEQ_LOCAL_VAR: NameType = "eqEqTemp$" - val FAKE_LOCAL_THIS: NameType = "this$" - val INITIALIZER: NameType = CONSTRUCTOR // Is this buying us something? - val LAZY_LOCAL: NameType = "$lzy" - val LAZY_SLOW_SUFFIX: NameType = "$lzycompute" - val LOCAL_SUFFIX_STRING = " " - val UNIVERSE_BUILD_PREFIX: NameType = "$u.build." - val UNIVERSE_BUILD: NameType = "$u.build" - val UNIVERSE_PREFIX: NameType = "$u." - val UNIVERSE_SHORT: NameType = "$u" - val MIRROR_PREFIX: NameType = "$m." - val MIRROR_SHORT: NameType = "$m" - val MIRROR_UNTYPED: NameType = "$m$untyped" - val REIFY_FREE_PREFIX: NameType = "free$" - val REIFY_FREE_THIS_SUFFIX: NameType = "$this" - val REIFY_FREE_VALUE_SUFFIX: NameType = "$value" - val REIFY_SYMDEF_PREFIX: NameType = "symdef$" - val MIXIN_CONSTRUCTOR: NameType = "$init$" - val MODULE_INSTANCE_FIELD: NameType = NameTransformer.MODULE_INSTANCE_NAME // "MODULE$" - val OUTER: NameType = "$outer" - val OUTER_LOCAL: NameType = OUTER + LOCAL_SUFFIX_STRING // "$outer ", note the space - val OUTER_SYNTH: NameType = "<outer>" // emitted by virtual pattern matcher, replaced by outer accessor in explicitouter - val ROOTPKG: NameType = "_root_" - val SELECTOR_DUMMY: NameType = "<unapply-selector>" - val SELF: NameType = "$this" - val SETTER_SUFFIX: NameType = encode("_=") - val SPECIALIZED_INSTANCE: NameType = "specInstance$" - val STAR: NameType = "*" - val THIS: NameType = "_$this" - - @deprecated("Use SPECIALIZED_SUFFIX", "2.10.0") - def SPECIALIZED_SUFFIX_STRING = SPECIALIZED_SUFFIX.toString - @deprecated("Use SPECIALIZED_SUFFIX", "2.10.0") - def SPECIALIZED_SUFFIX_NAME: TermName = SPECIALIZED_SUFFIX.toTermName - - def isConstructorName(name: Name) = name == CONSTRUCTOR || name == MIXIN_CONSTRUCTOR - def isExceptionResultName(name: Name) = name startsWith EXCEPTION_RESULT_PREFIX - def isImplClassName(name: Name) = name endsWith IMPL_CLASS_SUFFIX - def isLocalDummyName(name: Name) = name startsWith LOCALDUMMY_PREFIX - def isLocalName(name: Name) = name endsWith LOCAL_SUFFIX_STRING - def isLoopHeaderLabel(name: Name) = (name startsWith WHILE_PREFIX) || (name startsWith DO_WHILE_PREFIX) - def isProtectedAccessorName(name: Name) = name startsWith PROTECTED_PREFIX - def isSuperAccessorName(name: Name) = name startsWith SUPER_PREFIX_STRING - def isReplWrapperName(name: Name) = name containsName INTERPRETER_IMPORT_WRAPPER - def isSetterName(name: Name) = name endsWith SETTER_SUFFIX - def isTraitSetterName(name: Name) = isSetterName(name) && (name containsName TRAIT_SETTER_SEPARATOR_STRING) - def isSingletonName(name: Name) = name endsWith SINGLETON_SUFFIX - def isModuleName(name: Name) = name endsWith MODULE_SUFFIX_NAME - - def isDeprecatedIdentifierName(name: Name) = name.toTermName match { - case nme.`then` | nme.`macro` => true - case _ => false - } - - def isOpAssignmentName(name: Name) = name match { - case raw.NE | raw.LE | raw.GE | EMPTY => false - case _ => - name.endChar == '=' && name.startChar != '=' && isOperatorPart(name.startChar) - } - - /** The expanded name of `name` relative to this class `base` with given `separator` - */ - def expandedName(name: TermName, base: Symbol, separator: String = EXPAND_SEPARATOR_STRING): TermName = - newTermNameCached(base.fullName('$') + separator + name) - - /** The expanded setter name of `name` relative to this class `base` - */ - def expandedSetterName(name: TermName, base: Symbol): TermName = - expandedName(name, base, separator = TRAIT_SETTER_SEPARATOR_STRING) - - /** If `name` is an expandedName name, the original name. - * Otherwise `name` itself. - */ - def originalName(name: Name): Name = { - var i = name.length - while (i >= 2 && !(name(i - 1) == '$' && name(i - 2) == '$')) i -= 1 - if (i >= 2) { - while (i >= 3 && name(i - 3) == '$') i -= 1 - name.subName(i, name.length) - } else name - } - - def unspecializedName(name: Name): Name = ( - if (name endsWith SPECIALIZED_SUFFIX) - name.subName(0, name.lastIndexOf('m') - 1) - else name - ) - - /* - def anonNumberSuffix(name: Name): Name = { - ("" + name) lastIndexOf '$' match { - case -1 => nme.EMPTY - case idx => - val s = name drop idx - if (s.toString forall (_.isDigit)) s - else nme.EMPTY - } - } - */ - - /** Return the original name and the types on which this name - * is specialized. For example, - * {{{ - * splitSpecializedName("foo$mIcD$sp") == ('foo', "I", "D") - * }}} - * `foo$mIcD$sp` is the name of a method specialized on two type - * parameters, the first one belonging to the method itself, on Int, - * and another one belonging to the enclosing class, on Double. - */ - def splitSpecializedName(name: Name): (Name, String, String) = - if (name endsWith SPECIALIZED_SUFFIX) { - val name1 = name dropRight SPECIALIZED_SUFFIX.length - val idxC = name1 lastIndexOf 'c' - val idxM = name1 lastIndexOf 'm' - - (name1.subName(0, idxM - 1), - name1.subName(idxC + 1, name1.length).toString, - name1.subName(idxM + 1, idxC).toString) - } else - (name, "", "") - - def getterName(name: TermName): TermName = if (isLocalName(name)) localToGetter(name) else name - def getterToLocal(name: TermName): TermName = name append LOCAL_SUFFIX_STRING - def getterToSetter(name: TermName): TermName = name append SETTER_SUFFIX - def localToGetter(name: TermName): TermName = name dropRight LOCAL_SUFFIX_STRING.length - - def dropLocalSuffix(name: Name): Name = if (name endsWith ' ') name dropRight 1 else name - - def setterToGetter(name: TermName): TermName = { - val p = name.pos(TRAIT_SETTER_SEPARATOR_STRING) - if (p < name.length) - setterToGetter(name drop (p + TRAIT_SETTER_SEPARATOR_STRING.length)) - else - name.subName(0, name.length - SETTER_SUFFIX.length) - } - - // Nominally, name$default$N, encoded for <init> - def defaultGetterName(name: Name, pos: Int): TermName = { - val prefix = if (isConstructorName(name)) DEFAULT_GETTER_INIT_STRING else name - newTermName(prefix + DEFAULT_GETTER_STRING + pos) - } - // Nominally, name from name$default$N, CONSTRUCTOR for <init> - def defaultGetterToMethod(name: Name): TermName = { - val p = name.pos(DEFAULT_GETTER_STRING) - if (p < name.length) { - val q = name.toTermName.subName(0, p) - // i.e., if (q.decoded == CONSTRUCTOR.toString) CONSTRUCTOR else q - if (q.toString == DEFAULT_GETTER_INIT_STRING) CONSTRUCTOR else q - } else name.toTermName - } - - // If the name ends with $nn where nn are - // all digits, strip the $ and the digits. - // Otherwise return the argument. - def stripAnonNumberSuffix(name: Name): Name = { - var pos = name.length - while (pos > 0 && name(pos - 1).isDigit) - pos -= 1 - - if (pos <= 0 || pos == name.length || name(pos - 1) != '$') name - else name.subName(0, pos - 1) - } - - def stripModuleSuffix(name: Name): Name = ( - if (isModuleName(name)) name dropRight MODULE_SUFFIX_STRING.length else name - ) - def localDummyName(clazz: Symbol): TermName = newTermName(LOCALDUMMY_PREFIX + clazz.name + ">") - def superName(name: Name): TermName = newTermName(SUPER_PREFIX_STRING + name) - - /** The name of an accessor for protected symbols. */ - def protName(name: Name): TermName = newTermName(PROTECTED_PREFIX + name) - - /** The name of a setter for protected symbols. Used for inherited Java fields. */ - def protSetterName(name: Name): TermName = newTermName(PROTECTED_SET_PREFIX + name) - - final val Nil: NameType = "Nil" - final val Predef: NameType = "Predef" - final val ScalaRunTime: NameType = "ScalaRunTime" - final val Some: NameType = "Some" - - val _1 : NameType = "_1" - val _2 : NameType = "_2" - val _3 : NameType = "_3" - val _4 : NameType = "_4" - val _5 : NameType = "_5" - val _6 : NameType = "_6" - val _7 : NameType = "_7" - val _8 : NameType = "_8" - val _9 : NameType = "_9" - val _10 : NameType = "_10" - val _11 : NameType = "_11" - val _12 : NameType = "_12" - val _13 : NameType = "_13" - val _14 : NameType = "_14" - val _15 : NameType = "_15" - val _16 : NameType = "_16" - val _17 : NameType = "_17" - val _18 : NameType = "_18" - val _19 : NameType = "_19" - val _20 : NameType = "_20" - val _21 : NameType = "_21" - val _22 : NameType = "_22" - - val x_0 : NameType = "x$0" - val x_1 : NameType = "x$1" - val x_2 : NameType = "x$2" - val x_3 : NameType = "x$3" - val x_4 : NameType = "x$4" - val x_5 : NameType = "x$5" - val x_6 : NameType = "x$6" - val x_7 : NameType = "x$7" - val x_8 : NameType = "x$8" - val x_9 : NameType = "x$9" - - @switch def syntheticParamName(i: Int): TermName = i match { - case 0 => nme.x_0 - case 1 => nme.x_1 - case 2 => nme.x_2 - case 3 => nme.x_3 - case 4 => nme.x_4 - case 5 => nme.x_5 - case 6 => nme.x_6 - case 7 => nme.x_7 - case 8 => nme.x_8 - case 9 => nme.x_9 - case _ => newTermName("x$" + i) - } - - @switch def productAccessorName(j: Int): TermName = j match { - case 1 => nme._1 - case 2 => nme._2 - case 3 => nme._3 - case 4 => nme._4 - case 5 => nme._5 - case 6 => nme._6 - case 7 => nme._7 - case 8 => nme._8 - case 9 => nme._9 - case 10 => nme._10 - case 11 => nme._11 - case 12 => nme._12 - case 13 => nme._13 - case 14 => nme._14 - case 15 => nme._15 - case 16 => nme._16 - case 17 => nme._17 - case 18 => nme._18 - case 19 => nme._19 - case 20 => nme._20 - case 21 => nme._21 - case 22 => nme._22 - case _ => newTermName("_" + j) - } - - val ??? = encode("???") - - val wrapRefArray: NameType = "wrapRefArray" - val wrapByteArray: NameType = "wrapByteArray" - val wrapShortArray: NameType = "wrapShortArray" - val wrapCharArray: NameType = "wrapCharArray" - val wrapIntArray: NameType = "wrapIntArray" - val wrapLongArray: NameType = "wrapLongArray" - val wrapFloatArray: NameType = "wrapFloatArray" - val wrapDoubleArray: NameType = "wrapDoubleArray" - val wrapBooleanArray: NameType = "wrapBooleanArray" - val wrapUnitArray: NameType = "wrapUnitArray" - val genericWrapArray: NameType = "genericWrapArray" - - // Compiler utilized names - - val AnnotatedType: NameType = "AnnotatedType" - val AnnotationInfo: NameType = "AnnotationInfo" - val Any: NameType = "Any" - val AnyVal: NameType = "AnyVal" - val AppliedTypeTree: NameType = "AppliedTypeTree" - val Apply: NameType = "Apply" - val ArrayAnnotArg: NameType = "ArrayAnnotArg" - val Constant: NameType = "Constant" - val ConstantType: NameType = "ConstantType" - val EmptyPackage: NameType = "EmptyPackage" - val EmptyPackageClass: NameType = "EmptyPackageClass" - val ExistentialTypeTree: NameType = "ExistentialTypeTree" - val Flag : NameType = "Flag" - val Ident: NameType = "Ident" - val Import: NameType = "Import" - val Literal: NameType = "Literal" - val LiteralAnnotArg: NameType = "LiteralAnnotArg" - val Modifiers: NameType = "Modifiers" - val NestedAnnotArg: NameType = "NestedAnnotArg" - val NoFlags: NameType = "NoFlags" - val NoPrefix: NameType = "NoPrefix" - val NoSymbol: NameType = "NoSymbol" - val Nothing: NameType = "Nothing" - val NoType: NameType = "NoType" - val Null: NameType = "Null" - val Object: NameType = "Object" - val RootPackage: NameType = "RootPackage" - val RootClass: NameType = "RootClass" - val Select: NameType = "Select" - val StringContext: NameType = "StringContext" - val This: NameType = "This" - val ThisType: NameType = "ThisType" - val Tree : NameType = "Tree" - val Tuple2: NameType = "Tuple2" - val TYPE_ : NameType = "TYPE" - val TypeApply: NameType = "TypeApply" - val TypeRef: NameType = "TypeRef" - val TypeTree: NameType = "TypeTree" - val UNIT : NameType = "UNIT" - val add_ : NameType = "add" - val annotation: NameType = "annotation" - val anyValClass: NameType = "anyValClass" - val append: NameType = "append" - val apply: NameType = "apply" - val applyDynamic: NameType = "applyDynamic" - val applyDynamicNamed: NameType = "applyDynamicNamed" - val applyImpl: NameType = "applyImpl" - val applyOrElse: NameType = "applyOrElse" - val args : NameType = "args" - val argv : NameType = "argv" - val arrayClass: NameType = "arrayClass" - val arrayElementClass: NameType = "arrayElementClass" - val arrayTagToClassManifest: NameType = "arrayTagToClassManifest" - val arrayValue: NameType = "arrayValue" - val array_apply : NameType = "array_apply" - val array_clone : NameType = "array_clone" - val array_length : NameType = "array_length" - val array_update : NameType = "array_update" - val arraycopy: NameType = "arraycopy" - val asTermSymbol: NameType = "asTermSymbol" - val asModuleSymbol: NameType = "asModuleSymbol" - val asMethodSymbol: NameType = "asMethodSymbol" - val asTypeSymbol: NameType = "asTypeSymbol" - val asClassSymbol: NameType = "asClassSymbol" - val asInstanceOf_ : NameType = "asInstanceOf" - val asInstanceOf_Ob : NameType = "$asInstanceOf" - val asTypeConstructor: NameType = "asTypeConstructor" - val assert_ : NameType = "assert" - val assume_ : NameType = "assume" - val basis : NameType = "basis" - val box: NameType = "box" - val build : NameType = "build" - val bytes: NameType = "bytes" - val canEqual_ : NameType = "canEqual" - val checkInitialized: NameType = "checkInitialized" - val classOf: NameType = "classOf" - val clone_ : NameType = if (forMSIL) "MemberwiseClone" else "clone" // sn.OClone causes checkinit failure - val concreteTypeTagToManifest: NameType = "concreteTypeTagToManifest" - val conforms: NameType = "conforms" - val copy: NameType = "copy" - val currentMirror: NameType = "currentMirror" - val definitions: NameType = "definitions" - val delayedInit: NameType = "delayedInit" - val delayedInitArg: NameType = "delayedInit$body" - val drop: NameType = "drop" - val elem: NameType = "elem" - val emptyValDef: NameType = "emptyValDef" - val ensureAccessible : NameType = "ensureAccessible" - val eq: NameType = "eq" - val equalsNumChar : NameType = "equalsNumChar" - val equalsNumNum : NameType = "equalsNumNum" - val equalsNumObject : NameType = "equalsNumObject" - val equals_ : NameType = if (forMSIL) "Equals" else "equals" - val error: NameType = "error" - val eval: NameType = "eval" - val ex: NameType = "ex" - val experimental: NameType = "experimental" - val false_ : NameType = "false" - val filter: NameType = "filter" - val finalize_ : NameType = if (forMSIL) "Finalize" else "finalize" - val find_ : NameType = "find" - val flagsFromBits : NameType = "flagsFromBits" - val flatMap: NameType = "flatMap" - val foreach: NameType = "foreach" - val genericArrayOps: NameType = "genericArrayOps" - val get: NameType = "get" - val getOrElse: NameType = "getOrElse" - val hasNext: NameType = "hasNext" - val hashCode_ : NameType = if (forMSIL) "GetHashCode" else "hashCode" - val hash_ : NameType = "hash" - val head: NameType = "head" - val identity: NameType = "identity" - val implicitly: NameType = "implicitly" - val in: NameType = "in" - val info: NameType = "info" - val inlinedEquals: NameType = "inlinedEquals" - val isArray: NameType = "isArray" - val isDefinedAt: NameType = "isDefinedAt" - val isEmpty: NameType = "isEmpty" - val isInstanceOf_ : NameType = "isInstanceOf" - val isInstanceOf_Ob : NameType = "$isInstanceOf" - val java: NameType = "java" - val key: NameType = "key" - val lang: NameType = "lang" - val length: NameType = "length" - val lengthCompare: NameType = "lengthCompare" - val liftedTree: NameType = "liftedTree" - val `macro` : NameType = "macro" - val macroThis : NameType = "_this" - val macroContext : NameType = "c" - val main: NameType = "main" - val manifest: NameType = "manifest" - val manifestToConcreteTypeTag: NameType = "manifestToConcreteTypeTag" - val map: NameType = "map" - val materializeArrayTag: NameType = "materializeArrayTag" - val materializeClassTag: NameType = "materializeClassTag" - val materializeConcreteTypeTag: NameType = "materializeConcreteTypeTag" - val materializeTypeTag: NameType = "materializeTypeTag" - val mirror : NameType = "mirror" - val moduleClass : NameType = "moduleClass" - val name: NameType = "name" - val ne: NameType = "ne" - val newArray: NameType = "newArray" - val newFreeExistential: NameType = "newFreeExistential" - val newFreeTerm: NameType = "newFreeTerm" - val newFreeType: NameType = "newFreeType" - val newNestedSymbol: NameType = "newNestedSymbol" - val newScopeWith: NameType = "newScopeWith" - val next: NameType = "next" - val nmeNewTermName: NameType = "newTermName" - val nmeNewTypeName: NameType = "newTypeName" - val normalize: NameType = "normalize" - val notifyAll_ : NameType = "notifyAll" - val notify_ : NameType = "notify" - val null_ : NameType = "null" - val ofDim: NameType = "ofDim" - val origin: NameType = "origin" - val prefix : NameType = "prefix" - val productArity: NameType = "productArity" - val productElement: NameType = "productElement" - val productIterator: NameType = "productIterator" - val productPrefix: NameType = "productPrefix" - val readResolve: NameType = "readResolve" - val reflect : NameType = "reflect" - val reify : NameType = "reify" - val rootMirror : NameType = "rootMirror" - val runOrElse: NameType = "runOrElse" - val runtime: NameType = "runtime" - val runtimeClass: NameType = "runtimeClass" - val runtimeMirror: NameType = "runtimeMirror" - val sameElements: NameType = "sameElements" - val scala_ : NameType = "scala" - val selectDynamic: NameType = "selectDynamic" - val selectOverloadedMethod: NameType = "selectOverloadedMethod" - val selectTerm: NameType = "selectTerm" - val selectType: NameType = "selectType" - val self: NameType = "self" - val setAccessible: NameType = "setAccessible" - val setAnnotations: NameType = "setAnnotations" - val setSymbol: NameType = "setSymbol" - val setType: NameType = "setType" - val setTypeSignature: NameType = "setTypeSignature" - val splice: NameType = "splice" - val staticClass : NameType = "staticClass" - val staticModule : NameType = "staticModule" - val synchronized_ : NameType = "synchronized" - val tail: NameType = "tail" - val `then` : NameType = "then" - val this_ : NameType = "this" - val thisPrefix : NameType = "thisPrefix" - val throw_ : NameType = "throw" - val toArray: NameType = "toArray" - val toList: NameType = "toList" - val toObjectArray : NameType = "toObjectArray" - val toSeq: NameType = "toSeq" - val toString_ : NameType = if (forMSIL) "ToString" else "toString" - val tpe : NameType = "tpe" - val tree : NameType = "tree" - val true_ : NameType = "true" - val typedProductIterator: NameType = "typedProductIterator" - val unapply: NameType = "unapply" - val unapplySeq: NameType = "unapplySeq" - val unbox: NameType = "unbox" - val universe: NameType = "universe" - val update: NameType = "update" - val updateDynamic: NameType = "updateDynamic" - val value: NameType = "value" - val valueOf : NameType = "valueOf" - val values : NameType = "values" - val view_ : NameType = "view" - val wait_ : NameType = "wait" - val withFilter: NameType = "withFilter" - val wrap: NameType = "wrap" - val zip: NameType = "zip" - - val synthSwitch: NameType = "$synthSwitch" - - // unencoded operators - object raw { - final val AMP : NameType = "&" - final val BANG : NameType = "!" - final val BAR : NameType = "|" - final val DOLLAR: NameType = "$" - final val GE: NameType = ">=" - final val LE: NameType = "<=" - final val MINUS: NameType = "-" - final val NE: NameType = "!=" - final val PLUS : NameType = "+" - final val SLASH: NameType = "/" - final val STAR : NameType = "*" - final val TILDE: NameType = "~" - - final val isUnary: Set[Name] = Set(MINUS, PLUS, TILDE, BANG) - } - - // value-conversion methods - val toByte: NameType = "toByte" - val toShort: NameType = "toShort" - val toChar: NameType = "toChar" - val toInt: NameType = "toInt" - val toLong: NameType = "toLong" - val toFloat: NameType = "toFloat" - val toDouble: NameType = "toDouble" - - // primitive operation methods for structual types mostly - // overlap with the above, but not for these two. - val toCharacter: NameType = "toCharacter" - val toInteger: NameType = "toInteger" - - def newLazyValSlowComputeName(lzyValName: Name) = lzyValName append LAZY_SLOW_SUFFIX - - // ASCII names for operators - val ADD = encode("+") - val AND = encode("&") - val ASR = encode(">>") - val DIV = encode("/") - val EQ = encode("==") - val EQL = encode("=") - val GE = encode(">=") - val GT = encode(">") - val HASHHASH = encode("##") - val LE = encode("<=") - val LSL = encode("<<") - val LSR = encode(">>>") - val LT = encode("<") - val MINUS = encode("-") - val MOD = encode("%") - val MUL = encode("*") - val NE = encode("!=") - val OR = encode("|") - val PLUS = ADD // technically redundant, but ADD looks funny with MINUS - val SUB = MINUS // ... as does SUB with PLUS - val XOR = encode("^") - val ZAND = encode("&&") - val ZOR = encode("||") - - // unary operators - val UNARY_~ = encode("unary_~") - val UNARY_+ = encode("unary_+") - val UNARY_- = encode("unary_-") - val UNARY_! = encode("unary_!") - - // Grouped here so Cleanup knows what tests to perform. - val CommonOpNames = Set[Name](OR, XOR, AND, EQ, NE) - val ConversionNames = Set[Name](toByte, toChar, toDouble, toFloat, toInt, toLong, toShort) - val BooleanOpNames = Set[Name](ZOR, ZAND, UNARY_!) ++ CommonOpNames - val NumberOpNames = ( - Set[Name](ADD, SUB, MUL, DIV, MOD, LSL, LSR, ASR, LT, LE, GE, GT) - ++ Set(UNARY_+, UNARY_-, UNARY_!) - ++ ConversionNames - ++ CommonOpNames - ) - - val add: NameType = "add" - val complement: NameType = "complement" - val divide: NameType = "divide" - val multiply: NameType = "multiply" - val negate: NameType = "negate" - val positive: NameType = "positive" - val shiftLogicalRight: NameType = "shiftLogicalRight" - val shiftSignedLeft: NameType = "shiftSignedLeft" - val shiftSignedRight: NameType = "shiftSignedRight" - val subtract: NameType = "subtract" - val takeAnd: NameType = "takeAnd" - val takeConditionalAnd: NameType = "takeConditionalAnd" - val takeConditionalOr: NameType = "takeConditionalOr" - val takeModulo: NameType = "takeModulo" - val takeNot: NameType = "takeNot" - val takeOr: NameType = "takeOr" - val takeXor: NameType = "takeXor" - val testEqual: NameType = "testEqual" - val testGreaterOrEqualThan: NameType = "testGreaterOrEqualThan" - val testGreaterThan: NameType = "testGreaterThan" - val testLessOrEqualThan: NameType = "testLessOrEqualThan" - val testLessThan: NameType = "testLessThan" - val testNotEqual: NameType = "testNotEqual" - - def toUnaryName(name: TermName): TermName = name match { - case raw.MINUS => UNARY_- - case raw.PLUS => UNARY_+ - case raw.TILDE => UNARY_~ - case raw.BANG => UNARY_! - case _ => name - } - /** The name of a method which stands in for a primitive operation - * during structural type dispatch. - */ - def primitiveInfixMethodName(name: Name): TermName = name match { - case OR => takeOr - case XOR => takeXor - case AND => takeAnd - case EQ => testEqual - case NE => testNotEqual - case ADD => add - case SUB => subtract - case MUL => multiply - case DIV => divide - case MOD => takeModulo - case LSL => shiftSignedLeft - case LSR => shiftLogicalRight - case ASR => shiftSignedRight - case LT => testLessThan - case LE => testLessOrEqualThan - case GE => testGreaterOrEqualThan - case GT => testGreaterThan - case ZOR => takeConditionalOr - case ZAND => takeConditionalAnd - case _ => NO_NAME - } - /** Postfix/prefix, really. - */ - def primitivePostfixMethodName(name: Name): TermName = name match { - case UNARY_! => takeNot - case UNARY_+ => positive - case UNARY_- => negate - case UNARY_~ => complement - case `toByte` => toByte - case `toShort` => toShort - case `toChar` => toCharacter - case `toInt` => toInteger - case `toLong` => toLong - case `toFloat` => toFloat - case `toDouble` => toDouble - case _ => NO_NAME - } - - /** Translate a String into a list of simple TypeNames and TermNames. - * In all segments before the last, type/term is determined by whether - * the following separator char is '.' or '#'. In the last segment, - * the argument "assumeTerm" determines it. Examples: - * - * package foo { - * object Lorax { object Wog ; class Wog } - * class Lorax { object Zax ; class Zax } - * } - * - * f("foo.Lorax", true) == List("foo": Term, "Lorax": Term) // object Lorax - * f("foo.Lorax", false) == List("foo": Term, "Lorax": Type) // class Lorax - * f("Lorax.Wog", true) == List("Lorax": Term, "Wog": Term) // object Wog - * f("Lorax.Wog", false) == List("Lorax": Term, "Wog": Type) // class Wog - * f("Lorax#Zax", true) == List("Lorax": Type, "Zax": Term) // object Zax - * f("Lorax#Zax", false) == List("Lorax": Type, "Zax": Type) // class Zax - * - * Note that in actual scala syntax you cannot refer to object Zax without an - * instance of Lorax, so Lorax#Zax could only mean the type. One might think - * that Lorax#Zax.type would work, but this is not accepted by the parser. - * For the purposes of referencing that object, the syntax is allowed. - */ - def segments(name: String, assumeTerm: Boolean): List[Name] = { - def mkName(str: String, term: Boolean): Name = - if (term) newTermName(str) else newTypeName(str) - - name.indexWhere(ch => ch == '.' || ch == '#') match { - // it's the last segment: the parameter tells us whether type or term - case -1 => if (name == "") scala.Nil else scala.List(mkName(name, assumeTerm)) - // otherwise, we can tell based on whether '#' or '.' is the following char. - case idx => - val (simple, div, rest) = (name take idx, name charAt idx, newTermName(name) drop (idx + 1)) - mkName(simple, div == '.') :: segments(rest, assumeTerm) - } - } - - def newBitmapName(bitmapPrefix: Name, n: Int) = bitmapPrefix append ("" + n) - - val BITMAP_NORMAL: NameType = BITMAP_PREFIX + "" // initialization bitmap for public/protected lazy vals - val BITMAP_TRANSIENT: NameType = BITMAP_PREFIX + "trans$" // initialization bitmap for transient lazy vals - val BITMAP_CHECKINIT: NameType = BITMAP_PREFIX + "init$" // initialization bitmap for checkinit values - val BITMAP_CHECKINIT_TRANSIENT: NameType = BITMAP_PREFIX + "inittrans$" // initialization bitmap for transient checkinit values - } - - object tpnme extends TypeNames { } - - /** For fully qualified type names. - */ - object fulltpnme extends TypeNames { - val RuntimeNothing: NameType = "scala.runtime.Nothing$" - val RuntimeNull: NameType = "scala.runtime.Null$" - val JavaLangEnum: NameType = "java.lang.Enum" - } - - /** Java binary names, like scala/runtime/Nothing$. - */ - object binarynme { - def toBinary(name: Name) = name mapName (_.replace('.', '/')) - - val RuntimeNothing = toBinary(fulltpnme.RuntimeNothing).toTypeName - val RuntimeNull = toBinary(fulltpnme.RuntimeNull).toTypeName - } - - val javanme = nme.javaKeywords - - // [Eugene++ to Martin] had to move a lot of stuff from here to TermNames to satisfy the contract - // why do we even have stuff in object nme? cf. object tpnme - object nme extends TermNames { - - def isModuleVarName(name: Name): Boolean = - stripAnonNumberSuffix(name) endsWith MODULE_VAR_SUFFIX - - def moduleVarName(name: TermName): TermName = - newTermNameCached("" + name + MODULE_VAR_SUFFIX) - - def getCause = sn.GetCause - def getClass_ = sn.GetClass - def getComponentType = sn.GetComponentType - def getMethod_ = sn.GetMethod - def invoke_ = sn.Invoke - - val isBoxedNumberOrBoolean: NameType = "isBoxedNumberOrBoolean" - val isBoxedNumber: NameType = "isBoxedNumber" - - val reflPolyCacheName: NameType = "reflPoly$Cache" - val reflClassCacheName: NameType = "reflClass$Cache" - val reflParamsCacheName: NameType = "reflParams$Cache" - val reflMethodCacheName: NameType = "reflMethod$Cache" - val reflMethodName: NameType = "reflMethod$Method" - - private val reflectionCacheNames = Set[NameType]( - reflPolyCacheName, - reflClassCacheName, - reflParamsCacheName, - reflMethodCacheName, - reflMethodName - ) - def isReflectionCacheName(name: Name) = reflectionCacheNames exists (name startsWith _) - - @deprecated("Use a method in tpnme", "2.10.0") def dropSingletonName(name: Name): TypeName = tpnme.dropSingletonName(name) - @deprecated("Use a method in tpnme", "2.10.0") def singletonName(name: Name): TypeName = tpnme.singletonName(name) - @deprecated("Use a method in tpnme", "2.10.0") def implClassName(name: Name): TypeName = tpnme.implClassName(name) - @deprecated("Use a method in tpnme", "2.10.0") def interfaceName(implname: Name): TypeName = tpnme.interfaceName(implname) - } - - abstract class SymbolNames { - protected implicit def createNameType(s: String): TypeName = newTypeNameCached(s) - - val BeanProperty : TypeName - val BooleanBeanProperty : TypeName - val BoxedBoolean : TypeName - val BoxedCharacter : TypeName - val BoxedNumber : TypeName - val Class : TypeName - val Delegate : TypeName - val IOOBException : TypeName // IndexOutOfBoundsException - val InvTargetException : TypeName // InvocationTargetException - val JavaSerializable : TypeName - val MethodAsObject : TypeName - val NPException : TypeName // NullPointerException - val Object : TypeName - val String : TypeName - val Throwable : TypeName - val ValueType : TypeName - - val ForName : TermName - val GetCause : TermName - val GetClass : TermName - val GetClassLoader : TermName - val GetComponentType : TermName - val GetMethod : TermName - val Invoke : TermName - val JavaLang : TermName - - val Boxed: immutable.Map[TypeName, TypeName] - } - - class JavaKeywords { - private val kw = new KeywordSetBuilder - - final val ABSTRACTkw: TermName = kw("abstract") - final val ASSERTkw: TermName = kw("assert") - final val BOOLEANkw: TermName = kw("boolean") - final val BREAKkw: TermName = kw("break") - final val BYTEkw: TermName = kw("byte") - final val CASEkw: TermName = kw("case") - final val CATCHkw: TermName = kw("catch") - final val CHARkw: TermName = kw("char") - final val CLASSkw: TermName = kw("class") - final val CONSTkw: TermName = kw("const") - final val CONTINUEkw: TermName = kw("continue") - final val DEFAULTkw: TermName = kw("default") - final val DOkw: TermName = kw("do") - final val DOUBLEkw: TermName = kw("double") - final val ELSEkw: TermName = kw("else") - final val ENUMkw: TermName = kw("enum") - final val EXTENDSkw: TermName = kw("extends") - final val FINALkw: TermName = kw("final") - final val FINALLYkw: TermName = kw("finally") - final val FLOATkw: TermName = kw("float") - final val FORkw: TermName = kw("for") - final val IFkw: TermName = kw("if") - final val GOTOkw: TermName = kw("goto") - final val IMPLEMENTSkw: TermName = kw("implements") - final val IMPORTkw: TermName = kw("import") - final val INSTANCEOFkw: TermName = kw("instanceof") - final val INTkw: TermName = kw("int") - final val INTERFACEkw: TermName = kw("interface") - final val LONGkw: TermName = kw("long") - final val NATIVEkw: TermName = kw("native") - final val NEWkw: TermName = kw("new") - final val PACKAGEkw: TermName = kw("package") - final val PRIVATEkw: TermName = kw("private") - final val PROTECTEDkw: TermName = kw("protected") - final val PUBLICkw: TermName = kw("public") - final val RETURNkw: TermName = kw("return") - final val SHORTkw: TermName = kw("short") - final val STATICkw: TermName = kw("static") - final val STRICTFPkw: TermName = kw("strictfp") - final val SUPERkw: TermName = kw("super") - final val SWITCHkw: TermName = kw("switch") - final val SYNCHRONIZEDkw: TermName = kw("synchronized") - final val THISkw: TermName = kw("this") - final val THROWkw: TermName = kw("throw") - final val THROWSkw: TermName = kw("throws") - final val TRANSIENTkw: TermName = kw("transient") - final val TRYkw: TermName = kw("try") - final val VOIDkw: TermName = kw("void") - final val VOLATILEkw: TermName = kw("volatile") - final val WHILEkw: TermName = kw("while") - - final val keywords = kw.result - } - - private abstract class JavaNames extends SymbolNames { - final val BoxedBoolean: TypeName = "java.lang.Boolean" - final val BoxedByte: TypeName = "java.lang.Byte" - final val BoxedCharacter: TypeName = "java.lang.Character" - final val BoxedDouble: TypeName = "java.lang.Double" - final val BoxedFloat: TypeName = "java.lang.Float" - final val BoxedInteger: TypeName = "java.lang.Integer" - final val BoxedLong: TypeName = "java.lang.Long" - final val BoxedNumber: TypeName = "java.lang.Number" - final val BoxedShort: TypeName = "java.lang.Short" - final val Class: TypeName = "java.lang.Class" - final val Delegate: TypeName = tpnme.NO_NAME - final val IOOBException: TypeName = "java.lang.IndexOutOfBoundsException" - final val InvTargetException: TypeName = "java.lang.reflect.InvocationTargetException" - final val MethodAsObject: TypeName = "java.lang.reflect.Method" - final val NPException: TypeName = "java.lang.NullPointerException" - final val Object: TypeName = "java.lang.Object" - final val String: TypeName = "java.lang.String" - final val Throwable: TypeName = "java.lang.Throwable" - final val ValueType: TypeName = tpnme.NO_NAME - - final val ForName: TermName = newTermName("forName") - final val GetCause: TermName = newTermName("getCause") - final val GetClass: TermName = newTermName("getClass") - final val GetClassLoader: TermName = newTermName("getClassLoader") - final val GetComponentType: TermName = newTermName("getComponentType") - final val GetMethod: TermName = newTermName("getMethod") - final val Invoke: TermName = newTermName("invoke") - final val JavaLang: TermName = newTermName("java.lang") - - val Boxed = immutable.Map[TypeName, TypeName]( - tpnme.Boolean -> BoxedBoolean, - tpnme.Byte -> BoxedByte, - tpnme.Char -> BoxedCharacter, - tpnme.Short -> BoxedShort, - tpnme.Int -> BoxedInteger, - tpnme.Long -> BoxedLong, - tpnme.Float -> BoxedFloat, - tpnme.Double -> BoxedDouble - ) - } - - private class MSILNames extends SymbolNames { - final val BeanProperty: TypeName = tpnme.NO_NAME - final val BooleanBeanProperty: TypeName = tpnme.NO_NAME - final val BoxedBoolean: TypeName = "System.IConvertible" - final val BoxedCharacter: TypeName = "System.IConvertible" - final val BoxedNumber: TypeName = "System.IConvertible" - final val Class: TypeName = "System.Type" - final val Delegate: TypeName = "System.MulticastDelegate" - final val IOOBException: TypeName = "System.IndexOutOfRangeException" - final val InvTargetException: TypeName = "System.Reflection.TargetInvocationException" - final val JavaSerializable: TypeName = tpnme.NO_NAME - final val MethodAsObject: TypeName = "System.Reflection.MethodInfo" - final val NPException: TypeName = "System.NullReferenceException" - final val Object: TypeName = "System.Object" - final val String: TypeName = "System.String" - final val Throwable: TypeName = "System.Exception" - final val ValueType: TypeName = "System.ValueType" - - final val ForName: TermName = newTermName("GetType") - final val GetCause: TermName = newTermName("InnerException") /* System.Reflection.TargetInvocationException.InnerException */ - final val GetClass: TermName = newTermName("GetType") - final lazy val GetClassLoader: TermName = throw new UnsupportedOperationException("Scala reflection is not supported on this platform"); - final val GetComponentType: TermName = newTermName("GetElementType") - final val GetMethod: TermName = newTermName("GetMethod") - final val Invoke: TermName = newTermName("Invoke") - final val JavaLang: TermName = newTermName("System") - - val Boxed = immutable.Map[TypeName, TypeName]( - tpnme.Boolean -> "System.Boolean", - tpnme.Byte -> "System.SByte", // a scala.Byte is signed and a System.SByte too (unlike a System.Byte) - tpnme.Char -> "System.Char", - tpnme.Short -> "System.Int16", - tpnme.Int -> "System.Int32", - tpnme.Long -> "System.Int64", - tpnme.Float -> "System.Single", - tpnme.Double -> "System.Double" - ) - } - - private class J2SENames extends JavaNames { - final val BeanProperty: TypeName = "scala.beans.BeanProperty" - final val BooleanBeanProperty: TypeName = "scala.beans.BooleanBeanProperty" - final val JavaSerializable: TypeName = "java.io.Serializable" - } - - lazy val sn: SymbolNames = - if (forMSIL) new MSILNames - else new J2SENames -} diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala deleted file mode 100644 index cadd76b1ba..0000000000 --- a/src/compiler/scala/reflect/internal/SymbolTable.scala +++ /dev/null @@ -1,332 +0,0 @@ -/* NSC -- new scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.reflect -package internal - -import scala.collection.{ mutable, immutable } -import util._ - -abstract class SymbolTable extends makro.Universe - with Collections - with Names - with Symbols - with Types - with Kinds - with ExistentialsAndSkolems - with FlagSets - with Scopes - with Mirrors - with Definitions - with Constants - with BaseTypeSeqs - with InfoTransformers - with transform.Transforms - with StdNames - with AnnotationInfos - with AnnotationCheckers - with Trees - with TreePrinters - with Positions - with TypeDebugging - with Importers - with Required - with CapturedVariables - with StdAttachments - with StdCreators - with BuildUtils -{ - - val gen = new TreeGen { val global: SymbolTable.this.type = SymbolTable.this } - val treeBuild = gen - - def log(msg: => AnyRef): Unit - def abort(msg: String): Nothing = throw new FatalError(supplementErrorMessage(msg)) - - @deprecated("Give us a reason", "2.10.0") - def abort(): Nothing = abort("unknown error") - - /** Override with final implementation for inlining. */ - def debuglog(msg: => String): Unit = if (settings.debug.value) log(msg) - def debugwarn(msg: => String): Unit = if (settings.debug.value) Console.err.println(msg) - def throwableAsString(t: Throwable): String = "" + t - - /** Prints a stack trace if -Ydebug or equivalent was given, otherwise does nothing. */ - def debugStack(t: Throwable): Unit = debugwarn(throwableAsString(t)) - - /** Overridden when we know more about what was happening during a failure. */ - def supplementErrorMessage(msg: String): String = msg - - private[scala] def printCaller[T](msg: String)(result: T) = { - Console.err.println("%s: %s\nCalled from: %s".format(msg, result, - (new Throwable).getStackTrace.drop(2).take(15).mkString("\n"))) - - result - } - - private[scala] def printResult[T](msg: String)(result: T) = { - Console.err.println(msg + ": " + result) - result - } - private[scala] def logResult[T](msg: String)(result: T): T = { - log(msg + ": " + result) - result - } - private[scala] def logResultIf[T](msg: String, cond: T => Boolean)(result: T): T = { - if (cond(result)) - log(msg + ": " + result) - - result - } - - // For too long have we suffered in order to sort NAMES. - // I'm pretty sure there's a reasonable default for that. - // Notice challenge created by Ordering's invariance. - implicit def lowPriorityNameOrdering[T <: Names#Name]: Ordering[T] = - SimpleNameOrdering.asInstanceOf[Ordering[T]] - - private object SimpleNameOrdering extends Ordering[Names#Name] { - def compare(n1: Names#Name, n2: Names#Name) = ( - if (n1 eq n2) 0 - else n1.toString compareTo n2.toString - ) - } - - /** Dump each symbol to stdout after shutdown. - */ - final val traceSymbolActivity = sys.props contains "scalac.debug.syms" - object traceSymbols extends { - val global: SymbolTable.this.type = SymbolTable.this - } with util.TraceSymbolActivity - - /** Are we compiling for Java SE? */ - // def forJVM: Boolean - - /** Are we compiling for .NET? */ - def forMSIL: Boolean = false - - /** A last effort if symbol in a select <owner>.<name> is not found. - * This is overridden by the reflection compiler to make up a package - * when it makes sense (i.e. <owner> is a package and <name> is a term name). - */ - def missingHook(owner: Symbol, name: Name): Symbol = NoSymbol - - /** Returns the mirror that loaded given symbol */ - def mirrorThatLoaded(sym: Symbol): Mirror - - /** A period is an ordinal number for a phase in a run. - * Phases in later runs have higher periods than phases in earlier runs. - * Later phases have higher periods than earlier phases in the same run. - */ - type Period = Int - final val NoPeriod = 0 - - /** An ordinal number for compiler runs. First run has number 1. */ - type RunId = Int - final val NoRunId = 0 - - // sigh, this has to be public or atPhase doesn't inline. - var phStack: List[Phase] = Nil - private var ph: Phase = NoPhase - private var per = NoPeriod - - final def atPhaseStack: List[Phase] = phStack - final def phase: Phase = ph - - def atPhaseStackMessage = atPhaseStack match { - case Nil => "" - case ps => ps.reverseMap("->" + _).mkString("(", " ", ")") - } - - final def phase_=(p: Phase) { - //System.out.println("setting phase to " + p) - assert((p ne null) && p != NoPhase, p) - ph = p - per = period(currentRunId, p.id) - } - final def pushPhase(ph: Phase): Phase = { - val current = phase - phase = ph - phStack ::= ph - current - } - final def popPhase(ph: Phase) { - phStack = phStack.tail - phase = ph - } - - /** The current compiler run identifier. */ - def currentRunId: RunId - - /** The run identifier of the given period. */ - final def runId(period: Period): RunId = period >> 8 - - /** The phase identifier of the given period. */ - final def phaseId(period: Period): Phase#Id = period & 0xFF - - /** The period at the start of run that includes `period`. */ - final def startRun(period: Period): Period = period & 0xFFFFFF00 - - /** The current period. */ - final def currentPeriod: Period = { - //assert(per == (currentRunId << 8) + phase.id) - per - } - - /** The phase associated with given period. */ - final def phaseOf(period: Period): Phase = phaseWithId(phaseId(period)) - - final def period(rid: RunId, pid: Phase#Id): Period = - (rid << 8) + pid - - /** Are we later than given phase in compilation? */ - final def isAtPhaseAfter(p: Phase) = - p != NoPhase && phase.id > p.id - - /** Perform given operation at given phase. */ - @inline final def atPhase[T](ph: Phase)(op: => T): T = { - val saved = pushPhase(ph) - try op - finally popPhase(saved) - } - - - /** Since when it is to be "at" a phase is inherently ambiguous, - * a couple unambiguously named methods. - */ - @inline final def beforePhase[T](ph: Phase)(op: => T): T = atPhase(ph)(op) - @inline final def afterPhase[T](ph: Phase)(op: => T): T = atPhase(ph.next)(op) - @inline final def afterCurrentPhase[T](op: => T): T = atPhase(phase.next)(op) - @inline final def beforePrevPhase[T](op: => T): T = atPhase(phase.prev)(op) - - @inline final def atPhaseNotLaterThan[T](target: Phase)(op: => T): T = - if (isAtPhaseAfter(target)) atPhase(target)(op) else op - - final def isValid(period: Period): Boolean = - period != 0 && runId(period) == currentRunId && { - val pid = phaseId(period) - if (phase.id > pid) infoTransformers.nextFrom(pid).pid >= phase.id - else infoTransformers.nextFrom(phase.id).pid >= pid - } - - final def isValidForBaseClasses(period: Period): Boolean = { - def noChangeInBaseClasses(it: InfoTransformer, limit: Phase#Id): Boolean = ( - it.pid >= limit || - !it.changesBaseClasses && noChangeInBaseClasses(it.next, limit) - ); - period != 0 && runId(period) == currentRunId && { - val pid = phaseId(period) - if (phase.id > pid) noChangeInBaseClasses(infoTransformers.nextFrom(pid), phase.id) - else noChangeInBaseClasses(infoTransformers.nextFrom(phase.id), pid) - } - } - - def openPackageModule(container: Symbol, dest: Symbol) { - // unlink existing symbols in the package - for (member <- container.info.decls.iterator) { - if (!member.isPrivate && !member.isConstructor) { - // todo: handle overlapping definitions in some way: mark as errors - // or treat as abstractions. For now the symbol in the package module takes precedence. - for (existing <- dest.info.decl(member.name).alternatives) - dest.info.decls.unlink(existing) - } - } - // enter non-private decls the class - for (member <- container.info.decls.iterator) { - if (!member.isPrivate && !member.isConstructor) { - dest.info.decls.enter(member) - } - } - // enter decls of parent classes - for (p <- container.parentSymbols) { - if (p != definitions.ObjectClass) { - openPackageModule(p, dest) - } - } - } - - /** Convert array parameters denoting a repeated parameter of a Java method - * to `JavaRepeatedParamClass` types. - */ - def arrayToRepeated(tp: Type): Type = tp match { - case MethodType(params, rtpe) => - val formals = tp.paramTypes - assert(formals.last.typeSymbol == definitions.ArrayClass, formals) - val method = params.last.owner - val elemtp = formals.last.typeArgs.head match { - case RefinedType(List(t1, t2), _) if (t1.typeSymbol.isAbstractType && t2.typeSymbol == definitions.ObjectClass) => - t1 // drop intersection with Object for abstract types in varargs. UnCurry can handle them. - case t => - t - } - val newParams = method.newSyntheticValueParams(formals.init :+ definitions.javaRepeatedType(elemtp)) - MethodType(newParams, rtpe) - case PolyType(tparams, rtpe) => - PolyType(tparams, arrayToRepeated(rtpe)) - } - - abstract class SymLoader extends LazyType { - def fromSource = false - } - - /** if there's a `package` member object in `pkgClass`, enter its members into it. */ - def openPackageModule(pkgClass: Symbol) { - - val pkgModule = pkgClass.info.decl(nme.PACKAGEkw) - def fromSource = pkgModule.rawInfo match { - case ltp: SymLoader => ltp.fromSource - case _ => false - } - if (pkgModule.isModule && !fromSource) { - // println("open "+pkgModule)//DEBUG - openPackageModule(pkgModule, pkgClass) - } - } - - object perRunCaches { - import java.lang.ref.WeakReference - import scala.runtime.ScalaRunTime.stringOf - import scala.collection.generic.Clearable - - // Weak references so the garbage collector will take care of - // letting us know when a cache is really out of commission. - private val caches = mutable.HashSet[WeakReference[Clearable]]() - - def recordCache[T <: Clearable](cache: T): T = { - caches += new WeakReference(cache) - cache - } - - def clearAll() = { - debuglog("Clearing " + caches.size + " caches.") - caches foreach { ref => - val cache = ref.get() - if (cache == null) - caches -= ref - else - cache.clear() - } - } - - def newWeakMap[K, V]() = recordCache(mutable.WeakHashMap[K, V]()) - def newMap[K, V]() = recordCache(mutable.HashMap[K, V]()) - def newSet[K]() = recordCache(mutable.HashSet[K]()) - def newWeakSet[K <: AnyRef]() = recordCache(new WeakHashSet[K]()) - } - - /** The set of all installed infotransformers. */ - var infoTransformers = new InfoTransformer { - val pid = NoPhase.id - val changesBaseClasses = true - def transform(sym: Symbol, tpe: Type): Type = tpe - } - - /** The phase which has given index as identifier. */ - val phaseWithId: Array[Phase] - - /** Is this symbol table a part of a compiler universe? - */ - def isCompilerUniverse = false -} diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala deleted file mode 100644 index 86693cf880..0000000000 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ /dev/null @@ -1,3190 +0,0 @@ - /* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.reflect -package internal - -import scala.collection.{ mutable, immutable } -import scala.collection.mutable.ListBuffer -import util.Statistics._ -import Flags._ - -trait Symbols extends api.Symbols { self: SymbolTable => - import definitions._ - - protected var ids = 0 - - val emptySymbolArray = new Array[Symbol](0) - - def symbolCount = ids // statistics - - protected def nextId() = { ids += 1; ids } - - /** Used for deciding in the IDE whether we can interrupt the compiler */ - //protected var activeLocks = 0 - - /** Used for debugging only */ - //protected var lockedSyms = collection.immutable.Set[Symbol]() - - /** Used to keep track of the recursion depth on locked symbols */ - private var recursionTable = immutable.Map.empty[Symbol, Int] - - private var nextexid = 0 - protected def freshExistentialName(suffix: String) = { - nextexid += 1 - newTypeName("_" + nextexid + suffix) - } - - // Set the fields which point companions at one another. Returns the module. - def connectModuleToClass(m: ModuleSymbol, moduleClass: ClassSymbol): ModuleSymbol = { - moduleClass.sourceModule = m - m setModuleClass moduleClass - m - } - - /** Create a new free term. Its owner is NoSymbol. - */ - def newFreeTermSymbol(name: TermName, info: Type, value: => Any, flags: Long = 0L, origin: String): FreeTermSymbol = - new FreeTermSymbol(name, value, origin) initFlags flags setInfo info - - /** Create a new free type. Its owner is NoSymbol. - */ - def newFreeTypeSymbol(name: TypeName, info: Type, value: => Any, flags: Long = 0L, origin: String): FreeTypeSymbol = - new FreeTypeSymbol(name, value, origin) initFlags flags setInfo info - - /** The original owner of a class. Used by the backend to generate - * EnclosingMethod attributes. - */ - val originalOwner = perRunCaches.newMap[Symbol, Symbol]() - - abstract class SymbolContextApiImpl extends SymbolContextApi { - this: Symbol => - - def kind: String = kindString - def isExistential: Boolean = this.isExistentiallyBound - - def newNestedSymbol(name: Name, pos: Position, newFlags: Long, isClass: Boolean): Symbol = name match { - case n: TermName => newTermSymbol(n, pos, newFlags) - case n: TypeName => if (isClass) newClassSymbol(n, pos, newFlags) else newNonClassSymbol(n, pos, newFlags) - } - - def thisPrefix: Type = thisType - def selfType: Type = typeOfThis - def typeSignature: Type = info - def typeSignatureIn(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 setTypeSignature(tpe: Type): this.type = { setInfo(tpe); this } - def getAnnotations: List[AnnotationInfo] = { initialize; annotations } - def setAnnotations(annots: AnnotationInfo*): this.type = { setAnnotations(annots.toList); this } - - private def lastElemType(ts: Seq[Type]): Type = ts.last.normalize.typeArgs.head - - private def formalTypes(formals: List[Type], nargs: Int): List[Type] = { - val formals1 = formals mapConserve { - case TypeRef(_, ByNameParamClass, List(arg)) => arg - case formal => formal - } - if (isVarArgTypes(formals1)) { - val ft = lastElemType(formals) - formals1.init ::: List.fill(nargs - (formals1.length - 1))(ft) - } else formals1 - } - - def resolveOverloaded(pre: Type, targs: Seq[Type], actuals: Seq[Type]): Symbol = { - def firstParams(tpe: Type): (List[Symbol], List[Type]) = tpe match { - case PolyType(tparams, restpe) => - val (Nil, formals) = firstParams(restpe) - (tparams, formals) - case MethodType(params, _) => - (Nil, params map (_.tpe)) - case _ => - (Nil, Nil) - } - def isApplicable(alt: Symbol, targs: List[Type], actuals: Seq[Type]) = { - def isApplicableType(tparams: List[Symbol], tpe: Type): Boolean = { - val (tparams, formals) = firstParams(pre memberType alt) - val formals1 = formalTypes(formals, actuals.length) - val actuals1 = - if (isVarArgTypes(actuals)) { - if (!isVarArgTypes(formals)) return false - actuals.init :+ lastElemType(actuals) - } else actuals - if (formals1.length != actuals1.length) return false - - if (tparams.isEmpty) return (actuals1 corresponds formals1)(_ <:< _) - - if (targs.length == tparams.length) - isApplicableType(List(), tpe.instantiateTypeParams(tparams, targs)) - else if (targs.nonEmpty) - false - else { - val tvars = tparams map (TypeVar(_)) - (actuals1 corresponds formals1) { (actual, formal) => - val tp1 = actual.deconst.instantiateTypeParams(tparams, tvars) - val pt1 = actual.instantiateTypeParams(tparams, tvars) - tp1 <:< pt1 - } && - solve(tvars, tparams, List.fill(tparams.length)(COVARIANT), upper = false) - } - } - isApplicableType(List(), pre.memberType(alt)) - } - def isAsGood(alt1: Symbol, alt2: Symbol): Boolean = { - alt1 == alt2 || - alt2 == NoSymbol || { - val (tparams, formals) = firstParams(pre memberType alt1) - isApplicable(alt2, tparams map (_.tpe), formals) - } - } - assert(isOverloaded) - val applicables = alternatives filter (isApplicable(_, targs.toList, actuals)) - def winner(alts: List[Symbol]) = - ((NoSymbol: Symbol) /: alts)((best, alt) => if (isAsGood(alt, best)) alt else best) - val best = winner(applicables) - if (best == winner(applicables.reverse)) best else NoSymbol - } - } - - /** The class for all symbols */ - abstract class Symbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: Name) - extends SymbolContextApiImpl - with HasFlags - with Annotatable[Symbol] { - - type AccessBoundaryType = Symbol - type AnnotationType = AnnotationInfo - - // TODO - don't allow names to be renamed in this unstructured a fashion. - // Rename as little as possible. Enforce invariants on all renames. - type TypeOfClonedSymbol >: Null <: Symbol { type NameType = Symbol.this.NameType } - - // Abstract here so TypeSymbol and TermSymbol can have a private[this] field - // with the proper specific type. - def rawname: NameType - def name: NameType - def name_=(n: Name): Unit - def asNameType(n: Name): NameType - - private[this] var _rawowner = initOwner // Syncnote: need not be protected, as only assignment happens in owner_=, which is not exposed to api - private[this] var _rawflags: Long = _ - - def rawowner = _rawowner - def rawflags = _rawflags - - private var rawpos = initPos - - val id = nextId() // identity displayed when -uniqid - //assert(id != 3390, initName) - - private[this] var _validTo: Period = NoPeriod - - if (traceSymbolActivity) - traceSymbols.recordNewSymbol(this) - - def validTo = _validTo - def validTo_=(x: Period) { _validTo = x} - - def pos = rawpos - def setPos(pos: Position): this.type = { this.rawpos = pos; this } - def setName(name: Name): this.type = { this.name = asNameType(name) ; this } - - // Update the surrounding scopes - protected[this] def changeNameInOwners(name: Name) { - if (owner.isClass) { - var ifs = owner.infos - while (ifs != null) { - ifs.info.decls.rehash(this, name) - ifs = ifs.prev - } - } - } - - def rawFlagString(mask: Long): String = calculateFlagString(rawflags & mask) - def rawFlagString: String = rawFlagString(flagMask) - def debugFlagString: String = flagString(AllFlags) - - /** String representation of symbol's variance */ - def varianceString: String = - if (variance == 1) "+" - else if (variance == -1) "-" - else "" - - override def flagMask = - if (settings.debug.value && !isAbstractType) AllFlags - else if (owner.isRefinementClass) ExplicitFlags & ~OVERRIDE - else ExplicitFlags - - // make the error message more googlable - def flagsExplanationString = - if (isGADTSkolem) " (this is a GADT skolem)" - else "" - - def shortSymbolClass = getClass.getName.split('.').last.stripPrefix("Symbols$") - def symbolCreationString: String = ( - "%s%25s | %-40s | %s".format( - if (settings.uniqid.value) "%06d | ".format(id) else "", - shortSymbolClass, - name.decode + " in " + owner, - rawFlagString - ) - ) - -// ------ creators ------------------------------------------------------------------- - - final def newValue(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): TermSymbol = - newTermSymbol(name, pos, newFlags) - final def newVariable(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): TermSymbol = - newTermSymbol(name, pos, MUTABLE | newFlags) - final def newValueParameter(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): TermSymbol = - newTermSymbol(name, pos, PARAM | newFlags) - - /** Create local dummy for template (owner of local blocks) */ - final def newLocalDummy(pos: Position): TermSymbol = - newTermSymbol(nme.localDummyName(this), pos) setInfo NoType - final def newMethod(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): MethodSymbol = - createMethodSymbol(name, pos, METHOD | newFlags) - final def newMethodSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): MethodSymbol = - createMethodSymbol(name, pos, METHOD | newFlags) - final def newLabel(name: TermName, pos: Position = NoPosition): MethodSymbol = - newMethod(name, pos, LABEL) - - /** Propagates ConstrFlags (JAVA, specifically) from owner to constructor. */ - final def newConstructor(pos: Position, newFlags: Long = 0L): MethodSymbol = - newMethod(nme.CONSTRUCTOR, pos, getFlag(ConstrFlags) | newFlags) - - /** Static constructor with info set. */ - def newStaticConstructor(pos: Position): MethodSymbol = - newConstructor(pos, STATIC) setInfo UnitClass.tpe - - /** Instance constructor with info set. */ - def newClassConstructor(pos: Position): MethodSymbol = - newConstructor(pos) setInfo MethodType(Nil, this.tpe) - - def newLinkedModule(clazz: Symbol, newFlags: Long = 0L): ModuleSymbol = { - val m = newModuleSymbol(clazz.name.toTermName, clazz.pos, MODULE | newFlags) - connectModuleToClass(m, clazz.asInstanceOf[ClassSymbol]) - } - final def newModule(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol = { - val m = newModuleSymbol(name, pos, newFlags | MODULE) - val clazz = newModuleClass(name.toTypeName, pos, m getFlag ModuleToClassFlags) - connectModuleToClass(m, clazz) - } - - final def newPackage(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol = { - assert(name == nme.ROOT || isPackageClass, this) - newModule(name, pos, PackageFlags | newFlags) - } - - final def newThisSym(name: TermName = nme.this_, pos: Position = NoPosition): TermSymbol = - newTermSymbol(name, pos, SYNTHETIC) - - final def newImport(pos: Position): TermSymbol = - newTermSymbol(nme.IMPORT, pos) - - final def newModuleSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol = - newTermSymbol(name, pos, newFlags).asInstanceOf[ModuleSymbol] - - final def newModuleAndClassSymbol(name: Name, pos: Position, flags: FlagSet): (ModuleSymbol, ClassSymbol) = { - val m = newModuleSymbol(name, pos, flags | MODULE) - val c = newModuleClass(name.toTypeName, pos, m getFlag ModuleToClassFlags) - connectModuleToClass(m, c) - (m, c) - } - - final def newPackageSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol = - newTermSymbol(name, pos, newFlags).asInstanceOf[ModuleSymbol] - - final def newModuleClassSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleClassSymbol = - newClassSymbol(name, pos, newFlags).asInstanceOf[ModuleClassSymbol] - - final def newTypeSkolemSymbol(name: TypeName, origin: AnyRef, pos: Position = NoPosition, newFlags: Long = 0L): TypeSkolem = - createTypeSkolemSymbol(name, origin, pos, newFlags) - - /** @param pre type relative to which alternatives are seen. - * for instance: - * class C[T] { - * def m(x: T): T - * def m'(): T - * } - * val v: C[Int] - * - * Then v.m has symbol TermSymbol(flags = {OVERLOADED}, - * tpe = OverloadedType(C[Int], List(m, m'))) - * You recover the type of m doing a - * - * m.tpe.asSeenFrom(pre, C) (generally, owner of m, which is C here). - * - * or: - * - * pre.memberType(m) - */ - final def newOverloaded(pre: Type, alternatives: List[Symbol]): TermSymbol = ( - newTermSymbol(alternatives.head.name.toTermName, alternatives.head.pos, OVERLOADED) - setInfo OverloadedType(pre, alternatives) - ) - - final def newErrorValue(name: TermName): TermSymbol = - newTermSymbol(name, pos, SYNTHETIC | IS_ERROR) setInfo ErrorType - - /** Symbol of a type definition type T = ... - */ - final def newAliasType(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): AliasTypeSymbol = - createAliasTypeSymbol(name, pos, newFlags) - - /** Symbol of an abstract type type T >: ... <: ... - */ - final def newAbstractType(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): AbstractTypeSymbol = - createAbstractTypeSymbol(name, pos, DEFERRED | newFlags) - - /** Symbol of a type parameter - */ - final def newTypeParameter(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): TypeSymbol = - newAbstractType(name, pos, PARAM | newFlags) - -// is defined in SymbolCreations -// final def newTypeSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): TypeSymbol = -// (if ((newFlags & DEFERRED) != 0) new AbstractTypeSymbol(this, pos, name) -// else new AbstractTypeSymbol(this, pos, name)) setFlag newFlags - - /** Symbol of an existential type T forSome { ... } - */ - final def newExistential(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): TypeSymbol = - newAbstractType(name, pos, EXISTENTIAL | newFlags) - - /** Synthetic value parameters when parameter symbols are not available - */ - final def newSyntheticValueParamss(argtypess: List[List[Type]]): List[List[TermSymbol]] = { - var cnt = 0 - def freshName() = { cnt += 1; nme.syntheticParamName(cnt) } - mmap(argtypess)(tp => newValueParameter(freshName(), owner.pos.focus, SYNTHETIC) setInfo tp) - } - - def newSyntheticTypeParam(): TypeSymbol = newSyntheticTypeParam("T0", 0L) - def newSyntheticTypeParam(name: String, newFlags: Long): TypeSymbol = newTypeParameter(newTypeName(name), NoPosition, newFlags) setInfo TypeBounds.empty - def newSyntheticTypeParams(num: Int): List[TypeSymbol] = (0 until num).toList map (n => newSyntheticTypeParam("T" + n, 0L)) - - /** Create a new existential type skolem with this symbol its owner, - * based on the given symbol and origin. - */ - def newExistentialSkolem(basis: Symbol, origin: AnyRef): TypeSkolem = { - val skolem = newTypeSkolemSymbol(basis.name.toTypeName, origin, basis.pos, (basis.flags | EXISTENTIAL) & ~PARAM) - skolem setInfo (basis.info cloneInfo skolem) - } - - // flags set up to maintain TypeSkolem's invariant: origin.isInstanceOf[Symbol] == !hasFlag(EXISTENTIAL) - // CASEACCESSOR | SYNTHETIC used to single this symbol out in deskolemizeGADT - def newGADTSkolem(name: TypeName, origin: Symbol, info: Type): TypeSkolem = - newTypeSkolemSymbol(name, origin, origin.pos, origin.flags & ~(EXISTENTIAL | PARAM) | CASEACCESSOR | SYNTHETIC) setInfo info - - final def freshExistential(suffix: String): TypeSymbol = - newExistential(freshExistentialName(suffix), pos) - - /** Synthetic value parameters when parameter symbols are not available. - * Calling this method multiple times will re-use the same parameter names. - */ - final def newSyntheticValueParams(argtypes: List[Type]): List[TermSymbol] = - newSyntheticValueParamss(List(argtypes)).head - - /** Synthetic value parameter when parameter symbol is not available. - * Calling this method multiple times will re-use the same parameter name. - */ - final def newSyntheticValueParam(argtype: Type): Symbol = - newSyntheticValueParams(List(argtype)).head - - /** Type skolems are type parameters ''seen from the inside'' - * Assuming a polymorphic method m[T], its type is a PolyType which has a TypeParameter - * with name `T` in its typeParams list. While type checking the parameters, result type and - * body of the method, there's a local copy of `T` which is a TypeSkolem. - */ - final def newTypeSkolem: TypeSkolem = - owner.newTypeSkolemSymbol(name.toTypeName, this, pos, flags) - - final def newClass(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ClassSymbol = - newClassSymbol(name, pos, newFlags) - - /** A new class with its info set to a ClassInfoType with given scope and parents. */ - def newClassWithInfo(name: TypeName, parents: List[Type], scope: Scope, pos: Position = NoPosition, newFlags: Long = 0L): ClassSymbol = { - val clazz = newClass(name, pos, newFlags) - clazz setInfo ClassInfoType(parents, scope, clazz) - } - final def newErrorClass(name: TypeName): ClassSymbol = - newClassWithInfo(name, Nil, new ErrorScope(this), pos, SYNTHETIC | IS_ERROR) - - final def newModuleClass(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleClassSymbol = - newModuleClassSymbol(name, pos, newFlags | MODULE) - - final def newAnonymousFunctionClass(pos: Position = NoPosition, newFlags: Long = 0L): ClassSymbol = - newClassSymbol(tpnme.ANON_FUN_NAME, pos, FINAL | SYNTHETIC | newFlags) - - final def newAnonymousFunctionValue(pos: Position, newFlags: Long = 0L): TermSymbol = - newTermSymbol(nme.ANON_FUN_NAME, pos, SYNTHETIC | newFlags) setInfo NoType - - def newImplClass(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ClassSymbol = { - newClassSymbol(name, pos, newFlags | IMPLCLASS) - } - - /** Refinement types P { val x: String; type T <: Number } - * also have symbols, they are refinementClasses - */ - final def newRefinementClass(pos: Position): RefinementClassSymbol = - createRefinementClassSymbol(pos, 0L) - - /** Create a new getter for current symbol (which must be a field) - */ - final def newGetter: MethodSymbol = ( - owner.newMethod(nme.getterName(name.toTermName), NoPosition, getterFlags(flags)) - setPrivateWithin privateWithin - setInfo MethodType(Nil, tpe) - ) - - final def newErrorSymbol(name: Name): Symbol = name match { - case x: TypeName => newErrorClass(x) - case x: TermName => newErrorValue(x) - } - - @deprecated("Use the other signature", "2.10.0") - def newClass(pos: Position, name: TypeName): Symbol = newClass(name, pos) - @deprecated("Use the other signature", "2.10.0") - def newModuleClass(pos: Position, name: TypeName): Symbol = newModuleClass(name, pos) - @deprecated("Use the other signature", "2.10.0") - def newLabel(pos: Position, name: TermName): MethodSymbol = newLabel(name, pos) - @deprecated("Use the other signature", "2.10.0") - def newValue(pos: Position, name: TermName): TermSymbol = newTermSymbol(name, pos) - @deprecated("Use the other signature", "2.10.0") - def newAliasType(pos: Position, name: TypeName): Symbol = newAliasType(name, pos) - @deprecated("Use the other signature", "2.10.0") - def newAbstractType(pos: Position, name: TypeName): Symbol = newAbstractType(name, pos) - @deprecated("Use the other signature", "2.10.0") - def newExistential(pos: Position, name: TypeName): Symbol = newExistential(name, pos) - @deprecated("Use the other signature", "2.10.0") - def newMethod(pos: Position, name: TermName): MethodSymbol = newMethod(name, pos) - -// ----- locking and unlocking ------------------------------------------------------ - - // True if the symbol is unlocked. - // True if the symbol is locked but still below the allowed recursion depth. - // False otherwise - private[scala] def lockOK: Boolean = { - ((_rawflags & LOCKED) == 0L) || - ((settings.Yrecursion.value != 0) && - (recursionTable get this match { - case Some(n) => (n <= settings.Yrecursion.value) - case None => true })) - } - - // Lock a symbol, using the handler if the recursion depth becomes too great. - private[scala] def lock(handler: => Unit): Boolean = { - if ((_rawflags & LOCKED) != 0L) { - if (settings.Yrecursion.value != 0) { - recursionTable get this match { - case Some(n) => - if (n > settings.Yrecursion.value) { - handler - false - } else { - recursionTable += (this -> (n + 1)) - true - } - case None => - recursionTable += (this -> 1) - true - } - } else { handler; false } - } else { - _rawflags |= LOCKED - true -// activeLocks += 1 -// lockedSyms += this - } - } - - // Unlock a symbol - private[scala] def unlock() = { - if ((_rawflags & LOCKED) != 0L) { -// activeLocks -= 1 -// lockedSyms -= this - _rawflags &= ~LOCKED - if (settings.Yrecursion.value != 0) - recursionTable -= this - } - } - -// ----- tests ---------------------------------------------------------------------- - - def isAliasType = false - def isAbstractType = false - def isSkolem = false - - /** A Type, but not a Class. */ - def isNonClassType = false - - /** The bottom classes are Nothing and Null, found in Definitions. */ - def isBottomClass = false - def isSpecialized = this hasFlag SPECIALIZED - - /** These are all tests for varieties of ClassSymbol, which has these subclasses: - * - ModuleClassSymbol - * - RefinementClassSymbol - * - PackageClassSymbol (extends ModuleClassSymbol) - */ - def isAbstractClass = false - def isAnonOrRefinementClass = false - def isAnonymousClass = false - def isCaseClass = false - def isConcreteClass = false - def isImplClass = false // the implementation class of a trait - def isJavaInterface = false - def isModuleClass = false - def isNumericValueClass = false - def isPrimitiveValueClass = false - def isRefinementClass = false - override def isTrait = false - - /** Qualities of Types, always false for TermSymbols. - */ - def isContravariant = false - def isCovariant = false - def isExistentialQuantified = false - def isExistentialSkolem = false - def isExistentiallyBound = false - def isGADTSkolem = false - def isTypeParameter = false - def isTypeParameterOrSkolem = false - def isTypeSkolem = false - def isTypeMacro = false - - /** Qualities of Terms, always false for TypeSymbols. - */ - def isAccessor = false - def isBridge = false - def isCapturedVariable = false - def isClassConstructor = false - def isConstructor = false - def isEarlyInitialized = false - def isGetter = false - def isLocalDummy = false - def isMixinConstructor = false - def isOverloaded = false - def isSetter = false - def isSetterParameter = false - def isValue = false - def isValueParameter = false - def isVariable = false - override def hasDefault = false - def isTermMacro = false - - /** Qualities of MethodSymbols, always false for TypeSymbols - * and other TermSymbols. - */ - def isCaseAccessorMethod = false - def isLiftedMethod = false - def isSourceMethod = false - def isVarargsMethod = false - override def isLabel = false - - /** Package/package object tests */ - def isPackageClass = false - def isPackageObject = false - def isPackageObjectClass = false - def isPackageObjectOrClass = isPackageObject || isPackageObjectClass - def isModuleOrModuleClass = isModule || isModuleClass - - /** Overridden in custom objects in Definitions */ - def isRoot = false - def isRootPackage = false - def isRootSymbol = false // RootPackage and RootClass. TODO: also NoSymbol. - def isEmptyPackage = false - def isEmptyPackageClass = false - - /** Is this symbol an effective root for fullname string? - */ - def isEffectiveRoot = false - - /** For RootClass, this is EmptyPackageClass. For all other symbols, - * the symbol itself. - */ - def ownerOfNewSymbols = this - - final def isLazyAccessor = isLazy && lazyAccessor != NoSymbol - final def isOverridableMember = !(isClass || isEffectivelyFinal) && (this ne NoSymbol) && owner.isClass - - /** Does this symbol denote a wrapper created by the repl? */ - final def isInterpreterWrapper = ( - (this hasFlag MODULE) - && owner.isPackageClass - && nme.isReplWrapperName(name) - ) - @inline final def getFlag(mask: Long): Long = flags & mask - /** Does symbol have ANY flag in `mask` set? */ - @inline final def hasFlag(mask: Long): Boolean = (flags & mask) != 0 - /** Does symbol have ALL the flags in `mask` set? */ - @inline final def hasAllFlags(mask: Long): Boolean = (flags & mask) == mask - - def setFlag(mask: Long): this.type = { _rawflags |= mask ; this } - def resetFlag(mask: Long): this.type = { _rawflags &= ~mask ; this } - def resetFlags() { rawflags &= TopLevelCreationFlags } - - /** Default implementation calls the generic string function, which - * will print overloaded flags as <flag1/flag2/flag3>. Subclasses - * of Symbol refine. - */ - override def resolveOverloadedFlag(flag: Long): String = Flags.flagToString(flag) - - /** Set the symbol's flags to the given value, asserting - * that the previous value was 0. - */ - def initFlags(mask: Long): this.type = { - assert(rawflags == 0L, symbolCreationString) - _rawflags = mask - this - } - - final def flags: Long = { - val fs = _rawflags & phase.flagMask - (fs | ((fs & LateFlags) >>> LateShift)) & ~(fs >>> AntiShift) - } - def flags_=(fs: Long) = _rawflags = fs - def rawflags_=(x: Long) { _rawflags = x } - - final def hasGetter = isTerm && nme.isLocalName(name) - - final def isInitializedToDefault = !isType && hasAllFlags(DEFAULTINIT | ACCESSOR) - final def isStaticModule = isModule && isStatic && !isMethod - final def isThisSym = isTerm && owner.thisSym == this - final def isError = hasFlag(IS_ERROR) - final def isErroneous = isError || isInitialized && tpe.isErroneous - - def isHigherOrderTypeParameter = owner.isTypeParameterOrSkolem - - // class C extends D( { class E { ... } ... } ). Here, E is a class local to a constructor - def isClassLocalToConstructor = false - - final def isDerivedValueClass = - isClass && info.firstParent.typeSymbol == AnyValClass && !isPrimitiveValueClass - - final def isMethodWithExtension = - isMethod && owner.isDerivedValueClass && !isParamAccessor && !isConstructor && !hasFlag(SUPERACCESSOR) - - final def isAnonymousFunction = isSynthetic && (name containsName tpnme.ANON_FUN_NAME) - final def isDefinedInPackage = effectiveOwner.isPackageClass - final def needsFlatClasses = phase.flatClasses && rawowner != NoSymbol && !rawowner.isPackageClass - - /** change name by appending $$<fully-qualified-name-of-class `base`> - * Do the same for any accessed symbols or setters/getters. - * Implementation in TermSymbol. - */ - def expandName(base: Symbol) { } - - // In java.lang, Predef, or scala package/package object - def isInDefaultNamespace = UnqualifiedOwners(effectiveOwner) - - /** The owner, skipping package objects. - */ - def effectiveOwner = owner.skipPackageObject - - /** If this is a package object or its implementing class, its owner: otherwise this. - */ - def skipPackageObject: Symbol = this - - /** If this is a constructor, its owner: otherwise this. - */ - final def skipConstructor: Symbol = if (isConstructor) owner else this - - /** Conditions where we omit the prefix when printing a symbol, to avoid - * unpleasantries like Predef.String, $iw.$iw.Foo and <empty>.Bippy. - */ - final def isOmittablePrefix = /*!settings.debug.value &&*/ ( - UnqualifiedOwners(skipPackageObject) - || isEmptyPrefix - ) - def isEmptyPrefix = ( - isEffectiveRoot // has no prefix for real, <empty> or <root> - || isAnonOrRefinementClass // has uninteresting <anon> or <refinement> prefix - || nme.isReplWrapperName(name) // has ugly $iw. prefix (doesn't call isInterpreterWrapper due to nesting) - ) - def isFBounded = info match { - case TypeBounds(_, _) => info.baseTypeSeq exists (_ contains this) - case _ => false - } - - /** Is symbol a monomorphic type? - * assumption: if a type starts out as monomorphic, it will not acquire - * type parameters in later phases. - */ - final def isMonomorphicType = - isType && { - val info = originalInfo - info.isComplete && !info.isHigherKinded - } - - def isStrictFP = hasAnnotation(ScalaStrictFPAttr) || (enclClass hasAnnotation ScalaStrictFPAttr) - def isSerializable = ( - info.baseClasses.exists(p => p == SerializableClass || p == JavaSerializableClass) - || hasAnnotation(SerializableAttr) // last part can be removed, @serializable annotation is deprecated - ) - def hasBridgeAnnotation = hasAnnotation(BridgeClass) - def isDeprecated = hasAnnotation(DeprecatedAttr) - def deprecationMessage = getAnnotation(DeprecatedAttr) flatMap (_ stringArg 0) - def deprecationVersion = getAnnotation(DeprecatedAttr) flatMap (_ stringArg 1) - def deprecatedParamName = getAnnotation(DeprecatedNameAttr) flatMap (_ symbolArg 0) - - // !!! when annotation arguments are not literal strings, but any sort of - // assembly of strings, there is a fair chance they will turn up here not as - // Literal(const) but some arbitrary AST. However nothing in the compiler - // prevents someone from writing a @migration annotation with a calculated - // string. So this needs attention. For now the fact that migration is - // private[scala] ought to provide enough protection. - def hasMigrationAnnotation = hasAnnotation(MigrationAnnotationClass) - def migrationMessage = getAnnotation(MigrationAnnotationClass) flatMap { _.stringArg(0) } - def migrationVersion = getAnnotation(MigrationAnnotationClass) flatMap { _.stringArg(1) } - def elisionLevel = getAnnotation(ElidableMethodClass) flatMap { _.intArg(0) } - def implicitNotFoundMsg = getAnnotation(ImplicitNotFoundClass) flatMap { _.stringArg(0) } - - /** Is this symbol an accessor method for outer? */ - final def isOuterAccessor = { - hasFlag(STABLE | SYNTHETIC) && - originalName == nme.OUTER - } - - /** Is this symbol an accessor method for outer? */ - final def isOuterField = { - hasFlag(SYNTHETIC) && - originalName == nme.OUTER_LOCAL - } - - /** Does this symbol denote a stable value? */ - def isStable = false - - /** Does this symbol denote the primary constructor of its enclosing class? */ - final def isPrimaryConstructor = - isConstructor && owner.primaryConstructor == this - - /** Does this symbol denote an auxiliary constructor of its enclosing class? */ - final def isAuxiliaryConstructor = - isConstructor && !isPrimaryConstructor - - /** Is this symbol a synthetic apply or unapply method in a companion object of a case class? */ - final def isCaseApplyOrUnapply = - isMethod && isCase && isSynthetic - - /** Is this symbol a trait which needs an implementation class? */ - final def needsImplClass = ( - isTrait - && (!isInterface || hasFlag(lateINTERFACE)) - && !isImplClass - ) - - /** Is this a symbol which exists only in the implementation class, not in its trait? */ - final def isImplOnly = isPrivate || ( - (owner.isTrait || owner.isImplClass) && ( - hasAllFlags(LIFTED | MODULE | METHOD) - || isConstructor - || hasFlag(notPRIVATE | LIFTED) && !hasFlag(ACCESSOR | SUPERACCESSOR | MODULE) - ) - ) - final def isModuleVar = hasFlag(MODULEVAR) - - /** Is this symbol static (i.e. with no outer instance)? - * Q: When exactly is a sym marked as STATIC? - * A: If it's a member of a toplevel object, or of an object contained in a toplevel object, or any number of levels deep. - * http://groups.google.com/group/scala-internals/browse_thread/thread/d385bcd60b08faf6 - */ - def isStatic = (this hasFlag STATIC) || owner.isStaticOwner - - /** Is this symbol a static constructor? */ - final def isStaticConstructor: Boolean = - isStaticMember && isClassConstructor - - /** Is this symbol a static member of its class? (i.e. needs to be implemented as a Java static?) */ - final def isStaticMember: Boolean = - hasFlag(STATIC) || owner.isImplClass - - /** Does this symbol denote a class that defines static symbols? */ - final def isStaticOwner: Boolean = - isPackageClass || isModuleClass && isStatic - - def isTopLevelModule = hasFlag(MODULE) && owner.isPackageClass - - /** Is this symbol effectively final? I.e, it cannot be overridden */ - final def isEffectivelyFinal: Boolean = ( - (this hasFlag FINAL | PACKAGE) - || isModuleOrModuleClass && (owner.isPackageClass || !settings.overrideObjects.value) - || isTerm && ( - isPrivate - || isLocal - || owner.isClass && owner.isEffectivelyFinal - ) - ) - - /** Is this symbol locally defined? I.e. not accessed from outside `this` instance */ - final def isLocal: Boolean = owner.isTerm - - /** Is this symbol a constant? */ - final def isConstant: Boolean = isStable && isConstantType(tpe.resultType) - - /** Is this class nested in another class or module (not a package)? */ - def isNestedClass = false - - /** Is this class locally defined? - * A class is local, if - * - it is anonymous, or - * - its owner is a value - * - it is defined within a local class - */ - def isLocalClass = false - - def isStableClass = false - -/* code for fixing nested objects - override final def isModuleClass: Boolean = - super.isModuleClass && !isExpandedModuleClass -*/ - /** Is this class or type defined as a structural refinement type? - */ - final def isStructuralRefinement: Boolean = - (isClass || isType || isModule) && info.normalize/*.underlying*/.isStructuralRefinement - - /** Is this a term symbol only defined in a refinement (so that it needs - * to be accessed by reflection)? - */ - def isOnlyRefinementMember: Boolean = - isTerm && // type members are not affected - owner.isRefinementClass && // owner must be a refinement class - (owner.info decl name) == this && // symbol must be explicitly declared in the refinement (not synthesized from glb) - allOverriddenSymbols.isEmpty && // symbol must not override a symbol in a base class - !isConstant // symbol must not be a constant. Question: Can we exclude @inline methods as well? - - 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 - - /** A a member of class `base` is incomplete if - * (1) it is declared deferred or - * (2) it is abstract override and its super symbol in `base` is - * nonexistent or incomplete. - * - * @param base ... - * @return ... - */ - final def isIncompleteIn(base: Symbol): Boolean = - this.isDeferred || - (this hasFlag ABSOVERRIDE) && { - val supersym = superSymbol(base) - supersym == NoSymbol || supersym.isIncompleteIn(base) - } - - // Does not always work if the rawInfo is a SourcefileLoader, see comment - // in "def coreClassesFirst" in Global. - def exists = !owner.isPackageClass || { rawInfo.load(this); rawInfo != NoType } - - final def isInitialized: Boolean = - validTo != NoPeriod - - // [Eugene] todo. needs to be reviewed and [only then] rewritten without explicit returns - /** Determines whether this symbol can be loaded by subsequent reflective compilation */ - final def isLocatable: Boolean = { - if (this == NoSymbol) return false - if (isRoot || isRootPackage) return true - - if (!owner.isLocatable) return false - if (owner.isTerm) return false - if (isLocalDummy) return false - - if (isType && isNonClassType) return false - if (isRefinementClass) return false - return true - } - - // [Eugene] is it a good idea to add ``dealias'' to Symbol? - /** Expands type aliases */ - def dealias: Symbol = this - - /** The variance of this symbol as an integer */ - final def variance: Int = - if (isCovariant) 1 - else if (isContravariant) -1 - else 0 - - /** The sequence number of this parameter symbol among all type - * and value parameters of symbol's owner. -1 if symbol does not - * appear among the parameters of its owner. - */ - def paramPos: Int = { - def searchIn(tpe: Type, base: Int): Int = { - def searchList(params: List[Symbol], fallback: Type): Int = { - val idx = params indexOf this - if (idx >= 0) idx + base - else searchIn(fallback, base + params.length) - } - tpe match { - case PolyType(tparams, res) => searchList(tparams, res) - case MethodType(params, res) => searchList(params, res) - case _ => -1 - } - } - searchIn(owner.info, 0) - } - -// ------ owner attribute -------------------------------------------------------------- - - def owner: Symbol = rawowner - // TODO - don't allow the owner to be changed without checking invariants, at least - // when under some flag. Define per-phase invariants for owner/owned relationships, - // e.g. after flatten all classes are owned by package classes, there are lots and - // lots of these to be declared (or more realistically, discovered.) - def owner_=(owner: Symbol) { - // don't keep the original owner in presentation compiler runs - // (the map will grow indefinitely, and the only use case is the - // backend). - if (!forInteractive) { - if (originalOwner contains this) () - else originalOwner(this) = rawowner - } - assert(isCompilerUniverse, "owner_= is not thread-safe; cannot be run in reflexive code") - if (traceSymbolActivity) - traceSymbols.recordNewSymbolOwner(this, owner) - _rawowner = owner - } - - def ownerChain: List[Symbol] = this :: owner.ownerChain - def originalOwnerChain: List[Symbol] = this :: originalOwner.getOrElse(this, rawowner).originalOwnerChain - - // Non-classes skip self and return rest of owner chain; overridden in ClassSymbol. - def enclClassChain: List[Symbol] = owner.enclClassChain - - def ownersIterator: Iterator[Symbol] = new Iterator[Symbol] { - private var current = Symbol.this - def hasNext = current ne NoSymbol - def next = { val r = current; current = current.owner; r } - } - - /** Same as `ownerChain contains sym` but more efficient, and - * with a twist for refinement classes (see RefinementClassSymbol.) - */ - def hasTransOwner(sym: Symbol): Boolean = { - var o = this - while ((o ne sym) && (o ne NoSymbol)) o = o.owner - (o eq sym) - } - -// ------ name attribute -------------------------------------------------------------- - - /** If this symbol has an expanded name, its original name, otherwise its name itself. - * @see expandName - */ - def originalName: Name = nme.originalName(name) - - /** The name of the symbol before decoding, e.g. `\$eq\$eq` instead of `==`. - */ - def encodedName: String = name.toString - - /** The decoded name of the symbol, e.g. `==` instead of `\$eq\$eq`. - */ - def decodedName: String = nme.dropLocalSuffix(name).decode - - private def addModuleSuffix(n: Name): Name = - if (needsModuleSuffix) n append nme.MODULE_SUFFIX_STRING else n - - def moduleSuffix: String = ( - if (needsModuleSuffix) nme.MODULE_SUFFIX_STRING - else "" - ) - /** Whether this symbol needs nme.MODULE_SUFFIX_STRING (aka $) appended on the java platform. - */ - def needsModuleSuffix = ( - hasModuleFlag - && !isMethod - && !isImplClass - && !isJavaDefined - ) - /** These should be moved somewhere like JavaPlatform. - */ - def javaSimpleName: Name = addModuleSuffix(nme.dropLocalSuffix(simpleName)) - def javaBinaryName: Name = addModuleSuffix(fullNameInternal('/')) - def javaClassName: String = addModuleSuffix(fullNameInternal('.')).toString - - /** The encoded full path name of this symbol, where outer names and inner names - * are separated by `separator` characters. - * Never translates expansions of operators back to operator symbol. - * Never adds id. - * Drops package objects. - */ - final def fullName(separator: Char): String = fullNameAsName(separator).toString - - /** Doesn't drop package objects, for those situations (e.g. classloading) - * where the true path is needed. - */ - private def fullNameInternal(separator: Char): Name = ( - if (isRoot || isRootPackage || this == NoSymbol) name - else if (owner.isEffectiveRoot) name - else effectiveOwner.enclClass.fullNameAsName(separator) append separator append name - ) - - def fullNameAsName(separator: Char): Name = nme.dropLocalSuffix(fullNameInternal(separator)) - - /** The encoded full path name of this symbol, where outer names and inner names - * are separated by periods. - */ - final def fullName: String = fullName('.') - - /** - * Symbol creation implementations. - */ - - protected def createAbstractTypeSymbol(name: TypeName, pos: Position, newFlags: Long): AbstractTypeSymbol = - new AbstractTypeSymbol(this, pos, name) initFlags newFlags - - protected def createAliasTypeSymbol(name: TypeName, pos: Position, newFlags: Long): AliasTypeSymbol = - new AliasTypeSymbol(this, pos, name) initFlags newFlags - - protected def createTypeSkolemSymbol(name: TypeName, origin: AnyRef, pos: Position, newFlags: Long): TypeSkolem = - new TypeSkolem(this, pos, name, origin) initFlags newFlags - - protected def createClassSymbol(name: TypeName, pos: Position, newFlags: Long): ClassSymbol = - new ClassSymbol(this, pos, name) initFlags newFlags - - protected def createModuleClassSymbol(name: TypeName, pos: Position, newFlags: Long): ModuleClassSymbol = - new ModuleClassSymbol(this, pos, name) initFlags newFlags - - protected def createPackageClassSymbol(name: TypeName, pos: Position, newFlags: Long): PackageClassSymbol = - new PackageClassSymbol(this, pos, name) initFlags newFlags - - protected def createRefinementClassSymbol(pos: Position, newFlags: Long): RefinementClassSymbol = - new RefinementClassSymbol(this, pos) initFlags newFlags - - protected def createPackageObjectClassSymbol(pos: Position, newFlags: Long): PackageObjectClassSymbol = - new PackageObjectClassSymbol(this, pos) initFlags newFlags - - protected def createImplClassSymbol(name: TypeName, pos: Position, newFlags: Long): ClassSymbol = - new ClassSymbol(this, pos, name) with ImplClassSymbol initFlags newFlags - - protected def createTermSymbol(name: TermName, pos: Position, newFlags: Long): TermSymbol = - new TermSymbol(this, pos, name) initFlags newFlags - - protected def createMethodSymbol(name: TermName, pos: Position, newFlags: Long): MethodSymbol = - new MethodSymbol(this, pos, name) initFlags newFlags - - protected def createModuleSymbol(name: TermName, pos: Position, newFlags: Long): ModuleSymbol = - new ModuleSymbol(this, pos, name) initFlags newFlags - - protected def createPackageSymbol(name: TermName, pos: Position, newFlags: Long): ModuleSymbol = - new ModuleSymbol(this, pos, name) initFlags newFlags - - protected def createValueParameterSymbol(name: TermName, pos: Position, newFlags: Long): TermSymbol = - new TermSymbol(this, pos, name) initFlags newFlags - - protected def createValueMemberSymbol(name: TermName, pos: Position, newFlags: Long): TermSymbol = - new TermSymbol(this, pos, name) initFlags newFlags - - final def newTermSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): TermSymbol = { - if ((newFlags & METHOD) != 0) - createMethodSymbol(name, pos, newFlags) - else if ((newFlags & PACKAGE) != 0) - createPackageSymbol(name, pos, newFlags | PackageFlags) - else if ((newFlags & MODULE) != 0) - createModuleSymbol(name, pos, newFlags) - else if ((newFlags & PARAM) != 0) - createValueParameterSymbol(name, pos, newFlags) - else - createValueMemberSymbol(name, pos, newFlags) - } - - final def newClassSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ClassSymbol = { - if (name == tpnme.REFINE_CLASS_NAME) - createRefinementClassSymbol(pos, newFlags) - else if ((newFlags & PACKAGE) != 0) - createPackageClassSymbol(name, pos, newFlags | PackageFlags) - else if (name == tpnme.PACKAGE) - createPackageObjectClassSymbol(pos, newFlags) - else if ((newFlags & MODULE) != 0) - createModuleClassSymbol(name, pos, newFlags) - else if ((newFlags & IMPLCLASS) != 0) - createImplClassSymbol(name, pos, newFlags) - else - createClassSymbol(name, pos, newFlags) - } - - final def newNonClassSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): TypeSymbol = { - if ((newFlags & DEFERRED) != 0) - createAbstractTypeSymbol(name, pos, newFlags) - else - createAliasTypeSymbol(name, pos, newFlags) - } - - def newTypeSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): TypeSymbol = - newNonClassSymbol(name, pos, newFlags) - - /** The class or term up to which this symbol is accessible, - * or RootClass if it is public. As java protected statics are - * otherwise completely inaccessible in scala, they are treated - * as public. - */ - def accessBoundary(base: Symbol): Symbol = { - if (hasFlag(PRIVATE) || isLocal) owner - else if (hasAllFlags(PROTECTED | STATIC | JAVA)) enclosingRootClass - else if (hasAccessBoundary && !phase.erasedTypes) privateWithin - else if (hasFlag(PROTECTED)) base - else enclosingRootClass - } - - def isLessAccessibleThan(other: Symbol): Boolean = { - val tb = this.accessBoundary(owner) - val ob1 = other.accessBoundary(owner) - val ob2 = ob1.linkedClassOfClass - var o = tb - while (o != NoSymbol && o != ob1 && o != ob2) { - o = o.owner - } - o != NoSymbol && o != tb - } - - /** See comment in HasFlags for how privateWithin combines with flags. - */ - 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) - -// ------ info and type ------------------------------------------------------------------- - - private[Symbols] var infos: TypeHistory = null - def originalInfo = { - if (infos eq null) null - else { - var is = infos - while (is.prev ne null) { is = is.prev } - is.info - } - } - - /** Get type. The type of a symbol is: - * for a type symbol, the type corresponding to the symbol itself, - * @M you should use tpeHK for a type symbol with type parameters if - * the kind of the type need not be *, as tpe introduces dummy arguments - * to generate a type of kind * - * for a term symbol, its usual type. - * See the tpe/tpeHK overrides in TypeSymbol for more. - */ - def tpe: Type = info - def tpeHK: Type = tpe - - /** Get type info associated with symbol at current phase, after - * ensuring that symbol is initialized (i.e. type is completed). - */ - def info: Type = try { - var cnt = 0 - while (validTo == NoPeriod) { - //if (settings.debug.value) System.out.println("completing " + this);//DEBUG - assert(infos ne null, this.name) - assert(infos.prev eq null, this.name) - val tp = infos.info - //if (settings.debug.value) System.out.println("completing " + this.rawname + tp.getClass());//debug - - if ((_rawflags & LOCKED) != 0L) { // rolled out once for performance - lock { - setInfo(ErrorType) - throw CyclicReference(this, tp) - } - } else { - _rawflags |= LOCKED -// activeLocks += 1 - // lockedSyms += this - } - val current = phase - try { - phase = phaseOf(infos.validFrom) - tp.complete(this) - } finally { - unlock() - phase = current - } - cnt += 1 - // allow for two completions: - // one: sourceCompleter to LazyType, two: LazyType to completed type - if (cnt == 3) abort("no progress in completing " + this + ":" + tp) - } - rawInfo - } - catch { - case ex: CyclicReference => - debugwarn("... hit cycle trying to complete " + this.fullLocationString) - throw ex - } - - def info_=(info: Type) { - assert(info ne null) - infos = TypeHistory(currentPeriod, info, null) - unlock() - _validTo = if (info.isComplete) currentPeriod else NoPeriod - } - - /** Set initial info. */ - 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]): this.type = - if (syms0.isEmpty) this - else modifyInfo(_.substSym(syms0, syms1)) - - def setInfoOwnerAdjusted(info: Type): this.type = setInfo(info atOwner this) - - /** Set the info and enter this symbol into the owner's scope. */ - def setInfoAndEnter(info: Type): this.type = { - setInfo(info) - owner.info.decls enter this - this - } - - /** Set new info valid from start of this phase. */ - def updateInfo(info: Type): Symbol = { - val pid = phaseId(infos.validFrom) - assert(pid <= phase.id, (pid, phase.id)) - if (pid == phase.id) infos = infos.prev - infos = TypeHistory(currentPeriod, info, infos) - _validTo = if (info.isComplete) currentPeriod else NoPeriod - this - } - - def hasRawInfo: Boolean = infos ne null - def hasCompleteInfo = hasRawInfo && rawInfo.isComplete - - /** Return info without checking for initialization or completing */ - def rawInfo: Type = { - var infos = this.infos - assert(infos != null) - val curPeriod = currentPeriod - val curPid = phaseId(curPeriod) - - if (validTo != NoPeriod) { - // skip any infos that concern later phases - while (curPid < phaseId(infos.validFrom) && infos.prev != null) - infos = infos.prev - - if (validTo < curPeriod) { - // adapt any infos that come from previous runs - val current = phase - try { - infos = adaptInfos(infos) - - //assert(runId(validTo) == currentRunId, name) - //assert(runId(infos.validFrom) == currentRunId, name) - - if (validTo < curPeriod) { - var itr = infoTransformers.nextFrom(phaseId(validTo)) - infoTransformers = itr; // caching optimization - while (itr.pid != NoPhase.id && itr.pid < current.id) { - phase = phaseWithId(itr.pid) - val info1 = itr.transform(this, infos.info) - if (info1 ne infos.info) { - infos = TypeHistory(currentPeriod + 1, info1, infos) - this.infos = infos - } - _validTo = currentPeriod + 1 // to enable reads from same symbol during info-transform - itr = itr.next - } - _validTo = if (itr.pid == NoPhase.id) curPeriod - else period(currentRunId, itr.pid) - } - } finally { - phase = current - } - } - } - infos.info - } - - // adapt to new run in fsc. - private def adaptInfos(infos: TypeHistory): TypeHistory = { - assert(isCompilerUniverse) - if (infos == null || runId(infos.validFrom) == currentRunId) { - infos - } else { - val prev1 = adaptInfos(infos.prev) - if (prev1 ne infos.prev) prev1 - else { - val pid = phaseId(infos.validFrom) - - _validTo = period(currentRunId, pid) - phase = phaseWithId(pid) - - val info1 = ( - if (isPackageClass) infos.info - else adaptToNewRunMap(infos.info) - ) - if (info1 eq infos.info) { - infos.validFrom = validTo - infos - } else { - this.infos = TypeHistory(validTo, info1, prev1) - this.infos - } - } - } - } - - /** Initialize the symbol */ - final def initialize: this.type = { - if (!isInitialized) info - this - } - - /** Was symbol's type updated during given phase? */ - final def isUpdatedAt(pid: Phase#Id): Boolean = { - assert(isCompilerUniverse) - var infos = this.infos - while ((infos ne null) && phaseId(infos.validFrom) != pid + 1) infos = infos.prev - infos ne null - } - - /** Was symbol's type updated during given phase? */ - final def hasTypeAt(pid: Phase#Id): Boolean = { - assert(isCompilerUniverse) - var infos = this.infos - while ((infos ne null) && phaseId(infos.validFrom) > pid) infos = infos.prev - infos ne null - } - - /** Modify term symbol's type so that a raw type C is converted to an existential C[_] - * - * This is done in checkAccessible and overriding checks in refchecks - * We can't do this on class loading because it would result in infinite cycles. - */ - final def cookJavaRawInfo() { - if (hasFlag(TRIEDCOOKING)) return else setFlag(TRIEDCOOKING) // only try once... - val oldInfo = info - doCookJavaRawInfo() - } - - protected def doCookJavaRawInfo(): Unit - - /** The type constructor of a symbol is: - * For a type symbol, the type corresponding to the symbol itself, - * excluding parameters. - * Not applicable for term symbols. - */ - def typeConstructor: Type = - abort("typeConstructor inapplicable for " + this) - - /** The logic approximately boils down to finding the most recent phase - * which immediately follows any of parser, namer, typer, or erasure. - * In effect that means this will return one of: - * - * - packageobjects (follows namer) - * - superaccessors (follows typer) - * - lazyvals (follows erasure) - * - null - */ - private def unsafeTypeParamPhase = { - var ph = phase - while (ph.prev.keepsTypeParams) - ph = ph.prev - - ph - } - /** The type parameters of this symbol, without ensuring type completion. - * assumption: if a type starts out as monomorphic, it will not acquire - * type parameters later. - */ - def unsafeTypeParams: List[Symbol] = - if (isMonomorphicType) Nil - else atPhase(unsafeTypeParamPhase)(rawInfo.typeParams) - - /** The type parameters of this symbol. - * assumption: if a type starts out as monomorphic, it will not acquire - * type parameters later. - */ - def typeParams: List[Symbol] = - if (isMonomorphicType) Nil - else { - // analogously to the "info" getter, here we allow for two completions: - // one: sourceCompleter to LazyType, two: LazyType to completed type - if (validTo == NoPeriod) - atPhase(phaseOf(infos.validFrom))(rawInfo load this) - if (validTo == NoPeriod) - atPhase(phaseOf(infos.validFrom))(rawInfo load this) - - rawInfo.typeParams - } - - /** The value parameter sections of this symbol. - */ - def paramss: List[List[Symbol]] = info.paramss - def hasParamWhich(cond: Symbol => Boolean) = mexists(paramss)(cond) - - /** The least proper supertype of a class; includes all parent types - * and refinement where needed. You need to compute that in a situation like this: - * { - * class C extends P { ... } - * new C - * } - */ - def classBound: Type = { - val tp = refinedType(info.parents, owner) - val thistp = tp.typeSymbol.thisType - val oldsymbuf = new ListBuffer[Symbol] - val newsymbuf = new ListBuffer[Symbol] - for (sym <- info.decls) { - // todo: what about public references to private symbols? - if (sym.isPublic && !sym.isConstructor) { - oldsymbuf += sym - newsymbuf += ( - if (sym.isClass) - tp.typeSymbol.newAbstractType(sym.name.toTypeName, sym.pos).setInfo(sym.existentialBound) - else - sym.cloneSymbol(tp.typeSymbol)) - } - } - val oldsyms = oldsymbuf.toList - val newsyms = newsymbuf.toList - for (sym <- newsyms) { - addMember(thistp, tp, sym modifyInfo (_ substThisAndSym(this, thistp, oldsyms, newsyms))) - } - tp - } - - /** If we quantify existentially over this symbol, - * the bound of the type variable that stands for it - * pre: symbol is a term, a class, or an abstract type (no alias type allowed) - */ - def existentialBound: Type - - /** Reset symbol to initial state - */ - def reset(completer: Type): this.type = { - resetFlags() - infos = null - _validTo = NoPeriod - //limit = NoPhase.id - setInfo(completer) - } - - /** - * Adds the interface scala.Serializable to the parents of a ClassInfoType. - * Note that the tree also has to be updated accordingly. - */ - def makeSerializable() { - info match { - case ci @ ClassInfoType(_, _, _) => - updateInfo(ci.copy(parents = ci.parents :+ SerializableClass.tpe)) - case i => - abort("Only ClassInfoTypes can be made serializable: "+ i) - } - } - -// ----- setters implemented in selected subclasses ------------------------------------- - - def typeOfThis_=(tp: Type) { throw new UnsupportedOperationException("typeOfThis_= inapplicable for " + this) } - def sourceModule_=(sym: Symbol) { throw new UnsupportedOperationException("sourceModule_= inapplicable for " + this) } - def addChild(sym: Symbol) { throw new UnsupportedOperationException("addChild inapplicable for " + this) } - -// ----- annotations ------------------------------------------------------------ - - // null is a marker that they still need to be obtained. - private[this] var _annotations: List[AnnotationInfo] = Nil - - 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] = - _annotations - - def setAnnotations(annots: List[AnnotationInfo]): this.type = { - _annotations = annots - this - } - - def withAnnotations(annots: List[AnnotationInfo]): this.type = - setAnnotations(annots ::: annotations) - - def withoutAnnotations: this.type = - setAnnotations(Nil) - - def filterAnnotations(p: AnnotationInfo => Boolean): this.type = - setAnnotations(annotations filter p) - - def addAnnotation(annot: AnnotationInfo): this.type = - setAnnotations(annot :: annotations) - - // Convenience for the overwhelmingly common case - def addAnnotation(sym: Symbol, args: Tree*): this.type = - addAnnotation(AnnotationInfo(sym.tpe, args.toList, Nil)) - -// ------ comparisons ---------------------------------------------------------------- - - /** A total ordering between symbols that refines the class - * inheritance graph (i.e. subclass.isLess(superclass) always holds). - * the ordering is given by: (_.isType, -_.baseTypeSeq.length) for type symbols, followed by `id`. - */ - final def isLess(that: Symbol): Boolean = { - def baseTypeSeqLength(sym: Symbol) = - if (sym.isAbstractType) 1 + sym.info.bounds.hi.baseTypeSeq.length - else sym.info.baseTypeSeq.length - if (this.isType) - (that.isType && - { val diff = baseTypeSeqLength(this) - baseTypeSeqLength(that) - diff > 0 || diff == 0 && this.id < that.id }) - else - that.isType || this.id < that.id - } - - /** A partial ordering between symbols. - * (this isNestedIn that) holds iff this symbol is defined within - * a class or method defining that symbol - */ - final def isNestedIn(that: Symbol): Boolean = - owner == that || owner != NoSymbol && (owner isNestedIn that) - - /** Is this class symbol a subclass of that symbol, - * and is this class symbol also different from Null or Nothing? */ - def isNonBottomSubClass(that: Symbol): Boolean = false - - /** Overridden in NullClass and NothingClass for custom behavior. - */ - def isSubClass(that: Symbol) = isNonBottomSubClass(that) - - final def isNumericSubClass(that: Symbol): Boolean = - definitions.isNumericSubClass(this, that) - - final def isWeakSubClass(that: Symbol) = - isSubClass(that) || isNumericSubClass(that) - -// ------ overloaded alternatives ------------------------------------------------------ - - def alternatives: List[Symbol] = - if (isOverloaded) info.asInstanceOf[OverloadedType].alternatives - else List(this) - - def filter(cond: Symbol => Boolean): Symbol = - if (isOverloaded) { - val alts = alternatives - val alts1 = alts filter cond - if (alts1 eq alts) this - else if (alts1.isEmpty) NoSymbol - else if (alts1.tail.isEmpty) alts1.head - else owner.newOverloaded(info.prefix, alts1) - } - else if (cond(this)) this - else NoSymbol - - def suchThat(cond: Symbol => Boolean): Symbol = { - val result = filter(cond) - assert(!result.isOverloaded, result.alternatives) - result - } - - @inline final def map(f: Symbol => Symbol): Symbol = if (this eq NoSymbol) this else f(this) - -// ------ cloneing ------------------------------------------------------------------- - - /** A clone of this symbol. */ - final def cloneSymbol: TypeOfClonedSymbol = - cloneSymbol(owner) - - /** A clone of this symbol, but with given owner. */ - final def cloneSymbol(newOwner: Symbol): TypeOfClonedSymbol = - cloneSymbol(newOwner, _rawflags) - final def cloneSymbol(newOwner: Symbol, newFlags: Long): TypeOfClonedSymbol = - cloneSymbol(newOwner, newFlags, null) - final def cloneSymbol(newOwner: Symbol, newFlags: Long, newName: Name): TypeOfClonedSymbol = { - val clone = cloneSymbolImpl(newOwner, newFlags) - ( clone - setPrivateWithin privateWithin - setInfo (this.info cloneInfo clone) - setAnnotations this.annotations - ) - if (clone.thisSym != clone) - clone.typeOfThis = (clone.typeOfThis cloneInfo clone) - - if (newName ne null) - clone setName asNameType(newName) - - clone - } - - /** Internal method to clone a symbol's implementation with the given flags and no info. */ - def cloneSymbolImpl(owner: Symbol, newFlags: Long): TypeOfClonedSymbol - -// ------ access to related symbols -------------------------------------------------- - - /** The next enclosing class. */ - def enclClass: Symbol = if (isClass) this else owner.enclClass - - /** The next enclosing method. */ - def enclMethod: Symbol = if (isSourceMethod) this else owner.enclMethod - - /** The primary constructor of a class. */ - def primaryConstructor: Symbol = NoSymbol - - /** The self symbol (a TermSymbol) of a class with explicit self type, or else the - * symbol itself (a TypeSymbol). - * - * WARNING: you're probably better off using typeOfThis, as it's more uniform across classes with and without self variables. - * - * Example by Paul: - * scala> trait Foo1 { } - * scala> trait Foo2 { self => } - * scala> intp("Foo1").thisSym - * res0: $r.intp.global.Symbol = trait Foo1 - * - * scala> intp("Foo2").thisSym - * res1: $r.intp.global.Symbol = value self - * - * Martin says: The reason `thisSym' is `this' is so that thisType can be this.thisSym.tpe. - * It's a trick to shave some cycles off. - * - * Morale: DO: if (clazz.typeOfThis.typeConstructor ne clazz.typeConstructor) ... - * DON'T: if (clazz.thisSym ne clazz) ... - * - */ - def thisSym: Symbol = this - - /** The type of `this` in a class, or else the type of the symbol itself. */ - def typeOfThis = thisSym.tpe - - /** If symbol is a class, the type <code>this.type</code> in this class, - * otherwise <code>NoPrefix</code>. - * We always have: thisType <:< typeOfThis - */ - def thisType: Type = NoPrefix - - /** For a case class, the symbols of the accessor methods, one for each - * argument in the first parameter list of the primary constructor. - * The empty list for all other classes. - */ - final def caseFieldAccessors: List[Symbol] = - (info.decls filter (_.isCaseAccessorMethod)).toList - - final def constrParamAccessors: List[Symbol] = - info.decls.toList filter (sym => !sym.isMethod && sym.isParamAccessor) - - /** The symbol accessed by this accessor (getter or setter) function. */ - final def accessed: Symbol = accessed(owner.info) - - /** The symbol accessed by this accessor function, but with given owner type. */ - final def accessed(ownerTp: Type): Symbol = { - assert(hasAccessorFlag, this) - ownerTp decl nme.getterToLocal(getterName.toTermName) - } - - /** The module corresponding to this module class (note that this - * is not updated when a module is cloned), or NoSymbol if this is not a ModuleClass. - */ - def sourceModule: Symbol = NoSymbol - - /** The implementation class of a trait. If available it will be the - * symbol with the same owner, and the name of this symbol with $class - * appended to it. - */ - final def implClass: Symbol = owner.info.decl(tpnme.implClassName(name)) - - /** The class that is logically an outer class of given `clazz`. - * This is the enclosing class, except for classes defined locally to constructors, - * where it is the outer class of the enclosing class. - */ - final def outerClass: Symbol = - if (owner.isClass) owner - else if (isClassLocalToConstructor) owner.enclClass.outerClass - else owner.outerClass - - /** For a paramaccessor: a superclass paramaccessor for which this symbol - * is an alias, NoSymbol for all others. - */ - def alias: Symbol = NoSymbol - - /** For a lazy value, its lazy accessor. NoSymbol for all others. */ - def lazyAccessor: Symbol = NoSymbol - - /** If this is a lazy value, the lazy accessor; otherwise this symbol. */ - def lazyAccessorOrSelf: Symbol = if (isLazy) lazyAccessor else this - - /** If this is an accessor, the accessed symbol. Otherwise, this symbol. */ - def accessedOrSelf: Symbol = if (hasAccessorFlag) accessed else this - - /** For an outer accessor: The class from which the outer originates. - * For all other symbols: NoSymbol - */ - def outerSource: Symbol = NoSymbol - - /** The superclass of this class. */ - def superClass: Symbol = if (info.parents.isEmpty) NoSymbol else info.parents.head.typeSymbol - def parentSymbols: List[Symbol] = info.parents map (_.typeSymbol) - - /** The directly or indirectly inherited mixins of this class - * except for mixin classes inherited by the superclass. Mixin classes appear - * in linearization order. - */ - def mixinClasses: List[Symbol] = { - val sc = superClass - ancestors takeWhile (sc ne _) - } - - /** All directly or indirectly inherited classes. */ - def ancestors: List[Symbol] = info.baseClasses drop 1 - - @inline final def enclosingSuchThat(p: Symbol => Boolean): Symbol = { - var sym = this - while (sym != NoSymbol && !p(sym)) - sym = sym.owner - sym - } - - /** The package class containing this symbol, or NoSymbol if there - * is not one. - * TODO: formulate as enclosingSuchThat, after making sure - * we can start with current symbol rather than onwner. - * TODO: Also harmonize with enclClass, enclMethod etc. - */ - def enclosingPackageClass: Symbol = { - var sym = this.owner - while (sym != NoSymbol && !sym.isPackageClass) - sym = sym.owner - sym - } - - /** The package class containing this symbol, or NoSymbol if there - * is not one. */ - def enclosingRootClass: Symbol = enclosingSuchThat(_.isRoot) - - /** The package containing this symbol, or NoSymbol if there - * is not one. */ - def enclosingPackage: Symbol = enclosingPackageClass.companionModule - - /** Return the original enclosing method of this symbol. It should return - * the same thing as enclMethod when called before lambda lift, - * but it preserves the original nesting when called afterwards. - * - * @note This method is NOT available in the presentation compiler run. The - * originalOwner map is not populated for memory considerations (the symbol - * may hang on to lazy types and in turn to whole (outdated) compilation units. - */ - def originalEnclosingMethod: Symbol = { - assert(!forInteractive, "originalOwner is not kept in presentation compiler runs.") - if (isMethod) this - else { - val owner = originalOwner.getOrElse(this, rawowner) - if (isLocalDummy) owner.enclClass.primaryConstructor - else owner.originalEnclosingMethod - } - } - - /** The method or class which logically encloses the current symbol. - * If the symbol is defined in the initialization part of a template - * this is the template's primary constructor, otherwise it is - * the physically enclosing method or class. - * - * Example 1: - * - * def f() { val x = { def g() = ...; g() } } - * - * In this case the owner chain of `g` is `x`, followed by `f` and - * `g.logicallyEnclosingMember == f`. - * - * Example 2: - * - * class C { - * def <init> = { ... } - * val x = { def g() = ...; g() } } - * } - * - * In this case the owner chain of `g` is `x`, followed by `C` but - * g.logicallyEnclosingMember is the primary constructor symbol `<init>` - * (or, for traits: `$init`) of `C`. - * - */ - def logicallyEnclosingMember: Symbol = - if (isLocalDummy) enclClass.primaryConstructor - else if (isMethod || isClass) this - else owner.logicallyEnclosingMember - - /** Kept for source compatibility with 2.9. Scala IDE for Eclipse relies on this. */ - @deprecated("Use enclosingTopLevelClass", "2.10.0") - def toplevelClass: Symbol = enclosingTopLevelClass - - /** The top-level class containing this symbol. */ - def enclosingTopLevelClass: Symbol = - if (owner.isPackageClass) { - if (isClass) this else moduleClass - } else owner.enclosingTopLevelClass - - /** Is this symbol defined in the same scope and compilation unit as `that` symbol? */ - def isCoDefinedWith(that: Symbol) = { - import language.reflectiveCalls - (this.rawInfo ne NoType) && - (this.effectiveOwner == that.effectiveOwner) && { - !this.effectiveOwner.isPackageClass || - (this.sourceFile eq null) || - (that.sourceFile eq null) || - (this.sourceFile == that.sourceFile) || { - // recognize companion object in separate file and fail, else compilation - // appears to succeed but highly opaque errors come later: see bug #1286 - if (this.sourceFile.path != that.sourceFile.path) { - // The cheaper check can be wrong: do the expensive normalization - // before failing. - if (this.sourceFile.canonicalPath != that.sourceFile.canonicalPath) - throw InvalidCompanions(this, that) - } - - false - } - } - } - - /** The internal representation of classes and objects: - * - * class Foo is "the class" or sometimes "the plain class" - * object Foo is "the module" - * class Foo$ is "the module class" (invisible to the user: it implements object Foo) - * - * class Foo < - * ^ ^ (2) \ - * | | | \ - * | (5) | (3) - * | | | \ - * (1) v v \ - * object Foo (4)-> > class Foo$ - * - * (1) companionClass - * (2) companionModule - * (3) linkedClassOfClass - * (4) moduleClass - * (5) companionSymbol - */ - - /** For a module: the class with the same name in the same package. - * For all others: NoSymbol - * Note: does not work for classes owned by methods, see Namers.companionClassOf - * - * object Foo . companionClass --> class Foo - * - * !!! linkedClassOfClass depends on companionClass on the module class getting - * to the class. As presently implemented this potentially returns class for - * any symbol except NoSymbol. - */ - def companionClass: Symbol = flatOwnerInfo.decl(name.toTypeName).suchThat(_ isCoDefinedWith this) - - /** For a class: the module or case class factory with the same name in the same package. - * For all others: NoSymbol - * Note: does not work for modules owned by methods, see Namers.companionModuleOf - * - * class Foo . companionModule --> object Foo - */ - def companionModule: Symbol = NoSymbol - - /** For a module: its linked class - * For a plain class: its linked module or case factory. - * Note: does not work for modules owned by methods, see Namers.companionSymbolOf - * - * class Foo <-- companionSymbol --> object Foo - */ - def companionSymbol: Symbol = NoSymbol - - /** For a module class: its linked class - * For a plain class: the module class of its linked module. - * - * class Foo <-- linkedClassOfClass --> class Foo$ - */ - def linkedClassOfClass: Symbol = NoSymbol - - /** - * Returns the rawInfo of the owner. If the current phase has flat classes, - * it first applies all pending type maps to this symbol. - * - * assume this is the ModuleSymbol for B in the following definition: - * package p { class A { object B { val x = 1 } } } - * - * The owner after flatten is "package p" (see "def owner"). The flatten type map enters - * symbol B in the decls of p. So to find a linked symbol ("object B" or "class B") - * we need to apply flatten to B first. Fixes #2470. - */ - protected final def flatOwnerInfo: Type = { - if (needsFlatClasses) - info - owner.rawInfo - } - - /** If this symbol is an implementation class, its interface, otherwise the symbol itself - * The method follows two strategies to determine the interface. - * - during or after erasure, it takes the last parent of the implementation class - * (which is always the interface, by convention) - * - before erasure, it looks up the interface name in the scope of the owner of the class. - * This only works for implementation classes owned by other classes or traits. - * !!! Why? - */ - def toInterface: Symbol = this - - /** The module class corresponding to this module. - */ - def moduleClass: Symbol = NoSymbol - - /** The non-private symbol whose type matches the type of this symbol - * in in given class. - * - * @param ofclazz The class containing the symbol's definition - * @param site The base type from which member types are computed - */ - final def matchingSymbol(ofclazz: Symbol, site: Type): Symbol = - ofclazz.info.nonPrivateDecl(name).filter(sym => - !sym.isTerm || (site.memberType(this) matches site.memberType(sym))) - - /** The non-private member of `site` whose type and name match the type of this symbol. */ - final def matchingSymbol(site: Type, admit: Long = 0L): Symbol = - site.nonPrivateMemberAdmitting(name, admit).filter(sym => - !sym.isTerm || (site.memberType(this) matches site.memberType(sym))) - - /** The symbol, in class `ofclazz`, that is overridden by this symbol. - * - * @param ofclazz is a base class of this symbol's owner. - */ - final def overriddenSymbol(ofclazz: Symbol): Symbol = - if (isClassConstructor) NoSymbol else matchingSymbol(ofclazz, owner.thisType) - - /** The symbol overriding this symbol in given subclass `ofclazz`. - * - * @param ofclazz is a subclass of this symbol's owner - */ - final def overridingSymbol(ofclazz: Symbol): Symbol = - if (isClassConstructor) NoSymbol else matchingSymbol(ofclazz, ofclazz.thisType) - - /** Returns all symbols overriden by this symbol. */ - final def allOverriddenSymbols: List[Symbol] = - if (!owner.isClass) Nil - else owner.ancestors map overriddenSymbol filter (_ != NoSymbol) - - /** Equivalent to allOverriddenSymbols.nonEmpty, but more efficient. */ - // !!! When if ever will this answer differ from .isOverride? - // How/where is the OVERRIDE flag managed, as compared to how checks - // based on type membership will evaluate? - def isOverridingSymbol = owner.isClass && ( - owner.ancestors exists (cls => matchingSymbol(cls, owner.thisType) != NoSymbol) - ) - /** Equivalent to allOverriddenSymbols.head (or NoSymbol if no overrides) but more efficient. */ - def nextOverriddenSymbol: Symbol = { - if (owner.isClass) owner.ancestors foreach { base => - val sym = overriddenSymbol(base) - if (sym != NoSymbol) - return sym - } - NoSymbol - } - - /** Returns all symbols overridden by this symbol, plus all matching symbols - * defined in parents of the selftype. - */ - final def extendedOverriddenSymbols: List[Symbol] = - if (!owner.isClass) Nil - else owner.thisSym.ancestors map overriddenSymbol filter (_ != NoSymbol) - - /** The symbol accessed by a super in the definition of this symbol when - * seen from class `base`. This symbol is always concrete. - * pre: `this.owner` is in the base class sequence of `base`. - */ - final def superSymbol(base: Symbol): Symbol = { - var bcs = base.info.baseClasses.dropWhile(owner != _).tail - var sym: Symbol = NoSymbol - while (!bcs.isEmpty && sym == NoSymbol) { - if (!bcs.head.isImplClass) - sym = matchingSymbol(bcs.head, base.thisType).suchThat(!_.isDeferred) - bcs = bcs.tail - } - sym - } - - /** The getter of this value or setter definition in class `base`, or NoSymbol if - * none exists. - */ - final def getter(base: Symbol): Symbol = base.info.decl(getterName) filter (_.hasAccessorFlag) - - def getterName: TermName = ( - if (isSetter) nme.setterToGetter(name.toTermName) - else if (nme.isLocalName(name)) nme.localToGetter(name.toTermName) - else name.toTermName - ) - - /** The setter of this value or getter definition, or NoSymbol if none exists */ - final def setter(base: Symbol): Symbol = setter(base, false) - - final def setter(base: Symbol, hasExpandedName: Boolean): Symbol = { - var sname = nme.getterToSetter(nme.getterName(name.toTermName)) - if (hasExpandedName) sname = nme.expandedSetterName(sname, base) - base.info.decl(sname) filter (_.hasAccessorFlag) - } - - /** Return the accessor method of the first parameter of this class. - * or NoSymbol if it does not exist. - */ - def firstParamAccessor: Symbol = NoSymbol - - /** The case module corresponding to this case class - * @pre case class is a member of some other class or package - */ - final def caseModule: Symbol = { - var modname = name.toTermName - if (privateWithin.isClass && !privateWithin.isModuleClass && !hasFlag(EXPANDEDNAME)) - modname = nme.expandedName(modname, privateWithin) - initialize.owner.info.decl(modname).suchThat(_.isModule) - } - - /** If this symbol is a type parameter skolem (not an existential skolem!) - * its corresponding type parameter, otherwise this */ - def deSkolemize: Symbol = this - - /** If this symbol is an existential skolem the location (a Tree or null) - * where it was unpacked. Resulttype is AnyRef because trees are not visible here. */ - def unpackLocation: AnyRef = null - - /** Remove private modifier from symbol `sym`s definition. If `sym` is a - * is not a constructor nor a static module rename it by expanding its name to avoid name clashes - * @param base the fully qualified name of this class will be appended if name expansion is needed - */ - final def makeNotPrivate(base: Symbol) { - if (this.isPrivate) { - setFlag(notPRIVATE) - // Marking these methods final causes problems for proxies which use subclassing. If people - // write their code with no usage of final, we probably shouldn't introduce it ourselves - // unless we know it is safe. ... Unfortunately if they aren't marked final the inliner - // thinks it can't inline them. So once again marking lateFINAL, and in genjvm we no longer - // generate ACC_FINAL on "final" methods which are actually lateFINAL. - if (isMethod && !isDeferred) - setFlag(lateFINAL) - if (!isStaticModule && !isClassConstructor) { - expandName(base) - if (isModule) moduleClass.makeNotPrivate(base) - } - } - } - - /** Remove any access boundary and clear flags PROTECTED | PRIVATE. - */ - def makePublic = this setPrivateWithin NoSymbol resetFlag AccessFlags - - /** The first parameter to the first argument list of this method, - * or NoSymbol if inapplicable. - */ - def firstParam = info.params match { - case p :: _ => p - case _ => NoSymbol - } -/* code for fixing nested objects - def expandModuleClassName() { - name = newTypeName(name.toString + "$") - } - - def isExpandedModuleClass: Boolean = name(name.length - 1) == '$' -*/ - - /** Desire to re-use the field in ClassSymbol which stores the source - * file to also store the classfile, but without changing the behavior - * of sourceFile (which is expected at least in the IDE only to - * return actual source code.) So sourceFile has classfiles filtered out. - */ - private def sourceFileOnly(file: AbstractFileType): AbstractFileType = - if ((file eq null) || (file.path endsWith ".class")) null else file - - private def binaryFileOnly(file: AbstractFileType): AbstractFileType = - if ((file eq null) || !(file.path endsWith ".class")) null else file - - final def binaryFile: AbstractFileType = binaryFileOnly(associatedFile) - final def sourceFile: AbstractFileType = sourceFileOnly(associatedFile) - - /** Overridden in ModuleSymbols to delegate to the module class. */ - def associatedFile: AbstractFileType = enclosingTopLevelClass.associatedFile - def associatedFile_=(f: AbstractFileType) { abort("associatedFile_= inapplicable for " + this) } - - @deprecated("Use associatedFile_= instead", "2.10.0") - def sourceFile_=(f: AbstractFileType): Unit = associatedFile_=(f) - - /** If this is a sealed class, its known direct subclasses. - * Otherwise, the empty set. - */ - def children: Set[Symbol] = Set() - - /** Recursively assemble all children of this symbol. - */ - def sealedDescendants: Set[Symbol] = children.flatMap(_.sealedDescendants) + this - - @inline final def orElse(alt: => Symbol): Symbol = if (this ne NoSymbol) this else alt - @inline final def andAlso(f: Symbol => Unit): Symbol = { if (this ne NoSymbol) f(this) ; this } - -// ------ toString ------------------------------------------------------------------- - - /** A tag which (in the ideal case) uniquely identifies class symbols */ - final def tag: Int = fullName.## - - /** The simple name of this Symbol */ - final def simpleName: Name = name - - /** The String used to order otherwise identical sealed symbols. - * This uses data which is stable across runs and variable classpaths - * (the initial Name) before falling back on id, which varies depending - * on exactly when a symbol is loaded. - */ - final def sealedSortName: String = initName + "#" + id - - /** String representation of symbol's definition key word */ - final def keyString: String = - if (isJavaInterface) "interface" - else if (isTrait && !isImplClass) "trait" - else if (isClass) "class" - else if (isType && !isParameter) "type" - else if (isVariable) "var" - else if (isPackage) "package" - else if (isModule) "object" - else if (isSourceMethod) "def" - else if (isTerm && (!isParameter || isParamAccessor)) "val" - else "" - - private case class SymbolKind(accurate: String, sanitized: String, abbreviation: String) - private def symbolKind: SymbolKind = { - var kind = - if (isTermMacro) ("macro method", "macro method", "MAC") - else if (isInstanceOf[FreeTermSymbol]) ("free term", "free term", "FTE") - else if (isInstanceOf[FreeTypeSymbol]) ("free type", "free type", "FTY") - else if (isPackage) ("package", "package", "PK") - else if (isPackageClass) ("package class", "package", "PKC") - else if (isPackageObject) ("package object", "package", "PKO") - else if (isPackageObjectClass) ("package object class", "package", "PKOC") - else if (isAnonymousClass) ("anonymous class", "anonymous class", "AC") - else if (isRefinementClass) ("refinement class", "", "RC") - else if (isModule) ("module", "object", "MOD") - else if (isModuleClass) ("module class", "object", "MODC") - else if (isGetter) ("getter", if (isSourceMethod) "method" else "value", "GET") - else if (isSetter) ("setter", if (isSourceMethod) "method" else "value", "SET") - else if (isTerm && isLazy) ("lazy value", "lazy value", "LAZ") - else if (isVariable) ("field", "variable", "VAR") - else if (isImplClass) ("implementation class", "class", "IMPL") - else if (isTrait) ("trait", "trait", "TRT") - else if (isClass) ("class", "class", "CLS") - else if (isType) ("type", "type", "TPE") - else if (isClassConstructor && isPrimaryConstructor) ("primary constructor", "constructor", "PCTOR") - else if (isClassConstructor) ("constructor", "constructor", "CTOR") - else if (isSourceMethod) ("method", "method", "METH") - else if (isTerm) ("value", "value", "VAL") - else ("", "", "???") - if (isSkolem) kind = (kind._1, kind._2, kind._3 + "#SKO") - SymbolKind(kind._1, kind._2, kind._3) - } - - /** Accurate string representation of symbols' kind, suitable for developers. */ - final def accurateKindString: String = - symbolKind.accurate - - /** String representation of symbol's kind, suitable for the masses. */ - private def sanitizedKindString: String = - symbolKind.sanitized - - /** String representation of symbol's kind, suitable for the masses. */ - protected[scala] def abbreviatedKindString: String = - symbolKind.abbreviation - - final def kindString: String = - if (settings.debug.value) accurateKindString - else sanitizedKindString - - /** If the name of the symbol's owner should be used when you care about - * seeing an interesting name: in such cases this symbol is e.g. a method - * parameter with a synthetic name, a constructor named "this", an object - * "package", etc. The kind string, if non-empty, will be phrased relative - * to the name of the owner. - */ - def hasMeaninglessName = ( - isSetterParameter // x$1 - || isClassConstructor // this - || isRefinementClass // <refinement> - || (name == nme.PACKAGE) // package - ) - - /** String representation of symbol's simple name. - * If !settings.debug translates expansions of operators back to operator symbol. - * E.g. $eq => =. - * If settings.uniqid, adds id. - * If settings.Yshowsymkinds, adds abbreviated symbol kind. - */ - def nameString: String = ( - if (!settings.uniqid.value && !settings.Yshowsymkinds.value) "" + decodedName - else if (settings.uniqid.value && !settings.Yshowsymkinds.value) decodedName + "#" + id - else if (!settings.uniqid.value && settings.Yshowsymkinds.value) decodedName + "#" + abbreviatedKindString - else decodedName + "#" + id + "#" + abbreviatedKindString - ) - - def fullNameString: String = { - def recur(sym: Symbol): String = { - if (sym.isRootSymbol || sym == NoSymbol) sym.nameString - else if (sym.owner.isEffectiveRoot) sym.nameString - else recur(sym.effectiveOwner.enclClass) + "." + sym.nameString - } - - recur(this) - } - - /** If settings.uniqid is set, the symbol's id, else "" */ - final def idString = if (settings.uniqid.value) "#"+id else "" - - /** String representation, including symbol's kind e.g., "class Foo", "method Bar". - * If hasMeaninglessName is true, uses the owner's name to disambiguate identity. - */ - override def toString: String = compose( - kindString, - if (hasMeaninglessName) owner.decodedName + idString else nameString - ) - - /** String representation of location. - */ - def ownsString: String = { - val owns = effectiveOwner - if (owns.isClass && !owns.isEmptyPrefix) "" + owns else "" - } - - /** String representation of location, plus a preposition. Doesn't do much, - * for backward compatibility reasons. - */ - def locationString: String = ownsString match { - case "" => "" - case s => " in " + s - } - def fullLocationString: String = toString + locationString - def signatureString: String = if (hasRawInfo) infoString(rawInfo) else "<_>" - - /** String representation of symbol's definition following its name */ - final def infoString(tp: Type): String = { - def parents = ( - if (settings.debug.value) parentsString(tp.parents) - else briefParentsString(tp.parents) - ) - if (isType) typeParamsString(tp) + ( - if (isClass) " extends " + parents - else if (isAliasType) " = " + tp.resultType - else tp.resultType match { - case rt @ TypeBounds(_, _) => "" + rt - case rt => " <: " + rt - } - ) - else if (isModule) "" // avoid "object X of type X.type" - else tp match { - case PolyType(tparams, res) => typeParamsString(tp) + infoString(res) - case NullaryMethodType(res) => infoString(res) - case MethodType(params, res) => valueParamsString(tp) + infoString(res) - case _ => ": " + tp - } - } - - def infosString = infos.toString - def debugLocationString = fullLocationString + " (flags: " + debugFlagString + ")" - - private def defStringCompose(infoString: String) = compose( - flagString, - keyString, - varianceString + nameString + infoString + flagsExplanationString - ) - /** String representation of symbol's definition. It uses the - * symbol's raw info to avoid forcing types. - */ - def defString = defStringCompose(signatureString) - - /** String representation of symbol's definition, using the supplied - * info rather than the symbol's. - */ - def defStringSeenAs(info: Type) = defStringCompose(infoString(info)) - - /** Concatenate strings separated by spaces */ - private def compose(ss: String*) = ss filter (_ != "") mkString " " - - def isSingletonExistential = - nme.isSingletonName(name) && (info.bounds.hi.typeSymbol isSubClass SingletonClass) - - /** String representation of existentially bound variable */ - def existentialToString = - if (isSingletonExistential && !settings.debug.value) - "val " + tpnme.dropSingletonName(name) + ": " + dropSingletonType(info.bounds.hi) - else defString - } - implicit val SymbolTag = ClassTag[Symbol](classOf[Symbol]) - - /** A class for term symbols */ - class TermSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TermName) - extends Symbol(initOwner, initPos, initName) with TermSymbolApi { - private[this] var _referenced: Symbol = NoSymbol - privateWithin = NoSymbol - - type TypeOfClonedSymbol = TermSymbol - - private[this] var _rawname: TermName = initName - def rawname = _rawname - def name = _rawname - def name_=(name: Name) { - if (name != rawname) { - log("Renaming %s %s %s to %s".format(shortSymbolClass, debugFlagString, rawname, name)) - changeNameInOwners(name) - _rawname = name.toTermName - } - } - final def asNameType(n: Name) = n.toTermName - - /** Term symbols with the exception of static parts of Java classes and packages. - */ - override def isValue = !(isModule && hasFlag(PACKAGE | JAVA)) - override def isVariable = isMutable && !isMethod - override def isTermMacro = hasFlag(MACRO) - - // interesting only for lambda lift. Captured variables are accessed from inner lambdas. - override def isCapturedVariable = hasAllFlags(MUTABLE | CAPTURED) && !hasFlag(METHOD) - - override def companionSymbol: Symbol = companionClass - override def moduleClass = if (isModule) referenced else NoSymbol - - override def hasDefault = this hasFlag DEFAULTPARAM // overloaded with TRAIT - override def isBridge = this hasFlag BRIDGE - override def isEarlyInitialized = this hasFlag PRESUPER - override def isMethod = this hasFlag METHOD - override def isModule = this hasFlag MODULE - override def isOverloaded = this hasFlag OVERLOADED - override def isPackage = this hasFlag PACKAGE - override def isValueParameter = this hasFlag PARAM - - override def isSetterParameter = isValueParameter && owner.isSetter - override def isAccessor = this hasFlag ACCESSOR - override def isGetter = isAccessor && !isSetter - override def isSetter = isAccessor && nme.isSetterName(name) // todo: make independent of name, as this can be forged. - override def isLocalDummy = nme.isLocalDummyName(name) - override def isClassConstructor = name == nme.CONSTRUCTOR - override def isMixinConstructor = name == nme.MIXIN_CONSTRUCTOR - override def isConstructor = nme.isConstructorName(name) - - override def isPackageObject = isModule && (name == nme.PACKAGE) - override def isStable = !isUnstable - private def isUnstable = ( - isMutable - || (hasFlag(METHOD | BYNAMEPARAM) && !hasFlag(STABLE)) - || (tpe.isVolatile && !hasAnnotation(uncheckedStableClass)) - ) - - // The name in comments is what it is being disambiguated from. - // TODO - rescue CAPTURED from BYNAMEPARAM so we can see all the names. - override def resolveOverloadedFlag(flag: Long) = flag match { - case DEFAULTPARAM => "<defaultparam>" // TRAIT - case MIXEDIN => "<mixedin>" // EXISTENTIAL - case LABEL => "<label>" // CONTRAVARIANT / INCONSTRUCTOR - case PRESUPER => "<presuper>" // IMPLCLASS - case BYNAMEPARAM => if (this.isValueParameter) "<bynameparam>" else "<captured>" // COVARIANT - case _ => super.resolveOverloadedFlag(flag) - } - - def referenced: Symbol = _referenced - def referenced_=(x: Symbol) { _referenced = x } - - def existentialBound = singletonBounds(this.tpe) - - def cloneSymbolImpl(owner: Symbol, newFlags: Long): TermSymbol = - owner.newTermSymbol(name, pos, newFlags).copyAttrsFrom(this) - - def copyAttrsFrom(original: TermSymbol): this.type = { - referenced = original.referenced - this - } - - private val validAliasFlags = SUPERACCESSOR | PARAMACCESSOR | MIXEDIN | SPECIALIZED - - override def alias: Symbol = - if (hasFlag(validAliasFlags)) initialize.referenced - else NoSymbol - - def setAlias(alias: Symbol): TermSymbol = { - assert(alias != NoSymbol, this) - assert(!alias.isOverloaded, alias) - assert(hasFlag(validAliasFlags), this) - - referenced = alias - this - } - - override def outerSource: Symbol = - if (originalName == nme.OUTER) initialize.referenced - else NoSymbol - - def setModuleClass(clazz: Symbol): TermSymbol = { - assert(isModule, this) - referenced = clazz - this - } - - def setLazyAccessor(sym: Symbol): TermSymbol = { - assert(isLazy && (referenced == NoSymbol || referenced == sym), (this, debugFlagString, referenced, sym)) - referenced = sym - this - } - - override def lazyAccessor: Symbol = { - assert(isLazy, this) - referenced - } - - /** change name by appending $$<fully-qualified-name-of-class `base`> - * Do the same for any accessed symbols or setters/getters - */ - override def expandName(base: Symbol) { - if (!hasFlag(EXPANDEDNAME)) { - setFlag(EXPANDEDNAME) - if (hasAccessorFlag && !isDeferred) { - accessed.expandName(base) - } - else if (hasGetter) { - getter(owner).expandName(base) - setter(owner).expandName(base) - } - name = nme.expandedName(name.toTermName, base) - } - } - - protected def doCookJavaRawInfo() { - def cook(sym: Symbol) { - require(sym.isJavaDefined, sym) - // @M: I think this is more desirable, but Martin prefers to leave raw-types as-is as much as possible - // object rawToExistentialInJava extends TypeMap { - // def apply(tp: Type): Type = tp match { - // // any symbol that occurs in a java sig, not just java symbols - // // see http://lampsvn.epfl.ch/trac/scala/ticket/2454#comment:14 - // case TypeRef(pre, sym, List()) if !sym.typeParams.isEmpty => - // val eparams = typeParamsToExistentials(sym, sym.typeParams) - // existentialAbstraction(eparams, TypeRef(pre, sym, eparams map (_.tpe))) - // case _ => - // mapOver(tp) - // } - // } - val tpe1 = rawToExistential(sym.tpe) - // println("cooking: "+ sym +": "+ sym.tpe +" to "+ tpe1) - if (tpe1 ne sym.tpe) { - sym.setInfo(tpe1) - } - } - - if (isJavaDefined) - cook(this) - else if (isOverloaded) - for (sym2 <- alternatives) - if (sym2.isJavaDefined) - cook(sym2) - } - } - implicit val TermSymbolTag = ClassTag[TermSymbol](classOf[TermSymbol]) - - /** A class for module symbols */ - class ModuleSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TermName) - extends TermSymbol(initOwner, initPos, initName) with ModuleSymbolApi { - private var flatname: TermName = null - - override def associatedFile = moduleClass.associatedFile - override def associatedFile_=(f: AbstractFileType) { moduleClass.associatedFile = f } - - override def moduleClass = referenced - override def companionClass = - flatOwnerInfo.decl(name.toTypeName).suchThat(_ isCoDefinedWith this) - - override def owner = ( - if (!isMethod && needsFlatClasses) rawowner.owner - else rawowner - ) - override def name: TermName = ( - if (!isMethod && needsFlatClasses) { - if (flatname eq null) - flatname = nme.flattenedName(rawowner.name, rawname) - - flatname - } - else rawname - ) - } - implicit val ModuleSymbolTag = ClassTag[ModuleSymbol](classOf[ModuleSymbol]) - - /** A class for method symbols */ - class MethodSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TermName) - extends TermSymbol(initOwner, initPos, initName) with MethodSymbolApi { - private[this] var mtpePeriod = NoPeriod - private[this] var mtpePre: Type = _ - private[this] var mtpeResult: Type = _ - private[this] var mtpeInfo: Type = _ - - override def isLabel = this hasFlag LABEL - override def isVarargsMethod = this hasFlag VARARGS - override def isLiftedMethod = this hasFlag LIFTED - - // TODO - this seems a strange definition for "isSourceMethod", given that - // it does not make any specific effort to exclude synthetics. Figure out what - // this method is really for and what logic makes sense. - override def isSourceMethod = !(this hasFlag STABLE) // exclude all accessors - // unfortunately having the CASEACCESSOR flag does not actually mean you - // are a case accessor (you can also be a field.) - override def isCaseAccessorMethod = isCaseAccessor - - def typeAsMemberOf(pre: Type): Type = { - if (mtpePeriod == currentPeriod) { - if ((mtpePre eq pre) && (mtpeInfo eq info)) return mtpeResult - } else if (isValid(mtpePeriod)) { - mtpePeriod = currentPeriod - if ((mtpePre eq pre) && (mtpeInfo eq info)) return mtpeResult - } - val res = pre.computeMemberType(this) - mtpePeriod = currentPeriod - mtpePre = pre - mtpeInfo = info - mtpeResult = res - res - } - } - implicit val MethodSymbolTag = ClassTag[MethodSymbol](classOf[MethodSymbol]) - - class AliasTypeSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName) - extends TypeSymbol(initOwner, initPos, initName) { - type TypeOfClonedSymbol = TypeSymbol - final override def isAliasType = true - final override def dealias = info.typeSymbol.dealias - override def cloneSymbolImpl(owner: Symbol, newFlags: Long): TypeSymbol = - owner.newNonClassSymbol(name, pos, newFlags) - } - - class AbstractTypeSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName) - extends TypeSymbol(initOwner, initPos, initName) { - type TypeOfClonedSymbol = TypeSymbol - final override def isAbstractType = true - override def existentialBound = this.info - override def cloneSymbolImpl(owner: Symbol, newFlags: Long): TypeSymbol = - owner.newNonClassSymbol(name, pos, newFlags) - } - - /** A class of type symbols. Alias and abstract types are direct instances - * of this class. Classes are instances of a subclass. - */ - abstract class TypeSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName) - extends Symbol(initOwner, initPos, initName) with TypeSymbolApi { - privateWithin = NoSymbol - private[this] var _rawname: TypeName = initName - - type TypeOfClonedSymbol >: Null <: TypeSymbol - // cloneSymbolImpl still abstract in TypeSymbol. - - def rawname = _rawname - def name = _rawname - final def asNameType(n: Name) = n.toTypeName - - override def isNonClassType = true - override def isTypeMacro = hasFlag(MACRO) - - override def resolveOverloadedFlag(flag: Long) = flag match { - case TRAIT => "<trait>" // DEFAULTPARAM - case EXISTENTIAL => "<existential>" // MIXEDIN - case COVARIANT => "<covariant>" // BYNAMEPARAM / CAPTURED - case CONTRAVARIANT => "<contravariant>" // LABEL / INCONSTRUCTOR (overridden again in ClassSymbol) - case _ => super.resolveOverloadedFlag(flag) - } - - private var tyconCache: Type = null - private var tyconRunId = NoRunId - private var tpeCache: Type = _ - private var tpePeriod = NoPeriod - - override def isAbstractType = this hasFlag DEFERRED - override def isContravariant = this hasFlag CONTRAVARIANT - override def isCovariant = this hasFlag COVARIANT - override def isExistentialQuantified = isExistentiallyBound && !isSkolem - override def isExistentiallyBound = this hasFlag EXISTENTIAL - override def isTypeParameter = isTypeParameterOrSkolem && !isSkolem - override def isTypeParameterOrSkolem = this hasFlag PARAM - - /** Overridden in subclasses for which it makes sense. - */ - def existentialBound: Type = abort("unexpected type: "+this.getClass+ " "+debugLocationString) - - // TODO - don't allow names to be renamed in this unstructured a fashion. - // Rename as little as possible. Enforce invariants on all renames. - def name_=(name: Name) { - if (name != rawname) { - log("Renaming %s %s %s to %s".format(shortSymbolClass, debugFlagString, rawname, name)) - changeNameInOwners(name) - _rawname = name.toTypeName - } - } - - private def newPrefix = if (this hasFlag EXISTENTIAL | PARAM) NoPrefix else owner.thisType - private def newTypeRef(targs: List[Type]) = typeRef(newPrefix, this, targs) - - /** Let's say you have a type definition - * - * {{{ - * type T <: Number - * }}} - * - * and tsym is the symbol corresponding to T. Then - * - * {{{ - * tsym.info = TypeBounds(Nothing, Number) - * tsym.tpe = TypeRef(NoPrefix, T, List()) - * }}} - */ - override def tpe: Type = { - if (tpeCache eq NoType) throw CyclicReference(this, typeConstructor) - if (tpePeriod != currentPeriod) { - if (isValid(tpePeriod)) { - tpePeriod = currentPeriod - } else { - if (isInitialized) tpePeriod = currentPeriod - tpeCache = NoType - val targs = - if (phase.erasedTypes && this != ArrayClass) List() - else unsafeTypeParams map (_.typeConstructor) - //@M! use typeConstructor to generate dummy type arguments, - // sym.tpe should not be called on a symbol that's supposed to be a higher-kinded type - // memberType should be used instead, that's why it uses tpeHK and not tpe - tpeCache = newTypeRef(targs) - } - } - assert(tpeCache ne null/*, "" + this + " " + phase*/)//debug - tpeCache - } - - /** @M -- tpe vs tpeHK: - * - * tpe: creates a TypeRef with dummy type arguments and kind * - * tpeHK: creates a TypeRef with no type arguments but with type parameters - * - * If typeParams is nonEmpty, calling tpe may hide errors or - * introduce spurious ones. (For example, when deriving a type from - * the symbol of a type argument that may be higher-kinded.) As far - * as I can tell, it only makes sense to call tpe in conjunction - * with a substitution that replaces the generated dummy type - * arguments by their actual types. - * - * TODO: the above conditions desperately need to be enforced by code. - */ - override def tpeHK = typeConstructor // @M! used in memberType - - override def typeConstructor: Type = { - if ((tyconCache eq null) || tyconRunId != currentRunId) { - tyconCache = newTypeRef(Nil) - tyconRunId = currentRunId - } - assert(tyconCache ne null) - tyconCache - } - - override def info_=(tp: Type) { - tpePeriod = NoPeriod - tyconCache = null - super.info_=(tp) - } - - final override def isNonBottomSubClass(that: Symbol): Boolean = ( - (this eq that) || this.isError || that.isError || - info.baseTypeIndex(that) >= 0 - ) - - override def reset(completer: Type): this.type = { - super.reset(completer) - tpePeriod = NoPeriod - tyconRunId = NoRunId - this - } - - /*** example: - * public class Test3<T> {} - * public class Test1<T extends Test3> {} - * info for T in Test1 should be >: Nothing <: Test3[_] - */ - protected def doCookJavaRawInfo() { - if (isJavaDefined || owner.isJavaDefined) { - val tpe1 = rawToExistential(info) - // println("cooking type: "+ this +": "+ info +" to "+ tpe1) - if (tpe1 ne info) { - setInfo(tpe1) - } - } - } - - incCounter(typeSymbolCount) - } - implicit val TypeSymbolTag = ClassTag[TypeSymbol](classOf[TypeSymbol]) - - /** A class for type parameters viewed from inside their scopes - * - * @param origin Can be either a tree, or a symbol, or null. - * If skolem got created from newTypeSkolem (called in Namers), origin denotes - * the type parameter from which the skolem was created. If it got created from - * skolemizeExistential, origin is either null or a Tree. If it is a Tree, it indicates - * where the skolem was introduced (this is important for knowing when to pack it - * again into ab Existential). origin is `null` only in skolemizeExistentials called - * from <:< or isAsSpecific, because here its value does not matter. - * I believe the following invariant holds: - * - * origin.isInstanceOf[Symbol] == !hasFlag(EXISTENTIAL) - */ - class TypeSkolem protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName, origin: AnyRef) - extends TypeSymbol(initOwner, initPos, initName) { - type TypeOfClonedSymbol = TypeSkolem - /** The skolemization level in place when the skolem was constructed */ - val level = skolemizationLevel - - final override def isSkolem = true - - // a type symbol bound by an existential type, for instance the T in - // List[T] forSome { type T } - override def isExistentialSkolem = this hasFlag EXISTENTIAL - override def isGADTSkolem = this hasFlag CASEACCESSOR | SYNTHETIC - override def isTypeSkolem = this hasFlag PARAM - override def isAbstractType = this hasFlag DEFERRED - - override def isExistentialQuantified = false - override def existentialBound = if (isAbstractType) this.info else super.existentialBound - - /** If typeskolem comes from a type parameter, that parameter, otherwise skolem itself */ - override def deSkolemize = origin match { - case s: Symbol => s - case _ => this - } - - /** If type skolem comes from an existential, the tree where it was created */ - override def unpackLocation = origin - - //@M! (not deSkolemize.typeParams!!), also can't leave superclass definition: use info, not rawInfo - override def typeParams = info.typeParams - - override def cloneSymbolImpl(owner: Symbol, newFlags: Long): TypeSkolem = - owner.newTypeSkolemSymbol(name, origin, pos, newFlags) - - override def nameString: String = - if (settings.debug.value) (super.nameString + "&" + level) - else super.nameString - } - - /** A class for class symbols */ - class ClassSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName) - extends TypeSymbol(initOwner, initPos, initName) with ClassSymbolApi { - type TypeOfClonedSymbol = ClassSymbol - - private[this] var flatname: TypeName = _ - private[this] var _associatedFile: AbstractFileType = _ - private[this] var thissym: Symbol = this - - private[this] var thisTypeCache: Type = _ - private[this] var thisTypePeriod = NoPeriod - - override def resolveOverloadedFlag(flag: Long) = flag match { - case INCONSTRUCTOR => "<inconstructor>" // INCONSTRUCTOR / CONTRAVARIANT / LABEL - case EXISTENTIAL => "<existential>" // EXISTENTIAL / MIXEDIN - case IMPLCLASS => "<implclass>" // IMPLCLASS / PRESUPER - case _ => super.resolveOverloadedFlag(flag) - } - - final override def isNonClassType = false - final override def isAbstractType = false - final override def isAliasType = false - - override def isAbstractClass = this hasFlag ABSTRACT - override def isCaseClass = this hasFlag CASE - override def isClassLocalToConstructor = this hasFlag INCONSTRUCTOR - override def isImplClass = this hasFlag IMPLCLASS - override def isModuleClass = this hasFlag MODULE - override def isPackageClass = this hasFlag PACKAGE - override def isTrait = this hasFlag TRAIT - - override def isAnonOrRefinementClass = isAnonymousClass || isRefinementClass - override def isAnonymousClass = name containsName tpnme.ANON_CLASS_NAME - override def isConcreteClass = !(this hasFlag ABSTRACT | TRAIT) - override def isJavaInterface = hasAllFlags(JAVA | TRAIT) - override def isNestedClass = !owner.isPackageClass - override def isNumericValueClass = definitions.isNumericValueClass(this) - override def isPackageObjectClass = isModuleClass && (name == tpnme.PACKAGE) - override def isPrimitiveValueClass = definitions.isPrimitiveValueClass(this) - - // The corresponding interface is the last parent by convention. - private def lastParent = if (tpe.parents.isEmpty) NoSymbol else tpe.parents.last.typeSymbol - override def toInterface: Symbol = ( - if (isImplClass) { - if (phase.next.erasedTypes) lastParent - else owner.info.decl(tpnme.interfaceName(name)) - } - else super.toInterface - ) - - /** Is this class locally defined? - * A class is local, if - * - it is anonymous, or - * - its owner is a value - * - it is defined within a local class - */ - override def isLocalClass = ( - isAnonOrRefinementClass - || isLocal - || !owner.isPackageClass && owner.isLocalClass - ) - override def isStableClass = (this hasFlag STABLE) || checkStable() - - private def checkStable() = { - def hasNoAbstractTypeMember(clazz: Symbol): Boolean = - (clazz hasFlag STABLE) || { - var e = clazz.info.decls.elems - while ((e ne null) && !(e.sym.isAbstractType && info.member(e.sym.name) == e.sym)) - e = e.next - e == null - } - (info.baseClasses forall hasNoAbstractTypeMember) && { - setFlag(STABLE) - true - } - } - - override def enclClassChain = this :: owner.enclClassChain - - /** A helper method that factors the common code used the discover a - * companion module of a class. If a companion module exists, its symbol is - * returned, otherwise, `NoSymbol` is returned. - */ - protected final def companionModule0: Symbol = - flatOwnerInfo.decl(name.toTermName).suchThat( - sym => sym.hasFlag(MODULE) && (sym isCoDefinedWith this) && !sym.isMethod) - - override def companionModule = companionModule0 - override def companionSymbol = companionModule0 - override def linkedClassOfClass = companionModule.moduleClass - - override def sourceModule = if (isModuleClass) companionModule else NoSymbol - - override def existentialBound = GenPolyType(this.typeParams, TypeBounds.upper(this.classBound)) - - def primaryConstructorName = if (this hasFlag TRAIT | IMPLCLASS) nme.MIXIN_CONSTRUCTOR else nme.CONSTRUCTOR - - override def primaryConstructor = { - val c = info decl primaryConstructorName - if (c.isOverloaded) c.alternatives.head else c - } - - override def associatedFile = if (owner.isPackageClass) _associatedFile else super.associatedFile - override def associatedFile_=(f: AbstractFileType) { _associatedFile = f } - - override def reset(completer: Type): this.type = { - super.reset(completer) - thissym = this - this - } - - /** the type this.type in this class */ - override def thisType: Type = { - val period = thisTypePeriod - if (period != currentPeriod) { - thisTypePeriod = currentPeriod - if (!isValid(period)) thisTypeCache = ThisType(this) - } - thisTypeCache - } - - override def owner: Symbol = - if (needsFlatClasses) rawowner.owner else rawowner - - override def name: TypeName = ( - if (needsFlatClasses) { - if (flatname eq null) - flatname = nme.flattenedName(rawowner.name, rawname).toTypeName - - flatname - } - else rawname - ) - - /** A symbol carrying the self type of the class as its type */ - override def thisSym: Symbol = thissym - - /** Sets the self type of the class */ - override def typeOfThis_=(tp: Type) { - thissym = newThisSym(nme.this_, pos).setInfo(tp) - } - - override def cloneSymbolImpl(owner: Symbol, newFlags: Long): ClassSymbol = { - val clone = owner.newClassSymbol(name, pos, newFlags) - if (thisSym != this) { - clone.typeOfThis = typeOfThis - clone.thisSym setName thisSym.name - } - if (_associatedFile ne null) - clone.associatedFile = _associatedFile - - clone - } - - override def firstParamAccessor = - info.decls.find(_ hasAllFlags PARAMACCESSOR | METHOD) getOrElse NoSymbol - - private[this] var childSet: Set[Symbol] = Set() - override def children = childSet - override def addChild(sym: Symbol) { childSet = childSet + sym } - - incCounter(classSymbolCount) - } - implicit val ClassSymbolTag = ClassTag[ClassSymbol](classOf[ClassSymbol]) - - /** A class for module class symbols - * Note: Not all module classes are of this type; when unpickled, we get - * plain class symbols! - */ - class ModuleClassSymbol protected[Symbols] (owner: Symbol, pos: Position, name: TypeName) - extends ClassSymbol(owner, pos, name) { - private[this] var module: Symbol = _ - private[this] var typeOfThisCache: Type = _ - private[this] var typeOfThisPeriod = NoPeriod - - private var implicitMembersCacheValue: List[Symbol] = Nil - private var implicitMembersCacheKey1: Type = NoType - private var implicitMembersCacheKey2: ScopeEntry = null - - override def isModuleClass = true - override def linkedClassOfClass = companionClass - - /** the self type of an object foo is foo.type, not class<foo>.this.type - */ - override def typeOfThis = { - val period = typeOfThisPeriod - if (period != currentPeriod) { - typeOfThisPeriod = currentPeriod - if (!isValid(period)) - typeOfThisCache = singleType(owner.thisType, sourceModule) - } - typeOfThisCache - } - - def implicitMembers: List[Symbol] = { - val tp = info - if ((implicitMembersCacheKey1 ne tp) || (implicitMembersCacheKey2 ne tp.decls.elems)) { - // Skip a package object class, because the members are also in - // the package and we wish to avoid spurious ambiguities as in pos/t3999. - if (!isPackageObjectClass) { - implicitMembersCacheKey1 = tp - implicitMembersCacheKey2 = tp.decls.elems - implicitMembersCacheValue = tp.implicitMembers - } - } - implicitMembersCacheValue - } - // The null check seems to be necessary for the reifier. - override def sourceModule = if (module ne null) module else companionModule - override def sourceModule_=(module: Symbol) { this.module = module } - } - - class PackageObjectClassSymbol protected[Symbols] (owner0: Symbol, pos0: Position) - extends ModuleClassSymbol(owner0, pos0, tpnme.PACKAGE) { - final override def isPackageObjectClass = true - final override def isPackageObjectOrClass = true - final override def skipPackageObject = owner - final override def setName(name: Name): this.type = { - abort("Can't rename a package object to " + name) - } - } - - trait ImplClassSymbol extends ClassSymbol { - override def sourceModule = companionModule - // override def isImplClass = true - override def typeOfThis = thisSym.tpe // don't use the ModuleClassSymbol typeOfThisCache. - } - - class PackageClassSymbol protected[Symbols] (owner0: Symbol, pos0: Position, name0: TypeName) - extends ModuleClassSymbol(owner0, pos0, name0) { - override def sourceModule = companionModule - override def enclClassChain = Nil - override def isPackageClass = true - } - - class RefinementClassSymbol protected[Symbols] (owner0: Symbol, pos0: Position) - extends ClassSymbol(owner0, pos0, tpnme.REFINE_CLASS_NAME) { - override def name_=(name: Name) { - assert(false, "Cannot set name of RefinementClassSymbol to " + name) - super.name_=(name) - } - override def isRefinementClass = true - override def isAnonOrRefinementClass = true - override def isLocalClass = true - override def hasMeaninglessName = true - override def companionModule: Symbol = NoSymbol - - /** The mentioned twist. A refinement class has transowner X - * if any of its parents has transowner X. - */ - override def hasTransOwner(sym: Symbol) = ( - super.hasTransOwner(sym) - || info.parents.exists(_.typeSymbol hasTransOwner sym) - ) - } - - trait FreeSymbol extends Symbol { - def origin: String - } - class FreeTermSymbol(name0: TermName, value0: => Any, val origin: String) extends TermSymbol(NoSymbol, NoPosition, name0) with FreeSymbol with FreeTermSymbolApi { - def value = value0 - } - implicit val FreeTermSymbolTag = ClassTag[FreeTermSymbol](classOf[FreeTermSymbol]) - - class FreeTypeSymbol(name0: TypeName, value0: => Any, val origin: String) extends TypeSkolem(NoSymbol, NoPosition, name0, NoSymbol) with FreeSymbol with FreeTypeSymbolApi { - def value = value0 - } - implicit val FreeTypeSymbolTag = ClassTag[FreeTypeSymbol](classOf[FreeTypeSymbol]) - - /** An object representing a missing symbol */ - class NoSymbol protected[Symbols]() extends Symbol(null, NoPosition, nme.NO_NAME) { - final type NameType = TermName - type TypeOfClonedSymbol = NoSymbol - - def asNameType(n: Name) = n.toTermName - def rawname = nme.NO_NAME - def name = nme.NO_NAME - def name_=(n: Name) = abort("Cannot set NoSymbol's name to " + n) - - synchronized { - setInfo(NoType) - privateWithin = this - } - override def info_=(info: Type) = { - infos = TypeHistory(1, NoType, null) - unlock() - validTo = currentPeriod - } - override def flagMask = AllFlags - override def exists = false - override def isHigherOrderTypeParameter = false - override def companionClass = NoSymbol - override def companionModule = NoSymbol - override def companionSymbol = NoSymbol - override def isSubClass(that: Symbol) = false - override def filter(cond: Symbol => Boolean) = this - override def defString: String = toString - override def locationString: String = "" - override def enclClassChain = Nil - override def enclClass: Symbol = this - override def enclosingTopLevelClass: Symbol = this - override def enclosingPackageClass: Symbol = this - override def enclMethod: Symbol = this - override def associatedFile = null - override def ownerChain: List[Symbol] = List() - override def ownersIterator: Iterator[Symbol] = Iterator.empty - override def alternatives: List[Symbol] = List() - override def reset(completer: Type): this.type = this - override def info: Type = NoType - override def existentialBound: Type = NoType - override def rawInfo: Type = NoType - protected def doCookJavaRawInfo() {} - override def accessBoundary(base: Symbol): Symbol = enclosingRootClass - def cloneSymbolImpl(owner: Symbol, newFlags: Long) = abort("NoSymbol.clone()") - override def originalEnclosingMethod = this - - override def owner: Symbol = - abort("no-symbol does not have an owner") - override def typeConstructor: Type = - abort("no-symbol does not have a type constructor (this may indicate scalac cannot find fundamental classes)") - } - - protected def makeNoSymbol: NoSymbol = new NoSymbol - - lazy val NoSymbol: NoSymbol = makeNoSymbol - - /** 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) - def cloneSymbolsAtOwnerAndModify(syms: List[Symbol], owner: Symbol, infoFn: Type => Type): List[Symbol] = - cloneSymbolsAtOwner(syms, owner) 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)) - } - - /** A deep map on a symbol's paramss. - */ - def mapParamss[T](sym: Symbol)(f: Symbol => T): List[List[T]] = mmap(sym.info.paramss)(f) - - /** An exception for cyclic references of symbol definitions */ - case class CyclicReference(sym: Symbol, info: Type) - extends TypeError("illegal cyclic reference involving " + sym) { - if (settings.debug.value) printStackTrace() - } - - case class InvalidCompanions(sym1: Symbol, sym2: Symbol) extends Throwable({ - import language.reflectiveCalls - "Companions '" + sym1 + "' and '" + sym2 + "' must be defined in same file:\n" + - " Found in " + sym1.sourceFile.canonicalPath + " and " + sym2.sourceFile.canonicalPath - }) { - override def toString = getMessage - } - - /** A class for type histories */ - private sealed case class TypeHistory(var validFrom: Period, info: Type, prev: TypeHistory) { - assert((prev eq null) || phaseId(validFrom) > phaseId(prev.validFrom), this) - assert(validFrom != NoPeriod, this) - - override def toString() = - "TypeHistory(" + phaseOf(validFrom)+":"+runId(validFrom) + "," + info + "," + prev + ")" - - def toList: List[TypeHistory] = this :: ( if (prev eq null) Nil else prev.toList ) - } -} diff --git a/src/compiler/scala/reflect/internal/TreeGen.scala b/src/compiler/scala/reflect/internal/TreeGen.scala deleted file mode 100644 index c3a6fce164..0000000000 --- a/src/compiler/scala/reflect/internal/TreeGen.scala +++ /dev/null @@ -1,280 +0,0 @@ -package scala.reflect -package internal - -abstract class TreeGen extends makro.TreeBuilder { - val global: SymbolTable - - import global._ - import definitions._ - - def rootId(name: Name) = Select(Ident(nme.ROOTPKG), name) - def rootScalaDot(name: Name) = Select(rootId(nme.scala_) setSymbol ScalaPackage, name) - def scalaDot(name: Name) = Select(Ident(nme.scala_) setSymbol ScalaPackage, name) - def scalaAnnotationDot(name: Name) = Select(scalaDot(nme.annotation), name) - def scalaAnyRefConstr = scalaDot(tpnme.AnyRef) setSymbol AnyRefClass - def scalaUnitConstr = scalaDot(tpnme.Unit) setSymbol UnitClass - def productConstr = scalaDot(tpnme.Product) setSymbol ProductRootClass - def serializableConstr = scalaDot(tpnme.Serializable) setSymbol SerializableClass - - def scalaFunctionConstr(argtpes: List[Tree], restpe: Tree, abstractFun: Boolean = false): Tree = { - val cls = if (abstractFun) - mkAttributedRef(AbstractFunctionClass(argtpes.length)) - else - mkAttributedRef(FunctionClass(argtpes.length)) - AppliedTypeTree(cls, argtpes :+ restpe) - } - - /** A creator for method calls, e.g. fn[T1, T2, ...](v1, v2, ...) - * There are a number of variations. - * - * @param receiver symbol of the method receiver - * @param methodName name of the method to call - * @param targs type arguments (if Nil, no TypeApply node will be generated) - * @param args value arguments - * @return the newly created trees. - */ - def mkMethodCall(receiver: Symbol, methodName: Name, targs: List[Type], args: List[Tree]): Tree = - mkMethodCall(Select(mkAttributedRef(receiver), methodName), targs, args) - def mkMethodCall(method: Symbol, targs: List[Type], args: List[Tree]): Tree = - mkMethodCall(mkAttributedRef(method), targs, args) - def mkMethodCall(method: Symbol, args: List[Tree]): Tree = - mkMethodCall(method, Nil, args) - def mkMethodCall(target: Tree, args: List[Tree]): Tree = - mkMethodCall(target, Nil, args) - def mkMethodCall(receiver: Symbol, methodName: Name, args: List[Tree]): Tree = - mkMethodCall(receiver, methodName, Nil, args) - 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 = - Apply(mkTypeApply(target, targs map TypeTree), args) - - def mkNullaryCall(method: Symbol, targs: List[Type]): Tree = - mkTypeApply(mkAttributedRef(method), targs map TypeTree) - - /** Builds a reference to value whose type is given stable prefix. - * The type must be suitable for this. For example, it - * must not be a TypeRef pointing to an abstract type variable. - */ - def mkAttributedQualifier(tpe: Type): Tree = - mkAttributedQualifier(tpe, NoSymbol) - - /** Builds a reference to value whose type is given stable prefix. - * If the type is unsuitable, e.g. it is a TypeRef for an - * abstract type variable, then an Ident will be made using - * termSym as the Ident's symbol. In that case, termSym must - * not be NoSymbol. - */ - def mkAttributedQualifier(tpe: Type, termSym: Symbol): Tree = { - def failMessage = "mkAttributedQualifier(" + tpe + ", " + termSym + ")" - tpe match { - case NoPrefix => - EmptyTree - case ThisType(clazz) => - if (clazz.isEffectiveRoot) EmptyTree - else mkAttributedThis(clazz) - case SingleType(pre, sym) => - mkApplyIfNeeded(mkAttributedStableRef(pre, sym)) - case TypeRef(pre, sym, args) => - if (sym.isRoot) { - mkAttributedThis(sym) - } else if (sym.isModuleClass) { - mkApplyIfNeeded(mkAttributedRef(pre, sym.sourceModule)) - } else if (sym.isModule || sym.isClass) { - assert(phase.erasedTypes, failMessage) - mkAttributedThis(sym) - } else if (sym.isType) { - assert(termSym != NoSymbol, failMessage) - mkAttributedIdent(termSym) setType tpe - } else { - mkAttributedRef(pre, sym) - } - - case ConstantType(value) => - Literal(value) setType tpe - - case AnnotatedType(_, atp, _) => - mkAttributedQualifier(atp) - - case RefinedType(parents, _) => - // I am unclear whether this is reachable, but - // the following implementation looks logical -Lex - val firstStable = parents.find(_.isStable) - assert(!firstStable.isEmpty, failMessage + " parents = " + parents) - mkAttributedQualifier(firstStable.get) - - case _ => - abort("bad qualifier received: " + failMessage) - } - } - /** If this is a reference to a method with an empty - * parameter list, wrap it in an apply. - */ - def mkApplyIfNeeded(qual: Tree) = qual.tpe match { - case MethodType(Nil, restpe) => atPos(qual.pos)(Apply(qual, Nil) setType restpe) - case _ => qual - } - - /** Builds a reference to given symbol with given stable prefix. */ - def mkAttributedRef(pre: Type, sym: Symbol): Tree = { - val qual = mkAttributedQualifier(pre) - qual match { - case EmptyTree => mkAttributedIdent(sym) - case This(clazz) if qual.symbol.isEffectiveRoot => mkAttributedIdent(sym) - case _ => mkAttributedSelect(qual, sym) - } - } - - /** Builds a reference to given symbol. */ - def mkAttributedRef(sym: Symbol): Tree = - if (sym.owner.isClass) mkAttributedRef(sym.owner.thisType, sym) - else mkAttributedIdent(sym) - - /** Builds an untyped reference to given symbol. */ - def mkUnattributedRef(sym: Symbol): Tree = - if (sym.owner.isClass) Select(This(sym.owner), sym) - else Ident(sym) - - /** Replaces tree type with a stable type if possible */ - def stabilize(tree: Tree): Tree = { - for(tp <- stableTypeFor(tree)) tree.tpe = tp - tree - } - - /** Computes stable type for a tree if possible */ - def stableTypeFor(tree: Tree): Option[Type] = tree match { - case Ident(_) if tree.symbol.isStable => - Some(singleType(tree.symbol.owner.thisType, tree.symbol)) - case Select(qual, _) if ((tree.symbol ne null) && (qual.tpe ne null)) && // turned assert into guard for #4064 - tree.symbol.isStable && qual.tpe.isStable => - Some(singleType(qual.tpe, tree.symbol)) - case _ => - None - } - - /** Builds a reference with stable type to given symbol */ - def mkAttributedStableRef(pre: Type, sym: Symbol): Tree = - stabilize(mkAttributedRef(pre, sym)) - - def mkAttributedStableRef(sym: Symbol): Tree = - stabilize(mkAttributedRef(sym)) - - def mkAttributedThis(sym: Symbol): Tree = - This(sym.name.toTypeName) setSymbol sym setType sym.thisType - - def mkAttributedIdent(sym: Symbol): Tree = - Ident(sym.name) setSymbol sym setType sym.tpe - - def mkAttributedSelect(qual: Tree, sym: Symbol): Tree = { - // Tests involving the repl fail without the .isEmptyPackage condition. - if (qual.symbol != null && (qual.symbol.isEffectiveRoot || qual.symbol.isEmptyPackage)) - mkAttributedIdent(sym) - else { - val pkgQualifier = - if (sym != null && sym.owner.isPackageObjectClass && sym.effectiveOwner == qual.tpe.typeSymbol) { - val obj = sym.owner.sourceModule - Select(qual, nme.PACKAGE) setSymbol obj setType singleType(qual.tpe, obj) - } - else qual - - val tree = Select(pkgQualifier, sym) - if (pkgQualifier.tpe == null) tree - else tree setType (qual.tpe memberType sym) - } - } - - /** 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 = - 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 = - 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)) 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 - * ClassType(value.asInstanceOf[Type]), i.e. java.lang.Class[Type]. - * Can't find any docs on how/why it's done this way. See ticket - * SI-490 for some interesting comments from lauri alanko suggesting - * that the type given by classOf[T] is too strong and should be - * weakened so as not to suggest that classOf[List[String]] is any - * different from classOf[List[Int]]. - * - * !!! See deconstMap in Erasure for one bug this encoding has induced: - * I would be very surprised if there aren't more. - */ - def mkClassOf(tp: Type): Tree = - Literal(Constant(tp)) setType ConstantType(Constant(tp)) - - /** Builds a list with given head and tail. */ - def mkNewCons(head: Tree, tail: Tree): Tree = - New(Apply(mkAttributedRef(ConsClass), List(head, tail))) - - /** Builds a list with given head and tail. */ - def mkNil: Tree = mkAttributedRef(NilModule) - - /** Builds a tree representing an undefined local, as in - * var x: T = _ - * which is appropriate to the given Type. - */ - def mkZero(tp: Type): Tree = tp.typeSymbol match { - case NothingClass => mkMethodCall(Predef_???, Nil) setType NothingClass.tpe - case _ => Literal(mkConstantZero(tp)) setType tp - } - - def mkConstantZero(tp: Type): Constant = tp.typeSymbol match { - case UnitClass => Constant(()) - case BooleanClass => Constant(false) - case FloatClass => Constant(0.0f) - case DoubleClass => Constant(0.0d) - case ByteClass => Constant(0.toByte) - case ShortClass => Constant(0.toShort) - case IntClass => Constant(0) - case LongClass => Constant(0L) - case CharClass => Constant(0.toChar) - case _ => Constant(null) - } - - /** Builds a tuple */ - def mkTuple(elems: List[Tree]): Tree = - if (elems.isEmpty) Literal(Constant()) - else Apply( - Select(mkAttributedRef(TupleClass(elems.length).caseModule), nme.apply), - elems) - - // tree1 AND tree2 - def mkAnd(tree1: Tree, tree2: Tree): Tree = - Apply(Select(tree1, Boolean_and), List(tree2)) - - // tree1 OR tree2 - def mkOr(tree1: Tree, tree2: Tree): Tree = - Apply(Select(tree1, Boolean_or), List(tree2)) - - def mkBasisUniverseRef: Tree = - mkAttributedRef(ReflectBasis) setType singleType(ReflectBasis.owner.thisPrefix, ReflectBasis) - - def mkRuntimeUniverseRef: Tree = { - assert(ReflectRuntimeUniverse != NoSymbol) - mkAttributedRef(ReflectRuntimeUniverse) setType singleType(ReflectRuntimeUniverse.owner.thisPrefix, ReflectRuntimeUniverse) - } -} diff --git a/src/compiler/scala/reflect/internal/TreeInfo.scala b/src/compiler/scala/reflect/internal/TreeInfo.scala deleted file mode 100644 index 4b2105876d..0000000000 --- a/src/compiler/scala/reflect/internal/TreeInfo.scala +++ /dev/null @@ -1,571 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.reflect -package internal - -import Flags._ - -/** This class ... - * - * @author Martin Odersky - * @version 1.0 - */ -abstract class TreeInfo { - val global: SymbolTable - - import global._ - import definitions.{ isVarArgsList, isCastSymbol, ThrowableClass, TupleClass } - - /* Does not seem to be used. Not sure what it does anyway. - def isOwnerDefinition(tree: Tree): Boolean = tree match { - case PackageDef(_, _) - | ClassDef(_, _, _, _) - | ModuleDef(_, _, _) - | DefDef(_, _, _, _, _, _) - | Import(_, _) => true - case _ => false - } -*/ - - // def isDefinition(tree: Tree): Boolean = tree.isDef - - /** Is tree a declaration or type definition? - */ - def isDeclarationOrTypeDef(tree: Tree): Boolean = tree match { - case x: ValOrDefDef => x.rhs eq EmptyTree - case _ => tree.isInstanceOf[TypeDef] - } - - /** Is tree legal as a member definition of an interface? - */ - def isInterfaceMember(tree: Tree): Boolean = tree match { - case EmptyTree => true - case Import(_, _) => true - case TypeDef(_, _, _, _) => true - case DefDef(mods, _, _, _, _, __) => mods.isDeferred - case ValDef(mods, _, _, _) => mods.isDeferred - case _ => false - } - - /** Is tree a pure (i.e. non-side-effecting) definition? - */ - def isPureDef(tree: Tree): Boolean = tree match { - case EmptyTree - | ClassDef(_, _, _, _) - | TypeDef(_, _, _, _) - | Import(_, _) - | DefDef(_, _, _, _, _, _) => - true - case ValDef(mods, _, _, rhs) => - !mods.isMutable && isExprSafeToInline(rhs) - case _ => - false - } - - /** Is tree an expression which can be inlined without affecting program semantics? - * - * Note that this is not called "isExprSafeToInline" since purity (lack of side-effects) - * is not the litmus test. References to modules and lazy vals are side-effecting, - * both because side-effecting code may be executed and because the first reference - * takes a different code path than all to follow; but they are safe to inline - * because the expression result from evaluating them is always the same. - */ - def isExprSafeToInline(tree: Tree): Boolean = tree match { - case EmptyTree - | This(_) - | Super(_, _) - | Literal(_) => - true - case Ident(_) => - tree.symbol.isStable - // this case is mostly to allow expressions like -5 and +7, but any - // member of an anyval should be safely pure - case Select(Literal(const), name) => - const.isAnyVal && (const.tpe.member(name) != NoSymbol) - case Select(qual, _) => - tree.symbol.isStable && isExprSafeToInline(qual) - case TypeApply(fn, _) => - isExprSafeToInline(fn) - case Apply(fn, List()) => - /* Note: After uncurry, field accesses are represented as Apply(getter, Nil), - * so an Apply can also be pure. - * However, before typing, applications of nullary functional values are also - * Apply(function, Nil) trees. To prevent them from being treated as pure, - * we check that the callee is a method. */ - fn.symbol.isMethod && !fn.symbol.isLazy && isExprSafeToInline(fn) - case Typed(expr, _) => - isExprSafeToInline(expr) - case Block(stats, expr) => - (stats forall isPureDef) && isExprSafeToInline(expr) - case _ => - false - } - - @deprecated("Use isExprSafeToInline instead", "2.10.0") - def isPureExpr(tree: Tree) = isExprSafeToInline(tree) - - def zipMethodParamsAndArgs(params: List[Symbol], args: List[Tree]): List[(Symbol, Tree)] = - mapMethodParamsAndArgs(params, args)((param, arg) => ((param, arg))) - - def mapMethodParamsAndArgs[R](params: List[Symbol], args: List[Tree])(f: (Symbol, Tree) => R): List[R] = { - val b = List.newBuilder[R] - foreachMethodParamAndArg(params, args)((param, arg) => b += f(param, arg)) - b.result - } - def foreachMethodParamAndArg(params: List[Symbol], args: List[Tree])(f: (Symbol, Tree) => Unit): Boolean = { - val plen = params.length - val alen = args.length - def fail() = { - global.debugwarn( - "Mismatch trying to zip method parameters and argument list:\n" + - " params = " + params + "\n" + - " args = " + args + "\n" - ) - false - } - - if (plen == alen) foreach2(params, args)(f) - else if (params.isEmpty) return fail - else if (isVarArgsList(params)) { - val plenInit = plen - 1 - if (alen == plenInit) { - if (alen == 0) Nil // avoid calling mismatched zip - else foreach2(params.init, args)(f) - } - else if (alen < plenInit) return fail - else { - foreach2(params.init, args take plenInit)(f) - val remainingArgs = args drop plenInit - foreach2(List.fill(remainingArgs.size)(params.last), remainingArgs)(f) - } - } - else return fail - - true - } - - /** - * Selects the correct parameter list when there are nested applications. - * Given Apply(fn, args), args might correspond to any of fn.symbol's parameter - * lists. To choose the correct one before uncurry, we have to unwrap any - * applies: for instance Apply(fn @ Apply(Apply(_, _), _), args) implies args - * correspond to the third parameter list. - * - * The argument fn is the function part of the apply node being considered. - * - * Also accounts for varargs. - */ - private def applyMethodParameters(fn: Tree): List[Symbol] = { - val depth = applyDepth(fn) - // There could be applies which go beyond the parameter list(s), - // being applied to the result of the method call. - // !!! Note that this still doesn't seem correct, although it should - // be closer than what it replaced. - if (depth < fn.symbol.paramss.size) fn.symbol.paramss(depth) - else if (fn.symbol.paramss.isEmpty) Nil - else fn.symbol.paramss.last - } - - def zipMethodParamsAndArgs(t: Tree): List[(Symbol, Tree)] = t match { - case Apply(fn, args) => zipMethodParamsAndArgs(applyMethodParameters(fn), args) - case _ => Nil - } - def foreachMethodParamAndArg(t: Tree)(f: (Symbol, Tree) => Unit): Unit = t match { - case Apply(fn, args) => foreachMethodParamAndArg(applyMethodParameters(fn), args)(f) - case _ => - } - - /** Is symbol potentially a getter of a variable? - */ - def mayBeVarGetter(sym: Symbol): Boolean = sym.info match { - case NullaryMethodType(_) => sym.owner.isClass && !sym.isStable - case PolyType(_, NullaryMethodType(_)) => sym.owner.isClass && !sym.isStable - case mt @ MethodType(_, _) => mt.isImplicit && sym.owner.isClass && !sym.isStable - case _ => false - } - - /** Is tree a mutable variable, or the getter of a mutable field? - */ - def isVariableOrGetter(tree: Tree) = { - def sym = tree.symbol - def isVar = sym.isVariable - def isGetter = mayBeVarGetter(sym) && sym.owner.info.member(nme.getterToSetter(sym.name.toTermName)) != NoSymbol - - tree match { - case Ident(_) => isVar - case Select(_, _) => isVar || isGetter - case _ => - methPart(tree) match { - case Select(qual, nme.apply) => qual.tpe.member(nme.update) != NoSymbol - case _ => false - } - } - } - - /** Is tree a self constructor call this(...)? I.e. a call to a constructor of the - * same object? - */ - def isSelfConstrCall(tree: Tree): Boolean = methPart(tree) match { - case Ident(nme.CONSTRUCTOR) - | Select(This(_), nme.CONSTRUCTOR) => true - case _ => false - } - - /** Is tree a super constructor call? - */ - def isSuperConstrCall(tree: Tree): Boolean = methPart(tree) match { - case Select(Super(_, _), nme.CONSTRUCTOR) => true - case _ => false - } - - /** - * Named arguments can transform a constructor call into a block, e.g. - * <init>(b = foo, a = bar) - * is transformed to - * { val x$1 = foo - * val x$2 = bar - * <init>(x$2, x$1) - * } - */ - def stripNamedApplyBlock(tree: Tree) = tree match { - case Block(stats, expr) if stats.forall(_.isInstanceOf[ValDef]) => - expr - case _ => - tree - } - - /** Is tree a self or super constructor call? */ - def isSelfOrSuperConstrCall(tree: Tree) = { - // stripNamedApply for SI-3584: adaptToImplicitMethod in Typers creates a special context - // for implicit search in constructor calls, adaptToImplicitMethod(isSelfOrConstrCall) - val tree1 = stripNamedApplyBlock(tree) - isSelfConstrCall(tree1) || isSuperConstrCall(tree1) - } - - /** Is tree a variable pattern? */ - def isVarPattern(pat: Tree): Boolean = pat match { - case x: Ident => !x.isBackquoted && isVariableName(x.name) - case _ => false - } - def isDeprecatedIdentifier(tree: Tree): Boolean = tree match { - case x: Ident => !x.isBackquoted && nme.isDeprecatedIdentifierName(x.name) - case _ => false - } - - /** The first constructor definitions in `stats` */ - def firstConstructor(stats: List[Tree]): Tree = stats find { - case x: DefDef => nme.isConstructorName(x.name) - case _ => false - } getOrElse EmptyTree - - /** The arguments to the first constructor in `stats`. */ - def firstConstructorArgs(stats: List[Tree]): List[Tree] = firstConstructor(stats) match { - case DefDef(_, _, _, args :: _, _, _) => args - case _ => Nil - } - - /** The value definitions marked PRESUPER in this statement sequence */ - def preSuperFields(stats: List[Tree]): List[ValDef] = - stats collect { case vd: ValDef if isEarlyValDef(vd) => vd } - - def isEarlyDef(tree: Tree) = tree match { - case TypeDef(mods, _, _, _) => mods hasFlag PRESUPER - case ValDef(mods, _, _, _) => mods hasFlag PRESUPER - case _ => false - } - - def isEarlyValDef(tree: Tree) = tree match { - case ValDef(mods, _, _, _) => mods hasFlag PRESUPER - case _ => false - } - - def isEarlyTypeDef(tree: Tree) = tree match { - case TypeDef(mods, _, _, _) => mods hasFlag PRESUPER - case _ => false - } - - /** Is tpt a vararg type of the form T* ? */ - def isRepeatedParamType(tpt: Tree) = tpt match { - case TypeTree() => definitions.isRepeatedParamType(tpt.tpe) - case AppliedTypeTree(Select(_, tpnme.REPEATED_PARAM_CLASS_NAME), _) => true - case AppliedTypeTree(Select(_, tpnme.JAVA_REPEATED_PARAM_CLASS_NAME), _) => true - case _ => false - } - - /** The parameter ValDefs of a method definition that have vararg types of the form T* - */ - def repeatedParams(tree: Tree): List[ValDef] = tree match { - case DefDef(_, _, _, vparamss, _, _) => vparamss.flatten filter (vd => isRepeatedParamType(vd.tpt)) - case _ => Nil - } - - /** Is tpt a by-name parameter type of the form => T? */ - def isByNameParamType(tpt: Tree) = tpt match { - case TypeTree() => definitions.isByNameParamType(tpt.tpe) - case AppliedTypeTree(Select(_, tpnme.BYNAME_PARAM_CLASS_NAME), _) => true - case _ => false - } - - /** Is name a left-associative operator? */ - def isLeftAssoc(operator: Name) = operator.nonEmpty && (operator.endChar != ':') - - private val reserved = Set[Name](nme.false_, nme.true_, nme.null_) - - /** Is name a variable name? */ - def isVariableName(name: Name): Boolean = { - val first = name(0) - ((first.isLower && first.isLetter) || first == '_') && !reserved(name) - } - - /** Is tree a `this` node which belongs to `enclClass`? */ - def isSelf(tree: Tree, enclClass: Symbol): Boolean = tree match { - case This(_) => tree.symbol == enclClass - case _ => false - } - - /** can this type be a type pattern */ - def mayBeTypePat(tree: Tree): Boolean = tree match { - case CompoundTypeTree(Template(tps, _, Nil)) => tps exists mayBeTypePat - case Annotated(_, tp) => mayBeTypePat(tp) - case AppliedTypeTree(constr, args) => mayBeTypePat(constr) || args.exists(_.isInstanceOf[Bind]) - case SelectFromTypeTree(tp, _) => mayBeTypePat(tp) - case _ => false - } - - /** Is this tree comprised of nothing but identifiers, - * but possibly in bindings or tuples? For instance - * - * foo @ (bar, (baz, quux)) - * - * is a variable pattern; if the structure matches, - * then the remainder is inevitable. - */ - def isVariablePattern(tree: Tree): Boolean = tree match { - case Bind(name, pat) => isVariablePattern(pat) - case Ident(name) => true - case Apply(sel, args) => - ( isReferenceToScalaMember(sel, TupleClass(args.size).name.toTermName) - && (args forall isVariablePattern) - ) - case _ => false - } - - /** Is this argument node of the form <expr> : _* ? - */ - def isWildcardStarArg(tree: Tree): Boolean = tree match { - case Typed(_, Ident(tpnme.WILDCARD_STAR)) => true - case _ => false - } - - /** If this tree represents a type application (after unwrapping - * any applies) the first type argument. Otherwise, EmptyTree. - */ - def firstTypeArg(tree: Tree): Tree = tree match { - case Apply(fn, _) => firstTypeArg(fn) - case TypeApply(_, targ :: _) => targ - case _ => EmptyTree - } - - /** If this tree has type parameters, those. Otherwise Nil. - */ - def typeParameters(tree: Tree): List[TypeDef] = tree match { - case DefDef(_, _, tparams, _, _, _) => tparams - case ClassDef(_, _, tparams, _) => tparams - case TypeDef(_, _, tparams, _) => tparams - case _ => Nil - } - - /** Does this argument list end with an argument of the form <expr> : _* ? */ - def isWildcardStarArgList(trees: List[Tree]) = - trees.nonEmpty && isWildcardStarArg(trees.last) - - /** Is the argument a wildcard argument of the form `_` or `x @ _`? - */ - def isWildcardArg(tree: Tree): Boolean = unbind(tree) match { - case Ident(nme.WILDCARD) => true - case _ => false - } - - /** Is this pattern node a catch-all (wildcard or variable) pattern? */ - def isDefaultCase(cdef: CaseDef) = cdef match { - case CaseDef(pat, EmptyTree, _) => isWildcardArg(pat) - case _ => false - } - - /** Does this CaseDef catch Throwable? */ - def catchesThrowable(cdef: CaseDef) = catchesAllOf(cdef, ThrowableClass.tpe) - - /** Does this CaseDef catch everything of a certain Type? */ - def catchesAllOf(cdef: CaseDef, threshold: Type) = - isDefaultCase(cdef) || (cdef.guard.isEmpty && (unbind(cdef.pat) match { - case Typed(Ident(nme.WILDCARD), tpt) => (tpt.tpe != null) && (threshold <:< tpt.tpe) - case _ => false - })) - - /** Is this pattern node a catch-all or type-test pattern? */ - def isCatchCase(cdef: CaseDef) = cdef match { - case CaseDef(Typed(Ident(nme.WILDCARD), tpt), EmptyTree, _) => - isSimpleThrowable(tpt.tpe) - case CaseDef(Bind(_, Typed(Ident(nme.WILDCARD), tpt)), EmptyTree, _) => - isSimpleThrowable(tpt.tpe) - case _ => - isDefaultCase(cdef) - } - - private def isSimpleThrowable(tp: Type): Boolean = tp match { - case TypeRef(pre, sym, args) => - (pre == NoPrefix || pre.widen.typeSymbol.isStatic) && - (sym isNonBottomSubClass ThrowableClass) && /* bq */ !sym.isTrait - case _ => - false - } - - /* If we have run-time types, and these are used for pattern matching, - we should replace this by something like: - - tp match { - case TypeRef(pre, sym, args) => - args.isEmpty && (sym.owner.isPackageClass || isSimple(pre)) - case NoPrefix => - true - case _ => - false - } -*/ - - /** Is this pattern node a sequence-valued pattern? */ - def isSequenceValued(tree: Tree): Boolean = unbind(tree) match { - case Alternative(ts) => ts exists isSequenceValued - case ArrayValue(_, _) | Star(_) => true - case _ => false - } - - /** The underlying pattern ignoring any bindings */ - def unbind(x: Tree): Tree = x match { - case Bind(_, y) => unbind(y) - case y => y - } - - /** Is this tree a Star(_) after removing bindings? */ - def isStar(x: Tree) = unbind(x) match { - case Star(_) => true - case _ => false - } - - /** The method part of an application node - */ - def methPart(tree: Tree): Tree = tree match { - case Apply(fn, _) => methPart(fn) - case TypeApply(fn, _) => methPart(fn) - case AppliedTypeTree(fn, _) => methPart(fn) - case _ => tree - } - - /** The depth of the nested applies: e.g. Apply(Apply(Apply(_, _), _), _) - * has depth 3. Continues through type applications (without counting them.) - */ - def applyDepth(tree: Tree): Int = tree match { - case Apply(fn, _) => 1 + applyDepth(fn) - case TypeApply(fn, _) => applyDepth(fn) - case AppliedTypeTree(fn, _) => applyDepth(fn) - case _ => 0 - } - def firstArgument(tree: Tree): Tree = tree match { - case Apply(fn, args) => - val f = firstArgument(fn) - if (f == EmptyTree && !args.isEmpty) args.head else f - case _ => - EmptyTree - } - - /** Does list of trees start with a definition of - * a class of module with given name (ignoring imports) - */ - def firstDefinesClassOrObject(trees: List[Tree], name: Name): Boolean = trees match { - case Import(_, _) :: xs => firstDefinesClassOrObject(xs, name) - case Annotated(_, tree1) :: Nil => firstDefinesClassOrObject(List(tree1), name) - case ModuleDef(_, `name`, _) :: Nil => true - case ClassDef(_, `name`, _, _) :: Nil => true - case _ => false - } - - - /** Is this file the body of a compilation unit which should not - * have Predef imported? - */ - def noPredefImportForUnit(body: Tree) = { - // Top-level definition whose leading imports include Predef. - def containsLeadingPredefImport(defs: List[Tree]): Boolean = defs match { - case PackageDef(_, defs1) :: _ => containsLeadingPredefImport(defs1) - case Import(expr, _) :: rest => isReferenceToPredef(expr) || containsLeadingPredefImport(rest) - case _ => false - } - - // Compilation unit is class or object 'name' in package 'scala' - def isUnitInScala(tree: Tree, name: Name) = tree match { - case PackageDef(Ident(nme.scala_), defs) => firstDefinesClassOrObject(defs, name) - case _ => false - } - - ( isUnitInScala(body, nme.Predef) - || containsLeadingPredefImport(List(body))) - } - - def isAbsTypeDef(tree: Tree) = tree match { - case TypeDef(_, _, _, TypeBoundsTree(_, _)) => true - case TypeDef(_, _, _, rhs) => rhs.tpe.isInstanceOf[TypeBounds] - case _ => false - } - - def isAliasTypeDef(tree: Tree) = tree match { - case TypeDef(_, _, _, _) => !isAbsTypeDef(tree) - case _ => false - } - - /** Some handy extractors for spotting trees through the - * the haze of irrelevant braces: i.e. Block(Nil, SomeTree) - * should not keep us from seeing SomeTree. - */ - abstract class SeeThroughBlocks[T] { - protected def unapplyImpl(x: Tree): T - def unapply(x: Tree): T = x match { - case Block(Nil, expr) => unapply(expr) - case _ => unapplyImpl(x) - } - } - object IsTrue extends SeeThroughBlocks[Boolean] { - protected def unapplyImpl(x: Tree): Boolean = x match { - case Literal(Constant(true)) => true - case _ => false - } - } - object IsFalse extends SeeThroughBlocks[Boolean] { - protected def unapplyImpl(x: Tree): Boolean = x match { - case Literal(Constant(false)) => true - case _ => false - } - } - object IsIf extends SeeThroughBlocks[Option[(Tree, Tree, Tree)]] { - protected def unapplyImpl(x: Tree) = x match { - case If(cond, thenp, elsep) => Some((cond, thenp, elsep)) - case _ => None - } - } - - def isApplyDynamicName(name: Name) = (name == nme.updateDynamic) || (name == nme.selectDynamic) || (name == nme.applyDynamic) || (name == nme.applyDynamicNamed) - - class DynamicApplicationExtractor(nameTest: Name => Boolean) { - def unapply(tree: Tree) = tree match { - case Apply(TypeApply(Select(qual, oper), _), List(Literal(Constant(name)))) if nameTest(oper) => Some((qual, name)) - case Apply(Select(qual, oper), List(Literal(Constant(name)))) if nameTest(oper) => Some((qual, name)) - case Apply(Ident(oper), List(Literal(Constant(name)))) if nameTest(oper) => Some((EmptyTree, name)) - case _ => None - } - } - object DynamicUpdate extends DynamicApplicationExtractor(_ == nme.updateDynamic) - object DynamicApplication extends DynamicApplicationExtractor(isApplyDynamicName) - object DynamicApplicationNamed extends DynamicApplicationExtractor(_ == nme.applyDynamicNamed) -} diff --git a/src/compiler/scala/reflect/internal/TreePrinters.scala b/src/compiler/scala/reflect/internal/TreePrinters.scala deleted file mode 100644 index 6d035c8b9d..0000000000 --- a/src/compiler/scala/reflect/internal/TreePrinters.scala +++ /dev/null @@ -1,478 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - -// [Eugene++ to Martin] we need to unify this prettyprinter with NodePrinters - -package scala.reflect -package internal - -import java.io.{ OutputStream, PrintWriter, StringWriter, Writer } -import Flags._ - -trait TreePrinters extends api.TreePrinters { self: SymbolTable => - - //nsc import treeInfo.{ IsTrue, IsFalse } - - final val showOuterTests = false - - /** Adds backticks if the name is a scala keyword. */ - def quotedName(name: Name, decode: Boolean): String = { - val s = if (decode) name.decode else name.toString - val term = name.toTermName - if (nme.keywords(term) && term != nme.USCOREkw) "`%s`" format s - else s - } - def quotedName(name: Name): String = quotedName(name, false) - def quotedName(name: String): String = quotedName(newTermName(name), false) - - private def symNameInternal(tree: Tree, name: Name, decoded: Boolean): String = { - val sym = tree.symbol - if (sym.name.toString == nme.ERROR.toString) { - "<" + quotedName(name, decoded) + ": error>" - } else if (sym != null && sym != NoSymbol) { - val prefix = if (sym.isMixinConstructor) "/*%s*/".format(quotedName(sym.owner.name, decoded)) else "" - var suffix = "" - if (settings.uniqid.value) suffix += ("#" + sym.id) - if (settings.Yshowsymkinds.value) suffix += ("#" + sym.abbreviatedKindString) - prefix + quotedName(tree.symbol.decodedName) + suffix - } else { - quotedName(name, decoded) - } - } - - def decodedSymName(tree: Tree, name: Name) = symNameInternal(tree, name, true) - def symName(tree: Tree, name: Name) = symNameInternal(tree, name, false) - - /** Turns a path into a String, introducing backquotes - * as necessary. - */ - def backquotedPath(t: Tree): String = { - t match { - case Select(qual, name) if name.isTermName => "%s.%s".format(backquotedPath(qual), symName(t, name)) - case Select(qual, name) if name.isTypeName => "%s#%s".format(backquotedPath(qual), symName(t, name)) - case Ident(name) => symName(t, name) - case _ => t.toString - } - } - - class TreePrinter(out: PrintWriter) extends super.TreePrinter { - protected var indentMargin = 0 - protected val indentStep = 2 - protected var indentString = " " // 40 - - typesPrinted = settings.printtypes.value - uniqueIds = settings.uniqid.value - protected def doPrintPositions = settings.Xprintpos.value - - def indent() = indentMargin += indentStep - def undent() = indentMargin -= indentStep - - def printPosition(tree: Tree) = if (doPrintPositions) print(tree.pos.show) - - def println() { - out.println() - while (indentMargin > indentString.length()) - indentString += indentString - if (indentMargin > 0) - out.write(indentString, 0, indentMargin) - } - - def printSeq[a](ls: List[a])(printelem: a => Unit)(printsep: => Unit) { - ls match { - case List() => - case List(x) => printelem(x) - case x :: rest => printelem(x); printsep; printSeq(rest)(printelem)(printsep) - } - } - - 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) - } - - def printRow(ts: List[Tree], start: String, sep: String, end: String) { - print(start); printSeq(ts){print(_)}{print(sep)}; print(end) - } - - def printRow(ts: List[Tree], sep: String) { printRow(ts, "", sep, "") } - - def printTypeParams(ts: List[TypeDef]) { - if (!ts.isEmpty) { - print("["); printSeq(ts){ t => - printAnnotations(t) - printParam(t) - }{print(", ")}; print("]") - } - } - - def printLabelParams(ps: List[Ident]) { - print("(") - printSeq(ps){printLabelParam}{print(", ")} - print(")") - } - - def printLabelParam(p: Ident) { - print(symName(p, p.name)); printOpt(": ", TypeTree() setType p.tpe) - } - - def printValueParams(ts: List[ValDef]) { - print("(") - if (!ts.isEmpty) printFlags(ts.head.mods.flags & IMPLICIT, "") - printSeq(ts){printParam}{print(", ")} - print(")") - } - - def printParam(tree: Tree) { - tree match { - case ValDef(mods, name, tp, rhs) => - printPosition(tree) - printAnnotations(tree) - print(symName(tree, name)); printOpt(": ", tp); printOpt(" = ", rhs) - case TypeDef(mods, name, tparams, rhs) => - printPosition(tree) - print(symName(tree, name)) - printTypeParams(tparams); print(rhs) - } - } - - def printBlock(tree: Tree) { - tree match { - case Block(_, _) => - print(tree) - case _ => - printColumn(List(tree), "{", ";", "}") - } - } - - private def symFn[T](tree: Tree, f: Symbol => T, orElse: => T): T = tree.symbol match { - case null | NoSymbol => orElse - case sym => f(sym) - } - private def ifSym(tree: Tree, p: Symbol => Boolean) = symFn(tree, p, false) - - def printOpt(prefix: String, tree: Tree) { - if (!tree.isEmpty) { print(prefix, tree) } - } - - def printModifiers(tree: Tree, mods: Modifiers): Unit = printFlags( - if (tree.symbol == NoSymbol) mods.flags else tree.symbol.flags, "" + ( - if (tree.symbol == NoSymbol) mods.privateWithin - else if (tree.symbol.hasAccessBoundary) tree.symbol.privateWithin.name - else "" - ) - ) - - def printFlags(flags: Long, privateWithin: String) { - var mask: Long = if (settings.debug.value) -1L else PrintableFlags - val s = flagsToString(flags & mask, privateWithin) - if (s != "") print(s + " ") - } - - def printAnnotations(tree: Tree) { - if (!isCompilerUniverse && tree.symbol != null && tree.symbol != NoSymbol) - // [Eugene++] todo. this is not 100% correct, but is necessary for sane printing - // the problem is that getting annotations doesn't automatically initialize the symbol - // so we might easily print something as if it doesn't have annotations, whereas it does - tree.symbol.initialize - - val annots = tree.symbol.annotations match { - case Nil => tree.asInstanceOf[MemberDef].mods.annotations - case anns => anns - } - annots foreach (annot => print("@"+annot+" ")) - } - - private var currentOwner: Symbol = NoSymbol - private var selectorType: Type = NoType - - def printTree(tree: Tree) { - tree match { - case EmptyTree => - print("<empty>") - - case ClassDef(mods, name, tparams, impl) => - printAnnotations(tree) - printModifiers(tree, mods) - val word = - if (mods.isTrait) "trait" - else if (ifSym(tree, _.isModuleClass)) "object" - else "class" - - print(word, " ", symName(tree, name)) - printTypeParams(tparams) - print(if (mods.isDeferred) " <: " else " extends ", impl) - - case PackageDef(packaged, stats) => - printAnnotations(tree) - print("package ", packaged); printColumn(stats, " {", ";", "}") - - case ModuleDef(mods, name, impl) => - printAnnotations(tree) - 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 ", symName(tree, name)) - printOpt(": ", tp) - if (!mods.isDeferred) - print(" = ", if (rhs.isEmpty) "_" else rhs) - - case DefDef(mods, name, tparams, vparamss, tp, rhs) => - printAnnotations(tree) - printModifiers(tree, mods) - print("def " + symName(tree, name)) - printTypeParams(tparams); vparamss foreach printValueParams - printOpt(": ", tp); printOpt(" = ", rhs) - - case TypeDef(mods, name, tparams, rhs) => - if (mods hasFlag (PARAM | DEFERRED)) { - printAnnotations(tree) - printModifiers(tree, mods); print("type "); printParam(tree) - } else { - printAnnotations(tree) - printModifiers(tree, mods); print("type " + symName(tree, name)) - printTypeParams(tparams); printOpt(" = ", rhs) - } - - case LabelDef(name, params, rhs) => - print(symName(tree, name)); printLabelParams(params); printBlock(rhs) - - case Import(expr, selectors) => - // Is this selector remapping a name (i.e, {name1 => name2}) - def isNotRemap(s: ImportSelector) : Boolean = (s.name == nme.WILDCARD || s.name == s.rename) - def selectorToString(s: ImportSelector): String = { - val from = quotedName(s.name) - if (isNotRemap(s)) from - else from + "=>" + quotedName(s.rename) - } - 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("{", selectorToString(s), "}") - // If there is more than one selector braces are always needed - case many => - print(many.map(selectorToString).mkString("{", ", ", "}")) - } - - case Template(parents, self, body) => - val currentOwner1 = currentOwner - if (tree.symbol != NoSymbol) currentOwner = tree.symbol.owner -// if (parents exists isReferenceToAnyVal) { -// print("AnyVal") -// } -// else { - printRow(parents, " with ") - if (!body.isEmpty) { - if (self.name != nme.WILDCARD) { - print(" { ", self.name); printOpt(": ", self.tpt); print(" => ") - } else if (!self.tpt.isEmpty) { - print(" { _ : ", self.tpt, " => ") - } else { - print(" {") - } - printColumn(body, "", ";", "}") - } -// } - currentOwner = currentOwner1 - - case Block(stats, expr) => - printColumn(stats ::: List(expr), "{", ";", "}") - - case Match(selector, cases) => - val selectorType1 = selectorType - selectorType = selector.tpe - print(selector); printColumn(cases, " match {", "", "}") - selectorType = selectorType1 - - case CaseDef(pat, guard, body) => - print("case ") - def patConstr(pat: Tree): Tree = pat match { - case Apply(fn, args) => patConstr(fn) - case _ => pat - } - if (showOuterTests && - needsOuterTest( - patConstr(pat).tpe.finalResultType, selectorType, currentOwner)) - print("???") - print(pat); printOpt(" if ", guard) - print(" => ", body) - - case Alternative(trees) => - printRow(trees, "(", "| ", ")") - - case Star(elem) => - print("(", elem, ")*") - - case Bind(name, t) => - print("(", symName(tree, name), " @ ", t, ")") - - case UnApply(fun, args) => - print(fun, " <unapply> "); printRow(args, "(", ", ", ")") - - case ArrayValue(elemtpt, trees) => - print("Array[", elemtpt); printRow(trees, "]{", ", ", "}") - - case Function(vparams, body) => - print("("); printValueParams(vparams); print(" => ", body, ")") - if (uniqueIds && tree.symbol != null) print("#"+tree.symbol.id) - - case Assign(lhs, rhs) => - print(lhs, " = ", rhs) - - case AssignOrNamedArg(lhs, rhs) => - print(lhs, " = ", rhs) - - case If(cond, thenp, elsep) => - print("if (", cond, ")"); indent; println() - print(thenp); undent - if (!elsep.isEmpty) { - println(); print("else"); indent; println(); print(elsep); undent - } - - case Return(expr) => - print("return ", expr) - - case Try(block, catches, finalizer) => - print("try "); printBlock(block) - if (!catches.isEmpty) printColumn(catches, " catch {", "", "}") - printOpt(" finally ", finalizer) - - case Throw(expr) => - print("throw ", expr) - - case New(tpe) => - print("new ", tpe) - - case Typed(expr, tp) => - print("(", expr, ": ", tp, ")") - - case TypeApply(fun, targs) => - print(fun); printRow(targs, "[", ", ", "]") - - case Apply(fun, vargs) => - print(fun); printRow(vargs, "(", ", ", ")") - - case ApplyDynamic(qual, vargs) => - print("<apply-dynamic>(", qual, "#", tree.symbol.nameString) - printRow(vargs, ", (", ", ", "))") - - case Super(This(qual), mix) => - if (!qual.isEmpty || tree.symbol != NoSymbol) print(symName(tree, qual) + ".") - print("super") - if (!mix.isEmpty) - print("[" + mix + "]") - - case Super(qual, mix) => - print(qual, ".super") - if (!mix.isEmpty) - print("[" + mix + "]") - - case This(qual) => - if (!qual.isEmpty) print(symName(tree, qual) + ".") - print("this") - - case Select(qual @ New(tpe), name) if (!settings.debug.value) => - print(qual) - - case Select(qualifier, name) => - print(backquotedPath(qualifier), ".", symName(tree, name)) - - case id @ Ident(name) => - val str = symName(tree, name) - print( if (id.isBackquoted) "`" + str + "`" else str ) - - case Literal(x) => - print(x.escapedStringValue) - - case tt: TypeTree => - 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) - } else { - print(tree.tpe.toString) - } - - case Annotated(Apply(Select(New(tpt), nme.CONSTRUCTOR), args), tree) => - def printAnnot() { - print("@", tpt) - if (!args.isEmpty) - printRow(args, "(", ",", ")") - } - print(tree, if (tree.isType) " " else ": ") - printAnnot() - - case SingletonTypeTree(ref) => - print(ref, ".type") - - case SelectFromTypeTree(qualifier, selector) => - print(qualifier, "#", symName(tree, selector)) - - case CompoundTypeTree(templ) => - print(templ) - - case AppliedTypeTree(tp, args) => - print(tp); printRow(args, "[", ", ", "]") - - case TypeBoundsTree(lo, hi) => - printOpt(" >: ", lo); printOpt(" <: ", hi) - - case ExistentialTypeTree(tpt, whereClauses) => - print(tpt); - printColumn(whereClauses, " forSome { ", ";", "}") - -// SelectFromArray is no longer visible in reflect.internal. -// eliminated until we figure out what we will do with both TreePrinters and -// SelectFromArray. -// case SelectFromArray(qualifier, name, _) => -// print(qualifier); print(".<arr>"); print(symName(tree, name)) - - case tree => - xprintTree(this, tree) - } - if (typesPrinted && tree.isTerm && !tree.isEmpty) { - print("{", if (tree.tpe eq null) "<null>" else tree.tpe.toString, "}") - } - } - - def print(args: Any*): Unit = args foreach { - case tree: Tree => - printPosition(tree) - printTree(tree) - case name: Name => - print(quotedName(name)) - case arg => - out.print(if (arg == null) "null" else arg.toString) - } - } - - /** Hook for extensions */ - def xprintTree(treePrinter: TreePrinter, tree: Tree) = - treePrinter.print(tree.productPrefix+tree.productIterator.mkString("(", ", ", ")")) - - def newTreePrinter(writer: PrintWriter): TreePrinter = new TreePrinter(writer) - def newTreePrinter(stream: OutputStream): TreePrinter = newTreePrinter(new PrintWriter(stream)) - def newTreePrinter(): TreePrinter = newTreePrinter(new PrintWriter(ConsoleWriter)) - - /** A writer that writes to the current Console and - * is sensitive to replacement of the Console's - * output stream. - */ - object ConsoleWriter extends Writer { - override def write(str: String) { Console.print(str) } - - def write(cbuf: Array[Char], off: Int, len: Int) { - write(new String(cbuf, off, len)) - } - - def close = { /* do nothing */ } - def flush = { /* do nothing */ } - } -} diff --git a/src/compiler/scala/reflect/internal/Trees.scala b/src/compiler/scala/reflect/internal/Trees.scala deleted file mode 100644 index 11d0790100..0000000000 --- a/src/compiler/scala/reflect/internal/Trees.scala +++ /dev/null @@ -1,1592 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.reflect -package internal - -import Flags._ -import base.Attachments -import collection.mutable.{ListBuffer, LinkedHashSet} - -trait Trees extends api.Trees { self: SymbolTable => - - private[scala] var nodeCount = 0 - - abstract class Tree extends TreeContextApiImpl with Product { - val id = nodeCount // TODO: add to attachment? - nodeCount += 1 - - @inline final def pos: Position = rawatt.pos - def pos_=(pos: Position): Unit = rawatt = (rawatt withPos pos) - def setPos(newpos: Position): this.type = { pos = newpos; this } - - private var rawatt: Attachments { type Pos = Position } = NoPosition - def attachments = rawatt - def addAttachment(attachment: Any): this.type = { rawatt = rawatt.add(attachment); this } - def removeAttachment[T: ClassTag]: this.type = { rawatt = rawatt.remove[T]; this } - - private[this] var rawtpe: Type = _ - @inline final def tpe = rawtpe - def tpe_=(t: Type) = rawtpe = t - def setType(tp: Type): this.type = { rawtpe = tp; this } - def defineType(tp: Type): this.type = setType(tp) - - def symbol: Symbol = null - def symbol_=(sym: Symbol) { throw new UnsupportedOperationException("symbol_= inapplicable for " + this) } - def setSymbol(sym: Symbol): this.type = { symbol = sym; this } - def hasSymbol = false - - def isDef = false - - def isEmpty = false - - /** The canonical way to test if a Tree represents a term. - */ - def isTerm: Boolean = this match { - case _: TermTree => true - case Bind(name, _) => name.isTermName - case Select(_, name) => name.isTermName - case Ident(name) => name.isTermName - case Annotated(_, arg) => arg.isTerm - case _ => false - } - - /** The canonical way to test if a Tree represents a type. - */ - def isType: Boolean = this match { - case _: TypTree => true - case Bind(name, _) => name.isTypeName - case Select(_, name) => name.isTypeName - case Ident(name) => name.isTypeName - case Annotated(_, arg) => arg.isType - case _ => false - } - - private[scala] def copyAttrs(tree: Tree): this.type = { - rawatt = tree.rawatt - tpe = tree.tpe - if (hasSymbol) symbol = tree.symbol - this - } - - override def hashCode(): Int = System.identityHashCode(this) - override def equals(that: Any) = this eq that.asInstanceOf[AnyRef] - - override def duplicate: this.type = - (duplicator transform this).asInstanceOf[this.type] - } - - abstract class TreeContextApiImpl extends TreeContextApi { this: Tree => - - override def orElse(alt: => Tree) = if (!isEmpty) this else alt - - override def foreach(f: Tree => Unit) { new ForeachTreeTraverser(f).traverse(this) } - - override def withFilter(f: Tree => Boolean): List[Tree] = { - val ft = new FilterTreeTraverser(f) - ft.traverse(this) - ft.hits.toList - } - - override def filter(f: Tree => Boolean): List[Tree] = withFilter(f) - - override def collect[T](pf: PartialFunction[Tree, T]): List[T] = { - val ctt = new CollectTreeTraverser[T](pf) - ctt.traverse(this) - ctt.results.toList - } - - override def find(p: Tree => Boolean): Option[Tree] = { - val ft = new FindTreeTraverser(p) - ft.traverse(this) - ft.result - } - - override def exists(p: Tree => Boolean): Boolean = !find(p).isEmpty - - override def forAll(p: Tree => Boolean): Boolean = find(!p(_)).isEmpty - - override def equalsStructure(that : Tree) = correspondsStructure(that)(_ eq _) - - def correspondsStructure(that: Tree)(f: (Tree,Tree) => Boolean): Boolean = - f(this, that) || ((productArity == that.productArity) && { - def equals0(this0: Any, that0: Any): Boolean = (this0, that0) match { - case (x: Tree, y: Tree) => f(x, y) || (x correspondsStructure y)(f) - case (xs: List[_], ys: List[_]) => (xs corresponds ys)(equals0) - case _ => this0 == that0 - } - def compareOriginals() = (this, that) match { - case (x: TypeTree, y: TypeTree) if x.original != null && y.original != null => - (x.original correspondsStructure y.original)(f) - case _ => - true - } - - (productIterator zip that.productIterator forall { case (x, y) => equals0(x, y) }) && compareOriginals() - }) - - override def children: List[Tree] = { - def subtrees(x: Any): List[Tree] = x match { - case EmptyTree => Nil - case t: Tree => List(t) - case xs: List[_] => xs flatMap subtrees - case _ => Nil - } - productIterator.toList flatMap subtrees - } - - override def freeTerms: List[FreeTermSymbol] = freeSyms[FreeTermSymbol](_.isFreeTerm, _.termSymbol) - override def freeTypes: List[FreeTypeSymbol] = freeSyms[FreeTypeSymbol](_.isFreeType, _.typeSymbol) - - private def freeSyms[S <: Symbol](isFree: Symbol => Boolean, symOfType: Type => Symbol): List[S] = { - val s = collection.mutable.LinkedHashSet[S]() - def addIfFree(sym: Symbol): Unit = if (sym != null && isFree(sym)) s += sym.asInstanceOf[S] - for (t <- this) { - addIfFree(t.symbol) - if (t.tpe != null) { - for (tp <- t.tpe) { - addIfFree(symOfType(tp)) - } - } - } - s.toList - } - - override def substituteSymbols(from: List[Symbol], to: List[Symbol]): Tree = - new TreeSymSubstituter(from, to)(this) - - override def substituteTypes(from: List[Symbol], to: List[Type]): Tree = - new TreeTypeSubstituter(from, to)(this) - - override def substituteThis(clazz: Symbol, to: Tree): Tree = - new ThisSubstituter(clazz, to) transform this - - def hasSymbolWhich(f: Symbol => Boolean) = - hasSymbol && symbol != null && f(symbol) - - def isErroneous = (tpe ne null) && tpe.isErroneous - def isTyped = (tpe ne null) && !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 (tpe eq null) this - else this setType f(tpe) - - /** If `pf` is defined for a given subtree, call super.traverse(pf(tree)), - * otherwise super.traverse(tree). - */ - def foreachPartial(pf: PartialFunction[Tree, Tree]) { - new ForeachPartialTreeTraverser(pf).traverse(this) - } - - def changeOwner(pairs: (Symbol, Symbol)*): Tree = { - pairs.foldLeft(this) { case (t, (oldOwner, newOwner)) => - new ChangeOwnerTraverser(oldOwner, newOwner) apply t - } - } - - def shallowDuplicate: Tree = new ShallowDuplicator(this) transform this - def shortClass: String = (getClass.getName split "[.$]").last - - def isErrorTyped = (tpe ne null) && tpe.isError - - /** When you want to know a little more than the class, but a lot - * less than the whole tree. - */ - def summaryString: String = this match { - case Literal(const) => "Literal(" + const + ")" - case Ident(name) => "Ident(%s)".format(name.decode) - case Select(qual, name) => "Select(%s, %s)".format(qual.summaryString, name.decode) - case t: NameTree => t.name.longString - case t => - t.shortClass + ( - if (t.symbol != null && t.symbol != NoSymbol) "(" + t.symbol + ")" - else "" - ) - } - } - - trait TermTree extends Tree with TermTreeApi - - trait TypTree extends Tree with TypTreeApi - - trait SymTree extends Tree with SymTreeContextApi { - override def hasSymbol = true - override var symbol: Symbol = NoSymbol - } - - trait NameTree extends Tree with NameTreeApi { - def name: Name - } - - trait RefTree extends SymTree with NameTree with RefTreeApi { - def qualifier: Tree // empty for Idents - def name: Name - } - - abstract class DefTree extends SymTree with NameTree with DefTreeApi { - def name: Name - override def isDef = true - } - - case object EmptyTree extends TermTree { - super.tpe_=(NoType) - override def tpe_=(t: Type) = - if (t != NoType) throw new UnsupportedOperationException("tpe_=("+t+") inapplicable for <empty>") - override def isEmpty = true - } - - abstract class MemberDef extends DefTree with MemberDefApi { - def mods: Modifiers - def keyword: String = this match { - case TypeDef(_, _, _, _) => "type" - case ClassDef(mods, _, _, _) => if (mods hasFlag TRAIT) "trait" else "class" - case DefDef(_, _, _, _, _, _) => "def" - case ModuleDef(_, _, _) => "object" - case PackageDef(_, _) => "package" - case ValDef(mods, _, _, _) => if (mods hasFlag MUTABLE) "var" else "val" - case _ => "" - } - } - - case class PackageDef(pid: RefTree, stats: List[Tree]) - extends MemberDef with PackageDefApi { - def name = pid.name - def mods = NoMods - } - object PackageDef extends PackageDefExtractor - - abstract class ImplDef extends MemberDef with ImplDefApi { - def impl: Template - } - - case class ClassDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], impl: Template) - extends ImplDef with ClassDefApi - object ClassDef extends ClassDefExtractor - - case class ModuleDef(mods: Modifiers, name: TermName, impl: Template) - extends ImplDef with ModuleDefApi - object ModuleDef extends ModuleDefExtractor - - abstract class ValOrDefDef extends MemberDef with ValOrDefDefApi { - def name: Name - def tpt: Tree - def rhs: Tree - } - - case class ValDef(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree) extends ValOrDefDef with ValDefApi - object ValDef extends ValDefExtractor - - case class DefDef(mods: Modifiers, name: Name, tparams: List[TypeDef], - vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) extends ValOrDefDef with DefDefApi - object DefDef extends DefDefExtractor - - case class TypeDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], rhs: Tree) - extends MemberDef with TypeDefApi - object TypeDef extends TypeDefExtractor - - case class LabelDef(name: TermName, params: List[Ident], rhs: Tree) - extends DefTree with TermTree with LabelDefApi - object LabelDef extends LabelDefExtractor - - case class ImportSelector(name: Name, namePos: Int, rename: Name, renamePos: Int) extends ImportSelectorApi - object ImportSelector extends ImportSelectorExtractor - - case class Import(expr: Tree, selectors: List[ImportSelector]) - extends SymTree with ImportApi - object Import extends ImportExtractor - - case class Template(parents: List[Tree], self: ValDef, body: List[Tree]) - extends SymTree with TemplateApi - object Template extends TemplateExtractor - - case class Block(stats: List[Tree], expr: Tree) - extends TermTree with BlockApi - object Block extends BlockExtractor - - case class CaseDef(pat: Tree, guard: Tree, body: Tree) - extends Tree with CaseDefApi - object CaseDef extends CaseDefExtractor - - case class Alternative(trees: List[Tree]) - extends TermTree with AlternativeApi - object Alternative extends AlternativeExtractor - - case class Star(elem: Tree) - extends TermTree with StarApi - object Star extends StarExtractor - - case class Bind(name: Name, body: Tree) - extends DefTree with BindApi - object Bind extends BindExtractor - - case class UnApply(fun: Tree, args: List[Tree]) - extends TermTree with UnApplyApi - object UnApply extends UnApplyExtractor - - case class ArrayValue(elemtpt: Tree, elems: List[Tree]) - extends TermTree with ArrayValueApi - object ArrayValue extends ArrayValueExtractor - - case class Function(vparams: List[ValDef], body: Tree) - extends TermTree with SymTree with FunctionApi - object Function extends FunctionExtractor - - case class Assign(lhs: Tree, rhs: Tree) - extends TermTree with AssignApi - object Assign extends AssignExtractor - - case class AssignOrNamedArg(lhs: Tree, rhs: Tree) - extends TermTree with AssignOrNamedArgApi - object AssignOrNamedArg extends AssignOrNamedArgExtractor - - case class If(cond: Tree, thenp: Tree, elsep: Tree) - extends TermTree with IfApi - object If extends IfExtractor - - case class Match(selector: Tree, cases: List[CaseDef]) - extends TermTree with MatchApi - object Match extends MatchExtractor - - case class Return(expr: Tree) - extends TermTree with SymTree with ReturnApi - object Return extends ReturnExtractor - - case class Try(block: Tree, catches: List[CaseDef], finalizer: Tree) - extends TermTree with TryApi - object Try extends TryExtractor - - case class Throw(expr: Tree) - extends TermTree with ThrowApi - object Throw extends ThrowExtractor - - case class New(tpt: Tree) extends TermTree with NewApi - object New extends NewExtractor - - case class Typed(expr: Tree, tpt: Tree) - extends TermTree with TypedApi - object Typed extends TypedExtractor - - abstract class GenericApply extends TermTree with GenericApplyApi { - val fun: Tree - val args: List[Tree] - } - - case class TypeApply(fun: Tree, args: List[Tree]) - extends GenericApply with TypeApplyApi { - override def symbol: Symbol = fun.symbol - override def symbol_=(sym: Symbol) { fun.symbol = sym } - } - object TypeApply extends TypeApplyExtractor - - case class Apply(fun: Tree, args: List[Tree]) - extends GenericApply with ApplyApi { - override def symbol: Symbol = fun.symbol - override def symbol_=(sym: Symbol) { fun.symbol = sym } - } - object Apply extends ApplyExtractor - - // TODO remove this class, add a tree attachment to Apply to track whether implicits were involved - // copying trees will all too easily forget to distinguish subclasses - class ApplyToImplicitArgs(fun: Tree, args: List[Tree]) extends Apply(fun, args) - - // TODO remove this class, add a tree attachment to Apply to track whether implicits were involved - // copying trees will all too easily forget to distinguish subclasses - class ApplyImplicitView(fun: Tree, args: List[Tree]) extends Apply(fun, args) - - def ApplyConstructor(tpt: Tree, args: List[Tree]) = Apply(Select(New(tpt), nme.CONSTRUCTOR), args) - - case class ApplyDynamic(qual: Tree, args: List[Tree]) - extends TermTree with SymTree with ApplyDynamicApi - object ApplyDynamic extends ApplyDynamicExtractor - - case class Super(qual: Tree, mix: TypeName) extends TermTree with SuperApi { - override def symbol: Symbol = qual.symbol - override def symbol_=(sym: Symbol) { qual.symbol = sym } - } - object Super extends SuperExtractor - - case class This(qual: TypeName) - extends TermTree with SymTree with ThisApi - object This extends ThisExtractor - - case class Select(qualifier: Tree, name: Name) - extends RefTree with SelectApi - object Select extends SelectExtractor - - case class Ident(name: Name) extends RefTree with IdentContextApi { - def qualifier: Tree = EmptyTree - def isBackquoted = this.attachments.get[BackquotedIdentifierAttachment.type].isDefined - } - object Ident extends IdentExtractor - - case class ReferenceToBoxed(ident: Ident) extends TermTree with ReferenceToBoxedApi { - override def symbol: Symbol = ident.symbol - override def symbol_=(sym: Symbol) { ident.symbol = sym } - } - object ReferenceToBoxed extends ReferenceToBoxedExtractor - - case class Literal(value: Constant) - extends TermTree with LiteralApi { - assert(value ne null) - } - object Literal extends LiteralExtractor - -// @deprecated("will be removed and then be re-introduced with changed semantics, use Literal(Constant(x)) instead") -// def Literal(x: Any) = new Literal(Constant(x)) - - case class Annotated(annot: Tree, arg: Tree) extends Tree with AnnotatedApi - object Annotated extends AnnotatedExtractor - - case class SingletonTypeTree(ref: Tree) - extends TypTree with SingletonTypeTreeApi - object SingletonTypeTree extends SingletonTypeTreeExtractor - - case class SelectFromTypeTree(qualifier: Tree, name: TypeName) - extends TypTree with RefTree with SelectFromTypeTreeApi - object SelectFromTypeTree extends SelectFromTypeTreeExtractor - - case class CompoundTypeTree(templ: Template) - extends TypTree with CompoundTypeTreeApi - object CompoundTypeTree extends CompoundTypeTreeExtractor - - case class AppliedTypeTree(tpt: Tree, args: List[Tree]) - extends TypTree with AppliedTypeTreeApi { - override def symbol: Symbol = tpt.symbol - override def symbol_=(sym: Symbol) { tpt.symbol = sym } - } - object AppliedTypeTree extends AppliedTypeTreeExtractor - - case class TypeBoundsTree(lo: Tree, hi: Tree) - extends TypTree with TypeBoundsTreeApi - object TypeBoundsTree extends TypeBoundsTreeExtractor - - case class ExistentialTypeTree(tpt: Tree, whereClauses: List[Tree]) - extends TypTree with ExistentialTypeTreeApi - object ExistentialTypeTree extends ExistentialTypeTreeExtractor - - case class TypeTree() extends TypTree with TypeTreeContextApi { - private var orig: Tree = null - private[scala] var wasEmpty: Boolean = false - - override def symbol = if (tpe == null) null else tpe.typeSymbol - override def isEmpty = (tpe eq null) || tpe == NoType - - def original: Tree = orig - def setOriginal(tree: Tree): this.type = { - def followOriginal(t: Tree): Tree = t match { - case tt: TypeTree => followOriginal(tt.original) - case t => t - } - - orig = followOriginal(tree); setPos(tree.pos); - this - } - - override def defineType(tp: Type): this.type = { - wasEmpty = isEmpty - setType(tp) - } - } - object TypeTree extends TypeTreeExtractor - - def TypeTree(tp: Type): TypeTree = TypeTree() setType tp - - class StrictTreeCopier extends TreeCopierOps { - def ClassDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], impl: Template) = - new ClassDef(mods, name.toTypeName, tparams, impl).copyAttrs(tree) - def PackageDef(tree: Tree, pid: RefTree, stats: List[Tree]) = - new PackageDef(pid, stats).copyAttrs(tree) - def ModuleDef(tree: Tree, mods: Modifiers, name: Name, impl: Template) = - new ModuleDef(mods, name.toTermName, impl).copyAttrs(tree) - def ValDef(tree: Tree, mods: Modifiers, name: Name, tpt: Tree, rhs: Tree) = - new ValDef(mods, name.toTermName, tpt, rhs).copyAttrs(tree) - def DefDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) = - new DefDef(mods, name.toTermName, tparams, vparamss, tpt, rhs).copyAttrs(tree) - def TypeDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], rhs: Tree) = - new TypeDef(mods, name.toTypeName, tparams, rhs).copyAttrs(tree) - def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree) = - new LabelDef(name.toTermName, params, rhs).copyAttrs(tree) - def Import(tree: Tree, expr: Tree, selectors: List[ImportSelector]) = - new Import(expr, selectors).copyAttrs(tree) - def Template(tree: Tree, parents: List[Tree], self: ValDef, body: List[Tree]) = - new Template(parents, self, body).copyAttrs(tree) - def Block(tree: Tree, stats: List[Tree], expr: Tree) = - new Block(stats, expr).copyAttrs(tree) - def CaseDef(tree: Tree, pat: Tree, guard: Tree, body: Tree) = - new CaseDef(pat, guard, body).copyAttrs(tree) - def Alternative(tree: Tree, trees: List[Tree]) = - new Alternative(trees).copyAttrs(tree) - def Star(tree: Tree, elem: Tree) = - new Star(elem).copyAttrs(tree) - def Bind(tree: Tree, name: Name, body: Tree) = - new Bind(name, body).copyAttrs(tree) - def UnApply(tree: Tree, fun: Tree, args: List[Tree]) = - new UnApply(fun, args).copyAttrs(tree) - def ArrayValue(tree: Tree, elemtpt: Tree, trees: List[Tree]) = - new ArrayValue(elemtpt, trees).copyAttrs(tree) - def Function(tree: Tree, vparams: List[ValDef], body: Tree) = - new Function(vparams, body).copyAttrs(tree) - def Assign(tree: Tree, lhs: Tree, rhs: Tree) = - new Assign(lhs, rhs).copyAttrs(tree) - def AssignOrNamedArg(tree: Tree, lhs: Tree, rhs: Tree) = - new AssignOrNamedArg(lhs, rhs).copyAttrs(tree) - def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree) = - new If(cond, thenp, elsep).copyAttrs(tree) - def Match(tree: Tree, selector: Tree, cases: List[CaseDef]) = - new Match(selector, cases).copyAttrs(tree) - def Return(tree: Tree, expr: Tree) = - new Return(expr).copyAttrs(tree) - def Try(tree: Tree, block: Tree, catches: List[CaseDef], finalizer: Tree) = - new Try(block, catches, finalizer).copyAttrs(tree) - def Throw(tree: Tree, expr: Tree) = - new Throw(expr).copyAttrs(tree) - def New(tree: Tree, tpt: Tree) = - new New(tpt).copyAttrs(tree) - def Typed(tree: Tree, expr: Tree, tpt: Tree) = - new Typed(expr, tpt).copyAttrs(tree) - def TypeApply(tree: Tree, fun: Tree, args: List[Tree]) = - new TypeApply(fun, args).copyAttrs(tree) - def Apply(tree: Tree, fun: Tree, args: List[Tree]) = - (tree match { // TODO: use a tree attachment to track whether this is an apply to implicit args or a view - case _: ApplyToImplicitArgs => new ApplyToImplicitArgs(fun, args) - case _: ApplyImplicitView => new ApplyImplicitView(fun, args) - // TODO: ApplyConstructor ??? - case _ => new Apply(fun, args) - }).copyAttrs(tree) - def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]) = - new ApplyDynamic(qual, args).copyAttrs(tree) - def Super(tree: Tree, qual: Tree, mix: TypeName) = - new Super(qual, mix).copyAttrs(tree) - def This(tree: Tree, qual: Name) = - new This(qual.toTypeName).copyAttrs(tree) - def Select(tree: Tree, qualifier: Tree, selector: Name) = - new Select(qualifier, selector).copyAttrs(tree) - def Ident(tree: Tree, name: Name) = - new Ident(name) copyAttrs tree - def ReferenceToBoxed(tree: Tree, idt: Ident) = - new ReferenceToBoxed(idt).copyAttrs(tree) - def Literal(tree: Tree, value: Constant) = - new Literal(value).copyAttrs(tree) - def TypeTree(tree: Tree) = - new TypeTree().copyAttrs(tree) - def Annotated(tree: Tree, annot: Tree, arg: Tree) = - new Annotated(annot, arg).copyAttrs(tree) - def SingletonTypeTree(tree: Tree, ref: Tree) = - new SingletonTypeTree(ref).copyAttrs(tree) - def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name) = - new SelectFromTypeTree(qualifier, selector.toTypeName).copyAttrs(tree) - def CompoundTypeTree(tree: Tree, templ: Template) = - new CompoundTypeTree(templ).copyAttrs(tree) - def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree]) = - new AppliedTypeTree(tpt, args).copyAttrs(tree) - def TypeBoundsTree(tree: Tree, lo: Tree, hi: Tree) = - new TypeBoundsTree(lo, hi).copyAttrs(tree) - def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]) = - new ExistentialTypeTree(tpt, whereClauses).copyAttrs(tree) - } - - class LazyTreeCopier extends TreeCopierOps { - val treeCopy: TreeCopier = newStrictTreeCopier - def ClassDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], impl: Template) = tree match { - case t @ ClassDef(mods0, name0, tparams0, impl0) - if (mods0 == mods) && (name0 == name) && (tparams0 == tparams) && (impl0 == impl) => t - case _ => treeCopy.ClassDef(tree, mods, name, tparams, impl) - } - def PackageDef(tree: Tree, pid: RefTree, stats: List[Tree]) = tree match { - case t @ PackageDef(pid0, stats0) - if (pid0 == pid) && (stats0 == stats) => t - case _ => treeCopy.PackageDef(tree, pid, stats) - } - def ModuleDef(tree: Tree, mods: Modifiers, name: Name, impl: Template) = tree match { - case t @ ModuleDef(mods0, name0, impl0) - if (mods0 == mods) && (name0 == name) && (impl0 == impl) => t - case _ => treeCopy.ModuleDef(tree, mods, name, impl) - } - def ValDef(tree: Tree, mods: Modifiers, name: Name, tpt: Tree, rhs: Tree) = tree match { - case t @ ValDef(mods0, name0, tpt0, rhs0) - if (mods0 == mods) && (name0 == name) && (tpt0 == tpt) && (rhs0 == rhs) => t - case _ => treeCopy.ValDef(tree, mods, name, tpt, rhs) - } - def DefDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) = tree match { - case t @ DefDef(mods0, name0, tparams0, vparamss0, tpt0, rhs0) - if (mods0 == mods) && (name0 == name) && (tparams0 == tparams) && - (vparamss0 == vparamss) && (tpt0 == tpt) && (rhs == rhs0) => t - case _ => treeCopy.DefDef(tree, mods, name, tparams, vparamss, tpt, rhs) - } - def TypeDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], rhs: Tree) = tree match { - case t @ TypeDef(mods0, name0, tparams0, rhs0) - if (mods0 == mods) && (name0 == name) && (tparams0 == tparams) && (rhs0 == rhs) => t - case _ => treeCopy.TypeDef(tree, mods, name, tparams, rhs) - } - def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree) = tree match { - case t @ LabelDef(name0, params0, rhs0) - if (name0 == name) && (params0 == params) && (rhs0 == rhs) => t - case _ => treeCopy.LabelDef(tree, name, params, rhs) - } - def Import(tree: Tree, expr: Tree, selectors: List[ImportSelector]) = tree match { - case t @ Import(expr0, selectors0) - if (expr0 == expr) && (selectors0 == selectors) => t - case _ => treeCopy.Import(tree, expr, selectors) - } - def Template(tree: Tree, parents: List[Tree], self: ValDef, body: List[Tree]) = tree match { - case t @ Template(parents0, self0, body0) - if (parents0 == parents) && (self0 == self) && (body0 == body) => t - case _ => treeCopy.Template(tree, parents, self, body) - } - def Block(tree: Tree, stats: List[Tree], expr: Tree) = tree match { - case t @ Block(stats0, expr0) - if ((stats0 == stats) && (expr0 == expr)) => t - case _ => treeCopy.Block(tree, stats, expr) - } - def CaseDef(tree: Tree, pat: Tree, guard: Tree, body: Tree) = tree match { - case t @ CaseDef(pat0, guard0, body0) - if (pat0 == pat) && (guard0 == guard) && (body0 == body) => t - case _ => treeCopy.CaseDef(tree, pat, guard, body) - } - def Alternative(tree: Tree, trees: List[Tree]) = tree match { - case t @ Alternative(trees0) - if trees0 == trees => t - case _ => treeCopy.Alternative(tree, trees) - } - def Star(tree: Tree, elem: Tree) = tree match { - case t @ Star(elem0) - if elem0 == elem => t - case _ => treeCopy.Star(tree, elem) - } - def Bind(tree: Tree, name: Name, body: Tree) = tree match { - case t @ Bind(name0, body0) - if (name0 == name) && (body0 == body) => t - case _ => treeCopy.Bind(tree, name, body) - } - def UnApply(tree: Tree, fun: Tree, args: List[Tree]) = tree match { - case t @ UnApply(fun0, args0) - if (fun0 == fun) && (args0 == args) => t - case _ => treeCopy.UnApply(tree, fun, args) - } - def ArrayValue(tree: Tree, elemtpt: Tree, trees: List[Tree]) = tree match { - case t @ ArrayValue(elemtpt0, trees0) - if (elemtpt0 == elemtpt) && (trees0 == trees) => t - case _ => treeCopy.ArrayValue(tree, elemtpt, trees) - } - def Function(tree: Tree, vparams: List[ValDef], body: Tree) = tree match { - case t @ Function(vparams0, body0) - if (vparams0 == vparams) && (body0 == body) => t - case _ => treeCopy.Function(tree, vparams, body) - } - def Assign(tree: Tree, lhs: Tree, rhs: Tree) = tree match { - case t @ Assign(lhs0, rhs0) - if (lhs0 == lhs) && (rhs0 == rhs) => t - case _ => treeCopy.Assign(tree, lhs, rhs) - } - def AssignOrNamedArg(tree: Tree, lhs: Tree, rhs: Tree) = tree match { - case t @ AssignOrNamedArg(lhs0, rhs0) - if (lhs0 == lhs) && (rhs0 == rhs) => t - case _ => treeCopy.AssignOrNamedArg(tree, lhs, rhs) - } - def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree) = tree match { - case t @ If(cond0, thenp0, elsep0) - if (cond0 == cond) && (thenp0 == thenp) && (elsep0 == elsep) => t - case _ => treeCopy.If(tree, cond, thenp, elsep) - } - def Match(tree: Tree, selector: Tree, cases: List[CaseDef]) = tree match { - case t @ Match(selector0, cases0) - if (selector0 == selector) && (cases0 == cases) => t - case _ => treeCopy.Match(tree, selector, cases) - } - def Return(tree: Tree, expr: Tree) = tree match { - case t @ Return(expr0) - if expr0 == expr => t - case _ => treeCopy.Return(tree, expr) - } - def Try(tree: Tree, block: Tree, catches: List[CaseDef], finalizer: Tree) = tree match { - case t @ Try(block0, catches0, finalizer0) - if (block0 == block) && (catches0 == catches) && (finalizer0 == finalizer) => t - case _ => treeCopy.Try(tree, block, catches, finalizer) - } - def Throw(tree: Tree, expr: Tree) = tree match { - case t @ Throw(expr0) - if expr0 == expr => t - case _ => treeCopy.Throw(tree, expr) - } - def New(tree: Tree, tpt: Tree) = tree match { - case t @ New(tpt0) - if tpt0 == tpt => t - case _ => treeCopy.New(tree, tpt) - } - def Typed(tree: Tree, expr: Tree, tpt: Tree) = tree match { - case t @ Typed(expr0, tpt0) - if (expr0 == expr) && (tpt0 == tpt) => t - case _ => treeCopy.Typed(tree, expr, tpt) - } - def TypeApply(tree: Tree, fun: Tree, args: List[Tree]) = tree match { - case t @ TypeApply(fun0, args0) - if (fun0 == fun) && (args0 == args) => t - case _ => treeCopy.TypeApply(tree, fun, args) - } - def Apply(tree: Tree, fun: Tree, args: List[Tree]) = tree match { - case t @ Apply(fun0, args0) - if (fun0 == fun) && (args0 == args) => t - case _ => treeCopy.Apply(tree, fun, args) - } - def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]) = tree match { - case t @ ApplyDynamic(qual0, args0) - if (qual0 == qual) && (args0 == args) => t - case _ => treeCopy.ApplyDynamic(tree, qual, args) - } - def Super(tree: Tree, qual: Tree, mix: TypeName) = tree match { - case t @ Super(qual0, mix0) - if (qual0 == qual) && (mix0 == mix) => t - case _ => treeCopy.Super(tree, qual, mix) - } - def This(tree: Tree, qual: Name) = tree match { - case t @ This(qual0) - if qual0 == qual => t - case _ => treeCopy.This(tree, qual) - } - def Select(tree: Tree, qualifier: Tree, selector: Name) = tree match { - case t @ Select(qualifier0, selector0) - if (qualifier0 == qualifier) && (selector0 == selector) => t - case _ => treeCopy.Select(tree, qualifier, selector) - } - def Ident(tree: Tree, name: Name) = tree match { - case t @ Ident(name0) - if name0 == name => t - case _ => treeCopy.Ident(tree, name) - } - def ReferenceToBoxed(tree: Tree, idt: Ident) = tree match { - case t @ ReferenceToBoxed(idt0) - if (idt0 == idt) => t - case _ => this.treeCopy.ReferenceToBoxed(tree, idt) - } - def Literal(tree: Tree, value: Constant) = tree match { - case t @ Literal(value0) - if value0 == value => t - case _ => treeCopy.Literal(tree, value) - } - def TypeTree(tree: Tree) = tree match { - case t @ TypeTree() => t - case _ => treeCopy.TypeTree(tree) - } - def Annotated(tree: Tree, annot: Tree, arg: Tree) = tree match { - case t @ Annotated(annot0, arg0) - if (annot0==annot) => t - case _ => treeCopy.Annotated(tree, annot, arg) - } - def SingletonTypeTree(tree: Tree, ref: Tree) = tree match { - case t @ SingletonTypeTree(ref0) - if ref0 == ref => t - case _ => treeCopy.SingletonTypeTree(tree, ref) - } - def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name) = tree match { - case t @ SelectFromTypeTree(qualifier0, selector0) - if (qualifier0 == qualifier) && (selector0 == selector) => t - case _ => treeCopy.SelectFromTypeTree(tree, qualifier, selector) - } - def CompoundTypeTree(tree: Tree, templ: Template) = tree match { - case t @ CompoundTypeTree(templ0) - if templ0 == templ => t - case _ => treeCopy.CompoundTypeTree(tree, templ) - } - def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree]) = tree match { - case t @ AppliedTypeTree(tpt0, args0) - if (tpt0 == tpt) && (args0 == args) => t - case _ => treeCopy.AppliedTypeTree(tree, tpt, args) - } - def TypeBoundsTree(tree: Tree, lo: Tree, hi: Tree) = tree match { - case t @ TypeBoundsTree(lo0, hi0) - if (lo0 == lo) && (hi0 == hi) => t - case _ => treeCopy.TypeBoundsTree(tree, lo, hi) - } - def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]) = tree match { - case t @ ExistentialTypeTree(tpt0, whereClauses0) - if (tpt0 == tpt) && (whereClauses0 == whereClauses) => t - case _ => treeCopy.ExistentialTypeTree(tree, tpt, whereClauses) - } - } - - // Belongs in TreeInfo but then I can't reach it from TreePrinters. - def isReferenceToScalaMember(t: Tree, Id: Name) = t match { - case Ident(Id) => true - case Select(Ident(nme.scala_), Id) => true - case Select(Select(Ident(nme.ROOTPKG), nme.scala_), Id) => true - case _ => false - } - /** Is the tree Predef, scala.Predef, or _root_.scala.Predef? - */ - def isReferenceToPredef(t: Tree) = isReferenceToScalaMember(t, nme.Predef) - def isReferenceToAnyVal(t: Tree) = isReferenceToScalaMember(t, tpnme.AnyVal) - - // --- modifiers implementation --------------------------------------- - - /** @param privateWithin the qualifier for a private (a type name) - * or tpnme.EMPTY, if none is given. - * @param annotations the annotations for the definition. - * '''Note:''' the typechecker drops these annotations, - * use the AnnotationInfo's (Symbol.annotations) in later phases. - */ - case class Modifiers(flags: Long, - privateWithin: Name, - annotations: List[Tree]) extends ModifiersApi with HasFlags { - - var positions: Map[Long, Position] = Map() - - def setPositions(poss: Map[Long, Position]): this.type = { - positions = poss; this - } - - /* Abstract types from HasFlags. */ - type AccessBoundaryType = Name - type AnnotationType = Tree - - def hasAnnotationNamed(name: TypeName) = { - annotations exists { - case Apply(Select(New(Ident(`name`)), _), _) => true - case Apply(Select(New(Select(_, `name`)), _), _) => true - case _ => false - } - } - - def hasAccessBoundary = privateWithin != tpnme.EMPTY - def hasAllFlags(mask: Long): Boolean = (flags & mask) == mask - def hasFlag(flag: Long) = (flag & flags) != 0L - - def & (flag: Long): Modifiers = { - val flags1 = flags & flag - if (flags1 == flags) this - else Modifiers(flags1, privateWithin, annotations) setPositions positions - } - def &~ (flag: Long): Modifiers = { - val flags1 = flags & (~flag) - if (flags1 == flags) this - else Modifiers(flags1, privateWithin, annotations) setPositions positions - } - def | (flag: Long): Modifiers = { - val flags1 = flags | flag - if (flags1 == flags) this - else Modifiers(flags1, privateWithin, annotations) setPositions positions - } - def withAnnotations(annots: List[Tree]) = - if (annots.isEmpty) this - else copy(annotations = annotations ::: annots) setPositions positions - - def withPosition(flag: Long, position: Position) = - copy() setPositions positions + (flag -> position) - - override def mapAnnotations(f: List[Tree] => List[Tree]): Modifiers = - Modifiers(flags, privateWithin, f(annotations)) setPositions positions - - override def toString = "Modifiers(%s, %s, %s)".format(flagString, annotations mkString ", ", positions) - } - - object Modifiers extends ModifiersCreator - - implicit val ModifiersTag = ClassTag[Modifiers](classOf[Modifiers]) - - // ---- values and creators --------------------------------------- - - /** @param sym the class symbol - * @return the implementation template - */ - def ClassDef(sym: Symbol, impl: Template): ClassDef = - atPos(sym.pos) { - ClassDef(Modifiers(sym.flags), - sym.name.toTypeName, - sym.typeParams map TypeDef, - impl) setSymbol sym - } - - /** - * @param sym the class symbol - * @param impl the implementation template - */ - def ModuleDef(sym: Symbol, impl: Template): ModuleDef = - atPos(sym.pos) { - ModuleDef(Modifiers(sym.flags), sym.name.toTermName, impl) setSymbol sym - } - - def ValDef(sym: Symbol, rhs: Tree): ValDef = - atPos(sym.pos) { - ValDef(Modifiers(sym.flags), sym.name.toTermName, - TypeTree(sym.tpe) setPos sym.pos.focus, - rhs) setSymbol sym - } - - def ValDef(sym: Symbol): ValDef = ValDef(sym, EmptyTree) - - object emptyValDef extends ValDef(Modifiers(PRIVATE), nme.WILDCARD, TypeTree(NoType), EmptyTree) { - override def isEmpty = true - super.setPos(NoPosition) - override def setPos(pos: Position) = { assert(false); this } - } - - def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef = - atPos(sym.pos) { - assert(sym != NoSymbol) - DefDef(mods, - sym.name.toTermName, - sym.typeParams map TypeDef, - vparamss, - TypeTree(sym.tpe.finalResultType) setPos sym.pos.focus, - rhs) setSymbol sym - } - - def DefDef(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree): DefDef = - DefDef(sym, Modifiers(sym.flags), vparamss, rhs) - - def DefDef(sym: Symbol, mods: Modifiers, rhs: Tree): DefDef = - DefDef(sym, mods, mapParamss(sym)(ValDef), rhs) - - def DefDef(sym: Symbol, rhs: Tree): DefDef = - DefDef(sym, Modifiers(sym.flags), rhs) - - def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef = - DefDef(sym, rhs(sym.info.paramss)) - - /** A TypeDef node which defines given `sym` with given tight hand side `rhs`. */ - def TypeDef(sym: Symbol, rhs: Tree): TypeDef = - atPos(sym.pos) { - TypeDef(Modifiers(sym.flags), sym.name.toTypeName, sym.typeParams map TypeDef, rhs) setSymbol sym - } - - /** A TypeDef node which defines abstract type or type parameter for given `sym` */ - def TypeDef(sym: Symbol): TypeDef = - TypeDef(sym, TypeBoundsTree(TypeTree(sym.info.bounds.lo), TypeTree(sym.info.bounds.hi))) - - def LabelDef(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef = - atPos(sym.pos) { - LabelDef(sym.name.toTermName, params map Ident, rhs) setSymbol sym - } - - /** casedef shorthand */ - def CaseDef(pat: Tree, body: Tree): CaseDef = - CaseDef(pat, EmptyTree, body) - - def Bind(sym: Symbol, body: Tree): Bind = - Bind(sym.name, body) setSymbol sym - - def Try(body: Tree, cases: (Tree, Tree)*): Try = - Try(body, cases.toList map { case (pat, rhs) => CaseDef(pat, EmptyTree, rhs) }, EmptyTree) - - def Throw(tpe: Type, args: Tree*): Throw = - Throw(New(tpe, args: _*)) - - def Apply(sym: Symbol, args: Tree*): Tree = - Apply(Ident(sym), args.toList) - - /** Factory method for object creation `new tpt(args_1)...(args_n)` - * A `New(t, as)` is expanded to: `(new t).<init>(as)` - */ - def New(tpt: Tree, argss: List[List[Tree]]): Tree = argss match { - case Nil => ApplyConstructor(tpt, Nil) - case xs :: rest => { - def mkApply(fun: Tree, args: List[Tree]) = Apply(fun, args) - rest.foldLeft(ApplyConstructor(tpt, xs): Tree)(mkApply) - // [Eugene++] no longer compiles after I moved the `Apply` case class here - // rest.foldLeft(ApplyConstructor(tpt, xs): Tree)(Apply) - } - } - - /** 0-1 argument list new, based on a type. - */ - def New(tpe: Type, args: Tree*): Tree = - ApplyConstructor(TypeTree(tpe), args.toList) - - def New(sym: Symbol, args: Tree*): Tree = - New(sym.tpe, args: _*) - - def Super(sym: Symbol, mix: TypeName): Tree = - Super(This(sym), mix) - - def This(sym: Symbol): Tree = - This(sym.name.toTypeName) setSymbol sym - - def Select(qualifier: Tree, name: String): Select = - Select(qualifier, newTermName(name)) - - def Select(qualifier: Tree, sym: Symbol): Select = - Select(qualifier, sym.name) setSymbol sym - - def Ident(name: String): Ident = - Ident(newTermName(name)) - - def Ident(sym: Symbol): Ident = - Ident(sym.name) setSymbol sym - - /** Block factory that flattens directly nested blocks. - */ - def Block(stats: Tree*): Block = { - if (stats.isEmpty) Block(Nil, Literal(Constant(()))) - else stats match { - case Seq(b @ Block(_, _)) => b - case Seq(stat) => Block(stats.toList, Literal(Constant(()))) - case Seq(_, rest @ _*) => Block(stats.init.toList, stats.last) - } - } - - // --- generic traversers and transformers - - override protected def itraverse(traverser: Traverser, tree: Tree): Unit = { - import traverser._ - tree match { - case EmptyTree => - ; - case PackageDef(pid, stats) => - traverse(pid) - atOwner(mclass(tree.symbol)) { - traverseTrees(stats) - } - case ClassDef(mods, name, tparams, impl) => - atOwner(tree.symbol) { - traverseTrees(mods.annotations); traverseTrees(tparams); traverse(impl) - } - case ModuleDef(mods, name, impl) => - atOwner(mclass(tree.symbol)) { - traverseTrees(mods.annotations); traverse(impl) - } - case ValDef(mods, name, tpt, rhs) => - atOwner(tree.symbol) { - traverseTrees(mods.annotations); traverse(tpt); traverse(rhs) - } - case DefDef(mods, name, tparams, vparamss, tpt, rhs) => - atOwner(tree.symbol) { - traverseTrees(mods.annotations); traverseTrees(tparams); traverseTreess(vparamss); traverse(tpt); traverse(rhs) - } - case TypeDef(mods, name, tparams, rhs) => - atOwner(tree.symbol) { - traverseTrees(mods.annotations); traverseTrees(tparams); traverse(rhs) - } - case LabelDef(name, params, rhs) => - traverseTrees(params); traverse(rhs) - case Import(expr, selectors) => - traverse(expr) - case Annotated(annot, arg) => - traverse(annot); traverse(arg) - case Template(parents, self, body) => - traverseTrees(parents) - if (!self.isEmpty) traverse(self) - traverseStats(body, tree.symbol) - case Block(stats, expr) => - traverseTrees(stats); traverse(expr) - case CaseDef(pat, guard, body) => - traverse(pat); traverse(guard); traverse(body) - case Alternative(trees) => - traverseTrees(trees) - case Star(elem) => - traverse(elem) - case Bind(name, body) => - traverse(body) - case UnApply(fun, args) => - traverse(fun); traverseTrees(args) - case ArrayValue(elemtpt, trees) => - traverse(elemtpt); traverseTrees(trees) - case Function(vparams, body) => - atOwner(tree.symbol) { - traverseTrees(vparams); traverse(body) - } - case Assign(lhs, rhs) => - traverse(lhs); traverse(rhs) - case AssignOrNamedArg(lhs, rhs) => - traverse(lhs); traverse(rhs) - case If(cond, thenp, elsep) => - traverse(cond); traverse(thenp); traverse(elsep) - case Match(selector, cases) => - traverse(selector); traverseTrees(cases) - case Return(expr) => - traverse(expr) - case Try(block, catches, finalizer) => - traverse(block); traverseTrees(catches); traverse(finalizer) - case Throw(expr) => - traverse(expr) - case New(tpt) => - traverse(tpt) - case Typed(expr, tpt) => - traverse(expr); traverse(tpt) - case TypeApply(fun, args) => - traverse(fun); traverseTrees(args) - case Apply(fun, args) => - traverse(fun); traverseTrees(args) - case ApplyDynamic(qual, args) => - traverse(qual); traverseTrees(args) - case Super(qual, _) => - traverse(qual) - case This(_) => - ; - case Select(qualifier, selector) => - traverse(qualifier) - case Ident(_) => - ; - case ReferenceToBoxed(idt) => - traverse(idt) - case Literal(_) => - ; - case TypeTree() => - ; - case SingletonTypeTree(ref) => - traverse(ref) - case SelectFromTypeTree(qualifier, selector) => - traverse(qualifier) - case CompoundTypeTree(templ) => - traverse(templ) - case AppliedTypeTree(tpt, args) => - traverse(tpt); traverseTrees(args) - case TypeBoundsTree(lo, hi) => - traverse(lo); traverse(hi) - case ExistentialTypeTree(tpt, whereClauses) => - traverse(tpt); traverseTrees(whereClauses) - case _ => xtraverse(traverser, tree) - } - } - - override protected def itransform(transformer: Transformer, tree: Tree): Tree = { - import transformer._ - val treeCopy = transformer.treeCopy - tree match { - case EmptyTree => - tree - case PackageDef(pid, stats) => - treeCopy.PackageDef( - tree, transform(pid).asInstanceOf[RefTree], - atOwner(mclass(tree.symbol)) { - transformStats(stats, currentOwner) - } - ) - case ClassDef(mods, name, tparams, impl) => - atOwner(tree.symbol) { - treeCopy.ClassDef(tree, transformModifiers(mods), name, - transformTypeDefs(tparams), transformTemplate(impl)) - } - case ModuleDef(mods, name, impl) => - atOwner(mclass(tree.symbol)) { - treeCopy.ModuleDef(tree, transformModifiers(mods), - name, transformTemplate(impl)) - } - case ValDef(mods, name, tpt, rhs) => - atOwner(tree.symbol) { - treeCopy.ValDef(tree, transformModifiers(mods), - name, transform(tpt), transform(rhs)) - } - case DefDef(mods, name, tparams, vparamss, tpt, rhs) => - atOwner(tree.symbol) { - treeCopy.DefDef(tree, transformModifiers(mods), name, - transformTypeDefs(tparams), transformValDefss(vparamss), - transform(tpt), transform(rhs)) - } - case TypeDef(mods, name, tparams, rhs) => - atOwner(tree.symbol) { - treeCopy.TypeDef(tree, transformModifiers(mods), name, - transformTypeDefs(tparams), transform(rhs)) - } - case LabelDef(name, params, rhs) => - treeCopy.LabelDef(tree, name, transformIdents(params), transform(rhs)) //bq: Martin, once, atOwner(...) works, also change `LamdaLifter.proxy' - case Import(expr, selectors) => - treeCopy.Import(tree, transform(expr), selectors) - case Template(parents, self, body) => - treeCopy.Template(tree, transformTrees(parents), transformValDef(self), transformStats(body, tree.symbol)) - case Block(stats, expr) => - treeCopy.Block(tree, transformStats(stats, currentOwner), transform(expr)) - case CaseDef(pat, guard, body) => - treeCopy.CaseDef(tree, transform(pat), transform(guard), transform(body)) - case Alternative(trees) => - treeCopy.Alternative(tree, transformTrees(trees)) - case Star(elem) => - treeCopy.Star(tree, transform(elem)) - case Bind(name, body) => - treeCopy.Bind(tree, name, transform(body)) - case UnApply(fun, args) => - treeCopy.UnApply(tree, fun, transformTrees(args)) // bq: see test/.../unapplyContexts2.scala - case ArrayValue(elemtpt, trees) => - treeCopy.ArrayValue(tree, transform(elemtpt), transformTrees(trees)) - case Function(vparams, body) => - atOwner(tree.symbol) { - treeCopy.Function(tree, transformValDefs(vparams), transform(body)) - } - case Assign(lhs, rhs) => - treeCopy.Assign(tree, transform(lhs), transform(rhs)) - case AssignOrNamedArg(lhs, rhs) => - treeCopy.AssignOrNamedArg(tree, transform(lhs), transform(rhs)) - case If(cond, thenp, elsep) => - treeCopy.If(tree, transform(cond), transform(thenp), transform(elsep)) - case Match(selector, cases) => - treeCopy.Match(tree, transform(selector), transformCaseDefs(cases)) - case Return(expr) => - treeCopy.Return(tree, transform(expr)) - case Try(block, catches, finalizer) => - treeCopy.Try(tree, transform(block), transformCaseDefs(catches), transform(finalizer)) - case Throw(expr) => - treeCopy.Throw(tree, transform(expr)) - case New(tpt) => - treeCopy.New(tree, transform(tpt)) - case Typed(expr, tpt) => - treeCopy.Typed(tree, transform(expr), transform(tpt)) - case TypeApply(fun, args) => - treeCopy.TypeApply(tree, transform(fun), transformTrees(args)) - case Apply(fun, args) => - treeCopy.Apply(tree, transform(fun), transformTrees(args)) - case ApplyDynamic(qual, args) => - treeCopy.ApplyDynamic(tree, transform(qual), transformTrees(args)) - case Super(qual, mix) => - treeCopy.Super(tree, transform(qual), mix) - case This(qual) => - treeCopy.This(tree, qual) - case Select(qualifier, selector) => - treeCopy.Select(tree, transform(qualifier), selector) - case Ident(name) => - treeCopy.Ident(tree, name) - case ReferenceToBoxed(idt) => - treeCopy.ReferenceToBoxed(tree, transform(idt) match { case idt1: Ident => idt1 }) - case Literal(value) => - treeCopy.Literal(tree, value) - case TypeTree() => - treeCopy.TypeTree(tree) - case Annotated(annot, arg) => - treeCopy.Annotated(tree, transform(annot), transform(arg)) - case SingletonTypeTree(ref) => - treeCopy.SingletonTypeTree(tree, transform(ref)) - case SelectFromTypeTree(qualifier, selector) => - treeCopy.SelectFromTypeTree(tree, transform(qualifier), selector) - case CompoundTypeTree(templ) => - treeCopy.CompoundTypeTree(tree, transformTemplate(templ)) - case AppliedTypeTree(tpt, args) => - treeCopy.AppliedTypeTree(tree, transform(tpt), transformTrees(args)) - case TypeBoundsTree(lo, hi) => - treeCopy.TypeBoundsTree(tree, transform(lo), transform(hi)) - case ExistentialTypeTree(tpt, whereClauses) => - treeCopy.ExistentialTypeTree(tree, transform(tpt), transformTrees(whereClauses)) - case _ => - xtransform(transformer, tree) - } - } - - private def mclass(sym: Symbol) = sym map (_.asModuleSymbol.moduleClass) - - // --- specific traversers and transformers - - class ForeachPartialTreeTraverser(pf: PartialFunction[Tree, Tree]) extends Traverser { - override def traverse(tree: Tree) { - val t = if (pf isDefinedAt tree) pf(tree) else tree - super.traverse(t) - } - } - - class ChangeOwnerTraverser(val oldowner: Symbol, val newowner: Symbol) extends Traverser { - def changeOwner(tree: Tree) = tree match { - case Return(expr) => - if (tree.symbol == oldowner) { - // SI-5612 - if (newowner hasTransOwner oldowner) - log("NOT changing owner of %s because %s is nested in %s".format(tree, newowner, oldowner)) - else { - log("changing owner of %s: %s => %s".format(tree, oldowner, newowner)) - tree.symbol = newowner - } - } - case _: DefTree | _: Function => - if (tree.symbol != NoSymbol && tree.symbol.owner == oldowner) { - tree.symbol.owner = newowner - } - case _ => - } - override def traverse(tree: Tree) { - changeOwner(tree) - super.traverse(tree) - } - } - - private class ShallowDuplicator(orig: Tree) extends Transformer { - override val treeCopy = newStrictTreeCopier - override def transform(tree: Tree) = - if (tree eq orig) super.transform(tree) - else tree - } - // Create a readable string describing a substitution. - private def substituterString(fromStr: String, toStr: String, from: List[Any], to: List[Any]): String = { - "subst[%s, %s](%s)".format(fromStr, toStr, (from, to).zipped map (_ + " -> " + _) mkString ", ") - } - - // NOTE: calls shallowDuplicate on trees in `to` to avoid problems when symbols in `from` - // occur multiple times in the `tree` passed to `transform`, - // otherwise, the resulting Tree would be a graph, not a tree... this breaks all sorts of stuff, - // notably concerning the mutable aspects of Trees (such as setting their .tpe) - class TreeSubstituter(from: List[Symbol], to: List[Tree]) extends Transformer { - override def transform(tree: Tree): Tree = tree match { - case Ident(_) => - def subst(from: List[Symbol], to: List[Tree]): Tree = - if (from.isEmpty) tree - else if (tree.symbol == from.head) to.head.shallowDuplicate // TODO: does it ever make sense *not* to perform a shallowDuplicate on `to.head`? - else subst(from.tail, to.tail); - subst(from, to) - case _ => - super.transform(tree) - } - override def toString = substituterString("Symbol", "Tree", from, to) - } - - /** Substitute clazz.this with `to`. `to` must be an attributed tree. - */ - class ThisSubstituter(clazz: Symbol, to: => Tree) extends Transformer { - val newtpe = to.tpe - override def transform(tree: Tree) = { - if (tree.tpe ne null) tree.tpe = tree.tpe.substThis(clazz, newtpe) - tree match { - case This(_) if tree.symbol == clazz => to - case _ => super.transform(tree) - } - } - } - - class TypeMapTreeSubstituter(val typeMap: TypeMap) extends Traverser { - override def traverse(tree: Tree) { - 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 TypeMapTreeSubstituter(new SubstSymMap(from, to)) { - override def toString() = "TreeSymSubstTraverser/" + substituterString("Symbol", "Symbol", from, to) - } - - /** Substitute symbols in `from` with symbols in `to`. Returns a new - * tree using the new symbols and whose Ident and Select nodes are - * name-consistent with the new symbols. - */ - class TreeSymSubstituter(from: List[Symbol], to: List[Symbol]) extends Transformer { - val symSubst = new SubstSymMap(from, to) - override def transform(tree: Tree): Tree = { - def subst(from: List[Symbol], to: List[Symbol]) { - if (!from.isEmpty) - if (tree.symbol == from.head) tree setSymbol to.head - else subst(from.tail, to.tail) - } - - if (tree.tpe ne null) tree.tpe = symSubst(tree.tpe) - if (tree.hasSymbol) { - subst(from, to) - tree match { - case Ident(name0) if tree.symbol != NoSymbol => - treeCopy.Ident(tree, tree.symbol.name) - case Select(qual, name0) if tree.symbol != NoSymbol => - treeCopy.Select(tree, transform(qual), tree.symbol.name) - case _ => - super.transform(tree) - } - } else - super.transform(tree) - } - def apply[T <: Tree](tree: T): T = transform(tree).asInstanceOf[T] - override def toString() = "TreeSymSubstituter/" + substituterString("Symbol", "Symbol", from, to) - } - - - class ForeachTreeTraverser(f: Tree => Unit) extends Traverser { - override def traverse(t: Tree) { - f(t) - super.traverse(t) - } - } - - class FilterTreeTraverser(p: Tree => Boolean) extends Traverser { - val hits = new ListBuffer[Tree] - override def traverse(t: Tree) { - if (p(t)) hits += t - super.traverse(t) - } - } - - class CollectTreeTraverser[T](pf: PartialFunction[Tree, T]) extends Traverser { - val results = new ListBuffer[T] - override def traverse(t: Tree) { - if (pf.isDefinedAt(t)) results += pf(t) - super.traverse(t) - } - } - - class FindTreeTraverser(p: Tree => Boolean) extends Traverser { - var result: Option[Tree] = None - override def traverse(t: Tree) { - if (result.isEmpty) { - if (p(t)) result = Some(t) - super.traverse(t) - } - } - } - - private lazy val duplicator = new Transformer { - override val treeCopy = newStrictTreeCopier - override def transform(t: Tree) = { - val t1 = super.transform(t) - if ((t1 ne t) && t1.pos.isRange) t1 setPos t.pos.focus - t1 - } - } - - // ------ copiers ------------------------------------------- - - def copyDefDef(tree: Tree)( - mods: Modifiers = null, - name: Name = null, - tparams: List[TypeDef] = null, - vparamss: List[List[ValDef]] = null, - tpt: Tree = null, - rhs: Tree = null - ): DefDef = tree match { - case DefDef(mods0, name0, tparams0, vparamss0, tpt0, rhs0) => - treeCopy.DefDef(tree, - if (mods eq null) mods0 else mods, - if (name eq null) name0 else name, - if (tparams eq null) tparams0 else tparams, - if (vparamss eq null) vparamss0 else vparamss, - if (tpt eq null) tpt0 else tpt, - if (rhs eq null) rhs0 else rhs - ) - case t => - sys.error("Not a DefDef: " + t + "/" + t.getClass) - } - def copyValDef(tree: Tree)( - mods: Modifiers = null, - name: Name = null, - tpt: Tree = null, - rhs: Tree = null - ): ValDef = tree match { - case ValDef(mods0, name0, tpt0, rhs0) => - treeCopy.ValDef(tree, - if (mods eq null) mods0 else mods, - if (name eq null) name0 else name, - if (tpt eq null) tpt0 else tpt, - if (rhs eq null) rhs0 else rhs - ) - case t => - sys.error("Not a ValDef: " + t + "/" + t.getClass) - } - def copyClassDef(tree: Tree)( - mods: Modifiers = null, - name: Name = null, - tparams: List[TypeDef] = null, - impl: Template = null - ): ClassDef = tree match { - case ClassDef(mods0, name0, tparams0, impl0) => - treeCopy.ClassDef(tree, - if (mods eq null) mods0 else mods, - if (name eq null) name0 else name, - if (tparams eq null) tparams0 else tparams, - if (impl eq null) impl0 else impl - ) - case t => - sys.error("Not a ClassDef: " + t + "/" + t.getClass) - } - - def deriveDefDef(ddef: Tree)(applyToRhs: Tree => Tree): DefDef = ddef match { - case DefDef(mods0, name0, tparams0, vparamss0, tpt0, rhs0) => - treeCopy.DefDef(ddef, mods0, name0, tparams0, vparamss0, tpt0, applyToRhs(rhs0)) - case t => - sys.error("Not a DefDef: " + t + "/" + t.getClass) - } - def deriveValDef(vdef: Tree)(applyToRhs: Tree => Tree): ValDef = vdef match { - case ValDef(mods0, name0, tpt0, rhs0) => - treeCopy.ValDef(vdef, mods0, name0, tpt0, applyToRhs(rhs0)) - case t => - sys.error("Not a ValDef: " + t + "/" + t.getClass) - } - def deriveTemplate(templ: Tree)(applyToBody: List[Tree] => List[Tree]): Template = templ match { - case Template(parents0, self0, body0) => - treeCopy.Template(templ, parents0, self0, applyToBody(body0)) - case t => - sys.error("Not a Template: " + t + "/" + t.getClass) - } - def deriveClassDef(cdef: Tree)(applyToImpl: Template => Template): ClassDef = cdef match { - case ClassDef(mods0, name0, tparams0, impl0) => - treeCopy.ClassDef(cdef, mods0, name0, tparams0, applyToImpl(impl0)) - case t => - sys.error("Not a ClassDef: " + t + "/" + t.getClass) - } - def deriveModuleDef(mdef: Tree)(applyToImpl: Template => Template): ModuleDef = mdef match { - case ModuleDef(mods0, name0, impl0) => - treeCopy.ModuleDef(mdef, mods0, name0, applyToImpl(impl0)) - case t => - sys.error("Not a ModuleDef: " + t + "/" + t.getClass) - } - def deriveCaseDef(cdef: Tree)(applyToBody: Tree => Tree): CaseDef = cdef match { - case CaseDef(pat0, guard0, body0) => - treeCopy.CaseDef(cdef, pat0, guard0, applyToBody(body0)) - case t => - sys.error("Not a CaseDef: " + t + "/" + t.getClass) - } - def deriveLabelDef(ldef: Tree)(applyToRhs: Tree => Tree): LabelDef = ldef match { - case LabelDef(name0, params0, rhs0) => - treeCopy.LabelDef(ldef, name0, params0, applyToRhs(rhs0)) - case t => - sys.error("Not a LabelDef: " + t + "/" + t.getClass) - } - - implicit val TreeTag = ClassTag[Tree](classOf[Tree]) - implicit val TermTreeTag = ClassTag[TermTree](classOf[TermTree]) - implicit val TypTreeTag = ClassTag[TypTree](classOf[TypTree]) - implicit val SymTreeTag = ClassTag[SymTree](classOf[SymTree]) - implicit val NameTreeTag = ClassTag[NameTree](classOf[NameTree]) - implicit val RefTreeTag = ClassTag[RefTree](classOf[RefTree]) - implicit val DefTreeTag = ClassTag[DefTree](classOf[DefTree]) - implicit val MemberDefTag = ClassTag[MemberDef](classOf[MemberDef]) - implicit val PackageDefTag = ClassTag[PackageDef](classOf[PackageDef]) - implicit val ImplDefTag = ClassTag[ImplDef](classOf[ImplDef]) - implicit val ClassDefTag = ClassTag[ClassDef](classOf[ClassDef]) - implicit val ModuleDefTag = ClassTag[ModuleDef](classOf[ModuleDef]) - implicit val ValOrDefDefTag = ClassTag[ValOrDefDef](classOf[ValOrDefDef]) - implicit val ValDefTag = ClassTag[ValDef](classOf[ValDef]) - implicit val DefDefTag = ClassTag[DefDef](classOf[DefDef]) - implicit val TypeDefTag = ClassTag[TypeDef](classOf[TypeDef]) - implicit val LabelDefTag = ClassTag[LabelDef](classOf[LabelDef]) - implicit val ImportSelectorTag = ClassTag[ImportSelector](classOf[ImportSelector]) - implicit val ImportTag = ClassTag[Import](classOf[Import]) - implicit val TemplateTag = ClassTag[Template](classOf[Template]) - implicit val BlockTag = ClassTag[Block](classOf[Block]) - implicit val CaseDefTag = ClassTag[CaseDef](classOf[CaseDef]) - implicit val AlternativeTag = ClassTag[Alternative](classOf[Alternative]) - implicit val StarTag = ClassTag[Star](classOf[Star]) - implicit val BindTag = ClassTag[Bind](classOf[Bind]) - implicit val UnApplyTag = ClassTag[UnApply](classOf[UnApply]) - implicit val ArrayValueTag = ClassTag[ArrayValue](classOf[ArrayValue]) - implicit val FunctionTag = ClassTag[Function](classOf[Function]) - implicit val AssignTag = ClassTag[Assign](classOf[Assign]) - implicit val AssignOrNamedArgTag = ClassTag[AssignOrNamedArg](classOf[AssignOrNamedArg]) - implicit val IfTag = ClassTag[If](classOf[If]) - implicit val MatchTag = ClassTag[Match](classOf[Match]) - implicit val ReturnTag = ClassTag[Return](classOf[Return]) - implicit val TryTag = ClassTag[Try](classOf[Try]) - implicit val ThrowTag = ClassTag[Throw](classOf[Throw]) - implicit val NewTag = ClassTag[New](classOf[New]) - implicit val TypedTag = ClassTag[Typed](classOf[Typed]) - implicit val GenericApplyTag = ClassTag[GenericApply](classOf[GenericApply]) - implicit val TypeApplyTag = ClassTag[TypeApply](classOf[TypeApply]) - implicit val ApplyTag = ClassTag[Apply](classOf[Apply]) - implicit val ApplyDynamicTag = ClassTag[ApplyDynamic](classOf[ApplyDynamic]) - implicit val SuperTag = ClassTag[Super](classOf[Super]) - implicit val ThisTag = ClassTag[This](classOf[This]) - implicit val SelectTag = ClassTag[Select](classOf[Select]) - implicit val IdentTag = ClassTag[Ident](classOf[Ident]) - implicit val ReferenceToBoxedTag = ClassTag[ReferenceToBoxed](classOf[ReferenceToBoxed]) - implicit val LiteralTag = ClassTag[Literal](classOf[Literal]) - implicit val AnnotatedTag = ClassTag[Annotated](classOf[Annotated]) - implicit val SingletonTypeTreeTag = ClassTag[SingletonTypeTree](classOf[SingletonTypeTree]) - implicit val SelectFromTypeTreeTag = ClassTag[SelectFromTypeTree](classOf[SelectFromTypeTree]) - implicit val CompoundTypeTreeTag = ClassTag[CompoundTypeTree](classOf[CompoundTypeTree]) - implicit val AppliedTypeTreeTag = ClassTag[AppliedTypeTree](classOf[AppliedTypeTree]) - implicit val TypeBoundsTreeTag = ClassTag[TypeBoundsTree](classOf[TypeBoundsTree]) - implicit val ExistentialTypeTreeTag = ClassTag[ExistentialTypeTree](classOf[ExistentialTypeTree]) - implicit val TypeTreeTag = ClassTag[TypeTree](classOf[TypeTree]) -} diff --git a/src/compiler/scala/reflect/internal/TypeDebugging.scala b/src/compiler/scala/reflect/internal/TypeDebugging.scala deleted file mode 100644 index 33f6a645e8..0000000000 --- a/src/compiler/scala/reflect/internal/TypeDebugging.scala +++ /dev/null @@ -1,71 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Paul Phillips - */ - -package scala.reflect -package internal - -trait TypeDebugging { - self: SymbolTable => - - import definitions._ - - // @M toString that is safe during debugging (does not normalize, ...) - object typeDebug { - private def to_s(x: Any): String = x match { - // otherwise case classes are caught looking like products - case _: Tree | _: Type => "" + x - case x: TraversableOnce[_] => x mkString ", " - case x: Product => x.productIterator mkString ("(", ", ", ")") - case _ => "" + x - } - def ptIndent(x: Any) = ("" + x).replaceAll("\\n", " ") - def ptBlock(label: String, pairs: (String, Any)*): String = { - if (pairs.isEmpty) label + "{ }" - else { - val width = (pairs map (_._1.length)).max - val fmt = "%-" + (width + 1) + "s %s" - val strs = pairs map { case (k, v) => fmt.format(k, to_s(v)) } - - strs.mkString(label + " {\n ", "\n ", "\n}") - } - } - def ptLine(label: String, pairs: (String, Any)*): String = { - val strs = pairs map { case (k, v) => k + "=" + to_s(v) } - strs.mkString(label + ": ", ", ", "") - } - def ptTree(t: Tree) = t match { - case PackageDef(pid, _) => "package " + pid - case ModuleDef(_, name, _) => "object " + name - case ClassDef(_, name, tparams, _) => "class " + name + str.brackets(tparams) - case _ => to_s(t) - } - - object str { - def parentheses(xs: List[_]): String = xs.mkString("(", ", ", ")") - def brackets(xs: List[_]): String = if (xs.isEmpty) "" else xs.mkString("[", ", ", "]") - def tparams(tparams: List[Type]): String = brackets(tparams map debug) - def parents(ps: List[Type]): String = (ps map debug).mkString(" with ") - def refine(defs: Scope): String = defs.toList.mkString("{", " ;\n ", "}") - } - - private def debug(tp: Type): String = tp match { - case TypeRef(pre, sym, args) => debug(pre) + "." + sym.nameString + str.tparams(args) - case ThisType(sym) => sym.nameString + ".this" - case SingleType(pre, sym) => debug(pre) +"."+ sym.nameString +".type" - case RefinedType(parents, defs) => str.parents(parents) + str.refine(defs) - case ClassInfoType(parents, defs, clazz) => "class "+ clazz.nameString + str.parents(parents) + str.refine(defs) - case PolyType(tparams, result) => str.brackets(tparams) + " " + debug(result) - case TypeBounds(lo, hi) => ">: "+ debug(lo) +" <: "+ debug(hi) - case tv @ TypeVar(_, _) => tv.toString - case ExistentialType(tparams, qtpe) => "forSome "+ str.brackets(tparams) + " " + debug(qtpe) - case _ => "?"+tp.getClass.getName+"?"//tp.toString might produce cyclic error... - } - def debugString(tp: Type) = debug(tp) - } - def paramString(tp: Type) = typeDebug.str parentheses (tp.params map (_.defString)) - def typeParamsString(tp: Type) = typeDebug.str brackets (tp.typeParams map (_.defString)) - def typeArgsString(tp: Type) = typeDebug.str brackets (tp.typeArgs map (_.safeToString)) - def debugString(tp: Type) = typeDebug debugString tp -} diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala deleted file mode 100644 index 23921d73cc..0000000000 --- a/src/compiler/scala/reflect/internal/Types.scala +++ /dev/null @@ -1,6820 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.reflect -package internal - -import scala.collection.{ mutable, immutable, generic } -import generic.Clearable -import scala.ref.WeakReference -import mutable.ListBuffer -import Flags._ -import scala.util.control.ControlThrowable -import scala.annotation.tailrec -import util.Statistics._ -import language.postfixOps - -/* A standard type pattern match: - case ErrorType => - // internal: error - case WildcardType => - // internal: unknown - case NoType => - case NoPrefix => - case ThisType(sym) => - // sym.this.type - case SuperType(thistpe, supertpe) => - // super references - case SingleType(pre, sym) => - // pre.sym.type - case ConstantType(value) => - // Int(2) - case TypeRef(pre, sym, args) => - // pre.sym[targs] - // Outer.this.C would be represented as TypeRef(ThisType(Outer), C, List()) - case RefinedType(parents, defs) => - // parent1 with ... with parentn { defs } - case ExistentialType(tparams, result) => - // result forSome { tparams } - case AnnotatedType(annots, tp, selfsym) => - // tp @annots - - // the following are non-value types; you cannot write them down in Scala source. - - case TypeBounds(lo, hi) => - // >: lo <: hi - case ClassInfoType(parents, defs, clazz) => - // same as RefinedType except as body of class - case MethodType(paramtypes, result) => - // (paramtypes)result - // For instance def m(): T is represented as MethodType(List(), T) - case NullaryMethodType(result) => // eliminated by uncurry - // an eval-by-name type - // For instance def m: T is represented as NullaryMethodType(T) - case PolyType(tparams, result) => - // [tparams]result where result is a (Nullary)MethodType or ClassInfoType - - // The remaining types are not used after phase `typer`. - case OverloadedType(pre, tparams, alts) => - // all alternatives of an overloaded ident - case AntiPolyType(pre, targs) => - // rarely used, disappears when combined with a PolyType - case TypeVar(inst, constr) => - // a type variable - // Replace occurrences of type parameters with type vars, where - // inst is the instantiation and constr is a list of bounds. - case DeBruijnIndex(level, index) - // for dependent method types: a type referring to a method parameter. - case ErasedValueType(tp) - // only used during erasure of derived value classes. -*/ - -trait Types extends api.Types { self: SymbolTable => - import definitions._ - - //statistics - def uniqueTypeCount = if (uniques == null) 0 else uniques.size - - private var explainSwitch = false - private final val emptySymbolSet = immutable.Set.empty[Symbol] - - private final val LogPendingSubTypesThreshold = 50 - private final val LogPendingBaseTypesThreshold = 50 - private final val LogVolatileThreshold = 50 - - /** A don't care value for the depth parameter in lubs/glbs and related operations. */ - private final val AnyDepth = -3 - - /** Decrement depth unless it is a don't care. */ - private final def decr(depth: Int) = if (depth == AnyDepth) AnyDepth else depth - 1 - - private final val printLubs = sys.props contains "scalac.debug.lub" - private final val traceTypeVars = sys.props contains "scalac.debug.tvar" - /** In case anyone wants to turn off lub verification without reverting anything. */ - private final val verifyLubs = true - /** In case anyone wants to turn off type parameter bounds being used - * to seed type constraints. - */ - private final val propagateParameterBoundsToTypeVars = sys.props contains "scalac.debug.prop-constraints" - - protected val enableTypeVarExperimentals = settings.Xexperimental.value - - /** Empty immutable maps to avoid allocations. */ - private val emptySymMap = immutable.Map[Symbol, Symbol]() - private val emptySymCount = immutable.Map[Symbol, Int]() - - /** The current skolemization level, needed for the algorithms - * in isSameType, isSubType that do constraint solving under a prefix. - */ - var skolemizationLevel = 0 - - /** A log of type variable with their original constraints. Used in order - * to undo constraints in the case of isSubType/isSameType failure. - */ - lazy val undoLog = newUndoLog - - protected def newUndoLog = new UndoLog - - class UndoLog extends Clearable { - private type UndoPairs = List[(TypeVar, TypeConstraint)] - private var log: UndoPairs = List() - - // register with the auto-clearing cache manager - perRunCaches.recordCache(this) - - /** Undo all changes to constraints to type variables upto `limit`. */ - private def undoTo(limit: UndoPairs) { - while ((log ne limit) && log.nonEmpty) { - val (tv, constr) = log.head - tv.constr = constr - log = log.tail - } - } - - /** No sync necessary, because record should only - * be called from within a undo or undoUnless block, - * which is already synchronized. - */ - private[reflect] def record(tv: TypeVar) = { - log ::= ((tv, tv.constr.cloneInternal)) - } - - def clear() { - if (settings.debug.value) - self.log("Clearing " + log.size + " entries from the undoLog.") - - log = Nil - } - def size = log.size - - // `block` should not affect constraints on typevars - def undo[T](block: => T): T = { - val before = log - - try block - finally undoTo(before) - } - - // if `block` evaluates to false, it should not affect constraints on typevars - def undoUnless(block: => Boolean): Boolean = { - val before = log - var result = false - - try result = block - finally if (!result) undoTo(before) - - result - } - } - - /** A map from lists to compound types that have the given list as parents. - * This is used to avoid duplication in the computation of base type sequences and baseClasses. - * It makes use of the fact that these two operations depend only on the parents, - * not on the refinement. - */ - val intersectionWitness = perRunCaches.newWeakMap[List[Type], WeakReference[Type]]() - - /** A proxy for a type (identified by field `underlying`) that forwards most - * operations to it (for exceptions, see WrappingProxy, which forwards even more operations). - * every operation that is overridden for some kind of types should be forwarded. - */ - trait SimpleTypeProxy extends Type { - def underlying: Type - - // the following operations + those in RewrappingTypeProxy are all operations - // in class Type that are overridden in some subclass - // Important to keep this up-to-date when new operations are added! - override def isTrivial = underlying.isTrivial - override def isHigherKinded: Boolean = underlying.isHigherKinded - override def typeConstructor: Type = underlying.typeConstructor - override def isNotNull = underlying.isNotNull - override def isError = underlying.isError - override def isErroneous = underlying.isErroneous - override def isStable: Boolean = underlying.isStable - override def isVolatile = underlying.isVolatile - override def finalResultType = underlying.finalResultType - override def paramSectionCount = underlying.paramSectionCount - override def paramss = underlying.paramss - override def params = underlying.params - override def paramTypes = underlying.paramTypes - override def termSymbol = underlying.termSymbol - override def termSymbolDirect = underlying.termSymbolDirect - override def typeParams = underlying.typeParams - override def boundSyms = underlying.boundSyms - override def typeSymbol = underlying.typeSymbol - override def typeSymbolDirect = underlying.typeSymbolDirect - override def widen = underlying.widen - override def typeOfThis = underlying.typeOfThis - override def bounds = underlying.bounds - override def parents = underlying.parents - override def prefix = underlying.prefix - override def decls = underlying.decls - override def baseType(clazz: Symbol) = underlying.baseType(clazz) - override def baseTypeSeq = underlying.baseTypeSeq - override def baseTypeSeqDepth = underlying.baseTypeSeqDepth - override def baseClasses = underlying.baseClasses - } - - /** A proxy for a type (identified by field `underlying`) that forwards most - * operations to it. Every operation that is overridden for some kind of types is - * forwarded here. Some operations are rewrapped again. - */ - trait RewrappingTypeProxy extends SimpleTypeProxy { - protected def maybeRewrap(newtp: Type) = if (newtp eq underlying) this else rewrap(newtp) - protected def rewrap(newtp: Type): Type - - // the following are all operations in class Type that are overridden in some subclass - // Important to keep this up-to-date when new operations are added! - override def widen = maybeRewrap(underlying.widen) - override def narrow = underlying.narrow - override def deconst = maybeRewrap(underlying.deconst) - override def resultType = maybeRewrap(underlying.resultType) - override def resultType(actuals: List[Type]) = maybeRewrap(underlying.resultType(actuals)) - override def finalResultType = maybeRewrap(underlying.finalResultType) - override def paramSectionCount = 0 - override def paramss: List[List[Symbol]] = List() - override def params: List[Symbol] = List() - override def paramTypes: List[Type] = List() - override def typeArgs = underlying.typeArgs - override def notNull = maybeRewrap(underlying.notNull) - override def instantiateTypeParams(formals: List[Symbol], actuals: List[Type]) = underlying.instantiateTypeParams(formals, actuals) - override def skolemizeExistential(owner: Symbol, origin: AnyRef) = underlying.skolemizeExistential(owner, origin) - override def normalize = maybeRewrap(underlying.normalize) - override def dealias = maybeRewrap(underlying.dealias) - override def cloneInfo(owner: Symbol) = maybeRewrap(underlying.cloneInfo(owner)) - override def atOwner(owner: Symbol) = maybeRewrap(underlying.atOwner(owner)) - override def prefixString = underlying.prefixString - override def isComplete = underlying.isComplete - override def complete(sym: Symbol) = underlying.complete(sym) - override def load(sym: Symbol) { underlying.load(sym) } - override def withAnnotations(annots: List[AnnotationInfo]) = maybeRewrap(underlying.withAnnotations(annots)) - override def withoutAnnotations = maybeRewrap(underlying.withoutAnnotations) - } - - case object UnmappableTree extends TermTree { - override def toString = "<unmappable>" - super.tpe_=(NoType) - override def tpe_=(t: Type) = if (t != NoType) { - throw new UnsupportedOperationException("tpe_=("+t+") inapplicable for <empty>") - } - } - - abstract class TypeApiImpl extends TypeApi { this: Type => - def declaration(name: Name): Symbol = decl(name) - def nonPrivateDeclaration(name: Name): Symbol = nonPrivateDecl(name) - def declarations = decls - def typeArguments = typeArgs - def erasure = this match { - case ConstantType(value) => widen.erasure // [Eugene to Martin] constant types are unaffected by erasure. weird. - case _ => - var result: Type = transformedType(this) - result = result.normalize match { // necessary to deal with erasures of HK types, typeConstructor won't work - case PolyType(undets, underlying) => existentialAbstraction(undets, underlying) // we don't want undets in the result - case _ => result - } - // [Eugene] erasure screws up all ThisTypes for modules into PackageTypeRefs - // we need to unscrew them, or certain typechecks will fail mysteriously - // http://groups.google.com/group/scala-internals/browse_thread/thread/6d3277ae21b6d581 - result = result.map(tpe => tpe match { - case tpe: PackageTypeRef => ThisType(tpe.sym) - case _ => tpe - }) - result - } - def substituteSymbols(from: List[Symbol], to: List[Symbol]): Type = substSym(from, to) - def substituteTypes(from: List[Symbol], to: List[Type]): Type = subst(from, to) - - // [Eugene] to be discussed and refactored - def isConcrete = { - def notConcreteSym(sym: Symbol) = - sym.isAbstractType && !sym.isExistential - - def notConcreteTpe(tpe: Type): Boolean = tpe match { - case ThisType(_) => false - case SuperType(_, _) => false - case SingleType(pre, sym) => notConcreteSym(sym) - case ConstantType(_) => false - case TypeRef(_, sym, args) => notConcreteSym(sym) || (args exists (arg => notConcreteTpe(arg))) - case RefinedType(_, _) => false - case ExistentialType(_, _) => false - case AnnotatedType(_, tp, _) => notConcreteTpe(tp) - case _ => true - } - - !notConcreteTpe(this) - } - - // [Eugene] is this comprehensive? - // the only thingies that we want to splice are: 1) type parameters, 2) type members - // the thingies that we don't want to splice are: 1) concrete types (obviously), 2) existential skolems - // this check seems to cover them all, right? - // todo. after we discuss this, move the check to subclasses - def isSpliceable = { - this.isInstanceOf[TypeRef] && typeSymbol.isAbstractType && !typeSymbol.isExistential - } - } - - /** The base class for all types */ - abstract class Type extends TypeApiImpl with Annotatable[Type] { - /** Types for which asSeenFrom always is the identity, no matter what - * prefix or owner. - */ - def isTrivial: Boolean = false - - /** Is this type higher-kinded, i.e., is it a type constructor @M */ - def isHigherKinded: Boolean = false - - /** Does this type denote a stable reference (i.e. singleton type)? */ - def isStable: Boolean = false - - /** Is this type dangerous (i.e. it might contain conflicting - * type information when empty, so that it can be constructed - * so that type unsoundness results.) A dangerous type has an underlying - * type of the form T_1 with T_n { decls }, where one of the - * T_i (i > 1) is an abstract type. - */ - def isVolatile: Boolean = false - - /** Is this type guaranteed not to have `null` as a value? */ - def isNotNull: Boolean = false - - /** Is this type a structural refinement type (it ''refines'' members that have not been inherited) */ - def isStructuralRefinement: Boolean = false - - /** Does this type depend immediately on an enclosing method parameter? - * I.e., is it a singleton type whose termSymbol refers to an argument of the symbol's owner (which is a method)? - */ - def isImmediatelyDependent: Boolean = false - - /** Does this depend on an enclosing method parameter? */ - def isDependent: Boolean = IsDependentCollector.collect(this) - - /** True for WildcardType or BoundedWildcardType. */ - def isWildcard = false - - /** Is this type produced as a repair for an error? */ - def isError: Boolean = typeSymbol.isError || termSymbol.isError - - /** Is this type produced as a repair for an error? */ - def isErroneous: Boolean = ErroneousCollector.collect(this) - - /** Does this type denote a reference type which can be null? */ - // def isNullable: Boolean = false - - /** Can this type only be subtyped by bottom types? - * This is assessed to be the case if the class is final, - * and all type parameters (if any) are invariant. - */ - def isFinalType = - typeSymbol.isFinal && (typeSymbol.typeParams forall (_.variance == 0)) - - /** Is this type completed (i.e. not a lazy type)? */ - def isComplete: Boolean = true - - /** If this is a lazy type, assign a new type to `sym`. */ - def complete(sym: Symbol) {} - - /** The term symbol associated with the type - * Note that the symbol of the normalized type is returned (@see normalize) - */ - def termSymbol: Symbol = NoSymbol - - /** The type symbol associated with the type - * Note that the symbol of the normalized type is returned (@see normalize) - * A type's typeSymbol should if possible not be inspected directly, due to - * the likelihood that what is true for tp.typeSymbol is not true for - * tp.sym, due to normalization. - */ - def typeSymbol: Symbol = NoSymbol - - /** The term symbol ''directly'' associated with the type. - */ - def termSymbolDirect: Symbol = termSymbol - - /** The type symbol ''directly'' associated with the type. - * In other words, no normalization is performed: if this is an alias type, - * the symbol returned is that of the alias, not the underlying type. - */ - def typeSymbolDirect: Symbol = typeSymbol - - /** The base type underlying a type proxy, identity on all other types */ - def underlying: Type = this - - /** Widen from singleton type to its underlying non-singleton - * base type by applying one or more `underlying` dereferences, - * identity for all other types. - * - * class Outer { class C ; val x: C } - * val o: Outer - * <o.x.type>.widen = o.C - */ - def widen: Type = this - - /** Map a constant type or not-null-type to its underlying base type, - * identity for all other types. - */ - def deconst: Type = this - - /** The type of `this` of a class type or reference type. */ - def typeOfThis: Type = typeSymbol.typeOfThis - - /** Map to a singleton type which is a subtype of this type. - * The fallback implemented here gives - * T.narrow = T' forSome { type T' <: T with Singleton } - * Overridden where we know more about where types come from. - */ - /* - Note: this implementation of narrow is theoretically superior to the one - in use below, but imposed a significant performance penalty. It was in trunk - from svn r24960 through r25080. - */ - /* - def narrow: Type = - if (phase.erasedTypes) this - else commonOwner(this) freshExistential ".type" setInfo singletonBounds(this) tpe - */ - - /** Map to a singleton type which is a subtype of this type. - * The fallback implemented here gives: - * {{{ - * T.narrow = (T {}).this.type - * }}} - * Overridden where we know more about where types come from. - */ - def narrow: Type = - if (phase.erasedTypes) this - else { - val cowner = commonOwner(this) - refinedType(List(this), cowner, EmptyScope, cowner.pos).narrow - } - - /** For a TypeBounds type, itself; - * for a reference denoting an abstract type, its bounds, - * for all other types, a TypeBounds type all of whose bounds are this type. - */ - def bounds: TypeBounds = TypeBounds(this, this) - - /** For a class or intersection type, its parents. - * For a TypeBounds type, the parents of its hi bound. - * inherited by typerefs, singleton types, and refinement types, - * The empty list for all other types */ - def parents: List[Type] = List() - - /** For a class with nonEmpty parents, the first parent. - * Otherwise some specific fixed top type. - */ - def firstParent = if (parents.nonEmpty) parents.head else ObjectClass.tpe - - /** For a typeref or single-type, the prefix of the normalized type (@see normalize). - * NoType for all other types. */ - def prefix: Type = NoType - - /** A chain of all typeref or singletype prefixes of this type, longest first. - * (Only used from safeToString.) - */ - def prefixChain: List[Type] = this match { - case TypeRef(pre, _, _) => pre :: pre.prefixChain - case SingleType(pre, _) => pre :: pre.prefixChain - case _ => List() - } - - /** This type, without its type arguments @M */ - def typeConstructor: Type = this - - /** For a typeref, its arguments. The empty list for all other types */ - def typeArgs: List[Type] = List() - - /** A list of placeholder types derived from the type parameters. - * Used by RefinedType and TypeRef. - */ - protected def dummyArgs: List[Type] = typeParams map (_.typeConstructor) - - /** For a (nullary) method or poly type, its direct result type, - * the type itself for all other types. */ - def resultType: Type = this - - def resultType(actuals: List[Type]) = this - - /** Only used for dependent method types. */ - def resultApprox: Type = ApproximateDependentMap(resultType) - - /** If this is a TypeRef `clazz`[`T`], return the argument `T` - * otherwise return this type - */ - def remove(clazz: Symbol): Type = this - - /** For a curried/nullary method or poly type its non-method result type, - * the type itself for all other types */ - def finalResultType: Type = this - - /** For a method type, the number of its value parameter sections, - * 0 for all other types */ - def paramSectionCount: Int = 0 - - /** For a method or poly type, a list of its value parameter sections, - * the empty list for all other types */ - def paramss: List[List[Symbol]] = List() - - /** For a method or poly type, its first value parameter section, - * the empty list for all other types */ - def params: List[Symbol] = List() - - /** For a method or poly type, the types of its first value parameter section, - * the empty list for all other types */ - def paramTypes: List[Type] = List() - - /** For a (potentially wrapped) poly type, its type parameters, - * the empty list for all other types */ - def typeParams: List[Symbol] = List() - - /** For a (potentially wrapped) poly or existential type, its bound symbols, - * the empty list for all other types */ - def boundSyms: immutable.Set[Symbol] = emptySymbolSet - - /** Mixin a NotNull trait unless type already has one - * ...if the option is given, since it is causing typing bugs. - */ - def notNull: Type = - if (!settings.Ynotnull.value || isNotNull || phase.erasedTypes) this - else NotNullType(this) - - /** Replace formal type parameter symbols with actual type arguments. - * - * Amounts to substitution except for higher-kinded types. (See overridden method in TypeRef) -- @M - */ - def instantiateTypeParams(formals: List[Symbol], actuals: List[Type]): Type = - if (sameLength(formals, actuals)) this.subst(formals, actuals) else ErrorType - - /** If this type is an existential, turn all existentially bound variables to type skolems. - * @param owner The owner of the created type skolems - * @param origin The tree whose type was an existential for which the skolem was created. - */ - def skolemizeExistential(owner: Symbol, origin: AnyRef): Type = this - - /** A simple version of skolemizeExistential for situations where - * owner or unpack location do not matter (typically used in subtype tests) - */ - def skolemizeExistential: Type = skolemizeExistential(NoSymbol, null) - - /** Reduce to beta eta-long normal form. - * Expands type aliases and converts higher-kinded TypeRefs to PolyTypes. - * Functions on types are also implemented as PolyTypes. - * - * Example: (in the below, <List> is the type constructor of List) - * TypeRef(pre, <List>, List()) is replaced by - * PolyType(X, TypeRef(pre, <List>, List(X))) - */ - def normalize = this // @MAT - - /** Expands type aliases. */ - def dealias = this - - /** For a classtype or refined type, its defined or declared members; - * inherited by subtypes and typerefs. - * The empty scope for all other types. - */ - def decls: Scope = EmptyScope - - /** The defined or declared members with name `name` in this type; - * an OverloadedSymbol if several exist, NoSymbol if none exist. - * Alternatives of overloaded symbol appear in the order they are declared. - */ - def decl(name: Name): Symbol = findDecl(name, 0) - - /** A list of all non-private members defined or declared in this type. */ - def nonPrivateDecls: List[Symbol] = decls filter (x => !x.isPrivate) toList - - /** The non-private defined or declared members with name `name` in this type; - * an OverloadedSymbol if several exist, NoSymbol if none exist. - * Alternatives of overloaded symbol appear in the order they are declared. - */ - def nonPrivateDecl(name: Name): Symbol = findDecl(name, PRIVATE) - - /** A list of all members of this type (defined or inherited) - * Members appear in linearization order of their owners. - * Members with the same owner appear in reverse order of their declarations. - */ - def members: List[Symbol] = membersBasedOnFlags(0, 0) - - /** A list of all non-private members of this type (defined or inherited) */ - def nonPrivateMembers: List[Symbol] = membersBasedOnFlags(BridgeAndPrivateFlags, 0) - - /** A list of all non-private members of this type (defined or inherited), - * admitting members with given flags `admit` - */ - def nonPrivateMembersAdmitting(admit: Long): List[Symbol] = membersBasedOnFlags(BridgeAndPrivateFlags & ~admit, 0) - - /** A list of all implicit symbols of this type (defined or inherited) */ - def implicitMembers: List[Symbol] = membersBasedOnFlags(BridgeFlags, IMPLICIT) - - /** A list of all deferred symbols of this type (defined or inherited) */ - def deferredMembers: List[Symbol] = membersBasedOnFlags(BridgeFlags, DEFERRED) - - /** The member with given name, - * an OverloadedSymbol if several exist, NoSymbol if none exist */ - def member(name: Name): Symbol = - memberBasedOnName(name, BridgeFlags) - - /** The non-private member with given name, - * an OverloadedSymbol if several exist, NoSymbol if none exist. - * Bridges are excluded from the result - */ - def nonPrivateMember(name: Name): Symbol = - memberBasedOnName(name, BridgeAndPrivateFlags) - - /** All members with the given flags, excluding bridges. - */ - def membersWithFlags(requiredFlags: Long): List[Symbol] = - membersBasedOnFlags(BridgeFlags, requiredFlags) - - /** All non-private members with the given flags, excluding bridges. - */ - def nonPrivateMembersWithFlags(requiredFlags: Long): List[Symbol] = - membersBasedOnFlags(BridgeAndPrivateFlags, requiredFlags) - - /** The non-private member with given name, admitting members with given flags `admit`. - * "Admitting" refers to the fact that members with a PRIVATE, BRIDGE, or VBRIDGE - * flag are usually excluded from findMember results, but supplying any of those flags - * to this method disables that exclusion. - * - * An OverloadedSymbol if several exist, NoSymbol if none exists. - */ - def nonPrivateMemberAdmitting(name: Name, admit: Long): Symbol = - memberBasedOnName(name, BridgeAndPrivateFlags & ~admit) - - /** The non-local member with given name, - * an OverloadedSymbol if several exist, NoSymbol if none exist */ - def nonLocalMember(name: Name): Symbol = - memberBasedOnName(name, BridgeFlags | LOCAL) - - /** Members excluding and requiring the given flags. - * Note: unfortunately it doesn't work to exclude DEFERRED this way. - */ - def membersBasedOnFlags(excludedFlags: Long, requiredFlags: Long): List[Symbol] = - findMember(nme.ANYNAME, excludedFlags, requiredFlags, false).alternatives - - def memberBasedOnName(name: Name, excludedFlags: Long): Symbol = - findMember(name, excludedFlags, 0, false) - - /** The least type instance of given class which is a supertype - * of this type. Example: - * class D[T] - * class C extends p.D[Int] - * ThisType(C).baseType(D) = p.D[Int] - */ - def baseType(clazz: Symbol): Type = NoType - - /** This type as seen from prefix `pre` and class `clazz`. This means: - * Replace all thistypes of `clazz` or one of its subclasses - * by `pre` and instantiate all parameters by arguments of `pre`. - * Proceed analogously for thistypes referring to outer classes. - * - * Example: - * class D[T] { def m: T } - * class C extends p.D[Int] - * T.asSeenFrom(ThisType(C), D) (where D is owner of m) - * = Int - */ - def asSeenFrom(pre: Type, clazz: Symbol): Type = { - if (isTrivial || phase.erasedTypes && pre.typeSymbol != ArrayClass) this - else { -// scala.tools.nsc.util.trace.when(pre.isInstanceOf[ExistentialType])("X "+this+".asSeenfrom("+pre+","+clazz+" = ") { - incCounter(asSeenFromCount) - val start = startTimer(asSeenFromNanos) - val m = new AsSeenFromMap(pre.normalize, clazz) - val tp = m apply this - val tp1 = existentialAbstraction(m.capturedParams, tp) - val result: Type = - if (m.capturedSkolems.isEmpty) tp1 - else deriveType(m.capturedSkolems, _.cloneSymbol setFlag CAPTURED)(tp1) - - stopTimer(asSeenFromNanos, start) - result - } - } - - /** The info of `sym`, seen as a member of this type. - * - * Example: - * {{{ - * class D[T] { def m: T } - * class C extends p.D[Int] - * ThisType(C).memberType(m) = Int - * }}} - */ - def memberInfo(sym: Symbol): Type = { - sym.info.asSeenFrom(this, sym.owner) - } - - /** The type of `sym`, seen as a member of this type. */ - def memberType(sym: Symbol): Type = sym match { - case meth: MethodSymbol => - meth.typeAsMemberOf(this) - case _ => - computeMemberType(sym) - } - - def computeMemberType(sym: Symbol): Type = sym.tpeHK match { //@M don't prematurely instantiate higher-kinded types, they will be instantiated by transform, typedTypeApply, etc. when really necessary - case OverloadedType(_, alts) => - OverloadedType(this, alts) - case tp => - tp.asSeenFrom(this, sym.owner) - } - - /** Substitute types `to` for occurrences of references to - * symbols `from` in this type. - */ - def subst(from: List[Symbol], to: List[Type]): Type = - if (from.isEmpty) this - else new SubstTypeMap(from, to) apply this - - /** Substitute symbols `to` for occurrences of symbols `from` in this type. - * - * !!! NOTE !!!: If you need to do a substThis and a substSym, the substThis has to come - * first, as otherwise symbols will immediately get rebound in typeRef to the old - * symbol. - */ - def substSym(from: List[Symbol], to: List[Symbol]): Type = - if ((from eq to) || from.isEmpty) this - else new SubstSymMap(from, to) apply this - - /** Substitute all occurrences of `ThisType(from)` in this type by `to`. - * - * !!! NOTE !!!: If you need to do a substThis and a substSym, the substThis has to come - * first, as otherwise symbols will immediately get rebound in typeRef to the old - * symbol. - */ - def substThis(from: Symbol, to: Type): Type = - new SubstThisMap(from, to) apply this - def substThis(from: Symbol, to: Symbol): Type = - substThis(from, to.thisType) - - /** Performs both substThis and substSym, in that order. - * - * [JZ] Reverted `SubstThisAndSymMap` from 334872, which was not the same as - * `substThis(from, to).substSym(symsFrom, symsTo)`. - * - * `SubstThisAndSymMap` performs a breadth-first map over this type, which meant that - * symbol substitution occured before `ThisType` substitution. Consequently, in substitution - * of a `SingleType(ThisType(`from`), sym), symbols were rebound to `from` rather than `to`. - */ - def substThisAndSym(from: Symbol, to: Type, symsFrom: List[Symbol], symsTo: List[Symbol]): Type = - if (symsFrom eq symsTo) substThis(from, to) - else substThis(from, to).substSym(symsFrom, symsTo) - - /** Returns all parts of this type which satisfy predicate `p` */ - def filter(p: Type => Boolean): List[Type] = new FilterTypeCollector(p) collect this - def withFilter(p: Type => Boolean) = new FilterMapForeach(p) - - class FilterMapForeach(p: Type => Boolean) extends FilterTypeCollector(p){ - def foreach[U](f: Type => U): Unit = collect(Type.this) foreach f - def map[T](f: Type => T): List[T] = collect(Type.this) map f - } - - /** Returns optionally first type (in a preorder traversal) which satisfies predicate `p`, - * or None if none exists. - */ - def find(p: Type => Boolean): Option[Type] = new FindTypeCollector(p).collect(this) - - /** Apply `f` to each part of this type */ - def foreach(f: Type => Unit) { new ForEachTypeTraverser(f).traverse(this) } - - /** Apply `pf' to each part of this type on which the function is defined */ - def collect[T](pf: PartialFunction[Type, T]): List[T] = new CollectTypeCollector(pf).collect(this) - - /** Apply `f` to each part of this type; children get mapped before their parents */ - def map(f: Type => Type): Type = new TypeMap { - def apply(x: Type) = f(mapOver(x)) - } apply this - - /** Is there part of this type which satisfies predicate `p`? */ - def exists(p: Type => Boolean): Boolean = !find(p).isEmpty - - /** Does this type contain a reference to this symbol? */ - def contains(sym: Symbol): Boolean = new ContainsCollector(sym).collect(this) - - /** Does this type contain a reference to this type */ - def containsTp(tp: Type): Boolean = new ContainsTypeCollector(tp).collect(this) - - /** Is this type a subtype of that type? */ - def <:<(that: Type): Boolean = { - if (util.Statistics.enabled) stat_<:<(that) - else { - (this eq that) || - (if (explainSwitch) explain("<:", isSubType, this, that) - else isSubType(this, that, AnyDepth)) - } - } - - /** Is this type a subtype of that type in a pattern context? - * Any type arguments on the right hand side are replaced with - * fresh existentials, except for Arrays. - * - * See bug1434.scala for an example of code which would fail - * if only a <:< test were applied. - */ - def matchesPattern(that: Type): Boolean = { - (this <:< that) || ((this, that) match { - case (TypeRef(_, ArrayClass, List(arg1)), TypeRef(_, ArrayClass, List(arg2))) if arg2.typeSymbol.typeParams.nonEmpty => - arg1 matchesPattern arg2 - case (_, TypeRef(_, _, args)) => - val newtp = existentialAbstraction(args map (_.typeSymbol), that) - !(that =:= newtp) && (this <:< newtp) - case _ => - false - }) - } - - def stat_<:<(that: Type): Boolean = { - incCounter(subtypeCount) - val start = startTimer(subtypeNanos) - val result = - (this eq that) || - (if (explainSwitch) explain("<:", isSubType, this, that) - else isSubType(this, that, AnyDepth)) - stopTimer(subtypeNanos, start) - result - } - - /** Is this type a weak subtype of that type? True also for numeric types, i.e. Int weak_<:< Long. - */ - def weak_<:<(that: Type): Boolean = { - incCounter(subtypeCount) - val start = startTimer(subtypeNanos) - val result = - ((this eq that) || - (if (explainSwitch) explain("weak_<:", isWeakSubType, this, that) - else isWeakSubType(this, that))) - stopTimer(subtypeNanos, start) - result - } - - /** Is this type equivalent to that type? */ - def =:=(that: Type): Boolean = ( - (this eq that) || - (if (explainSwitch) explain("=", isSameType, this, that) - else isSameType(this, that)) - ); - - /** Does this type implement symbol `sym` with same or stronger type? */ - def specializes(sym: Symbol): Boolean = - if (explainSwitch) explain("specializes", specializesSym, this, sym) - else specializesSym(this, sym) - - /** Is this type close enough to that type so that members - * with the two type would override each other? - * This means: - * - Either both types are polytypes with the same number of - * type parameters and their result types match after renaming - * corresponding type parameters - * - Or both types are (nullary) method types with equivalent type parameter types - * and matching result types - * - Or both types are equivalent - * - Or phase.erasedTypes is false and both types are neither method nor - * poly types. - */ - def matches(that: Type): Boolean = matchesType(this, that, !phase.erasedTypes) - - /** Same as matches, except that non-method types are always assumed to match. */ - def looselyMatches(that: Type): Boolean = matchesType(this, that, true) - - /** The shortest sorted upwards closed array of types that contains - * this type as first element. - * - * A list or array of types ts is upwards closed if - * - * for all t in ts: - * for all typerefs p.s[args] such that t <: p.s[args] - * there exists a typeref p'.s[args'] in ts such that - * t <: p'.s['args] <: p.s[args], - * - * and - * - * for all singleton types p.s such that t <: p.s - * there exists a singleton type p'.s in ts such that - * t <: p'.s <: p.s - * - * Sorting is with respect to Symbol.isLess() on type symbols. - */ - def baseTypeSeq: BaseTypeSeq = baseTypeSingletonSeq(this) - - /** The maximum depth (@see maxDepth) - * of each type in the BaseTypeSeq of this type. - */ - def baseTypeSeqDepth: Int = 1 - - /** The list of all baseclasses of this type (including its own typeSymbol) - * in reverse linearization order, starting with the class itself and ending - * in class Any. - */ - def baseClasses: List[Symbol] = List() - - /** - * @param sym the class symbol - * @return the index of given class symbol in the BaseTypeSeq of this type, - * or -1 if no base type with given class symbol exists. - */ - def baseTypeIndex(sym: Symbol): Int = { - val bts = baseTypeSeq - var lo = 0 - var hi = bts.length - 1 - while (lo <= hi) { - val mid = (lo + hi) / 2 - val btssym = bts.typeSymbol(mid) - if (sym == btssym) return mid - else if (sym isLess btssym) hi = mid - 1 - else if (btssym isLess sym) lo = mid + 1 - else abort() - } - -1 - } - - /** If this is a poly- or methodtype, a copy with cloned type / value parameters - * owned by `owner`. Identity for all other types. - */ - def cloneInfo(owner: Symbol) = this - - /** Make sure this type is correct as the info of given owner; clone it if not. */ - def atOwner(owner: Symbol) = this - - protected def objectPrefix = "object " - protected def packagePrefix = "package " - def trimPrefix(str: String) = str stripPrefix objectPrefix stripPrefix packagePrefix - - /** The string representation of this type used as a prefix */ - def prefixString = trimPrefix(toString) + "#" - - /** Convert toString avoiding infinite recursions by cutting off - * after `maxTostringRecursions` recursion levels. Uses `safeToString` - * to produce a string on each level. - */ - override def toString: String = typeToString(this) - - /** Method to be implemented in subclasses. - * Converts this type to a string in calling toString for its parts. - */ - def safeToString: String = super.toString - - /** The string representation of this type, with singletypes explained. */ - def toLongString = { - val str = toString - if (str == "type") widen.toString - else if ((str endsWith ".type") && !typeSymbol.isModuleClass) str + " (with underlying type " + widen + ")" - else str - } - - /** The string representation of this type when the direct object in a sentence. - * Normally this is no different from the regular representation, but modules - * read better as "object Foo" here and "Foo.type" the rest of the time. - */ - def directObjectString = safeToString - - /** A test whether a type contains any unification type variables. - * Overridden with custom logic except where trivially true. - */ - def isGround: Boolean = this match { - case ThisType(_) | NoPrefix | WildcardType | NoType | ErrorType | ConstantType(_) => - true - case _ => - typeVarToOriginMap(this) eq this - } - - /** If this is a symbol loader type, load and assign a new type to `sym`. */ - def load(sym: Symbol) {} - - private def findDecl(name: Name, excludedFlags: Int): Symbol = { - var alts: List[Symbol] = List() - var sym: Symbol = NoSymbol - var e: ScopeEntry = decls.lookupEntry(name) - while (e ne null) { - if (!e.sym.hasFlag(excludedFlags)) { - if (sym == NoSymbol) sym = e.sym - else { - if (alts.isEmpty) alts = List(sym) - alts = e.sym :: alts - } - } - e = decls.lookupNextEntry(e) - } - if (alts.isEmpty) sym - else (baseClasses.head.newOverloaded(this, alts)) - } - - /** - * Find member(s) in this type. If several members matching criteria are found, they are - * returned in an OverloadedSymbol - * - * @param name The member's name, where nme.ANYNAME means `unspecified` - * @param excludedFlags Returned members do not have these flags - * @param requiredFlags Returned members do have these flags - * @param stableOnly If set, return only members that are types or stable values - */ - //TODO: use narrow only for modules? (correct? efficiency gain?) - def findMember(name: Name, excludedFlags: Long, requiredFlags: Long, stableOnly: Boolean): Symbol = { - // if this type contains type variables, put them to sleep for a while -- don't just wipe them out by - // replacing them by the corresponding type parameter, as that messes up (e.g.) type variables in type refinements - // without this, the matchesType call would lead to type variables on both sides - // of a subtyping/equality judgement, which can lead to recursive types being constructed. - // See (t0851) for a situation where this happens. - val suspension: List[TypeVar] = if (this.isGround) null else suspendTypeVarsInType(this) - - incCounter(findMemberCount) - val start = startTimer(findMemberNanos) - - //Console.println("find member " + name.decode + " in " + this + ":" + this.baseClasses)//DEBUG - var members: Scope = null - var member: Symbol = NoSymbol - var excluded = excludedFlags | DEFERRED - var continue = true - var self: Type = null - var membertpe: Type = null - while (continue) { - continue = false - val bcs0 = baseClasses - var bcs = bcs0 - while (!bcs.isEmpty) { - val decls = bcs.head.info.decls - var entry = - if (name == nme.ANYNAME) decls.elems else decls.lookupEntry(name) - while (entry ne null) { - val sym = entry.sym - if (sym hasAllFlags requiredFlags) { - val excl = sym.getFlag(excluded) - if (excl == 0L && - (// omit PRIVATE LOCALS unless selector class is contained in class owning the def. - (bcs eq bcs0) || - !sym.isPrivateLocal || - (bcs0.head.hasTransOwner(bcs.head)))) { - if (name.isTypeName || stableOnly && sym.isStable) { - stopTimer(findMemberNanos, start) - if (suspension ne null) suspension foreach (_.suspended = false) - return sym - } else if (member == NoSymbol) { - member = sym - } else if (members eq null) { - if (member.name != sym.name || - !(member == sym || - member.owner != sym.owner && - !sym.isPrivate && { - if (self eq null) self = this.narrow - if (membertpe eq null) membertpe = self.memberType(member) - (membertpe matches self.memberType(sym)) - })) { - members = newScope - members enter member - members enter sym - } - } else { - var prevEntry = members.lookupEntry(sym.name) - var symtpe: Type = null - while ((prevEntry ne null) && - !(prevEntry.sym == sym || - prevEntry.sym.owner != sym.owner && - !sym.hasFlag(PRIVATE) && { - if (self eq null) self = this.narrow - if (symtpe eq null) symtpe = self.memberType(sym) - self.memberType(prevEntry.sym) matches symtpe - })) { - prevEntry = members lookupNextEntry prevEntry - } - if (prevEntry eq null) { - members enter sym - } - } - } else if (excl == DEFERRED.toLong) { - continue = true - } - } - entry = if (name == nme.ANYNAME) entry.next else decls lookupNextEntry entry - } // while (entry ne null) - // excluded = excluded | LOCAL - bcs = if (name == nme.CONSTRUCTOR) Nil else bcs.tail - } // while (!bcs.isEmpty) - excluded = excludedFlags - } // while (continue) - stopTimer(findMemberNanos, start) - if (suspension ne null) suspension foreach (_.suspended = false) - if (members eq null) { - if (member == NoSymbol) incCounter(noMemberCount) - member - } else { - incCounter(multMemberCount) - baseClasses.head.newOverloaded(this, members.toList) - } - } - /** The (existential or otherwise) skolems and existentially quantified variables which are free in this type */ - def skolemsExceptMethodTypeParams: List[Symbol] = { - var boundSyms: List[Symbol] = List() - var skolems: List[Symbol] = List() - for (t <- this) { - t match { - case ExistentialType(quantified, qtpe) => - boundSyms = boundSyms ::: quantified - case TypeRef(_, sym, _) => - if ((sym.isExistentialSkolem || sym.isGADTSkolem) && // treat GADT skolems like existential skolems - !((boundSyms contains sym) || (skolems contains sym))) - skolems = sym :: skolems - case _ => - } - } - skolems - } - - // Implementation of Annotatable for all types but AnnotatedType, which - // 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) - - /** Remove any annotations from this type and from any - * types embedded in this type. */ - def stripAnnotations = StripAnnotationsMap(this) - - /** Set the self symbol of an annotated type, or do nothing - * otherwise. */ - def withSelfsym(sym: Symbol) = this - - /** The selfsym of an annotated type, or NoSymbol of anything else */ - def selfsym: Symbol = NoSymbol - - /** The kind of this type; used for debugging */ - def kind: String = "unknown type of class "+getClass() - } - -// Subclasses ------------------------------------------------------------ - - trait UniqueType extends Product { - final override val hashCode = scala.runtime.ScalaRunTime._hashCode(this) - } - - /** A base class for types that defer some operations - * to their immediate supertype. - */ - abstract class SubType extends Type { - def supertype: Type - override def parents: List[Type] = supertype.parents - override def decls: Scope = supertype.decls - override def baseType(clazz: Symbol): Type = supertype.baseType(clazz) - override def baseTypeSeq: BaseTypeSeq = supertype.baseTypeSeq - override def baseTypeSeqDepth: Int = supertype.baseTypeSeqDepth - override def baseClasses: List[Symbol] = supertype.baseClasses - override def isNotNull = supertype.isNotNull - } - - case class NotNullType(override val underlying: Type) extends SubType with RewrappingTypeProxy { - def supertype = underlying - protected def rewrap(newtp: Type): Type = NotNullType(newtp) - override def isNotNull: Boolean = true - override def notNull = this - override def deconst: Type = underlying //todo: needed? - override def safeToString: String = underlying.toString + " with NotNull" - override def kind = "NotNullType" - } - - /** A base class for types that represent a single value - * (single-types and this-types). - */ - abstract class SingletonType extends SubType with SimpleTypeProxy { - def supertype = underlying - override def isTrivial = false - override def isStable = true - override def isVolatile = underlying.isVolatile - override def widen: Type = underlying.widen - override def baseTypeSeq: BaseTypeSeq = { - incCounter(singletonBaseTypeSeqCount) - underlying.baseTypeSeq prepend this - } - override def isHigherKinded = false // singleton type classifies objects, thus must be kind * - override def safeToString: String = { - // Avoiding printing Predef.type and scala.package.type as "type", - // since in all other cases we omit those prefixes. - val pre = underlying.typeSymbol.skipPackageObject - if (pre.isOmittablePrefix) pre.fullName + ".type" - else prefixString + "type" - } - -/* - override def typeOfThis: Type = typeSymbol.typeOfThis - override def bounds: TypeBounds = TypeBounds(this, this) - override def prefix: Type = NoType - override def typeArgs: List[Type] = List() - override def typeParams: List[Symbol] = List() -*/ - } - - /** An object representing an erroneous type */ - case object ErrorType extends Type { - // todo see whether we can do without - override def isError: Boolean = true - override def decls: Scope = new ErrorScope(NoSymbol) - override def findMember(name: Name, excludedFlags: Long, requiredFlags: Long, stableOnly: Boolean): Symbol = { - var sym = decls lookup name - if (sym == NoSymbol) { - sym = NoSymbol.newErrorSymbol(name) - decls enter sym - } - sym - } - override def baseType(clazz: Symbol): Type = this - override def safeToString: String = "<error>" - override def narrow: Type = this - // override def isNullable: Boolean = true - override def kind = "ErrorType" - } - - /** An object representing an unknown type, used during type inference. - * If you see WildcardType outside of inference it is almost certainly a bug. - */ - case object WildcardType extends Type { - override def isWildcard = true - override def safeToString: String = "?" - // 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 with BoundedWildcardTypeApi { - override def isWildcard = true - override def safeToString: String = "?" + bounds - override def kind = "BoundedWildcardType" - } - - object BoundedWildcardType extends BoundedWildcardTypeExtractor - - /** An object representing a non-existing type */ - case object NoType extends Type { - override def isTrivial: Boolean = true - override def safeToString: String = "<notype>" - // override def isNullable: Boolean = true - override def kind = "NoType" - } - - /** An object representing a non-existing prefix */ - case object NoPrefix extends Type { - override def isTrivial: Boolean = true - override def isStable: Boolean = true - override def prefixString = "" - override def safeToString: String = "<noprefix>" - // override def isNullable: Boolean = true - override def kind = "NoPrefixType" - } - - /** A class for this-types of the form <sym>.this.type - */ - abstract case class ThisType(sym: Symbol) extends SingletonType with ThisTypeApi { - assert(sym.isClass) - //assert(sym.isClass && !sym.isModuleClass || sym.isRoot, sym) - override def isTrivial: Boolean = sym.isPackageClass - override def isNotNull = true - override def typeSymbol = sym - override def underlying: Type = sym.typeOfThis - override def isVolatile = false - override def isHigherKinded = sym.isRefinementClass && underlying.isHigherKinded - override def prefixString = - if (settings.debug.value) sym.nameString + ".this." - else if (sym.isAnonOrRefinementClass) "this." - else if (sym.isOmittablePrefix) "" - else if (sym.isModuleClass) sym.fullNameString + "." - else sym.nameString + ".this." - override def safeToString: String = - if (sym.isEffectiveRoot) "" + sym.name - else super.safeToString - override def narrow: Type = this - override def kind = "ThisType" - } - - final class UniqueThisType(sym: Symbol) extends ThisType(sym) with UniqueType { } - - object ThisType extends ThisTypeExtractor { - def apply(sym: Symbol): Type = { - if (!phase.erasedTypes) unique(new UniqueThisType(sym)) - else if (sym.isImplClass) sym.typeOfThis - else sym.tpe - } - } - - /** A class for singleton types of the form `<prefix>.<sym.name>.type`. - * Cannot be created directly; one should always use `singleType` for creation. - */ - abstract case class SingleType(pre: Type, sym: Symbol) extends SingletonType with SingleTypeApi { - override val isTrivial: Boolean = pre.isTrivial - override def isGround = sym.isPackageClass || pre.isGround - - // override def isNullable = underlying.isNullable - override def isNotNull = underlying.isNotNull - private[reflect] var underlyingCache: Type = NoType - private[reflect] var underlyingPeriod = NoPeriod - override def underlying: Type = { - val cache = underlyingCache - if (underlyingPeriod == currentPeriod && cache != null) cache - else { - defineUnderlyingOfSingleType(this) - underlyingCache - } - } - - // more precise conceptually, but causes cyclic errors: (paramss exists (_ contains sym)) - override def isImmediatelyDependent = (sym ne NoSymbol) && (sym.owner.isMethod && sym.isValueParameter) - - override def isVolatile : Boolean = underlying.isVolatile && !sym.isStable -/* - override def narrow: Type = { - if (phase.erasedTypes) this - else { - val thissym = refinedType(List(this), sym.owner, EmptyScope).typeSymbol - if (sym.owner != NoSymbol) { - //Console.println("narrowing module " + sym + thissym.owner); - thissym.typeOfThis = this - } - thissym.thisType - } - } -*/ - override def narrow: Type = this - - override def termSymbol = sym - override def prefix: Type = pre - override def prefixString = ( - if (sym.skipPackageObject.isOmittablePrefix) "" - else if (sym.isPackageObjectOrClass) pre.prefixString - else pre.prefixString + sym.nameString + "." - ) - override def kind = "SingleType" - } - - final class UniqueSingleType(pre: Type, sym: Symbol) extends SingleType(pre, sym) with UniqueType { } - - object SingleType extends SingleTypeExtractor { - def apply(pre: Type, sym: Symbol): Type = { - unique(new UniqueSingleType(pre, sym)) - } - } - - protected def defineUnderlyingOfSingleType(tpe: SingleType) = { - val period = tpe.underlyingPeriod - if (period != currentPeriod) { - tpe.underlyingPeriod = currentPeriod - if (!isValid(period)) { - // [Eugene to Paul] needs review - tpe.underlyingCache = if (tpe.sym == NoSymbol) ThisType(rootMirror.RootClass) else tpe.pre.memberType(tpe.sym).resultType; - assert(tpe.underlyingCache ne tpe, tpe) - } - } - } - - abstract case class SuperType(thistpe: Type, supertpe: Type) extends SingletonType with SuperTypeApi { - override val isTrivial: Boolean = thistpe.isTrivial && supertpe.isTrivial - override def isNotNull = true; - override def typeSymbol = thistpe.typeSymbol - override def underlying = supertpe - override def prefix: Type = supertpe.prefix - override def prefixString = thistpe.prefixString.replaceAll("""\bthis\.$""", "super.") - override def narrow: Type = thistpe.narrow - override def kind = "SuperType" - } - - final class UniqueSuperType(thistp: Type, supertp: Type) extends SuperType(thistp, supertp) with UniqueType { } - - object SuperType extends SuperTypeExtractor { - def apply(thistp: Type, supertp: Type): Type = { - if (phase.erasedTypes) supertp - else unique(new UniqueSuperType(thistp, supertp)) - } - } - - /** A class for the bounds of abstract types and type parameters - */ - abstract case class TypeBounds(lo: Type, hi: Type) extends SubType with TypeBoundsApi { - def supertype = hi - override val isTrivial: Boolean = lo.isTrivial && hi.isTrivial - override def bounds: TypeBounds = this - def containsType(that: Type) = that match { - case TypeBounds(_, _) => that <:< this - case _ => lo <:< that && that <:< hi - } - private def lowerString = if (emptyLowerBound) "" else " >: " + lo - private def upperString = if (emptyUpperBound) "" else " <: " + hi - private def emptyLowerBound = lo.typeSymbolDirect eq NothingClass - private def emptyUpperBound = hi.typeSymbolDirect eq AnyClass - def isEmptyBounds = emptyLowerBound && emptyUpperBound - - // override def isNullable: Boolean = NullClass.tpe <:< lo; - override def safeToString = lowerString + upperString - override def kind = "TypeBoundsType" - } - - final class UniqueTypeBounds(lo: Type, hi: Type) extends TypeBounds(lo, hi) with UniqueType { } - - object TypeBounds extends TypeBoundsExtractor { - def empty: TypeBounds = apply(NothingClass.tpe, AnyClass.tpe) - def upper(hi: Type): TypeBounds = apply(NothingClass.tpe, hi) - def lower(lo: Type): TypeBounds = apply(lo, AnyClass.tpe) - def apply(lo: Type, hi: Type): TypeBounds = { - unique(new UniqueTypeBounds(lo, hi)).asInstanceOf[TypeBounds] - } - } - - /** A common base class for intersection types and class types - */ - abstract class CompoundType extends Type { - - private[reflect] var baseTypeSeqCache: BaseTypeSeq = _ - private[reflect] var baseTypeSeqPeriod = NoPeriod - private[reflect] var baseClassesCache: List[Symbol] = _ - private[reflect] var baseClassesPeriod = NoPeriod - - override def baseTypeSeq: BaseTypeSeq = { - val cached = baseTypeSeqCache - if (baseTypeSeqPeriod == currentPeriod && cached != null && cached != undetBaseTypeSeq) - cached - else { - defineBaseTypeSeqOfCompoundType(this) - if (baseTypeSeqCache eq undetBaseTypeSeq) - throw new RecoverableCyclicReference(typeSymbol) - - baseTypeSeqCache - } - } - - override def baseTypeSeqDepth: Int = baseTypeSeq.maxDepth - - override def baseClasses: List[Symbol] = { - val cached = baseClassesCache - if (baseClassesPeriod == currentPeriod && cached != null) cached - else { - defineBaseClassesOfCompoundType(this) - if (baseClassesCache eq null) - throw new RecoverableCyclicReference(typeSymbol) - - baseClassesCache - } - } - - /** The slightly less idiomatic use of Options is due to - * performance considerations. A version using for comprehensions - * might be too slow (this is deemed a hotspot of the type checker). - * - * See with Martin before changing this method. - */ - def memo[A](op1: => A)(op2: Type => A): A = { - def updateCache(): A = { - intersectionWitness(parents) = new WeakReference(this) - op1 - } - - intersectionWitness get parents match { - case Some(ref) => - ref.get match { - case Some(w) => if (w eq this) op1 else op2(w) - case None => updateCache() - } - case None => updateCache() - } - } - - override def baseType(sym: Symbol): Type = { - val index = baseTypeIndex(sym) - if (index >= 0) baseTypeSeq(index) else NoType - } - - override def narrow: Type = typeSymbol.thisType - override def isNotNull: Boolean = parents exists (_.isNotNull) - - override def isStructuralRefinement: Boolean = - typeSymbol.isAnonOrRefinementClass && decls.exists(_.isPossibleInRefinement) - - // override def isNullable: Boolean = - // parents forall (p => p.isNullable && !p.typeSymbol.isAbstractType); - - override def safeToString: String = parentsString(parents) + ( - (if (settings.debug.value || parents.isEmpty || (decls.elems ne null)) - decls.mkString("{", "; ", "}") else "") - ) - } - - protected def defineBaseTypeSeqOfCompoundType(tpe: CompoundType) = { - val period = tpe.baseTypeSeqPeriod - if (period != currentPeriod) { - tpe.baseTypeSeqPeriod = currentPeriod - if (!isValidForBaseClasses(period)) { - if (tpe.parents.exists(_.exists(_.isInstanceOf[TypeVar]))) { - // rename type vars to fresh type params, take base type sequence of - // resulting type, and rename back all the entries in that sequence - var tvs = Set[TypeVar]() - for (p <- tpe.parents) - for (t <- p) t match { - case tv: TypeVar => tvs += tv - case _ => - } - val varToParamMap: Map[Type, Symbol] = - mapFrom[TypeVar, Type, Symbol](tvs.toList)(_.origin.typeSymbol.cloneSymbol) - val paramToVarMap = varToParamMap map (_.swap) - val varToParam = new TypeMap { - def apply(tp: Type) = varToParamMap get tp match { - case Some(sym) => sym.tpe - case _ => mapOver(tp) - } - } - val paramToVar = new TypeMap { - def apply(tp: Type) = tp match { - case TypeRef(_, tsym, _) if paramToVarMap.isDefinedAt(tsym) => paramToVarMap(tsym) - case _ => mapOver(tp) - } - } - val bts = copyRefinedType(tpe.asInstanceOf[RefinedType], tpe.parents map varToParam, varToParam mapOver tpe.decls).baseTypeSeq - tpe.baseTypeSeqCache = bts lateMap paramToVar - } else { - incCounter(compoundBaseTypeSeqCount) - tpe.baseTypeSeqCache = undetBaseTypeSeq - tpe.baseTypeSeqCache = if (tpe.typeSymbol.isRefinementClass) - tpe.memo(compoundBaseTypeSeq(tpe))(_.baseTypeSeq updateHead tpe.typeSymbol.tpe) - else - compoundBaseTypeSeq(tpe) - // [Martin] suppressing memo-ization solves the problem with "same type after erasure" errors - // when compiling with - // scalac scala.collection.IterableViewLike.scala scala.collection.IterableLike.scala - // I have not yet figured out precisely why this is the case. - // My current assumption is that taking memos forces baseTypeSeqs to be computed - // at stale types (i.e. the underlying typeSymbol has already another type). - // I do not yet see precisely why this would cause a problem, but it looks - // fishy in any case. - } - } - } - //Console.println("baseTypeSeq(" + typeSymbol + ") = " + baseTypeSeqCache.toList);//DEBUG - if (tpe.baseTypeSeqCache eq undetBaseTypeSeq) - throw new TypeError("illegal cyclic inheritance involving " + tpe.typeSymbol) - } - - protected def defineBaseClassesOfCompoundType(tpe: CompoundType) = { - def computeBaseClasses: List[Symbol] = - if (tpe.parents.isEmpty) List(tpe.typeSymbol) - else { - //Console.println("computing base classes of " + typeSymbol + " at phase " + phase);//DEBUG - // optimized, since this seems to be performance critical - val superclazz = tpe.firstParent - var mixins = tpe.parents.tail - val sbcs = superclazz.baseClasses - var bcs = sbcs - def isNew(clazz: Symbol): Boolean = - superclazz.baseTypeIndex(clazz) < 0 && - { var p = bcs; - while ((p ne sbcs) && (p.head != clazz)) p = p.tail; - p eq sbcs - } - while (!mixins.isEmpty) { - def addMixinBaseClasses(mbcs: List[Symbol]): List[Symbol] = - if (mbcs.isEmpty) bcs - else if (isNew(mbcs.head)) mbcs.head :: addMixinBaseClasses(mbcs.tail) - else addMixinBaseClasses(mbcs.tail) - bcs = addMixinBaseClasses(mixins.head.baseClasses) - mixins = mixins.tail - } - tpe.typeSymbol :: bcs - } - val period = tpe.baseClassesPeriod - if (period != currentPeriod) { - tpe.baseClassesPeriod = currentPeriod - if (!isValidForBaseClasses(period)) { - tpe.baseClassesCache = null - tpe.baseClassesCache = tpe.memo(computeBaseClasses)(tpe.typeSymbol :: _.baseClasses.tail) - } - } - if (tpe.baseClassesCache eq null) - throw new TypeError("illegal cyclic reference involving " + tpe.typeSymbol) - } - - /** A class representing intersection types with refinements of the form - * `<parents_0> with ... with <parents_n> { decls }` - * Cannot be created directly; - * one should always use `refinedType` for creation. - */ - case class RefinedType(override val parents: List[Type], - override val decls: Scope) extends CompoundType with RefinedTypeApi { - - override def isHigherKinded = ( - parents.nonEmpty && - (parents forall (_.isHigherKinded)) && - !phase.erasedTypes - ) - - override def typeParams = - if (isHigherKinded) firstParent.typeParams - else super.typeParams - - //@M may result in an invalid type (references to higher-order args become dangling ) - override def typeConstructor = - copyRefinedType(this, parents map (_.typeConstructor), decls) - - final override def normalize: Type = - if (phase.erasedTypes) normalizeImpl - else { - if (normalized eq null) normalized = normalizeImpl - normalized - } - - private var normalized: Type = _ - private def normalizeImpl = { - // TODO see comments around def intersectionType and def merge - def flatten(tps: List[Type]): List[Type] = tps flatMap { case RefinedType(parents, ds) if ds.isEmpty => flatten(parents) case tp => List(tp) } - val flattened = flatten(parents).distinct - if (decls.isEmpty && flattened.tail.isEmpty) { - flattened.head - } else if (flattened != parents) { - refinedType(flattened, if (typeSymbol eq NoSymbol) NoSymbol else typeSymbol.owner, decls, NoPosition) - } else if (isHigherKinded) { - // MO to AM: This is probably not correct - // If they are several higher-kinded parents with different bounds we need - // to take the intersection of their bounds - typeFun( - typeParams, - RefinedType( - parents map { - case TypeRef(pre, sym, List()) => TypeRef(pre, sym, dummyArgs) - case p => p - }, - decls, - typeSymbol)) - } else super.normalize - } - - /** A refined type P1 with ... with Pn { decls } is volatile if - * one of the parent types Pi is an abstract type, and - * either i > 1, or decls or a following parent Pj, j > 1, contributes - * an abstract member. - * A type contributes an abstract member if it has an abstract member which - * is also a member of the whole refined type. A scope `decls` contributes - * an abstract member if it has an abstract definition which is also - * a member of the whole type. - */ - override def isVolatile = { - def isVisible(m: Symbol) = - this.nonPrivateMember(m.name).alternatives contains m - def contributesAbstractMembers(p: Type) = - p.deferredMembers exists isVisible - - ((parents exists (_.isVolatile)) - || - (parents dropWhile (! _.typeSymbol.isAbstractType) match { - case ps @ (_ :: ps1) => - (ps ne parents) || - (ps1 exists contributesAbstractMembers) || - (decls.iterator exists (m => m.isDeferred && isVisible(m))) - case _ => - false - })) - } - - override def kind = "RefinedType" - } - - final class RefinedType0(parents: List[Type], decls: Scope, clazz: Symbol) extends RefinedType(parents, decls) { - override def typeSymbol = clazz - } - - object RefinedType extends RefinedTypeExtractor { - def apply(parents: List[Type], decls: Scope, clazz: Symbol): RefinedType = - new RefinedType0(parents, decls, clazz) - } - - /** Overridden in reflection compiler */ - def validateClassInfo(tp: ClassInfoType) {} - - /** A class representing a class info - */ - case class ClassInfoType( - override val parents: List[Type], - override val decls: Scope, - override val typeSymbol: Symbol) extends CompoundType with ClassInfoTypeApi - { - validateClassInfo(this) - - /** refs indices */ - private final val NonExpansive = 0 - private final val Expansive = 1 - - /** initialization states */ - private final val UnInitialized = 0 - private final val Initializing = 1 - private final val Initialized = 2 - - private type RefMap = Map[Symbol, immutable.Set[Symbol]] - - /** All type parameters reachable from given type parameter - * by a path which contains at least one expansive reference. - * @See Kennedy, Pierce: On Decidability of Nominal Subtyping with Variance - */ - private[scala] def expansiveRefs(tparam: Symbol) = { - if (state == UnInitialized) { - computeRefs() - while (state != Initialized) propagate() - } - getRefs(Expansive, tparam) - } - - /* The rest of this class is auxiliary code for `expansiveRefs` - */ - - /** The type parameters which are referenced type parameters of this class. - * Two entries: refs(0): Non-expansive references - * refs(1): Expansive references - * Syncnote: This var need not be protected with synchronized, because - * it is accessed only from expansiveRefs, which is called only from - * Typer. - */ - private var refs: Array[RefMap] = _ - - /** The initialization state of the class: UnInialized --> Initializing --> Initialized - * Syncnote: This var need not be protected with synchronized, because - * it is accessed only from expansiveRefs, which is called only from - * Typer. - */ - private var state = UnInitialized - - /** Get references for given type parameter - * @param which in {NonExpansive, Expansive} - * @param from The type parameter from which references originate. - */ - private def getRefs(which: Int, from: Symbol): Set[Symbol] = refs(which) get from match { - case Some(set) => set - case none => Set() - } - - /** Augment existing refs map with reference <pre>from -> to</pre> - * @param which <- {NonExpansive, Expansive} - */ - private def addRef(which: Int, from: Symbol, to: Symbol) { - refs(which) = refs(which) + (from -> (getRefs(which, from) + to)) - } - - /** Augment existing refs map with references <pre>from -> sym</pre>, for - * all elements <pre>sym</pre> of set `to`. - * @param which <- {NonExpansive, Expansive} - */ - private def addRefs(which: Int, from: Symbol, to: Set[Symbol]) { - refs(which) = refs(which) + (from -> (getRefs(which, from) ++ to)) - } - - /** The ClassInfoType which belongs to the class containing given type parameter - */ - private def classInfo(tparam: Symbol): ClassInfoType = - tparam.owner.info.resultType match { - case ci: ClassInfoType => ci - case _ => classInfo(ObjectClass) // something's wrong; fall back to safe value - // (this can happen only for erroneous programs). - } - - private object enterRefs extends TypeMap { - private var tparam: Symbol = _ - - def apply(tp: Type): Type = { - tp match { - case tr @ TypeRef(_, sym, args) if args.nonEmpty => - val tparams = tr.initializedTypeParams - if (settings.debug.value && !sameLength(tparams, args)) - debugwarn("Mismatched zip in computeRefs(): " + sym.info.typeParams + ", " + args) - - foreach2(tparams, args) { (tparam1, arg) => - if (arg contains tparam) { - addRef(NonExpansive, tparam, tparam1) - if (arg.typeSymbol != tparam) - addRef(Expansive, tparam, tparam1) - } - } - case _ => - } - mapOver(tp) - } - def enter(tparam0: Symbol, parent: Type) { - this.tparam = tparam0 - this(parent) - } - } - - /** Compute initial (one-step) references and set state to `Initializing`. - */ - private def computeRefs() { - refs = Array(Map(), Map()) - typeSymbol.typeParams foreach { tparam => - parents foreach { p => - enterRefs.enter(tparam, p) - } - } - state = Initializing - } - - /** Propagate to form transitive closure. - * Set state to Initialized if no change resulted from propagation. - * @return true iff there as a change in last iteration - */ - private def propagate(): Boolean = { - if (state == UnInitialized) computeRefs() - //Console.println("Propagate "+symbol+", initial expansive = "+refs(Expansive)+", nonexpansive = "+refs(NonExpansive))//DEBUG - val lastRefs = Array(refs(0), refs(1)) - state = Initialized - var change = false - for ((from, targets) <- refs(NonExpansive).iterator) - for (target <- targets) { - var thatInfo = classInfo(target) - if (thatInfo.state != Initialized) - change = change | thatInfo.propagate() - addRefs(NonExpansive, from, thatInfo.getRefs(NonExpansive, target)) - addRefs(Expansive, from, thatInfo.getRefs(Expansive, target)) - } - for ((from, targets) <- refs(Expansive).iterator) - for (target <- targets) { - var thatInfo = classInfo(target) - if (thatInfo.state != Initialized) - change = change | thatInfo.propagate() - addRefs(Expansive, from, thatInfo.getRefs(NonExpansive, target)) - } - change = change || refs(0) != lastRefs(0) || refs(1) != lastRefs(1) - if (change) state = Initializing - //else Console.println("Propagate "+symbol+", final expansive = "+refs(Expansive)+", nonexpansive = "+refs(NonExpansive))//DEBUG - change - } - - // override def isNullable: Boolean = - // symbol == AnyClass || - // symbol != NothingClass && (symbol isSubClass ObjectClass) && !(symbol isSubClass NonNullClass); - - // override def isNonNull: Boolean = symbol == NonNullClass || super.isNonNull; - override def kind = "ClassInfoType" - - override def safeToString = - if (settings.debug.value || decls.size > 1) - formattedToString - else - super.safeToString - - /** A nicely formatted string with newlines and such. - */ - def formattedToString: String = - parents.mkString("\n with ") + - (if (settings.debug.value || parents.isEmpty || (decls.elems ne null)) - decls.mkString(" {\n ", "\n ", "\n}") else "") - } - - object ClassInfoType extends ClassInfoTypeExtractor - - class PackageClassInfoType(decls: Scope, clazz: Symbol) - extends ClassInfoType(List(), decls, clazz) - - /** A class representing a constant type. - * - * @param value ... - */ - abstract case class ConstantType(value: Constant) extends SingletonType with ConstantTypeApi { - override def underlying: Type = value.tpe - assert(underlying.typeSymbol != UnitClass) - override def isTrivial: Boolean = true - override def isNotNull = value.value != null - override def deconst: Type = underlying - override def safeToString: String = - underlying.toString + "(" + value.escapedStringValue + ")" - // override def isNullable: Boolean = value.value eq null - // override def isNonNull: Boolean = value.value ne null - override def kind = "ConstantType" - } - - final class UniqueConstantType(value: Constant) extends ConstantType(value) with UniqueType { - /** Save the type of `value`. For Java enums, it depends on finding the linked class, - * which might not be found after `flatten`. */ - private lazy val _tpe: Type = value.tpe - override def underlying: Type = _tpe - } - - object ConstantType extends ConstantTypeExtractor { - def apply(value: Constant): ConstantType = { - val tpe = new UniqueConstantType(value) - if (value.tag == ClazzTag) { - // if we carry a classOf, we might be in trouble - // http://groups.google.com/group/scala-internals/browse_thread/thread/45185b341aeb6a30 - // I don't have time for a thorough fix, so I put a hacky workaround here - val alreadyThere = uniques findEntry tpe - if ((alreadyThere ne null) && (alreadyThere ne tpe) && (alreadyThere.toString != tpe.toString)) { - // we need to remove a stale type that has the same hashcode as we do - // HashSet doesn't support removal, and this makes our task non-trivial - // also we cannot simply recreate it, because that'd skew hashcodes (that change over time, omg!) - // the only solution I can see is getting into the underlying array and sneakily manipulating it - val ftable = uniques.getClass.getDeclaredFields().find(f => f.getName endsWith "table").get - ftable.setAccessible(true) - val table = ftable.get(uniques).asInstanceOf[Array[AnyRef]] - def overwrite(hc: Int, x: Type) { - def index(x: Int): Int = math.abs(x % table.length) - var h = index(hc) - var entry = table(h) - while (entry ne null) { - if (x == entry) - table(h) = x - h = index(h + 1) - entry = table(h) - } - } - overwrite(tpe.##, tpe) - } - } - unique(tpe).asInstanceOf[ConstantType] - } - } - - /* Syncnote: The `volatile` var and `pendingVolatiles` mutable set need not be protected - * with synchronized, because they are accessed only from isVolatile, which is called only from - * Typer. - */ - private var volatileRecursions: Int = 0 - private val pendingVolatiles = new mutable.HashSet[Symbol] - - class ArgsTypeRef(pre0: Type, sym0: Symbol, args0: List[Type]) extends TypeRef(pre0, sym0, args0) with UniqueType { - require(args0.nonEmpty, this) - - /** No unapplied type params size it has (should have) equally as many args. */ - override def isHigherKinded = false - override def typeParams = Nil - - override def transform(tp: Type): Type = { - // This situation arises when a typevar is encountered for which - // too little information is known to determine its kind, and - // it later turns out not to have kind *. See SI-4070. Only - // logging it for now. - if (sym.typeParams.size != args.size) - log("!!! %s.transform(%s), but tparams.isEmpty and args=".format(this, tp, args)) - - asSeenFromOwner(tp).instantiateTypeParams(sym.typeParams, args) - } - - // note: does not go through typeRef. There's no need to because - // neither `pre` nor `sym` changes. And there's a performance - // advantage to call TypeRef directly. - override def typeConstructor = TypeRef(pre, sym, Nil) - } - - class ModuleTypeRef(pre0: Type, sym0: Symbol) extends NoArgsTypeRef(pre0, sym0) with ClassTypeRef { - require(sym.isModuleClass, sym) - private[this] var narrowedCache: Type = _ - override def isStable = true - override def narrow = { - if (narrowedCache eq null) - narrowedCache = singleType(pre, sym.sourceModule) - - narrowedCache - } - final override def isNotNull = true - override protected def finishPrefix(rest: String) = objectPrefix + rest - override def directObjectString = super.safeToString - override def toLongString = toString - override def safeToString = narrow.toString - } - class PackageTypeRef(pre0: Type, sym0: Symbol) extends ModuleTypeRef(pre0, sym0) { - require(sym.isPackageClass, sym) - override protected def finishPrefix(rest: String) = packagePrefix + rest - } - class RefinementTypeRef(pre0: Type, sym0: Symbol) extends NoArgsTypeRef(pre0, sym0) with ClassTypeRef { - require(sym.isRefinementClass, sym) - - // I think this is okay, but see #1241 (r12414), #2208, and typedTypeConstructor in Typers - override protected def normalizeImpl: Type = sym.info.normalize - override protected def finishPrefix(rest: String) = "" + thisInfo - } - - class NoArgsTypeRef(pre0: Type, sym0: Symbol) extends TypeRef(pre0, sym0, Nil) with UniqueType { - // 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, 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. - override def isHigherKinded = typeParams.nonEmpty - override def typeParams = if (isDefinitionsInitialized) sym.typeParams else sym.unsafeTypeParams - private def isRaw = !phase.erasedTypes && isRawIfWithoutArgs(sym) - - override def instantiateTypeParams(formals: List[Symbol], actuals: List[Type]): Type = - if (isHigherKinded) { - if (sameLength(formals intersect typeParams, typeParams)) - copyTypeRef(this, pre, sym, actuals) - // 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) - - override def transform(tp: Type): Type = { - val res = asSeenFromOwner(tp) - if (isHigherKinded && !isRaw) - res.instantiateTypeParams(typeParams, dummyArgs) - else - res - } - - override def transformInfo(tp: Type): Type = - appliedType(asSeenFromOwner(tp), dummyArgs) - - override def narrow = - if (sym.isModuleClass) singleType(pre, sym.sourceModule) - else super.narrow - - override def typeConstructor = this - // eta-expand, subtyping relies on eta-expansion of higher-kinded types - - override protected def normalizeImpl: Type = - if (isHigherKinded) etaExpand else super.normalizeImpl - } - - trait ClassTypeRef extends TypeRef { - // !!! There are scaladoc-created symbols arriving which violate this require. - // require(sym.isClass, sym) - - override def baseType(clazz: Symbol): Type = - if (sym == clazz) this - else transform(sym.info.baseType(clazz)) - } - - trait NonClassTypeRef extends TypeRef { - require(sym.isNonClassType, sym) - - /* Syncnote: These are pure caches for performance; no problem to evaluate these - * several times. Hence, no need to protected with synchronzied in a mutli-threaded - * usage scenario. - */ - private var relativeInfoCache: Type = _ - private var memberInfoCache: Type = _ - - private[Types] def relativeInfo = { - val memberInfo = pre.memberInfo(sym) - if (relativeInfoCache == null || (memberInfo ne memberInfoCache)) { - memberInfoCache = memberInfo - relativeInfoCache = transformInfo(memberInfo) - } - relativeInfoCache - } - - override def baseType(clazz: Symbol): Type = - if (sym == clazz) this else baseTypeOfNonClassTypeRef(this, clazz) - } - - protected def baseTypeOfNonClassTypeRef(tpe: NonClassTypeRef, clazz: Symbol) = try { - basetypeRecursions += 1 - if (basetypeRecursions < LogPendingBaseTypesThreshold) - tpe.relativeInfo.baseType(clazz) - else if (pendingBaseTypes contains tpe) - if (clazz == AnyClass) clazz.tpe else NoType - else - try { - pendingBaseTypes += tpe - tpe.relativeInfo.baseType(clazz) - } finally { - pendingBaseTypes -= tpe - } - } finally { - basetypeRecursions -= 1 - } - - trait AliasTypeRef extends NonClassTypeRef { - require(sym.isAliasType, sym) - - override def dealias = if (typeParamsMatchArgs) betaReduce.dealias else super.dealias - override def isStable = normalize.isStable - override def isVolatile = normalize.isVolatile - override def narrow = normalize.narrow - override def thisInfo = normalize - override def prefix = if (this ne normalize) normalize.prefix else pre - override def termSymbol = if (this ne normalize) normalize.termSymbol else super.termSymbol - override def typeSymbol = if (this ne normalize) normalize.typeSymbol else sym - - // beta-reduce, but don't do partial application -- cycles have been checked in typeRef - override protected def normalizeImpl = - if (typeParamsMatchArgs) betaReduce.normalize - else if (isHigherKinded) super.normalizeImpl - else ErrorType - - // 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. - // - // this crashes pos/depmet_implicit_tpbetareduce.scala - // appliedType(sym.info, typeArgs).asSeenFrom(pre, sym.owner) - def betaReduce = transform(sym.info.resultType) - - // #3731: return sym1 for which holds: pre bound sym.name to sym and - // pre1 now binds sym.name to sym1, conceptually exactly the same - // symbol as sym. The selection of sym on pre must be updated to the - // selection of sym1 on pre1, since sym's info was probably updated - // by the TypeMap to yield a new symbol, sym1 with transformed info. - // @returns sym1 - override def coevolveSym(pre1: Type): Symbol = - if (pre eq pre1) sym else (pre, pre1) match { - // don't look at parents -- it would be an error to override alias types anyway - case (RefinedType(_, _), RefinedType(_, decls1)) => decls1 lookup sym.name - // TODO: is there another way a typeref's symbol can refer to a symbol defined in its pre? - case _ => sym - } - override def kind = "AliasTypeRef" - } - - trait AbstractTypeRef extends NonClassTypeRef { - require(sym.isAbstractType, sym) - - /** Syncnote: Pure performance caches; no need to synchronize in multi-threaded environment - */ - private var symInfoCache: Type = _ - private var thisInfoCache: Type = _ - - override def isVolatile = { - // need to be careful not to fall into an infinite recursion here - // because volatile checking is done before all cycles are detected. - // the case to avoid is an abstract type directly or - // indirectly upper-bounded by itself. See #2918 - try { - volatileRecursions += 1 - if (volatileRecursions < LogVolatileThreshold) - bounds.hi.isVolatile - else if (pendingVolatiles(sym)) - true // we can return true here, because a cycle will be detected - // here afterwards and an error will result anyway. - else - try { - pendingVolatiles += sym - bounds.hi.isVolatile - } finally { - pendingVolatiles -= sym - } - } finally { - volatileRecursions -= 1 - } - } - - override def thisInfo = { - val symInfo = sym.info - if (thisInfoCache == null || (symInfo ne symInfoCache)) { - symInfoCache = symInfo - thisInfoCache = transformInfo(symInfo) match { - // If a subtyping cycle is not detected here, we'll likely enter an infinite - // loop before a sensible error can be issued. SI-5093 is one example. - case x: SubType if x.supertype eq this => - throw new RecoverableCyclicReference(sym) - case tp => tp - } - } - thisInfoCache - } - override def isStable = bounds.hi.typeSymbol isSubClass SingletonClass - override def bounds = thisInfo.bounds - // def transformInfo(tp: Type): Type = appliedType(tp.asSeenFrom(pre, sym.owner), typeArgsOrDummies) - override protected[Types] def baseTypeSeqImpl: BaseTypeSeq = transform(bounds.hi).baseTypeSeq prepend this - override def kind = "AbstractTypeRef" - } - - /** A class for named types of the form - * `<prefix>.<sym.name>[args]` - * Cannot be created directly; one should always use `typeRef` - * for creation. (@M: Otherwise hashing breaks) - * - * @M: a higher-kinded type is represented as a TypeRef with sym.typeParams.nonEmpty, but args.isEmpty - */ - abstract case class TypeRef(pre: Type, sym: Symbol, args: List[Type]) extends Type with TypeRefApi { - private[reflect] var parentsCache: List[Type] = _ - private[reflect] var parentsPeriod = NoPeriod - private[reflect] var baseTypeSeqCache: BaseTypeSeq = _ - private[reflect] var baseTypeSeqPeriod = NoPeriod - private var normalized: Type = _ - - // @M: propagate actual type params (args) to `tp`, by replacing - // formal type parameters with actual ones. If tp is higher kinded, - // the "actual" type arguments are types that simply reference the - // corresponding type parameters (unbound type variables) - def transform(tp: Type): Type - - // eta-expand, subtyping relies on eta-expansion of higher-kinded types - protected def normalizeImpl: Type = if (isHigherKinded) etaExpand else super.normalize - - // TODO: test case that is compiled in a specific order and in different runs - final override def normalize: Type = { - // arises when argument-dependent types are approximated (see def depoly in implicits) - if (pre eq WildcardType) WildcardType - else if (phase.erasedTypes) normalizeImpl - else { - if (normalized eq null) - normalized = normalizeImpl - normalized - } - } - - override def isGround = ( - sym.isPackageClass - || pre.isGround && args.forall(_.isGround) - ) - - def etaExpand: Type = { - // must initialise symbol, see test/files/pos/ticket0137.scala - val tpars = initializedTypeParams - if (tpars.isEmpty) this - else typeFunAnon(tpars, copyTypeRef(this, pre, sym, tpars map (_.tpeHK))) // todo: also beta-reduce? - } - - // only need to rebind type aliases, as typeRef already handles abstract types - // (they are allowed to be rebound more liberally) - def coevolveSym(pre1: Type): Symbol = sym - - //@M! use appliedType on the polytype that represents the bounds (or if aliastype, the rhs) - def transformInfo(tp: Type): Type = appliedType(asSeenFromOwner(tp), args) - - def thisInfo = sym.info - def initializedTypeParams = sym.info.typeParams - def typeParamsMatchArgs = sameLength(initializedTypeParams, args) - def asSeenFromOwner(tp: Type) = tp.asSeenFrom(pre, sym.owner) - - override def baseClasses = thisInfo.baseClasses - override def baseTypeSeqDepth = baseTypeSeq.maxDepth - override def isStable = (sym eq NothingClass) || (sym eq SingletonClass) - override def prefix = pre - override def termSymbol = super.termSymbol - override def termSymbolDirect = super.termSymbol - override def typeArgs = args - override def typeOfThis = transform(sym.typeOfThis) - override def typeSymbol = sym - override def typeSymbolDirect = sym - - override lazy val isTrivial: Boolean = - !sym.isTypeParameter && pre.isTrivial && args.forall(_.isTrivial) - - override def isNotNull = - sym.isModuleClass || sym == NothingClass || (sym isNonBottomSubClass NotNullClass) || super.isNotNull - - override def parents: List[Type] = { - val cache = parentsCache - if (parentsPeriod == currentPeriod && cache != null) cache - else { - defineParentsOfTypeRef(this) - parentsCache - } - } - - override def decls: Scope = { - sym.info match { - case TypeRef(_, sym1, _) => - assert(sym1 != sym, this) // @MAT was != typeSymbol - case _ => - } - thisInfo.decls - } - - protected[Types] def baseTypeSeqImpl: BaseTypeSeq = sym.info.baseTypeSeq map transform - - override def baseTypeSeq: BaseTypeSeq = { - val cache = baseTypeSeqCache - if (baseTypeSeqPeriod == currentPeriod && cache != null && cache != undetBaseTypeSeq) - cache - else { - defineBaseTypeSeqOfTypeRef(this) - if (baseTypeSeqCache == undetBaseTypeSeq) - throw new RecoverableCyclicReference(sym) - - baseTypeSeqCache - } - } - - // ensure that symbol is not a local copy with a name coincidence - private def needsPreString = ( - settings.debug.value - || !shorthands(sym.fullName) - || sym.ownerChain.exists(s => !s.isClass) - ) - private def preString = if (needsPreString) pre.prefixString else "" - private def argsString = if (args.isEmpty) "" else args.mkString("[", ",", "]") - - def refinementString = ( - if (sym.isStructuralRefinement) ( - decls filter (sym => sym.isPossibleInRefinement && sym.isPublic) - map (_.defString) - mkString("{", "; ", "}") - ) - else "" - ) - - protected def finishPrefix(rest: String) = ( - if (sym.isInitialized && sym.isAnonymousClass && !phase.erasedTypes) - parentsString(thisInfo.parents) + refinementString - else rest - ) - private def customToString = sym match { - case RepeatedParamClass => args.head + "*" - case ByNameParamClass => "=> " + args.head - case _ => - def targs = normalize.typeArgs - - if (isFunctionType(this)) { - // Aesthetics: printing Function1 as T => R rather than (T) => R - // ...but only if it's not a tuple, so ((T1, T2)) => R is distinguishable - // from (T1, T2) => R. - targs match { - case in :: out :: Nil if !isTupleType(in) => - // A => B => C should be (A => B) => C or A => (B => C) - val in_s = if (isFunctionType(in)) "(" + in + ")" else "" + in - val out_s = if (isFunctionType(out)) "(" + out + ")" else "" + out - in_s + " => " + out_s - case xs => - xs.init.mkString("(", ", ", ")") + " => " + xs.last - } - } - else if (isTupleType(this)) - targs.mkString("(", ", ", if (hasLength(targs, 1)) ",)" else ")") - else if (sym.isAliasType && prefixChain.exists(_.termSymbol.isSynthetic) && (this ne this.normalize)) - "" + normalize - else - "" - } - override def safeToString = { - val custom = if (settings.debug.value) "" else customToString - if (custom != "") custom - else finishPrefix(preString + sym.nameString + argsString) - } - override def prefixString = "" + ( - if (settings.debug.value) - super.prefixString - else if (sym.isOmittablePrefix) - "" - else if (sym.isPackageClass || sym.isPackageObjectOrClass) - sym.skipPackageObject.fullName + "." - else if (isStable && nme.isSingletonName(sym.name)) - tpnme.dropSingletonName(sym.name) + "." - else - super.prefixString - ) - override def kind = "TypeRef" - } - - object TypeRef extends TypeRefExtractor { - def apply(pre: Type, sym: Symbol, args: List[Type]): Type = unique({ - if (args.nonEmpty) { - if (sym.isAliasType) new ArgsTypeRef(pre, sym, args) with AliasTypeRef - else if (sym.isAbstractType) new ArgsTypeRef(pre, sym, args) with AbstractTypeRef - else new ArgsTypeRef(pre, sym, args) with ClassTypeRef - } - else { - if (sym.isAliasType) new NoArgsTypeRef(pre, sym) with AliasTypeRef - else if (sym.isAbstractType) new NoArgsTypeRef(pre, sym) with AbstractTypeRef - else if (sym.isRefinementClass) new RefinementTypeRef(pre, sym) - else if (sym.isPackageClass) new PackageTypeRef(pre, sym) - else if (sym.isModuleClass) new ModuleTypeRef(pre, sym) - else new NoArgsTypeRef(pre, sym) with ClassTypeRef - } - }) - } - - protected def defineParentsOfTypeRef(tpe: TypeRef) = { - val period = tpe.parentsPeriod - if (period != currentPeriod) { - tpe.parentsPeriod = currentPeriod - if (!isValidForBaseClasses(period)) { - tpe.parentsCache = tpe.thisInfo.parents map tpe.transform - } else if (tpe.parentsCache == null) { // seems this can happen if things are corrupted enough, see #2641 - tpe.parentsCache = List(AnyClass.tpe) - } - } - } - - protected def defineBaseTypeSeqOfTypeRef(tpe: TypeRef) = { - val period = tpe.baseTypeSeqPeriod - if (period != currentPeriod) { - tpe.baseTypeSeqPeriod = currentPeriod - if (!isValidForBaseClasses(period)) { - incCounter(typerefBaseTypeSeqCount) - tpe.baseTypeSeqCache = undetBaseTypeSeq - tpe.baseTypeSeqCache = tpe.baseTypeSeqImpl - } - } - if (tpe.baseTypeSeqCache == undetBaseTypeSeq) - throw new TypeError("illegal cyclic inheritance involving " + tpe.sym) - } - - /** A class representing a method type with parameters. - * Note that a parameterless method is represented by a NullaryMethodType: - * - * def m(): Int MethodType(Nil, Int) - * def m: Int NullaryMethodType(Int) - */ - case class MethodType(override val params: List[Symbol], - override val resultType: Type) extends Type with MethodTypeApi { - override def isTrivial: Boolean = isTrivial0 && (resultType eq resultType.withoutAnnotations) - private lazy val isTrivial0 = - resultType.isTrivial && params.forall{p => p.tpe.isTrivial && ( - !(params.exists(_.tpe.contains(p)) || resultType.contains(p))) - } - - def isImplicit = params.nonEmpty && params.head.isImplicit - def isJava = false // can we do something like for implicits? I.e. do Java methods without parameters need to be recognized? - - //assert(paramTypes forall (pt => !pt.typeSymbol.isImplClass))//DEBUG - override def paramSectionCount: Int = resultType.paramSectionCount + 1 - - override def paramss: List[List[Symbol]] = params :: resultType.paramss - - override def paramTypes = params map (_.tpe) - - override def boundSyms = resultType.boundSyms ++ params - - override def resultType(actuals: List[Type]) = - if (isTrivial || phase.erasedTypes) resultType - else if (sameLength(actuals, params)) { - val idm = new InstantiateDependentMap(params, actuals) - val res = idm(resultType) - existentialAbstraction(idm.existentialsNeeded, res) - } - else existentialAbstraction(params, resultType) - - // implicit args can only be depended on in result type: - //TODO this may be generalised so that the only constraint is dependencies are acyclic - def approximate: MethodType = MethodType(params, resultApprox) - - override def finalResultType: Type = resultType.finalResultType - - override def safeToString = paramString(this) + resultType - - override def cloneInfo(owner: Symbol) = { - val vparams = cloneSymbolsAtOwner(params, owner) - copyMethodType(this, vparams, resultType.substSym(params, vparams).cloneInfo(owner)) - } - - override def atOwner(owner: Symbol) = - if ((params exists (_.owner != owner)) || (resultType.atOwner(owner) ne resultType)) - cloneInfo(owner) - else - this - - override def kind = "MethodType" - } - - object MethodType extends MethodTypeExtractor - - class JavaMethodType(ps: List[Symbol], rt: Type) extends MethodType(ps, rt) { - override def isJava = true - } - - case class NullaryMethodType(override val resultType: Type) extends Type with NullaryMethodTypeApi { - override def isTrivial = resultType.isTrivial && (resultType eq resultType.withoutAnnotations) - override def prefix: Type = resultType.prefix - override def narrow: Type = resultType.narrow - override def finalResultType: Type = resultType.finalResultType - override def termSymbol: Symbol = resultType.termSymbol - override def typeSymbol: Symbol = resultType.typeSymbol - override def parents: List[Type] = resultType.parents - override def decls: Scope = resultType.decls - override def baseTypeSeq: BaseTypeSeq = resultType.baseTypeSeq - override def baseTypeSeqDepth: Int = resultType.baseTypeSeqDepth - override def baseClasses: List[Symbol] = resultType.baseClasses - override def baseType(clazz: Symbol): Type = resultType.baseType(clazz) - override def boundSyms = resultType.boundSyms - override def isVolatile = resultType.isVolatile - override def safeToString: String = "=> "+ resultType - override def kind = "NullaryMethodType" - } - - object NullaryMethodType extends NullaryMethodTypeExtractor - - /** A type function or the type of a polymorphic value (and thus of kind *). - * - * Before the introduction of NullaryMethodType, a polymorphic nullary method (e.g, def isInstanceOf[T]: Boolean) - * used to be typed as PolyType(tps, restpe), and a monomorphic one as PolyType(Nil, restpe) - * This is now: PolyType(tps, NullaryMethodType(restpe)) and NullaryMethodType(restpe) - * by symmetry to MethodTypes: PolyType(tps, MethodType(params, restpe)) and MethodType(params, restpe) - * - * Thus, a PolyType(tps, TypeRef(...)) unambiguously indicates a type function (which results from eta-expanding a type constructor alias). - * Similarly, PolyType(tps, ClassInfoType(...)) is a type constructor. - * - * A polytype is of kind * iff its resultType is a (nullary) method type. - */ - case class PolyType(override val typeParams: List[Symbol], override val resultType: Type) - extends Type with PolyTypeApi { - //assert(!(typeParams contains NoSymbol), this) - assert(typeParams nonEmpty, this) // used to be a marker for nullary method type, illegal now (see @NullaryMethodType) - - override def paramSectionCount: Int = resultType.paramSectionCount - override def paramss: List[List[Symbol]] = resultType.paramss - override def params: List[Symbol] = resultType.params - override def paramTypes: List[Type] = resultType.paramTypes - override def parents: List[Type] = resultType.parents - override def decls: Scope = resultType.decls - override def termSymbol: Symbol = resultType.termSymbol - override def typeSymbol: Symbol = resultType.typeSymbol - override def boundSyms = immutable.Set[Symbol](typeParams ++ resultType.boundSyms: _*) - override def prefix: Type = resultType.prefix - override def baseTypeSeq: BaseTypeSeq = resultType.baseTypeSeq - override def baseTypeSeqDepth: Int = resultType.baseTypeSeqDepth - override def baseClasses: List[Symbol] = resultType.baseClasses - override def baseType(clazz: Symbol): Type = resultType.baseType(clazz) - override def narrow: Type = resultType.narrow - override def isVolatile = resultType.isVolatile - override def finalResultType: Type = resultType.finalResultType - - /** @M: typeDefSig wraps a TypeBounds in a PolyType - * to represent a higher-kinded type parameter - * wrap lo&hi in polytypes to bind variables - */ - override def bounds: TypeBounds = - TypeBounds(typeFun(typeParams, resultType.bounds.lo), - typeFun(typeParams, resultType.bounds.hi)) - - override def isHigherKinded = !typeParams.isEmpty - - override def safeToString = typeParamsString(this) + resultType - - override def cloneInfo(owner: Symbol) = { - val tparams = cloneSymbolsAtOwner(typeParams, owner) - PolyType(tparams, resultType.substSym(typeParams, tparams).cloneInfo(owner)) - } - - override def atOwner(owner: Symbol) = - if ((typeParams exists (_.owner != owner)) || (resultType.atOwner(owner) ne resultType)) - cloneInfo(owner) - else - this - - override def kind = "PolyType" - } - - object PolyType extends PolyTypeExtractor - - /** A creator for existential types which flattens nested existentials. - */ - def newExistentialType(quantified: List[Symbol], underlying: Type): Type = - if (quantified.isEmpty) underlying - else underlying match { - case ExistentialType(qs, restpe) => newExistentialType(quantified ::: qs, restpe) - case _ => ExistentialType(quantified, underlying) - } - - case class ExistentialType(quantified: List[Symbol], - override val underlying: Type) extends RewrappingTypeProxy with ExistentialTypeApi - { - override protected def rewrap(newtp: Type) = existentialAbstraction(quantified, newtp) - - override def isTrivial = false - override def isStable: Boolean = false - override def bounds = TypeBounds(maybeRewrap(underlying.bounds.lo), maybeRewrap(underlying.bounds.hi)) - override def parents = underlying.parents map maybeRewrap - override def boundSyms = quantified.toSet - override def prefix = maybeRewrap(underlying.prefix) - override def typeArgs = underlying.typeArgs map maybeRewrap - override def params = underlying.params mapConserve { param => - val tpe1 = rewrap(param.tpeHK) - if (tpe1 eq param.tpeHK) param else param.cloneSymbol.setInfo(tpe1) - } - override def paramTypes = underlying.paramTypes map maybeRewrap - override def instantiateTypeParams(formals: List[Symbol], actuals: List[Type]) = { -// maybeRewrap(underlying.instantiateTypeParams(formals, actuals)) - - val quantified1 = new SubstTypeMap(formals, actuals) mapOver quantified - val underlying1 = underlying.instantiateTypeParams(formals, actuals) - if ((quantified1 eq quantified) && (underlying1 eq underlying)) this - else existentialAbstraction(quantified1, underlying1.substSym(quantified, quantified1)) - - } - override def baseType(clazz: Symbol) = maybeRewrap(underlying.baseType(clazz)) - override def baseTypeSeq = underlying.baseTypeSeq map maybeRewrap - override def isHigherKinded = false - - override def skolemizeExistential(owner: Symbol, origin: AnyRef) = - deriveType(quantified, tparam => (owner orElse tparam.owner).newExistentialSkolem(tparam, origin))(underlying) - - private def wildcardArgsString(qset: Set[Symbol], args: List[Type]): List[String] = args map { - case TypeRef(_, sym, _) if (qset contains sym) => - "_"+sym.infoString(sym.info) - case arg => - arg.toString - } - - /** An existential can only be printed with wildcards if: - * - the underlying type is a typeref - * - every quantified variable appears at most once as a type argument and - * nowhere inside a type argument - * - no quantified type argument contains a quantified variable in its bound - * - the typeref's symbol is not itself quantified - * - the prefix is not quanitified - */ - def isRepresentableWithWildcards = { - val qset = quantified.toSet - underlying match { - case TypeRef(pre, sym, args) => - def isQuantified(tpe: Type): Boolean = { - (tpe exists (t => qset contains t.typeSymbol)) || - tpe.typeSymbol.isRefinementClass && (tpe.parents exists isQuantified) - } - val (wildcardArgs, otherArgs) = args partition (arg => qset contains arg.typeSymbol) - wildcardArgs.distinct == wildcardArgs && - !(otherArgs exists (arg => isQuantified(arg))) && - !(wildcardArgs exists (arg => isQuantified(arg.typeSymbol.info.bounds))) && - !(qset contains sym) && - !isQuantified(pre) - case _ => false - } - } - - override def safeToString: String = { - def clauses = { - val str = quantified map (_.existentialToString) mkString (" forSome { ", "; ", " }") - if (settings.explaintypes.value) "(" + str + ")" else str - } - underlying match { - case TypeRef(pre, sym, args) if !settings.debug.value && isRepresentableWithWildcards => - "" + TypeRef(pre, sym, Nil) + wildcardArgsString(quantified.toSet, args).mkString("[", ", ", "]") - case MethodType(_, _) | NullaryMethodType(_) | PolyType(_, _) => - "(" + underlying + ")" + clauses - case _ => - "" + underlying + clauses - } - } - - override def cloneInfo(owner: Symbol) = - createFromClonedSymbolsAtOwner(quantified, owner, underlying)(newExistentialType) - - override def atOwner(owner: Symbol) = - if (quantified exists (_.owner != owner)) cloneInfo(owner) else this - - override def kind = "ExistentialType" - - def withTypeVars(op: Type => Boolean): Boolean = withTypeVars(op, AnyDepth) - - def withTypeVars(op: Type => Boolean, depth: Int): Boolean = { - val quantifiedFresh = cloneSymbols(quantified) - val tvars = quantifiedFresh map (tparam => TypeVar(tparam)) - val underlying1 = underlying.instantiateTypeParams(quantified, tvars) // fuse subst quantified -> quantifiedFresh -> tvars - op(underlying1) && { - solve(tvars, quantifiedFresh, quantifiedFresh map (x => 0), false, depth) && - isWithinBounds(NoPrefix, NoSymbol, quantifiedFresh, tvars map (_.constr.inst)) - } - } - } - - object ExistentialType extends ExistentialTypeExtractor - - /** A class containing the alternatives and type prefix of an overloaded symbol. - * Not used after phase `typer`. - */ - case class OverloadedType(pre: Type, alternatives: List[Symbol]) extends Type { - override def prefix: Type = pre - override def safeToString = - (alternatives map pre.memberType).mkString("", " <and> ", "") - override def kind = "OverloadedType" - } - - def overloadedType(pre: Type, alternatives: List[Symbol]): Type = - if (alternatives.tail.isEmpty) pre memberType alternatives.head - else OverloadedType(pre, alternatives) - - /** A class remembering a type instantiation for some a set of overloaded - * polymorphic symbols. - * Not used after phase `typer`. - */ - case class AntiPolyType(pre: Type, targs: List[Type]) extends Type { - override def safeToString = - pre.toString + targs.mkString("(with type arguments ", ", ", ")"); - override def memberType(sym: Symbol) = appliedType(pre.memberType(sym), targs) -// override def memberType(sym: Symbol) = pre.memberType(sym) match { -// case PolyType(tparams, restp) => -// restp.subst(tparams, targs) -// /* I don't think this is needed, as existential types close only over value types -// case ExistentialType(tparams, qtpe) => -// existentialAbstraction(tparams, qtpe.memberType(sym)) -// */ -// case ErrorType => -// ErrorType -// } - override def kind = "AntiPolyType" - } - - //private var tidCount = 0 //DEBUG - - object HasTypeMember { - def apply(name: TypeName, tp: Type): Type = { - val bound = refinedType(List(WildcardType), NoSymbol) - val bsym = bound.typeSymbol.newAliasType(name) - bsym setInfo tp - bound.decls enter bsym - bound - } - def unapply(tp: Type): Option[(TypeName, Type)] = tp match { - case RefinedType(List(WildcardType), Scope(sym)) => Some((sym.name.toTypeName, sym.info)) - case _ => None - } - } - - // 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), - // but pattern-matching returned the original constr0 (a bug) - // now, pattern-matching returns the most recent constr - object TypeVar { - @inline final def trace[T](action: String, msg: => String)(value: T): T = { - if (traceTypeVars) { - val s = msg match { - case "" => "" - case str => "( " + str + " )" - } - Console.err.println("[%10s] %-25s%s".format(action, value, s)) - } - value - } - - /** Create a new TypeConstraint based on the given symbol. - */ - private def deriveConstraint(tparam: Symbol): TypeConstraint = { - /** Must force the type parameter's info at this point - * or things don't end well for higher-order type params. - * See SI-5359. - */ - val bounds = tparam.info.bounds - /** We can seed the type constraint with the type parameter - * bounds as long as the types are concrete. This should lower - * the complexity of the search even if it doesn't improve - * any results. - */ - if (propagateParameterBoundsToTypeVars) { - val exclude = bounds.isEmptyBounds || bounds.exists(_.typeSymbolDirect.isNonClassType) - - if (exclude) new TypeConstraint - else TypeVar.trace("constraint", "For " + tparam.fullLocationString)(new TypeConstraint(bounds)) - } - else new TypeConstraint - } - def unapply(tv: TypeVar): Some[(Type, TypeConstraint)] = Some((tv.origin, tv.constr)) - def untouchable(tparam: Symbol): TypeVar = createTypeVar(tparam, untouchable = true) - def apply(tparam: Symbol): TypeVar = createTypeVar(tparam, untouchable = false) - def apply(origin: Type, constr: TypeConstraint): TypeVar = apply(origin, constr, Nil, Nil) - def apply(origin: Type, constr: TypeConstraint, args: List[Type], params: List[Symbol]): TypeVar = - createTypeVar(origin, constr, args, params, untouchable = false) - - /** This is the only place TypeVars should be instantiated. - */ - private def createTypeVar(origin: Type, constr: TypeConstraint, args: List[Type], params: List[Symbol], untouchable: Boolean): TypeVar = { - val tv = ( - if (args.isEmpty && params.isEmpty) { - if (untouchable) new TypeVar(origin, constr) with UntouchableTypeVar - else new TypeVar(origin, constr) - } - else if (args.size == params.size) { - if (untouchable) new AppliedTypeVar(origin, constr, params zip args) with UntouchableTypeVar - else new AppliedTypeVar(origin, constr, params zip args) - } - else if (args.isEmpty) { - if (untouchable) new HKTypeVar(origin, constr, params) with UntouchableTypeVar - else new HKTypeVar(origin, constr, params) - } - else throw new Error("Invalid TypeVar construction: " + ((origin, constr, args, params))) - ) - - trace("create", "In " + tv.originLocation)(tv) - } - private def createTypeVar(tparam: Symbol, untouchable: Boolean): TypeVar = - createTypeVar(tparam.tpeHK, deriveConstraint(tparam), Nil, tparam.typeParams, untouchable) - } - - /** Repack existential types, otherwise they sometimes get unpacked in the - * wrong location (type inference comes up with an unexpected skolem) - */ - def repackExistential(tp: Type): Type = ( - if (tp == NoType) tp - else existentialAbstraction(existentialsInType(tp), tp) - ) - def containsExistential(tpe: Type) = - tpe exists (_.typeSymbol.isExistentiallyBound) - - def existentialsInType(tpe: Type) = ( - for (tp <- tpe ; if tp.typeSymbol.isExistentiallyBound) yield - tp.typeSymbol - ) - - /** Precondition: params.nonEmpty. (args.nonEmpty enforced structurally.) - */ - class HKTypeVar( - _origin: Type, - _constr: TypeConstraint, - override val params: List[Symbol] - ) extends TypeVar(_origin, _constr) { - - require(params.nonEmpty, this) - override def isHigherKinded = true - override protected def typeVarString = params.map(_.name).mkString("[", ", ", "]=>" + originName) - } - - /** Precondition: zipped params/args nonEmpty. (Size equivalence enforced structurally.) - */ - class AppliedTypeVar( - _origin: Type, - _constr: TypeConstraint, - zippedArgs: List[(Symbol, Type)] - ) extends TypeVar(_origin, _constr) { - - require(zippedArgs.nonEmpty, this) - - override def params: List[Symbol] = zippedArgs map (_._1) - override def typeArgs: List[Type] = zippedArgs map (_._2) - - override protected def typeVarString = ( - zippedArgs map { case (p, a) => p.name + "=" + a } mkString (origin + "[", ", ", "]") - ) - } - - trait UntouchableTypeVar extends TypeVar { - override def untouchable = true - override def isGround = true - override def registerTypeEquality(tp: Type, typeVarLHS: Boolean) = tp match { - case t: TypeVar if !t.untouchable => - t.registerTypeEquality(this, !typeVarLHS) - case _ => - super.registerTypeEquality(tp, typeVarLHS) - } - override def registerBound(tp: Type, isLowerBound: Boolean, isNumericBound: Boolean = false): Boolean = tp match { - case t: TypeVar if !t.untouchable => - t.registerBound(this, !isLowerBound, isNumericBound) - case _ => - super.registerBound(tp, isLowerBound, isNumericBound) - } - } - - /** A class representing a type variable: not used after phase `typer`. - * - * A higher-kinded TypeVar has params (Symbols) and typeArgs (Types). - * A TypeVar with nonEmpty typeArgs can only be instantiated by a higher-kinded - * type that can be applied to those args. A TypeVar is much like a TypeRef, - * except it has special logic for equality and subtyping. - * - * Precondition for this class, enforced structurally: args.isEmpty && params.isEmpty. - */ - class TypeVar( - val origin: Type, - val constr0: TypeConstraint - ) extends Type { - def untouchable = false // by other typevars - override def params: List[Symbol] = Nil - override def typeArgs: List[Type] = Nil - override def isHigherKinded = false - - /** The constraint associated with the variable - * Syncnote: Type variables are assumed to be used from only one - * thread. They are not exposed in api.Types and are used only locally - * in operations that are exposed from types. Hence, no syncing of `constr` - * or `encounteredHigherLevel` or `suspended` accesses should be necessary. - */ - var constr = constr0 - def instValid = constr.instValid - override def isGround = instValid && constr.inst.isGround - - /** The variable's skolemization level */ - val level = skolemizationLevel - - /** Two occurrences of a higher-kinded typevar, e.g. `?CC[Int]` and `?CC[String]`, correspond to - * ''two instances'' of `TypeVar` that share the ''same'' `TypeConstraint`. - * - * `constr` for `?CC` only tracks type constructors anyway, - * so when `?CC[Int] <:< List[Int]` and `?CC[String] <:< Iterable[String]` - * `?CC's` hibounds contains List and Iterable. - */ - def applyArgs(newArgs: List[Type]): TypeVar = ( - if (newArgs.isEmpty && typeArgs.isEmpty) - this - else if (newArgs.size == params.size) { - val tv = TypeVar(origin, constr, newArgs, params) - TypeVar.trace("applyArgs", "In " + originLocation + ", apply args " + newArgs.mkString(", ") + " to " + originName)(tv) - } - else - throw new Error("Invalid type application in TypeVar: " + params + ", " + newArgs) - ) - // newArgs.length may differ from args.length (could've been empty before) - // - // !!! @PP - I need an example of this, since this exception never triggers - // even though I am requiring the size match. - // - // example: when making new typevars, you start out with C[A], then you replace C by ?C, which should yield ?C[A], then A by ?A, ?C[?A] - // we need to track a TypeVar's arguments, and map over them (see TypeMap::mapOver) - // TypeVars get applied to different arguments over time (in asSeenFrom) - // -- see pos/tcpoly_infer_implicit_tuplewrapper.scala - // thus: make new TypeVar's for every application of a TV to args, - // inference may generate several TypeVar's for a single type parameter that must be inferred, - // only one of them is in the set of tvars that need to be solved, but - // they share the same TypeConstraint instance - - // When comparing to types containing skolems, remember the highest level - // of skolemization. If that highest level is higher than our initial - // skolemizationLevel, we can't re-use those skolems as the solution of this - // typevar, which means we'll need to repack our constr.inst into a fresh - // existential. - // were we compared to skolems at a higher skolemizationLevel? - // EXPERIMENTAL: value will not be considered unless enableTypeVarExperimentals is true - // see SI-5729 for why this is still experimental - private var encounteredHigherLevel = false - private def shouldRepackType = enableTypeVarExperimentals && encounteredHigherLevel - - // <region name="constraint mutators + undoLog"> - // invariant: before mutating constr, save old state in undoLog - // (undoLog is used to reset constraints to avoid piling up unrelated ones) - def setInst(tp: Type) { -// assert(!(tp containsTp this), this) - undoLog record this - // if we were compared against later typeskolems, repack the existential, - // because skolems are only compatible if they were created at the same level - val res = if (shouldRepackType) repackExistential(tp) else tp - constr.inst = TypeVar.trace("setInst", "In " + originLocation + ", " + originName + "=" + res)(res) - } - - def addLoBound(tp: Type, isNumericBound: Boolean = false) { - assert(tp != this, tp) // implies there is a cycle somewhere (?) - //println("addLoBound: "+(safeToString, debugString(tp))) //DEBUG - undoLog record this - constr.addLoBound(tp, isNumericBound) - } - - def addHiBound(tp: Type, isNumericBound: Boolean = false) { - // assert(tp != this) - //println("addHiBound: "+(safeToString, debugString(tp))) //DEBUG - undoLog record this - constr.addHiBound(tp, isNumericBound) - } - // </region> - - // ignore subtyping&equality checks while true -- see findMember - private[Types] var suspended = false - - /** Called when a TypeVar is involved in a subtyping check. Result is whether - * this TypeVar could plausibly be a [super/sub]type of argument `tp` and if so, - * tracks tp as a [lower/upper] bound of this TypeVar. - * - * if (isLowerBound) this typevar could be a subtype, track tp as a lower bound - * if (!isLowerBound) this typevar could be a supertype, track tp as an upper bound - * - * If isNumericBound is true, the subtype check is performed with weak_<:< instead of <:<. - */ - def registerBound(tp: Type, isLowerBound: Boolean, isNumericBound: Boolean = false): Boolean = { - // println("regBound: "+(safeToString, debugString(tp), isLowerBound)) //@MDEBUG - if (isLowerBound) - assert(tp != this) - - // side effect: adds the type to upper or lower bounds - def addBound(tp: Type) { - if (isLowerBound) addLoBound(tp, isNumericBound) - else addHiBound(tp, isNumericBound) - } - // swaps the arguments if it's an upper bound - def checkSubtype(tp1: Type, tp2: Type) = { - val lhs = if (isLowerBound) tp1 else tp2 - val rhs = if (isLowerBound) tp2 else tp1 - - if (isNumericBound) lhs weak_<:< rhs - else lhs <:< rhs - } - - /** Simple case: type arguments can be ignored, because either this typevar has - * no type parameters, or we are comparing to Any/Nothing. - * - * The latter condition is needed because HK unification is limited to constraints of the shape - * {{{ - * TC1[T1,..., TN] <: TC2[T'1,...,T'N] - * }}} - * which would preclude the following important constraints: - * {{{ - * Nothing <: ?TC[?T] - * ?TC[?T] <: Any - * }}} - */ - def unifySimple = ( - (params.isEmpty || tp.typeSymbol == NothingClass || tp.typeSymbol == AnyClass) && { - addBound(tp) - true - } - ) - - /** Full case: involving a check of the form - * {{{ - * TC1[T1,..., TN] <: TC2[T'1,...,T'N] - * }}} - * Checks subtyping of higher-order type vars, and uses variances as defined in the - * type parameter we're trying to infer (the result will be sanity-checked later). - */ - def unifyFull(tpe: Type) = { - // The alias/widen variations are often no-ops. - val tpes = ( - if (isLowerBound) List(tpe, tpe.widen, tpe.dealias, tpe.widen.dealias).distinct - else List(tpe) - ) - tpes exists { tp => - val lhs = if (isLowerBound) tp.typeArgs else typeArgs - val rhs = if (isLowerBound) typeArgs else tp.typeArgs - - sameLength(lhs, rhs) && { - // this is a higher-kinded type var with same arity as tp. - // side effect: adds the type constructor itself as a bound - addBound(tp.typeConstructor) - isSubArgs(lhs, rhs, params) - } - } - } - - // There's a <: test taking place right now, where tp is a concrete type and this is a typevar - // attempting to satisfy that test. Either the test will be unsatisfiable, in which case - // registerBound will return false; or the upper or lower bounds of this type var will be - // supplemented with the type being tested against. - // - // Eventually the types which have accumulated in the upper and lower bounds will be lubbed - // (resp. glbbed) to instantiate the typevar. - // - // The only types which are eligible for unification are those with the same number of - // typeArgs as this typevar, or Any/Nothing, which are kind-polymorphic. For the upper bound, - // any parent or base type of `tp` may be tested here (leading to a corresponding relaxation - // in the upper bound.) The universe of possible glbs, being somewhat more infinite, is not - // addressed here: all lower bounds are retained and their intersection calculated when the - // bounds are solved. - // - // In a side-effect free universe, checking tp and tp.parents beofre checking tp.baseTypeSeq - // would be pointless. In this case, each check we perform causes us to lose specificity: in - // the end the best we'll do is the least specific type we tested against, since the typevar - // does not see these checks as "probes" but as requirements to fulfill. - // TODO: can the `suspended` flag be used to poke around without leaving a trace? - // - // So the strategy used here is to test first the type, then the direct parents, and finally - // to fall back on the individual base types. This warrants eventual re-examination. - - // AM: I think we could use the `suspended` flag to avoid side-effecting during unification - if (suspended) // constraint accumulation is disabled - checkSubtype(tp, origin) - else if (constr.instValid) // type var is already set - checkSubtype(tp, constr.inst) - else isRelatable(tp) && { - unifySimple || unifyFull(tp) || ( - // only look harder if our gaze is oriented toward Any - isLowerBound && ( - (tp.parents exists unifyFull) || ( - // @PP: Is it going to be faster to filter out the parents we just checked? - // That's what's done here but I'm not sure it matters. - tp.baseTypeSeq.toList.tail filterNot (tp.parents contains _) exists unifyFull - ) - ) - ) - } - } - - def registerTypeEquality(tp: Type, typeVarLHS: Boolean): Boolean = { -// println("regTypeEq: "+(safeToString, debugString(tp), tp.getClass, if (typeVarLHS) "in LHS" else "in RHS", if (suspended) "ZZ" else if (constr.instValid) "IV" else "")) //@MDEBUG -// println("constr: "+ constr) - def checkIsSameType(tp: Type) = - if(typeVarLHS) constr.inst =:= tp - else tp =:= constr.inst - - if (suspended) tp =:= origin - else if (constr.instValid) checkIsSameType(tp) - else isRelatable(tp) && { - val newInst = wildcardToTypeVarMap(tp) - (constr isWithinBounds newInst) && { setInst(tp); true } - } - } - - /** - * `?A.T =:= tp` is rewritten as the constraint `?A <: {type T = tp}` - * - * TODO: make these constraints count (incorporate them into implicit search in `applyImplicitArgs`) - * (`T` corresponds to @param sym) - */ - def registerTypeSelection(sym: Symbol, tp: Type): Boolean = { - registerBound(HasTypeMember(sym.name.toTypeName, tp), false) - } - - private def isSkolemAboveLevel(tp: Type) = tp.typeSymbol match { - case ts: TypeSkolem => ts.level > level - case _ => false - } - // side-effects encounteredHigherLevel - private def containsSkolemAboveLevel(tp: Type) = - (tp exists isSkolemAboveLevel) && { encounteredHigherLevel = true ; true } - - /** Can this variable be related in a constraint to type `tp`? - * This is not the case if `tp` contains type skolems whose - * skolemization level is higher than the level of this variable. - */ - def isRelatable(tp: Type) = ( - shouldRepackType // short circuit if we already know we've seen higher levels - || !containsSkolemAboveLevel(tp) // side-effects tracking boolean - || enableTypeVarExperimentals // -Xexperimental: always say we're relatable, track consequences - ) - - override def normalize: Type = ( - if (constr.instValid) constr.inst - // get here when checking higher-order subtyping of the typevar by itself - // TODO: check whether this ever happens? - else if (isHigherKinded) typeFun(params, applyArgs(params map (_.typeConstructor))) - else super.normalize - ) - override def typeSymbol = origin.typeSymbol - override def isStable = origin.isStable - override def isVolatile = origin.isVolatile - - private def tparamsOfSym(sym: Symbol) = sym.info match { - case PolyType(tparams, _) if tparams.nonEmpty => - tparams map (_.defString) mkString("[", ",", "]") - case _ => "" - } - def originName = origin.typeSymbolDirect.decodedName - def originLocation = { - val sym = origin.typeSymbolDirect - val encl = sym.owner.logicallyEnclosingMember - - // This should display somewhere between one and three - // things which enclose the origin: at most, a class, a - // a method, and a term. At least, a class. - List( - Some(encl.enclClass), - if (encl.isMethod) Some(encl) else None, - if (sym.owner.isTerm && (sym.owner != encl)) Some(sym.owner) else None - ).flatten map (s => s.decodedName + tparamsOfSym(s)) mkString "#" - } - private def levelString = if (settings.explaintypes.value) level else "" - protected def typeVarString = originName - override def safeToString = ( - if ((constr eq null) || (constr.inst eq null)) "TVar<" + originName + "=null>" - else if (constr.inst ne NoType) "=?" + constr.inst - else (if(untouchable) "!?" else "?") + levelString + originName - ) - override def kind = "TypeVar" - - def cloneInternal = { - // cloning a suspended type variable when it's suspended will cause the clone - // to never be resumed with the current implementation - assert(!suspended, this) - TypeVar.trace("clone", originLocation)( - TypeVar(origin, constr cloneInternal, typeArgs, params) // @M TODO: clone args/params? - ) - } - } - - /** A type carrying some annotations. Created by the typechecker - * when eliminating ''Annotated'' trees (see typedAnnotated). - * - * @param annotations the list of annotations on the type - * @param underlying the type without the annotation - * @param selfsym a "self" symbol with type `underlying`; - * only available if -Yself-in-annots is turned on. Can be `NoSymbol` - * if it is not used. - */ - case class AnnotatedType(override val annotations: List[AnnotationInfo], - override val underlying: Type, - override val selfsym: Symbol) - extends RewrappingTypeProxy with AnnotatedTypeApi { - - assert(!annotations.isEmpty, "" + underlying) - - override protected def rewrap(tp: Type) = copy(underlying = tp) - - override def isTrivial: Boolean = isTrivial0 - private lazy val isTrivial0 = underlying.isTrivial && annotations.forall(_.isTrivial) - - 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) underlying - else copy(annotations = annots) - - /** Add a number of annotations to this type */ - override def withAnnotations(annots: List[AnnotationInfo]): Type = - if (annots.isEmpty) this - else copy(annots ::: this.annotations) - - /** 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 */ - override def withSelfsym(sym: Symbol) = copy(selfsym = sym) - - /** Drop the annotations on the bounds, unless the low and high - * bounds are exactly tp. - */ - override def bounds: TypeBounds = underlying.bounds match { - case TypeBounds(_: this.type, _: this.type) => TypeBounds(this, this) - case oftp => oftp - } - - // ** Replace formal type parameter symbols with actual type arguments. * / - override def instantiateTypeParams(formals: List[Symbol], actuals: List[Type]) = { - val annotations1 = annotations.map(info => AnnotationInfo(info.atp.instantiateTypeParams( - formals, actuals), info.args, info.assocs).setPos(info.pos)) - val underlying1 = underlying.instantiateTypeParams(formals, actuals) - if ((annotations1 eq annotations) && (underlying1 eq underlying)) this - else AnnotatedType(annotations1, underlying1, selfsym) - } - - /** Return the base type sequence of tp, dropping the annotations, unless the base type sequence of tp - * is precisely tp itself. */ - override def baseTypeSeq: BaseTypeSeq = { - val oftp = underlying.baseTypeSeq - if ((oftp.length == 1) && (oftp(0) eq underlying)) - baseTypeSingletonSeq(this) - else - oftp - } - - override def kind = "AnnotatedType" - } - - /** Creator for AnnotatedTypes. It returns the underlying type if annotations.isEmpty - * rather than walking into the assertion. - */ - def annotatedType(annots: List[AnnotationInfo], underlying: Type, selfsym: Symbol = NoSymbol): Type = - if (annots.isEmpty) underlying - else AnnotatedType(annots, underlying, selfsym) - - object AnnotatedType extends AnnotatedTypeExtractor - - /** A class representing types with a name. When an application uses - * named arguments, the named argument types for calling isApplicable - * are represented as NamedType. - */ - case class NamedType(name: Name, tp: Type) extends Type { - override def safeToString: String = name.toString +": "+ tp - } - - /** A De Bruijn index referring to a previous type argument. Only used - * as a serialization format. - */ - case class DeBruijnIndex(level: Int, idx: Int, args: List[Type]) extends Type { - override def safeToString: String = "De Bruijn index("+level+","+idx+")" - } - - /** A binder defining data associated with De Bruijn indices. Only used - * as a serialization format. - */ - case class DeBruijnBinder(pnames: List[Name], ptypes: List[Type], restpe: Type) extends Type { - override def safeToString = { - val kind = if (pnames.head.isTypeName) "poly" else "method" - "De Bruijn "+kind+"("+(pnames mkString ",")+";"+(ptypes mkString ",")+";"+restpe+")" - } - } - - abstract case class ErasedValueType(sym: Symbol) extends Type { - override def safeToString = sym.name+"$unboxed" - } - - final class UniqueErasedValueType(sym: Symbol) extends ErasedValueType(sym) with UniqueType - - object ErasedValueType { - def apply(sym: Symbol): Type = { - assert(sym ne NoSymbol, "ErasedValueType cannot be NoSymbol") - unique(new UniqueErasedValueType(sym)) - } - } - - /** A class representing an as-yet unevaluated type. - */ - abstract class LazyType extends Type { - override def isComplete: Boolean = false - override def complete(sym: Symbol) - override def safeToString = "<?>" - override def kind = "LazyType" - } - - abstract class LazyPolyType(override val typeParams: List[Symbol]) extends LazyType { - override def safeToString = - (if (typeParams.isEmpty) "" else typeParamsString(this)) + super.safeToString - } - - // def mkLazyType(tparams: Symbol*)(f: Symbol => Unit): LazyType = ( - // if (tparams.isEmpty) new LazyType { override def complete(sym: Symbol) = f(sym) } - // else new LazyPolyType(tparams.toList) { override def complete(sym: Symbol) = f(sym) } - // ) - -// Creators --------------------------------------------------------------- - - /** Rebind symbol `sym` to an overriding member in type `pre`. */ - private def rebind(pre: Type, sym: Symbol): Symbol = { - 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. */ - private def removeSuper(tp: Type, sym: Symbol): Type = tp match { - case SuperType(thistp, _) => - if (sym.isEffectivelyFinal || sym.isDeferred) thistp - else tp - case _ => - tp - } - - /** The canonical creator for single-types */ - def singleType(pre: Type, sym: Symbol): Type = { - if (phase.erasedTypes) - sym.tpe.resultType - else if (sym.isRootPackage) - ThisType(sym.moduleClass) - else { - var sym1 = rebind(pre, sym) - val pre1 = removeSuper(pre, sym1) - if (pre1 ne pre) sym1 = rebind(pre1, sym1) - SingleType(pre1, sym1) - } - } - - /** the canonical creator for a refined type with a given scope */ - def refinedType(parents: List[Type], owner: Symbol, decls: Scope, pos: Position): Type = { - if (phase.erasedTypes) - if (parents.isEmpty) ObjectClass.tpe else parents.head - else { - val clazz = owner.newRefinementClass(pos) // TODO: why were we passing in NoPosition instead of pos? - val result = RefinedType(parents, decls, clazz) - clazz.setInfo(result) - result - } - } - - /** The canonical creator for a refined type with an initially empty scope. - * - * @param parents ... - * @param owner ... - * @return ... - */ - def refinedType(parents: List[Type], owner: Symbol): Type = - refinedType(parents, owner, newScope, owner.pos) - - def copyRefinedType(original: RefinedType, parents: List[Type], decls: Scope) = - if ((parents eq original.parents) && (decls eq original.decls)) original - else { - val owner = if (original.typeSymbol == NoSymbol) NoSymbol else original.typeSymbol.owner - val result = refinedType(parents, owner) - val syms1 = decls.toList - for (sym <- syms1) - result.decls.enter(sym.cloneSymbol(result.typeSymbol)) - val syms2 = result.decls.toList - val resultThis = result.typeSymbol.thisType - for (sym <- syms2) - sym modifyInfo (_ substThisAndSym(original.typeSymbol, resultThis, syms1, syms2)) - - result - } - - /** The canonical creator for typerefs - * 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. - - 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) && !sym1.lockOK) - throw new RecoverableCyclicReference(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, _) if pre == pre0 && sym0.name == sym.name => - if (sym.isAliasType && sameLength(sym.info.typeParams, args) && !sym.lockOK) - throw new RecoverableCyclicReference(sym) - - 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! - - /** 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) - } - - /** A creator for intersection type where intersections of a single type are - * replaced by the type itself, and repeated parent classes are merged. - * - * !!! Repeated parent classes are not merged - is this a bug in the - * comment or in the code? - */ - def intersectionType(tps: List[Type], owner: Symbol): Type = tps match { - case tp :: Nil => tp - case _ => refinedType(tps, owner) - } - /** A creator for intersection type where intersections of a single type are - * replaced by the type itself. - */ - def intersectionType(tps: List[Type]): Type = tps match { - case tp :: Nil => tp - case _ => refinedType(tps, commonOwner(tps)) - } - -/**** This implementation to merge parents was checked in in commented-out - form and has languished unaltered for five years. I think we should - use it or lose it. - - def merge(tps: List[Type]): List[Type] = tps match { - case tp :: tps1 => - val tps1a = tps1 filter (_.typeSymbol.==(tp.typeSymbol)) - val tps1b = tps1 filter (_.typeSymbol.!=(tp.typeSymbol)) - mergePrefixAndArgs(tps1a, -1) match { - case Some(tp1) => tp1 :: merge(tps1b) - case None => throw new MalformedType( - "malformed type: "+refinedType(tps, owner)+" has repeated parent class "+ - tp.typeSymbol+" with incompatible prefixes or type arguments") - } - case _ => tps - } - refinedType(merge(tps), owner) -*/ - - /** A creator for type applications */ - def appliedType(tycon: Type, args: List[Type]): Type = - if (args.isEmpty) tycon //@M! `if (args.isEmpty) tycon' is crucial (otherwise we create new types in phases after typer and then they don't get adapted (??)) - else tycon match { - case TypeRef(pre, sym @ (NothingClass|AnyClass), _) => copyTypeRef(tycon, pre, sym, Nil) //@M drop type args to Any/Nothing - case TypeRef(pre, sym, _) => copyTypeRef(tycon, pre, sym, args) - case PolyType(tparams, restpe) => restpe.instantiateTypeParams(tparams, args) - case ExistentialType(tparams, restpe) => newExistentialType(tparams, appliedType(restpe, args)) - case st: SingletonType => appliedType(st.widen, args) // @M TODO: what to do? see bug1 - case RefinedType(parents, decls) => RefinedType(parents map (appliedType(_, args)), decls) // MO to AM: please check - case TypeBounds(lo, hi) => TypeBounds(appliedType(lo, args), appliedType(hi, args)) - case tv@TypeVar(_, _) => tv.applyArgs(args) - case AnnotatedType(annots, underlying, self) => AnnotatedType(annots, appliedType(underlying, args), self) - case ErrorType => tycon - case WildcardType => tycon // needed for neg/t0226 - case _ => abort(debugString(tycon)) - } - - /** Very convenient. */ - def appliedType(tyconSym: Symbol, args: Type*): Type = - appliedType(tyconSym.typeConstructor, args.toList) - - /** A creator for existential types where the type arguments, - * rather than being applied directly, are interpreted as the - * upper bounds of unknown types. For instance if the type argument - * list given is List(AnyRefClass), the resulting type would be - * e.g. Set[_ <: AnyRef] rather than Set[AnyRef] . - */ - def appliedTypeAsUpperBounds(tycon: Type, args: List[Type]): Type = { - tycon match { - case TypeRef(pre, sym, _) if sameLength(sym.typeParams, args) => - val eparams = typeParamsToExistentials(sym) - val bounds = args map (TypeBounds upper _) - foreach2(eparams, bounds)(_ setInfo _) - - newExistentialType(eparams, typeRef(pre, sym, eparams map (_.tpe))) - case _ => - appliedType(tycon, args) - } - } - - /** A creator and extractor 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.) - */ - object GenPolyType { - def apply(tparams: List[Symbol], tpe: Type): Type = ( - if (tparams nonEmpty) typeFun(tparams, tpe) - else tpe // it's okay to be forgiving here - ) - def unapply(tpe: Type): Option[(List[Symbol], Type)] = tpe match { - case PolyType(tparams, restpe) => Some((tparams, restpe)) - case _ => Some((Nil, tpe)) - } - } - def genPolyType(params: List[Symbol], tpe: Type): Type = GenPolyType(params, tpe) - - @deprecated("use genPolyType(...) instead", "2.10.0") - def polyType(params: List[Symbol], tpe: Type): Type = GenPolyType(params, tpe) - - /** A creator for anonymous type functions, where the symbol for the type function still needs to be created. - * - * TODO: - * type params of anonymous type functions, which currently can only arise from normalising type aliases, are owned by the type alias of which they are the eta-expansion - * higher-order subtyping expects eta-expansion of type constructors that arise from a class; here, the type params are owned by that class, but is that the right thing to do? - */ - def typeFunAnon(tps: List[Symbol], body: Type): Type = typeFun(tps, body) - - /** A creator for a type functions, assuming the type parameters tps already have the right owner. */ - def typeFun(tps: List[Symbol], body: Type): Type = PolyType(tps, body) - - /** A creator for existential types. This generates: - * - * tpe1 where { tparams } - * - * where `tpe1` is the result of extrapolating `tpe` wrt to `tparams`. - * Extrapolating means that type variables in `tparams` occurring - * in covariant positions are replaced by upper bounds, (minus any - * SingletonClass markers), type variables in `tparams` occurring in - * contravariant positions are replaced by upper bounds, provided the - * resulting type is legal wrt to stability, and does not contain any type - * variable in `tparams`. - * - * The abstraction drops all type parameters that are not directly or - * indirectly referenced by type `tpe1`. If there are no remaining type - * parameters, simply returns result type `tpe`. - */ - def existentialAbstraction(tparams: List[Symbol], tpe0: Type): Type = - if (tparams.isEmpty) tpe0 - else { - val tpe = deAlias(tpe0) - val tpe1 = new ExistentialExtrapolation(tparams) extrapolate tpe - var tparams0 = tparams - var tparams1 = tparams0 filter tpe1.contains - - while (tparams1 != tparams0) { - tparams0 = tparams1 - tparams1 = tparams filter { p => - tparams1 exists { p1 => p1 == p || (p1.info contains p) } - } - } - newExistentialType(tparams1, tpe1) - } - - /** Remove any occurrences of type aliases from this type */ - object deAlias extends TypeMap { - def apply(tp: Type): Type = mapOver { - tp match { - case TypeRef(pre, sym, args) if sym.isAliasType => tp.normalize - case _ => tp - } - } - } - - /** Remove any occurrence of type <singleton> from this type and its parents */ - object dropSingletonType extends TypeMap { - def apply(tp: Type): Type = { - tp match { - case TypeRef(_, SingletonClass, _) => - AnyClass.tpe - case tp1 @ RefinedType(parents, decls) => - var parents1 = parents filter (_.typeSymbol != SingletonClass) - if (parents1.isEmpty) parents1 = List(AnyClass.tpe) - if (parents1.tail.isEmpty && decls.isEmpty) mapOver(parents1.head) - else mapOver(copyRefinedType(tp1, parents1, decls)) - case tp1 => - mapOver(tp1) - } - } - } - - /** Substitutes the empty scope for any non-empty decls in the type. */ - object dropAllRefinements extends TypeMap { - def apply(tp: Type): Type = tp match { - case rt @ RefinedType(parents, decls) if !decls.isEmpty => - mapOver(copyRefinedType(rt, parents, EmptyScope)) - case ClassInfoType(parents, decls, clazz) if !decls.isEmpty => - mapOver(ClassInfoType(parents, EmptyScope, clazz)) - case _ => - mapOver(tp) - } - } - - /** Type with all top-level occurrences of abstract types replaced by their bounds */ - def abstractTypesToBounds(tp: Type): Type = tp match { // @M don't normalize here (compiler loops on pos/bug1090.scala ) - case TypeRef(_, sym, _) if sym.isAbstractType => - abstractTypesToBounds(tp.bounds.hi) - case TypeRef(_, sym, _) if sym.isAliasType => - abstractTypesToBounds(tp.normalize) - case rtp @ RefinedType(parents, decls) => - copyRefinedType(rtp, parents mapConserve abstractTypesToBounds, decls) - case AnnotatedType(_, underlying, _) => - abstractTypesToBounds(underlying) - case _ => - tp - } - - // Set to true for A* => Seq[A] - // (And it will only rewrite A* in method result types.) - // This is the pre-existing behavior. - // Or false for Seq[A] => Seq[A] - // (It will rewrite A* everywhere but method parameters.) - // This is the specified behavior. - protected def etaExpandKeepsStar = false - - object dropRepeatedParamType extends TypeMap { - def apply(tp: Type): Type = tp match { - case MethodType(params, restpe) => - MethodType(params, apply(restpe)) - case PolyType(tparams, restpe) => - PolyType(tparams, apply(restpe)) - case TypeRef(_, RepeatedParamClass, arg :: Nil) => - seqType(arg) - case _ => - if (etaExpandKeepsStar) tp else mapOver(tp) - } - } - - object toDeBruijn extends TypeMap { - private var paramStack: List[List[Symbol]] = Nil - def mkDebruijnBinder(params: List[Symbol], restpe: Type) = { - paramStack = params :: paramStack - try { - DeBruijnBinder(params map (_.name), params map (p => this(p.info)), this(restpe)) - } finally paramStack = paramStack.tail - } - def apply(tp: Type): Type = tp match { - case PolyType(tparams, restpe) => - mkDebruijnBinder(tparams, restpe) - case MethodType(params, restpe) => - mkDebruijnBinder(params, restpe) - case TypeRef(NoPrefix, sym, args) => - val level = paramStack indexWhere (_ contains sym) - if (level < 0) mapOver(tp) - else DeBruijnIndex(level, paramStack(level) indexOf sym, args mapConserve this) - case _ => - mapOver(tp) - } - } - - def fromDeBruijn(owner: Symbol) = new TypeMap { - private var paramStack: List[List[Symbol]] = Nil - def apply(tp: Type): Type = tp match { - case DeBruijnBinder(pnames, ptypes, restpe) => - val isType = pnames.head.isTypeName - val newParams = for (name <- pnames) yield - if (isType) owner.newTypeParameter(name.toTypeName) - else owner.newValueParameter(name.toTermName) - paramStack = newParams :: paramStack - try { - foreach2(newParams, ptypes)((p, t) => p setInfo this(t)) - val restpe1 = this(restpe) - if (isType) PolyType(newParams, restpe1) - else MethodType(newParams, restpe1) - } finally paramStack = paramStack.tail - case DeBruijnIndex(level, idx, args) => - TypeRef(NoPrefix, paramStack(level)(idx), args map this) - case _ => - mapOver(tp) - } - } - -// Hash consing -------------------------------------------------------------- - - private val initialUniquesCapacity = 4096 - private var uniques: util.HashSet[Type] = _ - private var uniqueRunId = NoRunId - - protected def unique[T <: Type](tp: T): T = { - incCounter(rawTypeCount) - if (uniqueRunId != currentRunId) { - uniques = util.HashSet[Type]("uniques", initialUniquesCapacity) - uniqueRunId = currentRunId - } - (uniques findEntryOrUpdate tp).asInstanceOf[T] - } - -// Helper Classes --------------------------------------------------------- - - /** @PP: Unable to see why these apparently constant types should need vals - * in every TypeConstraint, I lifted them out. - */ - private lazy val numericLoBound = IntClass.tpe - private lazy val numericHiBound = intersectionType(List(ByteClass.tpe, CharClass.tpe), ScalaPackageClass) - - /** A class expressing upper and lower bounds constraints of type variables, - * as well as their instantiations. - */ - class TypeConstraint(lo0: List[Type], hi0: List[Type], numlo0: Type, numhi0: Type, avoidWidening0: Boolean = false) { - def this(lo0: List[Type], hi0: List[Type]) = this(lo0, hi0, NoType, NoType) - def this(bounds: TypeBounds) = this(List(bounds.lo), List(bounds.hi)) - def this() = this(List(), List()) - - /* Syncnote: Type constraints are assumed to be used from only one - * thread. They are not exposed in api.Types and are used only locally - * in operations that are exposed from types. Hence, no syncing of any - * variables should be ncessesary. - */ - - /** Guard these lists against AnyClass and NothingClass appearing, - * else loBounds.isEmpty will have different results for an empty - * constraint and one with Nothing as a lower bound. [Actually - * guarding addLoBound/addHiBound somehow broke raw types so it - * only guards against being created with them.] - */ - private var lobounds = lo0 filterNot (_.typeSymbolDirect eq NothingClass) - private var hibounds = hi0 filterNot (_.typeSymbolDirect eq AnyClass) - private var numlo = numlo0 - private var numhi = numhi0 - private var avoidWidening = avoidWidening0 - - def loBounds: List[Type] = if (numlo == NoType) lobounds else numlo :: lobounds - def hiBounds: List[Type] = if (numhi == NoType) hibounds else numhi :: hibounds - def avoidWiden: Boolean = avoidWidening - - def addLoBound(tp: Type, isNumericBound: Boolean = false) { - if (isNumericBound && isNumericValueType(tp)) { - if (numlo == NoType || isNumericSubType(numlo, tp)) - numlo = tp - else if (!isNumericSubType(tp, numlo)) - numlo = numericLoBound - } - else lobounds ::= tp - } - - def checkWidening(tp: Type) { - if(tp.isStable) avoidWidening = true - else tp match { - case HasTypeMember(_, _) => avoidWidening = true - case _ => - } - } - - def addHiBound(tp: Type, isNumericBound: Boolean = false) { - checkWidening(tp) - if (isNumericBound && isNumericValueType(tp)) { - if (numhi == NoType || isNumericSubType(tp, numhi)) - numhi = tp - else if (!isNumericSubType(numhi, tp)) - numhi = numericHiBound - } - else hibounds ::= tp - } - - def isWithinBounds(tp: Type): Boolean = - lobounds.forall(_ <:< tp) && - hibounds.forall(tp <:< _) && - (numlo == NoType || (numlo weak_<:< tp)) && - (numhi == NoType || (tp weak_<:< numhi)) - - var inst: Type = NoType // @M reduce visibility? - - def instValid = (inst ne null) && (inst ne NoType) - - def cloneInternal = { - val tc = new TypeConstraint(lobounds, hibounds, numlo, numhi, avoidWidening) - tc.inst = inst - tc - } - - override def toString = { - val boundsStr = { - val lo = loBounds filterNot (_.typeSymbolDirect eq NothingClass) - val hi = hiBounds filterNot (_.typeSymbolDirect eq AnyClass) - val lostr = if (lo.isEmpty) Nil else List(lo.mkString(" >: (", ", ", ")")) - val histr = if (hi.isEmpty) Nil else List(hi.mkString(" <: (", ", ", ")")) - - lostr ++ histr mkString ("[", " | ", "]") - } - if (inst eq NoType) boundsStr - else boundsStr + " _= " + inst.safeToString - } - } - - class TypeUnwrapper(poly: Boolean, existential: Boolean, annotated: Boolean, nullary: Boolean) extends (Type => Type) { - def apply(tp: Type): Type = tp match { - case AnnotatedType(_, underlying, _) if annotated => apply(underlying) - case ExistentialType(_, underlying) if existential => apply(underlying) - case PolyType(_, underlying) if poly => apply(underlying) - case NullaryMethodType(underlying) if nullary => apply(underlying) - case tp => tp - } - } - class ClassUnwrapper(existential: Boolean) extends TypeUnwrapper(poly = true, existential, annotated = true, nullary = false) { - override def apply(tp: Type) = super.apply(tp.normalize) - } - - object unwrapToClass extends ClassUnwrapper(existential = true) { } - object unwrapToStableClass extends ClassUnwrapper(existential = false) { } - object unwrapWrapperTypes extends TypeUnwrapper(true, true, true, true) { } - - trait AnnotationFilter extends TypeMap { - def keepAnnotation(annot: AnnotationInfo): Boolean - - override def mapOver(annot: AnnotationInfo) = - if (keepAnnotation(annot)) super.mapOver(annot) - else UnmappableAnnotation - } - - trait KeepOnlyTypeConstraints extends AnnotationFilter { - // filter keeps only type constraint annotations - def keepAnnotation(annot: AnnotationInfo) = annot matches TypeConstraintClass - } - - trait VariantTypeMap extends TypeMap { - private[this] var _variance = 1 - - override def variance = _variance - def variance_=(x: Int) = _variance = x - - override protected def noChangeToSymbols(origSyms: List[Symbol]) = { - origSyms forall { sym => - val v = variance - if (sym.isAliasType) variance = 0 - val result = this(sym.info) - variance = v - result eq sym.info - } - } - - override protected def mapOverArgs(args: List[Type], tparams: List[Symbol]): List[Type] = - map2Conserve(args, tparams) { (arg, tparam) => - val v = variance - if (tparam.isContravariant) variance = -variance - else if (!tparam.isCovariant) variance = 0 - val arg1 = this(arg) - variance = v - arg1 - } - - /** Map this function over given type */ - override def mapOver(tp: Type): Type = tp match { - case MethodType(params, result) => - variance = -variance - val params1 = mapOver(params) - variance = -variance - val result1 = this(result) - if ((params1 eq params) && (result1 eq result)) tp - else copyMethodType(tp, params1, result1.substSym(params, params1)) - case PolyType(tparams, result) => - variance = -variance - val tparams1 = mapOver(tparams) - variance = -variance - var result1 = this(result) - if ((tparams1 eq tparams) && (result1 eq result)) tp - else PolyType(tparams1, result1.substSym(tparams, tparams1)) - case TypeBounds(lo, hi) => - variance = -variance - val lo1 = this(lo) - variance = -variance - val hi1 = this(hi) - if ((lo1 eq lo) && (hi1 eq hi)) tp - else TypeBounds(lo1, hi1) - case tr @ TypeRef(pre, sym, args) => - val pre1 = this(pre) - val args1 = - if (args.isEmpty) - args - else if (variance == 0) // fast & safe path: don't need to look at typeparams - args mapConserve this - else { - val tparams = sym.typeParams - if (tparams.isEmpty) args - else mapOverArgs(args, tparams) - } - if ((pre1 eq pre) && (args1 eq args)) tp - else copyTypeRef(tp, pre1, tr.coevolveSym(pre1), args1) - case _ => - super.mapOver(tp) - } - } - - // todo. move these into scala.reflect.api - - /** A prototype for mapping a function over all possible types - */ - abstract class TypeMap extends (Type => Type) { - def apply(tp: Type): Type - - /** Mix in VariantTypeMap if you want variances to be significant. - */ - def variance = 0 - - /** Map this function over given type */ - def mapOver(tp: Type): Type = tp match { - case tr @ TypeRef(pre, sym, args) => - val pre1 = this(pre) - val args1 = args mapConserve this - if ((pre1 eq pre) && (args1 eq args)) tp - else copyTypeRef(tp, pre1, tr.coevolveSym(pre1), args1) - case ThisType(_) => tp - case SingleType(pre, sym) => - if (sym.isPackageClass) tp // short path - else { - val pre1 = this(pre) - if (pre1 eq pre) tp - else singleType(pre1, sym) - } - case MethodType(params, result) => - val params1 = mapOver(params) - val result1 = this(result) - if ((params1 eq params) && (result1 eq result)) tp - else copyMethodType(tp, params1, result1.substSym(params, params1)) - case PolyType(tparams, result) => - val tparams1 = mapOver(tparams) - var result1 = this(result) - if ((tparams1 eq tparams) && (result1 eq result)) tp - else PolyType(tparams1, result1.substSym(tparams, tparams1)) - case NullaryMethodType(result) => - val result1 = this(result) - if (result1 eq result) tp - else NullaryMethodType(result1) - case ConstantType(_) => tp - case SuperType(thistp, supertp) => - val thistp1 = this(thistp) - val supertp1 = this(supertp) - if ((thistp1 eq thistp) && (supertp1 eq supertp)) tp - else SuperType(thistp1, supertp1) - case TypeBounds(lo, hi) => - val lo1 = this(lo) - val hi1 = this(hi) - if ((lo1 eq lo) && (hi1 eq hi)) tp - else TypeBounds(lo1, hi1) - case BoundedWildcardType(bounds) => - val bounds1 = this(bounds) - if (bounds1 eq bounds) tp - else BoundedWildcardType(bounds1.asInstanceOf[TypeBounds]) - case rtp @ RefinedType(parents, decls) => - val parents1 = parents mapConserve this - val decls1 = mapOver(decls) - //if ((parents1 eq parents) && (decls1 eq decls)) tp - //else refinementOfClass(tp.typeSymbol, parents1, decls1) - copyRefinedType(rtp, parents1, decls1) - case ExistentialType(tparams, result) => - val tparams1 = mapOver(tparams) - var result1 = this(result) - if ((tparams1 eq tparams) && (result1 eq result)) tp - else newExistentialType(tparams1, result1.substSym(tparams, tparams1)) - case OverloadedType(pre, alts) => - val pre1 = if (pre.isInstanceOf[ClassInfoType]) pre else this(pre) - if (pre1 eq pre) tp - else OverloadedType(pre1, alts) - case AntiPolyType(pre, args) => - val pre1 = this(pre) - val args1 = args mapConserve (this) - if ((pre1 eq pre) && (args1 eq args)) tp - else AntiPolyType(pre1, args1) - case tv@TypeVar(_, constr) => - if (constr.instValid) this(constr.inst) - else tv.applyArgs(mapOverArgs(tv.typeArgs, tv.params)) //@M !args.isEmpty implies !typeParams.isEmpty - case NotNullType(tp) => - val tp1 = this(tp) - if (tp1 eq tp) tp - else NotNullType(tp1) - case AnnotatedType(annots, atp, selfsym) => - val annots1 = mapOverAnnotations(annots) - val atp1 = this(atp) - if ((annots1 eq annots) && (atp1 eq atp)) tp - else if (annots1.isEmpty) atp1 - else AnnotatedType(annots1, atp1, selfsym) - case DeBruijnIndex(shift, idx, args) => - val args1 = args mapConserve this - if (args1 eq args) tp - else DeBruijnIndex(shift, idx, args1) -/* - case ErrorType => tp - case WildcardType => tp - case NoType => tp - case NoPrefix => tp - case ErasedSingleType(sym) => tp -*/ - case _ => - tp - // throw new Error("mapOver inapplicable for " + tp); - } - - protected def mapOverArgs(args: List[Type], tparams: List[Symbol]): List[Type] = - args mapConserve this - - /** Called by mapOver to determine whether the original symbols can - * be returned, or whether they must be cloned. Overridden in VariantTypeMap. - */ - protected def noChangeToSymbols(origSyms: List[Symbol]) = - origSyms forall (sym => sym.info eq this(sym.info)) - - /** Map this function over given scope */ - def mapOver(scope: Scope): Scope = { - val elems = scope.toList - val elems1 = mapOver(elems) - if (elems1 eq elems) scope - else newScopeWith(elems1: _*) - } - - /** Map this function over given list of symbols */ - def mapOver(origSyms: List[Symbol]): List[Symbol] = { - // fast path in case nothing changes due to map - if (noChangeToSymbols(origSyms)) origSyms - // map is not the identity --> do cloning properly - else cloneSymbolsAndModify(origSyms, TypeMap.this) - } - - def mapOver(annot: AnnotationInfo): AnnotationInfo = { - val AnnotationInfo(atp, args, assocs) = annot - val atp1 = mapOver(atp) - val args1 = mapOverAnnotArgs(args) - // there is no need to rewrite assocs, as they are constants - - if ((args eq args1) && (atp eq atp1)) annot - else if (args1.isEmpty && args.nonEmpty) UnmappableAnnotation // some annotation arg was unmappable - else AnnotationInfo(atp1, args1, assocs) setPos annot.pos - } - - def mapOverAnnotations(annots: List[AnnotationInfo]): List[AnnotationInfo] = { - val annots1 = annots mapConserve mapOver - if (annots1 eq annots) annots - else annots1 filterNot (_ eq UnmappableAnnotation) - } - - /** Map over a set of annotation arguments. If any - * of the arguments cannot be mapped, then return Nil. */ - def mapOverAnnotArgs(args: List[Tree]): List[Tree] = { - val args1 = args mapConserve mapOver - if (args1 contains UnmappableTree) Nil - else args1 - } - - def mapOver(tree: Tree): Tree = - mapOver(tree, () => return UnmappableTree) - - /** Map a tree that is part of an annotation argument. - * If the tree cannot be mapped, then invoke giveup(). - * The default is to transform the tree with - * TypeMapTransformer. - */ - def mapOver(tree: Tree, giveup: ()=>Nothing): Tree = - (new TypeMapTransformer).transform(tree) - - /** This transformer leaves the tree alone except to remap - * its types. */ - class TypeMapTransformer extends Transformer { - override def transform(tree: Tree) = { - val tree1 = super.transform(tree) - val tpe1 = TypeMap.this(tree1.tpe) - if ((tree eq tree1) && (tree.tpe eq tpe1)) - tree - else - tree1.shallowDuplicate.setType(tpe1) - } - } - } - - abstract class TypeTraverser extends TypeMap { - def traverse(tp: Type): Unit - def apply(tp: Type): Type = { traverse(tp); tp } - } - - abstract class TypeTraverserWithResult[T] extends TypeTraverser { - def result: T - def clear(): Unit - } - - abstract class TypeCollector[T](initial: T) extends TypeTraverser { - var result: T = _ - def collect(tp: Type) = { - result = initial - traverse(tp) - result - } - } - - /** A collector that tests for existential types appearing at given variance in a type - * @PP: Commenting out due to not being used anywhere. - */ - // class ContainsVariantExistentialCollector(v: Int) extends TypeCollector(false) with VariantTypeMap { - // variance = v - // - // def traverse(tp: Type) = tp match { - // case ExistentialType(_, _) if (variance == v) => result = true - // case _ => mapOver(tp) - // } - // } - // - // val containsCovariantExistentialCollector = new ContainsVariantExistentialCollector(1) - // val containsContravariantExistentialCollector = new ContainsVariantExistentialCollector(-1) - - def typeParamsToExistentials(clazz: Symbol, tparams: List[Symbol]): List[Symbol] = { - val eparams = mapWithIndex(tparams)((tparam, i) => - clazz.newExistential(newTypeName("?"+i), clazz.pos) setInfo tparam.info.bounds) - - eparams map (_ substInfo (tparams, eparams)) - } - def typeParamsToExistentials(clazz: Symbol): List[Symbol] = - typeParamsToExistentials(clazz, clazz.typeParams) - - // note: it's important to write the two tests in this order, - // as only typeParams forces the classfile to be read. See #400 - private def isRawIfWithoutArgs(sym: Symbol) = - sym.isClass && sym.typeParams.nonEmpty && sym.isJavaDefined - - def isRaw(sym: Symbol, args: List[Type]) = - !phase.erasedTypes && isRawIfWithoutArgs(sym) && args.isEmpty - - /** Is type tp a ''raw type''? */ - def isRawType(tp: Type) = tp match { - case TypeRef(_, sym, args) => isRaw(sym, args) - case _ => false - } - - /** The raw to existential map converts a ''raw type'' to an existential type. - * It is necessary because we might have read a raw type of a - * parameterized Java class from a class file. At the time we read the type - * the corresponding class file might still not be read, so we do not - * know what the type parameters of the type are. Therefore - * the conversion of raw types to existential types might not have taken place - * in ClassFileparser.sigToType (where it is usually done). - */ - def rawToExistential = new TypeMap { - private var expanded = immutable.Set[Symbol]() - def apply(tp: Type): Type = tp match { - case TypeRef(pre, sym, List()) if isRawIfWithoutArgs(sym) => - if (expanded contains sym) AnyRefClass.tpe - else try { - expanded += sym - val eparams = mapOver(typeParamsToExistentials(sym)) - existentialAbstraction(eparams, typeRef(apply(pre), sym, eparams map (_.tpe))) - } finally { - expanded -= sym - } - case _ => - mapOver(tp) - } - } - - /** Used by existentialAbstraction. - */ - class ExistentialExtrapolation(tparams: List[Symbol]) extends VariantTypeMap { - private val occurCount = mutable.HashMap[Symbol, Int]() - private def countOccs(tp: Type) = { - tp foreach { - case TypeRef(_, sym, _) => - if (tparams contains sym) - occurCount(sym) += 1 - case _ => () - } - } - def extrapolate(tpe: Type): Type = { - tparams foreach (t => occurCount(t) = 0) - countOccs(tpe) - for (tparam <- tparams) - countOccs(tparam.info) - - apply(tpe) - } - - def apply(tp: Type): Type = { - val tp1 = mapOver(tp) - if (variance == 0) tp1 - else tp1 match { - case TypeRef(pre, sym, args) if tparams contains sym => - val repl = if (variance == 1) dropSingletonType(tp1.bounds.hi) else tp1.bounds.lo - //println("eliminate "+sym+"/"+repl+"/"+occurCount(sym)+"/"+(tparams exists (repl.contains)))//DEBUG - if (!repl.typeSymbol.isBottomClass && occurCount(sym) == 1 && !(tparams exists (repl.contains))) - repl - else tp1 - case _ => - tp1 - } - } - override def mapOver(tp: Type): Type = tp match { - case SingleType(pre, sym) => - if (sym.isPackageClass) tp // short path - else { - val pre1 = this(pre) - if ((pre1 eq pre) || !pre1.isStable) tp - else singleType(pre1, sym) - } - case _ => super.mapOver(tp) - } - - // Do not discard the types of existential ident's. The - // symbol of the Ident itself cannot be listed in the - // existential's parameters, so the resulting existential - // type would be ill-formed. - override def mapOver(tree: Tree) = tree match { - case Ident(_) if tree.tpe.isStable => tree - case _ => super.mapOver(tree) - } - } - - def singletonBounds(hi: Type) = TypeBounds.upper(intersectionType(List(hi, SingletonClass.tpe))) - - /** A map to compute the asSeenFrom method */ - class AsSeenFromMap(pre: Type, clazz: Symbol) extends TypeMap with KeepOnlyTypeConstraints { - var capturedSkolems: List[Symbol] = List() - var capturedParams: List[Symbol] = List() - var capturedPre = emptySymMap - - override def mapOver(tree: Tree, giveup: ()=>Nothing): Tree = { - object annotationArgRewriter extends TypeMapTransformer { - /** Rewrite `This` trees in annotation argument trees */ - def rewriteThis(tree: Tree): Tree = - tree match { - case This(_) - if (tree.symbol isNonBottomSubClass clazz) && - (pre.widen.typeSymbol isNonBottomSubClass tree.symbol) => - if (pre.isStable) { // XXX why is this in this method? pull it out and guard the call `annotationArgRewriter.transform(tree)`? - val termSym = ( - pre.typeSymbol.owner.newValue(pre.typeSymbol.name.toTermName, pre.typeSymbol.pos) // what symbol should really be used? - setInfo pre - ) - gen.mkAttributedQualifier(pre, termSym) - } else - giveup() - - case tree => tree - } - - override def transform(tree: Tree): Tree = { - val tree1 = rewriteThis(super.transform(tree)) - tree1 - } - } - - annotationArgRewriter.transform(tree) - } - - def stabilize(pre: Type, clazz: Symbol): Type = - capturedPre.getOrElse(clazz, { - val qvar = clazz freshExistential ".type" setInfo singletonBounds(pre) - capturedPre += (clazz -> qvar) - capturedParams = qvar :: capturedParams - qvar - }).tpe - - /** Return `pre.baseType(clazz)`, or if that's `NoType` and `clazz` is a refinement, `pre` itself. - * See bug397.scala for an example where the second alternative is needed. - * The problem is that when forming the base type sequence of an abstract type, - * any refinements in the base type list might be regenerated, and thus acquire - * new class symbols. However, since refinements always have non-interesting prefixes - * it looks OK to me to just take the prefix directly. */ - def base(pre: Type, clazz: Symbol) = { - val b = pre.baseType(clazz) - if (b == NoType && clazz.isRefinementClass) pre - else b - } - - def apply(tp: Type): Type = - if ((pre eq NoType) || (pre eq NoPrefix) || !clazz.isClass) tp - else tp match { - case ThisType(sym) => - def toPrefix(pre: Type, clazz: Symbol): Type = - if ((pre eq NoType) || (pre eq NoPrefix) || !clazz.isClass) tp - else if ((sym isNonBottomSubClass clazz) && - (pre.widen.typeSymbol isNonBottomSubClass sym)) { - val pre1 = pre match { - case SuperType(thistp, _) => thistp - case _ => pre - } - if (!(pre1.isStable || - pre1.typeSymbol.isPackageClass || - pre1.typeSymbol.isModuleClass && pre1.typeSymbol.isStatic)) { - stabilize(pre1, sym) - } else { - pre1 - } - } else { - toPrefix(base(pre, clazz).prefix, clazz.owner) - } - toPrefix(pre, clazz) - case SingleType(pre, sym) => - if (sym.isPackageClass) tp // short path - else { - val pre1 = this(pre) - if (pre1 eq pre) tp - else if (pre1.isStable) singleType(pre1, sym) - else pre1.memberType(sym).resultType //todo: this should be rolled into existential abstraction - } - // AM: Martin, is this description accurate? - // walk the owner chain of `clazz` (the original argument to asSeenFrom) until we find the type param's owner (while rewriting pre as we crawl up the owner chain) - // once we're at the owner, extract the information that pre encodes about the type param, - // by minimally subsuming pre to the type instance of the class that owns the type param, - // the type we're looking for is the type instance's type argument at the position corresponding to the type parameter - // optimisation: skip this type parameter if it's not owned by a class, as those params are not influenced by the prefix through which they are seen - // (concretely: type params of anonymous type functions, which currently can only arise from normalising type aliases, are owned by the type alias of which they are the eta-expansion) - // (skolems also aren't affected: they are ruled out by the isTypeParameter check) - case TypeRef(prefix, sym, args) if (sym.isTypeParameter && sym.owner.isClass) => - def toInstance(pre: Type, clazz: Symbol): Type = - if ((pre eq NoType) || (pre eq NoPrefix) || !clazz.isClass) mapOver(tp) - //@M! see test pos/tcpoly_return_overriding.scala why mapOver is necessary - else { - def throwError = abort("" + tp + sym.locationString + " cannot be instantiated from " + pre.widen) - - val symclazz = sym.owner - if (symclazz == clazz && !pre.widen.isInstanceOf[TypeVar] && (pre.widen.typeSymbol isNonBottomSubClass symclazz)) { - // have to deconst because it may be a Class[T]. - pre.baseType(symclazz).deconst match { - case TypeRef(_, basesym, baseargs) => - - def instParam(ps: List[Symbol], as: List[Type]): Type = - if (ps.isEmpty) { - if (forInteractive) { - val saved = settings.uniqid.value - try { - settings.uniqid.value = true - println("*** stale type parameter: " + tp + sym.locationString + " cannot be instantiated from " + pre.widen) - println("*** confused with params: " + sym + " in " + sym.owner + " not in " + ps + " of " + basesym) - println("*** stacktrace = ") - new Error().printStackTrace() - } finally settings.uniqid.value = saved - instParamRelaxed(basesym.typeParams, baseargs) - } else throwError - } else if (sym eq ps.head) - // @M! don't just replace the whole thing, might be followed by type application - appliedType(as.head, args mapConserve (this)) // @M: was as.head - else instParam(ps.tail, as.tail) - - /** Relaxed version of instParams which matches on names not symbols. - * This is a last fallback in interactive mode because races in calls - * from the IDE to the compiler may in rare cases lead to symbols referring - * to type parameters that are no longer current. - */ - def instParamRelaxed(ps: List[Symbol], as: List[Type]): Type = - if (ps.isEmpty) throwError - else if (sym.name == ps.head.name) - // @M! don't just replace the whole thing, might be followed by type application - appliedType(as.head, args mapConserve (this)) // @M: was as.head - else instParamRelaxed(ps.tail, as.tail) - - //Console.println("instantiating " + sym + " from " + basesym + " with " + basesym.typeParams + " and " + baseargs+", pre = "+pre+", symclazz = "+symclazz);//DEBUG - if (sameLength(basesym.typeParams, baseargs)) - instParam(basesym.typeParams, baseargs) - else - if (symclazz.tpe.parents.exists(_.isErroneous)) - ErrorType // don't be to overzealous with throwing exceptions, see #2641 - else - throw new Error( - "something is wrong (wrong class file?): "+basesym+ - " with type parameters "+ - basesym.typeParams.map(_.name).mkString("[",",","]")+ - " gets applied to arguments "+baseargs.mkString("[",",","]")+", phase = "+phase) - case ExistentialType(tparams, qtpe) => - capturedSkolems = capturedSkolems union tparams - toInstance(qtpe, clazz) - case t => - throwError - } - } else toInstance(base(pre, clazz).prefix, clazz.owner) - } - toInstance(pre, clazz) - case _ => - mapOver(tp) - } - } - - /** A base class to compute all substitutions */ - abstract class SubstMap[T](from: List[Symbol], to: List[T]) extends TypeMap { - assert(sameLength(from, to), "Unsound substitution from "+ from +" to "+ to) - - /** Are `sym` and `sym1` the same? Can be tuned by subclasses. */ - protected def matches(sym: Symbol, sym1: Symbol): Boolean = sym eq sym1 - - /** Map target to type, can be tuned by subclasses */ - protected def toType(fromtp: Type, tp: T): Type - - protected def renameBoundSyms(tp: Type): Type = tp match { - case MethodType(ps, restp) => - createFromClonedSymbols(ps, restp)((ps1, tp1) => copyMethodType(tp, ps1, renameBoundSyms(tp1))) - case PolyType(bs, restp) => - createFromClonedSymbols(bs, restp)((ps1, tp1) => PolyType(ps1, renameBoundSyms(tp1))) - case ExistentialType(bs, restp) => - createFromClonedSymbols(bs, restp)(newExistentialType) - case _ => - tp - } - - def apply(tp0: Type): Type = if (from.isEmpty) tp0 else { - @tailrec def subst(tp: Type, sym: Symbol, from: List[Symbol], to: List[T]): Type = - if (from.isEmpty) tp - // else if (to.isEmpty) error("Unexpected substitution on '%s': from = %s but to == Nil".format(tp, from)) - else if (matches(from.head, sym)) toType(tp, to.head) - else subst(tp, sym, from.tail, to.tail) - - val boundSyms = tp0.boundSyms - val tp1 = if (boundSyms exists from.contains) renameBoundSyms(tp0) else tp0 - val tp = mapOver(tp1) - - tp match { - // @M - // 1) arguments must also be substituted (even when the "head" of the - // applied type has already been substituted) - // example: (subst RBound[RT] from [type RT,type RBound] to - // [type RT&,type RBound&]) = RBound&[RT&] - // 2) avoid loops (which occur because alpha-conversion is - // not performed properly imo) - // e.g. if in class Iterable[a] there is a new Iterable[(a,b)], - // we must replace the a in Iterable[a] by (a,b) - // (must not recurse --> loops) - // 3) replacing m by List in m[Int] should yield List[Int], not just List - case TypeRef(NoPrefix, sym, args) => - appliedType(subst(tp, sym, from, to), args) // if args.isEmpty, appliedType is the identity - case SingleType(NoPrefix, sym) => - subst(tp, sym, from, to) - case _ => - tp - } - } - } - - /** A map to implement the `substSym` method. */ - class SubstSymMap(from: List[Symbol], to: List[Symbol]) extends SubstMap(from, to) { - protected def toType(fromtp: Type, sym: Symbol) = fromtp match { - case TypeRef(pre, _, args) => copyTypeRef(fromtp, pre, sym, args) - case SingleType(pre, _) => singleType(pre, sym) - } - override def apply(tp: Type): Type = if (from.isEmpty) tp else { - @tailrec def subst(sym: Symbol, from: List[Symbol], to: List[Symbol]): Symbol = - if (from.isEmpty) sym - // else if (to.isEmpty) error("Unexpected substitution on '%s': from = %s but to == Nil".format(sym, from)) - else if (matches(from.head, sym)) to.head - else subst(sym, from.tail, to.tail) - tp match { - case TypeRef(pre, sym, args) if pre ne NoPrefix => - val newSym = subst(sym, from, to) - // assert(newSym.typeParams.length == sym.typeParams.length, "typars mismatch in SubstSymMap: "+(sym, sym.typeParams, newSym, newSym.typeParams)) - mapOver(copyTypeRef(tp, pre, newSym, args)) // mapOver takes care of subst'ing in args - case SingleType(pre, sym) if pre ne NoPrefix => - mapOver(singleType(pre, subst(sym, from, to))) - case _ => - super.apply(tp) - } - } - - override def mapOver(tree: Tree, giveup: ()=>Nothing): Tree = { - object trans extends TypeMapTransformer { - - def termMapsTo(sym: Symbol) = from indexOf sym match { - case -1 => None - case idx => Some(to(idx)) - } - - override def transform(tree: Tree) = - tree match { - case tree@Ident(_) => - termMapsTo(tree.symbol) match { - case Some(tosym) => - if (tosym.info.bounds.hi.typeSymbol isSubClass SingletonClass) { - Ident(tosym.existentialToString) - .setSymbol(tosym) - .setPos(tosym.pos) - .setType(dropSingletonType(tosym.info.bounds.hi)) - } else { - giveup() - } - case none => super.transform(tree) - } - case tree => super.transform(tree) - } - } - trans.transform(tree) - } - } - - /** A map to implement the `subst` method. */ - class SubstTypeMap(from: List[Symbol], to: List[Type]) - extends SubstMap(from, to) { - protected def toType(fromtp: Type, tp: Type) = tp - - override def mapOver(tree: Tree, giveup: () => Nothing): Tree = { - object trans extends TypeMapTransformer { - override def transform(tree: Tree) = tree match { - case Ident(name) => - from indexOf tree.symbol match { - case -1 => super.transform(tree) - case idx => - val totpe = to(idx) - if (totpe.isStable) tree.duplicate setType totpe - else giveup() - } - case _ => - super.transform(tree) - } - } - trans.transform(tree) - } - } - - /** A map to implement the `substThis` method. */ - class SubstThisMap(from: Symbol, to: Type) extends TypeMap { - def apply(tp: Type): Type = tp match { - case ThisType(sym) if (sym == from) => to - case _ => mapOver(tp) - } - } - - class SubstWildcardMap(from: List[Symbol]) extends TypeMap { - def apply(tp: Type): Type = try { - tp match { - case TypeRef(_, sym, _) if from contains sym => - BoundedWildcardType(sym.info.bounds) - case _ => - mapOver(tp) - } - } catch { - case ex: MalformedType => - WildcardType - } - } - -// dependent method types - object IsDependentCollector extends TypeCollector(false) { - def traverse(tp: Type) { - if(tp isImmediatelyDependent) result = true - else if (!result) mapOver(tp) - } - } - - object ApproximateDependentMap extends TypeMap { - def apply(tp: Type): Type = - if(tp isImmediatelyDependent) WildcardType - else mapOver(tp) - } - - class InstantiateDependentMap(params: List[Symbol], actuals0: List[Type]) extends TypeMap with KeepOnlyTypeConstraints { - private val actuals = actuals0.toIndexedSeq - private val existentials = new Array[Symbol](actuals.size) - def existentialsNeeded: List[Symbol] = existentials.filter(_ ne null).toList - - private object StableArg { - def unapply(param: Symbol) = Arg unapply param map actuals filter (tp => - tp.isStable && (tp.typeSymbol != NothingClass) - ) - } - private object Arg { - def unapply(param: Symbol) = Some(params indexOf param) filter (_ >= 0) - } - - def apply(tp: Type): Type = mapOver(tp) match { - // unsound to replace args by unstable actual #3873 - case SingleType(NoPrefix, StableArg(arg)) => arg - // (soundly) expand type alias selections on implicit arguments, - // see depmet_implicit_oopsla* test cases -- typically, `param.isImplicit` - case tp1 @ TypeRef(SingleType(NoPrefix, Arg(pid)), sym, targs) => - val arg = actuals(pid) - val res = typeRef(arg, sym, targs) - if (res.typeSymbolDirect.isAliasType) res.dealias else tp1 - // don't return the original `tp`, which may be different from `tp1`, - // due to dropping annotations - case tp1 => tp1 - } - - /* Return the type symbol for referencing a parameter inside the existential quantifier. - * (Only needed if the actual is unstable.) - */ - private def existentialFor(pid: Int) = { - if (existentials(pid) eq null) { - val param = params(pid) - existentials(pid) = ( - param.owner.newExistential(newTypeName(param.name + ".type"), param.pos, param.flags) - setInfo singletonBounds(actuals(pid)) - ) - } - existentials(pid) - } - - //AM propagate more info to annotations -- this seems a bit ad-hoc... (based on code by spoon) - override def mapOver(arg: Tree, giveup: ()=>Nothing): Tree = { - // TODO: this should be simplified; in the stable case, one can - // probably just use an Ident to the tree.symbol. - // - // @PP: That leads to failure here, where stuff no longer has type - // 'String @Annot("stuff")' but 'String @Annot(x)'. - // - // def m(x: String): String @Annot(x) = x - // val stuff = m("stuff") - // - // (TODO cont.) Why an existential in the non-stable case? - // - // @PP: In the following: - // - // def m = { val x = "three" ; val y: String @Annot(x) = x; y } - // - // m is typed as 'String @Annot(x) forSome { val x: String }'. - // - // Both examples are from run/constrained-types.scala. - object treeTrans extends Transformer { - override def transform(tree: Tree): Tree = tree.symbol match { - case StableArg(actual) => - gen.mkAttributedQualifier(actual, tree.symbol) - case Arg(pid) => - val sym = existentialFor(pid) - Ident(sym) copyAttrs tree setType typeRef(NoPrefix, sym, Nil) - case _ => - super.transform(tree) - } - } - treeTrans transform arg - } - } - - object StripAnnotationsMap extends TypeMap { - def apply(tp: Type): Type = tp match { - case AnnotatedType(_, atp, _) => - mapOver(atp) - case tp => - mapOver(tp) - } - } - - /** A map to convert every occurrence of a wildcard type to a fresh - * type variable */ - object wildcardToTypeVarMap extends TypeMap { - def apply(tp: Type): Type = tp match { - case WildcardType => - TypeVar(tp, new TypeConstraint) - case BoundedWildcardType(bounds) => - TypeVar(tp, new TypeConstraint(bounds)) - case _ => - mapOver(tp) - } - } - - /** A map to convert every occurrence of a type variable to a wildcard type. */ - object typeVarToOriginMap extends TypeMap { - def apply(tp: Type): Type = tp match { - case TypeVar(origin, _) => origin - case _ => mapOver(tp) - } - } - - /** A map to implement the `contains` method. */ - class ContainsCollector(sym: Symbol) extends TypeCollector(false) { - def traverse(tp: Type) { - if (!result) { - tp.normalize match { - case TypeRef(_, sym1, _) if (sym == sym1) => result = true - case SingleType(_, sym1) if (sym == sym1) => result = true - case _ => mapOver(tp) - } - } - } - - override def mapOver(arg: Tree) = { - for (t <- arg) { - traverse(t.tpe) - if (t.symbol == sym) - result = true - } - arg - } - } - - /** A map to implement the `contains` method. */ - class ContainsTypeCollector(t: Type) extends TypeCollector(false) { - def traverse(tp: Type) { - if (!result) { - if (tp eq t) result = true - else mapOver(tp) - } - } - override def mapOver(arg: Tree) = { - for (t <- arg) - traverse(t.tpe) - - arg - } - } - - /** A map to implement the `filter` method. */ - class FilterTypeCollector(p: Type => Boolean) extends TypeCollector[List[Type]](Nil) { - def withFilter(q: Type => Boolean) = new FilterTypeCollector(tp => p(tp) && q(tp)) - - override def collect(tp: Type) = super.collect(tp).reverse - - def traverse(tp: Type) { - if (p(tp)) result ::= tp - mapOver(tp) - } - } - - /** A map to implement the `collect` method. */ - class CollectTypeCollector[T](pf: PartialFunction[Type, T]) extends TypeCollector[List[T]](Nil) { - override def collect(tp: Type) = super.collect(tp).reverse - - def traverse(tp: Type) { - if (pf.isDefinedAt(tp)) result ::= pf(tp) - mapOver(tp) - } - } - - class ForEachTypeTraverser(f: Type => Unit) extends TypeTraverser { - def traverse(tp: Type) { - f(tp) - mapOver(tp) - } - } - - /** A map to implement the `filter` method. */ - class FindTypeCollector(p: Type => Boolean) extends TypeCollector[Option[Type]](None) { - def traverse(tp: Type) { - if (result.isEmpty) { - if (p(tp)) result = Some(tp) - mapOver(tp) - } - } - } - - /** A map to implement the `contains` method. */ - object ErroneousCollector extends TypeCollector(false) { - def traverse(tp: Type) { - if (!result) { - result = tp.isError - mapOver(tp) - } - } - } - - /** 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 = 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.clear() - tps foreach (commonOwnerMap traverse _) - if (commonOwnerMap.result ne null) commonOwnerMap.result else NoSymbol - } - } - - protected def commonOwnerMap: CommonOwnerMap = commonOwnerMapObj - - protected class CommonOwnerMap extends TypeTraverserWithResult[Symbol] { - var result: Symbol = _ - - def clear() { result = null } - - private def register(sym: Symbol) { - // 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) - } - } - - private lazy val commonOwnerMapObj = new CommonOwnerMap - - class MissingAliasControl extends ControlThrowable - val missingAliasException = new MissingAliasControl - class MissingTypeControl extends ControlThrowable - - object adaptToNewRunMap extends TypeMap { - - private def adaptToNewRun(pre: Type, sym: Symbol): Symbol = { - if (phase.flatClasses || sym.isRootSymbol || (pre eq NoPrefix) || (pre eq NoType) || sym.isPackageClass) - sym - else if (sym.isModuleClass) { - val sourceModule1 = adaptToNewRun(pre, sym.sourceModule) - - sourceModule1.moduleClass orElse sourceModule1.initialize.moduleClass orElse { - val msg = "Cannot adapt module class; sym = %s, sourceModule = %s, sourceModule.moduleClass = %s => sourceModule1 = %s, sourceModule1.moduleClass = %s" - debuglog(msg.format(sym, sym.sourceModule, sym.sourceModule.moduleClass, sourceModule1, sourceModule1.moduleClass)) - sym - } - } - else { - var rebind0 = pre.findMember(sym.name, BRIDGE, 0, true) orElse { - if (sym.isAliasType) throw missingAliasException - debugwarn(pre+"."+sym+" does no longer exist, phase = "+phase) - throw new MissingTypeControl // For build manager and presentation compiler purposes - } - /** The two symbols have the same fully qualified name */ - def corresponds(sym1: Symbol, sym2: Symbol): Boolean = - sym1.name == sym2.name && (sym1.isPackageClass || corresponds(sym1.owner, sym2.owner)) - if (!corresponds(sym.owner, rebind0.owner)) { - debuglog("ADAPT1 pre = "+pre+", sym = "+sym.fullLocationString+", rebind = "+rebind0.fullLocationString) - val bcs = pre.baseClasses.dropWhile(bc => !corresponds(bc, sym.owner)); - if (bcs.isEmpty) - assert(pre.typeSymbol.isRefinementClass, pre) // if pre is a refinementclass it might be a structural type => OK to leave it in. - else - rebind0 = pre.baseType(bcs.head).member(sym.name) - debuglog( - "ADAPT2 pre = " + pre + - ", bcs.head = " + bcs.head + - ", sym = " + sym.fullLocationString + - ", rebind = " + rebind0.fullLocationString - ) - } - rebind0.suchThat(sym => sym.isType || sym.isStable) orElse { - debuglog("" + phase + " " +phase.flatClasses+sym.owner+sym.name+" "+sym.isType) - throw new MalformedType(pre, sym.nameString) - } - } - } - def apply(tp: Type): Type = tp match { - case ThisType(sym) => - try { - val sym1 = adaptToNewRun(sym.owner.thisType, sym) - if (sym1 == sym) tp else ThisType(sym1) - } catch { - case ex: MissingTypeControl => - tp - } - case SingleType(pre, sym) => - if (sym.isPackage) tp - else { - val pre1 = this(pre) - try { - val sym1 = adaptToNewRun(pre1, sym) - if ((pre1 eq pre) && (sym1 eq sym)) tp - else singleType(pre1, sym1) - } catch { - case _: MissingTypeControl => - tp - } - } - case TypeRef(pre, sym, args) => - if (sym.isPackageClass) tp - else { - val pre1 = this(pre) - val args1 = args mapConserve (this) - try { - val sym1 = adaptToNewRun(pre1, sym) - if ((pre1 eq pre) && (sym1 eq sym) && (args1 eq args)/* && sym.isExternal*/) { - tp - } else if (sym1 == NoSymbol) { - debugwarn("adapt fail: "+pre+" "+pre1+" "+sym) - tp - } else { - copyTypeRef(tp, pre1, sym1, args1) - } - } catch { - case ex: MissingAliasControl => - apply(tp.dealias) - case _: MissingTypeControl => - tp - } - } - case MethodType(params, restp) => - val restp1 = this(restp) - if (restp1 eq restp) tp - else copyMethodType(tp, params, restp1) - case NullaryMethodType(restp) => - val restp1 = this(restp) - if (restp1 eq restp) tp - else NullaryMethodType(restp1) - case PolyType(tparams, restp) => - val restp1 = this(restp) - if (restp1 eq restp) tp - else PolyType(tparams, restp1) - - // Lukas: we need to check (together) whether we should also include parameter types - // of PolyType and MethodType in adaptToNewRun - - case ClassInfoType(parents, decls, clazz) => - if (clazz.isPackageClass) tp - else { - val parents1 = parents mapConserve (this) - if (parents1 eq parents) tp - else ClassInfoType(parents1, decls, clazz) - } - case RefinedType(parents, decls) => - val parents1 = parents mapConserve (this) - if (parents1 eq parents) tp - else refinedType(parents1, tp.typeSymbol.owner, decls, tp.typeSymbol.owner.pos) - case SuperType(_, _) => mapOver(tp) - case TypeBounds(_, _) => mapOver(tp) - case TypeVar(_, _) => mapOver(tp) - case AnnotatedType(_,_,_) => mapOver(tp) - case NotNullType(_) => mapOver(tp) - case ExistentialType(_, _) => mapOver(tp) - case _ => tp - } - } - - class SubTypePair(val tp1: Type, val tp2: Type) { - override def hashCode = tp1.hashCode * 41 + tp2.hashCode - override def equals(other: Any) = other match { - case stp: SubTypePair => - // suspend TypeVars in types compared by =:=, - // since we don't want to mutate them simply to check whether a subtype test is pending - // in addition to making subtyping "more correct" for type vars, - // it should avoid the stackoverflow that's been plaguing us (https://groups.google.com/d/topic/scala-internals/2gHzNjtB4xA/discussion) - // this method is only called when subtyping hits a recursion threshold (subsametypeRecursions >= LogPendingSubTypesThreshold) - @inline def suspend(tp: Type) = - if (tp.isGround) null else suspendTypeVarsInType(tp) - @inline def revive(suspension: List[TypeVar]) = - if (suspension ne null) suspension foreach (_.suspended = false) - - val suspensions = Array(tp1, stp.tp1, tp2, stp.tp2) map suspend - - val sameTypes = (tp1 =:= stp.tp1) && (tp2 =:= stp.tp2) - - suspensions foreach revive - - sameTypes - case _ => - false - } - override def toString = tp1+" <:<? "+tp2 - } - -// Helper Methods ------------------------------------------------------------- - - final val LubGlbMargin = 0 - - /** The maximum allowable depth of lubs or glbs over types `ts`. - * This is the maximum depth of all types in the base type sequences - * of each of the types `ts`, plus LubGlbMargin. - */ - def lubDepth(ts: List[Type]) = { - var d = 0 - for (tp <- ts) d = math.max(d, tp.baseTypeSeqDepth) - d + LubGlbMargin - } - - /** Is intersection of given types populated? That is, - * for all types tp1, tp2 in intersection - * for all common base classes bc of tp1 and tp2 - * let bt1, bt2 be the base types of tp1, tp2 relative to class bc - * Then: - * bt1 and bt2 have the same prefix, and - * any corresponding non-variant type arguments of bt1 and bt2 are the same - */ - def isPopulated(tp1: Type, tp2: Type): Boolean = { - def isConsistent(tp1: Type, tp2: Type): Boolean = (tp1, tp2) match { - case (TypeRef(pre1, sym1, args1), TypeRef(pre2, sym2, args2)) => - assert(sym1 == sym2) - pre1 =:= pre2 && - forall3(args1, args2, sym1.typeParams) { (arg1, arg2, tparam) => - //if (tparam.variance == 0 && !(arg1 =:= arg2)) Console.println("inconsistent: "+arg1+"!="+arg2)//DEBUG - if (tparam.variance == 0) arg1 =:= arg2 - else if (arg1.isInstanceOf[TypeVar]) - // if left-hand argument is a typevar, make it compatible with variance - // this is for more precise pattern matching - // todo: work this in the spec of this method - // also: think what happens if there are embedded typevars? - if (tparam.variance < 0) arg1 <:< arg2 else arg2 <:< arg1 - else true - } - case (et: ExistentialType, _) => - et.withTypeVars(isConsistent(_, tp2)) - case (_, et: ExistentialType) => - et.withTypeVars(isConsistent(tp1, _)) - } - - def check(tp1: Type, tp2: Type) = - if (tp1.typeSymbol.isClass && tp1.typeSymbol.hasFlag(FINAL)) - tp1 <:< tp2 || isNumericValueClass(tp1.typeSymbol) && isNumericValueClass(tp2.typeSymbol) - else tp1.baseClasses forall (bc => - tp2.baseTypeIndex(bc) < 0 || isConsistent(tp1.baseType(bc), tp2.baseType(bc))) - - check(tp1, tp2)/* && check(tp2, tp1)*/ // need to investgate why this can't be made symmetric -- neg/gadts1 fails, and run/existials also. - } - - /** Does a pattern of type `patType` need an outer test when executed against - * selector type `selType` in context defined by `currentOwner`? - */ - def needsOuterTest(patType: Type, selType: Type, currentOwner: Symbol) = { - def createDummyClone(pre: Type): Type = { - val dummy = currentOwner.enclClass.newValue(nme.ANYNAME).setInfo(pre.widen) - singleType(ThisType(currentOwner.enclClass), dummy) - } - def maybeCreateDummyClone(pre: Type, sym: Symbol): Type = pre match { - case SingleType(pre1, sym1) => - if (sym1.isModule && sym1.isStatic) { - NoType - } else if (sym1.isModule && sym.owner == sym1.moduleClass) { - val pre2 = maybeCreateDummyClone(pre1, sym1) - if (pre2 eq NoType) pre2 - else singleType(pre2, sym1) - } else { - createDummyClone(pre) - } - case ThisType(clazz) => - if (clazz.isModuleClass) - maybeCreateDummyClone(clazz.typeOfThis, sym) - else if (sym.owner == clazz && (sym.hasFlag(PRIVATE) || sym.privateWithin == clazz)) - NoType - else - createDummyClone(pre) - case _ => - NoType - } - patType match { - case TypeRef(pre, sym, args) => - val pre1 = maybeCreateDummyClone(pre, sym) - (pre1 ne NoType) && isPopulated(copyTypeRef(patType, pre1, sym, args), selType) - case _ => - false - } - } - - private var subsametypeRecursions: Int = 0 - - private def isUnifiable(pre1: Type, pre2: Type) = - (beginsWithTypeVarOrIsRefined(pre1) || beginsWithTypeVarOrIsRefined(pre2)) && (pre1 =:= pre2) - - /** Returns true iff we are past phase specialize, - * sym1 and sym2 are two existential skolems with equal names and bounds, - * and pre1 and pre2 are equal prefixes - */ - private def isSameSpecializedSkolem(sym1: Symbol, sym2: Symbol, pre1: Type, pre2: Type) = { - sym1.isExistentialSkolem && sym2.isExistentialSkolem && - sym1.name == sym2.name && - phase.specialized && - sym1.info =:= sym2.info && - pre1 =:= pre2 - } - - private def isSubPre(pre1: Type, pre2: Type, sym: Symbol) = - if ((pre1 ne pre2) && (pre1 ne NoPrefix) && (pre2 ne NoPrefix) && pre1 <:< pre2) { - if (settings.debug.value) println(s"new isSubPre $sym: $pre1 <:< $pre2") - true - } else - false - - private def equalSymsAndPrefixes(sym1: Symbol, pre1: Type, sym2: Symbol, pre2: Type): Boolean = - if (sym1 == sym2) sym1.hasPackageFlag || phase.erasedTypes || pre1 =:= pre2 - else (sym1.name == sym2.name) && isUnifiable(pre1, pre2) - - /** Do `tp1` and `tp2` denote equivalent types? */ - def isSameType(tp1: Type, tp2: Type): Boolean = try { - incCounter(sametypeCount) - subsametypeRecursions += 1 - undoLog undoUnless { - isSameType1(tp1, tp2) - } - } finally { - subsametypeRecursions -= 1 - // XXX AM TODO: figure out when it is safe and needed to clear the log -- the commented approach below is too eager (it breaks #3281, #3866) - // it doesn't help to keep separate recursion counts for the three methods that now share it - // if (subsametypeRecursions == 0) undoLog.clear() - } - - def isDifferentType(tp1: Type, tp2: Type): Boolean = try { - subsametypeRecursions += 1 - undoLog undo { // undo type constraints that arise from operations in this block - !isSameType1(tp1, tp2) - } - } finally { - subsametypeRecursions -= 1 - // XXX AM TODO: figure out when it is safe and needed to clear the log -- the commented approach below is too eager (it breaks #3281, #3866) - // it doesn't help to keep separate recursion counts for the three methods that now share it - // if (subsametypeRecursions == 0) undoLog.clear() - } - - def isDifferentTypeConstructor(tp1: Type, tp2: Type): Boolean = tp1 match { - case TypeRef(pre1, sym1, _) => - tp2 match { - case TypeRef(pre2, sym2, _) => sym1 != sym2 || isDifferentType(pre1, pre2) - case _ => true - } - case _ => true - } - - def normalizePlus(tp: Type) = - if (isRawType(tp)) rawToExistential(tp) - else tp.normalize - - /* - todo: change to: - def normalizePlus(tp: Type) = tp match { - case TypeRef(pre, sym, List()) => - if (!sym.isInitialized) sym.rawInfo.load(sym) - if (sym.isJavaDefined && !sym.typeParams.isEmpty) rawToExistential(tp) - else tp.normalize - case _ => tp.normalize - } - */ -/* - private def isSameType0(tp1: Type, tp2: Type): Boolean = { - if (tp1 eq tp2) return true - ((tp1, tp2) match { - case (ErrorType, _) => true - case (WildcardType, _) => true - case (_, ErrorType) => true - case (_, WildcardType) => true - - case (NoType, _) => false - case (NoPrefix, _) => tp2.typeSymbol.isPackageClass - case (_, NoType) => false - case (_, NoPrefix) => tp1.typeSymbol.isPackageClass - - case (ThisType(sym1), ThisType(sym2)) - if (sym1 == sym2) => - true - case (SingleType(pre1, sym1), SingleType(pre2, sym2)) - if (equalSymsAndPrefixes(sym1, pre1, sym2, pre2)) => - true -/* - case (SingleType(pre1, sym1), ThisType(sym2)) - if (sym1.isModule && - sym1.moduleClass == sym2 && - pre1 =:= sym2.owner.thisType) => - true - case (ThisType(sym1), SingleType(pre2, sym2)) - if (sym2.isModule && - sym2.moduleClass == sym1 && - pre2 =:= sym1.owner.thisType) => - true -*/ - case (ConstantType(value1), ConstantType(value2)) => - value1 == value2 - case (TypeRef(pre1, sym1, args1), TypeRef(pre2, sym2, args2)) => - equalSymsAndPrefixes(sym1, pre1, sym2, pre2) && - ((tp1.isHigherKinded && tp2.isHigherKinded && tp1.normalize =:= tp2.normalize) || - isSameTypes(args1, args2)) - // @M! normalize reduces higher-kinded case to PolyType's - case (RefinedType(parents1, ref1), RefinedType(parents2, ref2)) => - def isSubScope(s1: Scope, s2: Scope): Boolean = s2.toList.forall { - sym2 => - var e1 = s1.lookupEntry(sym2.name) - (e1 ne null) && { - val substSym = sym2.info.substThis(sym2.owner, e1.sym.owner.thisType) - var isEqual = false - while (!isEqual && (e1 ne null)) { - isEqual = e1.sym.info =:= substSym - e1 = s1.lookupNextEntry(e1) - } - isEqual - } - } - //Console.println("is same? " + tp1 + " " + tp2 + " " + tp1.typeSymbol.owner + " " + tp2.typeSymbol.owner)//DEBUG - isSameTypes(parents1, parents2) && isSubScope(ref1, ref2) && isSubScope(ref2, ref1) - case (MethodType(params1, res1), MethodType(params2, res2)) => - // new dependent types: probably fix this, use substSym as done for PolyType - (isSameTypes(tp1.paramTypes, tp2.paramTypes) && - res1 =:= res2 && - tp1.isImplicit == tp2.isImplicit) - case (PolyType(tparams1, res1), PolyType(tparams2, res2)) => - // assert((tparams1 map (_.typeParams.length)) == (tparams2 map (_.typeParams.length))) - (tparams1.length == tparams2.length) && (tparams1 corresponds tparams2)(_.info =:= _.info.substSym(tparams2, tparams1)) && // @M looks like it might suffer from same problem as #2210 - res1 =:= res2.substSym(tparams2, tparams1) - case (ExistentialType(tparams1, res1), ExistentialType(tparams2, res2)) => - (tparams1.length == tparams2.length) && (tparams1 corresponds tparams2)(_.info =:= _.info.substSym(tparams2, tparams1)) && // @M looks like it might suffer from same problem as #2210 - res1 =:= res2.substSym(tparams2, tparams1) - case (TypeBounds(lo1, hi1), TypeBounds(lo2, hi2)) => - lo1 =:= lo2 && hi1 =:= hi2 - case (BoundedWildcardType(bounds), _) => - bounds containsType tp2 - case (_, BoundedWildcardType(bounds)) => - bounds containsType tp1 - case (tv @ TypeVar(_,_), tp) => - tv.registerTypeEquality(tp, true) - case (tp, tv @ TypeVar(_,_)) => - tv.registerTypeEquality(tp, false) - case (AnnotatedType(_,_,_), _) => - annotationsConform(tp1, tp2) && annotationsConform(tp2, tp1) && tp1.withoutAnnotations =:= tp2.withoutAnnotations - case (_, AnnotatedType(_,_,_)) => - annotationsConform(tp1, tp2) && annotationsConform(tp2, tp1) && tp1.withoutAnnotations =:= tp2.withoutAnnotations - case (_: SingletonType, _: SingletonType) => - var origin1 = tp1 - while (origin1.underlying.isInstanceOf[SingletonType]) { - assert(origin1 ne origin1.underlying, origin1) - origin1 = origin1.underlying - } - var origin2 = tp2 - while (origin2.underlying.isInstanceOf[SingletonType]) { - assert(origin2 ne origin2.underlying, origin2) - origin2 = origin2.underlying - } - ((origin1 ne tp1) || (origin2 ne tp2)) && (origin1 =:= origin2) - case _ => - false - }) || { - val tp1n = normalizePlus(tp1) - val tp2n = normalizePlus(tp2) - ((tp1n ne tp1) || (tp2n ne tp2)) && isSameType(tp1n, tp2n) - } - } -*/ - private def isSameType1(tp1: Type, tp2: Type): Boolean = { - if ((tp1 eq tp2) || - (tp1 eq ErrorType) || (tp1 eq WildcardType) || - (tp2 eq ErrorType) || (tp2 eq WildcardType)) - true - else if ((tp1 eq NoType) || (tp2 eq NoType)) - false - else if (tp1 eq NoPrefix) // !! I do not see how this would be warranted by the spec - tp2.typeSymbol.isPackageClass - else if (tp2 eq NoPrefix) // !! I do not see how this would be warranted by the spec - tp1.typeSymbol.isPackageClass - else { - isSameType2(tp1, tp2) || { - val tp1n = normalizePlus(tp1) - val tp2n = normalizePlus(tp2) - ((tp1n ne tp1) || (tp2n ne tp2)) && isSameType(tp1n, tp2n) - } - } - } - - def isSameType2(tp1: Type, tp2: Type): Boolean = { - tp1 match { - case tr1: TypeRef => - tp2 match { - case tr2: TypeRef => - return (equalSymsAndPrefixes(tr1.sym, tr1.pre, tr2.sym, tr2.pre) && - ((tp1.isHigherKinded && tp2.isHigherKinded && tp1.normalize =:= tp2.normalize) || - isSameTypes(tr1.args, tr2.args))) || - ((tr1.pre, tr2.pre) match { - case (tv @ TypeVar(_,_), _) => tv.registerTypeSelection(tr1.sym, tr2) - case (_, tv @ TypeVar(_,_)) => tv.registerTypeSelection(tr2.sym, tr1) - case _ => false - }) - case _: SingleType => - return isSameType2(tp2, tp1) // put singleton type on the left, caught below - case _ => - } - case tt1: ThisType => - tp2 match { - case tt2: ThisType => - if (tt1.sym == tt2.sym) return true - case _ => - } - case st1: SingleType => - tp2 match { - case st2: SingleType => - if (equalSymsAndPrefixes(st1.sym, st1.pre, st2.sym, st2.pre)) return true - case TypeRef(pre2, sym2, Nil) => - if (sym2.isModuleClass && equalSymsAndPrefixes(st1.sym, st1.pre, sym2.sourceModule, pre2)) return true - case _ => - } - case ct1: ConstantType => - tp2 match { - case ct2: ConstantType => - return (ct1.value == ct2.value) - case _ => - } - case rt1: RefinedType => - tp2 match { - case rt2: RefinedType => // - def isSubScope(s1: Scope, s2: Scope): Boolean = s2.toList.forall { - sym2 => - var e1 = s1.lookupEntry(sym2.name) - (e1 ne null) && { - val substSym = sym2.info.substThis(sym2.owner, e1.sym.owner) - var isEqual = false - while (!isEqual && (e1 ne null)) { - isEqual = e1.sym.info =:= substSym - e1 = s1.lookupNextEntry(e1) - } - isEqual - } - } - //Console.println("is same? " + tp1 + " " + tp2 + " " + tp1.typeSymbol.owner + " " + tp2.typeSymbol.owner)//DEBUG - return isSameTypes(rt1.parents, rt2.parents) && { - val decls1 = rt1.decls - val decls2 = rt2.decls - isSubScope(decls1, decls2) && isSubScope(decls2, decls1) - } - case _ => - } - case mt1: MethodType => - tp2 match { - case mt2: MethodType => - return isSameTypes(mt1.paramTypes, mt2.paramTypes) && - mt1.resultType =:= mt2.resultType.substSym(mt2.params, mt1.params) && - mt1.isImplicit == mt2.isImplicit - // note: no case NullaryMethodType(restpe) => return mt1.params.isEmpty && mt1.resultType =:= restpe - case _ => - } - case NullaryMethodType(restpe1) => - tp2 match { - // note: no case mt2: MethodType => return mt2.params.isEmpty && restpe =:= mt2.resultType - case NullaryMethodType(restpe2) => - return restpe1 =:= restpe2 - case _ => - } - case PolyType(tparams1, res1) => - tp2 match { - case PolyType(tparams2, res2) => -// assert((tparams1 map (_.typeParams.length)) == (tparams2 map (_.typeParams.length))) - // @M looks like it might suffer from same problem as #2210 - return ( - (sameLength(tparams1, tparams2)) && // corresponds does not check length of two sequences before checking the predicate - (tparams1 corresponds tparams2)(_.info =:= _.info.substSym(tparams2, tparams1)) && - res1 =:= res2.substSym(tparams2, tparams1) - ) - case _ => - } - case ExistentialType(tparams1, res1) => - tp2 match { - case ExistentialType(tparams2, res2) => - // @M looks like it might suffer from same problem as #2210 - return ( - // corresponds does not check length of two sequences before checking the predicate -- faster & needed to avoid crasher in #2956 - sameLength(tparams1, tparams2) && - (tparams1 corresponds tparams2)(_.info =:= _.info.substSym(tparams2, tparams1)) && - res1 =:= res2.substSym(tparams2, tparams1) - ) - case _ => - } - case TypeBounds(lo1, hi1) => - tp2 match { - case TypeBounds(lo2, hi2) => - return lo1 =:= lo2 && hi1 =:= hi2 - case _ => - } - case BoundedWildcardType(bounds) => - return bounds containsType tp2 - case _ => - } - tp2 match { - case BoundedWildcardType(bounds) => - return bounds containsType tp1 - case _ => - } - tp1 match { - case tv @ TypeVar(_,_) => - return tv.registerTypeEquality(tp2, true) - case _ => - } - tp2 match { - case tv @ TypeVar(_,_) => - return tv.registerTypeEquality(tp1, false) - case _ => - } - tp1 match { - case _: AnnotatedType => - return annotationsConform(tp1, tp2) && annotationsConform(tp2, tp1) && tp1.withoutAnnotations =:= tp2.withoutAnnotations - case _ => - } - tp2 match { - case _: AnnotatedType => - return annotationsConform(tp1, tp2) && annotationsConform(tp2, tp1) && tp1.withoutAnnotations =:= tp2.withoutAnnotations - case _ => - } - tp1 match { - case _: SingletonType => - tp2 match { - case _: SingletonType => - @inline def chaseDealiasedUnderlying(tp: Type): Type = { - var origin = tp - var next = origin.underlying.dealias - while (next.isInstanceOf[SingletonType]) { - assert(origin ne next, origin) - origin = next - next = origin.underlying.dealias - } - origin - } - val origin1 = chaseDealiasedUnderlying(tp1) - val origin2 = chaseDealiasedUnderlying(tp2) - ((origin1 ne tp1) || (origin2 ne tp2)) && (origin1 =:= origin2) - case _ => - false - } - case _ => - false - } - } - - /** Are `tps1` and `tps2` lists of pairwise equivalent types? */ - def isSameTypes(tps1: List[Type], tps2: List[Type]): Boolean = (tps1 corresponds tps2)(_ =:= _) - - /** True if two lists have the same length. Since calling length on linear sequences - * is O(n), it is an inadvisable way to test length equality. - */ - final def sameLength(xs1: List[_], xs2: List[_]) = compareLengths(xs1, xs2) == 0 - @tailrec final def compareLengths(xs1: List[_], xs2: List[_]): Int = - if (xs1.isEmpty) { if (xs2.isEmpty) 0 else -1 } - else if (xs2.isEmpty) 1 - else compareLengths(xs1.tail, xs2.tail) - - /** Again avoiding calling length, but the lengthCompare interface is clunky. - */ - final def hasLength(xs: List[_], len: Int) = xs.lengthCompare(len) == 0 - - private val pendingSubTypes = new mutable.HashSet[SubTypePair] - private var basetypeRecursions: Int = 0 - private val pendingBaseTypes = new mutable.HashSet[Type] - - def isSubType(tp1: Type, tp2: Type): Boolean = isSubType(tp1, tp2, AnyDepth) - - def isSubType(tp1: Type, tp2: Type, depth: Int): Boolean = try { - subsametypeRecursions += 1 - - undoLog undoUnless { // if subtype test fails, it should not affect constraints on typevars - if (subsametypeRecursions >= LogPendingSubTypesThreshold) { - val p = new SubTypePair(tp1, tp2) - if (pendingSubTypes(p)) - false - else - try { - pendingSubTypes += p - isSubType2(tp1, tp2, depth) - } finally { - pendingSubTypes -= p - } - } else { - isSubType2(tp1, tp2, depth) - } - } - } finally { - subsametypeRecursions -= 1 - // XXX AM TODO: figure out when it is safe and needed to clear the log -- the commented approach below is too eager (it breaks #3281, #3866) - // it doesn't help to keep separate recursion counts for the three methods that now share it - // if (subsametypeRecursions == 0) undoLog.clear() - } - - /** Does this type have a prefix that begins with a type variable, - * or is it a refinement type? For type prefixes that fulfil this condition, - * type selections with the same name of equal (wrt) =:= prefixes are - * considered equal wrt =:= - */ - def beginsWithTypeVarOrIsRefined(tp: Type): Boolean = tp match { - case SingleType(pre, sym) => - !(sym hasFlag PACKAGE) && beginsWithTypeVarOrIsRefined(pre) - case tv@TypeVar(_, constr) => - !tv.instValid || beginsWithTypeVarOrIsRefined(constr.inst) - case RefinedType(_, _) => - true - case _ => - false - } - - def instTypeVar(tp: Type): Type = tp match { - case TypeRef(pre, sym, args) => - copyTypeRef(tp, instTypeVar(pre), sym, args) - case SingleType(pre, sym) => - singleType(instTypeVar(pre), sym) - case TypeVar(_, constr) => - instTypeVar(constr.inst) - case _ => - tp - } - - def isErrorOrWildcard(tp: Type) = (tp eq ErrorType) || (tp eq WildcardType) - - def isSingleType(tp: Type) = tp match { - case ThisType(_) | SuperType(_, _) | SingleType(_, _) => true - case _ => false - } - - def isConstantType(tp: Type) = tp match { - case ConstantType(_) => true - case _ => false - } - - // @assume tp1.isHigherKinded || tp2.isHigherKinded - def isHKSubType0(tp1: Type, tp2: Type, depth: Int): Boolean = ( - tp1.typeSymbol == NothingClass - || - tp2.typeSymbol == AnyClass // @M Any and Nothing are super-type resp. subtype of every well-kinded type - || // @M! normalize reduces higher-kinded case to PolyType's - ((tp1.normalize.withoutAnnotations , tp2.normalize.withoutAnnotations) match { - case (PolyType(tparams1, res1), PolyType(tparams2, res2)) => // @assume tp1.isHigherKinded && tp2.isHigherKinded (as they were both normalized to PolyType) - sameLength(tparams1, tparams2) && { - if (tparams1.head.owner.isMethod) { // fast-path: polymorphic method type -- type params cannot be captured - (tparams1 corresponds tparams2)((p1, p2) => p2.info.substSym(tparams2, tparams1) <:< p1.info) && - res1 <:< res2.substSym(tparams2, tparams1) - } else { // normalized higher-kinded type - //@M for an example of why we need to generate fresh symbols, see neg/tcpoly_ticket2101.scala - val tpsFresh = cloneSymbols(tparams1) - - (tparams1 corresponds tparams2)((p1, p2) => - p2.info.substSym(tparams2, tpsFresh) <:< p1.info.substSym(tparams1, tpsFresh)) && - res1.substSym(tparams1, tpsFresh) <:< res2.substSym(tparams2, tpsFresh) - - //@M the forall in the previous test could be optimised to the following, - // but not worth the extra complexity since it only shaves 1s from quick.comp - // (List.forall2(tpsFresh/*optimisation*/, tparams2)((p1, p2) => - // p2.info.substSym(tparams2, tpsFresh) <:< p1.info /*optimisation, == (p1 from tparams1).info.substSym(tparams1, tpsFresh)*/) && - // this optimisation holds because inlining cloneSymbols in `val tpsFresh = cloneSymbols(tparams1)` gives: - // val tpsFresh = tparams1 map (_.cloneSymbol) - // for (tpFresh <- tpsFresh) tpFresh.setInfo(tpFresh.info.substSym(tparams1, tpsFresh)) - } - } && annotationsConform(tp1.normalize, tp2.normalize) - case (_, _) => false // @assume !tp1.isHigherKinded || !tp2.isHigherKinded - // --> thus, cannot be subtypes (Any/Nothing has already been checked) - })) - - def isSubArg(t1: Type, t2: Type, variance: Int) = - (variance > 0 || t2 <:< t1) && (variance < 0 || t1 <:< t2) - - def isSubArgs(tps1: List[Type], tps2: List[Type], tparams: List[Symbol]): Boolean = - corresponds3(tps1, tps2, tparams map (_.variance))(isSubArg) - - def differentOrNone(tp1: Type, tp2: Type) = if (tp1 eq tp2) NoType else tp1 - - /** Does type `tp1` conform to `tp2`? */ - private def isSubType2(tp1: Type, tp2: Type, depth: Int): Boolean = { - if ((tp1 eq tp2) || isErrorOrWildcard(tp1) || isErrorOrWildcard(tp2)) return true - if ((tp1 eq NoType) || (tp2 eq NoType)) return false - if (tp1 eq NoPrefix) return (tp2 eq NoPrefix) || tp2.typeSymbol.isPackageClass // !! I do not see how the "isPackageClass" would be warranted by the spec - if (tp2 eq NoPrefix) return tp1.typeSymbol.isPackageClass - if (isSingleType(tp1) && isSingleType(tp2) || isConstantType(tp1) && isConstantType(tp2)) return tp1 =:= tp2 - if (tp1.isHigherKinded || tp2.isHigherKinded) return isHKSubType0(tp1, tp2, depth) - - /** First try, on the right: - * - unwrap Annotated types, BoundedWildcardTypes, - * - bind TypeVars on the right, if lhs is not Annotated nor BoundedWildcard - * - handle common cases for first-kind TypeRefs on both sides as a fast path. - */ - def firstTry = tp2 match { - // fast path: two typerefs, none of them HK - case tr2: TypeRef => - tp1 match { - case tr1: TypeRef => - val sym1 = tr1.sym - val sym2 = tr2.sym - val pre1 = tr1.pre - val pre2 = tr2.pre - (((if (sym1 == sym2) phase.erasedTypes || pre1 <:< pre2 - else (sym1.name == sym2.name && !sym1.isModuleClass && !sym2.isModuleClass && - (isUnifiable(pre1, pre2) || - isSameSpecializedSkolem(sym1, sym2, pre1, pre2) || - sym2.isAbstractType && isSubPre(pre1, pre2, sym2)))) && - isSubArgs(tr1.args, tr2.args, sym1.typeParams)) - || - sym2.isClass && { - val base = tr1 baseType sym2 - (base ne tr1) && base <:< tr2 - } - || - thirdTryRef(tr1, tr2)) - case _ => - secondTry - } - case AnnotatedType(_, _, _) => - tp1.withoutAnnotations <:< tp2.withoutAnnotations && annotationsConform(tp1, tp2) - case BoundedWildcardType(bounds) => - tp1 <:< bounds.hi - case tv2 @ TypeVar(_, constr2) => - tp1 match { - case AnnotatedType(_, _, _) | BoundedWildcardType(_) => - secondTry - case _ => - tv2.registerBound(tp1, true) - } - case _ => - secondTry - } - - /** Second try, on the left: - * - unwrap AnnotatedTypes, BoundedWildcardTypes, - * - bind typevars, - * - handle existential types by skolemization. - */ - def secondTry = tp1 match { - case AnnotatedType(_, _, _) => - tp1.withoutAnnotations <:< tp2.withoutAnnotations && annotationsConform(tp1, tp2) - case BoundedWildcardType(bounds) => - tp1.bounds.lo <:< tp2 - case tv @ TypeVar(_,_) => - tv.registerBound(tp2, false) - case ExistentialType(_, _) => - try { - skolemizationLevel += 1 - tp1.skolemizeExistential <:< tp2 - } finally { - skolemizationLevel -= 1 - } - case _ => - thirdTry - } - - def thirdTryRef(tp1: Type, tp2: TypeRef): Boolean = { - val sym2 = tp2.sym - sym2 match { - case NotNullClass => tp1.isNotNull - case SingletonClass => tp1.isStable || fourthTry - case _: ClassSymbol => - if (isRaw(sym2, tp2.args)) - isSubType(tp1, rawToExistential(tp2), depth) - else if (sym2.name == tpnme.REFINE_CLASS_NAME) - isSubType(tp1, sym2.info, depth) - else - fourthTry - case _: TypeSymbol => - if (sym2 hasFlag DEFERRED) { - val tp2a = tp2.bounds.lo - isDifferentTypeConstructor(tp2, tp2a) && tp1 <:< tp2a || fourthTry - } else { - isSubType(tp1.normalize, tp2.normalize, depth) - } - case _ => - fourthTry - } - } - - /** Third try, on the right: - * - decompose refined types. - * - handle typerefs, existentials, and notnull types. - * - handle left+right method types, polytypes, typebounds - */ - def thirdTry = tp2 match { - case tr2: TypeRef => - thirdTryRef(tp1, tr2) - case rt2: RefinedType => - (rt2.parents forall (tp1 <:< _)) && - (rt2.decls forall tp1.specializes) - case et2: ExistentialType => - et2.withTypeVars(tp1 <:< _, depth) || fourthTry - case nn2: NotNullType => - tp1.isNotNull && tp1 <:< nn2.underlying - case mt2: MethodType => - tp1 match { - case mt1 @ MethodType(params1, res1) => - val params2 = mt2.params - val res2 = mt2.resultType - (sameLength(params1, params2) && - mt1.isImplicit == mt2.isImplicit && - matchingParams(params1, params2, mt1.isJava, mt2.isJava) && - (res1 <:< res2.substSym(params2, params1))) - // TODO: if mt1.params.isEmpty, consider NullaryMethodType? - case _ => - false - } - case pt2 @ NullaryMethodType(_) => - tp1 match { - // TODO: consider MethodType mt for which mt.params.isEmpty?? - case pt1 @ NullaryMethodType(_) => - pt1.resultType <:< pt2.resultType - case _ => - false - } - case TypeBounds(lo2, hi2) => - tp1 match { - case TypeBounds(lo1, hi1) => - lo2 <:< lo1 && hi1 <:< hi2 - case _ => - false - } - case _ => - fourthTry - } - - /** Fourth try, on the left: - * - handle typerefs, refined types, notnull and singleton types. - */ - def fourthTry = tp1 match { - case tr1 @ TypeRef(pre1, sym1, _) => - sym1 match { - case NothingClass => true - case NullClass => - tp2 match { - case TypeRef(_, sym2, _) => - containsNull(sym2) - case _ => - isSingleType(tp2) && tp1 <:< tp2.widen - } - case _: ClassSymbol => - if (isRaw(sym1, tr1.args)) - isSubType(rawToExistential(tp1), tp2, depth) - else if (sym1.isModuleClass) tp2 match { - case SingleType(pre2, sym2) => equalSymsAndPrefixes(sym1.sourceModule, pre1, sym2, pre2) - case _ => false - } - else if (sym1.isRefinementClass) - isSubType(sym1.info, tp2, depth) - else false - - case _: TypeSymbol => - if (sym1 hasFlag DEFERRED) { - val tp1a = tp1.bounds.hi - isDifferentTypeConstructor(tp1, tp1a) && tp1a <:< tp2 - } else { - isSubType(tp1.normalize, tp2.normalize, depth) - } - case _ => - false - } - case RefinedType(parents1, _) => - parents1 exists (_ <:< tp2) - case _: SingletonType | _: NotNullType => - tp1.underlying <:< tp2 - case _ => - false - } - - firstTry - } - - private def containsNull(sym: Symbol): Boolean = - sym.isClass && sym != NothingClass && - !(sym isNonBottomSubClass AnyValClass) && - !(sym isNonBottomSubClass NotNullClass) - - /** Are `tps1` and `tps2` lists of equal length such that all elements - * of `tps1` conform to corresponding elements of `tps2`? - */ - def isSubTypes(tps1: List[Type], tps2: List[Type]): Boolean = (tps1 corresponds tps2)(_ <:< _) - - /** Does type `tp` implement symbol `sym` with same or - * stronger type? Exact only if `sym` is a member of some - * refinement type, otherwise we might return false negatives. - */ - def specializesSym(tp: Type, sym: Symbol): Boolean = - tp.typeSymbol == NothingClass || - tp.typeSymbol == NullClass && containsNull(sym.owner) || - (tp.nonPrivateMember(sym.name).alternatives exists - (alt => sym == alt || specializesSym(tp.narrow, alt, sym.owner.thisType, sym))) - - /** Does member `sym1` of `tp1` have a stronger type - * than member `sym2` of `tp2`? - */ - private def specializesSym(tp1: Type, sym1: Symbol, tp2: Type, sym2: Symbol): Boolean = { - val info1 = tp1.memberInfo(sym1) - val info2 = tp2.memberInfo(sym2).substThis(tp2.typeSymbol, tp1) - //System.out.println("specializes "+tp1+"."+sym1+":"+info1+sym1.locationString+" AND "+tp2+"."+sym2+":"+info2)//DEBUG - ( sym2.isTerm && (info1 <:< info2) && (!sym2.isStable || sym1.isStable) - || sym2.isAbstractType && { - val memberTp1 = tp1.memberType(sym1) - // println("kinds conform? "+(memberTp1, tp1, sym2, kindsConform(List(sym2), List(memberTp1), tp2, sym2.owner))) - info2.bounds.containsType(memberTp1) && - kindsConform(List(sym2), List(memberTp1), tp1, sym1.owner) - } - || sym2.isAliasType && tp2.memberType(sym2).substThis(tp2.typeSymbol, tp1) =:= tp1.memberType(sym1) //@MAT ok - ) - } - - /** A function implementing `tp1` matches `tp2`. */ - final def matchesType(tp1: Type, tp2: Type, alwaysMatchSimple: Boolean): Boolean = { - def matchesQuantified(tparams1: List[Symbol], tparams2: List[Symbol], res1: Type, res2: Type): Boolean = ( - sameLength(tparams1, tparams2) && - matchesType(res1, res2.substSym(tparams2, tparams1), alwaysMatchSimple) - ) - def lastTry = - tp2 match { - case ExistentialType(_, res2) if alwaysMatchSimple => - matchesType(tp1, res2, true) - case MethodType(_, _) => - false - case PolyType(_, _) => - false - case _ => - alwaysMatchSimple || tp1 =:= tp2 - } - tp1 match { - case mt1 @ MethodType(params1, res1) => - tp2 match { - case mt2 @ MethodType(params2, res2) => - // sameLength(params1, params2) was used directly as pre-screening optimization (now done by matchesQuantified -- is that ok, performancewise?) - mt1.isImplicit == mt2.isImplicit && - matchingParams(params1, params2, mt1.isJava, mt2.isJava) && - matchesQuantified(params1, params2, res1, res2) - case NullaryMethodType(res2) => - if (params1.isEmpty) matchesType(res1, res2, alwaysMatchSimple) - else matchesType(tp1, res2, alwaysMatchSimple) - case ExistentialType(_, res2) => - alwaysMatchSimple && matchesType(tp1, res2, true) - case TypeRef(_, sym, Nil) => - params1.isEmpty && sym.isModuleClass && matchesType(res1, tp2, alwaysMatchSimple) - case _ => - false - } - case mt1 @ NullaryMethodType(res1) => - tp2 match { - case mt2 @ MethodType(Nil, res2) => // could never match if params nonEmpty, and !mt2.isImplicit is implied by empty param list - matchesType(res1, res2, alwaysMatchSimple) - case NullaryMethodType(res2) => - matchesType(res1, res2, alwaysMatchSimple) - case ExistentialType(_, res2) => - alwaysMatchSimple && matchesType(tp1, res2, true) - case TypeRef(_, sym, Nil) if sym.isModuleClass => - matchesType(res1, tp2, alwaysMatchSimple) - case _ => - matchesType(res1, tp2, alwaysMatchSimple) - } - case PolyType(tparams1, res1) => - tp2 match { - case PolyType(tparams2, res2) => - if ((tparams1 corresponds tparams2)(_ eq _)) - matchesType(res1, res2, alwaysMatchSimple) - else - matchesQuantified(tparams1, tparams2, res1, res2) - case ExistentialType(_, res2) => - alwaysMatchSimple && matchesType(tp1, res2, true) - case _ => - false // remember that tparams1.nonEmpty is now an invariant of PolyType - } - case ExistentialType(tparams1, res1) => - tp2 match { - case ExistentialType(tparams2, res2) => - matchesQuantified(tparams1, tparams2, res1, res2) - case _ => - if (alwaysMatchSimple) matchesType(res1, tp2, true) - else lastTry - } - case TypeRef(_, sym, Nil) if sym.isModuleClass => - tp2 match { - case MethodType(Nil, res2) => matchesType(tp1, res2, alwaysMatchSimple) - case NullaryMethodType(res2) => matchesType(tp1, res2, alwaysMatchSimple) - case _ => lastTry - } - case _ => - lastTry - } - } - -/** matchesType above is an optimized version of the following implementation: - - def matchesType2(tp1: Type, tp2: Type, alwaysMatchSimple: Boolean): Boolean = { - def matchesQuantified(tparams1: List[Symbol], tparams2: List[Symbol], res1: Type, res2: Type): Boolean = - tparams1.length == tparams2.length && - matchesType(res1, res2.substSym(tparams2, tparams1), alwaysMatchSimple) - (tp1, tp2) match { - case (MethodType(params1, res1), MethodType(params2, res2)) => - params1.length == params2.length && // useful pre-secreening optimization - matchingParams(params1, params2, tp1.isInstanceOf[JavaMethodType], tp2.isInstanceOf[JavaMethodType]) && - matchesType(res1, res2, alwaysMatchSimple) && - tp1.isImplicit == tp2.isImplicit - case (PolyType(tparams1, res1), PolyType(tparams2, res2)) => - matchesQuantified(tparams1, tparams2, res1, res2) - case (NullaryMethodType(rtp1), MethodType(List(), rtp2)) => - matchesType(rtp1, rtp2, alwaysMatchSimple) - case (MethodType(List(), rtp1), NullaryMethodType(rtp2)) => - matchesType(rtp1, rtp2, alwaysMatchSimple) - case (ExistentialType(tparams1, res1), ExistentialType(tparams2, res2)) => - matchesQuantified(tparams1, tparams2, res1, res2) - case (ExistentialType(_, res1), _) if alwaysMatchSimple => - matchesType(res1, tp2, alwaysMatchSimple) - case (_, ExistentialType(_, res2)) if alwaysMatchSimple => - matchesType(tp1, res2, alwaysMatchSimple) - case (NullaryMethodType(rtp1), _) => - matchesType(rtp1, tp2, alwaysMatchSimple) - case (_, NullaryMethodType(rtp2)) => - matchesType(tp1, rtp2, alwaysMatchSimple) - case (MethodType(_, _), _) => false - case (PolyType(_, _), _) => false - case (_, MethodType(_, _)) => false - case (_, PolyType(_, _)) => false - case _ => - alwaysMatchSimple || tp1 =:= tp2 - } - } -*/ - - /** Are `syms1` and `syms2` parameter lists with pairwise equivalent types? */ - private def matchingParams(syms1: List[Symbol], syms2: List[Symbol], syms1isJava: Boolean, syms2isJava: Boolean): Boolean = syms1 match { - case Nil => - syms2.isEmpty - case sym1 :: rest1 => - syms2 match { - case Nil => - false - case sym2 :: rest2 => - val tp1 = sym1.tpe - val tp2 = sym2.tpe - (tp1 =:= tp2 || - syms1isJava && tp2.typeSymbol == ObjectClass && tp1.typeSymbol == AnyClass || - syms2isJava && tp1.typeSymbol == ObjectClass && tp2.typeSymbol == AnyClass) && - matchingParams(rest1, rest2, syms1isJava, syms2isJava) - } - } - - /** like map2, but returns list `xs` itself - instead of a copy - if function - * `f` maps all elements to themselves. - */ - def map2Conserve[A <: AnyRef, B](xs: List[A], ys: List[B])(f: (A, B) => A): List[A] = - if (xs.isEmpty) xs - else { - val x1 = f(xs.head, ys.head) - val xs1 = map2Conserve(xs.tail, ys.tail)(f) - if ((x1 eq xs.head) && (xs1 eq xs.tail)) xs - else x1 :: xs1 - } - - /** Solve constraint collected in types `tvars`. - * - * @param tvars All type variables to be instantiated. - * @param tparams The type parameters corresponding to `tvars` - * @param variances The variances of type parameters; need to reverse - * solution direction for all contravariant variables. - * @param upper When `true` search for max solution else min. - */ - def solve(tvars: List[TypeVar], tparams: List[Symbol], - variances: List[Int], upper: Boolean): Boolean = - solve(tvars, tparams, variances, upper, AnyDepth) - - def solve(tvars: List[TypeVar], tparams: List[Symbol], - variances: List[Int], upper: Boolean, depth: Int): Boolean = { - - def solveOne(tvar: TypeVar, tparam: Symbol, variance: Int) { - if (tvar.constr.inst == NoType) { - val up = if (variance != CONTRAVARIANT) upper else !upper - tvar.constr.inst = null - val bound: Type = if (up) tparam.info.bounds.hi else tparam.info.bounds.lo - //Console.println("solveOne0(tv, tp, v, b)="+(tvar, tparam, variance, bound)) - var cyclic = bound contains tparam - foreach3(tvars, tparams, variances)((tvar2, tparam2, variance2) => { - val ok = (tparam2 != tparam) && ( - (bound contains tparam2) - || up && (tparam2.info.bounds.lo =:= tparam.tpeHK) - || !up && (tparam2.info.bounds.hi =:= tparam.tpeHK) - ) - if (ok) { - if (tvar2.constr.inst eq null) cyclic = true - solveOne(tvar2, tparam2, variance2) - } - }) - if (!cyclic) { - if (up) { - if (bound.typeSymbol != AnyClass) - tvar addHiBound bound.instantiateTypeParams(tparams, tvars) - for (tparam2 <- tparams) - tparam2.info.bounds.lo.dealias match { - case TypeRef(_, `tparam`, _) => - tvar addHiBound tparam2.tpeHK.instantiateTypeParams(tparams, tvars) - case _ => - } - } else { - if (bound.typeSymbol != NothingClass && bound.typeSymbol != tparam) { - tvar addLoBound bound.instantiateTypeParams(tparams, tvars) - } - for (tparam2 <- tparams) - tparam2.info.bounds.hi.dealias match { - case TypeRef(_, `tparam`, _) => - tvar addLoBound tparam2.tpeHK.instantiateTypeParams(tparams, tvars) - case _ => - } - } - } - tvar.constr.inst = NoType // necessary because hibounds/lobounds may contain tvar - - //println("solving "+tvar+" "+up+" "+(if (up) (tvar.constr.hiBounds) else tvar.constr.loBounds)+((if (up) (tvar.constr.hiBounds) else tvar.constr.loBounds) map (_.widen))) - - tvar setInst ( - if (up) { - if (depth != AnyDepth) glb(tvar.constr.hiBounds, depth) else glb(tvar.constr.hiBounds) - } else { - if (depth != AnyDepth) lub(tvar.constr.loBounds, depth) else lub(tvar.constr.loBounds) - }) - - //Console.println("solving "+tvar+" "+up+" "+(if (up) (tvar.constr.hiBounds) else tvar.constr.loBounds)+((if (up) (tvar.constr.hiBounds) else tvar.constr.loBounds) map (_.widen))+" = "+tvar.constr.inst)//@MDEBUG - } - } - - // println("solving "+tvars+"/"+tparams+"/"+(tparams map (_.info))) - foreach3(tvars, tparams, variances)(solveOne) - tvars forall (tvar => tvar.constr.isWithinBounds(tvar.constr.inst)) - } - - /** Do type arguments `targs` conform to formal parameters `tparams`? - */ - def isWithinBounds(pre: Type, owner: Symbol, tparams: List[Symbol], targs: List[Type]): Boolean = { - var bounds = instantiatedBounds(pre, owner, tparams, targs) - if (targs.exists(_.annotations.nonEmpty)) - bounds = adaptBoundsToAnnotations(bounds, tparams, targs) - (bounds corresponds targs)(_ containsType _) - } - - def instantiatedBounds(pre: Type, owner: Symbol, tparams: List[Symbol], targs: List[Type]): List[TypeBounds] = - tparams map (_.info.asSeenFrom(pre, owner).instantiateTypeParams(tparams, targs).bounds) - -// Lubs and Glbs --------------------------------------------------------- - - private def printLubMatrix(btsMap: Map[Type, List[Type]], depth: Int) { - import util.TableDef - import TableDef.Column - def str(tp: Type) = { - if (tp == NoType) "" - else { - val s = ("" + tp).replaceAll("""[\w.]+\.(\w+)""", "$1") - if (s.length < 60) s - else (s take 57) + "..." - } - } - - val sorted = btsMap.toList.sortWith((x, y) => x._1.typeSymbol isLess y._1.typeSymbol) - val maxSeqLength = sorted map (_._2.size) max - val padded = sorted map (_._2.padTo(maxSeqLength, NoType)) - val transposed = padded.transpose - - val columns: List[Column[List[Type]]] = mapWithIndex(sorted) { - case ((k, v), idx) => - Column(str(k), (xs: List[Type]) => str(xs(idx)), true) - } - - val tableDef = TableDef(columns: _*) - val formatted = tableDef.table(transposed) - println("** Depth is " + depth + "\n" + formatted) - } - - /** From a list of types, find any which take type parameters - * where the type parameter bounds contain references to other - * any types in the list (including itself.) - * - * @return List of symbol pairs holding the recursive type - * parameter and the parameter which references it. - */ - def findRecursiveBounds(ts: List[Type]): List[(Symbol, Symbol)] = { - if (ts.isEmpty) Nil - else { - val sym = ts.head.typeSymbol - require(ts.tail forall (_.typeSymbol == sym), ts) - for (p <- sym.typeParams ; in <- sym.typeParams ; if in.info.bounds contains p) yield - p -> in - } - } - - /** Given a matrix `tsBts` whose columns are basetype sequences (and the symbols `tsParams` that should be interpreted as type parameters in this matrix), - * compute its least sorted upwards closed upper bound relative to the following ordering <= between lists of types: - * - * xs <= ys iff forall y in ys exists x in xs such that x <: y - * - * @arg tsParams for each type in the original list of types `ts0`, its list of type parameters (if that type is a type constructor) - * (these type parameters may be referred to by type arguments in the BTS column of those types, - * and must be interpreted as bound variables; i.e., under a type lambda that wraps the types that refer to these type params) - * @arg tsBts a matrix whose columns are basetype sequences - * the first row is the original list of types for which we're computing the lub - * (except that type constructors have been applied to their dummyArgs) - * @See baseTypeSeq for a definition of sorted and upwards closed. - */ - private def lubList(ts: List[Type], depth: Int): List[Type] = { - // Matching the type params of one of the initial types means dummies. - val initialTypeParams = ts map (_.typeParams) - def isHotForTs(xs: List[Type]) = initialTypeParams contains xs.map(_.typeSymbol) - - def elimHigherOrderTypeParam(tp: Type) = tp match { - case TypeRef(pre, sym, args) if args.nonEmpty && isHotForTs(args) => tp.typeConstructor - case _ => tp - } - var lubListDepth = 0 - def loop(tsBts: List[List[Type]]): List[Type] = { - lubListDepth += 1 - - if (tsBts.isEmpty || tsBts.exists(_.isEmpty)) Nil - else if (tsBts.tail.isEmpty) tsBts.head - else { - // ts0 is the 1-dimensional frontier of symbols cutting through 2-dimensional tsBts. - // Invariant: all symbols "under" (closer to the first row) the frontier - // are smaller (according to _.isLess) than the ones "on and beyond" the frontier - val ts0 = tsBts map (_.head) - - // Is the frontier made up of types with the same symbol? - val isUniformFrontier = (ts0: @unchecked) match { - case t :: ts => ts forall (_.typeSymbol == t.typeSymbol) - } - - // Produce a single type for this frontier by merging the prefixes and arguments of those - // typerefs that share the same symbol: that symbol is the current maximal symbol for which - // the invariant holds, i.e., the one that conveys most information wrt subtyping. Before - // merging, strip targs that refer to bound tparams (when we're computing the lub of type - // constructors.) Also filter out all types that are a subtype of some other type. - if (isUniformFrontier) { - if (settings.debug.value || printLubs) { - val fbounds = findRecursiveBounds(ts0) - if (fbounds.nonEmpty) { - println("Encountered " + fbounds.size + " recursive bounds while lubbing " + ts0.size + " types.") - for ((p0, p1) <- fbounds) { - val desc = if (p0 == p1) "its own bounds" else "the bounds of " + p1 - - println(" " + p0.fullLocationString + " appears in " + desc) - println(" " + p1 + " " + p1.info.bounds) - } - println("") - } - } - val tails = tsBts map (_.tail) - mergePrefixAndArgs(elimSub(ts0 map elimHigherOrderTypeParam, depth), 1, depth) match { - case Some(tp) => tp :: loop(tails) - case _ => loop(tails) - } - } - else { - // frontier is not uniform yet, move it beyond the current minimal symbol; - // lather, rinSe, repeat - val sym = minSym(ts0) - val newtps = tsBts map (ts => if (ts.head.typeSymbol == sym) ts.tail else ts) - if (printLubs) { - val str = (newtps.zipWithIndex map { case (tps, idx) => - tps.map(" " + _ + "\n").mkString(" (" + idx + ")\n", "", "\n") - }).mkString("") - - println("Frontier(\n" + str + ")") - printLubMatrix(ts zip tsBts toMap, lubListDepth) - } - - loop(newtps) - } - } - } - - val initialBTSes = ts map (_.baseTypeSeq.toList) - if (printLubs) - printLubMatrix(ts zip initialBTSes toMap, depth) - - loop(initialBTSes) - } - - /** The minimal symbol (wrt Symbol.isLess) of a list of types */ - private def minSym(tps: List[Type]): Symbol = - (tps.head.typeSymbol /: tps.tail) { - (sym1, tp2) => if (tp2.typeSymbol isLess sym1) tp2.typeSymbol else sym1 - } - - /** A minimal type list which has a given list of types as its base type sequence */ - def spanningTypes(ts: List[Type]): List[Type] = ts match { - case List() => List() - case first :: rest => - first :: spanningTypes( - rest filter (t => !first.typeSymbol.isSubClass(t.typeSymbol))) - } - - /** Eliminate from list of types all elements which are a supertype - * of some other element of the list. */ - private def elimSuper(ts: List[Type]): List[Type] = ts match { - case List() => List() - case t :: ts1 => - val rest = elimSuper(ts1 filter (t1 => !(t <:< t1))) - if (rest exists (t1 => t1 <:< t)) rest else t :: rest - } - def elimAnonymousClass(t: Type) = t match { - case TypeRef(pre, clazz, Nil) if clazz.isAnonymousClass => - clazz.classBound.asSeenFrom(pre, clazz.owner) - case _ => - t - } - def elimRefinement(t: Type) = t match { - case RefinedType(parents, decls) if !decls.isEmpty => intersectionType(parents) - case _ => t - } - - /** Eliminate from list of types all elements which are a subtype - * of some other element of the list. */ - private def elimSub(ts: List[Type], depth: Int): List[Type] = { - def elimSub0(ts: List[Type]): List[Type] = ts match { - case List() => List() - case t :: ts1 => - val rest = elimSub0(ts1 filter (t1 => !isSubType(t1, t, decr(depth)))) - if (rest exists (t1 => isSubType(t, t1, decr(depth)))) rest else t :: rest - } - val ts0 = elimSub0(ts) - if (ts0.isEmpty || ts0.tail.isEmpty) ts0 - else { - val ts1 = ts0 mapConserve (t => elimAnonymousClass(t.underlying)) - if (ts1 eq ts0) ts0 - else elimSub(ts1, depth) - } - } - - private def stripExistentialsAndTypeVars(ts: List[Type]): (List[Type], List[Symbol]) = { - val quantified = ts flatMap { - case ExistentialType(qs, _) => qs - case t => List() - } - def stripType(tp: Type) = tp match { - case ExistentialType(_, res) => - res - case tv@TypeVar(_, constr) => - if (tv.instValid) constr.inst - else if (tv.untouchable) tv - else abort("trying to do lub/glb of typevar "+tp) - case t => t - } - val strippedTypes = ts mapConserve stripType - (strippedTypes, quantified) - } - - def weakLub(ts: List[Type]) = - if (ts.nonEmpty && (ts forall isNumericValueType)) (numericLub(ts), true) - else if (ts.nonEmpty && (ts exists (_.annotations.nonEmpty))) - (annotationsLub(lub(ts map (_.withoutAnnotations)), ts), true) - else (lub(ts), false) - - def weakGlb(ts: List[Type]) = { - if (ts.nonEmpty && (ts forall isNumericValueType)) { - val nglb = numericGlb(ts) - if (nglb != NoType) (nglb, true) - else (glb(ts), false) - } else if (ts.nonEmpty && (ts exists (_.annotations.nonEmpty))) { - (annotationsGlb(glb(ts map (_.withoutAnnotations)), ts), true) - } else (glb(ts), false) - } - - def numericLub(ts: List[Type]) = - ts reduceLeft ((t1, t2) => - if (isNumericSubType(t1, t2)) t2 - else if (isNumericSubType(t2, t1)) t1 - else IntClass.tpe) - - def numericGlb(ts: List[Type]) = - ts reduceLeft ((t1, t2) => - if (isNumericSubType(t1, t2)) t1 - else if (isNumericSubType(t2, t1)) t2 - else NoType) - - def isWeakSubType(tp1: Type, tp2: Type) = - tp1.deconst.normalize match { - case TypeRef(_, sym1, _) if isNumericValueClass(sym1) => - tp2.deconst.normalize match { - case TypeRef(_, sym2, _) if isNumericValueClass(sym2) => - isNumericSubClass(sym1, sym2) - case tv2 @ TypeVar(_, _) => - tv2.registerBound(tp1, isLowerBound = true, isNumericBound = true) - case _ => - isSubType(tp1, tp2) - } - case tv1 @ TypeVar(_, _) => - tp2.deconst.normalize match { - case TypeRef(_, sym2, _) if isNumericValueClass(sym2) => - tv1.registerBound(tp2, isLowerBound = false, isNumericBound = true) - case _ => - isSubType(tp1, tp2) - } - case _ => - isSubType(tp1, tp2) - } - - /** The isNumericValueType tests appear redundant, but without them - * test/continuations-neg/function3.scala goes into an infinite loop. - * (Even if the calls are to typeSymbolDirect.) - */ - def isNumericSubType(tp1: Type, tp2: Type) = ( - isNumericValueType(tp1) - && isNumericValueType(tp2) - && isNumericSubClass(tp1.typeSymbol, tp2.typeSymbol) - ) - - private val lubResults = new mutable.HashMap[(Int, List[Type]), Type] - private val glbResults = new mutable.HashMap[(Int, List[Type]), Type] - - def lub(ts: List[Type]): Type = ts match { - case List() => NothingClass.tpe - case List(t) => t - case _ => - try { - lub(ts, lubDepth(ts)) - } finally { - lubResults.clear() - glbResults.clear() - } - } - - /** The least upper bound wrt <:< of a list of types */ - private def lub(ts: List[Type], depth: Int): Type = { - def lub0(ts0: List[Type]): Type = elimSub(ts0, depth) match { - case List() => NothingClass.tpe - case List(t) => t - case ts @ PolyType(tparams, _) :: _ => - val tparams1 = map2(tparams, matchingBounds(ts, tparams).transpose)((tparam, bounds) => - tparam.cloneSymbol.setInfo(glb(bounds, depth))) - PolyType(tparams1, lub0(matchingInstTypes(ts, tparams1))) - case ts @ MethodType(params, _) :: rest => - MethodType(params, lub0(matchingRestypes(ts, params map (_.tpe)))) - case ts @ NullaryMethodType(_) :: rest => - NullaryMethodType(lub0(matchingRestypes(ts, Nil))) - case ts @ TypeBounds(_, _) :: rest => - TypeBounds(glb(ts map (_.bounds.lo), depth), lub(ts map (_.bounds.hi), depth)) - case ts => - lubResults get (depth, ts) match { - case Some(lubType) => - lubType - case None => - lubResults((depth, ts)) = AnyClass.tpe - val res = if (depth < 0) AnyClass.tpe else lub1(ts) - lubResults((depth, ts)) = res - res - } - } - def lub1(ts0: List[Type]): Type = { - val (ts, tparams) = stripExistentialsAndTypeVars(ts0) - val lubBaseTypes: List[Type] = lubList(ts, depth) - val lubParents = spanningTypes(lubBaseTypes) - val lubOwner = commonOwner(ts) - val lubBase = intersectionType(lubParents, lubOwner) - val lubType = - if (phase.erasedTypes || depth == 0) lubBase - else { - val lubRefined = refinedType(lubParents, lubOwner) - val lubThisType = lubRefined.typeSymbol.thisType - val narrowts = ts map (_.narrow) - def excludeFromLub(sym: Symbol) = ( - sym.isClass - || sym.isConstructor - || !sym.isPublic - || isGetClass(sym) - || narrowts.exists(t => !refines(t, sym)) - ) - def lubsym(proto: Symbol): Symbol = { - val prototp = lubThisType.memberInfo(proto) - val syms = narrowts map (t => - t.nonPrivateMember(proto.name).suchThat(sym => - sym.tpe matches prototp.substThis(lubThisType.typeSymbol, t))) - if (syms contains NoSymbol) NoSymbol - else { - val symtypes = - map2(narrowts, syms)((t, sym) => t.memberInfo(sym).substThis(t.typeSymbol, lubThisType)) - if (proto.isTerm) // possible problem: owner of info is still the old one, instead of new refinement class - proto.cloneSymbol(lubRefined.typeSymbol).setInfoOwnerAdjusted(lub(symtypes, decr(depth))) - else if (symtypes.tail forall (symtypes.head =:=)) - proto.cloneSymbol(lubRefined.typeSymbol).setInfoOwnerAdjusted(symtypes.head) - else { - def lubBounds(bnds: List[TypeBounds]): TypeBounds = - TypeBounds(glb(bnds map (_.lo), decr(depth)), lub(bnds map (_.hi), decr(depth))) - lubRefined.typeSymbol.newAbstractType(proto.name.toTypeName, proto.pos) - .setInfoOwnerAdjusted(lubBounds(symtypes map (_.bounds))) - } - } - } - def refines(tp: Type, sym: Symbol): Boolean = { - val syms = tp.nonPrivateMember(sym.name).alternatives; - !syms.isEmpty && (syms forall (alt => - // todo alt != sym is strictly speaking not correct, but without it we lose - // efficiency. - alt != sym && !specializesSym(lubThisType, sym, tp, alt))) - } - // add a refinement symbol for all non-class members of lubBase - // which are refined by every type in ts. - for (sym <- lubBase.nonPrivateMembers ; if !excludeFromLub(sym)) { - try { - val lsym = lubsym(sym) - if (lsym != NoSymbol) addMember(lubThisType, lubRefined, lsym) - } catch { - case ex: NoCommonType => - } - } - if (lubRefined.decls.isEmpty) lubBase - else if (!verifyLubs) lubRefined - else { - // Verify that every given type conforms to the calculated lub. - // In theory this should not be necessary, but higher-order type - // parameters are not handled correctly. - val ok = ts forall { t => - (t <:< lubRefined) || { - if (settings.debug.value || printLubs) { - Console.println( - "Malformed lub: " + lubRefined + "\n" + - "Argument " + t + " does not conform. Falling back to " + lubBase - ) - } - false - } - } - // If not, fall back on the more conservative calculation. - if (ok) lubRefined - else lubBase - } - } - existentialAbstraction(tparams, lubType) - } - if (printLubs) { - println(indent + "lub of " + ts + " at depth "+depth)//debug - indent = indent + " " - assert(indent.length <= 100) - } - val res = lub0(ts) - if (printLubs) { - indent = indent stripSuffix " " - println(indent + "lub of " + ts + " is " + res)//debug - } - if (ts forall (_.isNotNull)) res.notNull else res - } - - val GlbFailure = new Throwable - - /** A global counter for glb calls in the `specializes` query connected to the `addMembers` - * call in `glb`. There's a possible infinite recursion when `specializes` calls - * memberType, which calls baseTypeSeq, which calls mergePrefixAndArgs, which calls glb. - * The counter breaks this recursion after two calls. - * If the recursion is broken, no member is added to the glb. - */ - private var globalGlbDepth = 0 - private final val globalGlbLimit = 2 - - /** The greatest lower bound wrt <:< of a list of types */ - def glb(ts: List[Type]): Type = elimSuper(ts) match { - case List() => AnyClass.tpe - case List(t) => t - case ts0 => - try { - glbNorm(ts0, lubDepth(ts0)) - } finally { - lubResults.clear() - glbResults.clear() - } - } - - private def glb(ts: List[Type], depth: Int): Type = elimSuper(ts) match { - case List() => AnyClass.tpe - case List(t) => t - case ts0 => glbNorm(ts0, depth) - } - - /** The greatest lower bound wrt <:< of a list of types, which have been normalized - * wrt elimSuper */ - protected def glbNorm(ts: List[Type], depth: Int): Type = { - def glb0(ts0: List[Type]): Type = ts0 match { - case List() => AnyClass.tpe - case List(t) => t - case ts @ PolyType(tparams, _) :: _ => - val tparams1 = map2(tparams, matchingBounds(ts, tparams).transpose)((tparam, bounds) => - tparam.cloneSymbol.setInfo(lub(bounds, depth))) - PolyType(tparams1, glbNorm(matchingInstTypes(ts, tparams1), depth)) - case ts @ MethodType(params, _) :: rest => - MethodType(params, glbNorm(matchingRestypes(ts, params map (_.tpe)), depth)) - case ts @ NullaryMethodType(_) :: rest => - NullaryMethodType(glbNorm(matchingRestypes(ts, Nil), depth)) - case ts @ TypeBounds(_, _) :: rest => - TypeBounds(lub(ts map (_.bounds.lo), depth), glb(ts map (_.bounds.hi), depth)) - case ts => - glbResults get (depth, ts) match { - case Some(glbType) => - glbType - case _ => - glbResults((depth, ts)) = NothingClass.tpe - val res = if (depth < 0) NothingClass.tpe else glb1(ts) - glbResults((depth, ts)) = res - res - } - } - def glb1(ts0: List[Type]): Type = { - try { - val (ts, tparams) = stripExistentialsAndTypeVars(ts0) - val glbOwner = commonOwner(ts) - def refinedToParents(t: Type): List[Type] = t match { - case RefinedType(ps, _) => ps flatMap refinedToParents - case _ => List(t) - } - def refinedToDecls(t: Type): List[Scope] = t match { - case RefinedType(ps, decls) => - val dss = ps flatMap refinedToDecls - if (decls.isEmpty) dss else decls :: dss - case _ => List() - } - val ts1 = ts flatMap refinedToParents - val glbBase = intersectionType(ts1, glbOwner) - val glbType = - if (phase.erasedTypes || depth == 0) glbBase - else { - val glbRefined = refinedType(ts1, glbOwner) - val glbThisType = glbRefined.typeSymbol.thisType - def glbsym(proto: Symbol): Symbol = { - val prototp = glbThisType.memberInfo(proto) - val syms = for (t <- ts; - alt <- (t.nonPrivateMember(proto.name).alternatives); - if glbThisType.memberInfo(alt) matches prototp - ) yield alt - val symtypes = syms map glbThisType.memberInfo - assert(!symtypes.isEmpty) - proto.cloneSymbol(glbRefined.typeSymbol).setInfoOwnerAdjusted( - if (proto.isTerm) glb(symtypes, decr(depth)) - else { - def isTypeBound(tp: Type) = tp match { - case TypeBounds(_, _) => true - case _ => false - } - def glbBounds(bnds: List[Type]): TypeBounds = { - val lo = lub(bnds map (_.bounds.lo), decr(depth)) - val hi = glb(bnds map (_.bounds.hi), decr(depth)) - if (lo <:< hi) TypeBounds(lo, hi) - else throw GlbFailure - } - val symbounds = symtypes filter isTypeBound - var result: Type = - if (symbounds.isEmpty) - TypeBounds.empty - else glbBounds(symbounds) - for (t <- symtypes if !isTypeBound(t)) - if (result.bounds containsType t) result = t - else throw GlbFailure - result - }) - } - if (globalGlbDepth < globalGlbLimit) - try { - globalGlbDepth += 1 - val dss = ts flatMap refinedToDecls - for (ds <- dss; sym <- ds.iterator) - if (globalGlbDepth < globalGlbLimit && !(glbThisType specializes sym)) - try { - addMember(glbThisType, glbRefined, glbsym(sym)) - } catch { - case ex: NoCommonType => - } - } finally { - globalGlbDepth -= 1 - } - if (glbRefined.decls.isEmpty) glbBase else glbRefined - } - existentialAbstraction(tparams, glbType) - } catch { - case GlbFailure => - if (ts forall (t => NullClass.tpe <:< t)) NullClass.tpe - else NothingClass.tpe - } - } - // if (settings.debug.value) { println(indent + "glb of " + ts + " at depth "+depth); indent = indent + " " } //DEBUG - - val res = glb0(ts) - - // if (settings.debug.value) { indent = indent.substring(0, indent.length() - 2); log(indent + "glb of " + ts + " is " + res) }//DEBUG - - if (ts exists (_.isNotNull)) res.notNull else res - } - - /** A list of the typevars in a type. */ - def typeVarsInType(tp: Type): List[TypeVar] = { - var tvs: List[TypeVar] = Nil - tp foreach { - case t: TypeVar => tvs ::= t - case _ => - } - tvs.reverse - } - /** Make each type var in this type use its original type for comparisons instead - * of collecting constraints. - */ - def suspendTypeVarsInType(tp: Type): List[TypeVar] = { - val tvs = typeVarsInType(tp) - // !!! Is it somehow guaranteed that this will not break under nesting? - // In general one has to save and restore the contents of the field... - tvs foreach (_.suspended = true) - tvs - } - - /** 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. - * Return `Some(x)` if the computation succeeds with result `x`. - * Return `None` if the computation fails. - */ - def mergePrefixAndArgs(tps: List[Type], variance: Int, depth: Int): Option[Type] = tps match { - case List(tp) => - Some(tp) - case TypeRef(_, sym, _) :: rest => - val pres = tps map (_.prefix) // prefix normalizes automatically - val pre = if (variance == 1) lub(pres, depth) else glb(pres, depth) - val argss = tps map (_.normalize.typeArgs) // symbol equality (of the tp in tps) was checked using typeSymbol, which normalizes, so should normalize before retrieving arguments - val capturedParams = new ListBuffer[Symbol] - try { - if (sym == ArrayClass && phase.erasedTypes) { - // special treatment for lubs of array types after erasure: - // if argss contain one value type and some other type, the lub is Object - // if argss contain several reference types, the lub is an array over lub of argtypes - if (argss exists (_.isEmpty)) { - None // something is wrong: an array without a type arg. - } else { - val args = argss map (_.head) - if (args.tail forall (_ =:= args.head)) Some(typeRef(pre, sym, List(args.head))) - else if (args exists (arg => isPrimitiveValueClass(arg.typeSymbol))) Some(ObjectClass.tpe) - else Some(typeRef(pre, sym, List(lub(args)))) - } - } - else transposeSafe(argss) match { - case None => - // transpose freaked out because of irregular argss - // catching just in case (shouldn't happen, but also doesn't cost us) - // [JZ] It happens: see SI-5683. - debuglog("transposed irregular matrix!?" +(tps, argss)) - None - case Some(argsst) => - val args = map2(sym.typeParams, argsst) { (tparam, as) => - if (depth == 0) { - if (tparam.variance == variance) { - // Take the intersection of the upper bounds of the type parameters - // rather than falling all the way back to "Any", otherwise we end up not - // conforming to bounds. - val bounds0 = sym.typeParams map (_.info.bounds.hi) filterNot (_.typeSymbol == AnyClass) - if (bounds0.isEmpty) AnyClass.tpe - else intersectionType(bounds0 map (b => b.asSeenFrom(tps.head, sym))) - } - else if (tparam.variance == -variance) NothingClass.tpe - else NoType - } - else { - if (tparam.variance == variance) lub(as, decr(depth)) - else if (tparam.variance == -variance) glb(as, decr(depth)) - else { - val l = lub(as, decr(depth)) - val g = glb(as, decr(depth)) - if (l <:< g) l - else { // Martin: I removed this, because incomplete. Not sure there is a good way to fix it. For the moment we - // just err on the conservative side, i.e. with a bound that is too high. - // if(!(tparam.info.bounds contains tparam)) //@M can't deal with f-bounds, see #2251 - - val qvar = commonOwner(as) freshExistential "" setInfo TypeBounds(g, l) - capturedParams += qvar - qvar.tpe - } - } - } - } - if (args contains NoType) None - else Some(existentialAbstraction(capturedParams.toList, typeRef(pre, sym, args))) - } - } catch { - case ex: MalformedType => None - } - case SingleType(_, sym) :: rest => - val pres = tps map (_.prefix) - val pre = if (variance == 1) lub(pres, depth) else glb(pres, depth) - try { - Some(singleType(pre, sym)) - } catch { - case ex: MalformedType => None - } - case ExistentialType(tparams, quantified) :: rest => - mergePrefixAndArgs(quantified :: rest, variance, depth) map (existentialAbstraction(tparams, _)) - case _ => - assert(false, tps); None - } - - /** Make symbol `sym` a member of scope `tp.decls` - * where `thistp` is the narrowed owner type of the scope. - */ - def addMember(thistp: Type, tp: Type, sym: Symbol) { - assert(sym != NoSymbol) - // debuglog("add member " + sym+":"+sym.info+" to "+thistp) //DEBUG - if (!(thistp specializes sym)) { - if (sym.isTerm) - for (alt <- tp.nonPrivateDecl(sym.name).alternatives) - if (specializesSym(thistp, sym, thistp, alt)) - tp.decls unlink alt; - tp.decls enter sym - } - } - - /** All types in list must be polytypes with type parameter lists of - * same length as tparams. - * Returns list of list of bounds infos, where corresponding type - * parameters are renamed to tparams. - */ - private def matchingBounds(tps: List[Type], tparams: List[Symbol]): List[List[Type]] = { - def getBounds(tp: Type): List[Type] = tp match { - case PolyType(tparams1, _) if sameLength(tparams1, tparams) => - tparams1 map (tparam => tparam.info.substSym(tparams1, tparams)) - case tp => - if (tp ne tp.normalize) getBounds(tp.normalize) - else throw new NoCommonType(tps) - } - tps map getBounds - } - - /** All types in list must be polytypes with type parameter lists of - * same length as tparams. - * Returns list of instance types, where corresponding type - * parameters are renamed to tparams. - */ - private def matchingInstTypes(tps: List[Type], tparams: List[Symbol]): List[Type] = { - def transformResultType(tp: Type): Type = tp match { - case PolyType(tparams1, restpe) if sameLength(tparams1, tparams) => - restpe.substSym(tparams1, tparams) - case tp => - if (tp ne tp.normalize) transformResultType(tp.normalize) - else throw new NoCommonType(tps) - } - tps map transformResultType - } - - /** All types in list must be method types with equal parameter types. - * Returns list of their result types. - */ - private def matchingRestypes(tps: List[Type], pts: List[Type]): List[Type] = - tps map { - case MethodType(params1, res) if (isSameTypes(params1 map (_.tpe), pts)) => - res - case NullaryMethodType(res) if pts isEmpty => - res - case _ => - throw new NoCommonType(tps) - } - -// Errors and Diagnostics ----------------------------------------------------- - - /** A throwable signalling a type error */ - class TypeError(var pos: Position, val msg: String) extends Throwable(msg) { - def this(msg: String) = this(NoPosition, msg) - } - - // TODO: RecoverableCyclicReference should be separated from TypeError, - // but that would be a big change. Left for further refactoring. - /** An exception for cyclic references from which we can recover */ - case class RecoverableCyclicReference(sym: Symbol) - extends TypeError("illegal cyclic reference involving " + sym) { - if (settings.debug.value) printStackTrace() - } - - class NoCommonType(tps: List[Type]) extends Throwable( - "lub/glb of incompatible types: " + tps.mkString("", " and ", "")) with ControlThrowable - - /** A throwable signalling a malformed type */ - class MalformedType(msg: String) extends TypeError(msg) { - def this(pre: Type, tp: String) = this("malformed type: " + pre + "#" + tp) - } - - /** The current indentation string for traces */ - private var indent: String = "" - - /** Perform operation `p` on arguments `tp1`, `arg2` and print trace of computation. */ - protected def explain[T](op: String, p: (Type, T) => Boolean, tp1: Type, arg2: T): Boolean = { - Console.println(indent + tp1 + " " + op + " " + arg2 + "?" /* + "("+tp1.getClass+","+arg2.getClass+")"*/) - indent = indent + " " - val result = p(tp1, arg2) - indent = indent stripSuffix " " - Console.println(indent + result) - result - } - - /** If option `explaintypes` is set, print a subtype trace for `found <:< required`. */ - def explainTypes(found: Type, required: Type) { - if (settings.explaintypes.value) withTypesExplained(found <:< required) - } - - /** If option `explaintypes` is set, print a subtype trace for `op(found, required)`. */ - def explainTypes(op: (Type, Type) => Any, found: Type, required: Type) { - if (settings.explaintypes.value) withTypesExplained(op(found, required)) - } - - /** Execute `op` while printing a trace of the operations on types executed. */ - def withTypesExplained[A](op: => A): A = { - val s = explainSwitch - try { explainSwitch = true; op } finally { explainSwitch = s } - } - - def isUnboundedGeneric(tp: Type) = tp match { - case t @ TypeRef(_, sym, _) => sym.isAbstractType && !(t <:< AnyRefClass.tpe) - case _ => false - } - def isBoundedGeneric(tp: Type) = tp match { - case TypeRef(_, sym, _) if sym.isAbstractType => (tp <:< AnyRefClass.tpe) - case TypeRef(_, sym, _) => !isPrimitiveValueClass(sym) - case _ => false - } - // Add serializable to a list of parents, unless one of them already is - def addSerializable(ps: Type*): List[Type] = ( - if (ps exists (_ <:< SerializableClass.tpe)) ps.toList - else (ps :+ SerializableClass.tpe).toList - ) - - def objToAny(tp: Type): Type = - if (!phase.erasedTypes && tp.typeSymbol == ObjectClass) AnyClass.tpe - else tp - - val shorthands = Set( - "scala.collection.immutable.List", - "scala.collection.immutable.Nil", - "scala.collection.Seq", - "scala.collection.Traversable", - "scala.collection.Iterable", - "scala.collection.mutable.StringBuilder", - "scala.collection.IndexedSeq", - "scala.collection.Iterator") - - - /** The maximum number of recursions allowed in toString - */ - final val maxTostringRecursions = 50 - - private var tostringRecursions = 0 - - protected def typeToString(tpe: Type): String = - if (tostringRecursions >= maxTostringRecursions) - "..." - else - try { - tostringRecursions += 1 - tpe.safeToString - } finally { - tostringRecursions -= 1 - } - - implicit val AnnotatedTypeTag = ClassTag[AnnotatedType](classOf[AnnotatedType]) - implicit val BoundedWildcardTypeTag = ClassTag[BoundedWildcardType](classOf[BoundedWildcardType]) - implicit val ClassInfoTypeTag = ClassTag[ClassInfoType](classOf[ClassInfoType]) - implicit val CompoundTypeTag = ClassTag[CompoundType](classOf[CompoundType]) - implicit val ConstantTypeTag = ClassTag[ConstantType](classOf[ConstantType]) - implicit val ExistentialTypeTag = ClassTag[ExistentialType](classOf[ExistentialType]) - implicit val MethodTypeTag = ClassTag[MethodType](classOf[MethodType]) - implicit val NullaryMethodTypeTag = ClassTag[NullaryMethodType](classOf[NullaryMethodType]) - implicit val PolyTypeTag = ClassTag[PolyType](classOf[PolyType]) - implicit val RefinedTypeTag = ClassTag[RefinedType](classOf[RefinedType]) - implicit val SingletonTypeTag = ClassTag[SingletonType](classOf[SingletonType]) - implicit val SingleTypeTag = ClassTag[SingleType](classOf[SingleType]) - implicit val SuperTypeTag = ClassTag[SuperType](classOf[SuperType]) - implicit val ThisTypeTag = ClassTag[ThisType](classOf[ThisType]) - implicit val TypeBoundsTag = ClassTag[TypeBounds](classOf[TypeBounds]) - implicit val TypeRefTag = ClassTag[TypeRef](classOf[TypeRef]) - implicit val TypeTagg = ClassTag[Type](classOf[Type]) -} diff --git a/src/compiler/scala/reflect/internal/package.scala b/src/compiler/scala/reflect/internal/package.scala deleted file mode 100644 index 99b837152d..0000000000 --- a/src/compiler/scala/reflect/internal/package.scala +++ /dev/null @@ -1,6 +0,0 @@ -package scala.reflect - -package object internal { - - type MirrorOf[U <: base.Universe with Singleton] = base.MirrorOf[U] -} diff --git a/src/compiler/scala/reflect/internal/pickling/ByteCodecs.scala b/src/compiler/scala/reflect/internal/pickling/ByteCodecs.scala deleted file mode 100644 index 4670bd4eef..0000000000 --- a/src/compiler/scala/reflect/internal/pickling/ByteCodecs.scala +++ /dev/null @@ -1,221 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ -package scala.reflect.internal.pickling - -object ByteCodecs { - - def avoidZero(src: Array[Byte]): Array[Byte] = { - var i = 0 - val srclen = src.length - var count = 0 - while (i < srclen) { - if (src(i) == 0x7f) count += 1 - i += 1 - } - val dst = new Array[Byte](srclen + count) - i = 0 - var j = 0 - while (i < srclen) { - val in = src(i) - if (in == 0x7f) { - dst(j) = (0xc0).toByte - dst(j + 1) = (0x80).toByte - j += 2 - } else { - dst(j) = (in + 1).toByte - j += 1 - } - i += 1 - } - dst - } - - def regenerateZero(src: Array[Byte]): Int = { - var i = 0 - val srclen = src.length - var j = 0 - while (i < srclen) { - val in: Int = src(i) & 0xff - if (in == 0xc0 && (src(i + 1) & 0xff) == 0x80) { - src(j) = 0x7f - i += 2 - } else if (in == 0) { - src(j) = 0x7f - i += 1 - } else { - src(j) = (in - 1).toByte - i += 1 - } - j += 1 - } - j - } - - def encode8to7(src: Array[Byte]): Array[Byte] = { - val srclen = src.length - val dstlen = (srclen * 8 + 6) / 7 - val dst = new Array[Byte](dstlen) - var i = 0 - var j = 0 - while (i + 6 < srclen) { - var in: Int = src(i) & 0xff - dst(j) = (in & 0x7f).toByte - var out: Int = in >>> 7 - in = src(i + 1) & 0xff - dst(j + 1) = (out | (in << 1) & 0x7f).toByte - out = in >>> 6 - in = src(i + 2) & 0xff - dst(j + 2) = (out | (in << 2) & 0x7f).toByte - out = in >>> 5 - in = src(i + 3) & 0xff - dst(j + 3) = (out | (in << 3) & 0x7f).toByte - out = in >>> 4 - in = src(i + 4) & 0xff - dst(j + 4) = (out | (in << 4) & 0x7f).toByte - out = in >>> 3 - in = src(i + 5) & 0xff - dst(j + 5) = (out | (in << 5) & 0x7f).toByte - out = in >>> 2 - in = src(i + 6) & 0xff - dst(j + 6) = (out | (in << 6) & 0x7f).toByte - out = in >>> 1 - dst(j + 7) = out.toByte - i += 7 - j += 8 - } - if (i < srclen) { - var in: Int = src(i) & 0xff - dst(j) = (in & 0x7f).toByte; j += 1 - var out: Int = in >>> 7 - if (i + 1 < srclen) { - in = src(i + 1) & 0xff - dst(j) = (out | (in << 1) & 0x7f).toByte; j += 1 - out = in >>> 6 - if (i + 2 < srclen) { - in = src(i + 2) & 0xff - dst(j) = (out | (in << 2) & 0x7f).toByte; j += 1 - out = in >>> 5 - if (i + 3 < srclen) { - in = src(i + 3) & 0xff - dst(j) = (out | (in << 3) & 0x7f).toByte; j += 1 - out = in >>> 4 - if (i + 4 < srclen) { - in = src(i + 4) & 0xff - dst(j) = (out | (in << 4) & 0x7f).toByte; j += 1 - out = in >>> 3 - if (i + 5 < srclen) { - in = src(i + 5) & 0xff - dst(j) = (out | (in << 5) & 0x7f).toByte; j += 1 - out = in >>> 2 - } - } - } - } - } - if (j < dstlen) dst(j) = out.toByte - } - dst - } - - def decode7to8(src: Array[Byte], srclen: Int): Int = { - var i = 0 - var j = 0 - val dstlen = (srclen * 7 + 7) / 8 - while (i + 7 < srclen) { - var out: Int = src(i) - var in: Byte = src(i + 1) - src(j) = (out | (in & 0x01) << 7).toByte - out = in >>> 1 - in = src(i + 2) - src(j + 1) = (out | (in & 0x03) << 6).toByte - out = in >>> 2 - in = src(i + 3) - src(j + 2) = (out | (in & 0x07) << 5).toByte - out = in >>> 3 - in = src(i + 4) - src(j + 3) = (out | (in & 0x0f) << 4).toByte - out = in >>> 4 - in = src(i + 5) - src(j + 4) = (out | (in & 0x1f) << 3).toByte - out = in >>> 5 - in = src(i + 6) - src(j + 5) = (out | (in & 0x3f) << 2).toByte - out = in >>> 6 - in = src(i + 7) - src(j + 6) = (out | in << 1).toByte - i += 8 - j += 7 - } - if (i < srclen) { - var out: Int = src(i) - if (i + 1 < srclen) { - var in: Byte = src(i + 1) - src(j) = (out | (in & 0x01) << 7).toByte; j += 1 - out = in >>> 1 - if (i + 2 < srclen) { - in = src(i + 2) - src(j) = (out | (in & 0x03) << 6).toByte; j += 1 - out = in >>> 2 - if (i + 3 < srclen) { - in = src(i + 3) - src(j) = (out | (in & 0x07) << 5).toByte; j += 1 - out = in >>> 3 - if (i + 4 < srclen) { - in = src(i + 4) - src(j) = (out | (in & 0x0f) << 4).toByte; j += 1 - out = in >>> 4 - if (i + 5 < srclen) { - in = src(i + 5) - src(j) = (out | (in & 0x1f) << 3).toByte; j += 1 - out = in >>> 5 - if (i + 6 < srclen) { - in = src(i + 6) - src(j) = (out | (in & 0x3f) << 2).toByte; j += 1 - out = in >>> 6 - } - } - } - } - } - } - if (j < dstlen) src(j) = out.toByte - } - dstlen - } - - def encode(xs: Array[Byte]): Array[Byte] = avoidZero(encode8to7(xs)) - - /** - * Destructively decodes array xs and returns the length of the decoded array. - * - * Sometimes returns (length+1) of the decoded array. Example: - * - * scala> val enc = reflect.generic.ByteCodecs.encode(Array(1,2,3)) - * enc: Array[Byte] = Array(2, 5, 13, 1) - * - * scala> reflect.generic.ByteCodecs.decode(enc) - * res43: Int = 4 - * - * scala> enc - * res44: Array[Byte] = Array(1, 2, 3, 0) - * - * However, this does not always happen. - */ - def decode(xs: Array[Byte]): Int = { - val len = regenerateZero(xs) - decode7to8(xs, len) - } -} - - - - - - - - diff --git a/src/compiler/scala/reflect/internal/pickling/PickleBuffer.scala b/src/compiler/scala/reflect/internal/pickling/PickleBuffer.scala deleted file mode 100644 index 7f0895ce64..0000000000 --- a/src/compiler/scala/reflect/internal/pickling/PickleBuffer.scala +++ /dev/null @@ -1,188 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.reflect -package internal -package pickling - -/** Variable length byte arrays, with methods for basic pickling and unpickling. - * - * @param data The initial buffer - * @param from The first index where defined data are found - * @param to The first index where new data can be written - */ -class PickleBuffer(data: Array[Byte], from: Int, to: Int) { - - var bytes = data - var readIndex = from - var writeIndex = to - - /** Double bytes array */ - private def dble() { - val bytes1 = new Array[Byte](bytes.length * 2) - Array.copy(bytes, 0, bytes1, 0, writeIndex) - bytes = bytes1 - } - - def ensureCapacity(capacity: Int) = - while (bytes.length < writeIndex + capacity) dble() - - // -- Basic output routines -------------------------------------------- - - /** Write a byte of data */ - def writeByte(b: Int) { - if (writeIndex == bytes.length) dble() - bytes(writeIndex) = b.toByte - writeIndex += 1 - } - - /** Write a natural number in big endian format, base 128. - * All but the last digits have bit 0x80 set. - */ - def writeNat(x: Int) = - writeLongNat(x.toLong & 0x00000000FFFFFFFFL) - - /** - * Like writeNat, but for longs. This is not the same as - * writeLong, which writes in base 256. Note that the - * binary representation of LongNat is identical to Nat - * if the long value is in the range Int.MIN_VALUE to - * Int.MAX_VALUE. - */ - def writeLongNat(x: Long) { - def writeNatPrefix(x: Long) { - val y = x >>> 7 - if (y != 0L) writeNatPrefix(y) - writeByte(((x & 0x7f) | 0x80).toInt) - } - val y = x >>> 7 - if (y != 0L) writeNatPrefix(y) - writeByte((x & 0x7f).toInt) - } - - /** Write a natural number <code>x</code> at position <code>pos</code>. - * If number is more than one byte, shift rest of array to make space. - * - * @param pos ... - * @param x ... - */ - def patchNat(pos: Int, x: Int) { - def patchNatPrefix(x: Int) { - writeByte(0) - Array.copy(bytes, pos, bytes, pos+1, writeIndex - (pos+1)) - bytes(pos) = ((x & 0x7f) | 0x80).toByte - val y = x >>> 7 - if (y != 0) patchNatPrefix(y) - } - bytes(pos) = (x & 0x7f).toByte - val y = x >>> 7 - if (y != 0) patchNatPrefix(y) - } - - /** Write a long number <code>x</code> in signed big endian format, base 256. - * - * @param x The long number to be written. - */ - def writeLong(x: Long) { - val y = x >> 8 - val z = x & 0xff - if (-y != (z >> 7)) writeLong(y) - writeByte(z.toInt) - } - - // -- Basic input routines -------------------------------------------- - - /** Peek at the current byte without moving the read index */ - def peekByte(): Int = bytes(readIndex) - - /** Read a byte */ - def readByte(): Int = { - val x = bytes(readIndex); readIndex += 1; x - } - - /** Read a natural number in big endian format, base 128. - * All but the last digits have bit 0x80 set.*/ - def readNat(): Int = readLongNat().toInt - - def readLongNat(): Long = { - var b = 0L - var x = 0L - do { - b = readByte() - x = (x << 7) + (b & 0x7f) - } while ((b & 0x80) != 0L); - x - } - - /** Read a long number in signed big endian format, base 256. */ - def readLong(len: Int): Long = { - var x = 0L - var i = 0 - while (i < len) { - x = (x << 8) + (readByte() & 0xff) - i += 1 - } - val leading = 64 - (len << 3) - x << leading >> leading - } - - /** Returns the buffer as a sequence of (Int, Array[Byte]) representing - * (tag, data) of the individual entries. Saves and restores buffer state. - */ - - def toIndexedSeq: IndexedSeq[(Int, Array[Byte])] = { - val saved = readIndex - readIndex = 0 - readNat() ; readNat() // discarding version - val result = new Array[(Int, Array[Byte])](readNat()) - - result.indices foreach { index => - val tag = readNat() - val len = readNat() - val bytes = data.slice(readIndex, len + readIndex) - readIndex += len - - result(index) = tag -> bytes - } - - readIndex = saved - result.toIndexedSeq - } - - /** Perform operation <code>op</code> until the condition - * <code>readIndex == end</code> is satisfied. - * Concatenate results into a list. - * - * @param end ... - * @param op ... - * @return ... - */ - def until[T](end: Int, op: () => T): List[T] = - if (readIndex == end) List() else op() :: until(end, op); - - /** Perform operation <code>op</code> the number of - * times specified. Concatenate the results into a list. - */ - def times[T](n: Int, op: ()=>T): List[T] = - if (n == 0) List() else op() :: times(n-1, op) - - /** Pickle = majorVersion_Nat minorVersion_Nat nbEntries_Nat {Entry} - * Entry = type_Nat length_Nat [actual entries] - * - * Assumes that the ..Version_Nat are already consumed. - * - * @return an array mapping entry numbers to locations in - * the byte array where the entries start. - */ - def createIndex: Array[Int] = { - val index = new Array[Int](readNat()) // nbEntries_Nat - for (i <- 0 until index.length) { - index(i) = readIndex - readByte() // skip type_Nat - readIndex = readNat() + readIndex // read length_Nat, jump to next entry - } - index - } -} diff --git a/src/compiler/scala/reflect/internal/pickling/PickleFormat.scala b/src/compiler/scala/reflect/internal/pickling/PickleFormat.scala deleted file mode 100644 index 16747af08a..0000000000 --- a/src/compiler/scala/reflect/internal/pickling/PickleFormat.scala +++ /dev/null @@ -1,225 +0,0 @@ -package scala.reflect -package internal -package pickling - -/** This object provides constants for pickling attributes. - * - * If you extend the format, be sure to increase the - * version minor number. - * - * @author Martin Odersky - * @version 1.0 - */ -object PickleFormat { - -/*************************************************** - * Symbol table attribute format: - * Symtab = nentries_Nat {Entry} - * Entry = 1 TERMNAME len_Nat NameInfo - * | 2 TYPENAME len_Nat NameInfo - * | 3 NONEsym len_Nat - * | 4 TYPEsym len_Nat SymbolInfo - * | 5 ALIASsym len_Nat SymbolInfo - * | 6 CLASSsym len_Nat SymbolInfo [thistype_Ref] - * | 7 MODULEsym len_Nat SymbolInfo - * | 8 VALsym len_Nat [defaultGetter_Ref /* no longer needed*/] SymbolInfo [alias_Ref] - * | 9 EXTref len_Nat name_Ref [owner_Ref] - * | 10 EXTMODCLASSref len_Nat name_Ref [owner_Ref] - * | 11 NOtpe len_Nat - * | 12 NOPREFIXtpe len_Nat - * | 13 THIStpe len_Nat sym_Ref - * | 14 SINGLEtpe len_Nat type_Ref sym_Ref - * | 15 CONSTANTtpe len_Nat constant_Ref - * | 16 TYPEREFtpe len_Nat type_Ref sym_Ref {targ_Ref} - * | 17 TYPEBOUNDStpe len_Nat tpe_Ref tpe_Ref - * | 18 REFINEDtpe len_Nat classsym_Ref {tpe_Ref} - * | 19 CLASSINFOtpe len_Nat classsym_Ref {tpe_Ref} - * | 20 METHODtpe len_Nat tpe_Ref {sym_Ref} - * | 21 POLYTtpe len_Nat tpe_Ref {sym_Ref} - * | 22 IMPLICITMETHODtpe len_Nat tpe_Ref {sym_Ref} /* no longer needed */ - * | 52 SUPERtpe len_Nat tpe_Ref tpe_Ref - * | 24 LITERALunit len_Nat - * | 25 LITERALboolean len_Nat value_Long - * | 26 LITERALbyte len_Nat value_Long - * | 27 LITERALshort len_Nat value_Long - * | 28 LITERALchar len_Nat value_Long - * | 29 LITERALint len_Nat value_Long - * | 30 LITERALlong len_Nat value_Long - * | 31 LITERALfloat len_Nat value_Long - * | 32 LITERALdouble len_Nat value_Long - * | 33 LITERALstring len_Nat name_Ref - * | 34 LITERALnull len_Nat - * | 35 LITERALclass len_Nat tpe_Ref - * | 36 LITERALenum len_Nat sym_Ref - * | 40 SYMANNOT len_Nat sym_Ref AnnotInfoBody - * | 41 CHILDREN len_Nat sym_Ref {sym_Ref} - * | 42 ANNOTATEDtpe len_Nat [sym_Ref /* no longer needed */] tpe_Ref {annotinfo_Ref} - * | 43 ANNOTINFO len_Nat AnnotInfoBody - * | 44 ANNOTARGARRAY len_Nat {constAnnotArg_Ref} - * | 47 DEBRUIJNINDEXtpe len_Nat level_Nat index_Nat - * | 48 EXISTENTIALtpe len_Nat type_Ref {symbol_Ref} - * | 49 TREE len_Nat 1 EMPTYtree - * | 49 TREE len_Nat 2 PACKAGEtree type_Ref sym_Ref mods_Ref name_Ref {tree_Ref} - * | 49 TREE len_Nat 3 CLASStree type_Ref sym_Ref mods_Ref name_Ref tree_Ref {tree_Ref} - * | 49 TREE len_Nat 4 MODULEtree type_Ref sym_Ref mods_Ref name_Ref tree_Ref - * | 49 TREE len_Nat 5 VALDEFtree type_Ref sym_Ref mods_Ref name_Ref tree_Ref tree_Ref - * | 49 TREE len_Nat 6 DEFDEFtree type_Ref sym_Ref mods_Ref name_Ref numtparams_Nat {tree_Ref} numparamss_Nat {numparams_Nat {tree_Ref}} tree_Ref tree_Ref - * | 49 TREE len_Nat 7 TYPEDEFtree type_Ref sym_Ref mods_Ref name_Ref tree_Ref {tree_Ref} - * | 49 TREE len_Nat 8 LABELtree type_Ref sym_Ref tree_Ref {tree_Ref} - * | 49 TREE len_Nat 9 IMPORTtree type_Ref sym_Ref tree_Ref {name_Ref name_Ref} - * | 49 TREE len_Nat 11 DOCDEFtree type_Ref sym_Ref string_Ref tree_Ref - * | 49 TREE len_Nat 12 TEMPLATEtree type_Ref sym_Ref numparents_Nat {tree_Ref} tree_Ref {tree_Ref} - * | 49 TREE len_Nat 13 BLOCKtree type_Ref tree_Ref {tree_Ref} - * | 49 TREE len_Nat 14 CASEtree type_Ref tree_Ref tree_Ref tree_Ref - * | 49 TREE len_Nat 15 SEQUENCEtree type_Ref {tree_Ref} - * | 49 TREE len_Nat 16 ALTERNATIVEtree type_Ref {tree_Ref} - * | 49 TREE len_Nat 17 STARtree type_Ref {tree_Ref} - * | 49 TREE len_Nat 18 BINDtree type_Ref sym_Ref name_Ref tree_Ref - * | 49 TREE len_Nat 19 UNAPPLYtree type_Ref tree_Ref {tree_Ref} - * | 49 TREE len_Nat 20 ARRAYVALUEtree type_Ref tree_Ref {tree_Ref} - * | 49 TREE len_Nat 21 FUNCTIONtree type_Ref sym_Ref tree_Ref {tree_Ref} - * | 49 TREE len_Nat 22 ASSIGNtree type_Ref tree_Ref tree_Ref - * | 49 TREE len_Nat 23 IFtree type_Ref tree_Ref tree_Ref tree_Ref - * | 49 TREE len_Nat 24 MATCHtree type_Ref tree_Ref {tree_Ref} - * | 49 TREE len_Nat 25 RETURNtree type_Ref sym_Ref tree_Ref - * | 49 TREE len_Nat 26 TREtree type_Ref tree_Ref tree_Ref {tree_Ref} - * | 49 TREE len_Nat 27 THROWtree type_Ref tree_Ref - * | 49 TREE len_Nat 28 NEWtree type_Ref tree_Ref - * | 49 TREE len_Nat 29 TYPEDtree type_Ref tree_Ref tree_Ref - * | 49 TREE len_Nat 30 TYPEAPPLYtree type_Ref tree_Ref {tree_Ref} - * | 49 TREE len_Nat 31 APPLYtree type_Ref tree_Ref {tree_Ref} - * | 49 TREE len_Nat 32 APPLYDYNAMICtree type_Ref sym_Ref tree_Ref {tree_Ref} - * | 49 TREE len_Nat 33 SUPERtree type_Ref sym_Ref tree_Ref name_Ref - * | 49 TREE len_Nat 34 THIStree type_Ref sym_Ref name_Ref - * | 49 TREE len_Nat 35 SELECTtree type_Ref sym_Ref tree_Ref name_Ref - * | 49 TREE len_Nat 36 IDENTtree type_Ref sym_Ref name_Ref - * | 49 TREE len_Nat 37 LITERALtree type_Ref constant_Ref - * | 49 TREE len_Nat 38 TYPEtree type_Ref - * | 49 TREE len_Nat 39 ANNOTATEDtree type_Ref tree_Ref tree_Ref - * | 49 TREE len_Nat 40 SINGLETONTYPEtree type_Ref tree_Ref - * | 49 TREE len_Nat 41 SELECTFROMTYPEtree type_Ref tree_Ref name_Ref - * | 49 TREE len_Nat 42 COMPOUNDTYPEtree type_Ref tree_Ref - * | 49 TREE len_Nat 43 APPLIEDTYPEtree type_Ref tree_Ref {tree_Ref} - * | 49 TREE len_Nat 44 TYPEBOUNDStree type_Ref tree_Ref tree_Ref - * | 49 TREE len_Nat 45 EXISTENTIALTYPEtree type_Ref tree_Ref {tree_Ref} - * | 50 MODIFIERS len_Nat flags_Long privateWithin_Ref - * SymbolInfo = name_Ref owner_Ref flags_LongNat [privateWithin_Ref] info_Ref - * NameInfo = <character sequence of length len_Nat in Utf8 format> - * NumInfo = <len_Nat-byte signed number in big endian format> - * Ref = Nat - * AnnotInfoBody = info_Ref {annotArg_Ref} {name_Ref constAnnotArg_Ref} - * AnnotArg = Tree | Constant - * ConstAnnotArg = Constant | AnnotInfo | AnnotArgArray - * - * len is remaining length after `len`. - */ - val MajorVersion = 5 - val MinorVersion = 0 - def VersionString = "V" + MajorVersion + "." + MinorVersion - - final val TERMname = 1 - final val TYPEname = 2 - final val NONEsym = 3 - final val TYPEsym = 4 - final val ALIASsym = 5 - final val CLASSsym = 6 - final val MODULEsym = 7 - final val VALsym = 8 - final val EXTref = 9 - final val EXTMODCLASSref = 10 - final val NOtpe = 11 - final val NOPREFIXtpe = 12 - final val THIStpe = 13 - final val SINGLEtpe = 14 - final val CONSTANTtpe = 15 - final val TYPEREFtpe = 16 - final val TYPEBOUNDStpe = 17 - final val REFINEDtpe = 18 - final val CLASSINFOtpe = 19 - final val METHODtpe = 20 - final val POLYtpe = 21 - final val IMPLICITMETHODtpe = 22 // no longer generated - - final val LITERAL = 23 // base line for literals - final val LITERALunit = 24 - final val LITERALboolean = 25 - final val LITERALbyte = 26 - final val LITERALshort = 27 - final val LITERALchar = 28 - final val LITERALint = 29 - final val LITERALlong = 30 - final val LITERALfloat = 31 - final val LITERALdouble = 32 - final val LITERALstring = 33 - final val LITERALnull = 34 - final val LITERALclass = 35 - final val LITERALenum = 36 - final val SYMANNOT = 40 - final val CHILDREN = 41 - final val ANNOTATEDtpe = 42 - final val ANNOTINFO = 43 - final val ANNOTARGARRAY = 44 - - final val SUPERtpe = 46 - final val DEBRUIJNINDEXtpe = 47 - final val EXISTENTIALtpe = 48 - - final val TREE = 49 // prefix code that means a tree is coming - final val EMPTYtree = 1 - final val PACKAGEtree = 2 - final val CLASStree = 3 - final val MODULEtree = 4 - final val VALDEFtree = 5 - final val DEFDEFtree = 6 - final val TYPEDEFtree = 7 - final val LABELtree = 8 - final val IMPORTtree = 9 - final val DOCDEFtree = 11 - final val TEMPLATEtree = 12 - final val BLOCKtree = 13 - final val CASEtree = 14 - // This node type has been removed. - // final val SEQUENCEtree = 15 - final val ALTERNATIVEtree = 16 - final val STARtree = 17 - final val BINDtree = 18 - final val UNAPPLYtree = 19 - final val ARRAYVALUEtree = 20 - final val FUNCTIONtree = 21 - final val ASSIGNtree = 22 - final val IFtree = 23 - final val MATCHtree = 24 - final val RETURNtree = 25 - final val TREtree = 26 - final val THROWtree = 27 - final val NEWtree = 28 - final val TYPEDtree = 29 - final val TYPEAPPLYtree = 30 - final val APPLYtree = 31 - final val APPLYDYNAMICtree = 32 - final val SUPERtree = 33 - final val THIStree = 34 - final val SELECTtree = 35 - final val IDENTtree = 36 - final val LITERALtree = 37 - final val TYPEtree = 38 - final val ANNOTATEDtree = 39 - final val SINGLETONTYPEtree = 40 - final val SELECTFROMTYPEtree = 41 - final val COMPOUNDTYPEtree = 42 - final val APPLIEDTYPEtree = 43 - final val TYPEBOUNDStree = 44 - final val EXISTENTIALTYPEtree = 45 - - final val MODIFIERS = 50 - - final val firstSymTag = NONEsym - final val lastSymTag = VALsym - final val lastExtSymTag = EXTMODCLASSref - - - //The following two are no longer accurate, because ANNOTATEDtpe, - //SUPERtpe, ... are not in the same range as the other types - //final val firstTypeTag = NOtpe - //final val lastTypeTag = POLYtpe -} diff --git a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala deleted file mode 100644 index 757163a074..0000000000 --- a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala +++ /dev/null @@ -1,871 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.reflect -package internal -package pickling - -import java.io.IOException -import java.lang.Float.intBitsToFloat -import java.lang.Double.longBitsToDouble - -import Flags._ -import PickleFormat._ -import scala.collection.{ mutable, immutable } -import collection.mutable.ListBuffer -import annotation.switch - -/** @author Martin Odersky - * @version 1.0 - */ -abstract class UnPickler /*extends reflect.generic.UnPickler*/ { - val global: SymbolTable - import global._ - - /** Unpickle symbol table information descending from a class and/or module root - * from an array of bytes. - * @param bytes bytearray from which we unpickle - * @param offset offset from which unpickling starts - * @param classroot the top-level class which is unpickled, or NoSymbol if inapplicable - * @param moduleroot the top-level module which is unpickled, or NoSymbol if inapplicable - * @param filename filename associated with bytearray, only used for error messages - */ - def unpickle(bytes: Array[Byte], offset: Int, classRoot: Symbol, moduleRoot: Symbol, filename: String) { - try { - new Scan(bytes, offset, classRoot, moduleRoot, filename).run() - } catch { - case ex: IOException => - throw ex - case ex: MissingRequirementError => - throw ex - case ex: Throwable => - /*if (settings.debug.value)*/ ex.printStackTrace() - throw new RuntimeException("error reading Scala signature of "+filename+": "+ex.getMessage()) - } - } - - class Scan(_bytes: Array[Byte], offset: Int, classRoot: Symbol, moduleRoot: Symbol, filename: String) extends PickleBuffer(_bytes, offset, -1) { - //println("unpickle " + classRoot + " and " + moduleRoot)//debug - - protected def debug = settings.debug.value - - checkVersion() - - private val loadingMirror = mirrorThatLoaded(classRoot) - - /** A map from entry numbers to array offsets */ - private val index = createIndex - - /** A map from entry numbers to symbols, types, or annotations */ - private val entries = new Array[AnyRef](index.length) - - /** A map from symbols to their associated `decls` scopes */ - private val symScopes = mutable.HashMap[Symbol, Scope]() - - //println("unpickled " + classRoot + ":" + classRoot.rawInfo + ", " + moduleRoot + ":" + moduleRoot.rawInfo);//debug - - // Laboriously unrolled for performance. - def run() { - var i = 0 - while (i < index.length) { - if (entries(i) == null && isSymbolEntry(i)) { - val savedIndex = readIndex - readIndex = index(i) - entries(i) = readSymbol() - readIndex = savedIndex - } - i += 1 - } - // read children last, fix for #3951 - i = 0 - while (i < index.length) { - if (entries(i) == null) { - if (isSymbolAnnotationEntry(i)) { - val savedIndex = readIndex - readIndex = index(i) - readSymbolAnnotation() - readIndex = savedIndex - } - else if (isChildrenEntry(i)) { - val savedIndex = readIndex - readIndex = index(i) - readChildren() - readIndex = savedIndex - } - } - i += 1 - } - } - - private def checkVersion() { - val major = readNat() - val minor = readNat() - if (major != MajorVersion || minor > MinorVersion) - throw new IOException("Scala signature " + classRoot.decodedName + - " has wrong version\n expected: " + - MajorVersion + "." + MinorVersion + - "\n found: " + major + "." + minor + - " in "+filename) - } - - /** The `decls` scope associated with given symbol */ - protected def symScope(sym: Symbol) = symScopes.getOrElseUpdate(sym, newScope) - - /** Does entry represent an (internal) symbol */ - protected def isSymbolEntry(i: Int): Boolean = { - val tag = bytes(index(i)).toInt - (firstSymTag <= tag && tag <= lastSymTag && - (tag != CLASSsym || !isRefinementSymbolEntry(i))) - } - - /** Does entry represent an (internal or external) symbol */ - protected def isSymbolRef(i: Int): Boolean = { - val tag = bytes(index(i)) - (firstSymTag <= tag && tag <= lastExtSymTag) - } - - /** Does entry represent a name? */ - protected def isNameEntry(i: Int): Boolean = { - val tag = bytes(index(i)).toInt - tag == TERMname || tag == TYPEname - } - - /** Does entry represent a symbol annotation? */ - protected def isSymbolAnnotationEntry(i: Int): Boolean = { - val tag = bytes(index(i)).toInt - tag == SYMANNOT - } - - /** Does the entry represent children of a symbol? */ - protected def isChildrenEntry(i: Int): Boolean = { - val tag = bytes(index(i)).toInt - tag == CHILDREN - } - - /** Does entry represent a refinement symbol? - * pre: Entry is a class symbol - */ - protected def isRefinementSymbolEntry(i: Int): Boolean = { - val savedIndex = readIndex - readIndex = index(i) - val tag = readByte().toInt - assert(tag == CLASSsym) - - readNat(); // read length - val result = readNameRef() == tpnme.REFINE_CLASS_NAME - readIndex = savedIndex - result - } - - /** If entry at <code>i</code> is undefined, define it by performing - * operation <code>op</code> with <code>readIndex at start of i'th - * entry. Restore <code>readIndex</code> afterwards. - */ - protected def at[T <: AnyRef](i: Int, op: () => T): T = { - var r = entries(i) - if (r eq null) { - val savedIndex = readIndex - readIndex = index(i) - r = op() - assert(entries(i) eq null, entries(i)) - entries(i) = r - readIndex = savedIndex - } - r.asInstanceOf[T] - } - - /** Read a name */ - protected def readName(): Name = { - val tag = readByte() - val len = readNat() - tag match { - case TERMname => newTermName(bytes, readIndex, len) - case TYPEname => newTypeName(bytes, readIndex, len) - case _ => errorBadSignature("bad name tag: " + tag) - } - } - protected def readTermName(): TermName = readName().toTermName - protected def readTypeName(): TypeName = readName().toTypeName - - /** Read a symbol */ - protected def readSymbol(): Symbol = { - val tag = readByte() - val end = readNat() + readIndex - def atEnd = readIndex == end - - def readExtSymbol(): Symbol = { - val name = readNameRef() - val owner = if (atEnd) loadingMirror.RootClass else readSymbolRef() - - def adjust(sym: Symbol) = if (tag == EXTref) sym else sym.moduleClass - - def fromName(name: Name) = name.toTermName match { - case nme.ROOT => loadingMirror.RootClass - case nme.ROOTPKG => loadingMirror.RootPackage - case _ => adjust(owner.info.decl(name)) - } - def nestedObjectSymbol: Symbol = { - // If the owner is overloaded (i.e. a method), it's not possible to select the - // right member, so return NoSymbol. This can only happen when unpickling a tree. - // the "case Apply" in readTree() takes care of selecting the correct alternative - // after parsing the arguments. - if (owner.isOverloaded) - return NoSymbol - - if (tag == EXTMODCLASSref) { - val moduleVar = owner.info.decl(nme.moduleVarName(name.toTermName)) - if (moduleVar.isLazyAccessor) - return moduleVar.lazyAccessor.lazyAccessor - } - NoSymbol - } - - // (1) Try name. - fromName(name) orElse { - // (2) Try with expanded name. Can happen if references to private - // symbols are read from outside: for instance when checking the children - // of a class. See #1722. - fromName(nme.expandedName(name.toTermName, owner)) orElse { - // (3) Try as a nested object symbol. - nestedObjectSymbol orElse { - // (4) Otherwise, fail. - //System.err.println("missing "+name+" in "+owner+"/"+owner.id+" "+owner.info.decls) - adjust(errorMissingRequirement(name, owner)) - } - } - } - } - - tag match { - case NONEsym => return NoSymbol - case EXTref | EXTMODCLASSref => return readExtSymbol() - case _ => () - } - - // symbols that were pickled with Pickler.writeSymInfo - val nameref = readNat() - val name = at(nameref, readName) - val owner = readSymbolRef() - val flags = pickledToRawFlags(readLongNat()) - var inforef = readNat() - val privateWithin = - if (!isSymbolRef(inforef)) NoSymbol - else { - val pw = at(inforef, readSymbol) - inforef = readNat() - pw - } - - def isModuleFlag = (flags & MODULE) != 0L - def isClassRoot = (name == classRoot.name) && (owner == classRoot.owner) - def isModuleRoot = (name == moduleRoot.name) && (owner == moduleRoot.owner) - def pflags = flags & PickledFlags - - def finishSym(sym: Symbol): Symbol = { - sym.privateWithin = privateWithin - sym.info = ( - if (atEnd) { - assert(!sym.isSuperAccessor, sym) - newLazyTypeRef(inforef) - } - else { - assert(sym.isSuperAccessor || sym.isParamAccessor, sym) - newLazyTypeRefAndAlias(inforef, readNat()) - } - ) - if (sym.owner.isClass && sym != classRoot && sym != moduleRoot && - !sym.isModuleClass && !sym.isRefinementClass && !sym.isTypeParameter && !sym.isExistentiallyBound) - symScope(sym.owner) enter sym - - sym - } - - finishSym(tag match { - case TYPEsym | ALIASsym => - owner.newNonClassSymbol(name.toTypeName, NoPosition, pflags) - case CLASSsym => - val sym = ( - if (isClassRoot) { - if (isModuleFlag) moduleRoot.moduleClass setFlag pflags - else classRoot setFlag pflags - } - else owner.newClassSymbol(name.toTypeName, NoPosition, pflags) - ) - if (!atEnd) - sym.typeOfThis = newLazyTypeRef(readNat()) - - sym - case MODULEsym => - val clazz = at(inforef, () => readType()).typeSymbol // after the NMT_TRANSITION period, we can leave off the () => ... () - if (isModuleRoot) moduleRoot setFlag pflags - else owner.newLinkedModule(clazz, pflags) - case VALsym => - if (isModuleRoot) { assert(false); NoSymbol } - else owner.newTermSymbol(name.toTermName, NoPosition, pflags) - - case _ => - errorBadSignature("bad symbol tag: " + tag) - }) - } - - /** Read a type - * - * @param forceProperType is used to ease the transition to NullaryMethodTypes (commentmarker: NMT_TRANSITION) - * the flag say that a type of kind * is expected, so that PolyType(tps, restpe) can be disambiguated to PolyType(tps, NullaryMethodType(restpe)) - * (if restpe is not a ClassInfoType, a MethodType or a NullaryMethodType, which leaves TypeRef/SingletonType -- the latter would make the polytype a type constructor) - */ - protected def readType(forceProperType: Boolean = false): Type = { - val tag = readByte() - val end = readNat() + readIndex - (tag: @switch) match { - case NOtpe => - NoType - case NOPREFIXtpe => - NoPrefix - case THIStpe => - ThisType(readSymbolRef()) - case SINGLEtpe => - SingleType(readTypeRef(), readSymbolRef()) // !!! was singleType - case SUPERtpe => - val thistpe = readTypeRef() - val supertpe = readTypeRef() - SuperType(thistpe, supertpe) - case CONSTANTtpe => - ConstantType(readConstantRef()) - case TYPEREFtpe => - val pre = readTypeRef() - val sym = readSymbolRef() - var args = until(end, readTypeRef) - TypeRef(pre, sym, args) - case TYPEBOUNDStpe => - TypeBounds(readTypeRef(), readTypeRef()) - case REFINEDtpe => - val clazz = readSymbolRef() - RefinedType(until(end, readTypeRef), symScope(clazz), clazz) - case CLASSINFOtpe => - val clazz = readSymbolRef() - ClassInfoType(until(end, readTypeRef), symScope(clazz), clazz) - case METHODtpe | IMPLICITMETHODtpe => - val restpe = readTypeRef() - val params = until(end, readSymbolRef) - // if the method is overloaded, the params cannot be determined (see readSymbol) => return NoType. - // Only happen for trees, "case Apply" in readTree() takes care of selecting the correct - // alternative after parsing the arguments. - if (params.contains(NoSymbol) || restpe == NoType) NoType - else MethodType(params, restpe) - case POLYtpe => - val restpe = readTypeRef() - val typeParams = until(end, readSymbolRef) - if (typeParams.nonEmpty) { - // NMT_TRANSITION: old class files denoted a polymorphic nullary method as PolyType(tps, restpe), we now require PolyType(tps, NullaryMethodType(restpe)) - // when a type of kind * is expected (forceProperType is true), we know restpe should be wrapped in a NullaryMethodType (if it wasn't suitably wrapped yet) - def transitionNMT(restpe: Type) = { - val resTpeCls = restpe.getClass.toString // what's uglier than isInstanceOf? right! -- isInstanceOf does not work since the concrete types are defined in the compiler (not in scope here) - if(forceProperType /*&& pickleformat < 2.9 */ && !(resTpeCls.endsWith("MethodType"))) { assert(!resTpeCls.contains("ClassInfoType")) - NullaryMethodType(restpe) } - else restpe - } - PolyType(typeParams, transitionNMT(restpe)) - } - else - NullaryMethodType(restpe) - case EXISTENTIALtpe => - val restpe = readTypeRef() - // @PP: Where is the flag setting supposed to happen? I infer - // from the lack of flag setting in the rest of the unpickler - // that it isn't right here. See #4757 for the immediate - // motivation to fix it. - val tparams = until(end, readSymbolRef) map (_ setFlag EXISTENTIAL) - newExistentialType(tparams, restpe) - - case ANNOTATEDtpe => - var typeRef = readNat() - val selfsym = if (isSymbolRef(typeRef)) { - val s = at(typeRef, readSymbol) - typeRef = readNat() - s - } else NoSymbol // selfsym can go. - val tp = at(typeRef, () => readType(forceProperType)) // NMT_TRANSITION - val annots = until(end, readAnnotationRef) - if (selfsym == NoSymbol) AnnotatedType(annots, tp, selfsym) - else tp - case _ => - noSuchTypeTag(tag, end) - } - } - - def noSuchTypeTag(tag: Int, end: Int): Type = - errorBadSignature("bad type tag: " + tag) - - /** Read a constant */ - protected def readConstant(): Constant = { - val tag = readByte().toInt - val len = readNat() - (tag: @switch) match { - case LITERALunit => Constant(()) - case LITERALboolean => Constant(readLong(len) != 0L) - case LITERALbyte => Constant(readLong(len).toByte) - case LITERALshort => Constant(readLong(len).toShort) - case LITERALchar => Constant(readLong(len).toChar) - case LITERALint => Constant(readLong(len).toInt) - case LITERALlong => Constant(readLong(len)) - case LITERALfloat => Constant(intBitsToFloat(readLong(len).toInt)) - case LITERALdouble => Constant(longBitsToDouble(readLong(len))) - case LITERALstring => Constant(readNameRef().toString) - case LITERALnull => Constant(null) - case LITERALclass => Constant(readTypeRef()) - case LITERALenum => Constant(readSymbolRef()) - case _ => noSuchConstantTag(tag, len) - } - } - - def noSuchConstantTag(tag: Int, len: Int): Constant = - errorBadSignature("bad constant tag: " + tag) - - /** Read children and store them into the corresponding symbol. - */ - protected def readChildren() { - val tag = readByte() - assert(tag == CHILDREN) - val end = readNat() + readIndex - val target = readSymbolRef() - while (readIndex != end) target addChild readSymbolRef() - } - - /** Read an annotation argument, which is pickled either - * as a Constant or a Tree. - */ - protected def readAnnotArg(i: Int): Tree = bytes(index(i)) match { - case TREE => at(i, readTree) - case _ => - val const = at(i, readConstant) - Literal(const) setType const.tpe - } - - /** Read a ClassfileAnnotArg (argument to a classfile annotation) - */ - private def readArrayAnnot() = { - readByte() // skip the `annotargarray` tag - val end = readNat() + readIndex - until(end, () => readClassfileAnnotArg(readNat())).toArray(ClassfileAnnotArgTag) - } - protected def readClassfileAnnotArg(i: Int): ClassfileAnnotArg = bytes(index(i)) match { - case ANNOTINFO => NestedAnnotArg(at(i, readAnnotation)) - case ANNOTARGARRAY => at(i, () => ArrayAnnotArg(readArrayAnnot())) - case _ => LiteralAnnotArg(at(i, readConstant)) - } - - /** Read an AnnotationInfo. Not to be called directly, use - * readAnnotation or readSymbolAnnotation - */ - protected def readAnnotationInfo(end: Int): AnnotationInfo = { - val atp = readTypeRef() - val args = new ListBuffer[Tree] - val assocs = new ListBuffer[(Name, ClassfileAnnotArg)] - while (readIndex != end) { - val argref = readNat() - if (isNameEntry(argref)) { - val name = at(argref, readName) - val arg = readClassfileAnnotArg(readNat()) - assocs += ((name, arg)) - } - else - args += readAnnotArg(argref) - } - AnnotationInfo(atp, args.toList, assocs.toList) - } - - /** Read an annotation and as a side effect store it into - * the symbol it requests. Called at top-level, for all - * (symbol, annotInfo) entries. */ - protected def readSymbolAnnotation() { - val tag = readByte() - if (tag != SYMANNOT) - errorBadSignature("symbol annotation expected ("+ tag +")") - val end = readNat() + readIndex - val target = readSymbolRef() - target.addAnnotation(readAnnotationInfo(end)) - } - - /** Read an annotation and return it. Used when unpickling - * an ANNOTATED(WSELF)tpe or a NestedAnnotArg */ - protected def readAnnotation(): AnnotationInfo = { - val tag = readByte() - if (tag != ANNOTINFO) - errorBadSignature("annotation expected (" + tag + ")") - val end = readNat() + readIndex - readAnnotationInfo(end) - } - - /* Read an abstract syntax tree */ - protected def readTree(): Tree = { - val outerTag = readByte() - if (outerTag != TREE) - errorBadSignature("tree expected (" + outerTag + ")") - val end = readNat() + readIndex - val tag = readByte() - val tpe = if (tag == EMPTYtree) NoType else readTypeRef() - - // Set by the three functions to follow. If symbol is non-null - // after the new tree 't' has been created, t has its Symbol - // set to symbol; and it always has its Type set to tpe. - var symbol: Symbol = null - var mods: Modifiers = null - var name: Name = null - - /** Read a Symbol, Modifiers, and a Name */ - def setSymModsName() { - symbol = readSymbolRef() - mods = readModifiersRef() - name = readNameRef() - } - /** Read a Symbol and a Name */ - def setSymName() { - symbol = readSymbolRef() - name = readNameRef() - } - /** Read a Symbol */ - def setSym() { - symbol = readSymbolRef() - } - - val t = tag match { - case EMPTYtree => - EmptyTree - - case PACKAGEtree => - setSym() - val pid = readTreeRef().asInstanceOf[RefTree] - val stats = until(end, readTreeRef) - PackageDef(pid, stats) - - case CLASStree => - setSymModsName() - val impl = readTemplateRef() - val tparams = until(end, readTypeDefRef) - ClassDef(mods, name.toTypeName, tparams, impl) - - case MODULEtree => - setSymModsName() - ModuleDef(mods, name.toTermName, readTemplateRef()) - - case VALDEFtree => - setSymModsName() - val tpt = readTreeRef() - val rhs = readTreeRef() - ValDef(mods, name.toTermName, tpt, rhs) - - case DEFDEFtree => - setSymModsName() - val tparams = times(readNat(), readTypeDefRef) - val vparamss = times(readNat(), () => times(readNat(), readValDefRef)) - val tpt = readTreeRef() - val rhs = readTreeRef() - DefDef(mods, name.toTermName, tparams, vparamss, tpt, rhs) - - case TYPEDEFtree => - setSymModsName() - val rhs = readTreeRef() - val tparams = until(end, readTypeDefRef) - TypeDef(mods, name.toTypeName, tparams, rhs) - - case LABELtree => - setSymName() - val rhs = readTreeRef() - val params = until(end, readIdentRef) - LabelDef(name.toTermName, params, rhs) - - case IMPORTtree => - setSym() - val expr = readTreeRef() - val selectors = until(end, () => { - val from = readNameRef() - val to = readNameRef() - ImportSelector(from, -1, to, -1) - }) - - Import(expr, selectors) - - case TEMPLATEtree => - setSym() - val parents = times(readNat(), readTreeRef) - val self = readValDefRef() - val body = until(end, readTreeRef) - - Template(parents, self, body) - - case BLOCKtree => - val expr = readTreeRef() - val stats = until(end, readTreeRef) - Block(stats, expr) - - case CASEtree => - val pat = readTreeRef() - val guard = readTreeRef() - val body = readTreeRef() - CaseDef(pat, guard, body) - - case ALTERNATIVEtree => - Alternative(until(end, readTreeRef)) - - case STARtree => - Star(readTreeRef()) - - case BINDtree => - setSymName() - Bind(name, readTreeRef()) - - case UNAPPLYtree => - val fun = readTreeRef() - val args = until(end, readTreeRef) - UnApply(fun, args) - - case ARRAYVALUEtree => - val elemtpt = readTreeRef() - val trees = until(end, readTreeRef) - ArrayValue(elemtpt, trees) - - case FUNCTIONtree => - setSym() - val body = readTreeRef() - val vparams = until(end, readValDefRef) - Function(vparams, body) - - case ASSIGNtree => - val lhs = readTreeRef() - val rhs = readTreeRef() - Assign(lhs, rhs) - - case IFtree => - val cond = readTreeRef() - val thenp = readTreeRef() - val elsep = readTreeRef() - If(cond, thenp, elsep) - - case MATCHtree => - val selector = readTreeRef() - val cases = until(end, readCaseDefRef) - Match(selector, cases) - - case RETURNtree => - setSym() - Return(readTreeRef()) - - case TREtree => - val block = readTreeRef() - val finalizer = readTreeRef() - val catches = until(end, readCaseDefRef) - Try(block, catches, finalizer) - - case THROWtree => - Throw(readTreeRef()) - - case NEWtree => - New(readTreeRef()) - - case TYPEDtree => - val expr = readTreeRef() - val tpt = readTreeRef() - Typed(expr, tpt) - - case TYPEAPPLYtree => - val fun = readTreeRef() - val args = until(end, readTreeRef) - TypeApply(fun, args) - - case APPLYtree => - val fun = readTreeRef() - val args = until(end, readTreeRef) - if (fun.symbol.isOverloaded) { - fun.setType(fun.symbol.info) - inferMethodAlternative(fun, args map (_.tpe), tpe) - } - Apply(fun, args) - - case APPLYDYNAMICtree => - setSym() - val qual = readTreeRef() - val args = until(end, readTreeRef) - ApplyDynamic(qual, args) - - case SUPERtree => - setSym() - val qual = readTreeRef() - val mix = readTypeNameRef() - Super(qual, mix) - - case THIStree => - setSym() - This(readTypeNameRef()) - - case SELECTtree => - setSym() - val qualifier = readTreeRef() - val selector = readNameRef() - Select(qualifier, selector) - - case IDENTtree => - setSymName() - Ident(name) - - case LITERALtree => - Literal(readConstantRef()) - - case TYPEtree => - TypeTree() - - case ANNOTATEDtree => - val annot = readTreeRef() - val arg = readTreeRef() - Annotated(annot, arg) - - case SINGLETONTYPEtree => - SingletonTypeTree(readTreeRef()) - - case SELECTFROMTYPEtree => - val qualifier = readTreeRef() - val selector = readTypeNameRef() - SelectFromTypeTree(qualifier, selector) - - case COMPOUNDTYPEtree => - CompoundTypeTree(readTemplateRef()) - - case APPLIEDTYPEtree => - val tpt = readTreeRef() - val args = until(end, readTreeRef) - AppliedTypeTree(tpt, args) - - case TYPEBOUNDStree => - val lo = readTreeRef() - val hi = readTreeRef() - TypeBoundsTree(lo, hi) - - case EXISTENTIALTYPEtree => - val tpt = readTreeRef() - val whereClauses = until(end, readTreeRef) - ExistentialTypeTree(tpt, whereClauses) - - case _ => - noSuchTreeTag(tag, end) - } - - if (symbol == null) t setType tpe - else t setSymbol symbol setType tpe - } - - def noSuchTreeTag(tag: Int, end: Int) = - errorBadSignature("unknown tree type (" + tag + ")") - - def readModifiers(): Modifiers = { - val tag = readNat() - if (tag != MODIFIERS) - errorBadSignature("expected a modifiers tag (" + tag + ")") - val end = readNat() + readIndex - val pflagsHi = readNat() - val pflagsLo = readNat() - val pflags = (pflagsHi.toLong << 32) + pflagsLo - val flags = pickledToRawFlags(pflags) - val privateWithin = readNameRef() - Modifiers(flags, privateWithin, Nil) - } - - /* Read a reference to a pickled item */ - protected def readNameRef(): Name = at(readNat(), readName) - protected def readSymbolRef(): Symbol = at(readNat(), readSymbol) - protected def readTypeRef(): Type = at(readNat(), () => readType()) // after the NMT_TRANSITION period, we can leave off the () => ... () - protected def readConstantRef(): Constant = at(readNat(), readConstant) - protected def readAnnotationRef(): AnnotationInfo = at(readNat(), readAnnotation) - protected def readModifiersRef(): Modifiers = at(readNat(), readModifiers) - protected def readTreeRef(): Tree = at(readNat(), readTree) - - protected def readTypeNameRef(): TypeName = readNameRef().toTypeName - protected def readTermNameRef(): TermName = readNameRef().toTermName - - protected def readTemplateRef(): Template = - readTreeRef() match { - case templ:Template => templ - case other => - errorBadSignature("expected a template (" + other + ")") - } - protected def readCaseDefRef(): CaseDef = - readTreeRef() match { - case tree:CaseDef => tree - case other => - errorBadSignature("expected a case def (" + other + ")") - } - protected def readValDefRef(): ValDef = - readTreeRef() match { - case tree:ValDef => tree - case other => - errorBadSignature("expected a ValDef (" + other + ")") - } - protected def readIdentRef(): Ident = - readTreeRef() match { - case tree:Ident => tree - case other => - errorBadSignature("expected an Ident (" + other + ")") - } - protected def readTypeDefRef(): TypeDef = - readTreeRef() match { - case tree:TypeDef => tree - case other => - errorBadSignature("expected an TypeDef (" + other + ")") - } - - protected def errorBadSignature(msg: String) = - throw new RuntimeException("malformed Scala signature of " + classRoot.name + " at " + readIndex + "; " + msg) - - protected def errorMissingRequirement(name: Name, owner: Symbol): Symbol = - missingHook(owner, name) orElse MissingRequirementError.signal( - s"bad reference while unpickling $filename: ${name.longString} not found in ${owner.tpe.widen}" - ) - - def inferMethodAlternative(fun: Tree, argtpes: List[Type], restpe: Type) {} // can't do it; need a compiler for that. - - 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 = try { - val tp = at(i, () => readType(sym.isTerm)) // after NMT_TRANSITION, revert `() => readType(sym.isTerm)` to `readType` - atPhase(p) (sym setInfo tp) - if (currentRunId != definedAtRunId) - sym.setInfo(adaptToNewRunMap(tp)) - } - catch { - case e: MissingRequirementError => throw toTypeError(e) - } - override def load(sym: Symbol) { complete(sym) } - } - - /** A lazy type which when completed returns type at index `i` and sets alias - * of completed symbol to symbol at index `j`. - */ - private class LazyTypeRefAndAlias(i: Int, j: Int) extends LazyTypeRef(i) { - override def complete(sym: Symbol) = try { - super.complete(sym) - var alias = at(j, readSymbol) - if (alias.isOverloaded) - alias = atPhase(picklerPhase)((alias suchThat (alt => sym.tpe =:= sym.owner.thisType.memberType(alt)))) - - sym.asInstanceOf[TermSymbol].setAlias(alias) - } - catch { - case e: MissingRequirementError => throw toTypeError(e) - } - } - } -} diff --git a/src/compiler/scala/reflect/internal/settings/AbsSettings.scala b/src/compiler/scala/reflect/internal/settings/AbsSettings.scala deleted file mode 100644 index 9bbba3f079..0000000000 --- a/src/compiler/scala/reflect/internal/settings/AbsSettings.scala +++ /dev/null @@ -1,23 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Paul Phillips - */ - -package scala.reflect.internal -package settings - -/** A Settings abstraction boiled out of the original highly mutable Settings - * class with the intention of creating an ImmutableSettings which can be used - * interchangeably. Except of course without the mutants. - */ - -trait AbsSettings { - type Setting <: AbsSettingValue // Fix to the concrete Setting type - - trait AbsSettingValue { - type T <: Any - def value: T - def isDefault: Boolean - } -} - diff --git a/src/compiler/scala/reflect/internal/settings/MutableSettings.scala b/src/compiler/scala/reflect/internal/settings/MutableSettings.scala deleted file mode 100644 index 8640a23aa7..0000000000 --- a/src/compiler/scala/reflect/internal/settings/MutableSettings.scala +++ /dev/null @@ -1,48 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ -// $Id$ - -package scala.reflect.internal -package settings - -/** A mutable Settings object. - */ -abstract class MutableSettings extends AbsSettings { - - type Setting <: SettingValue - type BooleanSetting <: Setting { type T = Boolean } - type IntSetting <: Setting { type T = Int } - - // basically this is a value which remembers if it's been modified - trait SettingValue extends AbsSettingValue { - protected var v: T - protected var setByUser: Boolean = false - - def postSetHook(): Unit = () - def isDefault = !setByUser - def isSetByUser = setByUser - def value: T = v - def value_=(arg: T) = { - setByUser = true - v = arg - postSetHook() - } - } - - def overrideObjects: BooleanSetting - def printtypes: BooleanSetting - def debug: BooleanSetting - def Ynotnull: BooleanSetting - def explaintypes: BooleanSetting - def verbose: BooleanSetting - def uniqid: BooleanSetting - def Yshowsymkinds: BooleanSetting - def Xprintpos: BooleanSetting - def Yrecursion: IntSetting - def maxClassfileName: IntSetting - def Xexperimental: BooleanSetting - def XoldPatmat: BooleanSetting - def XnoPatmatAnalysis: BooleanSetting -}
\ No newline at end of file diff --git a/src/compiler/scala/reflect/internal/transform/Erasure.scala b/src/compiler/scala/reflect/internal/transform/Erasure.scala deleted file mode 100644 index 5beec70d62..0000000000 --- a/src/compiler/scala/reflect/internal/transform/Erasure.scala +++ /dev/null @@ -1,336 +0,0 @@ -package scala.reflect -package internal -package transform - -import Flags.PARAMACCESSOR - -trait Erasure { - - val global: SymbolTable - import global._ - import definitions._ - - /** An extractor object for generic arrays */ - object GenericArray { - - /** Is `tp` an unbounded generic type (i.e. which could be instantiated - * with primitive as well as class types)?. - */ - private def genericCore(tp: Type): Type = tp.normalize match { - /* A Java Array<T> is erased to Array[Object] (T can only be a reference type), where as a Scala Array[T] is - * erased to Object. However, there is only symbol for the Array class. So to make the distinction between - * a Java and a Scala array, we check if the owner of T comes from a Java class. - * This however caused issue SI-5654. The additional test for EXSITENTIAL fixes it, see the ticket comments. - * In short, members of an existential type (e.g. `T` in `forSome { type T }`) can have pretty arbitrary - * owners (e.g. when computing lubs, <root> is used). All packageClass symbols have `isJavaDefined == true`. - */ - case TypeRef(_, sym, _) if sym.isAbstractType && (!sym.owner.isJavaDefined || sym.hasFlag(Flags.EXISTENTIAL)) => - tp - case ExistentialType(tparams, restp) => - genericCore(restp) - case _ => - NoType - } - - /** If `tp` is of the form Array[...Array[T]...] where `T` is an abstract type - * then Some((N, T)) where N is the number of Array constructors enclosing `T`, - * otherwise None. Existentials on any level are ignored. - */ - def unapply(tp: Type): Option[(Int, Type)] = tp.normalize match { - case TypeRef(_, ArrayClass, List(arg)) => - genericCore(arg) match { - case NoType => - unapply(arg) match { - case Some((level, core)) => Some((level + 1, core)) - case None => None - } - case core => - Some((1, core)) - } - case ExistentialType(tparams, restp) => - unapply(restp) - case _ => - None - } - } - - protected def unboundedGenericArrayLevel(tp: Type): Int = tp match { - case GenericArray(level, core) if !(core <:< AnyRefClass.tpe) => level - case _ => 0 - } - - // @M #2585 when generating a java generic signature that includes - // a selection of an inner class p.I, (p = `pre`, I = `cls`) must - // rewrite to p'.I, where p' refers to the class that directly defines - // the nested class I. - // - // See also #2585 marker in javaSig: there, type arguments must be - // included (use pre.baseType(cls.owner)). - // - // This requires that cls.isClass. - protected def rebindInnerClass(pre: Type, cls: Symbol): Type = { - if (cls.owner.isClass) cls.owner.tpe else pre // why not cls.isNestedClass? - } - - def underlyingOfValueClass(clazz: Symbol): Type = - clazz.firstParamAccessor.tpe.resultType - - abstract class ErasureMap extends TypeMap { - private lazy val ObjectArray = arrayType(ObjectClass.tpe) - private lazy val ErasedObject = erasedTypeRef(ObjectClass) - - def mergeParents(parents: List[Type]): Type - - def eraseNormalClassRef(pre: Type, clazz: Symbol): Type = - typeRef(apply(rebindInnerClass(pre, clazz)), clazz, List()) // #2585 - - protected def eraseDerivedValueClassRef(clazz: Symbol): Type = - scalaErasure(underlyingOfValueClass(clazz)) - - def apply(tp: Type): Type = tp match { - case ConstantType(_) => - tp - case st: SubType => - apply(st.supertype) - case TypeRef(pre, sym, args) => - if (sym == ArrayClass) - if (unboundedGenericArrayLevel(tp) == 1) ObjectClass.tpe - else if (args.head.typeSymbol.isBottomClass) ObjectArray - else typeRef(apply(pre), sym, args map applyInArray) - else if (sym == AnyClass || sym == AnyValClass || sym == SingletonClass || sym == NotNullClass) ErasedObject - else if (sym == UnitClass) erasedTypeRef(BoxedUnitClass) - else if (sym.isRefinementClass) apply(mergeParents(tp.parents)) - else if (sym.isDerivedValueClass) eraseDerivedValueClassRef(sym) - else if (sym.isClass) eraseNormalClassRef(pre, sym) - else apply(sym.info) // alias type or abstract type - case PolyType(tparams, restpe) => - apply(restpe) - case ExistentialType(tparams, restpe) => - apply(restpe) - case mt @ MethodType(params, restpe) => - MethodType( - cloneSymbolsAndModify(params, ErasureMap.this), - if (restpe.typeSymbol == UnitClass) erasedTypeRef(UnitClass) - // 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)))) - case RefinedType(parents, decls) => - apply(mergeParents(parents)) - case AnnotatedType(_, atp, _) => - apply(atp) - case ClassInfoType(parents, decls, clazz) => - ClassInfoType( - if (clazz == ObjectClass || isPrimitiveValueClass(clazz)) Nil - else if (clazz == ArrayClass) List(ErasedObject) - else removeLaterObjects(parents map this), - decls, clazz) - case _ => - mapOver(tp) - } - - def applyInArray(tp: Type): Type = tp match { - case TypeRef(pre, sym, args) if (sym.isDerivedValueClass) => eraseNormalClassRef(pre, sym) - case _ => apply(tp) - } - } - - protected def verifyJavaErasure = false - - /** The erasure |T| of a type T. This is: - * - * - For a constant type, itself. - * - For a type-bounds structure, the erasure of its upper bound. - * - For every other singleton type, the erasure of its supertype. - * - For a typeref scala.Array+[T] where T is an abstract type, AnyRef. - * - For a typeref scala.Array+[T] where T is not an abstract type, scala.Array+[|T|]. - * - For a typeref scala.Any or scala.AnyVal, java.lang.Object. - * - For a typeref scala.Unit, scala.runtime.BoxedUnit. - * - For a typeref P.C[Ts] where C refers to a class, |P|.C. - * (Where P is first rebound to the class that directly defines C.) - * - For a typeref P.C[Ts] where C refers to an alias type, the erasure of C's alias. - * - For a typeref P.C[Ts] where C refers to an abstract type, the - * erasure of C's upper bound. - * - For a non-empty type intersection (possibly with refinement) - * - in scala, the erasure of the intersection dominator - * - in java, the erasure of its first parent <--- @PP: not yet in spec. - * - For an empty type intersection, java.lang.Object. - * - For a method type (Fs)scala.Unit, (|Fs|)scala#Unit. - * - For any other method type (Fs)Y, (|Fs|)|T|. - * - For a polymorphic type, the erasure of its result type. - * - For the class info type of java.lang.Object, the same type without any parents. - * - For a class info type of a value class, the same type without any parents. - * - For any other class info type with parents Ps, the same type with - * parents |Ps|, but with duplicate references of Object removed. - * - for all other types, the type itself (with any sub-components erased) - */ - def erasure(sym: Symbol): ErasureMap = - if (sym == NoSymbol || !sym.enclClass.isJavaDefined) scalaErasure - else if (verifyJavaErasure && sym.isMethod) verifiedJavaErasure - else javaErasure - - /** This is used as the Scala erasure during the erasure phase itself - * It differs from normal erasure in that value classes are erased to ErasedValueTypes which - * are then later converted to the underlying parameter type in phase posterasure. - */ - def specialErasure(sym: Symbol)(tp: Type): Type = - if (sym != NoSymbol && sym.enclClass.isJavaDefined) - erasure(sym)(tp) - else if (sym.isTerm && sym.owner.isDerivedValueClass) - specialErasureAvoiding(sym.owner, tp) - else if (sym.isValue && sym.owner.isMethodWithExtension) - specialErasureAvoiding(sym.owner.owner, tp) - else - specialScalaErasure(tp) - - def specialErasureAvoiding(clazz: Symbol, tpe: Type): Type = { - tpe match { - case PolyType(tparams, restpe) => - specialErasureAvoiding(clazz, restpe) - case ExistentialType(tparams, restpe) => - specialErasureAvoiding(clazz, restpe) - case mt @ MethodType(params, restpe) => - MethodType( - cloneSymbolsAndModify(params, specialErasureAvoiding(clazz, _)), - if (restpe.typeSymbol == UnitClass) erasedTypeRef(UnitClass) - else specialErasureAvoiding(clazz, (mt.resultType(params map (_.tpe))))) - case TypeRef(pre, `clazz`, args) => - typeRef(pre, clazz, List()) - case _ => - specialScalaErasure(tpe) - } - } - - /** Scala's more precise erasure than java's is problematic as follows: - * - * - Symbols are read from classfiles and populated with types - * - The textual signature read from the bytecode is forgotten - * - Bytecode generation must know the precise signature of a method - * - the signature is derived from the erasure of the method type - * - If that derivation does not adhere to the rules by which the original - * signature was created, a NoSuchMethod error will result. - * - * For this reason and others (such as distinguishing constructors from other methods) - * erasure is now (Symbol, Type) => Type rather than Type => Type. - */ - class ScalaErasureMap extends ErasureMap { - /** In scala, calculate a useful parent. - * An intersection such as `Object with Trait` erases to Trait. - */ - def mergeParents(parents: List[Type]): Type = - intersectionDominator(parents) - } - - class JavaErasureMap extends ErasureMap { - /** In java, always take the first parent. - * An intersection such as `Object with Trait` erases to Object. - */ - def mergeParents(parents: List[Type]): Type = - if (parents.isEmpty) ObjectClass.tpe - else parents.head - } - - object scalaErasure extends ScalaErasureMap - - /** This is used as the Scala erasure during the erasure phase itself - * It differs from normal erasure in that value classes are erased to ErasedValueTypes which - * are then later converted to the underlying parameter type in phase posterasure. - */ - object specialScalaErasure extends ScalaErasureMap { - override def eraseDerivedValueClassRef(clazz: Symbol): Type = ErasedValueType(clazz) - } - - object javaErasure extends JavaErasureMap - - object verifiedJavaErasure extends JavaErasureMap { - override def apply(tp: Type): Type = { - val res = javaErasure(tp) - val old = scalaErasure(tp) - if (!(res =:= old)) - log("Identified divergence between java/scala erasure:\n scala: " + old + "\n java: " + res) - res - } - } - - /** The intersection dominator (SLS 3.7) of a list of types is computed as follows. - * - * - If the list contains one or more occurrences of scala.Array with - * type parameters El1, El2, ... then the dominator is scala.Array with - * type parameter of intersectionDominator(List(El1, El2, ...)). <--- @PP: not yet in spec. - * - Otherwise, the list is reduced to a subsequence containing only types - * which are not subtypes of other listed types (the span.) - * - If the span is empty, the dominator is Object. - * - If the span contains a class Tc which is not a trait and which is - * not Object, the dominator is Tc. <--- @PP: "which is not Object" not in spec. - * - Otherwise, the dominator is the first element of the span. - */ - def intersectionDominator(parents: List[Type]): Type = { - if (parents.isEmpty) ObjectClass.tpe - else { - val psyms = parents map (_.typeSymbol) - if (psyms contains ArrayClass) { - // treat arrays specially - arrayType( - intersectionDominator( - parents filter (_.typeSymbol == ArrayClass) map (_.typeArgs.head))) - } else { - // implement new spec for erasure of refined types. - def isUnshadowed(psym: Symbol) = - !(psyms exists (qsym => (psym ne qsym) && (qsym isNonBottomSubClass psym))) - val cs = parents.iterator.filter { p => // isUnshadowed is a bit expensive, so try classes first - val psym = p.typeSymbol - psym.initialize - psym.isClass && !psym.isTrait && isUnshadowed(psym) - } - (if (cs.hasNext) cs else parents.iterator.filter(p => isUnshadowed(p.typeSymbol))).next() - } - } - } - - /** Type reference after erasure */ - def erasedTypeRef(sym: Symbol): Type = - typeRef(erasure(sym)(sym.owner.tpe), sym, Nil) - - /** The symbol's erased info. This is the type's erasure, except for the following symbols: - * - * - For $asInstanceOf : [T]T - * - For $isInstanceOf : [T]scala#Boolean - * - For class Array : [T]C where C is the erased classinfo of the Array class. - * - For Array[T].<init> : {scala#Int)Array[T] - * - For a type parameter : A type bounds type consisting of the erasures of its bounds. - */ - def transformInfo(sym: Symbol, tp: Type): Type = { - if (sym == Object_asInstanceOf) - sym.info - else if (sym == Object_isInstanceOf || sym == ArrayClass) - PolyType(sym.info.typeParams, specialErasure(sym)(sym.info.resultType)) - else if (sym.isAbstractType) - TypeBounds(WildcardType, WildcardType) - else if (sym.isTerm && sym.owner == ArrayClass) { - if (sym.isClassConstructor) - tp match { - case MethodType(params, TypeRef(pre, sym1, args)) => - MethodType(cloneSymbolsAndModify(params, specialErasure(sym)), - typeRef(specialErasure(sym)(pre), sym1, args)) - } - else if (sym.name == nme.apply) - tp - else if (sym.name == nme.update) - (tp: @unchecked) match { - case MethodType(List(index, tvar), restpe) => - MethodType(List(index.cloneSymbol.setInfo(specialErasure(sym)(index.tpe)), tvar), - erasedTypeRef(UnitClass)) - } - else specialErasure(sym)(tp) - } else if ( - sym.owner != NoSymbol && - sym.owner.owner == ArrayClass && - sym == Array_update.paramss.head(1)) { - // special case for Array.update: the non-erased type remains, i.e. (Int,A)Unit - // since the erasure type map gets applied to every symbol, we have to catch the - // symbol here - tp - } else { - specialErasure(sym)(tp) - } - } -} diff --git a/src/compiler/scala/reflect/internal/transform/RefChecks.scala b/src/compiler/scala/reflect/internal/transform/RefChecks.scala deleted file mode 100644 index d6108ab665..0000000000 --- a/src/compiler/scala/reflect/internal/transform/RefChecks.scala +++ /dev/null @@ -1,13 +0,0 @@ -package scala.reflect -package internal -package transform - -trait RefChecks { - - val global: SymbolTable - import global._ - - def transformInfo(sym: Symbol, tp: Type): Type = - if (sym.isModule && !sym.isStatic) NullaryMethodType(tp) - else tp -}
\ No newline at end of file diff --git a/src/compiler/scala/reflect/internal/transform/Transforms.scala b/src/compiler/scala/reflect/internal/transform/Transforms.scala deleted file mode 100644 index c4c5dc3a1c..0000000000 --- a/src/compiler/scala/reflect/internal/transform/Transforms.scala +++ /dev/null @@ -1,41 +0,0 @@ -package scala.reflect -package internal -package transform - -import language.existentials - -trait Transforms { self: SymbolTable => - - /** 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)) - -}
\ No newline at end of file diff --git a/src/compiler/scala/reflect/internal/transform/UnCurry.scala b/src/compiler/scala/reflect/internal/transform/UnCurry.scala deleted file mode 100644 index 0c1640ceb9..0000000000 --- a/src/compiler/scala/reflect/internal/transform/UnCurry.scala +++ /dev/null @@ -1,64 +0,0 @@ -package scala.reflect -package internal -package transform - -import Flags._ - -trait UnCurry { - - val global: SymbolTable - import global._ - import definitions._ - - private def expandAlias(tp: Type): Type = if (!tp.isHigherKinded) tp.normalize else tp - - val uncurry: TypeMap = new TypeMap { - def apply(tp0: Type): Type = { - val tp = expandAlias(tp0) - tp match { - case MethodType(params, MethodType(params1, restpe)) => - apply(MethodType(params ::: params1, restpe)) - case MethodType(params, ExistentialType(tparams, restpe @ MethodType(_, _))) => - assert(false, "unexpected curried method types with intervening existential") - tp0 - case MethodType(h :: t, restpe) if h.isImplicit => - apply(MethodType(h.cloneSymbol.resetFlag(IMPLICIT) :: t, restpe)) - case NullaryMethodType(restpe) => - apply(MethodType(List(), restpe)) - case TypeRef(pre, ByNameParamClass, arg :: Nil) => - apply(functionType(List(), arg)) - case TypeRef(pre, RepeatedParamClass, arg :: Nil) => - apply(seqType(arg)) - case TypeRef(pre, JavaRepeatedParamClass, arg :: Nil) => - apply(arrayType( - if (isUnboundedGeneric(arg)) ObjectClass.tpe else arg)) - case _ => - expandAlias(mapOver(tp)) - } - } - } - - private val uncurryType = new TypeMap { - def apply(tp0: Type): Type = { - val tp = expandAlias(tp0) - tp match { - case ClassInfoType(parents, decls, clazz) => - val parents1 = parents mapConserve uncurry - if (parents1 eq parents) tp - else ClassInfoType(parents1, decls, clazz) // @MAT normalize in decls?? - case PolyType(_, _) => - mapOver(tp) - case _ => - tp - } - } - } - - /** - return symbol's transformed type, - * - if symbol is a def parameter with transformed type T, return () => T - * - * @MAT: starting with this phase, the info of every symbol will be normalized - */ - def transformInfo(sym: Symbol, tp: Type): Type = - if (sym.isType) uncurryType(tp) else uncurry(tp) -}
\ No newline at end of file diff --git a/src/compiler/scala/reflect/internal/util/Collections.scala b/src/compiler/scala/reflect/internal/util/Collections.scala deleted file mode 100644 index 1f8eb15c90..0000000000 --- a/src/compiler/scala/reflect/internal/util/Collections.scala +++ /dev/null @@ -1,213 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Paul Phillips - */ - -package scala.reflect.internal.util - -import scala.collection.{ mutable, immutable } -import scala.annotation.tailrec -import mutable.ListBuffer - -/** Profiler driven changes. - * TODO - inlining doesn't work from here because of the bug that - * methods in traits aren't inlined. - */ -trait Collections { - /** True if all three arguments have the same number of elements and - * the function is true for all the triples. - */ - @tailrec final def corresponds3[A, B, C](xs1: List[A], xs2: List[B], xs3: List[C]) - (f: (A, B, C) => Boolean): Boolean = ( - if (xs1.isEmpty) xs2.isEmpty && xs3.isEmpty - else !xs2.isEmpty && !xs3.isEmpty && f(xs1.head, xs2.head, xs3.head) && corresponds3(xs1.tail, xs2.tail, xs3.tail)(f) - ) - - /** All these mm methods are "deep map" style methods for - * mapping etc. on a list of lists while avoiding unnecessary - * intermediate structures like those created via flatten. - */ - final def mexists[A](xss: List[List[A]])(p: A => Boolean) = - xss exists (_ exists p) - final def mforall[A](xss: List[List[A]])(p: A => Boolean) = - xss forall (_ forall p) - final def mmap[A, B](xss: List[List[A]])(f: A => B) = - xss map (_ map f) - final def mforeach[A](xss: List[List[A]])(f: A => Unit) = - xss foreach (_ foreach f) - final def mfind[A](xss: List[List[A]])(p: A => Boolean): Option[A] = { - var res: Option[A] = null - mforeach(xss)(x => if ((res eq null) && p(x)) res = Some(x)) - if (res eq null) None else res - } - final def mfilter[A](xss: List[List[A]])(p: A => Boolean) = - for (xs <- xss; x <- xs; if p(x)) yield x - - final def map2[A, B, C](xs1: List[A], xs2: List[B])(f: (A, B) => C): List[C] = { - val lb = new ListBuffer[C] - var ys1 = xs1 - var ys2 = xs2 - while (!ys1.isEmpty && !ys2.isEmpty) { - lb += f(ys1.head, ys2.head) - ys1 = ys1.tail - ys2 = ys2.tail - } - lb.toList - } - final def map3[A, B, C, D](xs1: List[A], xs2: List[B], xs3: List[C])(f: (A, B, C) => D): List[D] = { - if (xs1.isEmpty || xs2.isEmpty || xs3.isEmpty) Nil - else f(xs1.head, xs2.head, xs3.head) :: map3(xs1.tail, xs2.tail, xs3.tail)(f) - } - final def flatMap2[A, B, C](xs1: List[A], xs2: List[B])(f: (A, B) => List[C]): List[C] = { - val lb = new ListBuffer[C] - var ys1 = xs1 - var ys2 = xs2 - while (!ys1.isEmpty && !ys2.isEmpty) { - lb ++= f(ys1.head, ys2.head) - ys1 = ys1.tail - ys2 = ys2.tail - } - lb.toList - } - - final def flatCollect[A, B](elems: List[A])(pf: PartialFunction[A, Traversable[B]]): List[B] = { - val lb = new ListBuffer[B] - for (x <- elems ; if pf isDefinedAt x) - lb ++= pf(x) - - lb.toList - } - - final def distinctBy[A, B](xs: List[A])(f: A => B): List[A] = { - val buf = new ListBuffer[A] - val seen = mutable.Set[B]() - xs foreach { x => - val y = f(x) - if (!seen(y)) { - buf += x - seen += y - } - } - buf.toList - } - - @tailrec final def flattensToEmpty(xss: Seq[Seq[_]]): Boolean = { - xss.isEmpty || xss.head.isEmpty && flattensToEmpty(xss.tail) - } - - final def foreachWithIndex[A, B](xs: List[A])(f: (A, Int) => Unit) { - var index = 0 - var ys = xs - while (!ys.isEmpty) { - f(ys.head, index) - ys = ys.tail - index += 1 - } - } - - // @inline - final def findOrElse[A](xs: TraversableOnce[A])(p: A => Boolean)(orElse: => A): A = { - xs find p getOrElse orElse - } - - final def mapFrom[A, A1 >: A, B](xs: List[A])(f: A => B): Map[A1, B] = { - Map[A1, B](xs map (x => (x, f(x))): _*) - } - - final def mapWithIndex[A, B](xs: List[A])(f: (A, Int) => B): List[B] = { - val lb = new ListBuffer[B] - var index = 0 - var ys = xs - while (!ys.isEmpty) { - lb += f(ys.head, index) - ys = ys.tail - index += 1 - } - lb.toList - } - final def collectMap2[A, B, C](xs1: List[A], xs2: List[B])(p: (A, B) => Boolean): Map[A, B] = { - if (xs1.isEmpty || xs2.isEmpty) - return Map() - - val buf = immutable.Map.newBuilder[A, B] - var ys1 = xs1 - var ys2 = xs2 - while (!ys1.isEmpty && !ys2.isEmpty) { - val x1 = ys1.head - val x2 = ys2.head - if (p(x1, x2)) - buf += ((x1, x2)) - - ys1 = ys1.tail - ys2 = ys2.tail - } - buf.result - } - final def foreach2[A, B](xs1: List[A], xs2: List[B])(f: (A, B) => Unit): Unit = { - var ys1 = xs1 - var ys2 = xs2 - while (!ys1.isEmpty && !ys2.isEmpty) { - f(ys1.head, ys2.head) - ys1 = ys1.tail - ys2 = ys2.tail - } - } - final def foreach3[A, B, C](xs1: List[A], xs2: List[B], xs3: List[C])(f: (A, B, C) => Unit): Unit = { - var ys1 = xs1 - var ys2 = xs2 - var ys3 = xs3 - while (!ys1.isEmpty && !ys2.isEmpty && !ys3.isEmpty) { - f(ys1.head, ys2.head, ys3.head) - ys1 = ys1.tail - ys2 = ys2.tail - ys3 = ys3.tail - } - } - final def exists2[A, B](xs1: List[A], xs2: List[B])(f: (A, B) => Boolean): Boolean = { - var ys1 = xs1 - var ys2 = xs2 - while (!ys1.isEmpty && !ys2.isEmpty) { - if (f(ys1.head, ys2.head)) - return true - - ys1 = ys1.tail - ys2 = ys2.tail - } - false - } - final def forall2[A, B](xs1: List[A], xs2: List[B])(f: (A, B) => Boolean): Boolean = { - var ys1 = xs1 - var ys2 = xs2 - while (!ys1.isEmpty && !ys2.isEmpty) { - if (!f(ys1.head, ys2.head)) - return false - - ys1 = ys1.tail - ys2 = ys2.tail - } - true - } - final def forall3[A, B, C](xs1: List[A], xs2: List[B], xs3: List[C])(f: (A, B, C) => Boolean): Boolean = { - var ys1 = xs1 - var ys2 = xs2 - var ys3 = xs3 - while (!ys1.isEmpty && !ys2.isEmpty && !ys3.isEmpty) { - if (!f(ys1.head, ys2.head, ys3.head)) - return false - - ys1 = ys1.tail - ys2 = ys2.tail - ys3 = ys3.tail - } - true - } - - final def transposeSafe[A](ass: List[List[A]]): Option[List[List[A]]] = try { - Some(ass.transpose) - } catch { - case _: IllegalArgumentException => None - } -} - -object Collections extends Collections { } - diff --git a/src/compiler/scala/reflect/internal/util/HashSet.scala b/src/compiler/scala/reflect/internal/util/HashSet.scala deleted file mode 100644 index a771dad2b0..0000000000 --- a/src/compiler/scala/reflect/internal/util/HashSet.scala +++ /dev/null @@ -1,106 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - -package scala.reflect.internal.util - -object HashSet { - def apply[T >: Null <: AnyRef](): HashSet[T] = this(16) - def apply[T >: Null <: AnyRef](label: String): HashSet[T] = this(label, 16) - def apply[T >: Null <: AnyRef](initialCapacity: Int): HashSet[T] = this("No Label", initialCapacity) - def apply[T >: Null <: AnyRef](label: String, initialCapacity: Int): HashSet[T] = - new HashSet[T](label, initialCapacity) -} - -class HashSet[T >: Null <: AnyRef](val label: String, initialCapacity: Int) extends Set[T] { - private var used = 0 - private var table = new Array[AnyRef](initialCapacity) - private def index(x: Int): Int = math.abs(x % table.length) - - def size: Int = used - def clear() { - used = 0 - table = new Array[AnyRef](initialCapacity) - } - - def findEntryOrUpdate(x: T): T = { - var h = index(x.##) - var entry = table(h) - while (entry ne null) { - if (x == entry) - return entry.asInstanceOf[T] - - h = index(h + 1) - entry = table(h) - } - table(h) = x - used += 1 - if (used > (table.length >> 2)) growTable() - x - } - - def findEntry(x: T): T = { - var h = index(x.##) - var entry = table(h) - while ((entry ne null) && x != entry) { - h = index(h + 1) - entry = table(h) - } - entry.asInstanceOf[T] - } - - def addEntry(x: T) { - var h = index(x.##) - var entry = table(h) - while (entry ne null) { - if (x == entry) return - h = index(h + 1) - entry = table(h) - } - table(h) = x - used += 1 - if (used > (table.length >> 2)) growTable() - } - def addEntries(xs: TraversableOnce[T]) { - xs foreach addEntry - } - - def iterator = new Iterator[T] { - private var i = 0 - def hasNext: Boolean = { - while (i < table.length && (table(i) eq null)) i += 1 - i < table.length - } - def next(): T = - if (hasNext) { i += 1; table(i - 1).asInstanceOf[T] } - else null - } - - private def addOldEntry(x: T) { - var h = index(x.##) - var entry = table(h) - while (entry ne null) { - h = index(h + 1) - entry = table(h) - } - table(h) = x - } - - private def growTable() { - val oldtable = table - val growthFactor = - if (table.length <= initialCapacity) 8 - else if (table.length <= (initialCapacity * 8)) 4 - else 2 - - table = new Array[AnyRef](table.length * growthFactor) - var i = 0 - while (i < oldtable.length) { - val entry = oldtable(i) - if (entry ne null) addOldEntry(entry.asInstanceOf[T]) - i += 1 - } - } - override def toString() = "HashSet %s(%d / %d)".format(label, used, table.length) -} diff --git a/src/compiler/scala/reflect/internal/util/Origins.scala b/src/compiler/scala/reflect/internal/util/Origins.scala deleted file mode 100644 index 0bd5ad55ca..0000000000 --- a/src/compiler/scala/reflect/internal/util/Origins.scala +++ /dev/null @@ -1,119 +0,0 @@ -/* NSC -- new scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Paul Phillips - */ - -package scala.reflect -package internal.util - -import NameTransformer._ -import scala.collection.{ mutable, immutable } -import Origins._ - -/** A debugging class for logging from whence a method is being called. - * Say you wanted to discover who was calling phase_= in SymbolTable. - * You could do this: - * - * {{{ - * private lazy val origins = Origins("arbitraryTag") - * // Commented out original enclosed for contrast - * // final def phase_=(p: Phase): Unit = { - * final def phase_=(p: Phase): Unit = origins { - * }}} - * - * And that's it. When the JVM exits it would issue a report something like this: - {{{ - >> Origins tag 'arbitraryTag' logged 145585 calls from 51 distinguished sources. - - 71114 scala.tools.nsc.symtab.Symbols$Symbol.unsafeTypeParams(Symbols.scala:862) - 16584 scala.tools.nsc.symtab.Symbols$Symbol.rawInfo(Symbols.scala:757) - 15411 scala.tools.nsc.symtab.Symbols$Symbol.unsafeTypeParams(Symbols.scala:869) - 11507 scala.tools.nsc.symtab.Symbols$Symbol.rawInfo(Symbols.scala:770) - 10285 scala.tools.nsc.symtab.Symbols$Symbol.unsafeTypeParams(Symbols.scala:864) - 6860 scala.tools.nsc.transform.SpecializeTypes.specializedTypeVars(SpecializeTypes.scala:304) - ... - }}} - * - */ -abstract class Origins { - type Rep - type StackSlice = Array[StackTraceElement] - - def tag: String - def isCutoff(el: StackTraceElement): Boolean - def newRep(xs: StackSlice): Rep - def repString(rep: Rep): String - - private val origins = new mutable.HashMap[Rep, Int] withDefaultValue 0 - private def add(xs: Rep) = origins(xs) += 1 - private def total = origins.values.foldLeft(0L)(_ + _) - - // Create a stack and whittle it down to the interesting part. - def readStack(): Array[StackTraceElement] = ( - Thread.currentThread.getStackTrace dropWhile (x => !isCutoff(x)) dropWhile isCutoff drop 1 - ) - - def apply[T](body: => T): T = { - add(newRep(readStack())) - body - } - def clear() = origins.clear() - def show() = { - println("\n>> Origins tag '%s' logged %s calls from %s distinguished sources.\n".format(tag, total, origins.keys.size)) - origins.toList sortBy (-_._2) foreach { - case (k, v) => println("%7s %s".format(v, repString(k))) - } - } - def purge() = { - show() - clear() - } -} - -object Origins { - private val counters = mutable.HashMap[String, Origins]() - private val thisClass = this.getClass.getName - - locally { - sys.addShutdownHook(counters.values foreach (_.purge())) - } - - case class OriginId(className: String, methodName: String) { - def matches(el: StackTraceElement) = ( - (methodName == el.getMethodName) && (className startsWith el.getClassName) - ) - } - - def lookup(tag: String, orElse: String => Origins): Origins = - counters.getOrElseUpdate(tag, orElse(tag)) - def register(x: Origins): Origins = { - counters(x.tag) = x - x - } - - private def preCutoff(el: StackTraceElement) = ( - (el.getClassName == thisClass) - || (el.getClassName startsWith "java.lang.") - ) - private def findCutoff() = { - val cutoff = Thread.currentThread.getStackTrace dropWhile preCutoff head; - OriginId(cutoff.getClassName, cutoff.getMethodName) - } - - def apply(tag: String): Origins = counters.getOrElseUpdate(tag, new OneLine(tag, findCutoff())) - def apply(tag: String, frames: Int): Origins = counters.getOrElseUpdate(tag, new MultiLine(tag, findCutoff(), frames)) - - class OneLine(val tag: String, id: OriginId) extends Origins { - type Rep = StackTraceElement - def isCutoff(el: StackTraceElement) = id matches el - def newRep(xs: StackSlice): Rep = if ((xs eq null) || (xs.length == 0)) null else xs(0) - def repString(rep: Rep) = " " + rep - } - class MultiLine(val tag: String, id: OriginId, numLines: Int) extends Origins { - type Rep = List[StackTraceElement] - def isCutoff(el: StackTraceElement) = id matches el - def newRep(xs: StackSlice): Rep = (xs take numLines).toList - def repString(rep: Rep) = rep.map("\n " + _).mkString - override def readStack() = super.readStack() drop 1 - } -} diff --git a/src/compiler/scala/reflect/internal/util/Position.scala b/src/compiler/scala/reflect/internal/util/Position.scala deleted file mode 100644 index 3c251b3b31..0000000000 --- a/src/compiler/scala/reflect/internal/util/Position.scala +++ /dev/null @@ -1,277 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - * - */ - -package scala.reflect.internal.util - -import reflect.ClassTag -import reflect.base.Attachments -import reflect.api.PositionApi - -object Position { - val tabInc = 8 - - /** Prints the message with the given position indication. */ - def formatMessage(posIn: Position, msg: String, shortenFile: Boolean): String = { - val pos = ( - if (posIn eq null) NoPosition - else if (posIn.isDefined) posIn.inUltimateSource(posIn.source) - else posIn - ) - def file = pos.source.file - def prefix = if (shortenFile) file.name else file.path - - pos match { - case FakePos(fmsg) => fmsg+" "+msg - case NoPosition => msg - case _ => - List( - "%s:%s: %s".format(prefix, pos.line, msg), - pos.lineContent.stripLineEnd, - " " * (pos.column - 1) + "^" - ) mkString "\n" - } - } -} - -abstract class Position extends PositionApi { self => - - type Pos = Position - - def pos: Position = this - - def withPos(newPos: Position): Attachments { type Pos = self.Pos } = newPos - - /** Java file corresponding to the source file of this position. - */ - // necessary for conformance with scala.reflect.api.Position - def fileInfo: java.io.File = source.file.file - - /** Contents of the source file that contains this position. - */ - // necessary for conformance with scala.reflect.api.Position - def fileContent: Array[Char] = source.content - - /** An optional value containing the source file referred to by this position, or - * None if not defined. - */ - def source: SourceFile = throw new UnsupportedOperationException("Position.source") - - /** Is this position neither a NoPosition nor a FakePosition? - * If isDefined is true, offset and source are both defined. - */ - def isDefined: Boolean = false - - /** Is this position a transparent position? */ - def isTransparent: Boolean = false - - /** Is this position a range position? */ - def isRange: Boolean = false - - /** Is this position a non-transparent range position? */ - def isOpaqueRange: Boolean = false - - /** if opaque range, make this position transparent */ - def makeTransparent: Position = this - - /** The start of the position's range, error if not a range position */ - def start: Int = throw new UnsupportedOperationException("Position.start") - - /** The start of the position's range, or point if not a range position */ - def startOrPoint: Int = point - - /** The point (where the ^ is) of the position */ - def point: Int = throw new UnsupportedOperationException("Position.point") - - /** The point (where the ^ is) of the position, or else `default` if undefined */ - def pointOrElse(default: Int): Int = default - - /** The end of the position's range, error if not a range position */ - def end: Int = throw new UnsupportedOperationException("Position.end") - - /** The end of the position's range, or point if not a range position */ - def endOrPoint: Int = point - - @deprecated("use point instead", "2.9.0") - def offset: Option[Int] = if (isDefined) Some(point) else None - - /** The same position with a different start value (if a range) */ - def withStart(off: Int): Position = this - - /** The same position with a different end value (if a range) */ - def withEnd(off: Int): Position = this - - /** The same position with a different point value (if a range or offset) */ - def withPoint(off: Int): Position = this - - /** The same position with a different source value, and its values shifted by given offset */ - def withSource(source: SourceFile, shift: Int): Position = this - - /** If this is a range, the union with the other range, with the point of this position. - * Otherwise, this position - */ - def union(pos: Position): Position = this - - /** If this is a range position, the offset position of its start. - * Otherwise the position itself - */ - def focusStart: Position = this - - /** If this is a range position, the offset position of its point. - * Otherwise the position itself - */ - def focus: Position = this - - /** If this is a range position, the offset position of its end. - * Otherwise the position itself - */ - def focusEnd: Position = this - - /** Does this position include the given position `pos`. - * This holds if `this` is a range position and its range [start..end] - * is the same or covers the range of the given position, which may or may not be a range position. - */ - def includes(pos: Position): Boolean = false - - /** Does this position properly include the given position `pos` ("properly" meaning their - * ranges are not the same)? - */ - def properlyIncludes(pos: Position): Boolean = - includes(pos) && (start < pos.startOrPoint || pos.endOrPoint < end) - - /** Does this position precede that position? - * This holds if both positions are defined and the end point of this position - * is not larger than the start point of the given position. - */ - def precedes(pos: Position): Boolean = - isDefined && pos.isDefined && endOrPoint <= pos.startOrPoint - - /** Does this position properly precede the given position `pos` ("properly" meaning their ranges - * do not share a common point). - */ - def properlyPrecedes(pos: Position): Boolean = - isDefined && pos.isDefined && endOrPoint < pos.startOrPoint - - /** Does this position overlap with that position? - * This holds if both positions are ranges and there is an interval of - * non-zero length that is shared by both position ranges. - */ - def overlaps(pos: Position): Boolean = - isRange && pos.isRange && - ((pos.start < end && start < pos.end) || (start < pos.end && pos.start < end)) - - /** Does this position cover the same range as that position? - * Holds only if both position are ranges - */ - def sameRange(pos: Position): Boolean = - isRange && pos.isRange && start == pos.start && end == pos.end - - def line: Int = throw new UnsupportedOperationException("Position.line") - - def column: Int = throw new UnsupportedOperationException("Position.column") - - /** Convert this to a position around `point` that spans a single source line */ - def toSingleLine: Position = this - - def lineContent: String = - if (isDefined) source.lineToString(line - 1) - else "NO_LINE" - - /** Map this position to a position in an original source - * file. If the SourceFile is a normal SourceFile, simply - * return this. - */ - def inUltimateSource(source : SourceFile): Position = - if (source == null) this else source.positionInUltimateSource(this) - - def dbgString: String = toString - def safeLine: Int = try line catch { case _: UnsupportedOperationException => -1 } - - def show: String = "["+toString+"]" -} - -case object NoPosition extends Position { - override def dbgString = toString -} - -case class FakePos(msg: String) extends Position { - override def toString = msg -} - -class OffsetPosition(override val source: SourceFile, override val point: Int) extends Position { - override def isDefined = true - override def pointOrElse(default: Int): Int = point - override def withPoint(off: Int) = new OffsetPosition(source, off) - override def withSource(source: SourceFile, shift: Int) = new OffsetPosition(source, point + shift) - - override def line: Int = source.offsetToLine(point) + 1 - - override def column: Int = { - var idx = source.lineToOffset(source.offsetToLine(point)) - var col = 0 - while (idx != point) { - col += (if (source.content(idx) == '\t') Position.tabInc - col % Position.tabInc else 1) - idx += 1 - } - col + 1 - } - - override def union(pos: Position) = if (pos.isRange) pos else this - - override def equals(that : Any) = that match { - case that : OffsetPosition => point == that.point && source.file == that.source.file - case that => false - } - override def hashCode = point * 37 + source.file.hashCode - - override def toString = { - val pointmsg = if (point > source.length) "out-of-bounds-" else "offset=" - "source-%s,line-%s,%s%s".format(source.file.canonicalPath, line, pointmsg, point) - } - override def show = "["+point+"]" -} - -/** new for position ranges */ -class RangePosition(source: SourceFile, override val start: Int, point: Int, override val end: Int) -extends OffsetPosition(source, point) { - if (start > end) assert(false, "bad position: "+show) - override def isRange: Boolean = true - override def isOpaqueRange: Boolean = true - override def startOrPoint: Int = start - override def endOrPoint: Int = end - override def withStart(off: Int) = new RangePosition(source, off, point, end) - override def withEnd(off: Int) = new RangePosition(source, start, point, off) - override def withPoint(off: Int) = new RangePosition(source, start, off, end) - override def withSource(source: SourceFile, shift: Int) = new RangePosition(source, start + shift, point + shift, end + shift) - override def focusStart = new OffsetPosition(source, start) - override def focus = { - if (focusCache eq NoPosition) focusCache = new OffsetPosition(source, point) - focusCache - } - override def focusEnd = new OffsetPosition(source, end) - override def makeTransparent = new TransparentPosition(source, start, point, end) - override def includes(pos: Position) = pos.isDefined && start <= pos.startOrPoint && pos.endOrPoint <= end - override def union(pos: Position): Position = - if (pos.isRange) new RangePosition(source, start min pos.start, point, end max pos.end) else this - - override def toSingleLine: Position = source match { - case bs: BatchSourceFile - if end > 0 && bs.offsetToLine(start) < bs.offsetToLine(end - 1) => - val pointLine = bs.offsetToLine(point) - new RangePosition(source, bs.lineToOffset(pointLine), point, bs.lineToOffset(pointLine + 1)) - case _ => this - } - - override def toString = "RangePosition("+source.file.canonicalPath+", "+start+", "+point+", "+end+")" - override def show = "["+start+":"+end+"]" - private var focusCache: Position = NoPosition -} - -class TransparentPosition(source: SourceFile, start: Int, point: Int, end: Int) extends RangePosition(source, start, point, end) { - override def isOpaqueRange: Boolean = false - override def isTransparent = true - override def makeTransparent = this - override def show = "<"+start+":"+end+">" -}
\ No newline at end of file diff --git a/src/compiler/scala/reflect/internal/util/Set.scala b/src/compiler/scala/reflect/internal/util/Set.scala deleted file mode 100644 index cfc3e7eada..0000000000 --- a/src/compiler/scala/reflect/internal/util/Set.scala +++ /dev/null @@ -1,28 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ -package scala.reflect.internal.util - -/** A common class for lightweight sets. - */ -abstract class Set[T <: AnyRef] { - - def findEntry(x: T): T - - def addEntry(x: T): Unit - - def iterator: Iterator[T] - - def foreach[U](f: T => U): Unit = iterator foreach f - - def apply(x: T): Boolean = contains(x) - - @deprecated("use `iterator` instead", "2.9.0") def elements = iterator - - def contains(x: T): Boolean = - findEntry(x) ne null - - def toList = iterator.toList - -} diff --git a/src/compiler/scala/reflect/internal/util/SourceFile.scala b/src/compiler/scala/reflect/internal/util/SourceFile.scala deleted file mode 100644 index 7c80ddd37d..0000000000 --- a/src/compiler/scala/reflect/internal/util/SourceFile.scala +++ /dev/null @@ -1,161 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - - -package scala.reflect.internal.util - -import scala.tools.nsc.io.{ AbstractFile, VirtualFile } -import scala.collection.mutable.ArrayBuffer -import annotation.tailrec -import java.util.regex.Pattern -import java.io.IOException -import scala.reflect.internal.Chars._ - -/** abstract base class of a source file used in the compiler */ -abstract class SourceFile { - def content : Array[Char] // normalized, must end in SU - def file : AbstractFile - def isLineBreak(idx : Int) : Boolean - def isSelfContained: Boolean - def length : Int - def position(offset: Int) : Position = { - assert(offset < length, file + ": " + offset + " >= " + length) - new OffsetPosition(this, offset) - } - def position(line: Int, column: Int) : Position = new OffsetPosition(this, lineToOffset(line) + column) - - def offsetToLine(offset: Int): Int - def lineToOffset(index : Int): Int - - /** Map a position to a position in the underlying source file. - * For regular source files, simply return the argument. - */ - def positionInUltimateSource(position: Position) = position - override def toString() = file.name - def dbg(offset: Int) = (new OffsetPosition(this, offset)).dbgString - def path = file.path - - def beginsWith(offset: Int, text: String): Boolean = - (content drop offset) startsWith text - - def lineToString(index: Int): String = - content drop lineToOffset(index) takeWhile (c => !isLineBreakChar(c.toChar)) mkString - - @tailrec - final def skipWhitespace(offset: Int): Int = - if (content(offset).isWhitespace) skipWhitespace(offset + 1) else offset - - def identifier(pos: Position): Option[String] = None -} - -/** An object representing a missing source file. - */ -object NoSourceFile extends SourceFile { - def content = Array() - def file = NoFile - def isLineBreak(idx: Int) = false - def isSelfContained = true - def length = -1 - def offsetToLine(offset: Int) = -1 - def lineToOffset(index : Int) = -1 - override def toString = "<no source file>" -} - -object NoFile extends VirtualFile("<no file>", "<no file>") - -object ScriptSourceFile { - /** Length of the script header from the given content, if there is one. - * The header begins with "#!" or "::#!" and ends with a line starting - * with "!#" or "::!#". - */ - def headerLength(cs: Array[Char]): Int = { - val headerPattern = Pattern.compile("""((?m)^(::)?!#.*|^.*/env .*)(\r|\n|\r\n)""") - val headerStarts = List("#!", "::#!") - - if (headerStarts exists (cs startsWith _)) { - val matcher = headerPattern matcher cs.mkString - if (matcher.find) matcher.end - else throw new IOException("script file does not close its header with !# or ::!#") - } - else 0 - } - def stripHeader(cs: Array[Char]): Array[Char] = cs drop headerLength(cs) - - def apply(file: AbstractFile, content: Array[Char]) = { - val underlying = new BatchSourceFile(file, content) - val headerLen = headerLength(content) - val stripped = new ScriptSourceFile(underlying, content drop headerLen, headerLen) - - stripped - } -} -import ScriptSourceFile._ - -class ScriptSourceFile(underlying: BatchSourceFile, content: Array[Char], override val start: Int) extends BatchSourceFile(underlying.file, content) { - override def isSelfContained = false - - override def positionInUltimateSource(pos: Position) = - if (!pos.isDefined) super.positionInUltimateSource(pos) - else new OffsetPosition(underlying, pos.point + start) -} - -/** a file whose contents do not change over time */ -class BatchSourceFile(val file : AbstractFile, val content: Array[Char]) extends SourceFile { - - def this(_file: AbstractFile) = this(_file, _file.toCharArray) - def this(sourceName: String, cs: Seq[Char]) = this(new VirtualFile(sourceName), cs.toArray) - def this(file: AbstractFile, cs: Seq[Char]) = this(file, cs.toArray) - - override def equals(that : Any) = that match { - case that : BatchSourceFile => file.path == that.file.path && start == that.start - case _ => false - } - override def hashCode = file.path.## + start.## - val length = content.length - def start = 0 - def isSelfContained = true - - override def identifier(pos: Position) = - if (pos.isDefined && pos.source == this && pos.point != -1) { - def isOK(c: Char) = isIdentifierPart(c) || isOperatorPart(c) - Some(new String(content drop pos.point takeWhile isOK)) - } else { - super.identifier(pos) - } - - def isLineBreak(idx: Int) = - if (idx >= length) false else { - val ch = content(idx) - // don't identify the CR in CR LF as a line break, since LF will do. - if (ch == CR) (idx + 1 == length) || (content(idx + 1) != LF) - else isLineBreakChar(ch) - } - - def calculateLineIndices(cs: Array[Char]) = { - val buf = new ArrayBuffer[Int] - buf += 0 - for (i <- 0 until cs.length) if (isLineBreak(i)) buf += i + 1 - buf += cs.length // sentinel, so that findLine below works smoother - buf.toArray - } - private lazy val lineIndices: Array[Int] = calculateLineIndices(content) - - def lineToOffset(index : Int): Int = lineIndices(index) - - private var lastLine = 0 - - /** Convert offset to line in this source file - * Lines are numbered from 0 - */ - def offsetToLine(offset: Int): Int = { - val lines = lineIndices - def findLine(lo: Int, hi: Int, mid: Int): Int = - if (offset < lines(mid)) findLine(lo, mid - 1, (lo + mid - 1) / 2) - else if (offset >= lines(mid + 1)) findLine(mid + 1, hi, (mid + 1 + hi) / 2) - else mid - lastLine = findLine(0, lines.length, lastLine) - lastLine - } -} diff --git a/src/compiler/scala/reflect/internal/util/StatBase.scala b/src/compiler/scala/reflect/internal/util/StatBase.scala deleted file mode 100644 index b033ff98bc..0000000000 --- a/src/compiler/scala/reflect/internal/util/StatBase.scala +++ /dev/null @@ -1,97 +0,0 @@ -package scala.reflect.internal.util - -class StatBase { - - private var _enabled = false - - def enabled = _enabled - def enabled_=(cond: Boolean) = { - if (cond && !_enabled) { - val test = new Timer() - val start = System.nanoTime() - var total = 0L - for (i <- 1 to 10000) { - val time = System.nanoTime() - total += System.nanoTime() - time - } - val total2 = System.nanoTime() - start - println("Enabling statistics, measuring overhead = "+ - total/10000.0+"ns to "+total2/10000.0+"ns per timer") - _enabled = true - } - } - - def currentTime() = - if (_enabled) System.nanoTime() else 0L - - def showPercent(x: Double, base: Double) = - if (base == 0) "" else " ("+"%2.1f".format(x / base * 100)+"%)" - - def incCounter(c: Counter) { - if (_enabled) c.value += 1 - } - - def incCounter(c: Counter, delta: Int) { - if (_enabled) c.value += delta - } - - def startCounter(sc: SubCounter): IntPair = - if (_enabled) sc.start() else null - - def stopCounter(sc: SubCounter, start: IntPair) { - if (_enabled) sc.stop(start) - } - - def startTimer(tm: Timer): LongPair = - if (_enabled) tm.start() else null - - def stopTimer(tm: Timer, start: LongPair) { - if (_enabled) tm.stop(start) - } - - case class IntPair(x: Int, y: Int) - case class LongPair(x: Long, y: Long) - - class Counter { - var value: Int = 0 - override def toString = value.toString - } - - class SubCounter(c: Counter) { - var value: Int = 0 - def start(): IntPair = - if (_enabled) IntPair(value, c.value) else null - def stop(prev: IntPair) { - if (_enabled) { - val IntPair(value0, cvalue0) = prev - value = value0 + c.value - cvalue0 - } - } - override def toString = - value+showPercent(value, c.value) - } - - class Timer { - var nanos: Long = 0 - var timings = 0 - def start(): LongPair = - if (_enabled) { - timings += 1 - LongPair(nanos, System.nanoTime()) - } else null - def stop(prev: LongPair) { - if (_enabled) { - val LongPair(nanos0, start) = prev - nanos = nanos0 + System.nanoTime() - start - timings += 1 - } - } - override def toString = (timings/2)+" spans, "+nanos.toString+"ns" - } - - import Predef.Class - - class ClassCounts extends scala.collection.mutable.HashMap[Class[_], Int] { - override def default(key: Class[_]) = 0 - } -}
\ No newline at end of file diff --git a/src/compiler/scala/reflect/internal/util/Statistics.scala b/src/compiler/scala/reflect/internal/util/Statistics.scala deleted file mode 100644 index ef17327fda..0000000000 --- a/src/compiler/scala/reflect/internal/util/Statistics.scala +++ /dev/null @@ -1,34 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ -package scala.reflect.internal.util - -class Statistics extends StatBase { - val singletonBaseTypeSeqCount = new Counter - val compoundBaseTypeSeqCount = new Counter - val typerefBaseTypeSeqCount = new Counter - val findMemberCount = new Counter - val noMemberCount = new Counter - val multMemberCount = new Counter - val findMemberNanos = new Timer - val asSeenFromCount = new Counter - val asSeenFromNanos = new Timer - val subtypeCount = new Counter - val subtypeNanos = new Timer - val sametypeCount = new Counter - val rawTypeCount = new Counter - val rawTypeFailed = new SubCounter(rawTypeCount) - val findMemberFailed = new SubCounter(findMemberCount) - val subtypeFailed = new SubCounter(subtypeCount) - val rawTypeImpl = new SubCounter(rawTypeCount) - val findMemberImpl = new SubCounter(findMemberCount) - val subtypeImpl = new SubCounter(subtypeCount) - val baseTypeSeqCount = new Counter - val baseTypeSeqLenTotal = new Counter - val typeSymbolCount = new Counter - val classSymbolCount = new Counter -} - -object Statistics extends Statistics - diff --git a/src/compiler/scala/reflect/internal/util/StringOps.scala b/src/compiler/scala/reflect/internal/util/StringOps.scala deleted file mode 100644 index 281ade8134..0000000000 --- a/src/compiler/scala/reflect/internal/util/StringOps.scala +++ /dev/null @@ -1,99 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - -package scala.reflect.internal.util - -/** This object provides utility methods to extract elements - * from Strings. - * - * @author Martin Odersky - * @version 1.0 - */ -trait StringOps { - def onull(s: String) = if (s == null) "" else s - def oempty(xs: String*) = xs filterNot (x => x == null || x == "") - def ojoin(xs: String*): String = oempty(xs: _*) mkString " " - def ojoin(xs: Seq[String], sep: String): String = oempty(xs: _*) mkString sep - def ojoinOr(xs: Seq[String], sep: String, orElse: String) = { - val ys = oempty(xs: _*) - if (ys.isEmpty) orElse else ys mkString sep - } - def trimTrailingSpace(s: String) = { - if (s.length == 0 || !s.charAt(s.length - 1).isWhitespace) s - else { - var idx = s.length - 1 - while (idx >= 0 && s.charAt(idx).isWhitespace) - idx -= 1 - - s.substring(0, idx + 1) - } - } - - def decompose(str: String, sep: Char): List[String] = { - def ws(start: Int): List[String] = - if (start == str.length) List() - else if (str.charAt(start) == sep) ws(start + 1) - else { - val end = str.indexOf(sep, start) - if (end < 0) List(str.substring(start)) - else str.substring(start, end) :: ws(end + 1) - } - ws(0) - } - - def words(str: String): List[String] = decompose(str, ' ') - - def stripPrefixOpt(str: String, prefix: String): Option[String] = - if (str startsWith prefix) Some(str drop prefix.length) - else None - - def stripSuffixOpt(str: String, suffix: String): Option[String] = - if (str endsWith suffix) Some(str dropRight suffix.length) - else None - - def splitWhere(str: String, f: Char => Boolean, doDropIndex: Boolean = false): Option[(String, String)] = - splitAt(str, str indexWhere f, doDropIndex) - - def splitAt(str: String, idx: Int, doDropIndex: Boolean = false): Option[(String, String)] = - if (idx == -1) None - else Some((str take idx, str drop (if (doDropIndex) idx + 1 else idx))) - - /** Returns a string meaning "n elements". - * - * @param n ... - * @param elements ... - * @return ... - */ - def countElementsAsString(n: Int, elements: String): String = - n match { - case 0 => "no " + elements + "s" - case 1 => "one " + elements - case 2 => "two " + elements + "s" - case 3 => "three " + elements + "s" - case 4 => "four " + elements + "s" - case _ => "" + n + " " + elements + "s" - } - - /** Turns a count into a friendly English description if n<=4. - * - * @param n ... - * @return ... - */ - def countAsString(n: Int): String = - n match { - case 0 => "none" - case 1 => "one" - case 2 => "two" - case 3 => "three" - case 4 => "four" - case _ => "" + n - } -} - -object StringOps extends StringOps { } diff --git a/src/compiler/scala/reflect/internal/util/TableDef.scala b/src/compiler/scala/reflect/internal/util/TableDef.scala deleted file mode 100644 index d692a6d8f5..0000000000 --- a/src/compiler/scala/reflect/internal/util/TableDef.scala +++ /dev/null @@ -1,94 +0,0 @@ -package scala.reflect.internal.util - -import TableDef._ - -/** A class for representing tabular data in a way that preserves - * its inner beauty. See Exceptional for an example usage. - * One creates an instance of TableDef by defining the columns of - * the table, then uses that to create an instance of Table by - * passing in a sequence of rows. - */ -class TableDef[T](_cols: Column[T]*) { - /** These operators are about all there is to it. - * - * ~ appends a column to the table - * >> creates a right-justified column and appends it - * << creates a left-justified column and appends it - * >+ specifies a string to separate the previous column from the next. - * if none is specified, a space is used. - */ - def ~(next: Column[T]) = retThis(cols :+= next) - def >>(pair: (String, T => Any)) = this ~ Column(pair._1, pair._2, false) - def <<(pair: (String, T => Any)) = this ~ Column(pair._1, pair._2, true) - def >+(sep: String) = retThis(separators += ((cols.size - 1, sep))) - - /** Below this point should all be considered private/internal. - */ - private var cols: List[Column[T]] = _cols.toList - private var separators: Map[Int, String] = Map() - - def defaultSep(index: Int) = if (index > (cols.size - 2)) "" else " " - def sepAfter(i: Int): String = separators.getOrElse(i, defaultSep(i)) - def sepWidths = cols.indices map (i => sepAfter(i).length) - - def columns = cols - def colNames = cols map (_.name) - def colFunctions = cols map (_.f) - def colApply(el: T) = colFunctions map (f => f(el)) - def retThis(body: => Unit): this.type = { body ; this } - - class Table(val rows: Seq[T]) extends Seq[T] { - def iterator = rows.iterator - def apply(index: Int) = rows(index) - def length = rows.length - - def maxColWidth(col: Column[T]) = col.name +: (rows map col.f) map (_.toString.length) max - def specs = cols map (_ formatSpec rows) - - val colWidths = cols map maxColWidth - val rowFormat = mkFormatString(sepAfter) - val headFormat = mkFormatString(i => " " * sepWidths(i)) - val argLists = rows map colApply - - val headers = List( - headFormat.format(colNames: _*), - (colWidths, sepWidths).zipped map ((w1, w2) => "-" * w1 + " " * w2) mkString - ) - - def mkFormatString(sepf: Int => String): String = - specs.zipWithIndex map { case (c, i) => c + sepf(i) } mkString - - def pp(): Unit = allToSeq foreach println - - def toFormattedSeq = argLists map (xs => rowFormat.format(xs: _*)) - def allToSeq = headers ++ toFormattedSeq - - override def toString = allToSeq mkString "\n" - } - - def formatterFor(rows: Seq[T]): T => String = { - val formatStr = new Table(rows).rowFormat - - x => formatStr.format(colApply(x) : _*) - } - - def table(rows: Seq[T]) = new Table(rows) - - override def toString = cols.mkString("TableDef(", ", ", ")") -} - -object TableDef { - case class Column[-T](name: String, f: T => Any, left: Boolean) { - def maxWidth(elems: Seq[T]): Int = name +: (elems map f) map (_.toString.length) max - def formatSpec(elems: Seq[T]): String = { - val justify = if (left) "-" else "" - "%" + justify + maxWidth(elems) + "s" - } - override def toString = { - val justify = if (left) "<<" else ">>" - justify + "(" + name + ")" - } - } - - def apply[T](cols: Column[T]*) = new TableDef[T](cols: _*) -} diff --git a/src/compiler/scala/reflect/internal/util/TraceSymbolActivity.scala b/src/compiler/scala/reflect/internal/util/TraceSymbolActivity.scala deleted file mode 100644 index 5fbeb5f576..0000000000 --- a/src/compiler/scala/reflect/internal/util/TraceSymbolActivity.scala +++ /dev/null @@ -1,169 +0,0 @@ -package scala.reflect.internal -package util - -import scala.collection.{ mutable, immutable } -import language.postfixOps - -trait TraceSymbolActivity { - val global: SymbolTable - import global._ - - if (traceSymbolActivity && global.isCompilerUniverse) - scala.sys addShutdownHook showAllSymbols() - - private type Set[T] = scala.collection.immutable.Set[T] - private val Set = scala.collection.immutable.Set - - val allSymbols = mutable.Map[Int, Symbol]() - val allChildren = mutable.Map[Int, List[Int]]() withDefaultValue Nil - val prevOwners = mutable.Map[Int, List[(Int, Phase)]]() withDefaultValue Nil - val symsCaused = mutable.Map[Int, Int]() withDefaultValue 0 - val allTrees = mutable.Set[Tree]() - - def recordSymbolsInTree(tree: Tree) { - allTrees += tree - } - - def recordNewSymbol(sym: Symbol) { - if (sym.id > 1) { - allSymbols(sym.id) = sym - allChildren(sym.owner.id) ::= sym.id - } - } - def recordNewSymbolOwner(sym: Symbol, newOwner: Symbol) { - val sid = sym.id - val oid = sym.owner.id - val nid = newOwner.id - - prevOwners(sid) ::= (oid -> phase) - allChildren(oid) = allChildren(oid) filterNot (_ == sid) - allChildren(nid) ::= sid - } - - /** TODO. - */ - private def reachableDirectlyFromSymbol(sym: Symbol): List[Symbol] = ( - List(sym.owner, sym.alias, sym.thisSym) - ++ sym.children - ++ sym.info.parents.map(_.typeSymbol) - ++ sym.typeParams - ++ sym.paramss.flatten - ) - private def reachable[T](inputs: Traversable[T], mkSymbol: T => Symbol): Set[Symbol] = { - def loop(seen: Set[Symbol], remaining: List[Symbol]): Set[Symbol] = { - remaining match { - case Nil => seen - case head :: rest => - if ((head eq null) || (head eq NoSymbol) || seen(head)) loop(seen, rest) - else loop(seen + head, rest ++ reachableDirectlyFromSymbol(head).filterNot(seen)) - } - } - loop(immutable.Set(), inputs.toList map mkSymbol filterNot (_ eq null) distinct) - } - private def treeList(t: Tree) = { - val buf = mutable.ListBuffer[Tree]() - t foreach (buf += _) - buf.toList - } - - private def reachableFromSymbol(root: Symbol): Set[Symbol] = - reachable[Symbol](List(root, root.info.typeSymbol), x => x) - - private def reachableFromTree(tree: Tree): Set[Symbol] = - reachable[Tree](treeList(tree), _.symbol) - - private def signature(id: Int) = runBeforeErasure(allSymbols(id).defString) - - private def dashes(s: Any): String = ("" + s) map (_ => '-') - private def show(s1: Any, ss: Any*) { - println("%-12s".format(s1) +: ss mkString " ") - } - private def showHeader(s1: Any, ss: Any*) { - show(s1, ss: _*) - show(dashes(s1), ss map dashes: _*) - } - private def showSym(sym: Symbol) { - def prefix = (" " * (sym.ownerChain.length - 1)) + sym.id - try println("%s#%s %s".format(prefix, sym.accurateKindString, sym.name.decode)) - catch { - case x => println(prefix + " failed: " + x) - } - allChildren(sym.id).sorted foreach showIdAndRemove - } - private def showIdAndRemove(id: Int) { - allSymbols remove id foreach showSym - } - private def symbolStr(id: Int): String = { - if (id == 1) "NoSymbol" else { - val sym = allSymbols(id) - sym.accurateKindString + " " + sym.name.decode - } - } - private def ownerStr(id: Int): String = { - val sym = allSymbols(id) - sym.name.decode + "#" + sym.id - } - - private def freq[T, U](xs: collection.Traversable[T])(fn: T => U): List[(U, Int)] = { - val ys = xs groupBy fn mapValues (_.size) - ys.toList sortBy (-_._2) - } - - private def showMapFreq[T](xs: collection.Map[T, Traversable[_]])(showFn: T => String) { - xs.mapValues(_.size).toList.sortBy(-_._2) take 100 foreach { case (k, size) => - show(size, showFn(k)) - } - println("\n") - } - private def showFreq[T, U](xs: Traversable[T])(groupFn: T => U, showFn: U => String = (x: U) => "" + x) = { - showMapFreq(xs.toList groupBy groupFn)(showFn) - } - private lazy val findErasurePhase: Phase = { - var ph = phase - while (ph != NoPhase && ph.name != "erasure") { - ph = ph.prev - } - ph - } - private def runBeforeErasure[T](body: => T): T = atPhase(findErasurePhase)(body) - - def showAllSymbols() { - if (!traceSymbolActivity) return - allSymbols(1) = NoSymbol - - println("" + allSymbols.size + " symbols created.") - println("") - - showHeader("descendants", "symbol") - showFreq(allSymbols.values flatMap (_.ownerChain drop 1))(_.id, symbolStr) - - showHeader("children", "symbol") - showMapFreq(allChildren)(symbolStr) - - if (prevOwners.nonEmpty) { - showHeader("prev owners", "symbol") - showMapFreq(prevOwners) { k => - val owners = (((allSymbols(k).owner.id, NoPhase)) :: prevOwners(k)) map { - case (oid, NoPhase) => "-> owned by " + ownerStr(oid) - case (oid, ph) => "-> owned by %s (until %s)".format(ownerStr(oid), ph) - } - signature(k) :: owners mkString "\n " - } - } - - val nameFreq = allSymbols.values.toList groupBy (_.name) - showHeader("frequency", "%-15s".format("name"), "owners") - showMapFreq(nameFreq) { name => - "%-15s %s".format(name.decode, { - val owners = freq(nameFreq(name))(_.owner) - - "%4s owners (%s)".format( - owners.size, - owners.take(3).map({ case (k, v) => v + "/" + k }).mkString(", ") + ", ..." - ) - }) - } - - allSymbols.keys.toList.sorted foreach showIdAndRemove - } -} diff --git a/src/compiler/scala/reflect/internal/util/WeakHashSet.scala b/src/compiler/scala/reflect/internal/util/WeakHashSet.scala deleted file mode 100644 index 9882aad5e5..0000000000 --- a/src/compiler/scala/reflect/internal/util/WeakHashSet.scala +++ /dev/null @@ -1,61 +0,0 @@ -package scala.reflect.internal.util - -import scala.collection.mutable -import scala.collection.mutable.ArrayBuffer -import scala.collection.mutable.Builder -import scala.collection.mutable.SetBuilder -import scala.collection.generic.Clearable -import scala.runtime.AbstractFunction1 - -/** A bare-bones implementation of a mutable `Set` that uses weak references - * to hold the elements. - * - * This implementation offers only add/remove/test operations, - * therefore it does not fulfill the contract of Scala collection sets. - */ -class WeakHashSet[T <: AnyRef] extends AbstractFunction1[T, Boolean] with Clearable { - private val underlying = mutable.HashSet[WeakReferenceWithEquals[T]]() - - /** Add the given element to this set. */ - def +=(elem: T): this.type = { - underlying += new WeakReferenceWithEquals(elem) - this - } - - /** Remove the given element from this set. */ - def -=(elem: T): this.type = { - underlying -= new WeakReferenceWithEquals(elem) - this - } - - /** Does the given element belong to this set? */ - def contains(elem: T): Boolean = - underlying.contains(new WeakReferenceWithEquals(elem)) - - /** Does the given element belong to this set? */ - def apply(elem: T): Boolean = contains(elem) - - /** Return the number of elements in this set, including reclaimed elements. */ - def size = underlying.size - - /** Remove all elements in this set. */ - def clear() = underlying.clear() -} - -/** A WeakReference implementation that implements equals and hashCode by - * delegating to the referent. - */ -class WeakReferenceWithEquals[T <: AnyRef](ref: T) { - def get(): T = underlying.get() - - override val hashCode = ref.hashCode - - override def equals(other: Any): Boolean = other match { - case wf: WeakReferenceWithEquals[_] => - underlying.get() == wf.get() - case _ => - false - } - - private val underlying = new java.lang.ref.WeakReference(ref) -} diff --git a/src/compiler/scala/reflect/runtime/AbstractFile.scala b/src/compiler/scala/reflect/runtime/AbstractFile.scala deleted file mode 100644 index 0f88af1b0a..0000000000 --- a/src/compiler/scala/reflect/runtime/AbstractFile.scala +++ /dev/null @@ -1,7 +0,0 @@ -package scala.reflect -package runtime - -class AbstractFile(val jfile: java.io.File) extends internal.AbstractFileApi { - def path: String = jfile.getPath() - def canonicalPath: String = jfile.getCanonicalPath() -} diff --git a/src/compiler/scala/reflect/runtime/JavaMirrors.scala b/src/compiler/scala/reflect/runtime/JavaMirrors.scala deleted file mode 100644 index a8120d220a..0000000000 --- a/src/compiler/scala/reflect/runtime/JavaMirrors.scala +++ /dev/null @@ -1,981 +0,0 @@ -package scala.reflect -package runtime - -import scala.ref.WeakReference -import scala.collection.mutable.WeakHashMap - -import java.lang.{Class => jClass, Package => jPackage} -import java.lang.reflect.{ - Method => jMethod, Constructor => jConstructor, Modifier => jModifier, Field => jField, - Member => jMember, Type => jType, TypeVariable => jTypeVariable, Array => jArray, - GenericDeclaration, GenericArrayType, ParameterizedType, WildcardType, AnnotatedElement } -import java.io.IOException -import internal.MissingRequirementError -import internal.pickling.ByteCodecs -import internal.ClassfileConstants._ -import internal.pickling.UnPickler -import collection.mutable.{ HashMap, ListBuffer } -import internal.Flags._ -//import scala.tools.nsc.util.ScalaClassLoader -//import scala.tools.nsc.util.ScalaClassLoader._ -import ReflectionUtils.{singletonInstance} -import language.existentials - -trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: SymbolTable => - - private lazy val mirrors = new WeakHashMap[ClassLoader, WeakReference[JavaMirror]]() - - private def createMirror(owner: Symbol, cl: ClassLoader): Mirror = { - val jm = new JavaMirror(owner, cl) - mirrors(cl) = new WeakReference(jm) - jm.init() - jm - } - - override type Mirror = JavaMirror - - override lazy val rootMirror: Mirror = createMirror(NoSymbol, rootClassLoader) - - // overriden by ReflectGlobal - def rootClassLoader: ClassLoader = this.getClass.getClassLoader - - def init() = { - definitions.AnyValClass // force it. - - // establish root association to avoid cyclic dependency errors later - rootMirror.classToScala(classOf[java.lang.Object]).initialize - - // println("initializing definitions") - definitions.init() - } - - def runtimeMirror(cl: ClassLoader): Mirror = mirrors get cl match { - case Some(WeakReference(m)) => m - case _ => createMirror(rootMirror.RootClass, cl) - } - - /** The API of a mirror for a reflective universe */ - class JavaMirror(owner: Symbol, - /** Class loader that is a mastermind behind the reflexive mirror */ - val classLoader: ClassLoader - ) extends Roots(owner) with super.JavaMirror { wholemirror => - - val universe: self.type = self - - import definitions._ - - /** The lazy type for root. - */ - override lazy val rootLoader = new LazyType { - override def complete(sym: Symbol) = sym setInfo new LazyPackageType - } - -// ----------- Caching ------------------------------------------------------------------ - - // [Eugene++ to Martin] not weak? why? - private val classCache = new TwoWayCache[jClass[_], ClassSymbol] - private val packageCache = new TwoWayCache[Package, ModuleSymbol] - private val methodCache = new TwoWayCache[jMethod, MethodSymbol] - private val constructorCache = new TwoWayCache[jConstructor[_], MethodSymbol] - private val fieldCache = new TwoWayCache[jField, TermSymbol] - private val tparamCache = new TwoWayCache[jTypeVariable[_ <: GenericDeclaration], TypeSymbol] - - def toScala[J: HasJavaClass, S](cache: TwoWayCache[J, S], key: J)(body: (JavaMirror, J) => S): S = - cache.toScala(key){ - val jclazz = implicitly[HasJavaClass[J]] getClazz key - body(mirrorDefining(jclazz), key) - } - - private implicit val classHasJavaClass: HasJavaClass[jClass[_]] = - new HasJavaClass(identity) - private implicit val methHasJavaClass: HasJavaClass[jMethod] - = new HasJavaClass(_.getDeclaringClass) - private implicit val fieldHasJavaClass: HasJavaClass[jField] = - new HasJavaClass(_.getDeclaringClass) - private implicit val constrHasJavaClass: HasJavaClass[jConstructor[_]] = - new HasJavaClass(_.getDeclaringClass) - private implicit val tparamHasJavaClass: HasJavaClass[jTypeVariable[_ <: GenericDeclaration]] = - new HasJavaClass ( (tparam: jTypeVariable[_ <: GenericDeclaration]) => { - tparam.getGenericDeclaration match { - case jclazz: jClass[_] => jclazz - case jmeth: jMethod => jmeth.getDeclaringClass - case jconstr: jConstructor[_] => jconstr.getDeclaringClass - } - }) - -// ----------- Implementations of mirror operations and classes ------------------- - - def reflect(obj: Any): InstanceMirror = - new JavaInstanceMirror(obj.asInstanceOf[AnyRef]) - - def reflectClass(runtimeClass: RuntimeClass): ClassMirror = - new JavaClassMirror(classToScala(runtimeClass)) - - def reflectClass(fullName: String): ClassMirror = - reflectClass(java.lang.Class.forName(fullName)) - - def reflectModule(runtimeClass: RuntimeClass): ModuleMirror = - new JavaModuleMirror(classToScala(runtimeClass).companionModule.asModuleSymbol) - - def reflectModule(fullName: String): ModuleMirror = - reflectModule(java.lang.Class.forName(fullName)) - - def runtimeClass(tpe: Type): RuntimeClass = typeToJavaClass(tpe) - - def runtimeClass(cls: ClassSymbol): RuntimeClass = classToJava(cls) - - private class JavaInstanceMirror(obj: AnyRef) - extends InstanceMirror { - def instance = obj - def reflectClass = wholemirror.reflectClass(obj.getClass) - def reflectField(field: TermSymbol): FieldMirror = new JavaFieldMirror(obj, field) - def reflectMethod(method: MethodSymbol): MethodMirror = new JavaMethodMirror(obj, method) - } - - private class JavaFieldMirror(val receiver: AnyRef, val field: TermSymbol) - extends FieldMirror { - lazy val jfield = fieldToJava(field) - def get = jfield.get(receiver) - def set(value: Any) = jfield.set(receiver, value) - } - - private class JavaMethodMirror(val receiver: AnyRef, val method: MethodSymbol) - extends MethodMirror { - lazy val jmeth = methodToJava(method) - def apply(args: Any*): Any = - if (method.owner == ArrayClass) - method.name match { - case nme.length => jArray.getLength(receiver) - case nme.apply => jArray.get(receiver, args(0).asInstanceOf[Int]) - case nme.update => jArray.set(receiver, args(0).asInstanceOf[Int], args(1)) - case _ => throw new Error(s"unexpected array method $method") - } - else - jmeth.invoke(receiver, args.asInstanceOf[Seq[AnyRef]]: _*) - } - - private class JavaConstructorMirror(val method: MethodSymbol) - extends MethodMirror { - override val receiver = null - lazy val jconstr = constructorToJava(method) - def apply(args: Any*): Any = jconstr.newInstance(args.asInstanceOf[Seq[AnyRef]]: _*) - } - - - private abstract class JavaTemplateMirror - extends TemplateMirror { - def erasure: ClassSymbol - lazy val runtimeClass = classToJava(erasure) - lazy val signature = typeToScala(runtimeClass) - } - - private class JavaClassMirror(val symbol: ClassSymbol) - extends JavaTemplateMirror with ClassMirror { - def erasure = symbol - def isStatic = false - def reflectConstructor(constructor: MethodSymbol) = new JavaConstructorMirror(constructor) - def companion: Option[ModuleMirror] = symbol.companionModule match { - case module: ModuleSymbol => Some(new JavaModuleMirror(module)) - case _ => None - } - } - - private class JavaModuleMirror(val symbol: ModuleSymbol) - extends JavaTemplateMirror with ModuleMirror { - def erasure = symbol.moduleClass.asClassSymbol - def isStatic = true - def instance = singletonInstance(classLoader, symbol.fullName) - def companion: Option[ClassMirror] = symbol.companionClass match { - case cls: ClassSymbol => Some(new JavaClassMirror(cls)) - case _ => None - } - } - -// -------------------- Java to Scala ----------------------------------- - - /** Does method `meth` erase to Java method `jmeth`? - * This is true if the Java method type is the same as the Scala method type after performing - * all Scala-specific transformations in InfoTransformers. (to be done) - */ - private def erasesTo(meth: Symbol, jmeth: jMethod): Boolean = { - val mtpe = transformedType(meth) - (mtpe.paramTypes map runtimeClass) == jmeth.getParameterTypes.toList && - runtimeClass(mtpe.resultType) == jmeth.getReturnType - } - - private def erasesTo(meth: Symbol, jconstr: jConstructor[_]): Boolean = { - val mtpe = transformedType(meth) - (mtpe.paramTypes map runtimeClass) == jconstr.getParameterTypes.toList && - runtimeClass(mtpe.resultType) == jconstr.getDeclaringClass - } - - def javaClass(path: String): jClass[_] = - Class.forName(path, true, classLoader) - - /** Does `path` correspond to a Java class with that fully qualified name in the current class loader? */ - def tryJavaClass(path: String): Option[jClass[_]] = - try { - Some(javaClass(path)) - } catch { - case (_: ClassNotFoundException) | (_: NoClassDefFoundError) | (_: IncompatibleClassChangeError) => - None - } - - /** The mirror that corresponds to the classloader that original defined the given Java class */ - def mirrorDefining(jclazz: jClass[_]): JavaMirror = { - val cl = jclazz.getClassLoader - if (cl == this.classLoader) this else runtimeMirror(cl) - } - - private object unpickler extends UnPickler { - val global: self.type = self - } - - /** how connected???? - * Generate types for top-level Scala root class and root companion object - * from the pickled information stored in a corresponding Java class - * @param clazz The top-level Scala class for which info is unpickled - * @param module The top-level Scala companion object for which info is unpickled - * @param jclazz The Java class which contains the unpickled information in a - * ScalaSignature or ScalaLongSignature annotation. - */ - def unpickleClass(clazz: Symbol, module: Symbol, jclazz: jClass[_]): Unit = { - def markAbsent(tpe: Type) = setAllInfos(clazz, module, tpe) - def handleError(ex: Exception) = { - markAbsent(ErrorType) - if (settings.debug.value) ex.printStackTrace() - val msg = ex.getMessage() - MissingRequirementError.signal( - (if (msg eq null) "reflection error while loading " + clazz.name - else "error while loading " + clazz.name) + ", " + msg) - } - // don't use classOf[scala.reflect.ScalaSignature] here, because it will use getClass.getClassLoader, not mirror's classLoader - // don't use asInstanceOf either because of the same reason (lol, I cannot believe I fell for it) - // don't use structural types to simplify reflective invocations because of the same reason - def loadAnnotation(name: String): Option[java.lang.annotation.Annotation] = - tryJavaClass(name) flatMap { annotClass => - val anns = jclazz.getAnnotations - val result = anns find (_.annotationType == annotClass) - if (result.isEmpty && (anns exists (_.annotationType.getName == name))) - throw new ClassNotFoundException( - s"""Mirror classloader mismatch: $jclazz (loaded by ${ReflectionUtils.show(jclazz.getClassLoader)}) - |is unrelated to the mirror's classloader: (${ReflectionUtils.show(classLoader)})""".stripMargin) - result - } - def loadBytes[T: ClassTag](name: String): Option[T] = - loadAnnotation(name) map { ssig => - val bytesMethod = ssig.annotationType.getMethod("bytes") - bytesMethod.invoke(ssig).asInstanceOf[T] - } - - try { - markAbsent(NoType) - loadBytes[String]("scala.reflect.ScalaSignature") match { - case Some(ssig) => - info(s"unpickling Scala $clazz and $module, owner = ${clazz.owner}") - val bytes = ssig.getBytes - val len = ByteCodecs.decode(bytes) - unpickler.unpickle(bytes take len, 0, clazz, module, jclazz.getName) - case None => - loadBytes[Array[String]]("scala.reflect.ScalaLongSignature") match { - case Some(slsig) => - info(s"unpickling Scala $clazz and $module with long Scala signature") - val byteSegments = slsig map (_.getBytes) - val lens = byteSegments map ByteCodecs.decode - val bytes = Array.ofDim[Byte](lens.sum) - var len = 0 - for ((bs, l) <- byteSegments zip lens) { - bs.copyToArray(bytes, len, l) - len += l - } - unpickler.unpickle(bytes, 0, clazz, module, jclazz.getName) - case None => - // class does not have a Scala signature; it's a Java class - info("translating reflection info for Java " + jclazz) //debug - initClassModule(clazz, module, new FromJavaClassCompleter(clazz, module, jclazz)) - } - } - } catch { - case ex: MissingRequirementError => - handleError(ex) - case ex: IOException => - handleError(ex) - } - } - - /** - * A fresh Scala type parameter that corresponds to a Java type variable. - * The association between Scala type parameter and Java type variable is entered in the cache. - * @param jtvar The Java type variable - */ - private def createTypeParameter(jtvar: jTypeVariable[_ <: GenericDeclaration]): TypeSymbol = { - val tparam = sOwner(jtvar).newTypeParameter(newTypeName(jtvar.getName)) - .setInfo(new TypeParamCompleter(jtvar)) - tparamCache enter (jtvar, tparam) - tparam - } - - /** - * A completer that fills in the type of a Scala type parameter from the bounds of a Java type variable. - * @param jtvar The Java type variable - */ - private class TypeParamCompleter(jtvar: jTypeVariable[_ <: GenericDeclaration]) extends LazyType { - override def load(sym: Symbol) = complete(sym) - override def complete(sym: Symbol) = { - sym setInfo TypeBounds.upper(glb(jtvar.getBounds.toList map typeToScala map objToAny)) - } - } - - /** - * Copy all annotations of Java annotated element `jann` over to Scala symbol `sym`. - * Pre: `sym` is already initialized with a concrete type. - * Note: If `sym` is a method or constructor, its parameter annotations are copied as well. - */ - private def copyAnnotations(sym: Symbol, jann: AnnotatedElement) { - // to do: implement - } - - /** - * A completer that fills in the types of a Scala class and its companion object - * by copying corresponding type info from a Java class. This completer is used - * to reflect classes in Scala that do not have a Scala pickle info, be it - * because they are local classes or have been compiled from Java sources. - * @param clazz The Scala class for which info is copied - * @param module The Scala companion object for which info is copied - * @param jclazz The Java class - */ - private class FromJavaClassCompleter(clazz: Symbol, module: Symbol, jclazz: jClass[_]) extends LazyType { - - /** used to avoid cycles while initializing classes */ - private var parentsLevel = 0 - private var pendingLoadActions: List[() => Unit] = Nil - - override def load(sym: Symbol): Unit = { - debugInfo("completing from Java " + sym + "/" + clazz.fullName)//debug - assert(sym == clazz || (module != NoSymbol && (sym == module || sym == module.moduleClass)), sym) - val flags = toScalaClassFlags(jclazz.getModifiers) - clazz setFlag (flags | JAVA) - if (module != NoSymbol) { - module setFlag (flags & PRIVATE | JAVA) - module.moduleClass setFlag (flags & PRIVATE | JAVA) - } - - copyAnnotations(clazz, jclazz) - // to do: annotations to set also for module? - - clazz setInfo new LazyPolyType(jclazz.getTypeParameters.toList map createTypeParameter) - if (module != NoSymbol) { - module setInfo module.moduleClass.tpe - module.moduleClass setInfo new LazyPolyType(List()) - } - } - - override def complete(sym: Symbol): Unit = { - load(sym) - completeRest() - } - - def completeRest(): Unit = self.synchronized { - val tparams = clazz.rawInfo.typeParams - - val parents = try { - parentsLevel += 1 - val jsuperclazz = jclazz.getGenericSuperclass - val superclazz = if (jsuperclazz == null) AnyClass.tpe else typeToScala(jsuperclazz) - superclazz :: (jclazz.getGenericInterfaces.toList map typeToScala) - } finally { - parentsLevel -= 1 - } - clazz setInfo GenPolyType(tparams, new ClassInfoType(parents, newScope, clazz)) - if (module != NoSymbol) { - module.moduleClass setInfo new ClassInfoType(List(), newScope, module.moduleClass) - } - - def enter(sym: Symbol, mods: Int) = - (if (jModifier.isStatic(mods)) module.moduleClass else clazz).info.decls enter sym - - for (jinner <- jclazz.getDeclaredClasses) { - enter(jclassAsScala(jinner, clazz), jinner.getModifiers) - } - - pendingLoadActions = { () => - - for (jfield <- jclazz.getDeclaredFields) - enter(jfieldAsScala(jfield), jfield.getModifiers) - - for (jmeth <- jclazz.getDeclaredMethods) - enter(jmethodAsScala(jmeth), jmeth.getModifiers) - - for (jconstr <- jclazz.getConstructors) - enter(jconstrAsScala(jconstr), jconstr.getModifiers) - - } :: pendingLoadActions - - if (parentsLevel == 0) { - while (!pendingLoadActions.isEmpty) { - val item = pendingLoadActions.head - pendingLoadActions = pendingLoadActions.tail - item() - } - } - } - - class LazyPolyType(override val typeParams: List[Symbol]) extends LazyType { - override def complete(sym: Symbol) { - completeRest() - } - } - } - - /** - * If Java modifiers `mods` contain STATIC, return the module class - * of the companion module of `clazz`, otherwise the class `clazz` itself. - */ - private def followStatic(clazz: Symbol, mods: Int) = - if (jModifier.isStatic(mods)) clazz.companionModule.moduleClass else clazz - - implicit class RichClass(jclazz: jClass[_]) { - // [Eugene++] `jclazz.isLocalClass` doesn't work because of problems with `getSimpleName` - // java.lang.Error: sOwner(class Test$A$1) has failed - // Caused by: java.lang.InternalError: Malformed class name - // at java.lang.Class.getSimpleName(Class.java:1133) - // at java.lang.Class.isAnonymousClass(Class.java:1188) - // at java.lang.Class.isLocalClass(Class.java:1199) - // (see t5256c.scala for more details) - // hence we have to approximate by removing the `isAnonymousClass` check -// def isLocalClass0: Boolean = jclazz.isLocalClass - def isLocalClass0: Boolean = jclazz.getEnclosingMethod != null || jclazz.getEnclosingConstructor != null - } - - // [Eugene++] overflow from Paul's changes made concurrently with reflection refactoring - // https://github.com/scala/scala/commit/90d2bee45b25844f809f8c5300aefcb1bfe9e336 - // - // /** Methods which need to be wrapped because they either are getSimpleName - // * or call getSimpleName: - // * - // * public String getSimpleName() - // * public boolean isAnonymousClass() - // * public boolean isLocalClass() - // * public boolean isMemberClass() - // * public String getCanonicalName() - // * - // * TODO - find all such calls and wrap them. - // * TODO - create mechanism to avoid the recurrence of unwrapped calls. - // */ - // private def wrapClassCheck[T](alt: T)(body: => T): T = - // try body catch { case x: InternalError if x.getMessage == "Malformed class name" => alt } - - // private def wrapIsLocalClass(clazz: jClass[_]): Boolean = - // wrapClassCheck(false)(clazz.isLocalClass) - - // private def wrapGetSimpleName(clazz: jClass[_]): String = - // wrapClassCheck("")(clazz.getSimpleName) - - /** - * The Scala owner of the Scala class corresponding to the Java class `jclazz` - */ - private def sOwner(jclazz: jClass[_]): Symbol = - if (jclazz.isMemberClass) { - val jEnclosingClass = jclazz.getEnclosingClass - val sEnclosingClass = classToScala(jEnclosingClass) - followStatic(sEnclosingClass, jclazz.getModifiers) - } else if (jclazz.isLocalClass0) { - val jEnclosingMethod = jclazz.getEnclosingMethod - if (jEnclosingMethod != null) { - methodToScala(jEnclosingMethod) - } else { - val jEnclosingConstructor = jclazz.getEnclosingConstructor - constructorToScala(jEnclosingConstructor) - } - } else if (jclazz.isPrimitive || jclazz.isArray) { - ScalaPackageClass - } else if (jclazz.getPackage != null) { - val jPackage = jclazz.getPackage - packageToScala(jPackage).moduleClass - } else { - // @eb: a weird classloader might return a null package for something with a non-empty package name - // for example, http://groups.google.com/group/scala-internals/browse_thread/thread/7be09ff8f67a1e5c - // in that case we could invoke packageNameToScala(jPackageName) and, probably, be okay - // however, I think, it's better to blow up, since weirdness of the class loader might bite us elsewhere - // [martin] I think it's better to be forgiving here. Restoring packageNameToScala. - val jPackageName = jclazz.getName take jclazz.getName.lastIndexOf('.') - packageNameToScala(jPackageName).moduleClass - } - - /** - * The Scala owner of the Scala symbol corresponding to the Java member `jmember` - */ - private def sOwner(jmember: jMember): Symbol = { - followStatic(classToScala(jmember.getDeclaringClass), jmember.getModifiers) - } - - /** - * The Scala owner of the Scala type parameter corresponding to the Java type variable `jtvar` - */ - private def sOwner(jtvar: jTypeVariable[_ <: GenericDeclaration]): Symbol = - genericDeclarationToScala(jtvar.getGenericDeclaration) - - /** - * Find declarations or definition in class `clazz` that maps to a Java - * entity with name `jname`. Because of name-mangling, this is more difficult - * than a simple name-based lookup via `decl`. If `decl` fails, members - * that start with the given name are searched instead. - */ - private def lookup(clazz: Symbol, jname: String): Symbol = { - def approximateMatch(sym: Symbol, jstr: String): Boolean = - (sym.name.toString == jstr) || - sym.isPrivate && nme.expandedName(sym.name.toTermName, sym.owner).toString == jstr - - clazz.info.decl(newTermName(jname)) orElse { - (clazz.info.decls.iterator filter (approximateMatch(_, jname))).toList match { - case List() => NoSymbol - case List(sym) => sym - case alts => clazz.newOverloaded(alts.head.tpe.prefix, alts) - } - } - } - - /** - * The Scala method corresponding to given Java method. - * @param jmeth The Java method - * @return A Scala method object that corresponds to `jmeth`. - */ - def methodToScala(jmeth: jMethod): MethodSymbol = - toScala(methodCache, jmeth)(_ methodToScala1 _) - - private def methodToScala1(jmeth: jMethod): MethodSymbol = { - val jOwner = jmeth.getDeclaringClass - val preOwner = classToScala(jOwner) - val owner = followStatic(preOwner, jmeth.getModifiers) - (lookup(owner, jmeth.getName) suchThat (erasesTo(_, jmeth)) orElse jmethodAsScala(jmeth)) - .asMethodSymbol - } - - /** - * The Scala constructor corresponding to given Java constructor. - * @param jconstr The Java constructor - * @return A Scala method object that corresponds to `jconstr`. - */ - def constructorToScala(jconstr: jConstructor[_]): MethodSymbol = - toScala(constructorCache, jconstr)(_ constructorToScala1 _) - - private def constructorToScala1(jconstr: jConstructor[_]): MethodSymbol = { - val owner = followStatic(classToScala(jconstr.getDeclaringClass), jconstr.getModifiers) - (lookup(owner, jconstr.getName) suchThat (erasesTo(_, jconstr)) orElse jconstrAsScala(jconstr)) - .asMethodSymbol - } - - /** - * The Scala field corresponding to given Java field. - * @param jfield The Java field - * @return A Scala field object that corresponds to `jfield`. - * // ??? should we return the getter instead? - */ - def fieldToScala(jfield: jField): TermSymbol = - toScala(fieldCache, jfield)(_ fieldToScala1 _) - - private def fieldToScala1(jfield: jField): TermSymbol = { - val owner = followStatic(classToScala(jfield.getDeclaringClass), jfield.getModifiers) - (lookup(owner, jfield.getName) suchThat (!_.isMethod) orElse jfieldAsScala(jfield)) - .asTermSymbol - } - - /** - * The Scala package corresponding to given Java package - */ - def packageToScala(jpkg: jPackage): ModuleSymbol = packageCache.toScala(jpkg) { - makeScalaPackage(jpkg.getName) - } - - /** - * The Scala package with given fully qualified name. - */ - def packageNameToScala(fullname: String): ModuleSymbol = { - if (fullname == "") EmptyPackage - else { - val jpkg = jPackage.getPackage(fullname) - if (jpkg != null) packageToScala(jpkg) else makeScalaPackage(fullname) - } - } - - /** - * The Scala package with given fully qualified name. Unlike `packageNameToScala`, - * this one bypasses the cache. - */ - private[JavaMirrors] def makeScalaPackage(fullname: String): ModuleSymbol = { - val split = fullname lastIndexOf '.' - val ownerModule: ModuleSymbol = - if (split > 0) packageNameToScala(fullname take split) else this.RootPackage - val owner = ownerModule.moduleClass - val name = newTermName(fullname drop (split + 1)) - val opkg = owner.info decl name - if (opkg.isPackage) - opkg.asModuleSymbol - else if (opkg == NoSymbol) { - val pkg = owner.newPackage(name) - pkg.moduleClass setInfo new LazyPackageType - pkg setInfoAndEnter pkg.moduleClass.tpe - info("made Scala "+pkg) - pkg - } else - throw new ReflectError(opkg+" is not a package") - } - - private def scalaSimpleName(jclazz: jClass[_]): TypeName = { - val owner = sOwner(jclazz) - val enclosingClass = jclazz.getEnclosingClass - var prefix = if (enclosingClass != null) enclosingClass.getName else "" - val isObject = owner.isModuleClass && !owner.isPackageClass - if (isObject && !prefix.endsWith(nme.MODULE_SUFFIX_STRING)) prefix += nme.MODULE_SUFFIX_STRING - assert(jclazz.getName.startsWith(prefix)) - var name = jclazz.getName.substring(prefix.length) - name = name.substring(name.lastIndexOf(".") + 1) - newTypeName(name) - } - - /** - * The Scala class that corresponds to a given Java class. - * @param jclazz The Java class - * @return A Scala class symbol that reflects all elements of the Java class, - * in the form they appear in the Scala pickling info, or, if that is - * not available, wrapped from the Java reflection info. - */ - def classToScala(jclazz: jClass[_]): ClassSymbol = - toScala(classCache, jclazz)(_ classToScala1 _) - - private def classToScala1(jclazz: jClass[_]): ClassSymbol = { - val jname = newTypeName(jclazz.getName) - if (jname == fulltpnme.RuntimeNothing) NothingClass - else if (jname == fulltpnme.RuntimeNull) NullClass - else { - val owner = sOwner(jclazz) - val simpleName = scalaSimpleName(jclazz) - - def lookupClass = { - def coreLookup(name: Name): Symbol = - owner.info.decl(name) orElse { - if (name.startsWith(nme.NAME_JOIN_STRING)) coreLookup(name drop 1) else NoSymbol - } - if (nme.isModuleName(simpleName)) - coreLookup(nme.stripModuleSuffix(simpleName).toTermName) map (_.moduleClass) - else - coreLookup(simpleName) - } - - val cls = - if (jclazz.isMemberClass && !nme.isImplClassName(jname)) - lookupClass - else if (jclazz.isLocalClass0 || isInvalidClassName(jname)) - // local classes and implementation classes not preserved by unpickling - treat as Java - jclassAsScala(jclazz) - else if (jclazz.isArray) - ArrayClass - else - javaTypeToValueClass(jclazz) orElse lookupClass - - assert (cls.isType, - s"""${if (cls == NoSymbol) "not a type: symbol" else "no symbol could be"} - | loaded from $jclazz in $owner with name $simpleName and classloader $classLoader""".stripMargin) - - cls.asClassSymbol - } - } - - /** - * The Scala type parameter that corresponds to a given Java type parameter. - * @param jparam The Java type parameter - * @return A Scala type parameter symbol that has the same owner and name as the Java type parameter - */ - def typeParamToScala(jparam: jTypeVariable[_ <: GenericDeclaration]): TypeSymbol = - toScala(tparamCache, jparam)(_ typeParamToScala1 _) - - private def typeParamToScala1(jparam: jTypeVariable[_ <: GenericDeclaration]): TypeSymbol = { - val owner = genericDeclarationToScala(jparam.getGenericDeclaration) - owner.info match { - case PolyType(tparams, _) => tparams.find(_.name.toString == jparam.getName).get.asTypeSymbol - } - } - - /** - * The Scala symbol that corresponds to a given Java generic declaration (class, method, or constructor) - */ - def genericDeclarationToScala(jdecl: GenericDeclaration): Symbol = jdecl match { - case jclazz: jClass[_] => classToScala(jclazz) - case jmeth: jMethod => methodToScala(jmeth) - case jconstr: jConstructor[_] => constructorToScala(jconstr) - } - - /** - * Given some Java type arguments, a corresponding list of Scala types, plus potentially - * some existentially bound type variables that represent wildcard arguments. - */ - private def targsToScala(owner: Symbol, args: List[jType]): (List[Type], List[TypeSymbol]) = { - val tparams = new ListBuffer[TypeSymbol] - def targToScala(arg: jType): Type = arg match { - case jwild: WildcardType => - val tparam = owner.newExistential(newTypeName("T$" + tparams.length)) - .setInfo(TypeBounds( - lub(jwild.getLowerBounds.toList map typeToScala), - glb(jwild.getUpperBounds.toList map typeToScala map objToAny))) - tparams += tparam - typeRef(NoPrefix, tparam, List()) - case _ => - typeToScala(arg) - } - (args map targToScala, tparams.toList) - } - - /** - * The Scala type that corresponds to given Java type - */ - def typeToScala(jtpe: jType): Type = jtpe match { - case jclazz: jClass[_] => - if (jclazz.isArray) - arrayType(typeToScala(jclazz.getComponentType)) - else { - val clazz = classToScala(jclazz) - rawToExistential(typeRef(clazz.owner.thisType, clazz, List())) - } - case japplied: ParameterizedType => - val (pre, sym) = typeToScala(japplied.getRawType) match { - case ExistentialType(tparams, TypeRef(pre, sym, _)) => (pre, sym) - case TypeRef(pre, sym, _) => (pre, sym) - } - val args0 = japplied.getActualTypeArguments - val (args, bounds) = targsToScala(pre.typeSymbol, args0.toList) - ExistentialType(bounds, typeRef(pre, sym, args)) - case jarr: GenericArrayType => - arrayType(typeToScala(jarr.getGenericComponentType)) - case jtvar: jTypeVariable[_] => - val tparam = typeParamToScala(jtvar) - typeRef(NoPrefix, tparam, List()) - } - - /** - * The Scala class that corresponds to given Java class without taking - * Scala pickling info into account. - * @param jclazz The Java class - * @return A Scala class symbol that wraps all reflection info of `jclazz` - */ - private def jclassAsScala(jclazz: jClass[_]): Symbol = jclassAsScala(jclazz, sOwner(jclazz)) - - private def jclassAsScala(jclazz: jClass[_], owner: Symbol): ClassSymbol = { - val name = scalaSimpleName(jclazz) - val completer = (clazz: Symbol, module: Symbol) => new FromJavaClassCompleter(clazz, module, jclazz) - val (clazz, module) = createClassModule(owner, name, completer) - classCache enter (jclazz, clazz) - clazz - } - - /** - * The Scala field that corresponds to given Java field without taking - * Scala pickling info into account. - * @param jfield The Java field - * @return A Scala value symbol that wraps all reflection info of `jfield` - */ - private def jfieldAsScala(jfield: jField): TermSymbol = - toScala(fieldCache, jfield)(_ jfieldAsScala1 _) - - private def jfieldAsScala1(jfield: jField): TermSymbol = { - val field = sOwner(jfield) - .newValue(newTermName(jfield.getName), NoPosition, toScalaFieldFlags(jfield.getModifiers)) - .setInfo(typeToScala(jfield.getGenericType)) - fieldCache enter (jfield, field) - copyAnnotations(field, jfield) - field - } - - private def setMethType(meth: Symbol, tparams: List[Symbol], paramtpes: List[Type], restpe: Type) = { - meth setInfo GenPolyType(tparams, MethodType(meth.owner.newSyntheticValueParams(paramtpes map objToAny), restpe)) - } - - /** - * The Scala method that corresponds to given Java method without taking - * Scala pickling info into account. - * @param jmeth The Java method - * @return A Scala method symbol that wraps all reflection info of `jmethod` - */ - private def jmethodAsScala(jmeth: jMethod): MethodSymbol = - toScala(methodCache, jmeth)(_ jmethodAsScala1 _) - - private def jmethodAsScala1(jmeth: jMethod): MethodSymbol = { - val clazz = sOwner(jmeth) - val meth = clazz.newMethod(newTermName(jmeth.getName), NoPosition, toScalaMethodFlags(jmeth.getModifiers)) - methodCache enter (jmeth, meth) - val tparams = jmeth.getTypeParameters.toList map createTypeParameter - val paramtpes = jmeth.getGenericParameterTypes.toList map typeToScala - val resulttpe = typeToScala(jmeth.getGenericReturnType) - setMethType(meth, tparams, paramtpes, resulttpe) - copyAnnotations(meth, jmeth) - if ((jmeth.getModifiers & JAVA_ACC_VARARGS) != 0) meth.setInfo(arrayToRepeated(meth.info)) - meth - } - - /** - * The Scala constructor that corresponds to given Java constructor without taking - * Scala pickling info into account. - * @param jconstr The Java constructor - * @return A Scala constructor symbol that wraps all reflection info of `jconstr` - */ - private def jconstrAsScala(jconstr: jConstructor[_]): MethodSymbol = - toScala(constructorCache, jconstr)(_ jconstrAsScala1 _) - - private def jconstrAsScala1(jconstr: jConstructor[_]): MethodSymbol = { - // [Martin] Note: I know there's a lot of duplication wrt jmethodAsScala, but don't think it's worth it to factor this out. - val clazz = sOwner(jconstr) - val constr = clazz.newConstructor(NoPosition, toScalaMethodFlags(jconstr.getModifiers)) - constructorCache enter (jconstr, constr) - val tparams = jconstr.getTypeParameters.toList map createTypeParameter - val paramtpes = jconstr.getGenericParameterTypes.toList map typeToScala - setMethType(constr, tparams, paramtpes, clazz.tpe) - constr setInfo GenPolyType(tparams, MethodType(clazz.newSyntheticValueParams(paramtpes), clazz.tpe)) - copyAnnotations(constr, jconstr) - constr - } - -// -------------------- Scala to Java ----------------------------------- - - /** Optionally, the Java package corresponding to a given Scala package, or None if no such Java package exists. - * @param pkg The Scala package - */ - def packageToJavaOption(pkg: ModuleSymbol): Option[jPackage] = packageCache.toJavaOption(pkg) { - Option(jPackage.getPackage(pkg.fullName.toString)) - } - - /** The Java class corresponding to given Scala class. - * Note: This only works for - * - top-level classes - * - Scala classes that were generated via jclassToScala - * - classes that have a class owner that has a corresponding Java class - * @throws A `ClassNotFoundException` for all Scala classes not in one of these categories. - */ - @throws(classOf[ClassNotFoundException]) - def classToJava(clazz: ClassSymbol): jClass[_] = classCache.toJava(clazz) { - def noClass = throw new ClassNotFoundException("no Java class corresponding to "+clazz+" found") - //println("classToJava "+clazz+" "+clazz.owner+" "+clazz.owner.isPackageClass)//debug - if (clazz.isPrimitiveValueClass) - valueClassToJavaType(clazz) - else if (clazz == ArrayClass) - noClass - else if (clazz.owner.isPackageClass) - javaClass(clazz.javaClassName) - else if (clazz.owner.isClass) - classToJava(clazz.owner.asClassSymbol) - .getDeclaredClasses - .find(_.getSimpleName == clazz.name.toString) - .getOrElse(noClass) - else - noClass - } - - private def expandedName(sym: Symbol): String = - if (sym.isPrivate) nme.expandedName(sym.name.toTermName, sym.owner).toString - else sym.name.toString - - /** The Java field corresponding to a given Scala field. - * @param meth The Scala field. - */ - def fieldToJava(fld: TermSymbol): jField = fieldCache.toJava(fld) { - val jclazz = classToJava(fld.owner.asClassSymbol) - try jclazz getDeclaredField fld.name.toString - catch { - case ex: NoSuchFieldException => jclazz getDeclaredField expandedName(fld) - } - } - - /** The Java method corresponding to a given Scala method. - * @param meth The Scala method - */ - def methodToJava(meth: MethodSymbol): jMethod = methodCache.toJava(meth) { - val jclazz = classToJava(meth.owner.asClassSymbol) - val paramClasses = transformedType(meth).paramTypes map typeToJavaClass - try jclazz getDeclaredMethod (meth.name.toString, paramClasses: _*) - catch { - case ex: NoSuchMethodException => - jclazz getDeclaredMethod (expandedName(meth), paramClasses: _*) - } - } - - /** The Java constructor corresponding to a given Scala constructor. - * @param constr The Scala constructor - */ - def constructorToJava(constr: MethodSymbol): jConstructor[_] = constructorCache.toJava(constr) { - val jclazz = classToJava(constr.owner.asClassSymbol) - val paramClasses = transformedType(constr).paramTypes map typeToJavaClass - jclazz getConstructor (paramClasses: _*) - } - - private def jArrayClass(elemClazz: jClass[_]): jClass[_] = { - jArray.newInstance(elemClazz, 0).getClass - } - - /** The Java class that corresponds to given Scala type. - * Pre: Scala type is already transformed to Java level. - */ - def typeToJavaClass(tpe: Type): jClass[_] = tpe match { - case ExistentialType(_, rtpe) => typeToJavaClass(rtpe) - case TypeRef(_, ArrayClass, List(elemtpe)) => jArrayClass(typeToJavaClass(elemtpe)) - case TypeRef(_, sym: ClassSymbol, _) => classToJava(sym.asClassSymbol) - case _ => throw new NoClassDefFoundError("no Java class corresponding to "+tpe+" found") - } - } - - /** Assert that packages have package scopes */ - override def validateClassInfo(tp: ClassInfoType) { - assert(!tp.typeSymbol.isPackageClass || tp.decls.isInstanceOf[PackageScope]) - } - - override def newPackageScope(pkgClass: Symbol) = new PackageScope(pkgClass) - - override def scopeTransform(owner: Symbol)(op: => Scope): Scope = - if (owner.isPackageClass) owner.info.decls else op - - private lazy val rootToLoader = new WeakHashMap[Symbol, ClassLoader] - - override def mirrorThatLoaded(sym: Symbol): Mirror = { - val root = sym.enclosingRootClass - def findLoader = { - val loaders = (mirrors collect { case (cl, ref) if ref.get.get.RootClass == root => cl }) - assert(loaders.nonEmpty, sym) - loaders.head - } - mirrors(rootToLoader getOrElseUpdate(root, findLoader)).get.get - } - - private def byName(sym: Symbol): (Name, Symbol) = sym.name -> sym - - private lazy val phantomTypes: Map[Name, Symbol] = - Map(byName(definitions.AnyRefClass)) ++ (definitions.isPhantomClass map byName) - - /** 1. If `owner` is a package class (but not the empty package) and `name` is a term name, make a new package - * <owner>.<name>, otherwise return NoSymbol. - * Exception: If owner is root and a java class with given name exists, create symbol in empty package instead - * 2. If `owner` is the scala package and `name` designates a phantom class, return - * the corresponding class symbol and enter it into this mirror's ScalaPackage. - */ - override def missingHook(owner: Symbol, name: Name): Symbol = { - if (owner.hasPackageFlag) { - val mirror = mirrorThatLoaded(owner) - // [Eugene++] this makes toolbox tests pass, but it's a mere workaround for SI-5865 -// assert((owner.info decl name) == NoSymbol, s"already exists: $owner . $name") - if (owner.isRootSymbol && mirror.tryJavaClass(name.toString).isDefined) - return mirror.EmptyPackageClass.info decl name - if (name.isTermName && !owner.isEmptyPackageClass) - return mirror.makeScalaPackage( - if (owner.isRootSymbol) name.toString else owner.fullName+"."+name) - if (owner.name.toTermName == nme.scala_ && owner.owner.isRoot) - phantomTypes get name match { - case Some(tsym) => - owner.info.decls enter tsym - return tsym - case None => - } - } - info("*** missing: "+name+"/"+name.isTermName+"/"+owner+"/"+owner.hasPackageFlag+"/"+owner.info.decls.getClass) - super.missingHook(owner, name) - } -} - -class ReflectError(msg: String) extends java.lang.Error(msg) - -class HasJavaClass[J](val getClazz: J => java.lang.Class[_]) diff --git a/src/compiler/scala/reflect/runtime/JavaUniverse.scala b/src/compiler/scala/reflect/runtime/JavaUniverse.scala deleted file mode 100644 index d4a83b960d..0000000000 --- a/src/compiler/scala/reflect/runtime/JavaUniverse.scala +++ /dev/null @@ -1,33 +0,0 @@ -package scala.reflect -package runtime - -import internal.{SomePhase, NoPhase, Phase, TreeGen} - -/** The universe for standard runtime reflection from Java. - * This type implements all abstract term members in internal.SymbolTable. - */ -class JavaUniverse extends internal.SymbolTable with ReflectSetup with runtime.SymbolTable { self => - - type AbstractFileType = AbstractFile - - def picklerPhase = SomePhase - - type TreeGen = internal.TreeGen - - override type Position = scala.reflect.internal.util.Position - - override val gen = new TreeGen { val global: self.type = self } - - lazy val settings = new Settings - def forInteractive = false - def forScaladoc = false - - def log(msg: => AnyRef): Unit = println(" [] "+msg) - - type TreeCopier = TreeCopierOps - def newStrictTreeCopier: TreeCopier = new StrictTreeCopier - def newLazyTreeCopier: TreeCopier = new LazyTreeCopier - - init() -} - diff --git a/src/compiler/scala/reflect/runtime/ReflectSetup.scala b/src/compiler/scala/reflect/runtime/ReflectSetup.scala deleted file mode 100644 index 6e28fc8520..0000000000 --- a/src/compiler/scala/reflect/runtime/ReflectSetup.scala +++ /dev/null @@ -1,12 +0,0 @@ -package scala.reflect -package runtime - -import internal.{SomePhase, NoPhase, Phase, TreeGen} - -/** A helper trait to initialize things that need to be set before JavaMirrors and other - * reflect specific traits are initialized */ -private[runtime] trait ReflectSetup extends internal.SymbolTable { - override val phaseWithId: Array[Phase] = Array(NoPhase, SomePhase) - override val currentRunId = 1 // fake a run id so that it is different from NoRunId - phase = SomePhase // set to a phase different from NoPhase -} diff --git a/src/compiler/scala/reflect/runtime/ReflectionUtils.scala b/src/compiler/scala/reflect/runtime/ReflectionUtils.scala deleted file mode 100644 index 4e82fe8ad2..0000000000 --- a/src/compiler/scala/reflect/runtime/ReflectionUtils.scala +++ /dev/null @@ -1,80 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Paul Phillips - */ - -package scala.reflect.runtime - -import java.lang.{Class => jClass} -import java.lang.reflect.{ InvocationTargetException, UndeclaredThrowableException } - -/** A few java-reflection oriented utility functions useful during reflection bootstrapping. - */ -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 - _: ExceptionInInitializerError | // thrown when running a static initializer (e.g. a scala module constructor) - _: UndeclaredThrowableException | // invocation on a proxy instance if its invocation handler's `invoke` throws an exception - _: ClassNotFoundException | // no definition for a class instantiated by name - _: NoClassDefFoundError // the definition existed when the executing class was compiled, but can no longer be found - if x.getCause != null => - unwrapThrowable(x.getCause) - case _ => x - } - // Transforms an exception handler into one which will only receive the unwrapped - // exceptions (for the values of wrap covered in unwrapThrowable.) - def unwrapHandler[T](pf: PartialFunction[Throwable, T]): PartialFunction[Throwable, T] = { - case ex if pf isDefinedAt unwrapThrowable(ex) => pf(unwrapThrowable(ex)) - } - - private def systemProperties: Iterator[(String, String)] = { - import scala.collection.JavaConverters._ - System.getProperties.asScala.iterator - } - - private def inferBootClasspath: String = ( - systemProperties find (_._1 endsWith ".boot.class.path") map (_._2) getOrElse "" - ) - - def show(cl: ClassLoader) = { - def inferClasspath(cl: ClassLoader): String = cl match { - case cl: java.net.URLClassLoader => - "[" + (cl.getURLs mkString ",") + "]" - case cl if cl != null && cl.getClass.getName == "scala.tools.nsc.interpreter.AbstractFileClassLoader" => - "[" + cl.asInstanceOf[{val root: scala.reflect.internal.AbstractFileApi}].root + "] and " + inferClasspath(cl.getParent) - case null => - inferBootClasspath - case _ => - "<unknown>" - } - cl match { - case cl if cl != null => - "%s of type %s with classpath %s".format(cl, cl.getClass, inferClasspath(cl)) - case null => - "primordial classloader with boot classpath [%s]".format(inferClasspath(cl)) - } - } - - def singletonInstance(cl: ClassLoader, className: String): AnyRef = { - val name = if (className endsWith "$") className else className + "$" - val clazz = java.lang.Class.forName(name, true, cl) - val singleton = clazz getField "MODULE$" get null - singleton - } - - // Retrieves the MODULE$ field for the given class name. - def singletonInstanceOpt(cl: ClassLoader, className: String): Option[AnyRef] = - try Some(singletonInstance(cl, className)) - catch { case _: ClassNotFoundException => None } - - def invokeFactory(cl: ClassLoader, className: String, methodName: String, args: AnyRef*): AnyRef = { - val singleton = singletonInstance(cl, className) - val method = singleton.getClass.getMethod(methodName, classOf[ClassLoader]) - method.invoke(singleton, args: _*) - } - - def invokeFactoryOpt(cl: ClassLoader, className: String, methodName: String, args: AnyRef*): Option[AnyRef] = - try Some(invokeFactory(cl, className, methodName, args: _*)) - catch { case _: ClassNotFoundException => None } -} diff --git a/src/compiler/scala/reflect/runtime/Settings.scala b/src/compiler/scala/reflect/runtime/Settings.scala deleted file mode 100644 index b247797c6c..0000000000 --- a/src/compiler/scala/reflect/runtime/Settings.scala +++ /dev/null @@ -1,39 +0,0 @@ -package scala.reflect -package runtime - -/** The Settings class for runtime reflection. - * This should be refined, so that settings are settable via command - * line options or properties. - */ -class Settings extends internal.settings.MutableSettings { - - trait Setting extends SettingValue { } - - class BooleanSetting(x: Boolean) extends Setting { - type T = Boolean - protected var v: Boolean = x - override def value: Boolean = v - } - - class IntSetting(x: Int) extends Setting { - type T = Int - protected var v: Int = x - override def value: Int = v - } - - val overrideObjects = new BooleanSetting(false) - val debug = new BooleanSetting(false) - val Ynotnull = new BooleanSetting(false) - val explaintypes = new BooleanSetting(false) - val verbose = new BooleanSetting(false) - val uniqid = new BooleanSetting(false) - val Yshowsymkinds = new BooleanSetting(false) - val Xprintpos = new BooleanSetting(false) - val printtypes = new BooleanSetting(false) - val Yrecursion = new IntSetting(0) - val maxClassfileName = new IntSetting(255) - val Xexperimental = new BooleanSetting(false) - val deepCloning = new BooleanSetting (false) - val XoldPatmat = new BooleanSetting(false) - val XnoPatmatAnalysis = new BooleanSetting(false) -} diff --git a/src/compiler/scala/reflect/runtime/SymbolLoaders.scala b/src/compiler/scala/reflect/runtime/SymbolLoaders.scala deleted file mode 100644 index c1cd5d2911..0000000000 --- a/src/compiler/scala/reflect/runtime/SymbolLoaders.scala +++ /dev/null @@ -1,152 +0,0 @@ -package scala.reflect -package runtime - -import internal.Flags -import java.lang.{Class => jClass, Package => jPackage} -import collection.mutable - -trait SymbolLoaders { self: SymbolTable => - - /** The standard completer for top-level classes - * @param clazz The top-level class - * @param module The companion object of `clazz` - * Calling `complete` on this type will assign the infos of `clazz` and `module` - * by unpickling information from the corresponding Java class. If no Java class - * is found, a package is created instead. - */ - class TopClassCompleter(clazz: Symbol, module: Symbol) extends SymLoader { -// def makePackage() { -// println("wrong guess; making package "+clazz) -// val ptpe = newPackageType(module.moduleClass) -// for (sym <- List(clazz, module, module.moduleClass)) { -// sym setFlag Flags.PACKAGE -// sym setInfo ptpe -// } -// } - - override def complete(sym: Symbol) = { - debugInfo("completing "+sym+"/"+clazz.fullName) - assert(sym == clazz || sym == module || sym == module.moduleClass) -// try { - atPhaseNotLaterThan(picklerPhase) { - val loadingMirror = mirrorThatLoaded(sym) - val javaClass = loadingMirror.javaClass(clazz.javaClassName) - loadingMirror.unpickleClass(clazz, module, javaClass) -// } catch { -// case ex: ClassNotFoundException => makePackage() -// case ex: NoClassDefFoundError => makePackage() - // Note: We catch NoClassDefFoundError because there are situations - // where a package and a class have the same name except for capitalization. - // It seems in this case the class is loaded even if capitalization differs - // but then a NoClassDefFound error is issued with a ("wrong name: ...") - // reason. (I guess this is a concession to Windows). - // The present behavior is a bit too forgiving, in that it masks - // all class load errors, not just wrong name errors. We should try - // to be more discriminating. To get on the right track simply delete - // the clause above and load a collection class such as collection.Iterable. - // You'll see an error that class `parallel` has the wrong name. -// } - } - } - override def load(sym: Symbol) = complete(sym) - } - - /** Create a class and a companion object, enter in enclosing scope, - * and initialize with a lazy type completer. - * @param owner The owner of the newly created class and object - * @param name The simple name of the newly created class - * @param completer The completer to be used to set the info of the class and the module - */ - protected def createClassModule(owner: Symbol, name: TypeName, completer: (Symbol, Symbol) => LazyType) = { - assert(!(name.toString endsWith "[]"), name) - val clazz = owner.newClass(name) - val module = owner.newModule(name.toTermName) - // [Eugene++] am I doing this right? - // todo: drop condition, see what goes wrong - // [Eugene++ to Martin] test/files/run/t5256g and test/files/run/t5256h will crash - // reflection meeting verdict: need to enter the symbols into the first symbol in the owner chain that has a non-empty scope - if (owner.info.decls != EmptyScope) { - owner.info.decls enter clazz - owner.info.decls enter module - } - initClassModule(clazz, module, completer(clazz, module)) - (clazz, module) - } - - 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. - */ - class LazyPackageType extends LazyType { - override def complete(sym: Symbol) { - assert(sym.isPackageClass) - sym setInfo new ClassInfoType(List(), new PackageScope(sym), sym) - // override def safeToString = pkgClass.toString - openPackageModule(sym) - } - } - - /** 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 isInvalidClassName(name: Name) = { - val dp = name pos '$' - 0 < dp && dp < (name.length - 1) - } - - class PackageScope(pkgClass: Symbol) extends Scope() with SynchronizedScope { - assert(pkgClass.isType) - private val negatives = mutable.Set[Name]() // Syncnote: Performance only, so need not be protected. - override def lookupEntry(name: Name): ScopeEntry = { - val e = super.lookupEntry(name) - if (e != null) - e - else if (isInvalidClassName(name) || (negatives contains name)) - null - else { - val path = - if (pkgClass.isEmptyPackageClass) name.toString - else pkgClass.fullName + "." + name - val currentMirror = mirrorThatLoaded(pkgClass) - currentMirror.tryJavaClass(path) match { - case Some(cls) => - val loadingMirror = currentMirror.mirrorDefining(cls) - val (clazz, module) = - if (loadingMirror eq currentMirror) { - createClassModule(pkgClass, name.toTypeName, new TopClassCompleter(_, _)) - } else { - val origOwner = loadingMirror.packageNameToScala(pkgClass.fullName) - val clazz = origOwner.info decl name.toTypeName - val module = origOwner.info decl name.toTermName - assert(clazz != NoSymbol) - assert(module != NoSymbol) - pkgClass.info.decls enter clazz - pkgClass.info.decls enter module - (clazz, module) - } - debugInfo(s"created $module/${module.moduleClass} in $pkgClass") - lookupEntry(name) - case none => - debugInfo("*** not found : "+path) - negatives += name - null - } - } - } - } - - /** Assert that packages have package scopes */ - override def validateClassInfo(tp: ClassInfoType) { - assert(!tp.typeSymbol.isPackageClass || tp.decls.isInstanceOf[PackageScope]) - } - - override def newPackageScope(pkgClass: Symbol) = new PackageScope(pkgClass) - - override def scopeTransform(owner: Symbol)(op: => Scope): Scope = - if (owner.isPackageClass) owner.info.decls else op -} diff --git a/src/compiler/scala/reflect/runtime/SymbolTable.scala b/src/compiler/scala/reflect/runtime/SymbolTable.scala deleted file mode 100644 index c90665508b..0000000000 --- a/src/compiler/scala/reflect/runtime/SymbolTable.scala +++ /dev/null @@ -1,17 +0,0 @@ -package scala.reflect -package runtime - -/** - * This symbol table trait fills in the definitions so that class information is obtained by refection. - * It can be used either from a reflexive universe (class scala.reflect.runtime.JavaUniverse), or else from - * a runtime compiler that uses reflection to get a class information (class scala.tools.nsc.ReflectGlobal) - */ -trait SymbolTable extends internal.SymbolTable with JavaMirrors with SymbolLoaders with SynchronizedOps { - - def info(msg: => String) = - if (settings.verbose.value) println("[reflect-compiler] "+msg) - - def debugInfo(msg: => String) = - if (settings.debug.value) info(msg) - -} diff --git a/src/compiler/scala/reflect/runtime/SynchronizedOps.scala b/src/compiler/scala/reflect/runtime/SynchronizedOps.scala deleted file mode 100644 index 907c0dd369..0000000000 --- a/src/compiler/scala/reflect/runtime/SynchronizedOps.scala +++ /dev/null @@ -1,51 +0,0 @@ -package scala.reflect -package runtime - -trait SynchronizedOps extends internal.SymbolTable - with SynchronizedSymbols - with SynchronizedTypes { self: SymbolTable => - -// Names - - private lazy val nameLock = new Object - - override def newTermName(s: String): TermName = nameLock.synchronized { super.newTermName(s) } - override def newTypeName(s: String): TypeName = nameLock.synchronized { super.newTypeName(s) } - -// BaseTypeSeqs - - override protected def newBaseTypeSeq(parents: List[Type], elems: Array[Type]) = - new BaseTypeSeq(parents, elems) with SynchronizedBaseTypeSeq - - trait SynchronizedBaseTypeSeq extends BaseTypeSeq { - override def apply(i: Int): Type = synchronized { super.apply(i) } - override def rawElem(i: Int) = synchronized { super.rawElem(i) } - override def typeSymbol(i: Int): Symbol = synchronized { super.typeSymbol(i) } - override def toList: List[Type] = synchronized { super.toList } - override def copy(head: Type, offset: Int): BaseTypeSeq = synchronized { super.copy(head, offset) } - override def map(f: Type => Type): BaseTypeSeq = synchronized { super.map(f) } - override def exists(p: Type => Boolean): Boolean = synchronized { super.exists(p) } - override lazy val maxDepth = synchronized { maxDepthOfElems } - override def toString = synchronized { super.toString } - - override def lateMap(f: Type => Type): BaseTypeSeq = new MappedBaseTypeSeq(this, f) with SynchronizedBaseTypeSeq - } - -// Scopes - - override def newScope = new Scope() with SynchronizedScope - override def newNestedScope(outer: Scope): Scope = new Scope(outer) with SynchronizedScope - - trait SynchronizedScope extends Scope { - override def isEmpty: Boolean = synchronized { super.isEmpty } - override def size: Int = synchronized { super.size } - override def enter[T <: Symbol](sym: T): T = synchronized { super.enter(sym) } - override def rehash(sym: Symbol, newname: Name) = synchronized { super.rehash(sym, newname) } - override def unlink(e: ScopeEntry) = synchronized { super.unlink(e) } - override def unlink(sym: Symbol) = synchronized { super.unlink(sym) } - override def lookupAll(name: Name) = synchronized { super.lookupAll(name) } - override def lookupEntry(name: Name) = synchronized { super.lookupEntry(name) } - override def lookupNextEntry(entry: ScopeEntry) = synchronized { super.lookupNextEntry(entry) } - override def toList: List[Symbol] = synchronized { super.toList } - } -} diff --git a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala deleted file mode 100644 index 3b28ddf42c..0000000000 --- a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala +++ /dev/null @@ -1,140 +0,0 @@ -package scala.reflect -package runtime - -import internal.Flags.DEFERRED - -trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable => - - override protected def nextId() = synchronized { super.nextId() } - - override protected def freshExistentialName(suffix: String) = - synchronized { super.freshExistentialName(suffix) } - - // Set the fields which point companions at one another. Returns the module. - override def connectModuleToClass(m: ModuleSymbol, moduleClass: ClassSymbol): ModuleSymbol = - synchronized { super.connectModuleToClass(m, moduleClass) } - - override def newFreeTermSymbol(name: TermName, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTermSymbol = - new FreeTermSymbol(name, value, origin) with SynchronizedTermSymbol initFlags flags setInfo info - - override def newFreeTypeSymbol(name: TypeName, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTypeSymbol = - new FreeTypeSymbol(name, value, origin) with SynchronizedTypeSymbol initFlags flags setInfo info - - override protected def makeNoSymbol: NoSymbol = new NoSymbol with SynchronizedSymbol - - trait SynchronizedSymbol extends Symbol { - - override def rawflags = synchronized { super.rawflags } - override def rawflags_=(x: Long) = synchronized { super.rawflags_=(x) } - - override def rawowner = synchronized { super.rawowner } - override def owner_=(owner: Symbol) = synchronized { super.owner_=(owner) } - - override def validTo = synchronized { super.validTo } - override def validTo_=(x: Period) = synchronized { super.validTo_=(x) } - - override def pos = synchronized { super.pos } - override def setPos(pos: Position): this.type = { synchronized { super.setPos(pos) }; this } - - override def privateWithin = synchronized { super.privateWithin } - override def privateWithin_=(sym: Symbol) = synchronized { super.privateWithin_=(sym) } - - override def info = synchronized { super.info } - override def info_=(info: Type) = synchronized { super.info_=(info) } - override def updateInfo(info: Type): Symbol = synchronized { super.updateInfo(info) } - override def rawInfo: Type = synchronized { super.rawInfo } - - override def typeParams: List[Symbol] = synchronized { super.typeParams } - - override def reset(completer: Type): this.type = synchronized { super.reset(completer) } - - override def infosString: String = synchronized { super.infosString } - - override def annotations: List[AnnotationInfo] = synchronized { super.annotations } - override def setAnnotations(annots: List[AnnotationInfo]): this.type = { synchronized { super.setAnnotations(annots) }; this } - - -// ------ creators ------------------------------------------------------------------- - - override protected def createAbstractTypeSymbol(name: TypeName, pos: Position, newFlags: Long): AbstractTypeSymbol = - new AbstractTypeSymbol(this, pos, name) with SynchronizedTypeSymbol initFlags newFlags - - override protected def createAliasTypeSymbol(name: TypeName, pos: Position, newFlags: Long): AliasTypeSymbol = - new AliasTypeSymbol(this, pos, name) with SynchronizedTypeSymbol initFlags newFlags - - override protected def createTypeSkolemSymbol(name: TypeName, origin: AnyRef, pos: Position, newFlags: Long): TypeSkolem = - new TypeSkolem(this, pos, name, origin) with SynchronizedTypeSymbol initFlags newFlags - - override protected def createClassSymbol(name: TypeName, pos: Position, newFlags: Long): ClassSymbol = - new ClassSymbol(this, pos, name) with SynchronizedClassSymbol initFlags newFlags - - override protected def createModuleClassSymbol(name: TypeName, pos: Position, newFlags: Long): ModuleClassSymbol = - new ModuleClassSymbol(this, pos, name) with SynchronizedModuleClassSymbol initFlags newFlags - - override protected def createPackageClassSymbol(name: TypeName, pos: Position, newFlags: Long): PackageClassSymbol = - new PackageClassSymbol(this, pos, name) with SynchronizedModuleClassSymbol initFlags newFlags - - override protected def createRefinementClassSymbol(pos: Position, newFlags: Long): RefinementClassSymbol = - new RefinementClassSymbol(this, pos) with SynchronizedClassSymbol initFlags newFlags - - override protected def createImplClassSymbol(name: TypeName, pos: Position, newFlags: Long): ClassSymbol = - new ClassSymbol(this, pos, name) with ImplClassSymbol with SynchronizedClassSymbol initFlags newFlags - - override protected def createPackageObjectClassSymbol(pos: Position, newFlags: Long): PackageObjectClassSymbol = - new PackageObjectClassSymbol(this, pos) with SynchronizedClassSymbol initFlags newFlags - - override protected def createTermSymbol(name: TermName, pos: Position, newFlags: Long): TermSymbol = - new TermSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags - - override protected def createMethodSymbol(name: TermName, pos: Position, newFlags: Long): MethodSymbol = - new MethodSymbol(this, pos, name) with SynchronizedMethodSymbol initFlags newFlags - - override protected def createModuleSymbol(name: TermName, pos: Position, newFlags: Long): ModuleSymbol = - new ModuleSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags - - override protected def createPackageSymbol(name: TermName, pos: Position, newFlags: Long): ModuleSymbol = createModuleSymbol(name, pos, newFlags) - - // TODO - // override protected def createValueParameterSymbol(name: TermName, pos: Position, newFlags: Long) - // override protected def createValueMemberSymbol(name: TermName, pos: Position, newFlags: Long) - } - -// ------- subclasses --------------------------------------------------------------------- - - trait SynchronizedTermSymbol extends TermSymbol with SynchronizedSymbol { - override def name_=(x: Name) = synchronized { super.name_=(x) } - override def rawname = synchronized { super.rawname } - override def referenced: Symbol = synchronized { super.referenced } - override def referenced_=(x: Symbol) = synchronized { super.referenced_=(x) } - } - - trait SynchronizedMethodSymbol extends MethodSymbol with SynchronizedTermSymbol { - override def typeAsMemberOf(pre: Type): Type = synchronized { super.typeAsMemberOf(pre) } - } - - trait SynchronizedTypeSymbol extends TypeSymbol with SynchronizedSymbol { - override def name_=(x: Name) = synchronized { super.name_=(x) } - override def rawname = synchronized { super.rawname } - override def typeConstructor: Type = synchronized { super.typeConstructor } - override def tpe: Type = synchronized { super.tpe } - } - - trait SynchronizedClassSymbol extends ClassSymbol with SynchronizedTypeSymbol { - override def associatedFile = synchronized { super.associatedFile } - override def associatedFile_=(f: AbstractFileType) = synchronized { super.associatedFile_=(f) } - override def thisSym: Symbol = synchronized { super.thisSym } - override def thisType: Type = synchronized { super.thisType } - override def typeOfThis: Type = synchronized { super.typeOfThis } - override def typeOfThis_=(tp: Type) = synchronized { super.typeOfThis_=(tp) } - override def children = synchronized { super.children } - override def addChild(sym: Symbol) = synchronized { super.addChild(sym) } - } - - trait SynchronizedModuleClassSymbol extends ModuleClassSymbol with SynchronizedClassSymbol { - override def sourceModule = synchronized { super.sourceModule } - // [Eugene++ to Martin] doesn't override anything. no longer necessary? - // def sourceModule_=(module: ModuleSymbol) = synchronized { super.sourceModule_=(module) } - override def implicitMembers: List[Symbol] = synchronized { super.implicitMembers } - } -} - diff --git a/src/compiler/scala/reflect/runtime/SynchronizedTypes.scala b/src/compiler/scala/reflect/runtime/SynchronizedTypes.scala deleted file mode 100644 index e1eb7a57fe..0000000000 --- a/src/compiler/scala/reflect/runtime/SynchronizedTypes.scala +++ /dev/null @@ -1,88 +0,0 @@ -package scala.reflect -package runtime - -/** This trait overrides methods in reflect.internal, bracketing - * them in synchronized { ... } to make them thread-safe - */ -trait SynchronizedTypes extends internal.Types { self: SymbolTable => - - // No sharing of map objects: - override protected def commonOwnerMap = new CommonOwnerMap - - private object uniqueLock - - override def unique[T <: Type](tp: T): T = uniqueLock.synchronized { super.unique(tp) } - - class SynchronizedUndoLog extends UndoLog { - - override def clear() = - synchronized { super.clear() } - - override def undo[T](block: => T): T = - synchronized { super.undo(block) } - - override def undoUnless(block: => Boolean): Boolean = - synchronized { super.undoUnless(block) } - } - - override protected def newUndoLog = new SynchronizedUndoLog - - override protected def baseTypeOfNonClassTypeRef(tpe: NonClassTypeRef, clazz: Symbol) = - synchronized { super.baseTypeOfNonClassTypeRef(tpe, clazz) } - - private object subsametypeLock - - override def isSameType(tp1: Type, tp2: Type): Boolean = - subsametypeLock.synchronized { super.isSameType(tp1, tp2) } - - override def isDifferentType(tp1: Type, tp2: Type): Boolean = - subsametypeLock.synchronized { super.isDifferentType(tp1, tp2) } - - override def isSubType(tp1: Type, tp2: Type, depth: Int): Boolean = - subsametypeLock.synchronized { super.isSubType(tp1, tp2, depth) } - - private object lubglbLock - - override def glb(ts: List[Type]): Type = - lubglbLock.synchronized { super.glb(ts) } - - override def lub(ts: List[Type]): Type = - lubglbLock.synchronized { super.lub(ts) } - - private object indentLock - - override protected def explain[T](op: String, p: (Type, T) => Boolean, tp1: Type, arg2: T): Boolean = { - indentLock.synchronized { super.explain(op, p, tp1, arg2) } - } - - private object toStringLock - - override protected def typeToString(tpe: Type): String = - toStringLock.synchronized(super.typeToString(tpe)) - - /* The idea of caches is as follows. - * When in reflexive mode, a cache is either null, or one sentinal - * value representing undefined or the final defined - * value. Hence, we can ask in non-synchronized ode whether the cache field - * is non null and different from the sentinel (if a sentinel exists). - * If that's true, the cache value is current. - * Otherwise we arrive in one of the defined... methods listed below - * which go through all steps in synchronized mode. - */ - - override protected def defineUnderlyingOfSingleType(tpe: SingleType) = - tpe.synchronized { super.defineUnderlyingOfSingleType(tpe) } - - override protected def defineBaseTypeSeqOfCompoundType(tpe: CompoundType) = - tpe.synchronized { super.defineBaseTypeSeqOfCompoundType(tpe) } - - override protected def defineBaseClassesOfCompoundType(tpe: CompoundType) = - tpe.synchronized { super.defineBaseClassesOfCompoundType(tpe) } - - override protected def defineParentsOfTypeRef(tpe: TypeRef) = - tpe.synchronized { super.defineParentsOfTypeRef(tpe) } - - override protected def defineBaseTypeSeqOfTypeRef(tpe: TypeRef) = - tpe.synchronized { super.defineBaseTypeSeqOfTypeRef(tpe) } - -} diff --git a/src/compiler/scala/reflect/runtime/TwoWayCache.scala b/src/compiler/scala/reflect/runtime/TwoWayCache.scala deleted file mode 100644 index c7bfb3435d..0000000000 --- a/src/compiler/scala/reflect/runtime/TwoWayCache.scala +++ /dev/null @@ -1,52 +0,0 @@ -package scala.reflect -package runtime - -/** A cache that maintains a bijection between Java reflection type `J` - * and Scala reflection type `S`. - */ -import collection.mutable.HashMap - -private[runtime] class TwoWayCache[J, S] { - - private val toScalaMap = new HashMap[J, S] - private val toJavaMap = new HashMap[S, J] - - def enter(j: J, s: S) = synchronized { - // debugInfo("cached: "+j+"/"+s) - toScalaMap(j) = s - toJavaMap(s) = j - } - - def toScala(key: J)(body: => S): S = synchronized { - toScalaMap get key match { - case Some(v) => - v - case none => - val result = body - enter(key, result) - result - } - } - - def toJava(key: S)(body: => J): J = synchronized { - toJavaMap get key match { - case Some(v) => - v - case none => - val result = body - enter(result, key) - result - } - } - - def toJavaOption(key: S)(body: => Option[J]): Option[J] = synchronized { - toJavaMap get key match { - case None => - val result = body - for (value <- result) enter(value, key) - result - case some => some - } - } -} - diff --git a/src/compiler/scala/reflect/runtime/package.scala b/src/compiler/scala/reflect/runtime/package.scala deleted file mode 100644 index a5809a2629..0000000000 --- a/src/compiler/scala/reflect/runtime/package.scala +++ /dev/null @@ -1,26 +0,0 @@ -package scala.reflect - -import language.experimental.macros - -package object runtime { - - // type is api.JavaUniverse because we only want to expose the `scala.reflect.api.*` subset of reflection - lazy val universe: api.JavaUniverse = new runtime.JavaUniverse - - // [Eugene++ to Martin] removed `mirrorOfLoader`, because one can use `universe.runtimeMirror` instead - - def currentMirror: universe.Mirror = macro Macros.currentMirror -} - -package runtime { - object Macros { - def currentMirror(c: scala.reflect.makro.Context): c.Expr[universe.Mirror] = { - import c.universe._ - val runtimeClass = c.reifyEnclosingRuntimeClass - if (runtimeClass.isEmpty) c.abort(c.enclosingPosition, "call site does not have an enclosing class") - val runtimeUniverse = Select(Select(Select(Ident(newTermName("scala")), newTermName("reflect")), newTermName("runtime")), newTermName("universe")) - val currentMirror = Apply(Select(runtimeUniverse, newTermName("runtimeMirror")), List(Select(runtimeClass, newTermName("getClassLoader")))) - c.Expr[Nothing](currentMirror)(c.TypeTag.Nothing) - } - } -} diff --git a/src/compiler/scala/tools/nsc/io/AbstractFile.scala b/src/compiler/scala/tools/nsc/io/AbstractFile.scala deleted file mode 100644 index 3faaeaeaec..0000000000 --- a/src/compiler/scala/tools/nsc/io/AbstractFile.scala +++ /dev/null @@ -1,259 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - - -package scala.tools.nsc -package io - -import java.io.{ FileOutputStream, IOException, InputStream, OutputStream, BufferedOutputStream } -// [scala-reflect.jar migration note] uncomment when creating scala-reflect.jar -// import java.io.{ File => JFile } -import java.net.URL -import scala.collection.mutable.ArrayBuffer - -/** - * @author Philippe Altherr - * @version 1.0, 23/03/2004 - */ -object AbstractFile { - /** Returns "getFile(new File(path))". */ - def getFile(path: String): AbstractFile = getFile(File(path)) - def getFile(path: Path): AbstractFile = getFile(path.toFile) - - /** - * If the specified File exists and is a regular file, returns an - * abstract regular file backed by it. Otherwise, returns <code>null</code>. - */ - def getFile(file: File): AbstractFile = - if (file.isFile) new PlainFile(file) else null - - /** Returns "getDirectory(new File(path))". */ - def getDirectory(path: Path): AbstractFile = getDirectory(path.toFile) - - /** - * If the specified File exists and is either a directory or a - * readable zip or jar archive, returns an abstract directory - * backed by it. Otherwise, returns <code>null</code>. - * - * @param file ... - * @return ... - */ - def getDirectory(file: File): AbstractFile = - if (file.isDirectory) new PlainFile(file) - else if (file.isFile && Path.isExtensionJarOrZip(file.jfile)) ZipArchive fromFile file - else null - - /** - * If the specified URL exists and is a readable zip or jar archive, - * returns an abstract directory backed by it. Otherwise, returns - * <code>null</code>. - * - * @param file ... - * @return ... - */ - def getURL(url: URL): AbstractFile = { - if (url == null || !Path.isExtensionJarOrZip(url.getPath)) null - else ZipArchive fromURL url - } -} - -/** - * <p> - * This class and its children serve to unify handling of files and - * directories. These files and directories may or may not have some - * real counter part within the file system. For example, some file - * handles reference files within a zip archive or virtual ones - * that exist only in memory. - * </p> - * <p> - * Every abstract file has a path (i.e. a full name) and a name - * (i.e. a short name) and may be backed by some real File. There are - * two different kinds of abstract files: regular files and - * directories. Regular files may be read and have a last modification - * time. Directories may list their content and look for subfiles with - * a specified name or path and of a specified kind. - * </p> - * <p> - * The interface does <b>not</b> allow to access the content. - * The class <code>symtab.classfile.AbstractFileReader</code> accesses - * bytes, knowing that the character set of classfiles is UTF-8. For - * all other cases, the class <code>SourceFile</code> is used, which honors - * <code>global.settings.encoding.value</code>. - * </p> - */ -abstract class AbstractFile extends reflect.internal.AbstractFileApi with Iterable[AbstractFile] { - - /** Returns the name of this abstract file. */ - def name: String - - /** Returns the path of this abstract file. */ - def path: String - - /** Returns the path of this abstract file in a canonical form. */ - def canonicalPath: String = if (file == null) path else file.getCanonicalPath - - /** Checks extension case insensitively. */ - def hasExtension(other: String) = extension == other.toLowerCase - private lazy val extension: String = Path.extension(name) - - /** The absolute file, if this is a relative file. */ - def absolute: AbstractFile - - /** Returns the containing directory of this abstract file */ - def container : AbstractFile - - /** Returns the underlying File if any and null otherwise. */ - def file: JFile - - /** An underlying source, if known. Mostly, a zip/jar file. */ - def underlyingSource: Option[AbstractFile] = None - - /** Does this abstract file denote an existing file? */ - def exists: Boolean = (file eq null) || file.exists - - /** Does this abstract file represent something which can contain classfiles? */ - def isClassContainer = isDirectory || (file != null && (extension == "jar" || extension == "zip")) - - /** Create a file on disk, if one does not exist already. */ - def create(): Unit - - /** Delete the underlying file or directory (recursively). */ - def delete(): Unit - - /** Is this abstract file a directory? */ - def isDirectory: Boolean - - /** Returns the time that this abstract file was last modified. */ - def lastModified: Long - - /** returns an input stream so the file can be read */ - def input: InputStream - - /** Returns an output stream for writing the file */ - def output: OutputStream - - /** Returns a buffered output stream for writing the file - defaults to out */ - def bufferedOutput: BufferedOutputStream = new BufferedOutputStream(output) - - /** size of this file if it is a concrete file. */ - def sizeOption: Option[Int] = None - - def toURL: URL = if (file == null) null else file.toURI.toURL - - /** Returns contents of file (if applicable) in a Char array. - * warning: use <code>Global.getSourceFile()</code> to use the proper - * encoding when converting to the char array. - */ - @throws(classOf[IOException]) - def toCharArray = new String(toByteArray).toCharArray - - /** Returns contents of file (if applicable) in a byte array. - */ - @throws(classOf[IOException]) - def toByteArray: Array[Byte] = { - val in = input - var rest = sizeOption.getOrElse(0) - val arr = new Array[Byte](rest) - while (rest > 0) { - val res = in.read(arr, arr.length - rest, rest) - if (res == -1) - throw new IOException("read error") - rest -= res - } - in.close() - arr - } - - /** Returns all abstract subfiles of this abstract directory. */ - def iterator: Iterator[AbstractFile] - - /** Returns the abstract file in this abstract directory with the specified - * name. If there is no such file, returns <code>null</code>. The argument - * <code>directory</code> tells whether to look for a directory or - * a regular file. - */ - def lookupName(name: String, directory: Boolean): AbstractFile - - /** Returns an abstract file with the given name. It does not - * check that it exists. - */ - def lookupNameUnchecked(name: String, directory: Boolean): AbstractFile - - /** Returns the abstract file in this abstract directory with the specified - * path relative to it, If there is no such file, returns null. The argument - * <code>directory</code> tells whether to look for a directory or a regular - * file. - * - * @param path ... - * @param directory ... - * @return ... - */ - def lookupPath(path: String, directory: Boolean): AbstractFile = { - lookup((f, p, dir) => f.lookupName(p, dir), path, directory) - } - - /** Return an abstract file that does not check that `path` denotes - * an existing file. - */ - def lookupPathUnchecked(path: String, directory: Boolean): AbstractFile = { - lookup((f, p, dir) => f.lookupNameUnchecked(p, dir), path, directory) - } - - private def lookup(getFile: (AbstractFile, String, Boolean) => AbstractFile, - path0: String, - directory: Boolean): AbstractFile = { - val separator = java.io.File.separatorChar - // trim trailing '/'s - val path: String = if (path0.last == separator) path0 dropRight 1 else path0 - val length = path.length() - assert(length > 0 && !(path.last == separator), path) - var file = this - var start = 0 - while (true) { - val index = path.indexOf(separator, start) - assert(index < 0 || start < index, ((path, directory, start, index))) - val name = path.substring(start, if (index < 0) length else index) - file = getFile(file, name, if (index < 0) directory else true) - if ((file eq null) || index < 0) return file - start = index + 1 - } - file - } - - private def fileOrSubdirectoryNamed(name: String, isDir: Boolean): AbstractFile = { - val lookup = lookupName(name, isDir) - if (lookup != null) lookup - else { - val jfile = new JFile(file, name) - if (isDir) jfile.mkdirs() else jfile.createNewFile() - new PlainFile(jfile) - } - } - - /** - * Get the file in this directory with the given name, - * creating an empty file if it does not already existing. - */ - def fileNamed(name: String): AbstractFile = { - assert(isDirectory, "Tried to find '%s' in '%s' but it is not a directory".format(name, path)) - fileOrSubdirectoryNamed(name, false) - } - - /** - * Get the subdirectory with a given name, creating it if it - * does not already exist. - */ - def subdirectoryNamed(name: String): AbstractFile = { - assert (isDirectory, "Tried to find '%s' in '%s' but it is not a directory".format(name, path)) - fileOrSubdirectoryNamed(name, true) - } - - protected def unsupported(): Nothing = unsupported(null) - protected def unsupported(msg: String): Nothing = throw new UnsupportedOperationException(msg) - - /** Returns the path of this abstract file. */ - override def toString() = path - -} diff --git a/src/compiler/scala/tools/nsc/io/Directory.scala b/src/compiler/scala/tools/nsc/io/Directory.scala deleted file mode 100644 index 0eecd9a6e2..0000000000 --- a/src/compiler/scala/tools/nsc/io/Directory.scala +++ /dev/null @@ -1,76 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.tools.nsc -package io - -// [scala-reflect.jar migration note] uncomment when creating scala-reflect.jar -// import java.io.{ File => JFile } - -object Directory { - import scala.util.Properties.{ tmpDir, userHome, userDir } - - private def normalizePath(s: String) = Some(apply(Path(s).normalize)) - def Current: Option[Directory] = if (userDir == "") None else normalizePath(userDir) - def Home: Option[Directory] = if (userHome == "") None else normalizePath(userHome) - def TmpDir: Option[Directory] = if (tmpDir == "") None else normalizePath(tmpDir) - - def apply(path: Path): Directory = path.toDirectory - - // Like File.makeTemp but creates a directory instead - def makeTemp(prefix: String = Path.randomPrefix, suffix: String = null, dir: JFile = null): Directory = { - val path = File.makeTemp(prefix, suffix, dir) - path.delete() - path.createDirectory() - } -} -import Path._ - -/** An abstraction for directories. - * - * @author Paul Phillips - * @since 2.8 - */ -class Directory(jfile: JFile) extends Path(jfile) { - override def toAbsolute: Directory = if (isAbsolute) this else super.toAbsolute.toDirectory - override def toDirectory: Directory = this - override def toFile: File = new File(jfile) - override def isValid = jfile.isDirectory() || !jfile.exists() - override def normalize: Directory = super.normalize.toDirectory - - /** An iterator over the contents of this directory. - */ - def list: Iterator[Path] = - jfile.listFiles match { - case null => Iterator.empty - case xs => xs.iterator map Path.apply - } - - def dirs: Iterator[Directory] = list collect { case x: Directory => x } - def files: Iterator[File] = list collect { case x: File => x } - - override def walkFilter(cond: Path => Boolean): Iterator[Path] = - list filter cond flatMap (_ walkFilter cond) - - def deepDirs: Iterator[Directory] = Path.onlyDirs(deepList()) - def deepFiles: Iterator[File] = Path.onlyFiles(deepList()) - - /** If optional depth argument is not given, will recurse - * until it runs out of contents. - */ - def deepList(depth: Int = -1): Iterator[Path] = - if (depth < 0) list ++ (dirs flatMap (_ deepList (depth))) - else if (depth == 0) Iterator.empty - else list ++ (dirs flatMap (_ deepList (depth - 1))) - - /** An iterator over the directories underneath this directory, - * to the (optionally) given depth. - */ - def subdirs(depth: Int = 1): Iterator[Directory] = - deepList(depth) collect { case x: Directory => x } -} diff --git a/src/compiler/scala/tools/nsc/io/File.scala b/src/compiler/scala/tools/nsc/io/File.scala deleted file mode 100644 index 4cea8439b1..0000000000 --- a/src/compiler/scala/tools/nsc/io/File.scala +++ /dev/null @@ -1,194 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - -package scala.tools.nsc -package io - -import java.io.{ - FileInputStream, FileOutputStream, BufferedReader, BufferedWriter, InputStreamReader, OutputStreamWriter, - BufferedInputStream, BufferedOutputStream, IOException, PrintStream, PrintWriter, Closeable => JCloseable } -// [scala-reflect.jar migration note] uncomment when creating scala-reflect.jar -// import java.io.{ File => JFile } -import java.nio.channels.{ Channel, FileChannel } -import scala.io.Codec -import language.{reflectiveCalls, implicitConversions} - -object File { - def pathSeparator = java.io.File.pathSeparator - def separator = java.io.File.separator - - def apply(path: Path)(implicit codec: Codec) = new File(path.jfile)(codec) - - // Create a temporary file, which will be deleted upon jvm exit. - def makeTemp(prefix: String = Path.randomPrefix, suffix: String = null, dir: JFile = null) = { - val jfile = java.io.File.createTempFile(prefix, suffix, dir) - jfile.deleteOnExit() - apply(jfile) - } - - type HasClose = { def close(): Unit } - - def closeQuietly(target: HasClose) { - try target.close() catch { case e: IOException => } - } - def closeQuietly(target: JCloseable) { - try target.close() catch { case e: IOException => } - } - - // this is a workaround for http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6503430 - // we are using a static initializer to statically initialize a java class so we don't - // trigger java.lang.InternalErrors later when using it concurrently. We ignore all - // the exceptions so as not to cause spurious failures when no write access is available, - // e.g. google app engine. - // - // XXX need to put this behind a setting. - // - // try { - // import Streamable.closing - // val tmp = java.io.File.createTempFile("bug6503430", null, null) - // try closing(new FileInputStream(tmp)) { in => - // val inc = in.getChannel() - // closing(new FileOutputStream(tmp, true)) { out => - // out.getChannel().transferFrom(inc, 0, 0) - // } - // } - // finally tmp.delete() - // } - // catch { - // case _: IllegalArgumentException | _: IllegalStateException | _: IOException | _: SecurityException => () - // } -} -import File._ -import Path._ - -/** An abstraction for files. For character data, a Codec - * can be supplied at either creation time or when a method - * involving character data is called (with the latter taking - * precedence if supplied.) If neither is available, the value - * of scala.io.Codec.default is used. - * - * @author Paul Phillips - * @since 2.8 - */ -class File(jfile: JFile)(implicit constructorCodec: Codec) extends Path(jfile) with Streamable.Chars { - override val creationCodec = constructorCodec - def withCodec(codec: Codec): File = new File(jfile)(codec) - - override def addExtension(ext: String): File = super.addExtension(ext).toFile - override def toAbsolute: File = if (isAbsolute) this else super.toAbsolute.toFile - override def toDirectory: Directory = new Directory(jfile) - override def toFile: File = this - override def normalize: File = super.normalize.toFile - override def isValid = jfile.isFile() || !jfile.exists() - override def length = super[Path].length - override def walkFilter(cond: Path => Boolean): Iterator[Path] = - if (cond(this)) Iterator.single(this) else Iterator.empty - - /** Obtains an InputStream. */ - def inputStream() = new FileInputStream(jfile) - - /** Obtains a OutputStream. */ - def outputStream(append: Boolean = false) = new FileOutputStream(jfile, append) - def bufferedOutput(append: Boolean = false) = new BufferedOutputStream(outputStream(append)) - def printStream(append: Boolean = false) = new PrintStream(outputStream(append), true) - - /** Obtains an OutputStreamWriter wrapped around a FileOutputStream. - * This should behave like a less broken version of java.io.FileWriter, - * in that unlike the java version you can specify the encoding. - */ - def writer(): OutputStreamWriter = writer(false) - def writer(append: Boolean): OutputStreamWriter = writer(append, creationCodec) - def writer(append: Boolean, codec: Codec): OutputStreamWriter = - new OutputStreamWriter(outputStream(append), codec.charSet) - - /** Wraps a BufferedWriter around the result of writer(). - */ - def bufferedWriter(): BufferedWriter = bufferedWriter(false) - def bufferedWriter(append: Boolean): BufferedWriter = bufferedWriter(append, creationCodec) - def bufferedWriter(append: Boolean, codec: Codec): BufferedWriter = - new BufferedWriter(writer(append, codec)) - - def printWriter(): PrintWriter = new PrintWriter(bufferedWriter(), true) - def printWriter(append: Boolean): PrintWriter = new PrintWriter(bufferedWriter(append), true) - - /** Creates a new file and writes all the Strings to it. */ - def writeAll(strings: String*): Unit = { - val out = bufferedWriter() - try strings foreach (out write _) - finally out close - } - - def writeBytes(bytes: Array[Byte]): Unit = { - val out = bufferedOutput() - try out write bytes - finally out close - } - - def appendAll(strings: String*): Unit = { - val out = bufferedWriter(append = true) - try strings foreach (out write _) - finally out.close() - } - - /** Calls println on each string (so it adds a newline in the PrintWriter fashion.) */ - def printlnAll(strings: String*): Unit = { - val out = printWriter() - try strings foreach (out println _) - finally out close - } - - def safeSlurp(): Option[String] = - try Some(slurp()) - catch { case _: IOException => None } - - def copyTo(destPath: Path, preserveFileDate: Boolean = false): Boolean = { - val CHUNK = 1024 * 1024 * 16 // 16 MB - val dest = destPath.toFile - if (!isValid) fail("Source %s is not a valid file." format name) - if (this.normalize == dest.normalize) fail("Source and destination are the same.") - if (!dest.parent.exists) fail("Destination cannot be created.") - if (dest.exists && !dest.canWrite) fail("Destination exists but is not writable.") - if (dest.isDirectory) fail("Destination exists but is a directory.") - - lazy val in_s = inputStream() - lazy val out_s = dest.outputStream() - lazy val in = in_s.getChannel() - lazy val out = out_s.getChannel() - - try { - val size = in.size() - var pos, count = 0L - while (pos < size) { - count = (size - pos) min CHUNK - pos += out.transferFrom(in, pos, count) - } - } - finally List[HasClose](out, out_s, in, in_s) foreach closeQuietly - - if (this.length != dest.length) - fail("Failed to completely copy %s to %s".format(name, dest.name)) - - if (preserveFileDate) - dest.lastModified = this.lastModified - - true - } - - /** Reflection since we're into the java 6+ API. - */ - def setExecutable(executable: Boolean, ownerOnly: Boolean = true): Boolean = { - type JBoolean = java.lang.Boolean - val method = - try classOf[JFile].getMethod("setExecutable", classOf[Boolean], classOf[Boolean]) - catch { case _: NoSuchMethodException => return false } - - try method.invoke(jfile, executable: JBoolean, ownerOnly: JBoolean).asInstanceOf[JBoolean].booleanValue - catch { case _: Exception => false } - } -} diff --git a/src/compiler/scala/tools/nsc/io/FileOperationException.scala b/src/compiler/scala/tools/nsc/io/FileOperationException.scala deleted file mode 100644 index f23658efbc..0000000000 --- a/src/compiler/scala/tools/nsc/io/FileOperationException.scala +++ /dev/null @@ -1,13 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - -package scala.tools.nsc -package io - -case class FileOperationException(msg: String) extends RuntimeException(msg) diff --git a/src/compiler/scala/tools/nsc/io/NoAbstractFile.scala b/src/compiler/scala/tools/nsc/io/NoAbstractFile.scala deleted file mode 100644 index e468356722..0000000000 --- a/src/compiler/scala/tools/nsc/io/NoAbstractFile.scala +++ /dev/null @@ -1,32 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Paul Phillips - */ - -package scala.tools.nsc -package io - -import java.io.InputStream -// [scala-reflect.jar migration note] uncomment when creating scala-reflect.jar -// import java.io.{ File => JFile } - -/** A distinguished object so you can avoid both null - * and Option. - */ -object NoAbstractFile extends AbstractFile { - def absolute: AbstractFile = this - def container: AbstractFile = this - def create(): Unit = ??? - def delete(): Unit = ??? - def file: JFile = null - def input: InputStream = null - def isDirectory: Boolean = false - def iterator: Iterator[AbstractFile] = Iterator.empty - def lastModified: Long = 0L - def lookupName(name: String, directory: Boolean): AbstractFile = null - def lookupNameUnchecked(name: String, directory: Boolean): AbstractFile = null - def name: String = "" - def output: java.io.OutputStream = null - def path: String = "" - override def toByteArray = Array[Byte]() -} diff --git a/src/compiler/scala/tools/nsc/io/Path.scala b/src/compiler/scala/tools/nsc/io/Path.scala deleted file mode 100644 index 1db015e2f5..0000000000 --- a/src/compiler/scala/tools/nsc/io/Path.scala +++ /dev/null @@ -1,289 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Paul Phillips - */ - -package scala.tools.nsc -package io - -import java.io.{ - FileInputStream, FileOutputStream, BufferedReader, BufferedWriter, InputStreamReader, OutputStreamWriter, - BufferedInputStream, BufferedOutputStream, RandomAccessFile } -// [scala-reflect.jar migration note] uncomment when creating scala-reflect.jar -// import java.io.{ File => JFile } -import java.net.{ URI, URL } -import scala.util.Random.alphanumeric -import language.implicitConversions - -/** An abstraction for filesystem paths. The differences between - * Path, File, and Directory are primarily to communicate intent. - * Since the filesystem can change at any time, there is no way to - * reliably associate Files only with files and so on. Any Path - * can be converted to a File or Directory (and thus gain access to - * the additional entity specific methods) by calling toFile or - * toDirectory, which has no effect on the filesystem. - * - * Also available are createFile and createDirectory, which attempt - * to create the path in question. - * - * @author Paul Phillips - * @since 2.8 - */ - -object Path { - def isExtensionJarOrZip(jfile: JFile): Boolean = isExtensionJarOrZip(jfile.getName) - def isExtensionJarOrZip(name: String): Boolean = { - val ext = extension(name) - ext == "jar" || ext == "zip" - } - def extension(name: String): String = { - var i = name.length - 1 - while (i >= 0 && name.charAt(i) != '.') - i -= 1 - - if (i < 0) "" - else name.substring(i + 1).toLowerCase - } - // [Eugene++] I hope that noone relied on this method -// def isJarOrZip(f: Path, examineFile: Boolean = true) = Jar.isJarOrZip(f, examineFile) - - // not certain these won't be problematic, but looks good so far - implicit def string2path(s: String): Path = apply(s) - implicit def jfile2path(jfile: JFile): Path = apply(jfile) - - // java 7 style, we don't use it yet - // object AccessMode extends Enumeration { - // val EXECUTE, READ, WRITE = Value - // } - // def checkAccess(modes: AccessMode*): Boolean = { - // modes foreach { - // case EXECUTE => throw new Exception("Unsupported") // can't check in java 5 - // case READ => if (!jfile.canRead()) return false - // case WRITE => if (!jfile.canWrite()) return false - // } - // true - // } - - def onlyDirs(xs: Iterator[Path]): Iterator[Directory] = xs filter (_.isDirectory) map (_.toDirectory) - def onlyDirs(xs: List[Path]): List[Directory] = xs filter (_.isDirectory) map (_.toDirectory) - def onlyFiles(xs: Iterator[Path]): Iterator[File] = xs filter (_.isFile) map (_.toFile) - def onlyFiles(xs: List[Path]): List[File] = xs filter (_.isFile) map (_.toFile) - - def roots: List[Path] = java.io.File.listRoots().toList map Path.apply - - def apply(segments: Seq[String]): Path = apply(segments mkString java.io.File.separator) - def apply(path: String): Path = apply(new JFile(path)) - def apply(jfile: JFile): Path = - if (jfile.isFile) new File(jfile) - else if (jfile.isDirectory) new Directory(jfile) - else new Path(jfile) - - /** Avoiding any shell/path issues by only using alphanumerics. */ - private[io] def randomPrefix = alphanumeric take 6 mkString - private[io] def fail(msg: String) = throw FileOperationException(msg) -} -import Path._ - -/** The Path constructor is private so we can enforce some - * semantics regarding how a Path might relate to the world. - */ -class Path private[io] (val jfile: JFile) { - val separator = java.io.File.separatorChar - val separatorStr = java.io.File.separator - - // Validation: this verifies that the type of this object and the - // contents of the filesystem are in agreement. All objects are - // valid except File objects whose path points to a directory and - // Directory objects whose path points to a file. - def isValid: Boolean = true - - // conversions - def toFile: File = new File(jfile) - def toDirectory: Directory = new Directory(jfile) - def toAbsolute: Path = if (isAbsolute) this else Path(jfile.getAbsolutePath()) - def toCanonical: Path = Path(jfile.getCanonicalPath()) - def toURI: URI = jfile.toURI() - def toURL: URL = toURI.toURL() - /** If this path is absolute, returns it: otherwise, returns an absolute - * path made up of root / this. - */ - def toAbsoluteWithRoot(root: Path) = if (isAbsolute) this else root.toAbsolute / this - - /** Creates a new Path with the specified path appended. Assumes - * the type of the new component implies the type of the result. - */ - def /(child: Path): Path = if (isEmpty) child else new Path(new JFile(jfile, child.path)) - def /(child: Directory): Directory = /(child: Path).toDirectory - def /(child: File): File = /(child: Path).toFile - - /** If this path is a container, recursively iterate over its contents. - * The supplied condition is a filter which is applied to each element, - * with that branch of the tree being closed off if it is true. So for - * example if the condition is true for some subdirectory, nothing - * under that directory will be in the Iterator; but otherwise each - * file and subdirectory underneath it will appear. - */ - def walkFilter(cond: Path => Boolean): Iterator[Path] = - if (isFile) toFile walkFilter cond - else if (isDirectory) toDirectory walkFilter cond - else Iterator.empty - - /** Equivalent to walkFilter(_ => false). - */ - def walk: Iterator[Path] = walkFilter(_ => true) - - // identity - def name: String = jfile.getName() - def path: String = jfile.getPath() - def normalize: Path = Path(jfile.getAbsolutePath()) - def isRootPath: Boolean = roots exists (_ isSame this) - - def resolve(other: Path) = if (other.isAbsolute || isEmpty) other else /(other) - def relativize(other: Path) = { - assert(isAbsolute == other.isAbsolute, "Paths not of same type: "+this+", "+other) - - def createRelativePath(baseSegs: List[String], otherSegs: List[String]) : String = { - (baseSegs, otherSegs) match { - case (b :: bs, o :: os) if b == o => createRelativePath(bs, os) - case (bs, os) => ((".."+separator)*bs.length)+os.mkString(separatorStr) - } - } - - Path(createRelativePath(segments, other.segments)) - } - - // derived from identity - def root: Option[Path] = roots find (this startsWith _) - def segments: List[String] = (path split separator).toList filterNot (_.length == 0) - /** - * @return The path of the parent directory, or root if path is already root - */ - def parent: Directory = path match { - case "" | "." => Directory("..") - case _ => - // the only solution <-- a comment which could have used elaboration - if (segments.nonEmpty && segments.last == "..") - (path / "..").toDirectory - else jfile.getParent match { - case null => - if (isAbsolute) toDirectory // it should be a root. BTW, don't need to worry about relative pathed root - else Directory(".") // a dir under pwd - case x => - Directory(x) - } - } - def parents: List[Directory] = { - val p = parent - if (p isSame this) Nil else p :: p.parents - } - // if name ends with an extension (e.g. "foo.jpg") returns the extension ("jpg"), otherwise "" - def extension: String = { - var i = name.length - 1 - while (i >= 0 && name.charAt(i) != '.') - i -= 1 - - if (i < 0) "" - else name.substring(i + 1) - } - // def extension: String = (name lastIndexOf '.') match { - // case -1 => "" - // case idx => name drop (idx + 1) - // } - // compares against extensions in a CASE INSENSITIVE way. - def hasExtension(ext: String, exts: String*) = { - val lower = extension.toLowerCase - ext.toLowerCase == lower || exts.exists(_.toLowerCase == lower) - } - // returns the filename without the extension. - def stripExtension: String = name stripSuffix ("." + extension) - // returns the Path with the extension. - def addExtension(ext: String): Path = Path(path + "." + ext) - // changes the existing extension out for a new one, or adds it - // if the current path has none. - def changeExtension(ext: String): Path = ( - if (extension == "") addExtension(ext) - else Path(path.stripSuffix(extension) + ext) - ) - - // conditionally execute - def ifFile[T](f: File => T): Option[T] = if (isFile) Some(f(toFile)) else None - def ifDirectory[T](f: Directory => T): Option[T] = if (isDirectory) Some(f(toDirectory)) else None - - // Boolean tests - def canRead = jfile.canRead() - def canWrite = jfile.canWrite() - def exists = jfile.exists() - def notExists = try !jfile.exists() catch { case ex: SecurityException => false } - - def isFile = jfile.isFile() - def isDirectory = jfile.isDirectory() - def isAbsolute = jfile.isAbsolute() - def isHidden = jfile.isHidden() - def isEmpty = path.length == 0 - - // Information - def lastModified = jfile.lastModified() - def lastModified_=(time: Long) = jfile setLastModified time // should use setXXX function? - def length = jfile.length() - - // Boolean path comparisons - def endsWith(other: Path) = segments endsWith other.segments - def startsWith(other: Path) = segments startsWith other.segments - def isSame(other: Path) = toCanonical == other.toCanonical - def isFresher(other: Path) = lastModified > other.lastModified - - // creations - def createDirectory(force: Boolean = true, failIfExists: Boolean = false): Directory = { - val res = if (force) jfile.mkdirs() else jfile.mkdir() - if (!res && failIfExists && exists) fail("Directory '%s' already exists." format name) - else if (isDirectory) toDirectory - else new Directory(jfile) - } - def createFile(failIfExists: Boolean = false): File = { - val res = jfile.createNewFile() - if (!res && failIfExists && exists) fail("File '%s' already exists." format name) - else if (isFile) toFile - else new File(jfile) - } - - // deletions - def delete() = jfile.delete() - def deleteIfExists() = if (jfile.exists()) delete() else false - - /** Deletes the path recursively. Returns false on failure. - * Use with caution! - */ - def deleteRecursively(): Boolean = deleteRecursively(jfile) - private def deleteRecursively(f: JFile): Boolean = { - if (f.isDirectory) f.listFiles match { - case null => - case xs => xs foreach deleteRecursively - } - f.delete() - } - - def truncate() = - isFile && { - val raf = new RandomAccessFile(jfile, "rw") - raf setLength 0 - raf.close() - length == 0 - } - - def touch(modTime: Long = System.currentTimeMillis) = { - createFile() - if (isFile) - lastModified = modTime - } - - // todo - // def copyTo(target: Path, options ...): Boolean - // def moveTo(target: Path, options ...): Boolean - - override def toString() = path - override def equals(other: Any) = other match { - case x: Path => path == x.path - case _ => false - } - override def hashCode() = path.hashCode() -} diff --git a/src/compiler/scala/tools/nsc/io/PlainFile.scala b/src/compiler/scala/tools/nsc/io/PlainFile.scala deleted file mode 100644 index 21276e8740..0000000000 --- a/src/compiler/scala/tools/nsc/io/PlainFile.scala +++ /dev/null @@ -1,102 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - - -package scala.tools.nsc -package io - -import java.io.{ FileInputStream, FileOutputStream, IOException } -import PartialFunction._ - -object PlainFile { - /** - * If the specified File exists, returns an abstract file backed - * by it. Otherwise, returns null. - */ - def fromPath(file: Path): PlainFile = - if (file.isDirectory) new PlainDirectory(file.toDirectory) - else if (file.isFile) new PlainFile(file) - else null -} - -class PlainDirectory(givenPath: Directory) extends PlainFile(givenPath) { - override def isDirectory = true - override def iterator = givenPath.list filter (_.exists) map (x => new PlainFile(x)) - override def delete(): Unit = givenPath.deleteRecursively() -} - -/** This class implements an abstract file backed by a File. - */ -class PlainFile(val givenPath: Path) extends AbstractFile { - assert(path ne null) - - val file = givenPath.jfile - override def underlyingSource = Some(this) - - private val fpath = givenPath.toAbsolute - - /** Returns the name of this abstract file. */ - def name = givenPath.name - - /** Returns the path of this abstract file. */ - def path = givenPath.path - - /** The absolute file. */ - def absolute = new PlainFile(givenPath.toAbsolute) - - override def container: AbstractFile = new PlainFile(givenPath.parent) - override def input = givenPath.toFile.inputStream() - override def output = givenPath.toFile.outputStream() - override def sizeOption = Some(givenPath.length.toInt) - - override def toString = path - override def hashCode(): Int = fpath.hashCode - override def equals(that: Any): Boolean = that match { - case x: PlainFile => fpath == x.fpath - case _ => false - } - - /** Is this abstract file a directory? */ - def isDirectory: Boolean = givenPath.isDirectory - - /** Returns the time that this abstract file was last modified. */ - def lastModified: Long = givenPath.lastModified - - /** Returns all abstract subfiles of this abstract directory. */ - def iterator: Iterator[AbstractFile] = { - if (!isDirectory) Iterator.empty - else givenPath.toDirectory.list filter (_.exists) map (new PlainFile(_)) - } - - /** - * Returns the abstract file in this abstract directory with the - * specified name. If there is no such file, returns null. The - * argument "directory" tells whether to look for a directory or - * or a regular file. - * - * @param name ... - * @param directory ... - * @return ... - */ - def lookupName(name: String, directory: Boolean): AbstractFile = { - val child = givenPath / name - if ((child.isDirectory && directory) || (child.isFile && !directory)) new PlainFile(child) - else null - } - - /** Does this abstract file denote an existing file? */ - def create(): Unit = if (!exists) givenPath.createFile() - - /** Delete the underlying file or directory (recursively). */ - def delete(): Unit = - if (givenPath.isFile) givenPath.delete() - else if (givenPath.isDirectory) givenPath.toDirectory.deleteRecursively() - - /** Returns a plain file with the given name. It does not - * check that it exists. - */ - def lookupNameUnchecked(name: String, directory: Boolean): AbstractFile = - new PlainFile(givenPath / name) -} diff --git a/src/compiler/scala/tools/nsc/io/Streamable.scala b/src/compiler/scala/tools/nsc/io/Streamable.scala deleted file mode 100644 index 03318674ee..0000000000 --- a/src/compiler/scala/tools/nsc/io/Streamable.scala +++ /dev/null @@ -1,122 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Paul Phillips - */ - -package scala.tools.nsc -package io - -import java.net.{ URI, URL } -import java.io.{ BufferedInputStream, InputStream, PrintStream } -import java.io.{ BufferedReader, InputStreamReader, Closeable => JCloseable } -import scala.io.{ Codec, BufferedSource, Source } -import collection.mutable.ArrayBuffer -import Path.fail - -/** Traits for objects which can be represented as Streams. - * - * @author Paul Phillips - * @since 2.8 - */ - -object Streamable { - /** Traits which can be viewed as a sequence of bytes. Source types - * which know their length should override def length: Long for more - * efficient method implementations. - */ - trait Bytes { - def inputStream(): InputStream - def length: Long = -1 - - def bufferedInput() = new BufferedInputStream(inputStream()) - def bytes(): Iterator[Byte] = bytesAsInts() map (_.toByte) - def bytesAsInts(): Iterator[Int] = { - val in = bufferedInput() - Iterator continually in.read() takeWhile (_ != -1) - } - - /** This method aspires to be the fastest way to read - * a stream of known length into memory. - */ - def toByteArray(): Array[Byte] = { - // if we don't know the length, fall back on relative inefficiency - if (length == -1L) - return (new ArrayBuffer[Byte]() ++= bytes()).toArray - - val arr = new Array[Byte](length.toInt) - val len = arr.length - lazy val in = bufferedInput() - var offset = 0 - - def loop() { - if (offset < len) { - val read = in.read(arr, offset, len - offset) - if (read >= 0) { - offset += read - loop() - } - } - } - try loop() - finally in.close() - - if (offset == arr.length) arr - else fail("Could not read entire source (%d of %d bytes)".format(offset, len)) - } - } - - /** For objects which can be viewed as Chars. - */ - trait Chars extends Bytes { - /** Calls to methods requiring byte<->char transformations should be offered - * in a form which allows specifying the codec. When it is not specified, - * the one discovered at creation time will be used, which will always find the - * one in scala.io.Codec if no other is available. This can be overridden - * to use a different default. - */ - def creationCodec: Codec = implicitly[Codec] - - def chars(): BufferedSource = chars(creationCodec) - def chars(codec: Codec): BufferedSource = Source.fromInputStream(inputStream())(codec) - - def lines(): Iterator[String] = lines(creationCodec) - def lines(codec: Codec): Iterator[String] = chars(codec).getLines() - - /** Obtains an InputStreamReader wrapped around a FileInputStream. - */ - def reader(): InputStreamReader = reader(creationCodec) - def reader(codec: Codec): InputStreamReader = new InputStreamReader(inputStream, codec.charSet) - - /** Wraps a BufferedReader around the result of reader(). - */ - def bufferedReader(): BufferedReader = bufferedReader(creationCodec) - def bufferedReader(codec: Codec) = new BufferedReader(reader(codec)) - - /** Creates a BufferedReader and applies the closure, automatically closing it on completion. - */ - def applyReader[T](f: BufferedReader => T): T = { - val in = bufferedReader() - try f(in) - finally in.close() - } - - /** Convenience function to import entire file into a String. - */ - def slurp(): String = slurp(creationCodec) - def slurp(codec: Codec) = chars(codec).mkString - } - - /** Call a function on something Closeable, finally closing it. */ - def closing[T <: JCloseable, U](stream: T)(f: T => U): U = - try f(stream) - finally stream.close() - - def bytes(is: => InputStream): Array[Byte] = - new Bytes { def inputStream() = is } toByteArray - - def slurp(is: => InputStream)(implicit codec: Codec): String = - new Chars { def inputStream() = is } slurp codec - - def slurp(url: URL)(implicit codec: Codec): String = - slurp(url.openStream()) -} diff --git a/src/compiler/scala/tools/nsc/io/VirtualDirectory.scala b/src/compiler/scala/tools/nsc/io/VirtualDirectory.scala deleted file mode 100644 index 0bcb2de43f..0000000000 --- a/src/compiler/scala/tools/nsc/io/VirtualDirectory.scala +++ /dev/null @@ -1,70 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - */ - -package scala.tools.nsc -package io - -import scala.collection.mutable - -/** - * An in-memory directory. - * - * @author Lex Spoon - */ -class VirtualDirectory(val name: String, maybeContainer: Option[VirtualDirectory]) -extends AbstractFile { - def path: String = - maybeContainer match { - case None => name - case Some(parent) => parent.path+'/'+ name - } - - def absolute = this - - def container = maybeContainer.get - def isDirectory = true - var lastModified: Long = System.currentTimeMillis - - override def file = null - override def input = sys.error("directories cannot be read") - override def output = sys.error("directories cannot be written") - - /** Does this abstract file denote an existing file? */ - def create() { unsupported } - - /** Delete the underlying file or directory (recursively). */ - def delete() { unsupported } - - /** Returns an abstract file with the given name. It does not - * check that it exists. - */ - def lookupNameUnchecked(name: String, directory: Boolean): AbstractFile = unsupported - - private val files = mutable.Map.empty[String, AbstractFile] - - // the toList is so that the directory may continue to be - // modified while its elements are iterated - def iterator = files.values.toList.iterator - - override def lookupName(name: String, directory: Boolean): AbstractFile = - files get name filter (_.isDirectory == directory) orNull - - override def fileNamed(name: String): AbstractFile = - Option(lookupName(name, false)) getOrElse { - val newFile = new VirtualFile(name, path+'/'+name) - files(name) = newFile - newFile - } - - override def subdirectoryNamed(name: String): AbstractFile = - Option(lookupName(name, true)) getOrElse { - val dir = new VirtualDirectory(name, Some(this)) - files(name) = dir - dir - } - - def clear() { - files.clear(); - } -} diff --git a/src/compiler/scala/tools/nsc/io/VirtualFile.scala b/src/compiler/scala/tools/nsc/io/VirtualFile.scala deleted file mode 100644 index 48826ed191..0000000000 --- a/src/compiler/scala/tools/nsc/io/VirtualFile.scala +++ /dev/null @@ -1,102 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Martin Odersky - */ - - -package scala.tools.nsc -package io - -import java.io.{ ByteArrayInputStream, ByteArrayOutputStream, InputStream, OutputStream } -// [scala-reflect.jar migration note] uncomment when creating scala-reflect.jar -// import java.io.{ File => JFile } - -/** This class implements an in-memory file. - * - * @author Philippe Altherr - * @version 1.0, 23/03/2004 - */ -class VirtualFile(val name: String, override val path: String) extends AbstractFile { - /** - * Initializes this instance with the specified name and an - * identical path. - * - * @param name the name of the virtual file to be created - * @return the created virtual file - */ - def this(name: String) = this(name, name) - - override def hashCode = path.hashCode - override def equals(that: Any) = that match { - case x: VirtualFile => x.path == path - case _ => false - } - - //######################################################################## - // Private data - private var content = new Array[Byte](0) - - //######################################################################## - // Public Methods - def absolute = this - - /** Returns null. */ - final def file: JFile = null - - override def sizeOption: Option[Int] = Some(content.size) - - def input : InputStream = new ByteArrayInputStream(content); - - override def output: OutputStream = { - new ByteArrayOutputStream() { - override def close() { - super.close() - content = toByteArray() - } - } - } - - def container: AbstractFile = unsupported - - /** Is this abstract file a directory? */ - def isDirectory: Boolean = false - - /** Returns the time that this abstract file was last modified. */ - private var _lastModified: Long = 0 - def lastModified: Long = _lastModified - def lastModified_=(x: Long) = _lastModified = x - - /** Returns all abstract subfiles of this abstract directory. */ - def iterator: Iterator[AbstractFile] = { - assert(isDirectory, "not a directory '" + this + "'") - Iterator.empty - } - - /** Does this abstract file denote an existing file? */ - def create() { unsupported } - - /** Delete the underlying file or directory (recursively). */ - def delete() { unsupported } - - /** - * Returns the abstract file in this abstract directory with the - * specified name. If there is no such file, returns null. The - * argument "directory" tells whether to look for a directory or - * or a regular file. - * - * @param name ... - * @param directory ... - * @return ... - */ - def lookupName(name: String, directory: Boolean): AbstractFile = { - assert(isDirectory, "not a directory '" + this + "'") - null - } - - /** Returns an abstract file with the given name. It does not - * check that it exists. - */ - def lookupNameUnchecked(name: String, directory: Boolean) = unsupported - - //######################################################################## -} diff --git a/src/compiler/scala/tools/nsc/io/ZipArchive.scala b/src/compiler/scala/tools/nsc/io/ZipArchive.scala deleted file mode 100644 index e61a9ba0da..0000000000 --- a/src/compiler/scala/tools/nsc/io/ZipArchive.scala +++ /dev/null @@ -1,221 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Paul Phillips - */ - -package scala.tools.nsc -package io - -import java.net.URL -import java.io.{ IOException, InputStream, ByteArrayInputStream } -// [scala-reflect.jar migration note] uncomment when creating scala-reflect.jar -// import java.io.{ File => JFile } -import java.util.zip.{ ZipEntry, ZipFile, ZipInputStream } -import scala.collection.{ immutable, mutable } -import annotation.tailrec - -/** An abstraction for zip files and streams. Everything is written the way - * it is for performance: we come through here a lot on every run. Be careful - * about changing it. - * - * @author Philippe Altherr (original version) - * @author Paul Phillips (this one) - * @version 2.0, - */ -object ZipArchive { - def fromPath(path: String): FileZipArchive = fromFile(new JFile(path)) - def fromPath(path: Path): FileZipArchive = fromFile(path.toFile) - - /** - * @param file a File - * @return A ZipArchive if `file` is a readable zip file, otherwise null. - */ - def fromFile(file: File): FileZipArchive = fromFile(file.jfile) - def fromFile(file: JFile): FileZipArchive = - try { new FileZipArchive(file) } - catch { case _: IOException => null } - - /** - * @param url the url of a zip file - * @return A ZipArchive backed by the given url. - */ - def fromURL(url: URL): URLZipArchive = new URLZipArchive(url) - def fromURL(url: String): URLZipArchive = fromURL(new URL(url)) - - private def dirName(path: String) = splitPath(path, true) - private def baseName(path: String) = splitPath(path, false) - private def splitPath(path0: String, front: Boolean): String = { - val isDir = path0.charAt(path0.length - 1) == '/' - val path = if (isDir) path0.substring(0, path0.length - 1) else path0 - val idx = path.lastIndexOf('/') - - if (idx < 0) - if (front) "/" - else path - else - if (front) path.substring(0, idx + 1) - else path.substring(idx + 1) - } -} -import ZipArchive._ - -abstract class ZipArchive(override val file: JFile) extends AbstractFile with Equals { - self => - - override def underlyingSource = Some(this) - def isDirectory = true - def lookupName(name: String, directory: Boolean) = unsupported - def lookupNameUnchecked(name: String, directory: Boolean) = unsupported - def create() = unsupported - def delete() = unsupported - def output = unsupported - def container = unsupported - def absolute = unsupported - - private def walkIterator(its: Iterator[AbstractFile]): Iterator[AbstractFile] = { - its flatMap { f => - if (f.isDirectory) walkIterator(f.iterator) - else Iterator(f) - } - } - def deepIterator = walkIterator(iterator) - - sealed abstract class Entry(path: String) extends VirtualFile(baseName(path), path) { - // have to keep this name for compat with sbt's compiler-interface - def getArchive: ZipFile = null - override def underlyingSource = Some(self) - override def toString = self.path + "(" + path + ")" - } - class DirEntry(path: String) extends Entry(path) { - val entries = mutable.HashMap[String, Entry]() - - override def isDirectory = true - override def iterator: Iterator[Entry] = entries.valuesIterator - override def lookupName(name: String, directory: Boolean): Entry = { - if (directory) entries(name + "/") - else entries(name) - } - } - - private def ensureDir(dirs: mutable.Map[String, DirEntry], path: String, zipEntry: ZipEntry): DirEntry = { - dirs.getOrElseUpdate(path, { - val parent = ensureDir(dirs, dirName(path), null) - val dir = new DirEntry(path) - parent.entries(baseName(path)) = dir - dir - }) - } - protected def getDir(dirs: mutable.Map[String, DirEntry], entry: ZipEntry): DirEntry = { - if (entry.isDirectory) ensureDir(dirs, entry.getName, entry) - else ensureDir(dirs, dirName(entry.getName), null) - } -} - -final class FileZipArchive(file: JFile) extends ZipArchive(file) { - def iterator: Iterator[Entry] = { - val zipFile = new ZipFile(file) - val root = new DirEntry("/") - val dirs = mutable.HashMap[String, DirEntry]("/" -> root) - val enum = zipFile.entries() - - while (enum.hasMoreElements) { - val zipEntry = enum.nextElement - val dir = getDir(dirs, zipEntry) - if (zipEntry.isDirectory) dir - else { - class FileEntry() extends Entry(zipEntry.getName) { - override def getArchive = zipFile - override def lastModified = zipEntry.getTime() - override def input = getArchive getInputStream zipEntry - override def sizeOption = Some(zipEntry.getSize().toInt) - } - val f = new FileEntry() - dir.entries(f.name) = f - } - } - - try root.iterator - finally dirs.clear() - } - - def name = file.getName - def path = file.getPath - def input = File(file).inputStream() - def lastModified = file.lastModified - - override def sizeOption = Some(file.length.toInt) - override def canEqual(other: Any) = other.isInstanceOf[FileZipArchive] - override def hashCode() = file.hashCode - override def equals(that: Any) = that match { - case x: FileZipArchive => file.getAbsoluteFile == x.file.getAbsoluteFile - case _ => false - } -} - -final class URLZipArchive(val url: URL) extends ZipArchive(null) { - def iterator: Iterator[Entry] = { - val root = new DirEntry("/") - val dirs = mutable.HashMap[String, DirEntry]("/" -> root) - val in = new ZipInputStream(new ByteArrayInputStream(Streamable.bytes(input))) - - @tailrec def loop() { - val zipEntry = in.getNextEntry() - class EmptyFileEntry() extends Entry(zipEntry.getName) { - override def toByteArray: Array[Byte] = null - override def sizeOption = Some(0) - } - class FileEntry() extends Entry(zipEntry.getName) { - override val toByteArray: Array[Byte] = { - val len = zipEntry.getSize().toInt - val arr = new Array[Byte](len) - var offset = 0 - - def loop() { - if (offset < len) { - val read = in.read(arr, offset, len - offset) - if (read >= 0) { - offset += read - loop() - } - } - } - loop() - - if (offset == arr.length) arr - else throw new IOException("Input stream truncated: read %d of %d bytes".format(offset, len)) - } - override def sizeOption = Some(zipEntry.getSize().toInt) - } - - if (zipEntry != null) { - val dir = getDir(dirs, zipEntry) - if (zipEntry.isDirectory) - dir - else { - val f = if (zipEntry.getSize() == 0) new EmptyFileEntry() else new FileEntry() - dir.entries(f.name) = f - } - in.closeEntry() - loop() - } - } - - loop() - try root.iterator - finally dirs.clear() - } - - def name = url.getFile() - def path = url.getPath() - def input = url.openStream() - def lastModified = - try url.openConnection().getLastModified() - catch { case _: IOException => 0 } - - override def canEqual(other: Any) = other.isInstanceOf[URLZipArchive] - override def hashCode() = url.hashCode - override def equals(that: Any) = that match { - case x: URLZipArchive => url == x.url - case _ => false - } -} |