diff options
Diffstat (limited to 'src/library')
67 files changed, 4943 insertions, 3851 deletions
diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index c08462ac1b..a6477f1709 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -113,7 +113,6 @@ object Predef extends LowPriorityImplicits { // Tag types and companions, and incantations for summoning type ArrayTag[T] = scala.reflect.ArrayTag[T] - type ErasureTag[T] = scala.reflect.ErasureTag[T] type ClassTag[T] = scala.reflect.ClassTag[T] type TypeTag[T] = scala.reflect.TypeTag[T] type ConcreteTypeTag[T] = scala.reflect.ConcreteTypeTag[T] @@ -124,7 +123,6 @@ object Predef extends LowPriorityImplicits { // [Eugene to Martin] it's really tedious to type "implicitly[...]" all the time, so I'm reintroducing these shortcuts def arrayTag[T](implicit atag: ArrayTag[T]) = atag - def erasureTag[T](implicit etag: ErasureTag[T]) = etag def classTag[T](implicit ctag: ClassTag[T]) = ctag def tag[T](implicit ttag: TypeTag[T]) = ttag def typeTag[T](implicit ttag: TypeTag[T]) = ttag diff --git a/src/library/scala/ref/WeakReference.scala b/src/library/scala/ref/WeakReference.scala index 98cfb2c84b..322eab0be4 100644 --- a/src/library/scala/ref/WeakReference.scala +++ b/src/library/scala/ref/WeakReference.scala @@ -10,6 +10,9 @@ package scala.ref /** + * A wrapper class for java.lag.ref.WeakReference + * The new functionality is (1) results are Option values, instead of using null. + * (2) There is an extractor that maps the weak reference itself into an option. * @author Sean McDirmid */ class WeakReference[+T <: AnyRef](value: T, queue: ReferenceQueue[T]) extends ReferenceWrapper[T] { @@ -18,6 +21,19 @@ class WeakReference[+T <: AnyRef](value: T, queue: ReferenceQueue[T]) extends Re new WeakReferenceWithWrapper[T](value, queue, this) } +/** An extractor for weak reference values */ +object WeakReference { + + /** Creates a weak reference pointing to `value` */ + def apply[T <: AnyRef](value: T) = new WeakReference(value) + + /** Optionally returns the referenced value, or `None` if that value no longer exists */ + def unapply[T <: AnyRef](wr: WeakReference[T]): Option[T] = { + val x = wr.underlying.get + if (x != null) Some(x) else None + } +} + /** * @author Philipp Haller */ diff --git a/src/library/scala/reflect/ArrayTag.scala b/src/library/scala/reflect/ArrayTag.scala index ba0c075723..3eba901f4f 100644 --- a/src/library/scala/reflect/ArrayTag.scala +++ b/src/library/scala/reflect/ArrayTag.scala @@ -13,7 +13,7 @@ package scala.reflect * However other platforms (e.g. a Scala -> JS crosscompiler) may reimplement this trait as they see fit * and then expose the implementation via an implicit macro. * - * @see [[scala.reflect.api.TypeTags]] + * @see [[scala.reflect.base.TypeTags]] */ @annotation.implicitNotFound(msg = "No ArrayTag available for ${T}") trait ArrayTag[T] { diff --git a/src/library/scala/reflect/ClassTag.scala b/src/library/scala/reflect/ClassTag.scala index e485691747..ec66a42730 100644 --- a/src/library/scala/reflect/ClassTag.scala +++ b/src/library/scala/reflect/ClassTag.scala @@ -1,7 +1,6 @@ package scala.reflect import java.lang.{ Class => jClass } -import scala.reflect.{ mirror => rm } import language.{implicitConversions, existentials} import scala.runtime.ScalaRunTime.arrayClass @@ -21,13 +20,16 @@ import scala.runtime.ScalaRunTime.arrayClass * A ConcreteTypeTag member of the reflect.mirror object is convertible to a ClassTag via an implicit conversion * (this is not possible to do in all reflection universes because an operation that converts a type to a Java class might not be available). * - * @see [[scala.reflect.api.TypeTags]] + * @see [[scala.reflect.base.TypeTags]] */ @annotation.implicitNotFound(msg = "No ClassTag available for ${T}") -trait ClassTag[T] extends ArrayTag[T] with ErasureTag[T] with Equals with Serializable { +trait ClassTag[T] extends ArrayTag[T] with Equals with Serializable { // please, don't add any APIs here, like it was with `newWrappedArray` and `newArrayBuilder` // class tags, and all tags in general, should be as minimalistic as possible + /** Returns an erasure of type `T` */ + def erasure: jClass[_] + /** Produces a `ClassTag` that knows how to build `Array[Array[T]]` */ def wrap: ClassTag[Array[T]] = ClassTag[Array[T]](arrayClass(erasure)) diff --git a/src/library/scala/reflect/DummyMirror.scala b/src/library/scala/reflect/DummyMirror.scala deleted file mode 100644 index aa731f62db..0000000000 --- a/src/library/scala/reflect/DummyMirror.scala +++ /dev/null @@ -1,783 +0,0 @@ -package scala.reflect - -import scala.reflect.api.AbsTreeGen -import scala.reflect.api.Attachment -import scala.reflect.api.Modifier -import scala.reflect.api.Universe - -// todo. make Dummy objects not equal to themselves -class DummyMirror(cl: ClassLoader) extends api.Mirror { - // Members declared in scala.reflect.api.AnnotationInfos - implicit def classfileAnnotArgTag: scala.reflect.ClassTag[ClassfileAnnotArg] = notSupported() - type AnnotationInfo = DummyAnnotationInfo.type - object DummyAnnotationInfo - val AnnotationInfo: AnnotationInfoExtractor = DummyAnnotationInfoExtractor - object DummyAnnotationInfoExtractor extends AnnotationInfoExtractor { - def apply(atp: Type, args: List[Tree], assocs: List[(Name, ClassfileAnnotArg)]): AnnotationInfo = DummyAnnotationInfo - def unapply(info: AnnotationInfo): Option[(Type, List[Tree], List[(Name, ClassfileAnnotArg)])] = notSupported() - } - type ClassfileAnnotArg = AnyRef - type LiteralAnnotArg = DummyLiteralAnnotArg.type - object DummyLiteralAnnotArg - val LiteralAnnotArg: LiteralAnnotArgExtractor = DummyLiteralAnnotArgExtractor - type ArrayAnnotArg = DummyArrayAnnotArg.type - object DummyArrayAnnotArg - val ArrayAnnotArg: ArrayAnnotArgExtractor = DummyArrayAnnotArgExtractor - type NestedAnnotArg = DummyNestedAnnotArg.type - object DummyNestedAnnotArg - val NestedAnnotArg: NestedAnnotArgExtractor = DummyNestedAnnotArgExtractor - object DummyLiteralAnnotArgExtractor extends LiteralAnnotArgExtractor { - def apply(const: Constant): LiteralAnnotArg = DummyLiteralAnnotArg - def unapply(arg: LiteralAnnotArg): Option[Constant] = notSupported() - } - object DummyArrayAnnotArgExtractor extends ArrayAnnotArgExtractor { - def apply(const: Array[ClassfileAnnotArg]): ArrayAnnotArg = DummyArrayAnnotArg - def unapply(arg: ArrayAnnotArg): Option[Array[ClassfileAnnotArg]] = notSupported() - } - object DummyNestedAnnotArgExtractor extends NestedAnnotArgExtractor { - def apply(anninfo: AnnotationInfo): NestedAnnotArg = DummyNestedAnnotArg - def unapply(arg: NestedAnnotArg): Option[AnnotationInfo] = notSupported() - } - - // Members declared in scala.reflect.api.Constants - type Constant = DummyConstant.type - object DummyConstant extends AbsConstant { - val value: Any = notSupported() - def tpe: Type = notSupported() - def isNaN: Boolean = notSupported() - def booleanValue: Boolean = notSupported() - def byteValue: Byte = notSupported() - def shortValue: Short = notSupported() - def charValue: Char = notSupported() - def intValue: Int = notSupported() - def longValue: Long = notSupported() - def floatValue: Float = notSupported() - def doubleValue: Double = notSupported() - def stringValue: String = notSupported() - def typeValue: Type = notSupported() - def symbolValue: Symbol = notSupported() - def convertTo(pt: Type): Constant = notSupported() - } - val Constant: ConstantExtractor = DummyConstantExtractor - object DummyConstantExtractor extends ConstantExtractor { - def apply(const: Any): Constant = DummyConstant - def unapply(arg: Constant): Option[Any] = notSupported() - } - - // Members declared in scala.reflect.api.FreeVars - type FreeTerm = DummyFreeTerm.type - val DummyFreeTerm = DummySymbol - val FreeTerm: FreeTermExtractor = DummyFreeTermExtractor - object DummyFreeTermExtractor extends FreeTermExtractor { - def unapply(freeTerm: FreeTerm): Option[(TermName, Type, Any, String)] = notSupported() - } - type FreeType = DummyFreeType.type - val DummyFreeType = DummySymbol - val FreeType: FreeTypeExtractor = DummyFreeTypeExtractor - object DummyFreeTypeExtractor extends FreeTypeExtractor { - def unapply(freeType: FreeType): Option[(TypeName, Type, String)] = notSupported() - } - def freeTerms(tree: Tree): List[FreeTerm] = notSupported() - def freeTypes(tree: Tree): List[FreeType] = notSupported() - def substituteFreeTypes(tpe: Type,subs: Map[FreeType,Type]): Type = notSupported() - def substituteFreeTypes(tree: Tree,subs: Map[FreeType,Type]): Tree = notSupported() - - // Members declared in scala.reflect.api.Importers - def mkImporter(from0: scala.reflect.api.Universe): Importer{val from: from0.type} = notSupported() - - // Members declared in scala.reflect.api.Mirror - def classLoader: ClassLoader = cl - def classLoader_=(x$1: ClassLoader): Unit = notSupported() - def classToSymbol(clazz: Class[_]): Symbol = notSupported() - def classToType(clazz: Class[_]): Type = notSupported() - def companionInstance(clazz: Symbol): AnyRef = notSupported() - def getValueOfField(receiver: AnyRef,field: Symbol): Any = notSupported() - def invoke(receiver: AnyRef,meth: Symbol)(args: Any*): Any = notSupported() - def setValueOfField(receiver: AnyRef,field: Symbol,value: Any): Unit = notSupported() - def symbolForName(name: String): Symbol = notSupported() - def symbolOfInstance(instance: Any): Symbol = notSupported() - def symbolToClass(sym: Symbol): Class[_] = notSupported() - def typeOfInstance(instance: Any): Type = notSupported() - def typeToClass(tpe: Type): Class[_] = notSupported() - - // Members declared in scala.reflect.api.Names - type Name = DummyName.type - type TypeName = DummyName.type - type TermName = DummyName.type - object DummyName extends AbsName { - def isTermName: Boolean = notSupported() - def isTypeName: Boolean = notSupported() - def toTermName: TermName = notSupported() - def toTypeName: TypeName = notSupported() - def decoded: String = notSupported() - def encoded: String = notSupported() - def decodedName: Name = notSupported() - def encodedName: Name = notSupported() - } - def newTermName(s: String): TermName = notSupported() - def newTypeName(s: String): TypeName = notSupported() - - // Members declared in scala.reflect.api.Positions - type Position = DummyPosition.type - object DummyPosition extends api.Position { - def pos: Position = notSupported() - def withPos(newPos: scala.reflect.api.Position): Attachment = notSupported() - def payload: Any = notSupported() - def withPayload(newPayload: Any): Attachment = notSupported() - def fileInfo: java.io.File = notSupported() - def fileContent: Array[Char] = notSupported() - def isDefined: Boolean = notSupported() - def isTransparent: Boolean = notSupported() - def isRange: Boolean = notSupported() - def isOpaqueRange: Boolean = notSupported() - def makeTransparent: Position = notSupported() - def start: Int = notSupported() - def startOrPoint: Int = notSupported() - def point: Int = notSupported() - def pointOrElse(default: Int): Int = notSupported() - def end: Int = notSupported() - def endOrPoint: Int = notSupported() - def withStart(off: Int): Position = notSupported() - def withEnd(off: Int): Position = notSupported() - def withPoint(off: Int): Position = notSupported() - def union(pos: scala.reflect.api.Position): Position = notSupported() - def focusStart: Position = notSupported() - def focus: Position = notSupported() - def focusEnd: Position = notSupported() - def includes(pos: scala.reflect.api.Position): Boolean = notSupported() - def properlyIncludes(pos: scala.reflect.api.Position): Boolean = notSupported() - def precedes(pos: scala.reflect.api.Position): Boolean = notSupported() - def properlyPrecedes(pos: scala.reflect.api.Position): Boolean = notSupported() - def overlaps(pos: scala.reflect.api.Position): Boolean = notSupported() - def sameRange(pos: scala.reflect.api.Position): Boolean = notSupported() - def line: Int = notSupported() - def column: Int = notSupported() - def toSingleLine: Position = notSupported() - def lineContent: String = notSupported() - def show: String = notSupported() - } - val NoPosition: Position = DummyPosition - def atPos[T <: Tree](pos: Position)(tree: T): T = tree - def ensureNonOverlapping(tree: Tree,others: List[Tree]): Unit = notSupported() - def wrappingPos(trees: List[Tree]): Position = notSupported() - def wrappingPos(default: Position,trees: List[Tree]): Position = notSupported() - - // Members declared in scala.reflect.api.FrontEnds - def mkConsoleFrontEnd(minSeverity: Int): FrontEnd = notSupported() - - // Members declared in scala.reflect.api.Scopes - type Scope = DummyScope.type - object DummyScope extends Iterable[Symbol] { - def iterator: Iterator[Symbol] = notSupported() - } - def newScope: Scope = DummyScope - def newScopeWith(elems: Symbol*): Scope = DummyScope - def newNestedScope(outer: Scope): Scope = DummyScope - - // Members declared in scala.reflect.api.StandardDefinitions - val AnyRefTpe: Type = DummyType - val AnyTpe: Type = DummyType - val AnyValTpe: Type = DummyType - val BooleanTpe: Type = DummyType - val ByteTpe: Type = DummyType - val CharTpe: Type = DummyType - val DoubleTpe: Type = DummyType - val FloatTpe: Type = DummyType - val IntTpe: Type = DummyType - val LongTpe: Type = DummyType - val NothingTpe: Type = DummyType - val NullTpe: Type = DummyType - val ObjectTpe: Type = DummyType - val ShortTpe: Type = DummyType - val StringTpe: Type = DummyType - val UnitTpe: Type = DummyType - val definitions: AbsDefinitions = DummyDefinitions - object DummyDefinitions extends AbsDefinitions { - def ByNameParamClass = DummySymbol - def JavaRepeatedParamClass = DummySymbol - def RepeatedParamClass = DummySymbol - def AnyClass = DummyClassSymbol - def AnyRefClass = DummyTypeSymbol - def AnyValClass = DummyClassSymbol - def ArrayClass = DummyClassSymbol - def ArrayModule = DummySymbol - def ArrayModule_overloadedApply = DummySymbol - def Array_apply = DummySymbol - def Array_clone = DummySymbol - def Array_length = DummySymbol - def Array_update = DummySymbol - def BooleanClass = DummyClassSymbol - def ByteClass = DummyClassSymbol - def CharClass = DummyClassSymbol - def ClassClass = DummyClassSymbol - def ClassTagClass = DummyClassSymbol - def ClassTagModule = DummySymbol - def ConcreteTypeTagClass = DummyClassSymbol - def ConcreteTypeTagModule = DummySymbol - def ConsClass = DummySymbol - def DoubleClass = DummyClassSymbol - def EmptyPackage = DummyPackageSymbol - def EmptyPackageClass = DummySymbol - def FloatClass = DummyClassSymbol - def FunctionClass: Array[Symbol] = Array() - def IntClass = DummyClassSymbol - def IterableClass = DummySymbol - def IteratorClass = DummySymbol - def IteratorModule = DummySymbol - def Iterator_apply = DummySymbol - def JavaLangPackage = DummyPackageSymbol - def JavaLangPackageClass = DummySymbol - def ListClass = DummyClassSymbol - def ListModule = DummyModuleSymbol - def List_apply = DummySymbol - def LongClass = DummyClassSymbol - def NilModule = DummySymbol - def NoneModule = DummySymbol - def NothingClass = DummyClassSymbol - def NullClass = DummyClassSymbol - def ObjectClass = DummyClassSymbol - def OptionClass = DummySymbol - def PredefModule = DummyModuleSymbol - def ProductClass: Array[Symbol] = Array() - def RootClass = DummyClassSymbol - def RootPackage = DummyPackageSymbol - def ScalaPackage = DummyPackageSymbol - def ScalaPackageClass = DummySymbol - def ScalaPrimitiveValueClasses = Nil - def SeqClass = DummySymbol - def SeqModule = DummySymbol - def ShortClass = DummyClassSymbol - def SomeClass = DummySymbol - def SomeModule = DummySymbol - def StringBuilderClass = DummySymbol - def StringClass = DummyClassSymbol - def SymbolClass = DummySymbol - def TraversableClass = DummySymbol - def TupleClass: Array[Symbol] = Array() - def TypeTagClass = DummyClassSymbol - def TypeTagModule = DummySymbol - def UnitClass = DummyClassSymbol - def isNumericValueClass(sym: Symbol): Boolean = notSupported() - def isPrimitiveValueClass(sym: Symbol): Boolean = notSupported() - def vmClassType(arg: Type): Type = DummyType - def vmSignature(sym: Symbol,info: Type): String = notSupported() - } - - // Members declared in scala.reflect.api.StandardNames - val nme: AbsTermNames = DummyAbsTermNames - val tpnme: AbsTypeNames = DummyAbsTypeNames - object DummyAbsTermNames extends AbsTermNames { - type NameType = TermName - val EMPTY: NameType = DummyName - val ANON_FUN_NAME: NameType = DummyName - val ANON_CLASS_NAME: NameType = DummyName - val EMPTY_PACKAGE_NAME: NameType = DummyName - val IMPORT: NameType = DummyName - val MODULE_VAR_SUFFIX: NameType = DummyName - val ROOT: NameType = DummyName - val PACKAGE: NameType = DummyName - val SPECIALIZED_SUFFIX: NameType = DummyName - val ERROR: NameType = DummyName - val NO_NAME: NameType = DummyName - val WILDCARD: NameType = DummyName - def flattenedName(segments: Name*): NameType = notSupported() - val EXPAND_SEPARATOR_STRING: String = "" - val ANYNAME: TermName = DummyName - val CONSTRUCTOR: TermName = DummyName - val FAKE_LOCAL_THIS: TermName = DummyName - val INITIALIZER: TermName = DummyName - val LAZY_LOCAL: TermName = DummyName - val LOCAL_SUFFIX_STRING: String = "" - val MIRROR_PREFIX: TermName = DummyName - val MIRROR_SHORT: TermName = DummyName - val MIRROR_FREE_PREFIX: TermName = DummyName - val MIRROR_FREE_THIS_SUFFIX: TermName = DummyName - val MIRROR_FREE_VALUE_SUFFIX: TermName = DummyName - val MIRROR_SYMDEF_PREFIX: TermName = DummyName - val MIXIN_CONSTRUCTOR: TermName = DummyName - val MODULE_INSTANCE_FIELD: TermName = DummyName - val OUTER: TermName = DummyName - val OUTER_LOCAL: TermName = DummyName - val OUTER_SYNTH: TermName = DummyName - val SELECTOR_DUMMY: TermName = DummyName - val SELF: TermName = DummyName - val SPECIALIZED_INSTANCE: TermName = DummyName - val STAR: TermName = DummyName - val THIS: TermName = DummyName - val BITMAP_NORMAL: TermName = DummyName - val BITMAP_TRANSIENT: TermName = DummyName - val BITMAP_CHECKINIT: TermName = DummyName - val BITMAP_CHECKINIT_TRANSIENT: TermName = DummyName - val INTERPRETER_IMPORT_WRAPPER: String = "" - val INTERPRETER_LINE_PREFIX: String = "" - val INTERPRETER_VAR_PREFIX: String = "" - val INTERPRETER_WRAPPER_SUFFIX: String = "" - val ROOTPKG: TermName = DummyName - val ADD: TermName = DummyName - val AND: TermName = DummyName - val ASR: TermName = DummyName - val DIV: TermName = DummyName - val EQ: TermName = DummyName - val EQL: TermName = DummyName - val GE: TermName = DummyName - val GT: TermName = DummyName - val HASHHASH: TermName = DummyName - val LE: TermName = DummyName - val LSL: TermName = DummyName - val LSR: TermName = DummyName - val LT: TermName = DummyName - val MINUS: TermName = DummyName - val MOD: TermName = DummyName - val MUL: TermName = DummyName - val NE: TermName = DummyName - val OR: TermName = DummyName - val PLUS : TermName = DummyName - val SUB: TermName = DummyName - val XOR: TermName = DummyName - val ZAND: TermName = DummyName - val ZOR: TermName = DummyName - val UNARY_~ : TermName = DummyName - val UNARY_+ : TermName = DummyName - val UNARY_- : TermName = DummyName - val UNARY_! : TermName = DummyName - val ??? : TermName = DummyName - val MODULE_SUFFIX_NAME: TermName = DummyName - val NAME_JOIN_NAME: TermName = DummyName - val IMPL_CLASS_SUFFIX: String = "" - val LOCALDUMMY_PREFIX: String = "" - val PROTECTED_PREFIX: String = "" - val PROTECTED_SET_PREFIX: String = "" - val SINGLETON_SUFFIX: String = "" - val SUPER_PREFIX_STRING: String = "" - val TRAIT_SETTER_SEPARATOR_STRING: String = "" - val SETTER_SUFFIX: TermName = DummyName - def isConstructorName(name: Name): Boolean = notSupported() - def isExceptionResultName(name: Name): Boolean = notSupported() - def isImplClassName(name: Name): Boolean = notSupported() - def isLocalDummyName(name: Name): Boolean = notSupported() - def isLocalName(name: Name): Boolean = notSupported() - def isLoopHeaderLabel(name: Name): Boolean = notSupported() - def isProtectedAccessorName(name: Name): Boolean = notSupported() - def isSuperAccessorName(name: Name): Boolean = notSupported() - def isReplWrapperName(name: Name): Boolean = notSupported() - def isSetterName(name: Name): Boolean = notSupported() - def isTraitSetterName(name: Name): Boolean = notSupported() - def isSingletonName(name: Name): Boolean = notSupported() - def isModuleName(name: Name): Boolean = notSupported() - def isOpAssignmentName(name: Name): Boolean = notSupported() - def segments(name: String, assumeTerm: Boolean): List[Name] = notSupported() - def originalName(name: Name): Name = notSupported() - def stripModuleSuffix(name: Name): Name = notSupported() - def unspecializedName(name: Name): Name = notSupported() - def splitSpecializedName(name: Name): (Name, String, String) = notSupported() - def dropLocalSuffix(name: Name): Name = notSupported() - def expandedName(name: TermName, base: Symbol, separator: String = EXPAND_SEPARATOR_STRING): TermName = notSupported() - def expandedSetterName(name: TermName, base: Symbol): TermName = notSupported() - def protName(name: Name): TermName = notSupported() - def protSetterName(name: Name): TermName = notSupported() - def getterName(name: TermName): TermName = notSupported() - def getterToLocal(name: TermName): TermName = notSupported() - def getterToSetter(name: TermName): TermName = notSupported() - def localToGetter(name: TermName): TermName = notSupported() - def setterToGetter(name: TermName): TermName = notSupported() - def defaultGetterName(name: Name, pos: Int): TermName = notSupported() - def defaultGetterToMethod(name: Name): TermName = notSupported() - def localDummyName(clazz: Symbol): TermName = notSupported() - def superName(name: Name): TermName = notSupported() - } - object DummyAbsTypeNames extends AbsTypeNames { - type NameType = TypeName - val EMPTY: NameType = DummyName - val ANON_FUN_NAME: NameType = DummyName - val ANON_CLASS_NAME: NameType = DummyName - val EMPTY_PACKAGE_NAME: NameType = DummyName - val IMPORT: NameType = DummyName - val MODULE_VAR_SUFFIX: NameType = DummyName - val ROOT: NameType = DummyName - val PACKAGE: NameType = DummyName - val SPECIALIZED_SUFFIX: NameType = DummyName - val ERROR: NameType = DummyName - val NO_NAME: NameType = DummyName - val WILDCARD: NameType = DummyName - def flattenedName(segments: Name*): NameType = notSupported() - val REFINE_CLASS_NAME: TypeName = DummyName - val BYNAME_PARAM_CLASS_NAME: TypeName = DummyName - val EQUALS_PATTERN_NAME: TypeName = DummyName - val JAVA_REPEATED_PARAM_CLASS_NAME: TypeName = DummyName - val LOCAL_CHILD: TypeName = DummyName - val REPEATED_PARAM_CLASS_NAME: TypeName = DummyName - val WILDCARD_STAR: TypeName = DummyName - - def dropSingletonName(name: Name): TypeName = notSupported() - def singletonName(name: Name): TypeName = notSupported() - def implClassName(name: Name): TypeName = notSupported() - def interfaceName(implname: Name): TypeName = notSupported() - } - - // Members declared in scala.reflect.api.Symbols - val NoSymbol = DummySymbol - type Symbol = DummySymbolApi - object DummySymbol extends DummySymbolApi - type TypeSymbol = DummyTypeSymbolApi - object DummyTypeSymbol extends DummyTypeSymbolApi - type TermSymbol = DummyTermSymbolApi - object DummyTermSymbol extends DummyTermSymbolApi - type MethodSymbol = DummyMethodSymbolApi - object DummyMethodSymbol extends DummyMethodSymbolApi - type ModuleSymbol = DummyModuleSymbolApi - object DummyModuleSymbol extends DummyModuleSymbolApi - type PackageSymbol = DummyPackageSymbolApi - object DummyPackageSymbol extends DummyPackageSymbolApi - type ClassSymbol = DummyClassSymbolApi - object DummyClassSymbol extends DummyClassSymbolApi - trait DummySymbolApi extends AbsSymbol { - this: Symbol => - - def pos: Position = notSupported() - def modifiers: Set[Modifier] = notSupported() - def hasModifier(mod: Modifier): Boolean = notSupported() - def annotations: List[AnnotationInfo] = notSupported() - def hasAnnotation(sym: Symbol): Boolean = notSupported() - def owner: Symbol = notSupported() - def name: Name = notSupported() - def fullName: String = notSupported() - def id: Int = notSupported() - def orElse(alt: => Symbol): Symbol = notSupported() - def filter(cond: Symbol => Boolean): Symbol = notSupported() - def suchThat(cond: Symbol => Boolean): Symbol = notSupported() - def privateWithin: Symbol = notSupported() - def companionSymbol: Symbol = notSupported() - def moduleClass: Symbol = notSupported() - def enclosingTopLevelClass: Symbol = notSupported() - def enclosingClass: Symbol = notSupported() - def enclosingMethod: Symbol = notSupported() - def enclosingPackageClass: Symbol = notSupported() - def isTerm : Boolean = notSupported() - def isPackage : Boolean = notSupported() - def isMethod : Boolean = notSupported() - def isOverloaded : Boolean = notSupported() - def isFreeTerm : Boolean = notSupported() - def isType : Boolean = notSupported() - def isClass : Boolean = notSupported() - def isPackageClass : Boolean = notSupported() - def isPrimitiveValueClass: Boolean = notSupported() - def isDerivedValueClass: Boolean = notSupported() - def isAliasType : Boolean = notSupported() - def isAbstractType : Boolean = notSupported() - def isSkolem : Boolean = notSupported() - def isExistential : Boolean = notSupported() - def isFreeType : Boolean = notSupported() - def isContravariant : Boolean = notSupported() - def isCovariant : Boolean = notSupported() - def isErroneous : Boolean = notSupported() - def typeSignature: Type = notSupported() - def typeSignatureIn(site: Type): Type = notSupported() - def asType: Type = notSupported() - def asTypeIn(site: Type): Type = notSupported() - def asTypeConstructor: Type = notSupported() - def thisPrefix: Type = notSupported() - def selfType: Type = notSupported() - def alternatives: List[Symbol] = notSupported() - def resolveOverloaded(pre: Type = NoPrefix, targs: Seq[Type] = List(), actuals: Seq[Type]): Symbol = notSupported() - def newNestedSymbol(name: Name, pos: Position, flags: Long, isClass: Boolean): Symbol = notSupported() - def setInternalFlags(flags: Long): this.type = notSupported() - def setTypeSignature(tpe: Type): this.type = notSupported() - def setAnnotations(annots: AnnotationInfo*): this.type = notSupported() - def kind: String = notSupported() - } - trait DummyTypeSymbolApi extends DummySymbolApi with TypeSymbolApi { - this: TypeSymbol => - } - trait DummyTermSymbolApi extends DummySymbolApi with TermSymbolApi { - this: TermSymbol => - } - trait DummyMethodSymbolApi extends DummyTermSymbolApi with MethodSymbolApi { - this: MethodSymbol => - } - trait DummyModuleSymbolApi extends DummyTermSymbolApi with ModuleSymbolApi { - this: ModuleSymbol => - } - trait DummyPackageSymbolApi extends DummyModuleSymbolApi with PackageSymbolApi { - this: PackageSymbol => - } - trait DummyClassSymbolApi extends DummyTypeSymbolApi with ClassSymbolApi { - this: ClassSymbol => - } - - // Members declared in scala.reflect.api.ToolBoxes - def mkToolBox(frontEnd: FrontEnd, options: String): AbsToolBox = notSupported() - - // Members declared in scala.reflect.api.TreeBuildUtil - // type TreeGen = DummyTreeGen.type // [Eugene] cannot compile if uncomment this - val gen: TreeGen{val global: DummyMirror.this.type} = DummyTreeGen.asInstanceOf[TreeGen{val global: DummyMirror.this.type}] - def modifiersFromInternalFlags(flags: Long,privateWithin: Name,annotations: List[Tree]): Modifiers = DummyModifiers - def newFreeExistential(name: String,info: Type,value: => Any,flags: Long,origin: String) = DummySymbol - def newFreeTerm(name: String,info: Type,value: => Any,flags: Long,origin: String) = DummySymbol - def newFreeType(name: String,info: Type,value: => Any,flags: Long,origin: String) = DummySymbol - def selectOverloadedMethod(owner: Symbol,name: String,index: Int) = DummySymbol - def selectOverloadedMethodIfDefined(owner: Symbol,name: String,index: Int) = DummySymbol - def selectTerm(owner: Symbol,name: String) = DummySymbol - def selectTermIfDefined(owner: Symbol,name: String) = DummySymbol - def selectType(owner: Symbol,name: String) = DummySymbol - def selectTypeIfDefined(owner: Symbol,name: String) = DummySymbol - def staticClass(fullName: String) = DummySymbol - def staticClassIfDefined(fullName: String) = DummySymbol - def staticModule(fullName: String) = DummySymbol - def staticModuleIfDefined(fullName: String) = DummySymbol - def thisModuleType(fullName: String): Type = DummyType - object DummyTreeGen extends AbsTreeGen { - val global: Universe = DummyMirror.this - type TreeGenTree = global.Tree - type TreeGenType = global.Type - type TreeGenSymbol = global.Symbol - type TreeGenName = global.Name - def mkAttributedQualifier(tpe: TreeGenType): TreeGenTree = notSupported() - def mkAttributedQualifier(tpe: TreeGenType, termSym: TreeGenSymbol): TreeGenTree = notSupported() - def mkAttributedRef(pre: TreeGenType, sym: TreeGenSymbol): TreeGenTree = notSupported() - def mkAttributedRef(sym: TreeGenSymbol): TreeGenTree = notSupported() - def mkAttributedThis(sym: TreeGenSymbol): TreeGenTree = notSupported() - def mkAttributedIdent(sym: TreeGenSymbol): TreeGenTree = notSupported() - def mkAttributedSelect(qual: TreeGenTree, sym: TreeGenSymbol): TreeGenTree = notSupported() - def mkMethodCall(target: TreeGenTree,targs: List[TreeGenType],args: List[TreeGenTree]): TreeGenTree = notSupported() - def mkMethodCall(receiver: TreeGenTree,method: TreeGenSymbol,targs: List[TreeGenType],args: List[TreeGenTree]): TreeGenTree = notSupported() - def mkMethodCall(receiver: TreeGenSymbol,methodName: TreeGenName,args: List[TreeGenTree]): TreeGenTree = notSupported() - def mkMethodCall(target: TreeGenTree,args: List[TreeGenTree]): TreeGenTree = notSupported() - def mkMethodCall(method: TreeGenSymbol,args: List[TreeGenTree]): TreeGenTree = notSupported() - def mkMethodCall(method: TreeGenSymbol,targs: List[TreeGenType],args: List[TreeGenTree]): TreeGenTree = notSupported() - def mkMethodCall(receiver: TreeGenSymbol,methodName: TreeGenName,targs: List[TreeGenType],args: List[TreeGenTree]): TreeGenTree = notSupported() - def mkNullaryCall(method: TreeGenSymbol,targs: List[TreeGenType]): TreeGenTree = notSupported() - } - - // Members declared in scala.reflect.api.TreePrinters - def newTreePrinter(out: java.io.PrintWriter): TreePrinter = notSupported() - - // Members declared in scala.reflect.api.Trees - def Apply(sym: Symbol,args: Tree*): Tree = Apply(EmptyTree, Nil) - def Bind(sym: Symbol,body: Tree): Bind = Bind(DummyName, EmptyTree) - def Block(stats: Tree*): Block = Block() - def CaseDef(pat: Tree,body: Tree): CaseDef = CaseDef(EmptyTree, EmptyTree, EmptyTree) - def ClassDef(sym: Symbol,impl: Template): ClassDef = ClassDef(DummyModifiers, DummyName, Nil, Template(Nil, emptyValDef, Nil)) - def DefDef(sym: Symbol,rhs: List[List[Symbol]] => Tree): DefDef = DefDef(DummyModifiers, DummyName, Nil, Nil, EmptyTree, EmptyTree) - def DefDef(sym: Symbol,rhs: Tree): DefDef = DefDef(DummyModifiers, DummyName, Nil, Nil, EmptyTree, EmptyTree) - def DefDef(sym: Symbol,mods: Modifiers,rhs: Tree): DefDef = DefDef(DummyModifiers, DummyName, Nil, Nil, EmptyTree, EmptyTree) - def DefDef(sym: Symbol,vparamss: List[List[ValDef]],rhs: Tree): DefDef = DefDef(DummyModifiers, DummyName, Nil, Nil, EmptyTree, EmptyTree) - def DefDef(sym: Symbol,mods: Modifiers,vparamss: List[List[ValDef]],rhs: Tree): DefDef = DefDef(DummyModifiers, DummyName, Nil, Nil, EmptyTree, EmptyTree) - def Ident(sym: Symbol): Ident = Ident(DummyName) - def Ident(name: String): Ident = Ident(DummyName) - def LabelDef(sym: Symbol,params: List[Symbol],rhs: Tree): LabelDef = LabelDef(DummyName, Nil, EmptyTree) - type Modifiers = DummyModifiers.type - val NoMods: Modifiers = DummyModifiers - object DummyModifiers extends AbsModifiers { - def modifiers: Set[Modifier] = notSupported() - def hasModifier(mod: Modifier): Boolean = notSupported() - def privateWithin: Name = notSupported() - def annotations: List[Tree] = notSupported() - def mapAnnotations(f: List[Tree] => List[Tree]): Modifiers = notSupported() - } - def Modifiers(mods: Set[scala.reflect.api.Modifier],privateWithin: Name,annotations: List[Tree]): Modifiers = DummyModifiers - def ModuleDef(sym: Symbol,impl: Template): ModuleDef = ModuleDef(DummyModifiers, DummyName, Template(Nil, emptyValDef, Nil)) - def New(sym: Symbol,args: Tree*): Tree = New(EmptyTree) - def New(tpe: Type,args: Tree*): Tree = New(EmptyTree) - def New(tpt: Tree,argss: List[List[Tree]]): Tree = New(EmptyTree) - def Select(qualifier: Tree,sym: Symbol): Select = Select(EmptyTree, DummyName) - def Select(qualifier: Tree,name: String): Select = Select(EmptyTree, DummyName) - def Super(sym: Symbol,mix: TypeName): Tree = Super(EmptyTree, DummyName) - def This(sym: Symbol): Tree = This(DummyName) - def Throw(tpe: Type,args: Tree*): Throw = Throw(EmptyTree) - def Try(body: Tree,cases: (Tree, Tree)*): Try = Try(EmptyTree) - def TypeDef(sym: Symbol): TypeDef = TypeDef(DummyModifiers, DummyName, Nil, EmptyTree) - def TypeDef(sym: Symbol,rhs: Tree): TypeDef = TypeDef(DummyModifiers, DummyName, Nil, EmptyTree) - def ValDef(sym: Symbol): ValDef = ValDef(DummyModifiers, DummyName, EmptyTree, EmptyTree) - def ValDef(sym: Symbol,rhs: Tree): ValDef = ValDef(DummyModifiers, DummyName, EmptyTree, EmptyTree) - protected def duplicateTree(tree: Tree): Tree = notSupported() - object emptyValDef extends ValDef(DummyModifiers, DummyName, EmptyTree, EmptyTree) { override def isEmpty = true } - type TreeCopier = DummyTreeCopier.type - def newStrictTreeCopier: TreeCopier = DummyTreeCopier - def newLazyTreeCopier: TreeCopier = DummyTreeCopier - object DummyTreeCopier extends TreeCopierOps { - def ClassDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], impl: Template): ClassDef = notSupported() - def PackageDef(tree: Tree, pid: RefTree, stats: List[Tree]): PackageDef = notSupported() - def ModuleDef(tree: Tree, mods: Modifiers, name: Name, impl: Template): ModuleDef = notSupported() - def ValDef(tree: Tree, mods: Modifiers, name: Name, tpt: Tree, rhs: Tree): ValDef = notSupported() - def DefDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef = notSupported() - def TypeDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], rhs: Tree): TypeDef = notSupported() - def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree): LabelDef = notSupported() - def Import(tree: Tree, expr: Tree, selectors: List[ImportSelector]): Import = notSupported() - def Template(tree: Tree, parents: List[Tree], self: ValDef, body: List[Tree]): Template = notSupported() - def Block(tree: Tree, stats: List[Tree], expr: Tree): Block = notSupported() - def CaseDef(tree: Tree, pat: Tree, guard: Tree, body: Tree): CaseDef = notSupported() - def Alternative(tree: Tree, trees: List[Tree]): Alternative = notSupported() - def Star(tree: Tree, elem: Tree): Star = notSupported() - def Bind(tree: Tree, name: Name, body: Tree): Bind = notSupported() - def UnApply(tree: Tree, fun: Tree, args: List[Tree]): UnApply = notSupported() - def ArrayValue(tree: Tree, elemtpt: Tree, trees: List[Tree]): ArrayValue = notSupported() - def Function(tree: Tree, vparams: List[ValDef], body: Tree): Function = notSupported() - def Assign(tree: Tree, lhs: Tree, rhs: Tree): Assign = notSupported() - def AssignOrNamedArg(tree: Tree, lhs: Tree, rhs: Tree): AssignOrNamedArg = notSupported() - def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree): If = notSupported() - def Match(tree: Tree, selector: Tree, cases: List[CaseDef]): Match = notSupported() - def Return(tree: Tree, expr: Tree): Return = notSupported() - def Try(tree: Tree, block: Tree, catches: List[CaseDef], finalizer: Tree): Try = notSupported() - def Throw(tree: Tree, expr: Tree): Throw = notSupported() - def New(tree: Tree, tpt: Tree): New = notSupported() - def Typed(tree: Tree, expr: Tree, tpt: Tree): Typed = notSupported() - def TypeApply(tree: Tree, fun: Tree, args: List[Tree]): TypeApply = notSupported() - def Apply(tree: Tree, fun: Tree, args: List[Tree]): Apply = notSupported() - def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]): ApplyDynamic = notSupported() - def Super(tree: Tree, qual: Tree, mix: TypeName): Super = notSupported() - def This(tree: Tree, qual: Name): This = notSupported() - def Select(tree: Tree, qualifier: Tree, selector: Name): Select = notSupported() - def Ident(tree: Tree, name: Name): Ident = notSupported() - def ReferenceToBoxed(tree: Tree, idt: Ident): ReferenceToBoxed = notSupported() - def Literal(tree: Tree, value: Constant): Literal = notSupported() - def TypeTree(tree: Tree): TypeTree = notSupported() - def Annotated(tree: Tree, annot: Tree, arg: Tree): Annotated = notSupported() - def SingletonTypeTree(tree: Tree, ref: Tree): SingletonTypeTree = notSupported() - def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name): SelectFromTypeTree = notSupported() - def CompoundTypeTree(tree: Tree, templ: Template): CompoundTypeTree = notSupported() - def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree]): AppliedTypeTree = notSupported() - def TypeBoundsTree(tree: Tree, lo: Tree, hi: Tree): TypeBoundsTree = notSupported() - def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]): ExistentialTypeTree = notSupported() - } - - // Members declared in scala.reflect.api.Types - type Type = DummyType.type - type SingletonType = DummyType.type - type CompoundType = DummyType.type - type AnnotatedType = DummyType.type - val AnnotatedType: AnnotatedTypeExtractor = DummyAnnotatedTypeExtractor - type BoundedWildcardType = DummyType.type - val BoundedWildcardType: BoundedWildcardTypeExtractor = DummyBoundedWildcardTypeExtractor - type ClassInfoType = DummyType.type - val ClassInfoType: ClassInfoTypeExtractor = DummyClassInfoTypeExtractor - type ConstantType = DummyType.type - val ConstantType: ConstantTypeExtractor = DummyConstantTypeExtractor - type ExistentialType = DummyType.type - val ExistentialType: ExistentialTypeExtractor = DummyExistentialTypeExtractor - type MethodType = DummyType.type - val MethodType: MethodTypeExtractor = DummyMethodTypeExtractor - val NoPrefix: Type = DummyType - val NoType: Type = DummyType - type NullaryMethodType = DummyType.type - val NullaryMethodType: NullaryMethodTypeExtractor = DummyNullaryMethodTypeExtractor - type PolyType = DummyType.type - val PolyType: PolyTypeExtractor = DummyPolyTypeExtractor - type RefinedType = DummyType.type - val RefinedType: RefinedTypeExtractor = DummyRefinedTypeExtractor - type SingleType = DummyType.type - val SingleType: SingleTypeExtractor = DummySingleTypeExtractor - type SuperType = DummyType.type - val SuperType: SuperTypeExtractor = DummySuperTypeExtractor - type ThisType = DummyType.type - val ThisType: ThisTypeExtractor = DummyThisTypeExtractor - type TypeBounds = DummyType.type - val TypeBounds: TypeBoundsExtractor = DummyTypeBoundsExtractor - type TypeRef = DummyType.type - val TypeRef: TypeRefExtractor = DummyTypeRefExtractor - val WildcardType: Type = DummyType - def appliedType(tycon: Type,args: List[Type]): Type = DummyType - def existentialAbstraction(tparams: List[Symbol],tpe0: Type): Type = DummyType - def glb(ts: List[Type]): Type = DummyType - def intersectionType(tps: List[Type],owner: Symbol): Type = DummyType - def intersectionType(tps: List[Type]): Type = DummyType - def lub(xs: List[Type]): Type = DummyType - def polyType(tparams: List[Symbol],tpe: Type): Type = DummyType - def refinedType(parents: List[Type],owner: Symbol): Type = DummyType - def refinedType(parents: List[Type],owner: Symbol,decls: Scope,pos: Position): Type = DummyType - def singleType(pre: Type,sym: Symbol): Type = DummyType - def typeRef(pre: Type,sym: Symbol,args: List[Type]): Type = DummyType - object DummyType extends AbsType { - def =:=(that: Type): Boolean = notSupported() - def <:<(that: Type): Boolean = notSupported() - def asSeenFrom(pre: Type,clazz: Symbol): Type = notSupported() - def baseClasses: List[Symbol] = notSupported() - def baseType(clazz: Symbol): Type = notSupported() - def contains(sym: Symbol): Boolean = notSupported() - def declaration(name: Name): Symbol = notSupported() - def declarations: Iterable[Symbol] = notSupported() - def erasure: Type = notSupported() - def exists(p: Type => Boolean): Boolean = notSupported() - def find(p: Type => Boolean): Option[Type] = notSupported() - def foreach(f: Type => Unit): Unit = notSupported() - def isConcrete: Boolean = notSupported() - def isHigherKinded: Boolean = notSupported() - def isSpliceable: Boolean = notSupported() - def kind: String = notSupported() - def map(f: Type => Type): Type = notSupported() - def member(name: Name): Symbol = notSupported() - def members: Iterable[Symbol] = notSupported() - def nonPrivateMember(name: Name): Symbol = notSupported() - def nonPrivateMembers: Iterable[Symbol] = notSupported() - def normalize: Type = notSupported() - def parents: List[Type] = notSupported() - def substituteTypes(from: List[Symbol],to: List[Type]): Type = notSupported() - def typeArguments: List[Type] = notSupported() - def typeConstructor: Type = notSupported() - def typeParams: List[Symbol] = notSupported() - def typeSymbol: Symbol = notSupported() - def underlying: Type = notSupported() - def widen: Type = notSupported() - } - object DummyAnnotatedTypeExtractor extends AnnotatedTypeExtractor { - def apply(annotations: List[AnnotationInfo], underlying: Type, selfsym: Symbol): AnnotatedType = DummyType - def unapply(tpe: AnnotatedType): Option[(List[AnnotationInfo], Type, Symbol)] = notSupported() - } - object DummyBoundedWildcardTypeExtractor extends BoundedWildcardTypeExtractor { - def apply(bounds: TypeBounds): BoundedWildcardType = DummyType - def unapply(tpe: BoundedWildcardType): Option[TypeBounds] = notSupported() - } - object DummyClassInfoTypeExtractor extends ClassInfoTypeExtractor { - def apply(parents: List[Type], decls: Scope, clazz: Symbol): ClassInfoType = DummyType - def unapply(tpe: ClassInfoType): Option[(List[Type], Scope, Symbol)] = notSupported() - } - object DummyConstantTypeExtractor extends ConstantTypeExtractor { - def apply(value: Constant): ConstantType = DummyType - def unapply(tpe: ConstantType): Option[Constant] = notSupported() - } - object DummyExistentialTypeExtractor extends ExistentialTypeExtractor { - def apply(quantified: List[Symbol], underlying: Type): ExistentialType = DummyType - def unapply(tpe: ExistentialType): Option[(List[Symbol], Type)] = notSupported() - } - object DummyMethodTypeExtractor extends MethodTypeExtractor { - def apply(params: List[Symbol], resultType: Type): MethodType = DummyType - def unapply(tpe: MethodType): Option[(List[Symbol], Type)] = notSupported() - } - object DummyNullaryMethodTypeExtractor extends NullaryMethodTypeExtractor { - def apply(resultType: Type): NullaryMethodType = DummyType - def unapply(tpe: NullaryMethodType): Option[(Type)] = notSupported() - } - object DummyPolyTypeExtractor extends PolyTypeExtractor { - def apply(typeParams: List[Symbol], resultType: Type): PolyType = DummyType - def unapply(tpe: PolyType): Option[(List[Symbol], Type)] = notSupported() - } - object DummyRefinedTypeExtractor extends RefinedTypeExtractor { - def apply(parents: List[Type], decls: Scope): RefinedType = DummyType - def apply(parents: List[Type], decls: Scope, clazz: Symbol): RefinedType = DummyType - def unapply(tpe: RefinedType): Option[(List[Type], Scope)] = notSupported() - } - object DummySingleTypeExtractor extends SingleTypeExtractor { - def apply(pre: Type, sym: Symbol): Type = DummyType - def unapply(tpe: SingleType): Option[(Type, Symbol)] = notSupported() - } - object DummySuperTypeExtractor extends SuperTypeExtractor { - def apply(thistpe: Type, supertpe: Type): Type = DummyType - def unapply(tpe: SuperType): Option[(Type, Type)] = notSupported() - } - object DummyThisTypeExtractor extends ThisTypeExtractor { - def apply(sym: Symbol): Type = DummyType - def unapply(tpe: ThisType): Option[Symbol] = notSupported() - } - object DummyTypeBoundsExtractor extends TypeBoundsExtractor { - def apply(lo: Type, hi: Type): TypeBounds = DummyType - def unapply(tpe: TypeBounds): Option[(Type, Type)] = notSupported() - } - object DummyTypeRefExtractor extends TypeRefExtractor { - def apply(pre: Type, sym: Symbol, args: List[Type]): Type = DummyType - def unapply(tpe: TypeRef): Option[(Type, Symbol, List[Type])] = notSupported() - } - - // Utils - def notSupported() = { - throw new UnsupportedOperationException("Scala reflection not available on this platform." + mirrorDiagnostics(cl)) - } -}
\ No newline at end of file diff --git a/src/library/scala/reflect/ErasureTag.scala b/src/library/scala/reflect/ErasureTag.scala deleted file mode 100644 index f95451fab2..0000000000 --- a/src/library/scala/reflect/ErasureTag.scala +++ /dev/null @@ -1,23 +0,0 @@ -package scala.reflect - -import java.lang.{Class => jClass} - -/** An `ErasureTag[T]` is a descriptor that is requested by the compiler every time - * when it needs to persist an erasure of a type. - * - * Scala library provides a standard implementation of this trait, - * `TypeTag[T]` that carries the `java.lang.Class` erasure for arbitrary types. - * - * However other platforms may reimplement this trait as they see fit - * and then expose the implementation via an implicit macro. - * - * If you need to guarantee that the type does not contain - * references to type parameters or abstract types, use `ClassTag[T]`. - * - * @see [[scala.reflect.api.TypeTags]] - */ -@annotation.implicitNotFound(msg = "No ErasureTag available for ${T}") -trait ErasureTag[T] { - /** Returns an erasure of type `T` */ - def erasure: jClass[_] -} diff --git a/src/library/scala/reflect/Manifest.scala b/src/library/scala/reflect/Manifest.scala index da029f046d..559b82b177 100644 --- a/src/library/scala/reflect/Manifest.scala +++ b/src/library/scala/reflect/Manifest.scala @@ -9,7 +9,6 @@ package scala.reflect import scala.collection.mutable.{ ArrayBuilder, WrappedArray } -import mirror._ /** A `Manifest[T]` is an opaque descriptor for type T. Its supported use * is to give access to the erasure of the type as a `Class` instance, as diff --git a/src/library/scala/reflect/ReflectionUtils.scala b/src/library/scala/reflect/ReflectionUtils.scala deleted file mode 100644 index aa1285d5a0..0000000000 --- a/src/library/scala/reflect/ReflectionUtils.scala +++ /dev/null @@ -1,90 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Paul Phillips - */ - -package scala.reflect - -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: api.RequiredFile}].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 defaultReflectionClassLoader() = { - // say no to non-determinism of mirror classloaders - // default classloader will be instantiated using current system classloader - // if you wish so, you can rebind it by setting ``mirror.classLoader'' to whatever is necessary -// val cl = Thread.currentThread.getContextClassLoader -// if (cl == null) getClass.getClassLoader else cl -// cl - getClass.getClassLoader - } - - 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/library/scala/reflect/TagInterop.scala b/src/library/scala/reflect/TagInterop.scala deleted file mode 100644 index 6c6bfcc2f2..0000000000 --- a/src/library/scala/reflect/TagInterop.scala +++ /dev/null @@ -1,34 +0,0 @@ -package scala.reflect - -import scala.runtime.ScalaRunTime._ -import mirror._ -import definitions._ - -object TagInterop { - def arrayTagToClassManifest[T](tag: ArrayTag[T]): ClassManifest[T] = { - val erasure = arrayElementClass(tag) - if (erasure.isArray) { - val elementClass = arrayElementClass(erasure) - val elementManifest = arrayTagToClassManifest(ClassTag(elementClass)) - ClassManifest.arrayType(elementManifest).asInstanceOf[ClassManifest[T]] - } else { - ClassManifest.fromClass(erasure.asInstanceOf[Class[T]]) - } - } - - def concreteTypeTagToManifest[T](tag: ConcreteTypeTag[T]): Manifest[T] = { - // todo. reproduce manifest generation code here. toolboxes are too slow. - val implicitly = PredefModule.typeSignature.member(newTermName("implicitly")) - val taggedTpe = appliedType(staticClass("scala.reflect.Manifest").asTypeConstructor, List(tag.tpe)) - val materializer = TypeApply(Ident(implicitly), List(TypeTree(taggedTpe))) - try mkToolBox().runExpr(materializer).asInstanceOf[Manifest[T]] - catch { case ex: Throwable => Manifest.classType(tag.erasure).asInstanceOf[Manifest[T]] } - } - - def manifestToConcreteTypeTag[T](tag: Manifest[T]): ConcreteTypeTag[T] = { - val tpe = - if (tag.typeArguments.isEmpty) classToType(tag.erasure) - else appliedType(classToType(tag.erasure).typeConstructor, tag.typeArguments map (manifestToConcreteTypeTag(_)) map (_.tpe)) - ConcreteTypeTag(tpe, tag.erasure) - } -}
\ No newline at end of file diff --git a/src/library/scala/reflect/api/AnnotationInfos.scala b/src/library/scala/reflect/api/AnnotationInfos.scala index cc1c4d2b6b..d9f35024d9 100755 --- a/src/library/scala/reflect/api/AnnotationInfos.scala +++ b/src/library/scala/reflect/api/AnnotationInfos.scala @@ -1,42 +1,27 @@ package scala.reflect package api -trait AnnotationInfos { self: Universe => +trait AnnotationInfos extends base.AnnotationInfos { self: Universe => - type AnnotationInfo <: AnyRef - val AnnotationInfo: AnnotationInfoExtractor - - abstract class AnnotationInfoExtractor { - def apply(atp: Type, args: List[Tree], assocs: List[(Name, ClassfileAnnotArg)]): AnnotationInfo - def unapply(info: AnnotationInfo): Option[(Type, List[Tree], List[(Name, ClassfileAnnotArg)])] + override type AnnotationInfo >: Null <: AnyRef with AnnotationInfoApi + trait AnnotationInfoApi { + def atp: Type + def args: List[Tree] + def assocs: List[(Name, ClassfileAnnotArg)] } - type ClassfileAnnotArg <: AnyRef - implicit def classfileAnnotArgTag: ArrayTag[ClassfileAnnotArg] // need a precise tag to pass to UnPickle's toArray call - - type LiteralAnnotArg <: ClassfileAnnotArg - val LiteralAnnotArg: LiteralAnnotArgExtractor - - type ArrayAnnotArg <: ClassfileAnnotArg - val ArrayAnnotArg: ArrayAnnotArgExtractor - - type NestedAnnotArg <: ClassfileAnnotArg - val NestedAnnotArg: NestedAnnotArgExtractor - - abstract class LiteralAnnotArgExtractor { - def apply(const: Constant): LiteralAnnotArg - def unapply(arg: LiteralAnnotArg): Option[Constant] + override type LiteralAnnotArg >: Null <: ClassfileAnnotArg with LiteralAnnotArgApi + trait LiteralAnnotArgApi { + def const: Constant } - abstract class ArrayAnnotArgExtractor { - def apply(const: Array[ClassfileAnnotArg]): ArrayAnnotArg - def unapply(arg: ArrayAnnotArg): Option[Array[ClassfileAnnotArg]] + override type ArrayAnnotArg >: Null <: ClassfileAnnotArg with ArrayAnnotArgApi + trait ArrayAnnotArgApi { + def args: Array[ClassfileAnnotArg] } - abstract class NestedAnnotArgExtractor { - def apply(anninfo: AnnotationInfo): NestedAnnotArg - def unapply(arg: NestedAnnotArg): Option[AnnotationInfo] + override type NestedAnnotArg >: Null <: ClassfileAnnotArg with NestedAnnotArgApi + trait NestedAnnotArgApi { + def annInfo: AnnotationInfo } -} - - +}
\ No newline at end of file diff --git a/src/library/scala/reflect/api/Attachment.scala b/src/library/scala/reflect/api/Attachment.scala deleted file mode 100644 index 50f55b4aa5..0000000000 --- a/src/library/scala/reflect/api/Attachment.scala +++ /dev/null @@ -1,29 +0,0 @@ -package scala.reflect -package api - -/** Attachment is a generalisation of Position. - * Typically it stores a Position of a tree, but this can be extended to encompass arbitrary payloads. - * - * Attachments have to carry positions, because we don't want to introduce even a single additional field in Tree - * imposing an unnecessary memory tax because of something that will not be used in most cases. - */ -trait Attachment { - /** Gets the underlying position */ - def pos: Position - - /** Creates a copy of this attachment with its position updated */ - def withPos(newPos: Position): Attachment - - /** Gets the underlying payload */ - def payload: Any - - /** Creates a copy of this attachment with its payload updated */ - def withPayload(newPayload: Any): Attachment -} - -// [Eugene] with the introduction of `attach` and `attachment[T]` users don't need to create custom attachments anymore -// however, we cannot move attachments to scala.reflect.internal, because they are used in Trees, which are implemented completely in scala.reflect.api -private[scala] case class NontrivialAttachment(pos: api.Position, payload: collection.mutable.ListBuffer[Any]) extends Attachment { - def withPos(newPos: api.Position) = copy(pos = newPos, payload = payload) - def withPayload(newPayload: Any) = copy(pos = pos, payload = newPayload.asInstanceOf[collection.mutable.ListBuffer[Any]]) -}
\ No newline at end of file diff --git a/src/library/scala/reflect/api/ClassLoaders.scala b/src/library/scala/reflect/api/ClassLoaders.scala deleted file mode 100644 index 7be402d3df..0000000000 --- a/src/library/scala/reflect/api/ClassLoaders.scala +++ /dev/null @@ -1,16 +0,0 @@ -package scala.reflect -package api - -trait ClassLoaders { self: Universe => - - /** The symbol corresponding to the globally accessible class with the - * given fully qualified name `fullName`. - */ - def staticClass(fullName: String): Symbol - - /** The symbol corresponding to the globally accessible object with the - * given fully qualified name `fullName`. - */ - def staticModule(fullName: String): Symbol - -}
\ No newline at end of file diff --git a/src/library/scala/reflect/api/Constants.scala b/src/library/scala/reflect/api/Constants.scala index 42a0fa8a27..7862ab0d25 100755 --- a/src/library/scala/reflect/api/Constants.scala +++ b/src/library/scala/reflect/api/Constants.scala @@ -6,13 +6,12 @@ package scala.reflect package api -import java.lang.Integer.toOctalString -import annotation.switch - -trait Constants { +trait Constants extends base.Constants { self: Universe => - abstract class AbsConstant { + override type Constant >: Null <: AnyRef with ConstantApi + + abstract class ConstantApi { val value: Any def tpe: Type def isNaN: Boolean @@ -31,13 +30,4 @@ trait Constants { def convertTo(pt: Type): Constant } - - type Constant <: AbsConstant - - val Constant: ConstantExtractor - - abstract class ConstantExtractor { - def apply(const: Any): Constant - def unapply(arg: Constant): Option[Any] - } } diff --git a/src/library/scala/reflect/api/Exprs.scala b/src/library/scala/reflect/api/Exprs.scala index b8db64422e..dd09d8e7c6 100644 --- a/src/library/scala/reflect/api/Exprs.scala +++ b/src/library/scala/reflect/api/Exprs.scala @@ -6,14 +6,57 @@ package scala.reflect package api import language.implicitConversions +import scala.reflect.base.TreeCreator trait Exprs { self: Universe => /** An expression tree tagged with its type */ - case class Expr[+T: TypeTag](tree: Tree) { - def tpe: Type = implicitly[TypeTag[T]].tpe - def eval: T = mkToolBox().runExpr(tree).asInstanceOf[T] - lazy val value: T = eval - override def toString = "Expr["+tpe+"]("+tree+")" + trait Expr[+T] extends Equals with Serializable { + val mirror: Mirror + def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # Expr[T] + + def tree: Tree + def staticTpe: Type + def actualTpe: Type + + def splice: T + val value: T + + /** case class accessories */ + override def canEqual(x: Any) = x.isInstanceOf[Expr[_]] + override def equals(x: Any) = x.isInstanceOf[Expr[_]] && this.mirror == x.asInstanceOf[Expr[_]].mirror && this.tree == x.asInstanceOf[Expr[_]].tree + override def hashCode = mirror.hashCode * 31 + tree.hashCode + override def toString = "Expr["+staticTpe+"]("+tree+")" + } + + object Expr { + def apply[T: TypeTag](mirror: MirrorOf[self.type], treec: TreeCreator): Expr[T] = new ExprImpl[T](mirror.asInstanceOf[Mirror], treec) + def unapply[T](expr: Expr[T]): Option[Tree] = Some(expr.tree) + } + + private class ExprImpl[+T: TypeTag](val mirror: Mirror, val treec: TreeCreator) extends Expr[T] { + def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # Expr[T] = { + val otherMirror1 = otherMirror.asInstanceOf[MirrorOf[otherMirror.universe.type]] + val tag1 = (implicitly[TypeTag[T]] in otherMirror).asInstanceOf[otherMirror.universe.TypeTag[T]] + otherMirror.universe.Expr[T](otherMirror1, treec)(tag1) + } + + lazy val tree: Tree = treec[Exprs.this.type](mirror) + // [Eugene++] this is important + // !!! remove when we have improved type inference for singletons + // search for .type] to find other instances + lazy val staticTpe: Type = implicitly[TypeTag[T]].tpe + def actualTpe: Type = tree.tpe + + def splice: T = throw new UnsupportedOperationException(""" + |the function you're calling has not been spliced by the compiler. + |this means there is a cross-stage evaluation involved, and it needs to be invoked explicitly. + |if you're sure this is not an oversight, add scala-compiler.jar to the classpath, + |import `scala.tools.reflect.Eval` and call `<your expr>.eval` instead.""".trim.stripMargin) + lazy val value: T = throw new UnsupportedOperationException(""" + |the value you're calling is only meant to be used in cross-stage path-dependent types. + |if you want to splice the underlying expression, use `<your expr>.splice`. + |if you want to get a value of the underlying expression, add scala-compiler.jar to the classpath, + |import `scala.tools.reflect.Eval` and call `<your expr>.eval` instead.""".trim.stripMargin) } }
\ No newline at end of file diff --git a/src/library/scala/reflect/api/FlagSets.scala b/src/library/scala/reflect/api/FlagSets.scala new file mode 100644 index 0000000000..969176d641 --- /dev/null +++ b/src/library/scala/reflect/api/FlagSets.scala @@ -0,0 +1,112 @@ +package scala.reflect +package api + +import scala.language.implicitConversions + +trait FlagSets { self: Universe => + + type FlagSet + + trait FlagOps extends Any { + def | (right: FlagSet): FlagSet + def & (right: FlagSet): FlagSet + def containsAll (right: FlagSet): Boolean + } + + implicit def addFlagOps(left: FlagSet): FlagOps + + val Flag: FlagValues + + type FlagValues >: Null <: FlagValuesApi + + // [Eugene++] any other flags we would like to expose? + + trait FlagValuesApi { + + /** Flag indicating that symbol or tree represents a trait */ + val TRAIT: FlagSet + + /** Flag indicating that symbol or tree represents a module or its internal module class */ + val MODULE: FlagSet + + /** Flag indicating that symbol or tree represents a mutable variable */ + val MUTABLE: FlagSet + + /** Flag indicating that symbol or tree represents a package or its internal package class */ + val PACKAGE: FlagSet + + /** Flag indicating that symbol or tree represents a method */ + val METHOD: FlagSet + + /** Flag indicating that symbol or tree represents a macro definition. */ + val MACRO: FlagSet + + /** Flag indicating that symbol or tree represents an abstract type, method, or value */ + val DEFERRED: FlagSet + + /** Flag indicating that symbol or tree represents an abstract class */ + val ABSTRACT: FlagSet + + /** Flag indicating that symbol or tree has `final` modifier set */ + val FINAL: FlagSet + + /** Flag indicating that symbol or tree has `sealed` modifier set */ + val SEALED: FlagSet + + /** Flag indicating that symbol or tree has `implicit` modifier set */ + val IMPLICIT: FlagSet + + /** Flag indicating that symbol or tree has `lazy` modifier set */ + val LAZY: FlagSet + + /** Flag indicating that symbol or tree has `override` modifier set */ + val OVERRIDE: FlagSet + + /** Flag indicating that symbol or tree has `private` modifier set */ + val PRIVATE: FlagSet + + /** Flag indicating that symbol or tree has `protected` modifier set */ + val PROTECTED: FlagSet + + /** Flag indicating that symbol or tree has `case` modifier set */ + val CASE: FlagSet + + /** Flag indicating that symbol or tree has `abstract` and `override` modifiers set */ + val ABSOVERRIDE: FlagSet + + /** Flag indicating that symbol or tree represents a by-name parameter */ + val BYNAMEPARAM: FlagSet + + /** Flag indicating that symbol or tree represents a class or parameter. + * Both type and value parameters carry the flag. */ + val PARAM: FlagSet + + /** Flag indicating that symbol or tree represents a field of a class + * that was generated from a parameter of that class */ + val PARAMACCESSOR: FlagSet + + /** Flag indicating that symbol or tree represents a field of a case class + * that corresponds to a parameter in the first parameter list of the + * primary constructor of that class */ + val CASEACCESSOR: FlagSet + + /** Flag indicating that symbol or tree represents a contravariant + * type parameter (marked with `+`). */ + val COVARIANT: FlagSet + + /** Flag indicating that symbol or tree represents a contravariant + * type parameter (marked with `-`). */ + val CONTRAVARIANT: FlagSet + + /** Flag indicating that parameter has a default value */ + val DEFAULTPARAM: FlagSet + + /** Flag indicating that trait has neither method implementations nor fields. + * This means the trait can be represented as a Java interface. */ + val INTERFACE: FlagSet + + def union(flags: FlagSet*): FlagSet + def intersection(flag: FlagSet*): FlagSet + def containsAll(superset: FlagSet, subset: FlagSet): Boolean + } +} diff --git a/src/library/scala/reflect/api/FreeVars.scala b/src/library/scala/reflect/api/FreeVars.scala deleted file mode 100644 index 0bef099a55..0000000000 --- a/src/library/scala/reflect/api/FreeVars.scala +++ /dev/null @@ -1,42 +0,0 @@ -package scala.reflect -package api - -trait FreeVars { - self: Universe => - - /** Represents a free term captured by reification. - */ - type FreeTerm <: Symbol - - val FreeTerm: FreeTermExtractor - - abstract class FreeTermExtractor { - def unapply(freeTerm: FreeTerm): Option[(TermName, Type, Any, String)] - } - - /** Extracts free terms from a tree that is reified or contains reified subtrees. - */ - def freeTerms(tree: Tree): List[FreeTerm] - - /** Represents a free type captured by reification. - */ - type FreeType <: Symbol - - val FreeType: FreeTypeExtractor - - abstract class FreeTypeExtractor { - def unapply(freeType: FreeType): Option[(TypeName, Type, String)] - } - - /** Extracts free types from a tree that is reified or contains reified subtrees. - */ - def freeTypes(tree: Tree): List[FreeType] - - /** Substitutes free types in a reified tree. - */ - def substituteFreeTypes(tree: Tree, subs: Map[FreeType, Type]): Tree - - /** Substitutes free types in a reified type. - */ - def substituteFreeTypes(tpe: Type, subs: Map[FreeType, Type]): Type -} diff --git a/src/library/scala/reflect/api/FrontEnds.scala b/src/library/scala/reflect/api/FrontEnds.scala index 2c1f3feff6..a201b83444 100644 --- a/src/library/scala/reflect/api/FrontEnds.scala +++ b/src/library/scala/reflect/api/FrontEnds.scala @@ -1,7 +1,11 @@ package scala.reflect package api -trait FrontEnds { self: Universe => +// [Martin to Eugene] Todo: Needs to be evicted from API +// [Eugene++ to Martin] but how? we need them for macros +trait FrontEnds { + + type Position >: Null trait FrontEnd { object severity extends Enumeration diff --git a/src/library/scala/reflect/api/Importers.scala b/src/library/scala/reflect/api/Importers.scala index 1d8890b7db..69d6414f4f 100644 --- a/src/library/scala/reflect/api/Importers.scala +++ b/src/library/scala/reflect/api/Importers.scala @@ -1,6 +1,8 @@ package scala.reflect package api +// [Martin] Importers need to be made mirror aware. +// [Eugene++] this is important trait Importers { self: Universe => def mkImporter(from0: Universe): Importer { val from: from0.type } diff --git a/src/library/scala/reflect/api/Mirror.scala b/src/library/scala/reflect/api/Mirror.scala deleted file mode 100644 index ed8ead7aaf..0000000000 --- a/src/library/scala/reflect/api/Mirror.scala +++ /dev/null @@ -1,100 +0,0 @@ -package scala.reflect -package api - -/** A mirror establishes connections of - * runtime entities such as class names and object instances - * with a reflexive universe. - */ -trait Mirror extends Universe { - - /** Class loader that is a mastermind behind the reflexive mirror. - * - * By default it is set to system classloader (more precisely, to the classloader that loads the `scala.reflect.package` class). - * However, sometimes it is useful to have a mirror services by a custom classloader. - * - * There are two ways to customize the `classLoader`: - * 1) Create a new mirror using the `scala.reflect.mkMirror(classLoader: ClassLoader)` method - * 2) Set `classLoader` to the new value - * - * The first, immutable, way should be strongly preferred in most situation. - * However sometimes it is necessary to migrate the default reflexive mirror (`scala.reflect.mirror`) to a new classloader. - * In that and only that case, use the setter, but be very careful not to introduce inconsistencies. - */ - var classLoader: ClassLoader - - /** The Scala class symbol that has given fully qualified name - * @param name The fully qualified name of the class to be returned - * @throws java.lang.ClassNotFoundException if no class with that name exists - * to do: throws anything else? - */ - def symbolForName(name: String): Symbol - - /** Return a reference to the companion object of the given class symbol. - */ - def companionInstance(clazz: Symbol): AnyRef - - /** The Scala class symbol corresponding to the runtime class of the given instance. - * @param instance The instance - * @return The class Symbol for the instance - * @throws ? - */ - def symbolOfInstance(instance: Any): Symbol - - /** The Scala type corresponding to the runtime type of given instance. - * If the underlying class is parameterized, this will be an existential type, - * with unknown type arguments. - * - * @param instance The instance. - * @return The Type of the given instance. - * @throws ? - */ - def typeOfInstance(instance: Any): Type - - /** The value of a field on a receiver instance. - * @param receiver The receiver instance - * @param field The field - * @return The value contained in `receiver.field`. - */ - def getValueOfField(receiver: AnyRef, field: Symbol): Any - - /** Sets the value of a field on a receiver instance. - * @param receiver The receiver instance - * @param field The field - * @param value The new value to be stored in the field. - */ - def setValueOfField(receiver: AnyRef, field: Symbol, value: Any): Unit - - /** Invokes a method on a receiver instance with some arguments - * @param receiver The receiver instance - * @param meth The method - * @param args The method call's arguments - * @return The result of invoking `receiver.meth(args)` - */ - def invoke(receiver: AnyRef, meth: Symbol)(args: Any*): Any - - /** Maps a Java class to a Scala type reference - * @param clazz The Java class object - * @return A type (of kind `TypeRef`, or `ExistentialType` if `clazz` is polymorphic) - * that represents the class with all type parameters unknown - * (i.e. any type parameters of `clazz` are existentially quantified). - * */ - def classToType(clazz: java.lang.Class[_]): Type - - /** Maps a Java class to a Scala class symbol - * @param clazz The Java class object - * @return A symbol that represents the Scala view of the class. - */ - def classToSymbol(clazz: java.lang.Class[_]): Symbol - - /** Maps a Scala type to the corresponding Java class object - */ - def typeToClass(tpe: Type): java.lang.Class[_] - - /** Maps a Scala symbol to the corresponding Java class object - * @throws ClassNotFoundException if there is no Java class - * corresponding to the given Scala symbol. - * Note: If the Scala symbol is ArrayClass, a ClassNotFound exception is thrown - * because there is no unique Java class corresponding to a Scala generic array - */ - def symbolToClass(sym: Symbol): java.lang.Class[_] -} diff --git a/src/library/scala/reflect/api/Mirrors.scala b/src/library/scala/reflect/api/Mirrors.scala new file mode 100644 index 0000000000..2fcee8f227 --- /dev/null +++ b/src/library/scala/reflect/api/Mirrors.scala @@ -0,0 +1,213 @@ +package scala.reflect +package api + +trait Mirrors { self: Universe => + + type RuntimeClass >: Null + + // [Eugene++ to Martin] how do we reflect against inner classes? + // presumably, we should add `reflectClass` to both InstanceMirror (inner classes) and TemplateMirror (nested classes) + // in the former case, the resulting ClassMirror should remember the outer instance that spawned it to use it in reflective construction + + // [Eugene] also, it might make sense to provide shortcuts for the API + // + // for example, right now to invoke the same method for several different instances, you need: + // 1) get the method symbol + // 2) get the instance mirror for every instance + // 3) call reflectMethod on the instance mirrors for every instance + // 4) call apply for every instance (okay, this can be united with step #3, but still) + // + // I have several suggestions that we can discuss later: + // 1) For every `reflectXXX(sym: Symbol): XXXMirror`, add `reflectXXX(name: String, types: Type*): XXXMirror` and `reflectXXXs(): List[XXXMirror]` + // 2) Provide a way to skip obtaining InstanceMirror (step #2 in the outline provided above) + + // [Eugene] another improvement would be have mirrors reproduce the structure of the reflection domain + // e.g. a ClassMirror could also have a list of fields, methods, constructors and so on + // read up more on the proposed design in "Reflecting Scala" by Y. Coppel + + /** A mirror that reflects a runtime value */ + trait InstanceMirror { + + /** The instance value reflected by this mirror */ + def instance: Any + + /** The mirror corresponding to the run-time class of the reflected instance. */ + def reflectClass: ClassMirror + + /** Get value of field in reflected instance. + * @field A field symbol that should represent a field of the instance class. + * @return The value associated with that field in the reflected instance + * @throws ??? + */ + def reflectField(field: TermSymbol): FieldMirror + + /** Invokes a method on the reflected instance. + * @param meth A method symbol that should represent a method of the instance class + * @param args The arguments to pass to the method + * @return The result of invoking `meth(args)` on the reflected instance. + * @throws ??? + */ + def reflectMethod(method: MethodSymbol): MethodMirror + } + + /** A mirror that reflects a field */ + trait FieldMirror { + + /** The object containing the field */ + def receiver: AnyRef + + /** The field symbol representing the field */ + def field: TermSymbol + + /** Retrieves the value stored in the field */ + def get: Any + + /** Updates the value stored in the field */ + def set(value: Any): Unit + } + + /** A mirror that reflects a method handle */ + trait MethodMirror { + + /** The receiver object of the method */ + def receiver: AnyRef + + /** The method symbol representing the method */ + def method: MethodSymbol + + /** The result of applying the method to the given arguments */ + def apply(args: Any*): Any + } + + /** A mirror that reflects the instance or static parts of a runtime class */ + trait TemplateMirror { + + /** The runtime class reflected by this mirror */ + def runtimeClass: RuntimeClass + + /** True if the mirror represents the static part + * if a runtime class or the companion object of a Scala class. + * One has: + * + * this.isStatic == this.isInstanceOf[ModuleMirror] + * !this.isStatic == this.isInstanceOf[ClassMirror] + */ + def isStatic: Boolean + + /** The Scala symbol corresponding to the reflected runtime class or module. */ + def symbol: Symbol + + // [Eugene++ to Martin] I've removed `typeSignature`, because we can obtain it via `symbol.typeSignature` + + /** Optionally, the mirror of the companion reflected by this mirror. + * If this mirror reflects a Scala object, the mirror for the companion class, or None + * if the mirror represents a Scala object that comes without a class. + * Otherwise, if the mirror represents the static part of a runtime class, the + * mirror representing the instance part of the same class. + * Otherwise, if the mirror represents a Scala instance class, the mirror for the companion + * object of that class, or None if no such object exists. + * Otherwise, if the mirror represents a runtime instance class, a mirror representing the static + * part of the same class. + */ + def companion: Option[TemplateMirror] + } + + /** A mirror that reflects a Scala object definition or the static parts of a runtime class */ + trait ModuleMirror extends TemplateMirror { + + /** The Scala module symbol corresponding to the reflected module. */ + override def symbol: ModuleSymbol + + /** If the reflected runtime class corresponds to a Scala object definition, + * returns the single instance representing that object. + * If this mirror reflects the static part of a runtime class, returns `null`. + */ + def instance: Any + + /** Optionally, the mirror of the companion class if the object reflected by this mirror. + * If this mirror reflects a Scala object, the mirror for the companion class, or None + * if the mirror represents a Scala object that comes without a class. + * Otherwise, if the mirror represents the static part of a runtime class, the + * mirror representing the instance part of the same class. + */ + def companion: Option[ClassMirror] + } + + /** A mirror that reflects the instance parts of a runtime class */ + trait ClassMirror extends TemplateMirror { + + /** The Scala class symbol corresponding to the reflected class. */ + override def symbol: ClassSymbol + + /** Returns a fresh instance of by invoking that constructor. + * @throws InstantiationException if the class does not have a public + * constructor with an empty parameter list. + * @throws IllegalAccessException if the class or its constructor is not accessible. + * @throws ExceptionInInitializerError if the initialization of the constructor fails. + * @throws SecurityException if creating a new instance is not permitted. + */ + def reflectConstructor(constructor: MethodSymbol): MethodMirror + + /** Optionally, the mirror of the companion object of the class reflected by this mirror. + * If this mirror represents a Scala instance class, the mirror for the companion + * object of that class, or None if no such object exists. + * Otherwise, if the mirror represents a runtime instance class, a mirror representing the static + * part of the same class. + */ + def companion: Option[ModuleMirror] + } + + /** The API of a mirror for a reflective universe */ + trait RuntimeMirror extends MirrorOf[Mirrors.this.type] { self => + + /** A reflective mirror for the given object + * @param obj An arbitrary value + * @return The mirror for `obj`. + */ + def reflect(obj: Any): InstanceMirror + + /** A reflective mirror for the given Runtime class + * @param runtimeClass A Runtime class object + * @return The mirror for `runtimeClass` + */ + def reflectClass(runtimeClass: RuntimeClass): ClassMirror + + /** A reflective mirror for the Runtime class with the given name in the + * current classloader. + * @param name The fully qualified name of the class + * @return The mirror for the runtime class with fully qualified name + * `name` in the current class loader. + * @throws java.lang.ClassNotFoundException if no class with that name exists + * to do: throws anything else? + */ + def reflectClass(fullName: String): ClassMirror + + /** A reflective mirror for the given Runtime class + * @param runtimeClass A Runtime class object + * @return The mirror for `runtimeClass` + */ + def reflectModule(runtimeClass: RuntimeClass): ModuleMirror + + /** A reflective mirror for the Runtime class with the given name in the + * current classloader. + * @param name The fully qualified name of the class + * @return The mirror for the runtime class with fully qualified name + * `name` in the current class loader. + * @throws java.lang.ClassNotFoundException if no class with that name exists + * to do: throws anything else? + */ + def reflectModule(fullName: String): ModuleMirror + + /** Maps a Scala type to the corresponding Java class object + */ + def runtimeClass(tpe: Type): RuntimeClass + + /** Maps a Scala class symbol to the corresponding Java class object + * @throws ClassNotFoundException if there is no Java class + * corresponding to the given Scala class symbol. + * Note: If the Scala symbol is ArrayClass, a ClassNotFound exception is thrown + * because there is no unique Java class corresponding to a Scala generic array + */ + def runtimeClass(cls: ClassSymbol): RuntimeClass + } +} diff --git a/src/library/scala/reflect/api/Modifier.scala b/src/library/scala/reflect/api/Modifier.scala deleted file mode 100644 index 1b67929e15..0000000000 --- a/src/library/scala/reflect/api/Modifier.scala +++ /dev/null @@ -1,82 +0,0 @@ -package scala.reflect.api - -import collection.{ immutable, mutable } - -abstract class Modifier private[api] () { - def name: String - def isKeyword: Boolean - def sourceString: String = if (isKeyword) "`" + name + "`" else name - - override def equals(that: Any) = this eq that.asInstanceOf[AnyRef] - override def hashCode = name.hashCode - override def toString = name -} -final class SymbolModifier private (val name: String, val isKeyword: Boolean) extends Modifier { - def this(name: String) = this(name, false) -} -final class SourceModifier private (val name: String) extends Modifier { - def isKeyword = true -} - -object SymbolModifier { - private val seen = mutable.ListBuffer[SymbolModifier]() - private[api] def apply(name: String): SymbolModifier = { - val mod = name match { - case "case" | "trait" => new SymbolModifier(name, isKeyword = true) - case _ => new SymbolModifier(name) - } - seen += mod - mod - } - private[api] def all = seen.toList -} -object SourceModifier { - private val seen = mutable.ListBuffer[SourceModifier]() - private[api] def apply(name: String): SourceModifier = { - val mod = new SourceModifier(name) - seen += mod - mod - } - private[api] def all = seen.toList -} - -object Modifier extends immutable.Set[Modifier] { - val `abstract` = SourceModifier("abstract") - val `final` = SourceModifier("final") - val `implicit` = SourceModifier("implicit") - val `lazy` = SourceModifier("lazy") - val `macro` = SourceModifier("macro") - val `override` = SourceModifier("override") - val `private` = SourceModifier("private") - val `protected` = SourceModifier("protected") - val `sealed` = SourceModifier("sealed") - - val `case` = SymbolModifier("case") - val `trait` = SymbolModifier("trait") - val abstractOverride = SymbolModifier("abstractOverride") - val bynameParameter = SymbolModifier("bynameParameter") - val caseAccessor = SymbolModifier("caseAccessor") - val contravariant = SymbolModifier("contravariant") - val covariant = SymbolModifier("covariant") - val defaultInit = SymbolModifier("defaultInit") - val defaultParameter = SymbolModifier("defaultParameter") - val deferred = SymbolModifier("deferred") - val interface = SymbolModifier("interface") - val java = SymbolModifier("java") - val local = SymbolModifier("local") - val mutable = SymbolModifier("mutable") - val paramAccessor = SymbolModifier("paramAccessor") - val parameter = SymbolModifier("parameter") - val preSuper = SymbolModifier("preSuper") - val static = SymbolModifier("static") - - val sourceModifiers: Set[SourceModifier] = SourceModifier.all.toSet - val symbolModifiers: Set[SymbolModifier] = SymbolModifier.all.toSet - val allModifiers: Set[Modifier] = sourceModifiers ++ symbolModifiers - def values = allModifiers - - def contains(key: Modifier) = allModifiers(key) - def iterator = allModifiers.iterator - def -(elem: Modifier) = allModifiers - elem - def +(elem: Modifier) = allModifiers + elem -} diff --git a/src/library/scala/reflect/api/Names.scala b/src/library/scala/reflect/api/Names.scala index 96651ffa88..222ee5024b 100755 --- a/src/library/scala/reflect/api/Names.scala +++ b/src/library/scala/reflect/api/Names.scala @@ -10,28 +10,18 @@ package api * Names are interned. That is, for two names `name11 and `name2`, * `name1 == name2` implies `name1 eq name2`. */ -trait Names { - /** The abstract type of names */ - type Name >: Null <: AbsName - - /** The abstract type of names representing terms */ - type TypeName <: Name - - /** The abstract type of names representing types */ - type TermName <: Name +trait Names extends base.Names { - abstract class AbsName { - /** Is this name a term name? */ - def isTermName: Boolean - - /** Is this name a type name? */ - def isTypeName: Boolean + /** The abstract type of names */ + type Name >: Null <: NameApi - /** Returns a term name that represents the same string as this name */ - def toTermName: TermName + /** The extended API of names that's supported on reflect mirror via an + * implicit conversion in reflect.ops + */ + abstract class NameApi extends NameBase { - /** Returns a type name that represents the same string as this name */ - def toTypeName: TypeName + // [Eugene++] this functionality should be in base + // this is because stuff will be reified in mangled state, and people will need a way to figure it out /** Replaces all occurrences of \$op_names in this name by corresponding operator symbols. * Example: `foo_\$plus\$eq` becomes `foo_+=` @@ -51,16 +41,4 @@ trait Names { */ def encodedName: Name } - - /** Create a new term name. - */ - def newTermName(s: String): TermName - - /** Creates a new type name. - */ - def newTypeName(s: String): TypeName - - def EmptyTermName: TermName = newTermName("") - - def EmptyTypeName: TypeName = EmptyTermName.toTypeName } diff --git a/src/library/scala/reflect/api/Positions.scala b/src/library/scala/reflect/api/Positions.scala index 8f01e0ced1..9d3d90d9f8 100644 --- a/src/library/scala/reflect/api/Positions.scala +++ b/src/library/scala/reflect/api/Positions.scala @@ -1,16 +1,11 @@ package scala.reflect package api -trait Positions { +trait Positions extends base.Positions { self: Universe => - // [Eugene] in quite a lot of situations (mostly related to error reporting) we need positions in the API - // however it seems that neither runtime compilation, nor macros need facilities to create positions from scratch - // both emit ASTs, which can be automatically transformed into synthetic sources and assigned with synthetic positions - // hence I added possibilities to inspect everything we can, but add any position factories - // this simplified a lot of things, the biggest of them is that we don't need to expose SourceFile/AbstractFile - type Position <: scala.reflect.api.Position - val NoPosition: Position + /** .. */ + type Position >: Null <: PositionApi { type Pos = Position } /** A position that wraps a set of trees. * The point of the wrapping position is the point of the default position. @@ -31,11 +26,8 @@ trait Positions { * shortening the range or assigning TransparentPositions * to some of the nodes in `tree`. */ - def ensureNonOverlapping(tree: Tree, others: List[Tree]) - - /** Assigns a given position to all position-less nodes of a given AST. - */ - def atPos[T <: Tree](pos: Position)(tree: T): T + //def ensureNonOverlapping(tree: Tree, others: List[Tree]) + // [Eugene++] can this method be of use for macros? } /** The Position class and its subclasses represent positions of ASTs and symbols. @@ -82,7 +74,9 @@ trait Positions { * pos.makeTransparent converts an opaque range position into a transparent one. * returns all other positions unchanged. */ -trait Position extends Attachment { +trait PositionApi extends Attachments { + + type Pos >: Null <: PositionApi /** Java file corresponding to the source file of this position. */ @@ -97,17 +91,17 @@ trait Position extends Attachment { */ def isDefined: Boolean - /** Is this position a transparent position? */ - def isTransparent: Boolean - /** Is this position a range position? */ def isRange: Boolean + /** Is this position a transparent position? */ + def isTransparent: Boolean + /** Is this position a non-transparent range position? */ def isOpaqueRange: Boolean /** if opaque range, make this position transparent */ - def makeTransparent: Position + def makeTransparent: Pos /** The start of the position's range, error if not a range position */ def start: Int @@ -128,73 +122,73 @@ trait Position extends Attachment { def endOrPoint: Int /** The same position with a different start value (if a range) */ - def withStart(off: Int): Position + def withStart(off: Int): Pos /** The same position with a different end value (if a range) */ - def withEnd(off: Int): Position + def withEnd(off: Int): Pos /** The same position with a different point value (if a range or offset) */ - def withPoint(off: Int): Position + def withPoint(off: Int): Pos /** 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 + def union(pos: Pos): Pos - /** If this is a range position, the offset position of its start. + /** If this is a range position, the offset position of its point. * Otherwise the position itself */ - def focusStart: Position + def focus: Pos - /** If this is a range position, the offset position of its point. + /** If this is a range position, the offset position of its start. * Otherwise the position itself */ - def focus: Position + def focusStart: Pos /** If this is a range position, the offset position of its end. * Otherwise the position itself */ - def focusEnd: Position + def focusEnd: Pos /** 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 + def includes(pos: Pos): Boolean /** Does this position properly include the given position `pos` ("properly" meaning their * ranges are not the same)? */ - def properlyIncludes(pos: Position): Boolean + def properlyIncludes(pos: Pos): Boolean /** 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 + def precedes(pos: Pos): Boolean /** Does this position properly precede the given position `pos` ("properly" meaning their ranges * do not share a common point). */ - def properlyPrecedes(pos: Position): Boolean + def properlyPrecedes(pos: Pos): Boolean /** 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 + def overlaps(pos: Pos): Boolean /** Does this position cover the same range as that position? * Holds only if both position are ranges */ - def sameRange(pos: Position): Boolean + def sameRange(pos: Pos): Boolean def line: Int def column: Int /** Convert this to a position around `point` that spans a single source line */ - def toSingleLine: Position + def toSingleLine: Pos def lineContent: String diff --git a/src/library/scala/reflect/api/RequiredFile.scala b/src/library/scala/reflect/api/RequiredFile.scala deleted file mode 100644 index 4a54595940..0000000000 --- a/src/library/scala/reflect/api/RequiredFile.scala +++ /dev/null @@ -1,7 +0,0 @@ -package scala.reflect -package api - -trait RequiredFile { - def path: String - def canonicalPath: String -} diff --git a/src/library/scala/reflect/api/StandardDefinitions.scala b/src/library/scala/reflect/api/StandardDefinitions.scala index 21f7c9283b..c2a89f92dd 100755 --- a/src/library/scala/reflect/api/StandardDefinitions.scala +++ b/src/library/scala/reflect/api/StandardDefinitions.scala @@ -2,144 +2,47 @@ * Copyright 2005-2011 LAMP/EPFL * @author Martin Odersky */ - package scala.reflect package api -trait StandardTypes { - self: Universe => - - val ByteTpe: Type - val ShortTpe: Type - val CharTpe: Type - val IntTpe: Type - val LongTpe: Type - val FloatTpe: Type - val DoubleTpe: Type - val BooleanTpe: Type - val UnitTpe: Type - - val AnyTpe: Type - val AnyValTpe: Type - val AnyRefTpe: Type - val ObjectTpe: Type - - val NothingTpe: Type - val NullTpe: Type - val StringTpe: Type -} - -trait StandardDefinitions extends StandardTypes { +trait StandardDefinitions extends base.StandardDefinitions { self: Universe => - val definitions: AbsDefinitions - - // I intend to pull everything in here out of the public API. - trait AbsDefinitionsInternal { - def ArrayModule: Symbol - def ArrayModule_overloadedApply: Symbol - def Array_apply: Symbol - def Array_clone: Symbol - def Array_length: Symbol - def Array_update: Symbol - def ByNameParamClass: Symbol - def ClassTagModule: Symbol - def ConcreteTypeTagModule: Symbol - def ConsClass: Symbol - def EmptyPackageClass: Symbol - def FunctionClass : Array[Symbol] - def IterableClass: Symbol - def IteratorClass: Symbol - def IteratorModule: Symbol - def Iterator_apply: Symbol - def JavaLangPackageClass: Symbol - def JavaRepeatedParamClass: Symbol - def ListModule: Symbol - def List_apply: Symbol - def NilModule: Symbol - def NoneModule: Symbol - def OptionClass: Symbol - def ProductClass : Array[Symbol] - def RepeatedParamClass: Symbol - def ScalaPackageClass: Symbol - def SeqClass: Symbol - def SeqModule: Symbol - def SomeClass: Symbol - def SomeModule: Symbol - def StringBuilderClass: Symbol - def SymbolClass : Symbol - def TraversableClass: Symbol - def TupleClass : Array[Symbol] - def TypeTagModule: Symbol - def ScalaPrimitiveValueClasses: List[ClassSymbol] - } - - trait AbsDefinitions extends AbsDefinitionsInternal { - // packages - def RootClass: ClassSymbol - def RootPackage: PackageSymbol - def EmptyPackage: PackageSymbol - def ScalaPackage: PackageSymbol - def JavaLangPackage: PackageSymbol - - // top types - def AnyClass : ClassSymbol - def AnyValClass: ClassSymbol - def ObjectClass: ClassSymbol - def AnyRefClass: TypeSymbol - - // bottom types - def NullClass : ClassSymbol - def NothingClass: ClassSymbol - - // the scala value classes - def UnitClass : ClassSymbol - def ByteClass : ClassSymbol - def ShortClass : ClassSymbol - def CharClass : ClassSymbol - def IntClass : ClassSymbol - def LongClass : ClassSymbol - def FloatClass : ClassSymbol - def DoubleClass : ClassSymbol - def BooleanClass: ClassSymbol - - // some special classes - def StringClass : ClassSymbol - def ClassClass : ClassSymbol - def ArrayClass: ClassSymbol - - // collections classes - def ListClass: ClassSymbol + val definitions: DefinitionsApi + + trait DefinitionsApi extends DefinitionsBase { + def JavaLangPackageClass: ClassSymbol + def JavaLangPackage: ModuleSymbol + def ArrayModule: ModuleSymbol + def ArrayModule_overloadedApply: TermSymbol // todo. fix the bug in Definitions.getMemberMethod + def Array_apply: TermSymbol // todo. fix the bug in Definitions.getMemberMethod + def Array_clone: TermSymbol // todo. fix the bug in Definitions.getMemberMethod + def Array_length: TermSymbol // todo. fix the bug in Definitions.getMemberMethod + def Array_update: TermSymbol // todo. fix the bug in Definitions.getMemberMethod + def ByNameParamClass: ClassSymbol + def ConsClass: ClassSymbol + def FunctionClass : Array[ClassSymbol] + def IterableClass: ClassSymbol + def IteratorClass: ClassSymbol + def IteratorModule: ModuleSymbol + def Iterator_apply: TermSymbol // todo. fix the bug in Definitions.getMemberMethod + def JavaRepeatedParamClass: ClassSymbol def ListModule: ModuleSymbol - - // collections modules - def PredefModule: ModuleSymbol - - // type tags - def ClassTagClass: ClassSymbol - def TypeTagClass: ClassSymbol - def ConcreteTypeTagClass: ClassSymbol - - /** Given a type T, returns the type corresponding to the VM's - * representation: ClassClass's type constructor applied to `arg`. - */ - def vmClassType(arg: Type): Type // !!! better name? - // [Eugene] we already have arg.erasure, right? - // - // [Paul] You misunderstand the method (it could be better named). - // Given List[String], it returns java.lang.Class[List[String]] - // (or the .Net equivalent), not the erasure of List[String]. - // See def ClassType in definitions - that's what it was called before, - // and obviously that name has to go. - - /** The string representation used by the given type in the VM. - */ - def vmSignature(sym: Symbol, info: Type): String - - /** Is symbol one of the value classes? */ - def isPrimitiveValueClass(sym: Symbol): Boolean // !!! better name? - - /** Is symbol one of the numeric value classes? */ - def isNumericValueClass(sym: Symbol): Boolean // !!! better name? + def List_apply: TermSymbol // todo. fix the bug in Definitions.getMemberMethod + def NilModule: ModuleSymbol + def NoneModule: ModuleSymbol + def OptionClass: ClassSymbol + def ProductClass : Array[ClassSymbol] + def RepeatedParamClass: ClassSymbol + def SeqClass: ClassSymbol + def SeqModule: ModuleSymbol + def SomeClass: ClassSymbol + def SomeModule: ModuleSymbol + def StringBuilderClass: ClassSymbol + def SymbolClass : ClassSymbol + def TraversableClass: ClassSymbol + def TupleClass: Array[Symbol] // cannot make it Array[ClassSymbol], because TupleClass(0) is supposed to be NoSymbol. weird + def ScalaPrimitiveValueClasses: List[ClassSymbol] + def ScalaNumericValueClasses: List[ClassSymbol] } } diff --git a/src/library/scala/reflect/api/StandardNames.scala b/src/library/scala/reflect/api/StandardNames.scala index a17ea216f7..80aed04073 100644 --- a/src/library/scala/reflect/api/StandardNames.scala +++ b/src/library/scala/reflect/api/StandardNames.scala @@ -2,36 +2,30 @@ * Copyright 2005-2011 LAMP/EPFL * @author Martin Odersky */ - package scala.reflect package api -trait StandardNames { +trait StandardNames extends base.StandardNames { self: Universe => - val nme: AbsTermNames - val tpnme: AbsTypeNames - - trait AbsNames { - type NameType <: Name + val nme: TermNamesApi + val tpnme: TypeNamesApi + trait NamesApi extends NamesBase { val ANON_CLASS_NAME: NameType val ANON_FUN_NAME: NameType val EMPTY: NameType - val EMPTY_PACKAGE_NAME: NameType val ERROR: NameType val IMPORT: NameType val MODULE_VAR_SUFFIX: NameType - val NO_NAME: NameType val PACKAGE: NameType val ROOT: NameType val SPECIALIZED_SUFFIX: NameType - val WILDCARD: NameType def flattenedName(segments: Name*): NameType } - trait AbsTermNames extends AbsNames { + trait TermNamesApi extends NamesApi with TermNamesBase { val EXPAND_SEPARATOR_STRING: String val IMPL_CLASS_SUFFIX: String val INTERPRETER_IMPORT_WRAPPER: String @@ -50,16 +44,15 @@ trait StandardNames { val TRAIT_SETTER_SEPARATOR_STRING: String val ANYNAME: TermName - val CONSTRUCTOR: TermName val FAKE_LOCAL_THIS: TermName val INITIALIZER: TermName val LAZY_LOCAL: TermName - val MIRROR_FREE_PREFIX: TermName - val MIRROR_FREE_THIS_SUFFIX: TermName - val MIRROR_FREE_VALUE_SUFFIX: TermName - val MIRROR_PREFIX: TermName - val MIRROR_SHORT: TermName - val MIRROR_SYMDEF_PREFIX: TermName + val MIRROR_FREE_PREFIX: NameType + val MIRROR_FREE_THIS_SUFFIX: NameType + val MIRROR_FREE_VALUE_SUFFIX: NameType + val MIRROR_PREFIX: NameType + val MIRROR_SHORT: NameType + val MIRROR_SYMDEF_PREFIX: NameType val MIXIN_CONSTRUCTOR: TermName val MODULE_INSTANCE_FIELD: TermName val OUTER: TermName @@ -146,7 +139,7 @@ trait StandardNames { def splitSpecializedName(name: Name): (Name, String, String) } - trait AbsTypeNames extends AbsNames { + trait TypeNamesApi extends NamesApi with TypeNamesBase { val BYNAME_PARAM_CLASS_NAME: TypeName val EQUALS_PATTERN_NAME: TypeName val JAVA_REPEATED_PARAM_CLASS_NAME: TypeName diff --git a/src/library/scala/reflect/api/Symbols.scala b/src/library/scala/reflect/api/Symbols.scala index 32faee2512..1d266dc778 100755 --- a/src/library/scala/reflect/api/Symbols.scala +++ b/src/library/scala/reflect/api/Symbols.scala @@ -1,149 +1,55 @@ package scala.reflect package api -trait Symbols { self: Universe => - - type Symbol >: Null <: AbsSymbol - type TypeSymbol <: Symbol with TypeSymbolApi - type TermSymbol <: Symbol with TermSymbolApi - type MethodSymbol <: TermSymbol with MethodSymbolApi - type ModuleSymbol <: TermSymbol with ModuleSymbolApi - type PackageSymbol <: ModuleSymbol with PackageSymbolApi - type ClassSymbol <: TypeSymbol with ClassSymbolApi - - val NoSymbol: Symbol - - trait TypeSymbolApi { - self: TypeSymbol => - - def name: TypeName - } - trait TermSymbolApi { - self: TermSymbol => - - def name: TermName - } - trait MethodSymbolApi extends TermSymbolApi { - self: MethodSymbol => - } - trait ClassSymbolApi extends TypeSymbolApi { - self: ClassSymbol => - } - trait ModuleSymbolApi extends TermSymbolApi { - self: ModuleSymbol => - } - trait PackageSymbolApi extends ModuleSymbolApi { - self: PackageSymbol => - } - - // I intend to pull everything in here out of the public API. - trait AbsSymbolInternal { - this: Symbol => - - /** A fresh symbol with given name `name`, position `pos` and flags `flags` that has - * the current symbol as its owner. - */ - def newNestedSymbol(name: Name, pos: Position, flags: Long, isClass: Boolean): Symbol - // needed by LiftCode !!! not enough reason to have in the api - - /** Low-level operation to set the symbol's flags - * @return the symbol itself - */ - def setInternalFlags(flags: Long): this.type - // needed by LiftCode !!! not enough reason to have in the api - - /** Set symbol's type signature to given type - * @return the symbol itself - */ - def setTypeSignature(tpe: Type): this.type - // needed by LiftCode !!! not enough reason to have in the api - - /** Set symbol's annotations to given annotations `annots`. - */ - def setAnnotations(annots: AnnotationInfo*): this.type - // needed by LiftCode !!! not enough reason to have in the api - - /** Does this symbol represent the definition of a skolem? - * Skolems are used during typechecking to represent type parameters viewed from inside their scopes. - * If yes, `isType` is also guaranteed to be true. - */ - def isSkolem : Boolean - - /** Does this symbol represent a free type captured by reification? - */ - // needed for ones who wish to inspect reified trees - def isFreeType : Boolean - - /** The type signature of this symbol. - * Note if the symbol is a member of a class, one almost always is interested - * in `typeSignatureIn` with a site type instead. - */ - def typeSignature: Type // !!! Since one should almost never use this, let's give it a different name. - - /** A type reference that refers to this type symbol - * Note if symbol is a member of a class, one almost always is interested - * in `asTypeIn` with a site type instead. - * - * Example: Given a class declaration `class C[T] { ... } `, that generates a symbol - * `C`. Then `C.asType` is the type `C[T]`. - * - * By contrast, `C.typeSignature` would be a type signature of form - * `PolyType(ClassInfoType(...))` that describes type parameters, value - * parameters, parent types, and members of `C`. - */ - def asType: Type // !!! Same as typeSignature. - - /** The kind of this symbol; used for debugging */ - def kind: String +trait Symbols extends base.Symbols { self: Universe => + + override type Symbol >: Null <: SymbolApi + override type TypeSymbol >: Null <: Symbol with TypeSymbolApi + override type TermSymbol >: Null <: Symbol with TermSymbolApi + override type MethodSymbol >: Null <: TermSymbol with MethodSymbolApi + override type ModuleSymbol >: Null <: TermSymbol with ModuleSymbolApi + override type ClassSymbol >: Null <: TypeSymbol with ClassSymbolApi + override type FreeTermSymbol >: Null <: TermSymbol with FreeTermSymbolApi + override type FreeTypeSymbol >: Null <: TypeSymbol with FreeTypeSymbolApi + + trait HasFlagsApi { + def flags: FlagSet + def hasFlag(fs: FlagSet): Boolean + def hasAllFlags(fs: FlagSet): Boolean + def flagString: String } - trait AbsSymbol extends AbsSymbolInternal { - this: Symbol => + /** The API of symbols */ + trait SymbolApi extends SymbolBase with HasFlagsApi { this: Symbol => /** The position of this symbol */ def pos: Position - /** The modifiers of this symbol - */ - def modifiers: Set[Modifier] - - /** Does this symbol have given modifier? - */ - def hasModifier(mod: Modifier): Boolean - /** A list of annotations attached to this Symbol. */ - def annotations: List[self.AnnotationInfo] + // [Eugene++] we cannot expose the `annotations` method because it doesn't auto-initialize a symbol (see SI-5423) + // there was an idea to use the `isCompilerUniverse` flag and auto-initialize symbols in `annotations` whenever this flag is false + // but it doesn't work, because the unpickler (that is shared between reflective universes and global universes) is very picky about initialization + // scala.reflect.internal.Types$TypeError: bad reference while unpickling scala.collection.immutable.Nil: type Nothing not found in scala.type not found. + // at scala.reflect.internal.pickling.UnPickler$Scan.toTypeError(UnPickler.scala:836) + // at scala.reflect.internal.pickling.UnPickler$Scan$LazyTypeRef.complete(UnPickler.scala:849) // auto-initialize goes boom + // at scala.reflect.internal.Symbols$Symbol.info(Symbols.scala:1140) + // at scala.reflect.internal.Symbols$Symbol.initialize(Symbols.scala:1272) // this triggers auto-initialize + // at scala.reflect.internal.Symbols$Symbol.annotations(Symbols.scala:1438) // unpickler first tries to get pre-existing annotations + // at scala.reflect.internal.Symbols$Symbol.addAnnotation(Symbols.scala:1458) // unpickler tries to add the annotation being read + // at scala.reflect.internal.pickling.UnPickler$Scan.readSymbolAnnotation(UnPickler.scala:489) // unpickler detects an annotation + // at scala.reflect.internal.pickling.UnPickler$Scan.run(UnPickler.scala:88) + // at scala.reflect.internal.pickling.UnPickler.unpickle(UnPickler.scala:37) + // at scala.reflect.runtime.JavaMirrors$JavaMirror.unpickleClass(JavaMirrors.scala:253) // unpickle from within a reflexive mirror + // def annotations: List[AnnotationInfo] + def getAnnotations: List[AnnotationInfo] /** Whether this symbol carries an annotation for which the given * symbol is its typeSymbol. */ def hasAnnotation(sym: Symbol): Boolean - /** The owner of this symbol. This is the symbol - * that directly contains the current symbol's definition. - * The `NoSymbol` symbol does not have an owner, and calling this method - * on one causes an internal error. - * The owner of the Scala root class [[scala.reflect.api.mirror.RootClass]] - * and the Scala root object [[scala.reflect.api.mirror.RootPackage]] is `NoSymbol`. - * Every other symbol has a chain of owners that ends in - * [[scala.reflect.api.mirror.RootClass]]. - */ - def owner: Symbol - - /** The name of the symbol as a member of the `Name` type. - */ - def name: Name - - /** The encoded full path name of this symbol, where outer names and inner names - * are separated by periods. - */ - def fullName: String - - /** An id number which is unique for all symbols in this universe */ - def id: Int - /** ... */ def orElse(alt: => Symbol): Symbol @@ -152,6 +58,11 @@ trait Symbols { self: Universe => */ def filter(cond: Symbol => Boolean): Symbol + /** If this is a NoSymbol, returns NoSymbol, otherwise + * returns the result of applying `f` to this symbol. + */ + def map(f: Symbol => Symbol): Symbol + /** ... */ def suchThat(cond: Symbol => Boolean): Symbol @@ -189,82 +100,57 @@ trait Symbols { self: Universe => */ def companionSymbol: Symbol - /** If symbol is an object definition, its implied associated class, - * otherwise NoSymbol + /** If this symbol is a package class, this symbol; otherwise the next enclosing + * package class, or `NoSymbol` if none exists. */ - def moduleClass: Symbol // needed for LiftCode + def enclosingPackageClass: Symbol /** If this symbol is a top-level class, this symbol; otherwise the next enclosing * top-level class, or `NoSymbol` if none exists. */ def enclosingTopLevelClass: Symbol - /** If this symbol is a class, this symbol; otherwise the next enclosing - * class, or `NoSymbol` if none exists. - */ - def enclosingClass: Symbol - - /** If this symbol is a method, this symbol; otherwise the next enclosing - * method, or `NoSymbol` if none exists. - */ - def enclosingMethod: Symbol - - /** If this symbol is a package class, this symbol; otherwise the next enclosing - * package class, or `NoSymbol` if none exists. + /** Does this symbol represent a value, i.e. not a module and not a method? + * If yes, `isTerm` is also guaranteed to be true. + * [Eugene++] I need a review of the implementation */ - def enclosingPackageClass: Symbol + def isValue: Boolean - /** Does this symbol represent the definition of term? - * Note that every symbol is either a term or a type. - * So for every symbol `sym`, either `sym.isTerm` is true - * or `sym.isType` is true. + /** Does this symbol represent a mutable value? + * If yes, `isTerm` and `isValue` are also guaranteed to be true. */ - def isTerm : Boolean + def isVariable: Boolean - /** Does this symbol represent a package? + /** Does this symbol represent the definition of a package? * If yes, `isTerm` is also guaranteed to be true. */ - def isPackage : Boolean + def isPackage: Boolean - /** Does this symbol represent the definition of method? - * If yes, `isTerm` is also guaranteed to be true. + /** Does this symbol represent a package class? + * If yes, `isClass` is also guaranteed to be true. */ - def isMethod : Boolean + def isPackageClass: Boolean /** Is this symbol an overloaded method? */ def isOverloaded : Boolean - /** Does this symbol represent a free term captured by reification? - */ - // needed for ones who wish to inspect reified trees - def isFreeTerm : Boolean - - /** Does this symbol represent the definition of type? - * Note that every symbol is either a term or a type. - * So for every symbol `sym`, either `sym.isTerm` is true - * or `sym.isType` is true. - */ - def isType : Boolean - - /** Does this symbol represent the definition of class? - * If yes, `isType` is also guaranteed to be true. - */ - def isClass : Boolean - - /** Does this symbol represent a package class? - * If yes, `isClass` is also guaranteed to be true. - */ - def isPackageClass : Boolean - /** Does this symbol represent the definition of a primitive class? * Namely, is it one of [[scala.Double]], [[scala.Float]], [[scala.Long]], [[scala.Int]], [[scala.Char]], * [[scala.Short]], [[scala.Byte]], [[scala.Unit]] or [[scala.Boolean]]? */ def isPrimitiveValueClass: Boolean + /** Does this symbol represent the definition of a numeric value class? + * Namely, is it one of [[scala.Double]], [[scala.Float]], [[scala.Long]], [[scala.Int]], [[scala.Char]], + * [[scala.Short]], [[scala.Byte]], [[scala.Unit]] or [[scala.Boolean]]? + */ + def isNumericValueClass: Boolean + /** Does this symbol represent the definition of a custom value class? * Namely, is AnyVal among its parent classes? + * TODO: Why not just have in reflect.internal? + * [Eugene++] because it's useful for macros */ def isDerivedValueClass: Boolean @@ -283,6 +169,38 @@ trait Symbols { self: Universe => */ def isExistential : Boolean + /** Does this symbol represent a free type captured by reification? + */ + def isFreeType : Boolean + + /** Does this symbol or its underlying type represent a typechecking error? + */ + def isErroneous : Boolean + + /** The type signature of this symbol seen as a member of given type `site`. + */ + def typeSignatureIn(site: Type): Type + + /** The type signature of this symbol. + * Note if the symbol is a member of a class, one almost always is interested + * in `typeSignatureIn` with a site type instead. + */ + def typeSignature: Type + + /** The string discriminator of this symbol; useful for debugging */ + def kind: String + } + + /** The API of term symbols */ + trait TermSymbolApi extends SymbolApi with HasFlagsApi with TermSymbolBase { this: TermSymbol => + /** The overloaded alternatives of this symbol */ + def alternatives: List[Symbol] + + def resolveOverloaded(pre: Type = NoPrefix, targs: Seq[Type] = List(), actuals: Seq[Type]): Symbol + } + + /** The API of type symbols */ + trait TypeSymbolApi extends SymbolApi with HasFlagsApi with TypeSymbolBase { this: TypeSymbol => /** Is the type parameter represented by this symbol contravariant? */ def isContravariant : Boolean @@ -291,40 +209,60 @@ trait Symbols { self: Universe => */ def isCovariant : Boolean - /** Does this symbol or its underlying type represent a typechecking error? - */ - def isErroneous : Boolean - - /** The type signature of this symbol seen as a member of given type `site`. + /** Does this symbol represent the definition of a skolem? + * Skolems are used during typechecking to represent type parameters viewed from inside their scopes. + * If yes, `isType` is also guaranteed to be true. */ - def typeSignatureIn(site: Type): Type + def isSkolem : Boolean /** A type reference that refers to this type symbol seen * as a member of given type `site`. */ def asTypeIn(site: Type): Type - /** The type constructor corresponding to this type symbol. - * This is different from `asType` in that type parameters - * are part of results of `asType`, but not of `asTypeConstructor`. - * - * Example: Given a class declaration `class C[T] { ... } `, that generates a symbol - * `C`. Then `C.asType` is the type `C[T]`, but `C.asTypeConstructor` is `C`. - */ - def asTypeConstructor: Type // needed by LiftCode + /** A type reference that refers to this type symbol + * Note if symbol is a member of a class, one almost always is interested + * in `asTypeIn` with a site type instead. + * + * Example: Given a class declaration `class C[T] { ... } `, that generates a symbol + * `C`. Then `C.asType` is the type `C[T]`. + * + * By contrast, `C.typeSignature` would be a type signature of form + * `PolyType(ClassInfoType(...))` that describes type parameters, value + * parameters, parent types, and members of `C`. + */ + def asType: Type // !!! Same as typeSignature. + } - /** If this symbol is a class, the type `C.this`, otherwise `NoPrefix`. - */ - def thisPrefix: Type + /** The API of method symbols */ + type MethodSymbolApi = MethodSymbolBase + /** The API of module symbols */ + type ModuleSymbolApi = ModuleSymbolBase + + /** The API of class symbols */ + trait ClassSymbolApi extends TypeSymbolApi with ClassSymbolBase { this: ClassSymbol => /** If this symbol is a class or trait, its self type, otherwise the type * of the symbol itself. */ def selfType: Type - /** The overloaded alternatives of this symbol */ - def alternatives: List[Symbol] + /** The type `C.this`, where `C` is the current class */ + def thisPrefix: Type + } - def resolveOverloaded(pre: Type = NoPrefix, targs: Seq[Type] = List(), actuals: Seq[Type]): Symbol + /** The API of free term symbols */ + trait FreeTermSymbolApi extends TermSymbolApi with FreeTermSymbolBase { this: FreeTermSymbol => + /** The place where this symbol has been spawned */ + def origin: String + + /** The valus this symbol refers to */ + def value: Any + } + + /** The API of free term symbols */ + trait FreeTypeSymbolApi extends TypeSymbolApi with FreeTypeSymbolBase { this: FreeTypeSymbol => + /** The place where this symbol has been spawned */ + def origin: String } } diff --git a/src/library/scala/reflect/api/ToolBoxes.scala b/src/library/scala/reflect/api/ToolBoxes.scala deleted file mode 100644 index 15c9fcc403..0000000000 --- a/src/library/scala/reflect/api/ToolBoxes.scala +++ /dev/null @@ -1,90 +0,0 @@ -package scala.reflect -package api - -trait ToolBoxes { self: Universe => - - type ToolBox <: AbsToolBox - - def mkToolBox(frontEnd: FrontEnd = mkSilentFrontEnd(), options: String = ""): AbsToolBox - - // [Eugene] what do you think about the interface? namely about the ``freeTypes'' part. - trait AbsToolBox { - - /** Front end of the toolbox. - * - * Accumulates and displays warnings and errors, can drop to interactive mode (if supported). - * The latter can be useful to study the typechecker or to debug complex macros. - */ - def frontEnd: FrontEnd - - /** Typechecks a tree using this ToolBox. - * This populates symbols and types of the tree and possibly transforms it to reflect certain desugarings. - * - * If the tree has unresolved type variables (represented as instances of ``FreeType'' symbols), - * then they might, might be partially or might not be specified in the ``freeTypes'' parameter. - * - * If ``silent'' is false, ``TypeError'' will be thrown in case of a typecheck error. - * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs. - * Such errors don't vanish and can be inspected by turning on -Ydebug. - * - * Typechecking can be steered with the following optional parameters: - * ``withImplicitViewsDisabled'' recursively prohibits implicit views (though, implicit vals will still be looked up and filled in), default value is false - * ``withMacrosDisabled'' recursively prohibits macro expansions and macro-based implicits, default value is false - */ - def typeCheck(tree: Tree, pt: Type = WildcardType, freeTypes: Map[FreeType, Type] = Map[FreeType, Type](), silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree - - /** Infers an implicit value of the expected type ``pt'' in the macro callsite context. - * - * If ``silent'' is false, ``TypeError'' will be thrown in case of an inference error. - * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs. - * Such errors don't vanish and can be inspected by turning on -Xlog-implicits. - * Unlike in ``typeCheck'', ``silent'' is true by default. - */ - def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false): Tree - - /** Infers an implicit view from the provided tree ``tree'' from the type ``from'' to the type ``to'' in the macro callsite context. - * - * Otional parameter, ``reportAmbiguous`` controls whether ambiguous implicit errors should be reported. - * If we search for a view simply to find out whether one type is coercible to another, it might be desirable to set this flag to ``false''. - * - * If ``silent'' is false, ``TypeError'' will be thrown in case of an inference error. - * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs. - * Such errors don't vanish and can be inspected by turning on -Xlog-implicits. - * Unlike in ``typeCheck'', ``silent'' is true by default. - */ - def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, reportAmbiguous: Boolean = true): Tree - - /** Recursively resets symbols and types in a given tree. - * - * Note that this does not revert the tree to its pre-typer shape. - * For more info, read up https://issues.scala-lang.org/browse/SI-5464. - */ - def resetAllAttrs(tree: Tree): Tree - - /** Recursively resets locally defined symbols and types in a given tree. - * - * Note that this does not revert the tree to its pre-typer shape. - * For more info, read up https://issues.scala-lang.org/browse/SI-5464. - */ - def resetLocalAttrs(tree: Tree): Tree - - /** Compiles and runs a tree using this ToolBox. - * - * If the tree has unresolved type variables (represented as instances of ``FreeType'' symbols), - * then they all have to be specified in the ``freeTypes'' parameter or an error occurs. - * - * This spawns the compiler at the Namer phase, and pipelines the tree through that compiler. - * Currently ``runExpr'' does not accept trees that already typechecked, because typechecking isn't idempotent. - * For more info, take a look at https://issues.scala-lang.org/browse/SI-5464. - */ - def runExpr(tree: Tree, freeTypes: Map[FreeType, Type] = Map[FreeType, Type]()): Any - - /** Represents an error during toolboxing - */ - type ToolBoxError <: Throwable - val ToolBoxError: ToolBoxErrorExtractor - abstract class ToolBoxErrorExtractor { - def unapply(error: ToolBoxError): Option[(ToolBox, String)] - } - } -}
\ No newline at end of file diff --git a/src/library/scala/reflect/api/TreeBuildUtil.scala b/src/library/scala/reflect/api/TreeBuildUtil.scala deleted file mode 100644 index 87790b3812..0000000000 --- a/src/library/scala/reflect/api/TreeBuildUtil.scala +++ /dev/null @@ -1,159 +0,0 @@ -package scala.reflect -package api - -trait TreeBuildUtil { self: Universe => - - /** The symbol corresponding to the globally accessible class with the given fully qualified name `fullName`. - * Unlike `staticClassIfDefined`, throws `MissingRequirementError` is requested class cannot be found. - */ - def staticClass(fullName: String): Symbol - - /** The symbol corresponding to the globally accessible class with the given fully qualified name `fullName`. - * Unlike `staticClass`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested class cannot be found. - */ - def staticClassIfDefined(fullName: String): Symbol - - /** The symbol corresponding to the globally accessible object with the given fully qualified name `fullName`. - * Unlike `staticModuleIfDefined`, throws `MissingRequirementError` is requested object cannot be found. - */ - def staticModule(fullName: String): Symbol - - /** The symbol corresponding to the globally accessible object with the given fully qualified name `fullName`. - * Unlike `staticModule`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested object cannot be found. - */ - def staticModuleIfDefined(fullName: String): Symbol - - /** The this-ptype of the globally accessible object with the - * given fully qualified name `fullName`. - */ - def thisModuleType(fullName: String): Type - - /** Selects type symbol with given simple name `name` from the defined members of `owner`. - * Unlike `selectTypeIfDefined`, throws `MissingRequirementError` is requested type symbol cannot be found. - */ - def selectType(owner: Symbol, name: String): Symbol - - /** Selects type symbol with given simple name `name` from the defined members of `owner`. - * Unlike `selectType`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested type symbol cannot be found. - */ - def selectTypeIfDefined(owner: Symbol, name: String): Symbol - - /** Selects term symbol with given name and type from the defined members of prefix type - * Unlike `selectTermIfDefined`, throws `MissingRequirementError` is requested term symbol cannot be found. - */ - def selectTerm(owner: Symbol, name: String): Symbol - - /** Selects term symbol with given name and type from the defined members of prefix type - * Unlike `selectTerm`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested term symbol cannot be found. - */ - def selectTermIfDefined(owner: Symbol, name: String): Symbol - - /** Selects overloaded method symbol with given name and index - * Unlike `selectOverloadedMethodIfDefined`, throws `MissingRequirementError` is requested overloaded method cannot be found. - */ - def selectOverloadedMethod(owner: Symbol, name: String, index: Int): Symbol - - /** Selects overloaded method symbol with given name and index - * Unlike `selectOverloadedMethod`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested overloaded method cannot be found. - */ - def selectOverloadedMethodIfDefined(owner: Symbol, name: String, index: Int): Symbol - - /** Create a fresh free term symbol. - * @param name the name of the free variable - * @param info the type signature of the free variable - * @param value the value of the free variable at runtime - * @param flags (optional) flags of the free variable - * @param origin debug information that tells where this symbol comes from - */ - def newFreeTerm(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): Symbol - - /** Create a fresh free non-existential type symbol. - * @param name the name of the free variable - * @param info the type signature of the free variable - * @param value a type tag that captures the value of the free variable - * is completely phantom, since the captured type cannot be propagated to the runtime - * if it could be, we wouldn't be creating a free type to begin with - * the only usage for it is preserving the captured symbol for compile-time analysis - * @param flags (optional) flags of the free variable - * @param origin debug information that tells where this symbol comes from - */ - def newFreeType(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): Symbol - - /** Create a fresh free existential type symbol. - * @param name the name of the free variable - * @param info the type signature of the free variable - * @param value a type tag that captures the value of the free variable - * is completely phantom, since the captured type cannot be propagated to the runtime - * if it could be, we wouldn't be creating a free type to begin with - * the only usage for it is preserving the captured symbol for compile-time analysis - * @param flags (optional) flags of the free variable - * @param origin (optional) debug information that tells where this symbol comes from - */ - def newFreeExistential(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): Symbol - - /** Create a Modiiers structure given internal flags, qualifier, annotations */ - def modifiersFromInternalFlags(flags: Long, privateWithin: Name, annotations: List[Tree]): Modifiers - - val gen: TreeGen { val global: TreeBuildUtil.this.type } - - type TreeGen <: AbsTreeGen -} - -// [Eugene to Paul] we need to expose some of the functionality provided by TreeGen -// I added some stuff that was necessary for typetag materialization macros -// but we should think it over and pick other generally useful stuff -// same goes for tree traversers/transformers, type maps, etc -// and once we expose all that, there's another question: how do we stay in sync? -trait AbsTreeGen { - val global: Universe - - import global._ - import definitions._ - - /** 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 - - /** 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 - - /** Builds a typed reference to given symbol with given stable prefix. */ - def mkAttributedRef(pre: Type, sym: Symbol): Tree - - /** Builds a typed reference to given symbol. */ - def mkAttributedRef(sym: Symbol): Tree - - /** Builds a typed This reference to given symbol. */ - def mkAttributedThis(sym: Symbol): Tree - - /** Builds a typed Ident with an underlying symbol. */ - def mkAttributedIdent(sym: Symbol): Tree - - /** Builds a typed Select with an underlying symbol. */ - def mkAttributedSelect(qual: Tree, sym: Symbol): Tree - - /** 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 - def mkMethodCall(method: Symbol, targs: List[Type], args: List[Tree]): Tree - def mkMethodCall(method: Symbol, args: List[Tree]): Tree - def mkMethodCall(target: Tree, args: List[Tree]): Tree - def mkMethodCall(receiver: Symbol, methodName: Name, args: List[Tree]): Tree - def mkMethodCall(receiver: Tree, method: Symbol, targs: List[Type], args: List[Tree]): Tree - def mkMethodCall(target: Tree, targs: List[Type], args: List[Tree]): Tree - def mkNullaryCall(method: Symbol, targs: List[Type]): Tree -} diff --git a/src/library/scala/reflect/api/TreePrinters.scala b/src/library/scala/reflect/api/TreePrinters.scala index 3d64ec8e40..08a08e7b90 100644 --- a/src/library/scala/reflect/api/TreePrinters.scala +++ b/src/library/scala/reflect/api/TreePrinters.scala @@ -13,7 +13,9 @@ trait TreePrinters { self: Universe => def withUniqueIds: this.type = { uniqueIds = true; this } } - def show(tree: Tree, mkPrinter: PrintWriter => TreePrinter = newTreePrinter): String = { + def show(tree: Tree): String = show(tree, newTreePrinter) + + def show(tree: Tree, mkPrinter: PrintWriter => TreePrinter): String = { val buffer = new StringWriter() val writer = new PrintWriter(buffer) val printer = mkPrinter(writer) @@ -29,13 +31,12 @@ trait TreePrinters { self: Universe => def newTreePrinter(out: PrintWriter): TreePrinter // emits more or less verbatim representation of the provided tree + // [Eugene] todo. needs to be refined + // http://groups.google.com/group/scala-user/browse_thread/thread/de5a5be2e083cf8e class RawTreePrinter(out: PrintWriter) extends TreePrinter { - val EmptyValDef = self.emptyValDef def print(args: Any*): Unit = args foreach { case EmptyTree => print("EmptyTree") - case EmptyValDef => - print("emptyValDef") case tree @ TypeTree() => print("TypeTree()") if (tree.tpe != null) @@ -45,7 +46,7 @@ trait TreePrinters { self: Universe => case Literal(Constant(s: String)) => print("Literal(Constant(\"" + s + "\"))") case tree: Tree => - print(tree.printingPrefix+"(") + print(tree.productPrefix+"(") val it = tree.productIterator while (it.hasNext) { it.next() match { @@ -69,16 +70,12 @@ trait TreePrinters { self: Universe => print(")") case mods: Modifiers => val parts = collection.mutable.ListBuffer[String]() - parts += "Set(" + mods.modifiers.map(_.sourceString).mkString(", ") + ")" - parts += "newTypeName(\"" + mods.privateWithin.toString + "\")" - parts += "List(" + mods.annotations.map{showRaw}.mkString(", ") + ")" - - var keep = 3 - if (keep == 3 && mods.annotations.isEmpty) keep -= 1 - if (keep == 2 && mods.privateWithin == EmptyTypeName) keep -= 1 - if (keep == 1 && mods.modifiers.isEmpty) keep -= 1 - - print("Modifiers(", parts.take(keep).mkString(", "), ")") + parts += mods.flagString + if (mods.privateWithin.toString.nonEmpty) + parts += "newTypeName(\"" + mods.privateWithin.toString + "\")" + if (mods.annotations.nonEmpty) + parts += mods.annotations map showRaw mkString ("List(", ", ", ")") + print(parts mkString ("Modifiers(", ", ", ")")) case name: Name => if (name.isTermName) print("newTermName(\"") else print("newTypeName(\"") print(name.toString) diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala index 3427136fde..2d130daa4e 100644 --- a/src/library/scala/reflect/api/Trees.scala +++ b/src/library/scala/reflect/api/Trees.scala @@ -2,169 +2,22 @@ * Copyright 2005-2011 LAMP/EPFL * @author Martin Odersky */ - package scala.reflect package api -import scala.collection.mutable.ListBuffer - // Syncnote: Trees are currently not thread-safe. -trait Trees { self: Universe => +trait Trees extends base.Trees { self: Universe => - private[scala] var nodeCount = 0 + override type Tree >: Null <: TreeApi - type Modifiers >: Null <: AbsModifiers - val NoMods: Modifiers + /** ... */ + trait TreeApi extends TreeBase { this: Tree => - // TODO - Where do I put this? - object BackquotedIdentifier + /** ... */ + def pos: Position - abstract class AbsModifiers { - def modifiers: Set[Modifier] - def hasModifier(mod: Modifier): Boolean - def privateWithin: Name // default: EmptyTypeName - def annotations: List[Tree] // default: List() - def mapAnnotations(f: List[Tree] => List[Tree]): Modifiers - } - - def Modifiers(mods: Set[Modifier] = Set(), - privateWithin: Name = EmptyTypeName, - annotations: List[Tree] = List()): Modifiers - - /** Tree is the basis for scala's abstract syntax. The nodes are - * implemented as case classes, and the parameters which initialize - * a given tree are immutable: however Trees have several mutable - * fields which are manipulated in the course of typechecking, - * including pos, symbol, and tpe. - * - * Newly instantiated trees have tpe set to null (though it - * may be set immediately thereafter depending on how it is - * constructed.) When a tree is passed to the typer, typically via - * `typer.typed(tree)`, under normal circumstances the tpe must be - * null or the typer will ignore it. Furthermore, the typer is not - * required to return the same tree it was passed. - * - * Trees can be easily traversed with e.g. foreach on the root node; - * for a more nuanced traversal, subclass Traverser. Transformations - * can be considerably trickier: see the numerous subclasses of - * Transformer found around the compiler. - * - * Copying Trees should be done with care depending on whether - * it need be done lazily or strictly (see LazyTreeCopier and - * StrictTreeCopier) and on whether the contents of the mutable - * fields should be copied. The tree copiers will copy the mutable - * attributes to the new tree; calling Tree#duplicate will copy - * symbol and tpe, but all the positions will be focused. - * - * Trees can be coarsely divided into four mutually exclusive categories: - * - * - TermTrees, representing terms - * - TypTrees, representing types. Note that is `TypTree`, not `TypeTree`. - * - SymTrees, which may represent types or terms. - * - Other Trees, which have none of those as parents. - * - * SymTrees include important nodes Ident and Select, which are - * used as both terms and types; they are distinguishable based on - * whether the Name is a TermName or TypeName. The correct way for - * to test for a type or a term (on any Tree) are the isTerm/isType - * methods on Tree. - * - * "Others" are mostly syntactic or short-lived constructs. Examples - * include CaseDef, which wraps individual match cases: they are - * neither terms nor types, nor do they carry a symbol. Another - * example is Parens, which is eliminated during parsing. - */ - abstract class Tree extends Product { - val id = nodeCount - nodeCount += 1 - - /** Prefix under which to print this tree type. Defaults to product - * prefix (e.g. DefTree) but because that is used in reification - * it cannot be altered without breaking reflection. - */ - def printingPrefix = productPrefix - - def pos: Position = rawatt.pos.asInstanceOf[Position] // [Eugene] how do we get rid of this cast? - def pos_=(pos: Position): Unit = rawatt = (rawatt withPos pos) // the "withPos" part is crucial to robustness - def setPos(newpos: Position): this.type = { pos = newpos; this } - - // [Eugene] can we make this more type-safe - private var rawatt: Attachment = NoPosition - def attach(att: Any): Unit = - rawatt match { - case NontrivialAttachment(pos, payload) => - val index = payload.indexWhere(p => p.getClass == att.getClass) - if (index == -1) payload += att - else payload(index) = att - case _ => - rawatt = NontrivialAttachment(pos, collection.mutable.ListBuffer[Any](att)) - } - - // a) why didn't this method already exist - // b) what is all this "Any" business? - // c) am I reverse-engineering this correctly? It shouldn't be hard - // to figure out what is attached. - def attachments: List[Any] = rawatt match { - case NoPosition => Nil - case NontrivialAttachment(pos, atts) => pos :: atts.toList - case x => List(x) - } - // Writing "Any" repeatedly to work within this structure - // is making my skin crawl. - def hasAttachment(x: Any) = attachments contains x - - def withAttachment(att: Any): this.type = { attach(att); this } - def detach(att: Any): Unit = - detach(att.getClass) - def detach(clazz: java.lang.Class[_]): Unit = - rawatt match { - case NontrivialAttachment(pos, payload) => - val index = payload.indexWhere(p => p.getClass == clazz) - if (index != -1) payload.remove(index) - case _ => - // do nothing - } - def withoutAttachment(att: Any): this.type = { detach(att); this } - def attachment[T: ClassTag]: T = attachmentOpt[T] getOrElse { throw new Error("no attachment of type %s".format(classTag[T].erasure)) } - def attachmentOpt[T: ClassTag]: Option[T] = - firstAttachment { case attachment if attachment.getClass == classTag[T].erasure => attachment.asInstanceOf[T] } - - def firstAttachment[T](p: PartialFunction[Any, T]): Option[T] = - rawatt match { - case NontrivialAttachment(pos, payload) => payload.collectFirst(p) - case _ => None - } - - private[this] var rawtpe: Type = _ - - def tpe = rawtpe - def tpe_=(t: Type) = rawtpe = t - - def resetType(): this.type = { tpe = null ; this } - def resetSymbol(): this.type = { if (hasSymbol) symbol = NoSymbol ; this } - - /** Set tpe to give `tp` and return this. - */ - def setType(tp: Type): this.type = { rawtpe = tp; this } - - /** Like `setType`, but if this is a previously empty TypeTree that - * fact is remembered so that resetAllAttrs will snap back. - * - * @PP: Attempting to elaborate on the above, I find: If defineType - * is called on a TypeTree whose type field is null or NoType, - * this is recorded as "wasEmpty = true". That value is used in - * ResetAttrs, which nulls out the type field of TypeTrees - * for which wasEmpty is true, leaving the others alone. - * - * resetAllAttrs is used in situations where some speculative - * typing of a tree takes place, fails, and the tree needs to be - * returned to its former state to try again. So according to me: - * using `defineType` instead of `setType` is how you communicate - * that the type being set does not depend on any previous state, - * and therefore should be abandoned if the current line of type - * inquiry doesn't work out. - */ - def defineType(tp: Type): this.type = setType(tp) + /** ... */ + def tpe: Type /** Note that symbol is fixed as null at this level. In SymTrees, * it is overridden and implemented with a var, initialized to NoSymbol. @@ -181,887 +34,528 @@ trait Trees { self: Universe => * Attempting to set the symbol of a Tree which does not support * it will induce an exception. */ - 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 symbol: Symbol - def hasSymbol = false - def isDef = false - def isEmpty = false - @inline final def orElse(alt: => Tree) = if (!isEmpty) this else alt - @inline final def andAlso(f: Tree => Unit): Tree = { if (!this.isEmpty) f(this) ; this } + /** ... */ + def hasSymbol: Boolean - def hasAssignedType = (tpe ne null) && (tpe ne NoType) - def hasAssignedSymbol = (symbol ne null) && (symbol ne NoSymbol) - - @inline final def hasSymbolWhich(f: Symbol => Boolean) = hasAssignedSymbol && f(symbol) - @inline final def hasTypeWhich(f: Type => Boolean) = hasAssignedType && f(tpe) - - /** The canonical way to test if a Tree represents a term. + /** Provides an alternate if tree is empty + * @param alt The alternate tree + * @return If this tree is non empty, this tree, otherwise `alt`. */ - 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 - } + def orElse(alt: => Tree): Tree /** Apply `f` to each subtree */ - def foreach(f: Tree => Unit) { new ForeachTreeTraverser(f).traverse(this) } + def foreach(f: Tree => Unit): Unit - /** Find all subtrees matching predicate `p` */ - def withFilter(f: Tree => Boolean): List[Tree] = { - val ft = new FilterTreeTraverser(f) - ft.traverse(this) - ft.hits.toList - } - def filter(f: Tree => Boolean): List[Tree] = withFilter(f) + /** Find all subtrees matching predicate `p`. Same as `filter` */ + def withFilter(f: Tree => Boolean): List[Tree] - /** Apply `pf' to each subtree on which the function is defined */ - def collect[T](pf: PartialFunction[Tree, T]): List[T] = { - val ctt = new CollectTreeTraverser[T](pf) - ctt.traverse(this) - ctt.results.toList - } + /** Find all subtrees matching predicate `p`. Same as `withFilter` */ + def filter(f: Tree => Boolean): List[Tree] + + /** Apply `pf' to each subtree on which the function is defined and collect the results. + */ + def collect[T](pf: PartialFunction[Tree, T]): List[T] /** Returns optionally first tree (in a preorder traversal) which satisfies predicate `p`, * or None if none exists. */ - def find(p: Tree => Boolean): Option[Tree] = { - val ft = new FindTreeTraverser(p) - ft.traverse(this) - ft.result - } + def find(p: Tree => Boolean): Option[Tree] /** Is there exists a part of this tree which satisfies predicate `p`? */ - def exists(p: Tree => Boolean): Boolean = !find(p).isEmpty + def exists(p: Tree => Boolean): Boolean /** Do all parts of this tree satisfy predicate `p`? */ - def forAll(p: Tree => Boolean): Boolean = find(!p(_)).isEmpty - - def equalsStructure(that : Tree) = equalsStructure0(that)(_ eq _) - def equalsStructure0(that: Tree)(f: (Tree,Tree) => Boolean): Boolean = - f(this, that) || ((this.productArity == that.productArity) && { - def equals0(this0: Any, that0: Any): Boolean = (this0, that0) match { - case (x: Tree, y: Tree) => f(x, y) || (x equalsStructure0 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 equalsStructure0 y.original)(f) - case _ => - true - } - - (this.productIterator zip that.productIterator forall { case (x, y) => equals0(x, y) }) && compareOriginals() - }) + def forAll(p: Tree => Boolean): Boolean + + /** Tests whether two trees are structurall equal. + * Note that `==` on trees is reference equality. + */ + def equalsStructure(that : Tree): Boolean /** The direct child trees of this tree. * EmptyTrees are always omitted. Lists are flattened. */ - 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 - } + def children: List[Tree] + + /** Extracts free term symbols from a tree that is reified or contains reified subtrees. + */ + def freeTerms: List[FreeTermSymbol] + + /** Extracts free type symbols from a tree that is reified or contains reified subtrees. + */ + def freeTypes: List[FreeTypeSymbol] + + /** Substitute symbols in `to` for corresponding occurrences of references to + * symbols `from` in this type. + */ + def substituteSymbols(from: List[Symbol], to: List[Symbol]): Tree + + /** Substitute types in `to` for corresponding occurrences of references to + * symbols `from` in this tree. + */ + def substituteTypes(from: List[Symbol], to: List[Type]): Tree + + /** Substitute given tree `to` for occurrences of nodes that represent + * `C.this`, where `C` referes to the given class `clazz`. + */ + def substituteThis(clazz: Symbol, to: Tree): Tree /** Make a copy of this tree, keeping all attributes, * except that all positions are focused (so nothing * in this tree will be found when searching by position). */ - def duplicate: this.type = - duplicateTree(this).asInstanceOf[this.type] - - private[scala] def copyAttrs(tree: Tree): this.type = { - rawatt = tree.rawatt - tpe = tree.tpe - if (hasSymbol) symbol = tree.symbol - this - } + def duplicate: this.type + } + + override type TermTree >: Null <: Tree with TermTreeApi - override def toString: String = show(this) - override def hashCode(): Int = System.identityHashCode(this) - override def equals(that: Any) = this eq that.asInstanceOf[AnyRef] + /** The API that all term trees support */ + trait TermTreeApi extends TreeApi { this: TermTree => } - /** A tree for a term. Not all terms are TermTrees; use isTerm - * to reliably identify terms. - */ - trait TermTree extends Tree + override type TypTree >: Null <: Tree with TypTreeApi - /** A tree for a type. Not all types are TypTrees; use isType - * to reliably identify types. - */ - trait TypTree extends Tree + /** The API that all typ trees support */ + trait TypTreeApi extends TreeApi { this: TypTree => + } - /** A tree with a mutable symbol field, initialized to NoSymbol. - */ - trait SymTree extends Tree { - override def hasSymbol = true - override var symbol: Symbol = NoSymbol + override type SymTree >: Null <: Tree with SymTreeApi + + /** The API that all sym trees support */ + trait SymTreeApi extends TreeApi { this: SymTree => + def symbol: Symbol } - /** A tree with a name - effectively, a DefTree or RefTree. - */ - trait NameTree extends Tree { + override type NameTree >: Null <: Tree with NameTreeApi + + /** The API that all name trees support */ + trait NameTreeApi extends TreeApi { this: NameTree => def name: Name } - /** A tree which references a symbol-carrying entity. - * References one, as opposed to defining one; definitions - * are in DefTrees. - */ - trait RefTree extends SymTree with NameTree { + override type RefTree >: Null <: SymTree with NameTree with RefTreeApi + + /** The API that all ref trees support */ + trait RefTreeApi extends SymTreeApi with NameTreeApi { this: RefTree => def qualifier: Tree // empty for Idents def name: Name } - /** A tree which defines a symbol-carrying entity. - */ - abstract class DefTree extends SymTree with NameTree { + override type DefTree >: Null <: SymTree with NameTree with DefTreeApi + + /** The API that all def trees support */ + trait DefTreeApi extends SymTreeApi with NameTreeApi { this: DefTree => def name: Name - override def isDef = true } -// ----- tree node alternatives -------------------------------------- - - /** The empty tree */ - 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 - override def resetType(): this.type = this - } + override type MemberDef >: Null <: DefTree with MemberDefApi - /** Common base class for all member definitions: types, classes, - * objects, packages, vals and vars, defs. - */ - abstract class MemberDef extends DefTree { + /** The API that all member defs support */ + trait MemberDefApi extends DefTreeApi { this: MemberDef => def mods: Modifiers - def keyword: String = this match { - case TypeDef(_, _, _, _) => "type" - case ClassDef(mods, _, _, _) => if (mods hasModifier Modifier.`trait`) "trait" else "class" - case DefDef(_, _, _, _, _, _) => "def" - case ModuleDef(_, _, _) => "object" - case PackageDef(_, _) => "package" - case ValDef(mods, _, _, _) => if (mods hasModifier Modifier.mutable) "var" else "val" - case _ => "" - } } - /** A packaging, such as `package pid { stats }` - */ - case class PackageDef(pid: RefTree, stats: List[Tree]) - extends MemberDef { - def name = pid.name - def mods = Modifiers() + override type PackageDef >: Null <: MemberDef with PackageDefApi + + /** The API that all package defs support */ + trait PackageDefApi extends MemberDefApi { this: PackageDef => + val pid: RefTree + val stats: List[Tree] } - /** A common base class for class and object definitions. - */ - abstract class ImplDef extends MemberDef { - def impl: Template + override type ImplDef >: Null <: MemberDef with ImplDefApi + + /** The API that all impl defs support */ + trait ImplDefApi extends MemberDefApi { this: ImplDef => + val impl: Template } - /** A class definition. - */ - case class ClassDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], impl: Template) - extends ImplDef + override type ClassDef >: Null <: ImplDef with ClassDefApi - /** @param sym the class symbol - * @return the implementation template - */ - def ClassDef(sym: Symbol, impl: Template): ClassDef + /** The API that all class defs support */ + trait ClassDefApi extends ImplDefApi { this: ClassDef => + val mods: Modifiers + val name: TypeName + val tparams: List[TypeDef] + val impl: Template + } - /** An object definition, e.g. `object Foo`. Internally, objects are - * quite frequently called modules to reduce ambiguity. - */ - case class ModuleDef(mods: Modifiers, name: TermName, impl: Template) - extends ImplDef + override type ModuleDef >: Null <: ImplDef with ModuleDefApi - /** - * @param sym the class symbol - * @param impl the implementation template - */ - def ModuleDef(sym: Symbol, impl: Template): ModuleDef + /** The API that all module defs support */ + trait ModuleDefApi extends ImplDefApi { this: ModuleDef => + val mods: Modifiers + val name: TermName + val impl: Template + } - /** A common base class for ValDefs and DefDefs. - */ - abstract class ValOrDefDef extends MemberDef { + override type ValOrDefDef >: Null <: MemberDef with ValOrDefDefApi + + /** The API that all val defs and def defs support */ + trait ValOrDefDefApi extends MemberDefApi { this: ValOrDefDef => def name: Name // can't be a TermName because macros can be type names. def tpt: Tree def rhs: Tree } - /** Broadly speaking, a value definition. All these are encoded as ValDefs: - * - * - immutable values, e.g. "val x" - * - mutable values, e.g. "var x" - the MUTABLE flag set in mods - * - lazy values, e.g. "lazy val x" - the LAZY flag set in mods - * - method parameters, see vparamss in DefDef - the PARAM flag is set in mods - * - explicit self-types, e.g. class A { self: Bar => } - !!! not sure what is set. - */ - case class ValDef(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree) extends ValOrDefDef + override type ValDef >: Null <: ValOrDefDef with ValDefApi - def ValDef(sym: Symbol, rhs: Tree): ValDef + /** The API that all val defs support */ + trait ValDefApi extends ValOrDefDefApi { this: ValDef => + val mods: Modifiers + val name: TermName + val tpt: Tree + val rhs: Tree + } - def ValDef(sym: Symbol): ValDef + override type DefDef >: Null <: ValOrDefDef with DefDefApi - /** A method or macro definition. - * @param name The name of the method or macro. Can be a type name in case this is a type macro - */ - case class DefDef(mods: Modifiers, name: Name, tparams: List[TypeDef], - vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) extends ValOrDefDef + /** The API that all def defs support */ + trait DefDefApi extends ValOrDefDefApi { this: DefDef => + val mods: Modifiers + val name: Name + val tparams: List[TypeDef] + val vparamss: List[List[ValDef]] + val tpt: Tree + val rhs: Tree + } - def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef + override type TypeDef >: Null <: MemberDef with TypeDefApi - def DefDef(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree): DefDef + /** The API that all type defs support */ + trait TypeDefApi extends MemberDefApi { this: TypeDef => + val mods: Modifiers + val name: TypeName + val tparams: List[TypeDef] + val rhs: Tree + } - def DefDef(sym: Symbol, mods: Modifiers, rhs: Tree): DefDef + override type LabelDef >: Null <: DefTree with TermTree with LabelDefApi - def DefDef(sym: Symbol, rhs: Tree): DefDef + /** The API that all label defs support */ + trait LabelDefApi extends DefTreeApi with TermTreeApi { this: LabelDef => + val name: TermName + val params: List[Ident] + val rhs: Tree + } - def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef + override type ImportSelector >: Null <: ImportSelectorApi - /** An abstract type, a type parameter, or a type alias. - */ - case class TypeDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], rhs: Tree) - extends MemberDef - - /** A TypeDef node which defines given `sym` with given tight hand side `rhs`. */ - def TypeDef(sym: Symbol, rhs: Tree): TypeDef - - /** A TypeDef node which defines abstract type or type parameter for given `sym` */ - def TypeDef(sym: Symbol): TypeDef - - /** A labelled expression. Not expressible in language syntax, but - * generated by the compiler to simulate while/do-while loops, and - * also by the pattern matcher. - * - * The label acts much like a nested function, where `params` represents - * the incoming parameters. The symbol given to the LabelDef should have - * a MethodType, as if it were a nested function. - * - * Jumps are apply nodes attributed with a label's symbol. The - * arguments from the apply node will be passed to the label and - * assigned to the Idents. - * - * Forward jumps within a block are allowed. - */ - case class LabelDef(name: TermName, params: List[Ident], rhs: Tree) - extends DefTree with TermTree - - def LabelDef(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef - - /** Import selector - * - * Representation of an imported name its optional rename and their optional positions - * - * @param name the imported name - * @param namePos its position or -1 if undefined - * @param rename the name the import is renamed to (== name if no renaming) - * @param renamePos the position of the rename or -1 if undefined - */ - case class ImportSelector(name: Name, namePos: Int, rename: Name, renamePos: Int) - - /** Import clause - * - * @param expr - * @param selectors - */ - case class Import(expr: Tree, selectors: List[ImportSelector]) - extends SymTree - // The symbol of an Import is an import symbol @see Symbol.newImport - // It's used primarily as a marker to check that the import has been typechecked. - - /** Instantiation template of a class or trait - * - * @param parents - * @param body - */ - case class Template(parents: List[Tree], self: ValDef, body: List[Tree]) - extends SymTree { - // the symbol of a template is a local dummy. @see Symbol.newLocalDummy - // the owner of the local dummy is the enclosing trait or class. - // the local dummy is itself the owner of any local blocks - // For example: - // - // class C { - // def foo // owner is C - // { - // def bar // owner is local dummy - // } + /** The API that all import selectors support */ + trait ImportSelectorApi { this: ImportSelector => + val name: Name + val namePos: Int + val rename: Name + val renamePos: Int } - /** Block of expressions (semicolon separated expressions) */ - case class Block(stats: List[Tree], expr: Tree) - extends TermTree + override type Import >: Null <: SymTree with ImportApi - /** Block factory that flattens directly nested blocks. - */ - def Block(stats: Tree*): Block + /** The API that all imports support */ + trait ImportApi extends SymTreeApi { this: Import => + val expr: Tree + val selectors: List[ImportSelector] + } - /** Case clause in a pattern match, eliminated during explicitouter - * (except for occurrences in switch statements) - */ - case class CaseDef(pat: Tree, guard: Tree, body: Tree) - extends Tree + override type Template >: Null <: SymTree with TemplateApi - /** casedef shorthand */ - def CaseDef(pat: Tree, body: Tree): CaseDef + /** The API that all templates support */ + trait TemplateApi extends SymTreeApi { this: Template => + val parents: List[Tree] + val self: ValDef + val body: List[Tree] + } - /** Alternatives of patterns, eliminated by explicitouter, except for - * occurrences in encoded Switch stmt (=remaining Match(CaseDef(...)) - */ - case class Alternative(trees: List[Tree]) - extends TermTree + override type Block >: Null <: TermTree with BlockApi - /** Repetition of pattern, eliminated by explicitouter */ - case class Star(elem: Tree) - extends TermTree + /** The API that all blocks support */ + trait BlockApi extends TermTreeApi { this: Block => + val stats: List[Tree] + val expr: Tree + } - /** Bind of a variable to a rhs pattern, eliminated by explicitouter - * - * @param name - * @param body - */ - case class Bind(name: Name, body: Tree) - extends DefTree + override type CaseDef >: Null <: Tree with CaseDefApi - def Bind(sym: Symbol, body: Tree): Bind + /** The API that all case defs support */ + trait CaseDefApi extends TreeApi { this: CaseDef => + val pat: Tree + val guard: Tree + val body: Tree + } - case class UnApply(fun: Tree, args: List[Tree]) - extends TermTree + override type Alternative >: Null <: TermTree with AlternativeApi - /** Array of expressions, needs to be translated in backend, - */ - case class ArrayValue(elemtpt: Tree, elems: List[Tree]) - extends TermTree + /** The API that all alternatives support */ + trait AlternativeApi extends TermTreeApi { this: Alternative => + val trees: List[Tree] + } - /** Anonymous function, eliminated by analyzer */ - case class Function(vparams: List[ValDef], body: Tree) - extends TermTree with SymTree - // The symbol of a Function is a synthetic value of name nme.ANON_FUN_NAME - // It is the owner of the function's parameters. + override type Star >: Null <: TermTree with StarApi - /** Assignment */ - case class Assign(lhs: Tree, rhs: Tree) - extends TermTree + /** The API that all stars support */ + trait StarApi extends TermTreeApi { this: Star => + val elem: Tree + } - /** Either an assignment or a named argument. Only appears in argument lists, - * eliminated by typecheck (doTypedApply) - */ - case class AssignOrNamedArg(lhs: Tree, rhs: Tree) - extends TermTree - - /** Conditional expression */ - case class If(cond: Tree, thenp: Tree, elsep: Tree) - extends TermTree - - /** - Pattern matching expression (before explicitouter) - * - Switch statements (after explicitouter) - * - * After explicitouter, cases will satisfy the following constraints: - * - * - all guards are `EmptyTree`, - * - all patterns will be either `Literal(Constant(x:Int))` - * or `Alternative(lit|...|lit)` - * - except for an "otherwise" branch, which has pattern - * `Ident(nme.WILDCARD)` - */ - case class Match(selector: Tree, cases: List[CaseDef]) - extends TermTree + override type Bind >: Null <: DefTree with BindApi - /** Return expression */ - case class Return(expr: Tree) - extends TermTree with SymTree - // The symbol of a Return node is the enclosing method. + /** The API that all binds support */ + trait BindApi extends DefTreeApi { this: Bind => + val name: Name + val body: Tree + } - case class Try(block: Tree, catches: List[CaseDef], finalizer: Tree) - extends TermTree + override type UnApply >: Null <: TermTree with UnApplyApi - def Try(body: Tree, cases: (Tree, Tree)*): Try + /** The API that all unapplies support */ + trait UnApplyApi extends TermTreeApi { this: UnApply => + val fun: Tree + val args: List[Tree] + } - /** Throw expression */ - case class Throw(expr: Tree) - extends TermTree + override type ArrayValue >: Null <: TermTree with ArrayValueApi - def Throw(tpe: Type, args: Tree*): Throw + /** The API that all array values support */ + trait ArrayValueApi extends TermTreeApi { this: ArrayValue => + val elemtpt: Tree + val elems: List[Tree] + } - /** Object instantiation - * One should always use factory method below to build a user level new. - * - * @param tpt a class type - */ - case class New(tpt: Tree) extends TermTree + override type Function >: Null <: TermTree with SymTree with FunctionApi - /** 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 + /** The API that all functions support */ + trait FunctionApi extends TermTreeApi with SymTreeApi { this: Function => + val vparams: List[ValDef] + val body: Tree + } - /** 0-1 argument list new, based on a type. - */ - def New(tpe: Type, args: Tree*): Tree + override type Assign >: Null <: TermTree with AssignApi - def New(sym: Symbol, args: Tree*): Tree + /** The API that all assigns support */ + trait AssignApi extends TermTreeApi { this: Assign => + val lhs: Tree + val rhs: Tree + } - /** Type annotation, eliminated by explicit outer */ - case class Typed(expr: Tree, tpt: Tree) - extends TermTree + override type AssignOrNamedArg >: Null <: TermTree with AssignOrNamedArgApi - /** Common base class for Apply and TypeApply. This could in principle - * be a SymTree, but whether or not a Tree is a SymTree isn't used - * to settle any interesting questions, and it would add a useless - * field to all the instances (useless, since GenericApply forwards to - * the underlying fun.) - */ - abstract class GenericApply extends TermTree { - val fun: Tree - val args: List[Tree] + /** The API that all assigns support */ + trait AssignOrNamedArgApi extends TermTreeApi { this: AssignOrNamedArg => + val lhs: Tree + val rhs: Tree } - /** Explicit type application. - * @PP: All signs point toward it being a requirement that args.nonEmpty, - * but I can't find that explicitly stated anywhere. Unless your last name - * is odersky, you should probably treat it as true. - */ - case class TypeApply(fun: Tree, args: List[Tree]) - extends GenericApply { + override type If >: Null <: TermTree with IfApi - // Testing the above theory re: args.nonEmpty. - require(args.nonEmpty, this) - override def symbol: Symbol = fun.symbol - override def symbol_=(sym: Symbol) { fun.symbol = sym } + /** The API that all ifs support */ + trait IfApi extends TermTreeApi { this: If => + val cond: Tree + val thenp: Tree + val elsep: Tree } - /** Value application */ - case class Apply(fun: Tree, args: List[Tree]) - extends GenericApply { - override def symbol: Symbol = fun.symbol - override def symbol_=(sym: Symbol) { fun.symbol = sym } + override type Match >: Null <: TermTree with MatchApi + + /** The API that all matches support */ + trait MatchApi extends TermTreeApi { this: Match => + val selector: Tree + val cases: List[CaseDef] } - def Apply(sym: Symbol, args: Tree*): Tree + override type Return >: Null <: TermTree with SymTree with ReturnApi - // 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) + /** The API that all returns support */ + trait ReturnApi extends TermTreeApi { this: Return => + val expr: Tree + } - // 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) + override type Try >: Null <: TermTree with TryApi - // TODO: use a factory method, not a class (???) - // as a case in point of the comment that should go here by similarity to ApplyToImplicitArgs, - // this tree is considered in importers, but not in treecopier - class ApplyConstructor(tpt: Tree, args: List[Tree]) extends Apply(Select(New(tpt), nme.CONSTRUCTOR), args) { - override def printingPrefix = "ApplyConstructor" + /** The API that all tries support */ + trait TryApi extends TermTreeApi { this: Try => + val block: Tree + val catches: List[CaseDef] + val finalizer: Tree } - /** Dynamic value application. - * In a dynamic application q.f(as) - * - q is stored in qual - * - as is stored in args - * - f is stored as the node's symbol field. - */ - case class ApplyDynamic(qual: Tree, args: List[Tree]) - extends TermTree with SymTree - // The symbol of an ApplyDynamic is the function symbol of `qual`, or NoSymbol, if there is none. + override type Throw >: Null <: TermTree with ThrowApi - /** Super reference, qual = corresponding this reference - * A super reference C.super[M] is represented as Super(This(C), M). - */ - case class Super(qual: Tree, mix: TypeName) extends TermTree { - // The symbol of a Super is the class _from_ which the super reference is made. - // For instance in C.super(...), it would be C. - override def symbol: Symbol = qual.symbol - override def symbol_=(sym: Symbol) { qual.symbol = sym } + /** The API that all tries support */ + trait ThrowApi extends TermTreeApi { this: Throw => + val expr: Tree } - def Super(sym: Symbol, mix: TypeName): Tree - - /** Self reference */ - case class This(qual: TypeName) - extends TermTree with SymTree - // The symbol of a This is the class to which the this refers. - // For instance in C.this, it would be C. + override type New >: Null <: TermTree with NewApi - def This(sym: Symbol): Tree + /** The API that all news support */ + trait NewApi extends TermTreeApi { this: New => + val tpt: Tree + } - /** Designator <qualifier> . <name> */ - case class Select(qualifier: Tree, name: Name) - extends RefTree + override type Typed >: Null <: TermTree with TypedApi - def Select(qualifier: Tree, name: String): Select + /** The API that all typeds support */ + trait TypedApi extends TermTreeApi { this: Typed => + val expr: Tree + val tpt: Tree + } - def Select(qualifier: Tree, sym: Symbol): Select + override type GenericApply >: Null <: TermTree with GenericApplyApi - /** Identifier <name> */ - case class Ident(name: Name) extends RefTree { - def qualifier: Tree = EmptyTree - def isBackquoted = this hasAttachment BackquotedIdentifier + /** The API that all applies support */ + trait GenericApplyApi extends TermTreeApi { this: GenericApply => + val fun: Tree + val args: List[Tree] } - def Ident(name: String): Ident + override type TypeApply >: Null <: GenericApply with TypeApplyApi - def Ident(sym: Symbol): Ident - - /** Marks underlying reference to id as boxed. - * @pre id must refer to a captured variable - * A reference such marked will refer to the boxed entity, no dereferencing - * with `.elem` is done on it. - * This tree node can be emitted by macros such as reify that call referenceCapturedVariable. - * It is eliminated in LambdaLift, where the boxing conversion takes place. - */ - case class ReferenceToBoxed(ident: Ident) extends TermTree { - override def symbol: Symbol = ident.symbol - override def symbol_=(sym: Symbol) { ident.symbol = sym } + /** The API that all type applies support */ + trait TypeApplyApi extends GenericApplyApi { this: TypeApply => } - /** Literal */ - case class Literal(value: Constant) - extends TermTree { - assert(value ne null) + override type Apply >: Null <: GenericApply with ApplyApi + + /** The API that all applies support */ + trait ApplyApi extends GenericApplyApi { this: Apply => } -// @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)) + override type ApplyDynamic >: Null <: TermTree with SymTree with ApplyDynamicApi - /** A tree that has an annotation attached to it. Only used for annotated types and - * annotation ascriptions, annotations on definitions are stored in the Modifiers. - * Eliminated by typechecker (typedAnnotated), the annotations are then stored in - * an AnnotatedType. - */ - case class Annotated(annot: Tree, arg: Tree) extends Tree + /** The API that all apply dynamics support */ + trait ApplyDynamicApi extends TermTreeApi with SymTreeApi { this: ApplyDynamic => + val qual: Tree + val args: List[Tree] + } - /** Singleton type, eliminated by RefCheck */ - case class SingletonTypeTree(ref: Tree) - extends TypTree + override type Super >: Null <: TermTree with SuperApi - /** Type selection <qualifier> # <name>, eliminated by RefCheck */ - case class SelectFromTypeTree(qualifier: Tree, name: TypeName) - extends TypTree with RefTree + /** The API that all supers support */ + trait SuperApi extends TermTreeApi { this: Super => + val qual: Tree + val mix: TypeName + } - /** Intersection type <parent1> with ... with <parentN> { <decls> }, eliminated by RefCheck */ - case class CompoundTypeTree(templ: Template) - extends TypTree + override type This >: Null <: TermTree with SymTree with ThisApi - /** Applied type <tpt> [ <args> ], eliminated by RefCheck */ - case class AppliedTypeTree(tpt: Tree, args: List[Tree]) - extends TypTree { - override def symbol: Symbol = tpt.symbol - override def symbol_=(sym: Symbol) { tpt.symbol = sym } + /** The API that all thises support */ + trait ThisApi extends TermTreeApi with SymTreeApi { this: This => + val qual: TypeName } - case class TypeBoundsTree(lo: Tree, hi: Tree) - extends TypTree - - case class ExistentialTypeTree(tpt: Tree, whereClauses: List[Tree]) - extends TypTree - - /** A synthetic tree holding an arbitrary type. Not to be confused with - * with TypTree, the trait for trees that are only used for type trees. - * TypeTree's are inserted in several places, but most notably in - * `RefCheck`, where the arbitrary type trees are all replaced by - * TypeTree's. */ - case class TypeTree() extends TypTree { - 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) - this setPos tree.pos - } + override type Select >: Null <: RefTree with SelectApi - override def defineType(tp: Type): this.type = { - wasEmpty = isEmpty - setType(tp) - } + /** The API that all selects support */ + trait SelectApi extends RefTreeApi { this: Select => + val qualifier: Tree + val name: Name } - def TypeTree(tp: Type): TypeTree = TypeTree() setType tp + override type Ident >: Null <: RefTree with IdentApi - /** An empty deferred value definition corresponding to: - * val _: _ - * This is used as a placeholder in the `self` parameter Template if there is - * no definition of a self value of self type. - */ - def emptyValDef: ValDef - - // ------ traversers, copiers, and transformers --------------------------------------------- - - val treeCopy = newLazyTreeCopier - - 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) + /** The API that all idents support */ + trait IdentApi extends RefTreeApi { this: Ident => + val name: Name } - 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) + + override type ReferenceToBoxed >: Null <: TermTree with ReferenceToBoxedApi + + /** The API that all references support */ + trait ReferenceToBoxedApi extends TermTreeApi { this: ReferenceToBoxed => + val ident: Tree } - 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) + override type Literal >: Null <: TermTree with LiteralApi + + /** The API that all literals support */ + trait LiteralApi extends TermTreeApi { this: Literal => + val value: Constant } - 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) + + override type Annotated >: Null <: Tree with AnnotatedApi + + /** The API that all annotateds support */ + trait AnnotatedApi extends TreeApi { this: Annotated => + val annot: Tree + val arg: Tree } - 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) + + override type SingletonTypeTree >: Null <: TypTree with SingletonTypeTreeApi + + /** The API that all singleton type trees support */ + trait SingletonTypeTreeApi extends TypTreeApi { this: SingletonTypeTree => + val ref: Tree } - 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) + + override type SelectFromTypeTree >: Null <: TypTree with RefTree with SelectFromTypeTreeApi + + /** The API that all selects from type trees support */ + trait SelectFromTypeTreeApi extends TypTreeApi with RefTreeApi { this: SelectFromTypeTree => + val qualifier: Tree + val name: TypeName } - 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) + + override type CompoundTypeTree >: Null <: TypTree with CompoundTypeTreeApi + + /** The API that all compound type trees support */ + trait CompoundTypeTreeApi extends TypTreeApi { this: CompoundTypeTree => + val templ: Template } - 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) + + override type AppliedTypeTree >: Null <: TypTree with AppliedTypeTreeApi + + /** The API that all applied type trees support */ + trait AppliedTypeTreeApi extends TypTreeApi { this: AppliedTypeTree => + val tpt: Tree + val args: List[Tree] } - 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) + + override type TypeBoundsTree >: Null <: TypTree with TypeBoundsTreeApi + + /** The API that all type bound trees support */ + trait TypeBoundsTreeApi extends TypTreeApi { this: TypeBoundsTree => + val lo: Tree + val hi: Tree } - class Traverser { - protected var currentOwner: Symbol = definitions.RootClass - - def traverse(tree: Tree): Unit = tree match { - case EmptyTree => - ; - case PackageDef(pid, stats) => - traverse(pid) - atOwner(tree.symbol.moduleClass) { - traverseTrees(stats) - } - case ClassDef(mods, name, tparams, impl) => - atOwner(tree.symbol) { - traverseTrees(mods.annotations); traverseTrees(tparams); traverse(impl) - } - case ModuleDef(mods, name, impl) => - atOwner(tree.symbol.moduleClass) { - 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(this, tree) - } + override type ExistentialTypeTree >: Null <: TypTree with ExistentialTypeTreeApi - def traverseTrees(trees: List[Tree]) { - trees foreach traverse - } - def traverseTreess(treess: List[List[Tree]]) { - treess foreach traverseTrees - } - def traverseStats(stats: List[Tree], exprOwner: Symbol) { - stats foreach (stat => - if (exprOwner != currentOwner) atOwner(exprOwner)(traverse(stat)) - else traverse(stat) - ) - } + /** The API that all existential type trees support */ + trait ExistentialTypeTreeApi extends TypTreeApi { this: ExistentialTypeTree => + val tpt: Tree + val whereClauses: List[Tree] + } - def atOwner(owner: Symbol)(traverse: => Unit) { - val prevOwner = currentOwner - currentOwner = owner - traverse - currentOwner = prevOwner - } + override type TypeTree >: Null <: TypTree with TypeTreeApi - /** Leave apply available in the generic traverser to do something else. - */ - def apply[T <: Tree](tree: T): T = { traverse(tree); tree } + /** The API that all type trees support */ + trait TypeTreeApi extends TypTreeApi { this: TypeTree => + def original: Tree } - protected def xtraverse(traverser: Traverser, tree: Tree): Unit = throw new MatchError(tree) + /** An empty deferred value definition corresponding to: + * val _: _ + * This is used as a placeholder in the `self` parameter Template if there is + * no definition of a self value of self type. + */ + val emptyValDef: ValDef + +// ---------------------- copying ------------------------------------------------ - // to be implemented in subclasses: + /** The standard (lazy) tree copier + */ type TreeCopier <: TreeCopierOps + val treeCopy: TreeCopier = newLazyTreeCopier + def newStrictTreeCopier: TreeCopier def newLazyTreeCopier: TreeCopier - trait TreeCopierOps { + /** The API of a tree copier + * tree copiers are made available by an implicit conversion in reflect.ops + */ + abstract class TreeCopierOps { def ClassDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], impl: Template): ClassDef def PackageDef(tree: Tree, pid: RefTree, stats: List[Tree]): PackageDef def ModuleDef(tree: Tree, mods: Modifiers, name: Name, impl: Template): ModuleDef @@ -1107,443 +601,49 @@ trait Trees { self: Universe => def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]): ExistentialTypeTree } - 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) = { - val t = new Ident(name) copyAttrs tree - if (tree hasAttachment BackquotedIdentifier) t withAttachment BackquotedIdentifier - else t - } - 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) - } +// ---------------------- traversing and transforming ------------------------------ - 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) + class Traverser { + protected[scala] var currentOwner: Symbol = rootMirror.RootClass + + def traverse(tree: Tree): Unit = itraverse(this, tree) + + def traverseTrees(trees: List[Tree]) { + trees foreach traverse } - 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 traverseTreess(treess: List[List[Tree]]) { + treess foreach traverseTrees } - 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 traverseStats(stats: List[Tree], exprOwner: Symbol) { + stats foreach (stat => + if (exprOwner != currentOwner) atOwner(exprOwner)(traverse(stat)) + else traverse(stat) + ) } - 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) + + def atOwner(owner: Symbol)(traverse: => Unit) { + val prevOwner = currentOwner + currentOwner = owner + traverse + currentOwner = prevOwner } + + /** Leave apply available in the generic traverser to do something else. + */ + def apply[T <: Tree](tree: T): T = { traverse(tree); tree } } + protected def itraverse(traverser: Traverser, tree: Tree): Unit = throw new MatchError(tree) + + protected def xtraverse(traverser: Traverser, tree: Tree): Unit = throw new MatchError(tree) + abstract class Transformer { val treeCopy: TreeCopier = newLazyTreeCopier - protected var currentOwner: Symbol = definitions.RootClass + protected[scala] var currentOwner: Symbol = rootMirror.RootClass protected def currentMethod = currentOwner.enclosingMethod protected def currentClass = currentOwner.enclosingClass - protected def currentPackage = currentOwner.enclosingTopLevelClass.owner - def transform(tree: Tree): Tree = tree match { - case EmptyTree => - tree - case PackageDef(pid, stats) => - treeCopy.PackageDef( - tree, transform(pid).asInstanceOf[RefTree], - atOwner(tree.symbol.moduleClass) { - 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(tree.symbol.moduleClass) { - 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(this, tree) - } +// protected def currentPackage = currentOwner.enclosingTopLevelClass.owner + def transform(tree: Tree): Tree = itransform(this, tree) def transformTrees(trees: List[Tree]): List[Tree] = trees mapConserve (transform(_)) @@ -1577,154 +677,13 @@ trait Trees { self: Universe => } } - protected def xtransform(transformer: Transformer, tree: Tree): Tree = throw new MatchError(tree) - - class ForeachTreeTraverser(f: Tree => Unit) extends Traverser { - override def traverse(t: Tree) { - f(t) - super.traverse(t) - } - } + protected def itransform(transformer: Transformer, tree: Tree): Tree = throw new MatchError(tree) - 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) - } - } + protected def xtransform(transformer: Transformer, tree: Tree): Tree = throw new MatchError(tree) - 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) - } - } + type Modifiers >: Null <: ModifiersApi - 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) - } - } - } + abstract class ModifiersApi extends ModifiersBase with HasFlagsApi - protected def duplicateTree(tree: Tree): Tree - -/* A standard pattern match - case EmptyTree => - case PackageDef(pid, stats) => - // package pid { stats } - case ClassDef(mods, name, tparams, impl) => - // mods class name [tparams] impl where impl = extends parents { defs } - case ModuleDef(mods, name, impl) => (eliminated by refcheck) - // mods object name impl where impl = extends parents { defs } - case ValDef(mods, name, tpt, rhs) => - // mods val name: tpt = rhs - // note missing type information is expressed by tpt = TypeTree() - case DefDef(mods, name, tparams, vparamss, tpt, rhs) => - // mods def name[tparams](vparams_1)...(vparams_n): tpt = rhs - // note missing type information is expressed by tpt = TypeTree() - case TypeDef(mods, name, tparams, rhs) => (eliminated by erasure) - // mods type name[tparams] = rhs - // mods type name[tparams] >: lo <: hi, where lo, hi are in a TypeBoundsTree, - and DEFERRED is set in mods - case LabelDef(name, params, rhs) => - // used for tailcalls and like - // while/do are desugared to label defs as follows: - // while (cond) body ==> LabelDef($L, List(), if (cond) { body; L$() } else ()) - // do body while (cond) ==> LabelDef($L, List(), body; if (cond) L$() else ()) - case Import(expr, selectors) => (eliminated by typecheck) - // import expr.{selectors} - // Selectors are a list of pairs of names (from, to). - // The last (and maybe only name) may be a nme.WILDCARD - // for instance - // import qual.{x, y => z, _} would be represented as - // Import(qual, List(("x", "x"), ("y", "z"), (WILDCARD, null))) - case Template(parents, self, body) => - // extends parents { self => body } - // if self is missing it is represented as emptyValDef - case Block(stats, expr) => - // { stats; expr } - case CaseDef(pat, guard, body) => (eliminated by transmatch/explicitouter) - // case pat if guard => body - case Alternative(trees) => (eliminated by transmatch/explicitouter) - // pat1 | ... | patn - case Star(elem) => (eliminated by transmatch/explicitouter) - // pat* - case Bind(name, body) => (eliminated by transmatch/explicitouter) - // name @ pat - case UnApply(fun: Tree, args) (introduced by typer, eliminated by transmatch/explicitouter) - // used for unapply's - case ArrayValue(elemtpt, trees) => (introduced by uncurry) - // used to pass arguments to vararg arguments - // for instance, printf("%s%d", foo, 42) is translated to after uncurry to: - // Apply( - // Ident("printf"), - // Literal("%s%d"), - // ArrayValue(<Any>, List(Ident("foo"), Literal(42)))) - case Function(vparams, body) => (eliminated by lambdaLift) - // vparams => body where vparams:List[ValDef] - case Assign(lhs, rhs) => - // lhs = rhs - case AssignOrNamedArg(lhs, rhs) => (eliminated by typer, resurrected by reifier) - // @annotation(lhs = rhs) - case If(cond, thenp, elsep) => - // if (cond) thenp else elsep - case Match(selector, cases) => - // selector match { cases } - case Return(expr) => - // return expr - case Try(block, catches, finalizer) => - // try block catch { catches } finally finalizer where catches: List[CaseDef] - case Throw(expr) => - // throw expr - case New(tpt) => - // new tpt always in the context: (new tpt).<init>[targs](args) - case Typed(expr, tpt) => (eliminated by erasure) - // expr: tpt - case TypeApply(fun, args) => - // fun[args] - case Apply(fun, args) => - // fun(args) - // for instance fun[targs](args) is expressed as Apply(TypeApply(fun, targs), args) - case ApplyDynamic(qual, args) (introduced by erasure, eliminated by cleanup) - // fun(args) - case Super(qual, mix) => - // qual.super[mix] qual is always This(something), if mix is empty, it is tpnme.EMPTY - case This(qual) => - // qual.this - case Select(qualifier, selector) => - // qualifier.selector - case Ident(name) => - // name - // note: type checker converts idents that refer to enclosing fields or methods - // to selects; name ==> this.name - case ReferenceToBoxed(ident) => (created by typer, eliminated by lambdalift) - // synthetic node emitted by macros to reference capture vars directly without going through ``elem'' - // var x = ...; fun { x } will emit Ident(x), which gets transformed to Select(Ident(x), "elem") - // if ReferenceToBoxed were used instead of Ident, no transformation would be performed - case Literal(value) => - // value - case TypeTree() => (introduced by refcheck) - // a type that's not written out, but given in the tpe attribute - case Annotated(annot, arg) => (eliminated by typer) - // arg @annot for types, arg: @annot for exprs - case SingletonTypeTree(ref) => (eliminated by uncurry) - // ref.type - case SelectFromTypeTree(qualifier, selector) => (eliminated by uncurry) - // qualifier # selector, a path-dependent type p.T is expressed as p.type # T - case CompoundTypeTree(templ: Template) => (eliminated by uncurry) - // parent1 with ... with parentN { refinement } - case AppliedTypeTree(tpt, args) => (eliminated by uncurry) - // tpt[args] - case TypeBoundsTree(lo, hi) => (eliminated by uncurry) - // >: lo <: hi - case ExistentialTypeTree(tpt, whereClauses) => (eliminated by uncurry) - // tpt forSome { whereClauses } -*/ } diff --git a/src/library/scala/reflect/api/Types.scala b/src/library/scala/reflect/api/Types.scala index 3d42242641..b62a92cbd7 100755 --- a/src/library/scala/reflect/api/Types.scala +++ b/src/library/scala/reflect/api/Types.scala @@ -1,15 +1,13 @@ package scala.reflect package api -trait Types { self: Universe => +trait Types extends base.Types { self: Universe => - /** This class declares operations that are visible in a Type. + override type Type >: Null <: TypeApi + + /** The extended API of types */ - abstract class AbsType { - /** The type symbol associated with the type, or `NoSymbol` for types - * that do not refer to a type symbol. - */ - def typeSymbol: Symbol + abstract class TypeApi extends TypeBase { /** The defined or declared members with name `name` in this type; * an OverloadedSymbol if several exist, NoSymbol if none exist. @@ -18,6 +16,7 @@ trait Types { self: Universe => def declaration(name: Name): Symbol /** The collection of declarations in this type + * [Eugene++] why not List? */ def declarations: Iterable[Symbol] @@ -34,6 +33,7 @@ trait Types { self: Universe => /** An iterable containing all members of this type (directly declared or inherited) * Members appear in the linearization order of their owners. * Members with the same owner appear in reverse order of their declarations. + * [Eugene++] the order needs to be reversed back, at least in the public API */ def members: Iterable[Symbol] @@ -43,6 +43,11 @@ trait Types { self: Universe => */ def nonPrivateMembers: Iterable[Symbol] + /** Substitute symbols in `to` for corresponding occurrences of references to + * symbols `from` in this type. + */ + def substituteSymbols(from: List[Symbol], to: List[Symbol]): Type + /** Substitute types in `to` for corresponding occurrences of references to * symbols `from` in this type. */ @@ -166,304 +171,133 @@ trait Types { self: Universe => */ def widen: Type - /** The kind of this type; used for debugging */ + /** The string discriminator of this type; useful for debugging */ def kind: String } - /** An object representing an unknown type, used during type inference. - * If you see WildcardType outside of inference it is almost certainly a bug. - */ - val WildcardType: Type - - /** 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. - */ - type BoundedWildcardType >: Null <: Type - - val BoundedWildcardType: BoundedWildcardTypeExtractor + /** .. */ + override type ThisType >: Null <: SingletonType with ThisTypeApi - abstract class BoundedWildcardTypeExtractor { - def apply(bounds: TypeBounds): BoundedWildcardType - def unapply(tpe: BoundedWildcardType): Option[TypeBounds] + /** The API that all this types support */ + trait ThisTypeApi extends TypeApi { this: ThisType => + val sym: Symbol } - /** The type of Scala types, and also Scala type signatures. - * (No difference is internally made between the two). - */ - type Type >: Null <: AbsType - - /** The type of Scala singleton types, i.e. types that are inhabited - * by only one nun-null value. These include types of the forms - * {{{ - * C.this.type - * C.super.type - * x.type - * }}} - * as well as constant types. - */ - type SingletonType >: Null <: Type + /** .. */ + override type SingleType >: Null <: SingletonType with SingleTypeApi - /** This constant is used as a special value that indicates that no meaningful type exists. - */ - val NoType: Type - - /** This constant is used as a special value denoting the empty prefix in a path dependent type. - * For instance `x.type` is represented as `SingleType(NoPrefix, <x>)`, where `<x>` stands for - * the symbol for `x`. - */ - val NoPrefix: Type - - /** The `ThisType` type describes types of the form on the left with the - * correspnding ThisType representations to the right. - * {{{ - * C.this.type ThisType(C) - * }}} - */ - type ThisType <: SingletonType - - /** The constructor/deconstructor for `ThisType` instances. */ - val ThisType: ThisTypeExtractor - - /** An extractor class to create and pattern match with syntax `ThisType(sym)` - * where `sym` is the class prefix of the this type. - */ - abstract class ThisTypeExtractor { - def apply(sym: Symbol): Type - def unapply(tpe: ThisType): Option[Symbol] + /** The API that all single types support */ + trait SingleTypeApi extends TypeApi { this: SingleType => + val pre: Type + val sym: Symbol } - /** The `TypeRef` type describes types of any of the forms on the left, - * with their TypeRef representations to the right. - * {{{ - * T # C[T_1, ..., T_n] TypeRef(T, C, List(T_1, ..., T_n)) - * p.C[T_1, ..., T_n] TypeRef(p.type, C, List(T_1, ..., T_n)) - * C[T_1, ..., T_n] TypeRef(NoPrefix, C, List(T_1, ..., T_n)) - * T # C TypeRef(T, C, Nil) - * p.C TypeRef(p.type, C, Nil) - * C TypeRef(NoPrefix, C, Nil) - * }}} - */ - type TypeRef <: Type + /** .. */ + override type SuperType >: Null <: SingletonType with SuperTypeApi - /** The constructor/deconstructor for `TypeRef` instances. */ - val TypeRef: TypeRefExtractor - - /** An extractor class to create and pattern match with syntax `TypeRef(pre, sym, args)` - * Here, `pre` is the prefix of the type reference, `sym` is the symbol - * referred to by the type reference, and `args` is a possible empty list of - * type argumenrts. - */ - abstract class TypeRefExtractor { - def apply(pre: Type, sym: Symbol, args: List[Type]): Type - def unapply(tpe: TypeRef): Option[(Type, Symbol, List[Type])] + /** The API that all super types support */ + trait SuperTypeApi extends TypeApi { this: SuperType => + val thistpe: Type + val supertpe: Type } - /** The `SingleType` type describes types of any of the forms on the left, - * with their TypeRef representations to the right. - * {{{ - * (T # x).type SingleType(T, x) - * p.x.type SingleType(p.type, x) - * x.type SingleType(NoPrefix, x) - * }}} - */ - type SingleType <: SingletonType + /** .. */ + override type ConstantType >: Null <: SingletonType with ConstantTypeApi - /** The constructor/deconstructor for `SingleType` instances. */ - val SingleType: SingleTypeExtractor - - /** An extractor class to create and pattern match with syntax `SingleType(pre, sym)` - * Here, `pre` is the prefix of the single-type, and `sym` is the stable value symbol - * referred to by the single-type. - */ - abstract class SingleTypeExtractor { - def apply(pre: Type, sym: Symbol): Type - def unapply(tpe: SingleType): Option[(Type, Symbol)] + /** The API that all constant types support */ + trait ConstantTypeApi extends TypeApi { this: ConstantType => + val value: Constant } - /** The `SuperType` type is not directly written, but arises when `C.super` is used - * as a prefix in a `TypeRef` or `SingleType`. It's internal presentation is - * {{{ - * SuperType(thistpe, supertpe) - * }}} - * Here, `thistpe` is the type of the corresponding this-type. For instance, - * in the type arising from C.super, the `thistpe` part would be `ThisType(C)`. - * `supertpe` is the type of the super class referred to by the `super`. - */ - type SuperType <: SingletonType - - /** The constructor/deconstructor for `SuperType` instances. */ - val SuperType: SuperTypeExtractor + /** .. */ + override type TypeRef >: Null <: Type with TypeRefApi - /** An extractor class to create and pattern match with syntax `SingleType(thistpe, supertpe)` - */ - abstract class SuperTypeExtractor { - def apply(thistpe: Type, supertpe: Type): Type - def unapply(tpe: SuperType): Option[(Type, Type)] + /** The API that all type refs support */ + trait TypeRefApi extends TypeApi { this: TypeRef => + val pre: Type + val sym: Symbol + val args: List[Type] } - /** The `ConstantType` type is not directly written in user programs, but arises as the type of a constant. - * The REPL expresses constant types like Int(11). Here are some constants with their types. - * {{{ - * 1 ConstantType(Constant(1)) - * "abc" ConstantType(Constant("abc")) - * }}} - */ - type ConstantType <: SingletonType - - /** The constructor/deconstructor for `ConstantType` instances. */ - val ConstantType: ConstantTypeExtractor + /** .. */ + override type RefinedType >: Null <: CompoundType with RefinedTypeApi - /** An extractor class to create and pattern match with syntax `ConstantType(constant)` - * Here, `constant` is the constant value represented by the type. - */ - abstract class ConstantTypeExtractor { - def apply(value: Constant): ConstantType - def unapply(tpe: ConstantType): Option[Constant] + /** The API that all refined types support */ + trait RefinedTypeApi extends TypeApi { this: RefinedType => + val parents: List[Type] + val decls: Scope } - /** A subtype of Type representing refined types as well as `ClassInfo` signatures. - */ - type CompoundType <: Type + /** .. */ + override type ClassInfoType >: Null <: CompoundType with ClassInfoTypeApi - /** The `RefinedType` type defines types of any of the forms on the left, - * with their RefinedType representations to the right. - * {{{ - * P_1 with ... with P_m { D_1; ...; D_n} RefinedType(List(P_1, ..., P_m), Scope(D_1, ..., D_n)) - * P_1 with ... with P_m RefinedType(List(P_1, ..., P_m), Scope()) - * { D_1; ...; D_n} RefinedType(List(AnyRef), Scope(D_1, ..., D_n)) - * }}} - */ - type RefinedType <: CompoundType - - /** The constructor/deconstructor for `RefinedType` instances. */ - val RefinedType: RefinedTypeExtractor - - /** An extractor class to create and pattern match with syntax `RefinedType(parents, decls)` - * Here, `parents` is the list of parent types of the class, and `decls` is the scope - * containing all declarations in the class. - */ - abstract class RefinedTypeExtractor { - def apply(parents: List[Type], decls: Scope): RefinedType - - /** An alternative constructor that passes in the synthetic classs symbol - * that backs the refined type. (Normally, a fresh class symbol is created automatically). - */ - def apply(parents: List[Type], decls: Scope, clazz: Symbol): RefinedType - def unapply(tpe: RefinedType): Option[(List[Type], Scope)] + /** The API that all class info types support */ + trait ClassInfoTypeApi extends TypeApi { this: ClassInfoType => + val parents: List[Type] + val decls: Scope + val typeSymbol: Symbol } - type NullaryMethodType <: Type - val NullaryMethodType: NullaryMethodTypeExtractor + /** .. */ + override type MethodType >: Null <: Type with MethodTypeApi - type PolyType <: Type - val PolyType: PolyTypeExtractor - - type ExistentialType <: Type - val ExistentialType: ExistentialTypeExtractor + /** The API that all method types support */ + trait MethodTypeApi extends TypeApi { this: MethodType => + val params: List[Symbol] + val resultType: Type + } - type AnnotatedType <: Type - val AnnotatedType: AnnotatedTypeExtractor + /** .. */ + override type NullaryMethodType >: Null <: Type with NullaryMethodTypeApi - /** The `MethodType` type signature is used to indicate parameters and result type of a method - */ - type MethodType <: Type + /** The API that all nullary method types support */ + trait NullaryMethodTypeApi extends TypeApi { this: NullaryMethodType => + val resultType: Type + } - /** The constructor/deconstructor for `MethodType` instances. */ - val MethodType: MethodTypeExtractor + /** .. */ + override type PolyType >: Null <: Type with PolyTypeApi - /** An extractor class to create and pattern match with syntax `MethodType(params, respte)` - * Here, `params` is a potentially empty list of parameter symbols of the method, - * and `restpe` is the result type of the method. If the method is curried, `restpe` would - * be another `MethodType`. - * Note: `MethodType(Nil, Int)` would be the type of a method defined with an empty parameter list. - * {{{ - * def f(): Int - * }}} - * If the method is completely parameterless, as in - * {{{ - * def f: Int - * }}} - * its type is a `NullaryMethodType`. - */ - abstract class MethodTypeExtractor { - def apply(params: List[Symbol], resultType: Type): MethodType - def unapply(tpe: MethodType): Option[(List[Symbol], Type)] + /** The API that all polymorphic types support */ + trait PolyTypeApi extends TypeApi { this: PolyType => + val typeParams: List[Symbol] + val resultType: Type } - /** The `TypeBounds` type signature is used to indicate lower and upper type bounds - * of type parameters and abstract types. It is not a first-class type. - * If an abstract type or type parameter is declared with any of the forms - * on the left, its type signature is the TypeBounds type on the right. - * {{{ - * T >: L <: U TypeBounds(L, U) - * T >: L TypeBounds(L, Any) - * T <: U TypeBounds(Nothing, U) - * }}} - */ - type TypeBounds <: Type + /** .. */ + override type ExistentialType >: Null <: Type with ExistentialTypeApi - /** The constructor/deconstructor for `TypeBounds` instances. */ - val TypeBounds: TypeBoundsExtractor - - /** An extractor class to create and pattern match with syntax `TypeBound(lower, upper)` - * Here, `lower` is the lower bound of the `TypeBounds` pair, and `upper` is - * the upper bound. - */ - abstract class TypeBoundsExtractor { - def apply(lo: Type, hi: Type): TypeBounds - def unapply(tpe: TypeBounds): Option[(Type, Type)] + /** The API that all existential types support */ + trait ExistentialTypeApi extends TypeApi { this: ExistentialType => + val quantified: List[Symbol] + val underlying: Type } - /** The `ClassInfo` type signature is used to define parents and declarations - * of classes, traits, and objects. If a class, trait, or object C is declared like this - * {{{ - * C extends P_1 with ... with P_m { D_1; ...; D_n} - * }}} - * its `ClassInfo` type has the following form: - * {{{ - * ClassInfo(List(P_1, ..., P_m), Scope(D_1, ..., D_n), C) - * }}} - */ - type ClassInfoType <: CompoundType + /** .. */ + override type AnnotatedType >: Null <: Type with AnnotatedTypeApi - /** The constructor/deconstructor for `ClassInfoType` instances. */ - val ClassInfoType: ClassInfoTypeExtractor - - /** An extractor class to create and pattern match with syntax `ClassInfo(parents, decls, clazz)` - * Here, `parents` is the list of parent types of the class, `decls` is the scope - * containing all declarations in the class, and `clazz` is the symbol of the class - * itself. - */ - abstract class ClassInfoTypeExtractor { - def apply(parents: List[Type], decls: Scope, clazz: Symbol): ClassInfoType - def unapply(tpe: ClassInfoType): Option[(List[Type], Scope, Symbol)] + /** The API that all annotated types support */ + trait AnnotatedTypeApi extends TypeApi { this: AnnotatedType => + val annotations: List[AnnotationInfo] + val underlying: Type + val selfsym: Symbol } - abstract class NullaryMethodTypeExtractor { - def apply(resultType: Type): NullaryMethodType - def unapply(tpe: NullaryMethodType): Option[(Type)] - } + /** .. */ + override type TypeBounds >: Null <: Type with TypeBoundsApi - abstract class PolyTypeExtractor { - def apply(typeParams: List[Symbol], resultType: Type): PolyType - def unapply(tpe: PolyType): Option[(List[Symbol], Type)] + /** The API that all type bounds support */ + trait TypeBoundsApi extends TypeApi { this: TypeBounds => + val lo: Type + val hi: Type } - abstract class ExistentialTypeExtractor { - def apply(quantified: List[Symbol], underlying: Type): ExistentialType - def unapply(tpe: ExistentialType): Option[(List[Symbol], Type)] - } + /** .. */ + override type BoundedWildcardType >: Null <: Type with BoundedWildcardTypeApi - abstract class AnnotatedTypeExtractor { - def apply(annotations: List[AnnotationInfo], underlying: Type, selfsym: Symbol): AnnotatedType - def unapply(tpe: AnnotatedType): Option[(List[AnnotationInfo], Type, Symbol)] + /** The API that all this types support */ + trait BoundedWildcardTypeApi extends TypeApi { this: BoundedWildcardType => + val bounds: TypeBounds } /** The least upper bound of a list of types, as determined by `<:<`. */ diff --git a/src/library/scala/reflect/api/Universe.scala b/src/library/scala/reflect/api/Universe.scala index ce1b806812..002cd2e673 100755 --- a/src/library/scala/reflect/api/Universe.scala +++ b/src/library/scala/reflect/api/Universe.scala @@ -3,25 +3,22 @@ package api import language.experimental.macros -abstract class Universe extends Symbols - with FreeVars +abstract class Universe extends base.Universe + with Symbols with Types - with Constants - with Scopes + with FlagSets with Names with Trees - with AnnotationInfos + with TreePrinters + with Constants with Positions - with Exprs + with Mirrors with StandardDefinitions - with TypeTags - with TreePrinters with StandardNames - with ClassLoaders - with TreeBuildUtil - with ToolBoxes - with FrontEnds - with Importers { + with Importers + with Exprs + with AnnotationInfos +{ /** Given an expression, generate a tree that when compiled and executed produces the original tree. * The produced tree will be bound to the Universe it was called from. @@ -36,17 +33,17 @@ abstract class Universe extends Symbols * * {{{ * <[ - * val $mr: scala.reflect.api.Universe = <reference to the Universe that calls the reify> - * $mr.Expr[Int]($mr.Apply($mr.Select($mr.Ident($mr.newFreeVar("x", <Int>, x), "+"), List($mr.Literal($mr.Constant(1)))))) + * val $u: u.type = u // where u is a reference to the Universe that calls the reify + * $u.Expr[Int]($u.Apply($u.Select($u.Ident($u.newFreeVar("x", <Int>, x), "+"), List($u.Literal($u.Constant(1)))))) * ]> * }}} * - * Reification performs expression splicing (when processing Expr.eval and Expr.value) + * Reification performs expression splicing (when processing Expr.splice) * and type splicing (for every type T that has a TypeTag[T] implicit in scope): * * {{{ - * val two = mirror.reify(2) // Literal(Constant(2)) - * val four = mirror.reify(two.eval + two.eval) // Apply(Select(two.tree, newTermName("$plus")), List(two.tree)) + * val two = mirror.reify(2) // Literal(Constant(2)) + * val four = mirror.reify(two.splice + two.splice) // Apply(Select(two.tree, newTermName("$plus")), List(two.tree)) * * def macroImpl[T](c: Context) = { * ... diff --git a/src/library/scala/reflect/api/package.scala b/src/library/scala/reflect/api/package.scala new file mode 100644 index 0000000000..d2fce7cf1d --- /dev/null +++ b/src/library/scala/reflect/api/package.scala @@ -0,0 +1,12 @@ +package scala.reflect + +package object api { + + // type and value aliases for slices of the base Universe cake that are not + // repeated in api.Universe + type Scopes = base.Scopes + type BuildUtils = base.BuildUtils + type Attachments = base.Attachments + + type MirrorOf[U <: base.Universe with Singleton] = base.MirrorOf[U] +} diff --git a/src/library/scala/reflect/base/AnnotationInfos.scala b/src/library/scala/reflect/base/AnnotationInfos.scala new file mode 100644 index 0000000000..f03644deef --- /dev/null +++ b/src/library/scala/reflect/base/AnnotationInfos.scala @@ -0,0 +1,44 @@ +package scala.reflect +package base + +trait AnnotationInfos { self: Universe => + + type AnnotationInfo >: Null <: AnyRef + implicit val AnnotationInfoTag: ClassTag[AnnotationInfo] + val AnnotationInfo: AnnotationInfoExtractor + + abstract class AnnotationInfoExtractor { + def apply(atp: Type, args: List[Tree], assocs: List[(Name, ClassfileAnnotArg)]): AnnotationInfo + def unapply(info: AnnotationInfo): Option[(Type, List[Tree], List[(Name, ClassfileAnnotArg)])] + } + + type ClassfileAnnotArg >: Null <: AnyRef + implicit val ClassfileAnnotArgTag: ClassTag[ClassfileAnnotArg] + + type LiteralAnnotArg >: Null <: AnyRef with ClassfileAnnotArg + implicit val LiteralAnnotArgTag: ClassTag[LiteralAnnotArg] + val LiteralAnnotArg: LiteralAnnotArgExtractor + + abstract class LiteralAnnotArgExtractor { + def apply(const: Constant): LiteralAnnotArg + def unapply(arg: LiteralAnnotArg): Option[Constant] + } + + type ArrayAnnotArg >: Null <: AnyRef with ClassfileAnnotArg + implicit val ArrayAnnotArgTag: ClassTag[ArrayAnnotArg] + val ArrayAnnotArg: ArrayAnnotArgExtractor + + abstract class ArrayAnnotArgExtractor { + def apply(args: Array[ClassfileAnnotArg]): ArrayAnnotArg + def unapply(arg: ArrayAnnotArg): Option[Array[ClassfileAnnotArg]] + } + + type NestedAnnotArg >: Null <: AnyRef with ClassfileAnnotArg + implicit val NestedAnnotArgTag: ClassTag[NestedAnnotArg] + val NestedAnnotArg: NestedAnnotArgExtractor + + abstract class NestedAnnotArgExtractor { + def apply(annInfo: AnnotationInfo): NestedAnnotArg + def unapply(arg: NestedAnnotArg): Option[AnnotationInfo] + } +}
\ No newline at end of file diff --git a/src/library/scala/reflect/base/Attachments.scala b/src/library/scala/reflect/base/Attachments.scala new file mode 100644 index 0000000000..76606ca958 --- /dev/null +++ b/src/library/scala/reflect/base/Attachments.scala @@ -0,0 +1,42 @@ +package scala.reflect +package base + +/** Attachments is a generalisation of Position. + * Typically it stores a Position of a tree, but this can be extended to encompass arbitrary payloads. + * + * Attachments have to carry positions, because we don't want to introduce even a single additional field in Tree + * imposing an unnecessary memory tax because of something that will not be used in most cases. + */ +abstract class Attachments { self => + + type Pos >: Null + + /** Gets the underlying position */ + def pos: Pos + + /** Creates a copy of this attachment with its position updated */ + def withPos(newPos: Pos): Attachments { type Pos = self.Pos } + + /** Gets the underlying payload */ + def all: Set[Any] = Set.empty + + def get[T: ClassTag]: Option[T] = + (all find (_.getClass == classTag[T].erasure)).asInstanceOf[Option[T]] + + /** Creates a copy of this attachment with its payload updated */ + def add(attachment: Any): Attachments { type Pos = self.Pos } = + new NonemptyAttachments(this.pos, all + attachment) + + def remove[T: ClassTag]: Attachments { type Pos = self.Pos } = { + val newAll = all filterNot (_.getClass == classTag[T].erasure) + if (newAll.isEmpty) pos.asInstanceOf[Attachments { type Pos = self.Pos }] + else new NonemptyAttachments(this.pos, newAll) + } + + private class NonemptyAttachments(override val pos: Pos, override val all: Set[Any]) extends Attachments { + type Pos = self.Pos + def withPos(newPos: Pos) = new NonemptyAttachments(newPos, all) + } +} + + diff --git a/src/library/scala/reflect/base/Base.scala b/src/library/scala/reflect/base/Base.scala new file mode 100644 index 0000000000..461eaa2e9e --- /dev/null +++ b/src/library/scala/reflect/base/Base.scala @@ -0,0 +1,763 @@ +package scala.reflect +package base + +import language.experimental.macros +import java.io.PrintWriter +import scala.annotation.switch +import scala.ref.WeakReference +import collection.mutable + +class Base extends Universe { self => + + private var nextId = 0 + + abstract class Symbol(val name: Name, val flags: FlagSet) extends SymbolBase { + val id = { nextId += 1; nextId } + def owner: Symbol + def fullName: String = + if (isEffectiveRoot || owner.isEffectiveRoot) name.toString else owner.fullName + "." + name + private def isEffectiveRoot = + this == NoSymbol || this == rootMirror.RootClass || this == rootMirror.EmptyPackageClass + + def newTermSymbol(name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TermSymbol = + new TermSymbol(this, name, flags) + + def newModuleAndClassSymbol(name: Name, pos: Position = NoPosition, flags: FlagSet = NoFlags): (ModuleSymbol, ClassSymbol) = { + val c = newClassSymbol(name.toTypeName, pos, flags) + val m = new ModuleSymbol(this, name.toTermName, flags, c) + (m, c) + } + + def newMethodSymbol(name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): MethodSymbol + = new MethodSymbol(this, name, flags) + + def newTypeSymbol(name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TypeSymbol = + new TypeSymbol(this, name, flags) + + def newClassSymbol(name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): ClassSymbol = + new ClassSymbol(this, name, flags) + + def newFreeTermSymbol(name: TermName, info: Type, value: => Any, flags: FlagSet = NoFlags, origin: String = null) = + new FreeTermSymbol(this, name, flags) + + def newFreeTypeSymbol(name: TypeName, info: Type, value: => Any, flags: FlagSet = NoFlags, origin: String = null) = + new FreeTypeSymbol(this, name, flags) + + private def kindString: String = + if (isModule) "module" + else if (isClass) "class" + else if (isFreeType) "free type" + else if (isType) "type" + else if (isMethod) "method" + else if (isFreeTerm) "free term" + else if (isTerm) "value" + else "symbol" + // [Eugene++ to Martin] base names should expose `decode` + override def toString() = s"$kindString $name" + } + implicit val SymbolTag = ClassTag[Symbol](classOf[Symbol]) + + class TermSymbol(val owner: Symbol, override val name: TermName, flags: FlagSet) + extends Symbol(name, flags) with TermSymbolBase + implicit val TermSymbolTag = ClassTag[TermSymbol](classOf[TermSymbol]) + + class TypeSymbol(val owner: Symbol, override val name: TypeName, flags: FlagSet) + extends Symbol(name, flags) with TypeSymbolBase { + override val asTypeConstructor = TypeRef(ThisType(owner), this, Nil) + } + implicit val TypeSymbolTag = ClassTag[TypeSymbol](classOf[TypeSymbol]) + + class MethodSymbol(owner: Symbol, name: TermName, flags: FlagSet) + extends TermSymbol(owner, name, flags) with MethodSymbolBase + implicit val MethodSymbolTag = ClassTag[MethodSymbol](classOf[MethodSymbol]) + + class ModuleSymbol(owner: Symbol, name: TermName, flags: FlagSet, override val moduleClass: Symbol) + extends TermSymbol(owner, name, flags) with ModuleSymbolBase + implicit val ModuleSymbolTag = ClassTag[ModuleSymbol](classOf[ModuleSymbol]) + + class ClassSymbol(owner: Symbol, name: TypeName, flags: FlagSet) + extends TypeSymbol(owner, name, flags) with ClassSymbolBase + implicit val ClassSymbolTag = ClassTag[ClassSymbol](classOf[ClassSymbol]) + + class FreeTermSymbol(owner: Symbol, name: TermName, flags: FlagSet) + extends TermSymbol(owner, name, flags) with FreeTermSymbolBase + implicit val FreeTermSymbolTag = ClassTag[FreeTermSymbol](classOf[FreeTermSymbol]) + + class FreeTypeSymbol(owner: Symbol, name: TypeName, flags: FlagSet) + extends TypeSymbol(owner, name, flags) with FreeTypeSymbolBase + implicit val FreeTypeSymbolTag = ClassTag[FreeTypeSymbol](classOf[FreeTypeSymbol]) + + + object NoSymbol extends Symbol(nme.NO_NAME, NoFlags) { + override def owner = throw new UnsupportedOperationException("NoSymbol.owner") + } + + // todo. write a decent toString that doesn't crash on recursive types + class Type extends TypeBase { def typeSymbol: Symbol = NoSymbol } + implicit val TypeTagg = ClassTag[Type](classOf[Type]) + + val NoType = new Type + val NoPrefix = new Type + + class SingletonType extends Type + implicit val SingletonTypeTag = ClassTag[SingletonType](classOf[SingletonType]) + + case class ThisType(sym: Symbol) extends SingletonType { override val typeSymbol = sym } + object ThisType extends ThisTypeExtractor + implicit val ThisTypeTag = ClassTag[ThisType](classOf[ThisType]) + + case class SingleType(pre: Type, sym: Symbol) extends SingletonType + object SingleType extends SingleTypeExtractor + implicit val SingleTypeTag = ClassTag[SingleType](classOf[SingleType]) + + case class SuperType(thistpe: Type, supertpe: Type) extends SingletonType + object SuperType extends SuperTypeExtractor + implicit val SuperTypeTag = ClassTag[SuperType](classOf[SuperType]) + + case class ConstantType(value: Constant) extends SingletonType + object ConstantType extends ConstantTypeExtractor + implicit val ConstantTypeTag = ClassTag[ConstantType](classOf[ConstantType]) + + case class TypeRef(pre: Type, sym: Symbol, args: List[Type]) extends Type { override val typeSymbol = sym } + object TypeRef extends TypeRefExtractor + implicit val TypeRefTag = ClassTag[TypeRef](classOf[TypeRef]) + + abstract class CompoundType extends Type + implicit val CompoundTypeTag = ClassTag[CompoundType](classOf[CompoundType]) + + case class RefinedType(parents: List[Type], decls: Scope) extends CompoundType + object RefinedType extends RefinedTypeExtractor { + def apply(parents: List[Type], decls: Scope, clazz: Symbol): RefinedType = + RefinedType(parents, decls) + } + implicit val RefinedTypeTag = ClassTag[RefinedType](classOf[RefinedType]) + + case class ClassInfoType(parents: List[Type], decls: Scope, override val typeSymbol: Symbol) extends CompoundType + object ClassInfoType extends ClassInfoTypeExtractor + implicit val ClassInfoTypeTag = ClassTag[ClassInfoType](classOf[ClassInfoType]) + + case class MethodType(params: List[Symbol], resultType: Type) extends Type + object MethodType extends MethodTypeExtractor + implicit val MethodTypeTag = ClassTag[MethodType](classOf[MethodType]) + + case class NullaryMethodType(resultType: Type) extends Type + object NullaryMethodType extends NullaryMethodTypeExtractor + implicit val NullaryMethodTypeTag = ClassTag[NullaryMethodType](classOf[NullaryMethodType]) + + case class PolyType(typeParams: List[Symbol], resultType: Type) extends Type + object PolyType extends PolyTypeExtractor + implicit val PolyTypeTag = ClassTag[PolyType](classOf[PolyType]) + + case class ExistentialType(quantified: List[Symbol], underlying: Type) extends Type { override def typeSymbol = underlying.typeSymbol } + object ExistentialType extends ExistentialTypeExtractor + implicit val ExistentialTypeTag = ClassTag[ExistentialType](classOf[ExistentialType]) + + case class AnnotatedType(annotations: List[AnnotationInfo], underlying: Type, selfsym: Symbol) extends Type { override def typeSymbol = underlying.typeSymbol } + object AnnotatedType extends AnnotatedTypeExtractor + implicit val AnnotatedTypeTag = ClassTag[AnnotatedType](classOf[AnnotatedType]) + + case class TypeBounds(lo: Type, hi: Type) extends Type + object TypeBounds extends TypeBoundsExtractor + implicit val TypeBoundsTag = ClassTag[TypeBounds](classOf[TypeBounds]) + + val WildcardType = new Type + + case class BoundedWildcardType(bounds: TypeBounds) extends Type + object BoundedWildcardType extends BoundedWildcardTypeExtractor + implicit val BoundedWildcardTypeTag = ClassTag[BoundedWildcardType](classOf[BoundedWildcardType]) + + type Scope = Iterable[Symbol] + implicit val ScopeTag = ClassTag[Scope](classOf[Scope]) + + def newScope = newScopeWith() + def newNestedScope(outer: Iterable[Symbol]) = newScope + def newScopeWith(elems: Symbol*): Scope = elems + + abstract class Name(str: String) extends NameBase { + override def toString = str + } + implicit val NameTag = ClassTag[Name](classOf[Name]) + + class TermName(str: String) extends Name(str) { + def isTermName = true + def isTypeName = false + def toTermName = this + def toTypeName = new TypeName(str) + } + implicit val TermNameTag = ClassTag[TermName](classOf[TermName]) + + class TypeName(str: String) extends Name(str) { + def isTermName = false + def isTypeName = true + def toTermName = new TermName(str) + def toTypeName = this + } + implicit val TypeNameTag = ClassTag[TypeName](classOf[TypeName]) + + def newTermName(str: String) = new TermName(str) + def newTypeName(str: String) = new TypeName(str) + + object nme extends TermNamesBase { + type NameType = TermName + val EMPTY = newTermName("") + val ROOT = newTermName("<root>") + val EMPTY_PACKAGE_NAME = newTermName("<empty>") + val CONSTRUCTOR = newTermName("<init>") + val NO_NAME = newTermName("<none>") + val WILDCARD = newTermName("_") + } + + object tpnme extends TypeNamesBase { + type NameType = TypeName + val EMPTY = nme.EMPTY.toTypeName + val ROOT = nme.ROOT.toTypeName + val EMPTY_PACKAGE_NAME = nme.EMPTY_PACKAGE_NAME.toTypeName + val WILDCARD = nme.WILDCARD.toTypeName + } + + type FlagSet = Long + val NoFlags = 0L + implicit val FlagSetTag = ClassTag[FlagSet](classOf[FlagSet]) + + class Modifiers(override val flags: FlagSet, + override val privateWithin: Name, + override val annotations: List[Tree]) extends ModifiersBase { + def hasFlag(flags: FlagSet) = (this.flags & flags) != 0 + def hasAllFlags(flags: FlagSet) = (flags & ~this.flags) == 0 + } + + implicit val ModifiersTag = ClassTag[Modifiers](classOf[Modifiers]) + + object Modifiers extends ModifiersCreator { + def apply(flags: Long, + privateWithin: Name, + annotations: List[Tree]) = new Modifiers(flags, privateWithin, annotations) + } + + case class Constant(value: Any) + object Constant extends ConstantExtractor + implicit val ConstantTag = ClassTag[Constant](classOf[Constant]) + + case class AnnotationInfo(atp: Type, args: List[Tree], assocs: List[(Name, ClassfileAnnotArg)]) + object AnnotationInfo extends AnnotationInfoExtractor + implicit val AnnotationInfoTag = ClassTag[AnnotationInfo](classOf[AnnotationInfo]) + + abstract class ClassfileAnnotArg + implicit val ClassfileAnnotArgTag = ClassTag[ClassfileAnnotArg](classOf[ClassfileAnnotArg]) + + case class LiteralAnnotArg(const: Constant) extends ClassfileAnnotArg + object LiteralAnnotArg extends LiteralAnnotArgExtractor + implicit val LiteralAnnotArgTag = ClassTag[LiteralAnnotArg](classOf[LiteralAnnotArg]) + + case class ArrayAnnotArg(args: Array[ClassfileAnnotArg]) extends ClassfileAnnotArg + object ArrayAnnotArg extends ArrayAnnotArgExtractor + implicit val ArrayAnnotArgTag = ClassTag[ArrayAnnotArg](classOf[ArrayAnnotArg]) + + case class NestedAnnotArg(annInfo: AnnotationInfo) extends ClassfileAnnotArg + object NestedAnnotArg extends NestedAnnotArgExtractor + implicit val NestedAnnotArgTag = ClassTag[NestedAnnotArg](classOf[NestedAnnotArg]) + + class Position extends Attachments { + override type Pos = Position + def pos = this + def withPos(newPos: Position) = newPos + def isRange = false + def focus = this + } + implicit val PositionTag = ClassTag[Position](classOf[Position]) + + val NoPosition = new Position + + def atPos[T <: Tree](pos: Position)(tree: T): T = tree + + private val generated = new mutable.HashMap[String, WeakReference[Symbol]] + + private def cached(name: String)(symExpr: => Symbol): Symbol = + generated get name match { + case Some(WeakReference(sym)) => + sym + case _ => + val sym = symExpr + generated(name) = WeakReference(sym) + sym + } + + object build extends BuildBase { + def selectType(owner: Symbol, name: String): TypeSymbol = { + val clazz = new ClassSymbol(owner, newTypeName(name), NoFlags) + cached(clazz.fullName)(clazz).asTypeSymbol + } + + def selectTerm(owner: Symbol, name: String): TermSymbol = { + val valu = new MethodSymbol(owner, newTermName(name), NoFlags) + cached(valu.fullName)(valu).asTermSymbol + } + + def selectOverloadedMethod(owner: Symbol, name: String, index: Int): MethodSymbol = + selectTerm(owner, name).asMethodSymbol + + def newNestedSymbol(owner: Symbol, name: Name, pos: Position, flags: Long, isClass: Boolean): Symbol = + if (name.isTypeName) + if (isClass) new ClassSymbol(owner, name.toTypeName, flags) + else new TypeSymbol(owner, name.toTypeName, flags) + else new TermSymbol(owner, name.toTermName, flags) + + def newFreeTerm(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTermSymbol = + new FreeTermSymbol(rootMirror.RootClass, newTermName(name), flags) + + def newFreeType(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTypeSymbol = + new FreeTypeSymbol(rootMirror.RootClass, newTypeName(name), flags) + + def newFreeExistential(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTypeSymbol = + new FreeTypeSymbol(rootMirror.RootClass, newTypeName(name), flags) + + def setTypeSignature[S <: Symbol](sym: S, tpe: Type): S = sym + + def setAnnotations[S <: Symbol](sym: S, annots: List[AnnotationInfo]): S = sym + + def flagsFromBits(bits: Long): FlagSet = bits + + object emptyValDef extends ValDef(NoMods, nme.WILDCARD, TypeTree(NoType), EmptyTree) { + override def isEmpty = true + } + + def This(sym: Symbol): Tree = self.This(sym.name.toTypeName) + + def Select(qualifier: Tree, sym: Symbol): Select = self.Select(qualifier, sym.name) + + def Ident(sym: Symbol): Ident = self.Ident(sym.name) + + def TypeTree(tp: Type): TypeTree = self.TypeTree() + + def thisPrefix(sym: Symbol): Type = SingleType(NoPrefix, sym) + + def setType[T <: Tree](tree: T, tpe: Type): T = tree + + def setSymbol[T <: Tree](tree: T, sym: Symbol): T = tree + } + + import build._ + + class Mirror extends MirrorOf[self.type] { + val universe: self.type = self + + lazy val RootClass = new ClassSymbol(NoSymbol, tpnme.ROOT, NoFlags) + lazy val RootPackage = new ModuleSymbol(NoSymbol, nme.ROOT, NoFlags, RootClass) + lazy val EmptyPackageClass = new ClassSymbol(RootClass, tpnme.EMPTY_PACKAGE_NAME, NoFlags) + lazy val EmptyPackage = new ModuleSymbol(RootClass, nme.EMPTY_PACKAGE_NAME, NoFlags, EmptyPackageClass) + + def staticClass(fullName: String): ClassSymbol = + mkStatic[ClassSymbol](fullName) + + def staticModule(fullName: String): ModuleSymbol = + mkStatic[ModuleSymbol](fullName) + + private def mkStatic[S <: Symbol : ClassTag](fullName: String): S = + cached(fullName) { + val point = fullName lastIndexOf '.' + val owner = + if (point > 0) staticModule(fullName take point).moduleClass + else rootMirror.RootClass + val name = fullName drop point + 1 + val symtag = implicitly[ClassTag[S]] + if (symtag == ClassSymbolTag) new ClassSymbol(owner, newTypeName(name), NoFlags) + else owner.newModuleAndClassSymbol(newTermName(name))._1 + }.asInstanceOf[S] + } + + lazy val rootMirror = new Mirror + + import rootMirror._ + + object definitions extends DefinitionsBase { + lazy val ScalaPackage = staticModule("scala") + lazy val ScalaPackageClass = ScalaPackage.moduleClass.asClassSymbol + + lazy val AnyClass = staticClass("scala.Any") + lazy val AnyValClass = staticClass("scala.Any") + lazy val ObjectClass = staticClass("java.lang.Object") + lazy val AnyRefClass = ObjectClass + + lazy val NullClass = staticClass("scala.Null") + lazy val NothingClass = staticClass("scala.Nothing") + + lazy val UnitClass = staticClass("scala.Unit") + lazy val ByteClass = staticClass("scala.Byte") + lazy val ShortClass = staticClass("scala.Short") + lazy val CharClass = staticClass("scala.Char") + lazy val IntClass = staticClass("scala.Int") + lazy val LongClass = staticClass("scala.Long") + lazy val FloatClass = staticClass("scala.Float") + lazy val DoubleClass = staticClass("scala.Double") + lazy val BooleanClass = staticClass("scala.Boolean") + + lazy val StringClass = staticClass("java.lang.String") + lazy val ClassClass = staticClass("java.lang.Class") + lazy val ArrayClass = staticClass("scala.Array") + lazy val ListClass = staticClass("scala.List") + + lazy val PredefModule = staticModule("scala.Predef") + } + + import definitions._ + + private def thisModuleType(fullName: String): Type = ThisType(staticModule(fullName).moduleClass) + private lazy val ScalaPrefix = thisModuleType("scala") + private lazy val JavaLangPrefix = thisModuleType("java.lang") + + lazy val ByteTpe = TypeRef(ScalaPrefix, ByteClass, Nil) + lazy val ShortTpe = TypeRef(ScalaPrefix, ShortClass, Nil) + lazy val CharTpe = TypeRef(ScalaPrefix, CharClass, Nil) + lazy val IntTpe = TypeRef(ScalaPrefix, IntClass, Nil) + lazy val LongTpe = TypeRef(ScalaPrefix, LongClass, Nil) + lazy val FloatTpe = TypeRef(ScalaPrefix, FloatClass, Nil) + lazy val DoubleTpe = TypeRef(ScalaPrefix, DoubleClass, Nil) + lazy val BooleanTpe = TypeRef(ScalaPrefix, BooleanClass, Nil) + lazy val UnitTpe = TypeRef(ScalaPrefix, UnitClass, Nil) + lazy val AnyTpe = TypeRef(ScalaPrefix, AnyClass, Nil) + lazy val AnyValTpe = TypeRef(ScalaPrefix, AnyValClass, Nil) + lazy val NothingTpe = TypeRef(ScalaPrefix, NothingClass, Nil) + lazy val NullTpe = TypeRef(ScalaPrefix, NullClass, Nil) + lazy val ObjectTpe = TypeRef(JavaLangPrefix, ObjectClass, Nil) + lazy val AnyRefTpe = ObjectTpe + lazy val StringTpe = TypeRef(JavaLangPrefix, StringClass, Nil) + + private var nodeCount = 0 // not synchronized + + abstract class Tree extends TreeBase with Product { + def isDef: Boolean = false + def isEmpty: Boolean = 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 + } + } + + def show(tree: Tree) = s"<tree ${tree.getClass}>" + + trait TermTree extends Tree + + trait TypTree extends Tree + + trait SymTree extends Tree + + trait NameTree extends Tree { + def name: Name + } + + trait RefTree extends SymTree with NameTree { + def qualifier: Tree // empty for Idents + def name: Name + } + + abstract class DefTree extends SymTree with NameTree { + def name: Name + override def isDef = true + } + + case object EmptyTree extends TermTree { + override def isEmpty = true + } + + abstract class MemberDef extends DefTree { + def mods: Modifiers + } + + case class PackageDef(pid: RefTree, stats: List[Tree]) + extends MemberDef { + def name = pid.name + def mods = NoMods + } + object PackageDef extends PackageDefExtractor + + abstract class ImplDef extends MemberDef { + def impl: Template + } + + case class ClassDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], impl: Template) + extends ImplDef + object ClassDef extends ClassDefExtractor + + case class ModuleDef(mods: Modifiers, name: TermName, impl: Template) + extends ImplDef + object ModuleDef extends ModuleDefExtractor + + abstract class ValOrDefDef extends MemberDef { + val name: Name + val tpt: Tree + val rhs: Tree + } + + case class ValDef(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree) extends ValOrDefDef + object ValDef extends ValDefExtractor + + case class DefDef(mods: Modifiers, name: Name, tparams: List[TypeDef], + vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) extends ValOrDefDef + object DefDef extends DefDefExtractor + + case class TypeDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], rhs: Tree) + extends MemberDef + object TypeDef extends TypeDefExtractor + + case class LabelDef(name: TermName, params: List[Ident], rhs: Tree) + extends DefTree with TermTree + object LabelDef extends LabelDefExtractor + + case class ImportSelector(name: Name, namePos: Int, rename: Name, renamePos: Int) + object ImportSelector extends ImportSelectorExtractor + + case class Import(expr: Tree, selectors: List[ImportSelector]) + extends SymTree + object Import extends ImportExtractor + + case class Template(parents: List[Tree], self: ValDef, body: List[Tree]) + extends SymTree + object Template extends TemplateExtractor + + case class Block(stats: List[Tree], expr: Tree) + extends TermTree + object Block extends BlockExtractor + + case class CaseDef(pat: Tree, guard: Tree, body: Tree) + extends Tree + object CaseDef extends CaseDefExtractor + + case class Alternative(trees: List[Tree]) + extends TermTree + object Alternative extends AlternativeExtractor + + case class Star(elem: Tree) + extends TermTree + object Star extends StarExtractor + + case class Bind(name: Name, body: Tree) + extends DefTree + object Bind extends BindExtractor + + case class UnApply(fun: Tree, args: List[Tree]) + extends TermTree + object UnApply extends UnApplyExtractor + + case class ArrayValue(elemtpt: Tree, elems: List[Tree]) + extends TermTree + object ArrayValue extends ArrayValueExtractor + + case class Function(vparams: List[ValDef], body: Tree) + extends TermTree with SymTree + object Function extends FunctionExtractor + + case class Assign(lhs: Tree, rhs: Tree) + extends TermTree + object Assign extends AssignExtractor + + case class AssignOrNamedArg(lhs: Tree, rhs: Tree) + extends TermTree + object AssignOrNamedArg extends AssignOrNamedArgExtractor + + case class If(cond: Tree, thenp: Tree, elsep: Tree) + extends TermTree + object If extends IfExtractor + + case class Match(selector: Tree, cases: List[CaseDef]) + extends TermTree + object Match extends MatchExtractor + + case class Return(expr: Tree) + extends TermTree with SymTree + object Return extends ReturnExtractor + + case class Try(block: Tree, catches: List[CaseDef], finalizer: Tree) + extends TermTree + object Try extends TryExtractor + + case class Throw(expr: Tree) + extends TermTree + object Throw extends ThrowExtractor + + case class New(tpt: Tree) extends TermTree + object New extends NewExtractor + + case class Typed(expr: Tree, tpt: Tree) + extends TermTree + object Typed extends TypedExtractor + + abstract class GenericApply extends TermTree { + val fun: Tree + val args: List[Tree] + } + + case class TypeApply(fun: Tree, args: List[Tree]) + extends GenericApply + object TypeApply extends TypeApplyExtractor + + case class Apply(fun: Tree, args: List[Tree]) + extends GenericApply + object Apply extends ApplyExtractor + + case class ApplyDynamic(qual: Tree, args: List[Tree]) + extends TermTree with SymTree + object ApplyDynamic extends ApplyDynamicExtractor + + case class Super(qual: Tree, mix: TypeName) extends TermTree + object Super extends SuperExtractor + + case class This(qual: TypeName) + extends TermTree with SymTree + object This extends ThisExtractor + + case class Select(qualifier: Tree, name: Name) + extends RefTree + object Select extends SelectExtractor + + case class Ident(name: Name) extends RefTree { + def qualifier: Tree = EmptyTree + } + object Ident extends IdentExtractor + + case class ReferenceToBoxed(ident: Ident) extends TermTree + object ReferenceToBoxed extends ReferenceToBoxedExtractor + + case class Literal(value: Constant) + extends TermTree { + assert(value ne null) + } + object Literal extends LiteralExtractor + + case class Annotated(annot: Tree, arg: Tree) extends Tree + object Annotated extends AnnotatedExtractor + + case class SingletonTypeTree(ref: Tree) + extends TypTree + object SingletonTypeTree extends SingletonTypeTreeExtractor + + case class SelectFromTypeTree(qualifier: Tree, name: TypeName) + extends TypTree with RefTree + object SelectFromTypeTree extends SelectFromTypeTreeExtractor + + case class CompoundTypeTree(templ: Template) + extends TypTree + object CompoundTypeTree extends CompoundTypeTreeExtractor + + case class AppliedTypeTree(tpt: Tree, args: List[Tree]) + extends TypTree + object AppliedTypeTree extends AppliedTypeTreeExtractor + + case class TypeBoundsTree(lo: Tree, hi: Tree) + extends TypTree + object TypeBoundsTree extends TypeBoundsTreeExtractor + + case class ExistentialTypeTree(tpt: Tree, whereClauses: List[Tree]) + extends TypTree + object ExistentialTypeTree extends ExistentialTypeTreeExtractor + + case class TypeTree() extends TypTree { + val original: Tree = null + override def isEmpty = true + } + object TypeTree extends TypeTreeExtractor + + 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]) + + // [Eugene++] to be removed after SI-5863 is fixed + def ClassDef(sym: Symbol, impl: Template): ClassDef = ??? + def ModuleDef(sym: Symbol, impl: Template): ModuleDef = ??? + def ValDef(sym: Symbol, rhs: Tree): ValDef = ??? + def ValDef(sym: Symbol): ValDef = ??? + def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef = ??? + def DefDef(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree): DefDef = ??? + def DefDef(sym: Symbol, mods: Modifiers, rhs: Tree): DefDef = ??? + def DefDef(sym: Symbol, rhs: Tree): DefDef = ??? + def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef = ??? + def TypeDef(sym: Symbol, rhs: Tree): TypeDef = ??? + def TypeDef(sym: Symbol): TypeDef = ??? + def LabelDef(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef = ??? + def CaseDef(pat: Tree, body: Tree): CaseDef = ??? + def Bind(sym: Symbol, body: Tree): Bind = ??? + def Try(body: Tree, cases: (Tree, Tree)*): Try = ??? + def Throw(tpe: Type, args: Tree*): Throw = ??? + def Apply(sym: Symbol, args: Tree*): Tree = ??? + def New(tpt: Tree, argss: List[List[Tree]]): Tree = ??? + def New(tpe: Type, args: Tree*): Tree = ??? + def New(sym: Symbol, args: Tree*): Tree = ??? + def ApplyConstructor(tpt: Tree, args: List[Tree]): Tree = ??? + def Super(sym: Symbol, mix: TypeName): Tree = ??? + def This(sym: Symbol): Tree = ??? + def Select(qualifier: Tree, name: String): Select = ??? + def Select(qualifier: Tree, sym: Symbol): Select = ??? + def Ident(name: String): Ident = ??? + def Ident(sym: Symbol): Ident = ??? + def Block(stats: Tree*): Block = ??? + def TypeTree(tp: Type): TypeTree = ??? +} diff --git a/src/library/scala/reflect/base/BuildUtils.scala b/src/library/scala/reflect/base/BuildUtils.scala new file mode 100644 index 0000000000..eaba0ec2b7 --- /dev/null +++ b/src/library/scala/reflect/base/BuildUtils.scala @@ -0,0 +1,90 @@ +package scala.reflect +package base + +trait BuildUtils { self: Universe => + + val build: BuildBase + + abstract class BuildBase { + /** Selects type symbol with given simple name `name` from the defined members of `owner`. + */ + def selectType(owner: Symbol, name: String): TypeSymbol + + /** Selects term symbol with given name and type from the defined members of prefix type + */ + def selectTerm(owner: Symbol, name: String): TermSymbol + + /** Selects overloaded method symbol with given name and index + */ + def selectOverloadedMethod(owner: Symbol, name: String, index: Int): MethodSymbol + + /** A fresh symbol with given name `name`, position `pos` and flags `flags` that has + * the current symbol as its owner. + */ + def newNestedSymbol(owner: Symbol, name: Name, pos: Position, flags: FlagSet, isClass: Boolean): Symbol + + /** Create a fresh free term symbol. + * @param name the name of the free variable + * @param info the type signature of the free variable + * @param value the value of the free variable at runtime + * @param flags (optional) flags of the free variable + * @param origin debug information that tells where this symbol comes from + */ + def newFreeTerm(name: String, info: Type, value: => Any, flags: FlagSet = NoFlags, origin: String = null): FreeTermSymbol + + /** Create a fresh free non-existential type symbol. + * @param name the name of the free variable + * @param info the type signature of the free variable + * @param value a type tag that captures the value of the free variable + * is completely phantom, since the captured type cannot be propagated to the runtime + * if it could be, we wouldn't be creating a free type to begin with + * the only usage for it is preserving the captured symbol for compile-time analysis + * @param flags (optional) flags of the free variable + * @param origin debug information that tells where this symbol comes from + */ + def newFreeType(name: String, info: Type, value: => Any, flags: FlagSet = NoFlags, origin: String = null): FreeTypeSymbol + + /** Create a fresh free existential type symbol. + * @param name the name of the free variable + * @param info the type signature of the free variable + * @param value a type tag that captures the value of the free variable + * is completely phantom, since the captured type cannot be propagated to the runtime + * if it could be, we wouldn't be creating a free type to begin with + * the only usage for it is preserving the captured symbol for compile-time analysis + * @param flags (optional) flags of the free variable + * @param origin (optional) debug information that tells where this symbol comes from + * [Martin to Eugene: why needed?] + */ + def newFreeExistential(name: String, info: Type, value: => Any, flags: FlagSet = NoFlags, origin: String = null): FreeTypeSymbol + + /** Set symbol's type signature to given type. + * @return the symbol itself + */ + def setTypeSignature[S <: Symbol](sym: S, tpe: Type): S + + /** Set symbol's annotations to given annotations `annots`. + */ + def setAnnotations[S <: Symbol](sym: S, annots: List[AnnotationInfo]): S + + def flagsFromBits(bits: Long): FlagSet + + // [Eugene++ to Martin] these are necessary for reification + // on a second thought, I added them to BuildUtils instead of base + + def emptyValDef: ValDef + + def This(sym: Symbol): Tree + + def Select(qualifier: Tree, sym: Symbol): Select + + def Ident(sym: Symbol): Ident + + def TypeTree(tp: Type): TypeTree + + def thisPrefix(sym: Symbol): Type + + def setType[T <: Tree](tree: T, tpe: Type): T + + def setSymbol[T <: Tree](tree: T, sym: Symbol): T + } +} diff --git a/src/library/scala/reflect/base/Constants.scala b/src/library/scala/reflect/base/Constants.scala new file mode 100644 index 0000000000..8f98e85ad0 --- /dev/null +++ b/src/library/scala/reflect/base/Constants.scala @@ -0,0 +1,20 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Martin Odersky + */ + +package scala.reflect +package base + +trait Constants { + self: Universe => + + type Constant >: Null <: AnyRef + implicit val ConstantTag: ClassTag[Constant] + val Constant: ConstantExtractor + + abstract class ConstantExtractor { + def apply(value: Any): Constant + def unapply(arg: Constant): Option[Any] + } +} diff --git a/src/library/scala/reflect/base/FlagSets.scala b/src/library/scala/reflect/base/FlagSets.scala new file mode 100644 index 0000000000..57946d0f27 --- /dev/null +++ b/src/library/scala/reflect/base/FlagSets.scala @@ -0,0 +1,17 @@ +package scala.reflect +package base + +trait FlagSets { self: Universe => + + /** An abstract type representing sets of flags that apply to definition trees and symbols */ + type FlagSet + + /** A tag that preserves the identity of the `FlagSet` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val FlagSetTag: ClassTag[FlagSet] + + /** The empty set of flags */ + val NoFlags: FlagSet +} + diff --git a/src/library/scala/reflect/base/MirrorOf.scala b/src/library/scala/reflect/base/MirrorOf.scala new file mode 100644 index 0000000000..03e035cd81 --- /dev/null +++ b/src/library/scala/reflect/base/MirrorOf.scala @@ -0,0 +1,25 @@ +package scala.reflect +package base + +// [Eugene++ to Martin] why was this a member of `scala.reflect`, but not `scala.reflect.base`? + +abstract class MirrorOf[U <: base.Universe with Singleton] { + /** .. */ + val universe: U + + /** .. */ + def RootClass: U#ClassSymbol + def RootPackage: U#ModuleSymbol + def EmptyPackageClass: U#ClassSymbol + def EmptyPackage: U#ModuleSymbol + + /** The symbol corresponding to the globally accessible class with the + * given fully qualified name `fullName`. + */ + def staticClass(fullName: String): U#ClassSymbol + + /** The symbol corresponding to the globally accessible object with the + * given fully qualified name `fullName`. + */ + def staticModule(fullName: String): U#ModuleSymbol +} diff --git a/src/library/scala/reflect/base/Mirrors.scala b/src/library/scala/reflect/base/Mirrors.scala new file mode 100644 index 0000000000..50866ef000 --- /dev/null +++ b/src/library/scala/reflect/base/Mirrors.scala @@ -0,0 +1,12 @@ +package scala.reflect +package base + +trait Mirrors { + self: Universe => + + /** .. */ + type Mirror >: Null <: MirrorOf[self.type] + + /** .. */ + val rootMirror: Mirror +} diff --git a/src/library/scala/reflect/base/Names.scala b/src/library/scala/reflect/base/Names.scala new file mode 100644 index 0000000000..edf2ba7dc9 --- /dev/null +++ b/src/library/scala/reflect/base/Names.scala @@ -0,0 +1,53 @@ +package scala.reflect +package base + +/** A trait that manages names. + * A name is a string in one of two name universes: terms and types. + * The same string can be a name in both universes. + * Two names are equal if they represent the same string and they are + * members of the same universe. + * + * Names are interned. That is, for two names `name11 and `name2`, + * `name1 == name2` implies `name1 eq name2`. + */ +trait Names { + + /** The abstract type of names */ + type Name >: Null <: NameBase + implicit val NameTag: ClassTag[Name] + + /** The abstract type of names representing terms */ + type TypeName >: Null <: Name + implicit val TypeNameTag: ClassTag[TypeName] + + /** The abstract type of names representing types */ + type TermName >: Null <: Name + implicit val TermNameTag: ClassTag[TermName] + + /** The base API that all names support */ + abstract class NameBase { + /** Is this name a term name? */ + def isTermName: Boolean + + /** Is this name a type name? */ + def isTypeName: Boolean + + /** Returns a term name that represents the same string as this name */ + def toTermName: TermName + + /** Returns a type name that represents the same string as this name */ + def toTypeName: TypeName + } + + /** Create a new term name. + */ + def newTermName(s: String): TermName + + /** Creates a new type name. + */ + def newTypeName(s: String): TypeName + + def EmptyTermName: TermName = newTermName("") + + def EmptyTypeName: TypeName = EmptyTermName.toTypeName +} diff --git a/src/library/scala/reflect/base/Positions.scala b/src/library/scala/reflect/base/Positions.scala new file mode 100644 index 0000000000..cefeb51c9a --- /dev/null +++ b/src/library/scala/reflect/base/Positions.scala @@ -0,0 +1,22 @@ +package scala.reflect +package base + +trait Positions { + self: Universe => + + /** .. */ + type Position >: Null <: Attachments { type Pos = Position } + + /** A tag that preserves the identity of the `FlagSet` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val PositionTag: ClassTag[Position] + + /** .. */ + val NoPosition: Position + + /** Assigns a given position to all position-less nodes of a given AST. + */ + def atPos[T <: Tree](pos: Position)(tree: T): T + // [Eugene++] why do we have this in base? +} diff --git a/src/library/scala/reflect/api/Scopes.scala b/src/library/scala/reflect/base/Scopes.scala index 4a5702eadc..a5db01c0ce 100755..100644 --- a/src/library/scala/reflect/api/Scopes.scala +++ b/src/library/scala/reflect/base/Scopes.scala @@ -1,9 +1,14 @@ package scala.reflect -package api +package base trait Scopes { self: Universe => - type Scope <: Iterable[Symbol] + type Scope >: Null <: Iterable[Symbol] + + /** A tag that preserves the identity of the `Scope` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val ScopeTag: ClassTag[Scope] /** Create a new scope */ def newScope: Scope diff --git a/src/library/scala/reflect/base/StandardDefinitions.scala b/src/library/scala/reflect/base/StandardDefinitions.scala new file mode 100644 index 0000000000..eff23b539e --- /dev/null +++ b/src/library/scala/reflect/base/StandardDefinitions.scala @@ -0,0 +1,75 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Martin Odersky + */ + +package scala.reflect +package base + +// [Eugene++] not sure whether we need this in the top level of the universe +trait StandardTypes { + self: Universe => + + val ByteTpe: Type + val ShortTpe: Type + val CharTpe: Type + val IntTpe: Type + val LongTpe: Type + val FloatTpe: Type + val DoubleTpe: Type + val BooleanTpe: Type + val UnitTpe: Type + + val AnyTpe: Type + val AnyValTpe: Type + val AnyRefTpe: Type + val ObjectTpe: Type + + val NothingTpe: Type + val NullTpe: Type + val StringTpe: Type +} + +trait StandardDefinitions extends StandardTypes { + self: Universe => + + val definitions: DefinitionsBase + + // [Eugene] todo. shortcut to these fields if possible when generating tags + // todo. also shortcut to StandardTypes, of course + trait DefinitionsBase { + // packages + def ScalaPackageClass: ClassSymbol + def ScalaPackage: ModuleSymbol + + // top types + def AnyClass : ClassSymbol + def AnyValClass: ClassSymbol + def ObjectClass: ClassSymbol + def AnyRefClass: TypeSymbol + + // bottom types + def NullClass : ClassSymbol + def NothingClass: ClassSymbol + + // the scala value classes + def UnitClass : ClassSymbol + def ByteClass : ClassSymbol + def ShortClass : ClassSymbol + def CharClass : ClassSymbol + def IntClass : ClassSymbol + def LongClass : ClassSymbol + def FloatClass : ClassSymbol + def DoubleClass : ClassSymbol + def BooleanClass: ClassSymbol + + // some special classes + def StringClass : ClassSymbol + def ClassClass : ClassSymbol + def ArrayClass : ClassSymbol + def ListClass : ClassSymbol // [Eugene] I'd say List has earned its right to be here + + // the Predef object + def PredefModule: ModuleSymbol + } +} diff --git a/src/library/scala/reflect/base/StandardNames.scala b/src/library/scala/reflect/base/StandardNames.scala new file mode 100644 index 0000000000..8a3fbe9683 --- /dev/null +++ b/src/library/scala/reflect/base/StandardNames.scala @@ -0,0 +1,29 @@ +/* NSC -- new Scala compiler +* Copyright 2005-2011 LAMP/EPFL +* @author Martin Odersky +*/ + +package scala.reflect +package base + +trait StandardNames { + self: Universe => + + val nme: TermNamesBase + val tpnme: TypeNamesBase + + trait NamesBase { + type NameType >: Null <: Name + val EMPTY: NameType + val ROOT: NameType + val EMPTY_PACKAGE_NAME: NameType + val WILDCARD: NameType + } + + trait TypeNamesBase extends NamesBase + + trait TermNamesBase extends NamesBase { + val CONSTRUCTOR: TermName + val NO_NAME: NameType + } +} diff --git a/src/library/scala/reflect/base/Symbols.scala b/src/library/scala/reflect/base/Symbols.scala new file mode 100644 index 0000000000..9404520073 --- /dev/null +++ b/src/library/scala/reflect/base/Symbols.scala @@ -0,0 +1,272 @@ +package scala.reflect +package base + +trait Symbols { self: Universe => + + // [Eugene++ to Martin] why is Symbol >: Null, whereas all other symbol types are not nullable? + // same question goes for Types + + /** The abstract type of symbols representing declarations */ + type Symbol >: Null <: SymbolBase + + /** A tag that preserves the identity of the `Symbol` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val SymbolTag: ClassTag[Symbol] + + /** The abstract type of type symbols representing type, class, and trait declarations, + * as well as type parameters + */ + type TypeSymbol >: Null <: Symbol with TypeSymbolBase + + /** A tag that preserves the identity of the `TypeSymbol` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val TypeSymbolTag: ClassTag[TypeSymbol] + + /** The abstract type of term symbols representing val, var, def, and object declarations as + * well as packages and value parameters. + */ + type TermSymbol >: Null <: Symbol with TermSymbolBase + + /** A tag that preserves the identity of the `TermSymbol` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val TermSymbolTag: ClassTag[TermSymbol] + + /** The abstract type of method symbols representing def declarations */ + type MethodSymbol >: Null <: TermSymbol with MethodSymbolBase + + /** A tag that preserves the identity of the `MethodSymbol` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val MethodSymbolTag: ClassTag[MethodSymbol] + + /** The abstract type of module symbols representing object declarations */ + type ModuleSymbol >: Null <: TermSymbol with ModuleSymbolBase + + /** A tag that preserves the identity of the `ModuleSymbol` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val ModuleSymbolTag: ClassTag[ModuleSymbol] + + /** The abstract type of class symbols representing class and trait definitions */ + type ClassSymbol >: Null <: TypeSymbol with ClassSymbolBase + + /** A tag that preserves the identity of the `ClassSymbol` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val ClassSymbolTag: ClassTag[ClassSymbol] + + /** The abstract type of free terms introduced by reification */ + type FreeTermSymbol >: Null <: TermSymbol with FreeTermSymbolBase + + /** A tag that preserves the identity of the `FreeTermSymbol` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val FreeTermSymbolTag: ClassTag[FreeTermSymbol] + + /** The abstract type of free types introduced by reification */ + type FreeTypeSymbol >: Null <: TypeSymbol with FreeTypeSymbolBase + + /** A tag that preserves the identity of the `FreeTypeSymbol` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val FreeTypeSymbolTag: ClassTag[FreeTypeSymbol] + + /** A special "missing" symbol */ + val NoSymbol: Symbol + + /** The base API that all symbols support */ + trait SymbolBase { this: Symbol => + + /** An id number which is unique for all symbols in this universe */ + // [Eugene++ to Martin] do we leave this here? + def id: Int + + /** The owner of this symbol. This is the symbol + * that directly contains the current symbol's definition. + * The `NoSymbol` symbol does not have an owner, and calling this method + * on one causes an internal error. + * The owner of the Scala root class [[scala.reflect.api.mirror.RootClass]] + * and the Scala root object [[scala.reflect.api.mirror.RootPackage]] is `NoSymbol`. + * Every other symbol has a chain of owners that ends in + * [[scala.reflect.api.mirror.RootClass]]. + */ + def owner: Symbol + + /** The type of the symbol name. + * Can be either `TermName` or `TypeName` depending on whether this is a `TermSymbol` or a `TypeSymbol`. + * + * Type name namespaces do not intersect with term name namespaces. + * This fact is reflected in different types for names of `TermSymbol` and `TypeSymbol`. + */ + type NameType >: Null <: Name + + /** The name of the symbol as a member of the `Name` type. + */ + def name: Name + + /** The encoded full path name of this symbol, where outer names and inner names + * are separated by periods. + */ + def fullName: String + + /** If this symbol is a class, this symbol; otherwise the next enclosing + * class, or `NoSymbol` if none exists. + */ + def enclosingClass: Symbol = + if (isClass || this == NoSymbol) this else owner.enclosingClass + + /** If this symbol is a method, this symbol; otherwise the next enclosing + * method, or `NoSymbol` if none exists. + */ + def enclosingMethod: Symbol = + if (isMethod || this == NoSymbol) this else owner.enclosingMethod + + /** Does this symbol represent the definition of a type? + * Note that every symbol is either a term or a type. + * So for every symbol `sym`, either `sym.isTerm` is true + * or `sym.isType` is true. + */ + def isType: Boolean = false + + /** This symbol cast to a TypeSymbol. + * Returns ClassCastException if `isType` is false. + */ + def asTypeSymbol: TypeSymbol = throw new ClassCastException(toString) + + /** Does this symbol represent the definition of a term? + * Note that every symbol is either a term or a term. + * So for every symbol `sym`, either `sym.isTerm` is true + * or `sym.isTerm` is true. + */ + def isTerm: Boolean = false + + /** This symbol cast to a TermSymbol. + * Returns ClassCastException if `isTerm` is false. + */ + def asTermSymbol: TermSymbol = throw new ClassCastException(toString) + + /** Does this symbol represent the definition of a method? + * If yes, `isTerm` is also guaranteed to be true. + */ + def isMethod: Boolean = false + + /** This symbol cast to a MethodSymbol. + * Returns ClassCastException if `isMethod` is false. + */ + def asMethodSymbol: MethodSymbol = throw new ClassCastException(toString) + + /** Does this symbol represent the definition of a module (i.e. it + * results from an object definition?). + * If yes, `isTerm` is also guaranteed to be true. + */ + def isModule: Boolean = false + + /** This symbol cast to a ModuleSymbol defined by an object definition. + * Returns ClassCastException if `isModule` is false. + */ + def asModuleSymbol: ModuleSymbol = throw new ClassCastException(toString) + + /** Does this symbol represent the definition of a class or trait? + * If yes, `isType` is also guaranteed to be true. + */ + def isClass: Boolean = false + + /** This symbol cast to a ClassSymbol representing a class or trait. + * Returns ClassCastException if `isClass` is false. + */ + def asClassSymbol: ClassSymbol = throw new ClassCastException(toString) + + /** Does this symbol represent a free term captured by reification? + * If yes, `isTerm` is also guaranteed to be true. + */ + def isFreeTerm: Boolean = false + + /** This symbol cast to a free term symbol. + * Returns ClassCastException if `isFreeTerm` is false. + */ + def asFreeTermSymbol: FreeTermSymbol = throw new ClassCastException(toString) + + /** Does this symbol represent a free type captured by reification? + * If yes, `isType` is also guaranteed to be true. + */ + def isFreeType: Boolean = false + + /** This symbol cast to a free type symbol. + * Returns ClassCastException if `isFreeType` is false. + */ + def asFreeTypeSymbol: FreeTypeSymbol = throw new ClassCastException(toString) + + def newTermSymbol(name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TermSymbol + def newModuleAndClassSymbol(name: Name, pos: Position = NoPosition, flags: FlagSet = NoFlags): (ModuleSymbol, ClassSymbol) + def newMethodSymbol(name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): MethodSymbol + def newTypeSymbol(name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TypeSymbol + def newClassSymbol(name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): ClassSymbol + } + + /** The base API that all type symbols support */ + trait TypeSymbolBase extends SymbolBase { this: TypeSymbol => + /** Type symbols have their names of type `TypeName`. + */ + final type NameType = TypeName + + /** The type constructor corresponding to this type symbol. + * This is different from `asType` in that type parameters + * are part of results of `asType`, but not of `asTypeConstructor`. + * + * Example: Given a class declaration `class C[T] { ... } `, that generates a symbol + * `C`. Then `C.asType` is the type `C[T]`, but `C.asTypeConstructor` is `C`. + */ + def asTypeConstructor: Type + + override def isType = true + override def asTypeSymbol = this + } + + /** The base API that all term symbols support */ + trait TermSymbolBase extends SymbolBase { this: TermSymbol => + /** Term symbols have their names of type `TermName`. + */ + final type NameType = TermName + + final override def isTerm = true + final override def asTermSymbol = this + } + + /** The base API that all method symbols support */ + trait MethodSymbolBase extends TermSymbolBase { this: MethodSymbol => + final override def isMethod = true + final override def asMethodSymbol = this + } + + /** The base API that all module symbols support */ + trait ModuleSymbolBase extends TermSymbolBase { this: ModuleSymbol => + /** The class implicitly associated with the object definition. + */ + def moduleClass: Symbol // needed for tree traversals + // [Eugene++] when this becomes `moduleClass: ClassSymbol`, it will be the happiest day in my life + + final override def isModule = true + final override def asModuleSymbol = this + } + + /** The base API that all class symbols support */ + trait ClassSymbolBase extends TypeSymbolBase { this: ClassSymbol => + final override def isClass = true + final override def asClassSymbol = this + } + + /** The base API that all free type symbols support */ + trait FreeTypeSymbolBase extends TypeSymbolBase { this: FreeTypeSymbol => + final override def isFreeType = true + final override def asFreeTypeSymbol = this + } + + /** The base API that all free term symbols support */ + trait FreeTermSymbolBase extends TermSymbolBase { this: FreeTermSymbol => + final override def isFreeTerm = true + final override def asFreeTermSymbol = this + } +} diff --git a/src/library/scala/reflect/base/TagInterop.scala b/src/library/scala/reflect/base/TagInterop.scala new file mode 100644 index 0000000000..0ec4d06a6c --- /dev/null +++ b/src/library/scala/reflect/base/TagInterop.scala @@ -0,0 +1,29 @@ +package scala.reflect +package base + +import scala.runtime.ScalaRunTime._ + +trait TagInterop { self: Universe => + def arrayTagToClassManifest[T](tag: ArrayTag[T]): ClassManifest[T] = { + val erasure = arrayElementClass(tag) + if (erasure.isArray) { + val elementClass = arrayElementClass(erasure) + val elementManifest = arrayTagToClassManifest(ClassTag(elementClass)) + ClassManifest.arrayType(elementManifest).asInstanceOf[ClassManifest[T]] + } else { + ClassManifest.fromClass(erasure.asInstanceOf[Class[T]]) + } + } + + // [Eugene++] `mirror` parameters are now of type `Any`, because I can't make these path-dependent types work + // if you're brave enough, replace `Any` with `Mirror`, recompile and run interop_concretetypetags_are_manifests.scala + + // [Eugene++] would be great if we could approximate the interop without any mirrors + // todo. think how to implement that + + def concreteTypeTagToManifest[T: ClassTag](mirror: Any, tag: base.Universe # ConcreteTypeTag[T]): Manifest[T] = + throw new UnsupportedOperationException("This universe does not support tag -> manifest conversions. Use scala.reflect.runtime.universe from scala-reflect.jar.") + + def manifestToConcreteTypeTag[T](mirror: Any, manifest: Manifest[T]): base.Universe # ConcreteTypeTag[T] = + throw new UnsupportedOperationException("This universe does not support manifest -> tag conversions. Use scala.reflect.runtime.universe from scala-reflect.jar.") +} diff --git a/src/library/scala/reflect/base/TreeCreator.scala b/src/library/scala/reflect/base/TreeCreator.scala new file mode 100644 index 0000000000..c9c8de2307 --- /dev/null +++ b/src/library/scala/reflect/base/TreeCreator.scala @@ -0,0 +1,6 @@ +package scala.reflect +package base + +abstract class TreeCreator { + def apply[U <: Universe with Singleton](m: MirrorOf[U]): U # Tree +} diff --git a/src/library/scala/reflect/base/Trees.scala b/src/library/scala/reflect/base/Trees.scala new file mode 100644 index 0000000000..298d229570 --- /dev/null +++ b/src/library/scala/reflect/base/Trees.scala @@ -0,0 +1,1459 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Martin Odersky + */ +package scala.reflect +package base + +// [Eugene++] of all reflection APIs, this one is in the biggest need of review and documentation + +// Syncnote: Trees are currently not thread-safe. +// [Eugene++] now when trees are finally abstract types, can we do something for this? +trait Trees { self: Universe => + + /** The base API that all trees support */ + abstract class TreeBase extends Product { this: Tree => + /** ... */ + def isDef: Boolean + + /** ... */ + def isEmpty: Boolean + + /** The canonical way to test if a Tree represents a term. + */ + def isTerm: Boolean + + /** The canonical way to test if a Tree represents a type. + */ + def isType: Boolean + + /** Obtains string representation of a tree */ + override def toString: String = show(this) + } + + /** Obtains string representation of a tree */ + def show(tree: Tree): String + + /** Tree is the basis for scala's abstract syntax. The nodes are + * implemented as case classes, and the parameters which initialize + * a given tree are immutable: however Trees have several mutable + * fields which are manipulated in the course of typechecking, + * including pos, symbol, and tpe. + * + * Newly instantiated trees have tpe set to null (though it + * may be set immediately thereafter depending on how it is + * constructed.) When a tree is passed to the typer, typically via + * `typer.typed(tree)`, under normal circumstances the tpe must be + * null or the typer will ignore it. Furthermore, the typer is not + * required to return the same tree it was passed. + * + * Trees can be easily traversed with e.g. foreach on the root node; + * for a more nuanced traversal, subclass Traverser. Transformations + * can be considerably trickier: see the numerous subclasses of + * Transformer found around the compiler. + * + * Copying Trees should be done with care depending on whether + * it need be done lazily or strictly (see LazyTreeCopier and + * StrictTreeCopier) and on whether the contents of the mutable + * fields should be copied. The tree copiers will copy the mutable + * attributes to the new tree; calling Tree#duplicate will copy + * symbol and tpe, but all the positions will be focused. + * + * Trees can be coarsely divided into four mutually exclusive categories: + * + * - TermTrees, representing terms + * - TypTrees, representing types. Note that is `TypTree`, not `TypeTree`. + * - SymTrees, which may represent types or terms. + * - Other Trees, which have none of those as parents. + * + * SymTrees include important nodes Ident and Select, which are + * used as both terms and types; they are distinguishable based on + * whether the Name is a TermName or TypeName. The correct way for + * to test for a type or a term (on any Tree) are the isTerm/isType + * methods on Tree. + * + * "Others" are mostly syntactic or short-lived constructs. Examples + * include CaseDef, which wraps individual match cases: they are + * neither terms nor types, nor do they carry a symbol. Another + * example is Parens, which is eliminated during parsing. + */ + type Tree >: Null <: TreeBase + // [Eugene++] todo. discuss nullability of abstract types + + /** A tag that preserves the identity of the `Tree` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val TreeTag: ClassTag[Tree] + + /** The empty tree */ + val EmptyTree: Tree + + /** A tree for a term. Not all terms are TermTrees; use isTerm + * to reliably identify terms. + */ + type TermTree >: Null <: AnyRef with Tree + + /** A tag that preserves the identity of the `TermTree` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val TermTreeTag: ClassTag[TermTree] + + /** A tree for a type. Not all types are TypTrees; use isType + * to reliably identify types. + */ + type TypTree >: Null <: AnyRef with Tree + + /** A tag that preserves the identity of the `TypTree` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val TypTreeTag: ClassTag[TypTree] + + /** A tree with a mutable symbol field, initialized to NoSymbol. + */ + type SymTree >: Null <: AnyRef with Tree + + /** A tag that preserves the identity of the `SymTree` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val SymTreeTag: ClassTag[SymTree] + + /** A tree with a name - effectively, a DefTree or RefTree. + */ + type NameTree >: Null <: AnyRef with Tree + + /** A tag that preserves the identity of the `NameTree` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val NameTreeTag: ClassTag[NameTree] + + /** A tree which references a symbol-carrying entity. + * References one, as opposed to defining one; definitions + * are in DefTrees. + */ + type RefTree >: Null <: SymTree with NameTree + + /** A tag that preserves the identity of the `RefTree` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val RefTreeTag: ClassTag[RefTree] + + /** A tree which defines a symbol-carrying entity. + */ + type DefTree >: Null <: SymTree with NameTree + + /** A tag that preserves the identity of the `DefTree` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val DefTreeTag: ClassTag[DefTree] + + /** Common base class for all member definitions: types, classes, + * objects, packages, vals and vars, defs. + */ + type MemberDef >: Null <: DefTree + + /** A tag that preserves the identity of the `MemberDef` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val MemberDefTag: ClassTag[MemberDef] + + /** A packaging, such as `package pid { stats }` + */ + type PackageDef >: Null <: MemberDef + + /** A tag that preserves the identity of the `PackageDef` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val PackageDefTag: ClassTag[PackageDef] + + /** The constructor/deconstructor for `PackageDef` instances. */ + val PackageDef: PackageDefExtractor + + /** An extractor class to create and pattern match with syntax `PackageDef(pid, stats)`. + * This AST node corresponds to the following Scala code: + * + * `package` pid { stats } + */ + abstract class PackageDefExtractor { + def apply(pid: RefTree, stats: List[Tree]): PackageDef + def unapply(packageDef: PackageDef): Option[(RefTree, List[Tree])] + } + + /** A common base class for class and object definitions. + */ + type ImplDef >: Null <: MemberDef + + /** A tag that preserves the identity of the `ImplDef` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val ImplDefTag: ClassTag[ImplDef] + + /** A class definition. + */ + type ClassDef >: Null <: ImplDef + + /** A tag that preserves the identity of the `ClassDef` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val ClassDefTag: ClassTag[ClassDef] + + /** The constructor/deconstructor for `ClassDef` instances. */ + val ClassDef: ClassDefExtractor + + /** An extractor class to create and pattern match with syntax `ClassDef(mods, name, tparams, impl)`. + * This AST node corresponds to the following Scala code: + * + * mods `class` name [tparams] impl + * + * Where impl stands for: + * + * `extends` parents { defs } + */ + abstract class ClassDefExtractor { + def apply(mods: Modifiers, name: TypeName, tparams: List[TypeDef], impl: Template): ClassDef + def unapply(classDef: ClassDef): Option[(Modifiers, TypeName, List[TypeDef], Template)] + } + + /** An object definition, e.g. `object Foo`. Internally, objects are + * quite frequently called modules to reduce ambiguity. + * Eliminated by refcheck. + */ + type ModuleDef >: Null <: ImplDef + + /** A tag that preserves the identity of the `ModuleDef` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val ModuleDefTag: ClassTag[ModuleDef] + + /** The constructor/deconstructor for `ModuleDef` instances. */ + val ModuleDef: ModuleDefExtractor + + /** An extractor class to create and pattern match with syntax `ModuleDef(mods, name, impl)`. + * This AST node corresponds to the following Scala code: + * + * mods `object` name impl + * + * Where impl stands for: + * + * `extends` parents { defs } + */ + abstract class ModuleDefExtractor { + def apply(mods: Modifiers, name: TermName, impl: Template): ModuleDef + def unapply(moduleDef: ModuleDef): Option[(Modifiers, TermName, Template)] + } + + /** A common base class for ValDefs and DefDefs. + */ + type ValOrDefDef >: Null <: MemberDef + + /** A tag that preserves the identity of the `ValOrDefDef` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val ValOrDefDefTag: ClassTag[ValOrDefDef] + + /** Broadly speaking, a value definition. All these are encoded as ValDefs: + * + * - immutable values, e.g. "val x" + * - mutable values, e.g. "var x" - the MUTABLE flag set in mods + * - lazy values, e.g. "lazy val x" - the LAZY flag set in mods + * - method parameters, see vparamss in DefDef - the PARAM flag is set in mods + * - explicit self-types, e.g. class A { self: Bar => } - !!! not sure what is set. + */ + type ValDef >: Null <: ValOrDefDef + + /** A tag that preserves the identity of the `ValDef` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val ValDefTag: ClassTag[ValDef] + + /** The constructor/deconstructor for `ValDef` instances. */ + val ValDef: ValDefExtractor + + /** An extractor class to create and pattern match with syntax `ValDef(mods, name, tpt, rhs)`. + * This AST node corresponds to the following Scala code: + * + * mods `val` name: tpt = rhs + * + * mods `var` name: tpt = rhs + * + * mods name: tpt = rhs // in signatures of function and method definitions + * + * self: Bar => // self-types (!!! not sure what is set) + * + * If the type of a value is not specified explicitly (i.e. is meant to be inferred), + * this is expressed by having `tpt` set to `TypeTree()` (but not to an `EmptyTree`!). + */ + abstract class ValDefExtractor { + def apply(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree): ValDef + def unapply(valDef: ValDef): Option[(Modifiers, TermName, Tree, Tree)] + } + + /** A method or macro definition. + * @param name The name of the method or macro. Can be a type name in case this is a type macro + */ + type DefDef >: Null <: ValOrDefDef + + /** A tag that preserves the identity of the `DefDef` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val DefDefTag: ClassTag[DefDef] + + /** The constructor/deconstructor for `DefDef` instances. */ + val DefDef: DefDefExtractor + + /** An extractor class to create and pattern match with syntax `DefDef(mods, name, tparams, vparamss, tpt, rhs)`. + * This AST node corresponds to the following Scala code: + * + * mods `def` name[tparams](vparams_1)...(vparams_n): tpt = rhs + * + * If the return type is not specified explicitly (i.e. is meant to be inferred), + * this is expressed by having `tpt` set to `TypeTree()` (but not to an `EmptyTree`!). + */ + abstract class DefDefExtractor { + def apply(mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef + def unapply(defDef: DefDef): Option[(Modifiers, Name, List[TypeDef], List[List[ValDef]], Tree, Tree)] + } + + /** An abstract type, a type parameter, or a type alias. + * Eliminated by erasure. + */ + type TypeDef >: Null <: MemberDef + + /** A tag that preserves the identity of the `TypeDef` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val TypeDefTag: ClassTag[TypeDef] + + /** The constructor/deconstructor for `TypeDef` instances. */ + val TypeDef: TypeDefExtractor + + /** An extractor class to create and pattern match with syntax `TypeDef(mods, name, tparams, rhs)`. + * This AST node corresponds to the following Scala code: + * + * mods `type` name[tparams] = rhs + * + * mods `type` name[tparams] >: lo <: hi + * + * First usage illustrates `TypeDefs` representing type aliases and type parameters. + * Second usage illustrates `TypeDefs` representing abstract types, + * where lo and hi are both `TypeBoundsTrees` and `Modifier.deferred` is set in mods. + */ + abstract class TypeDefExtractor { + def apply(mods: Modifiers, name: TypeName, tparams: List[TypeDef], rhs: Tree): TypeDef + def unapply(typeDef: TypeDef): Option[(Modifiers, TypeName, List[TypeDef], Tree)] + } + + /** A labelled expression. Not expressible in language syntax, but + * generated by the compiler to simulate while/do-while loops, and + * also by the pattern matcher. + * + * The label acts much like a nested function, where `params` represents + * the incoming parameters. The symbol given to the LabelDef should have + * a MethodType, as if it were a nested function. + * + * Jumps are apply nodes attributed with a label's symbol. The + * arguments from the apply node will be passed to the label and + * assigned to the Idents. + * + * Forward jumps within a block are allowed. + */ + type LabelDef >: Null <: DefTree with TermTree + + /** A tag that preserves the identity of the `LabelDef` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val LabelDefTag: ClassTag[LabelDef] + + /** The constructor/deconstructor for `LabelDef` instances. */ + val LabelDef: LabelDefExtractor + + /** An extractor class to create and pattern match with syntax `LabelDef(name, params, rhs)`. + * + * This AST node does not have direct correspondence to Scala code. + * It is used for tailcalls and like. + * For example, while/do are desugared to label defs as follows: + * + * while (cond) body ==> LabelDef($L, List(), if (cond) { body; L$() } else ()) + * do body while (cond) ==> LabelDef($L, List(), body; if (cond) L$() else ()) + */ + abstract class LabelDefExtractor { + def apply(name: TermName, params: List[Ident], rhs: Tree): LabelDef + def unapply(labelDef: LabelDef): Option[(TermName, List[Ident], Tree)] + } + + /** Import selector + * + * Representation of an imported name its optional rename and their optional positions + * + * Eliminated by typecheck. + * + * @param name the imported name + * @param namePos its position or -1 if undefined + * @param rename the name the import is renamed to (== name if no renaming) + * @param renamePos the position of the rename or -1 if undefined + */ + type ImportSelector >: Null <: AnyRef + + /** A tag that preserves the identity of the `ImportSelector` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val ImportSelectorTag: ClassTag[ImportSelector] + + /** The constructor/deconstructor for `ImportSelector` instances. */ + val ImportSelector: ImportSelectorExtractor + + /** An extractor class to create and pattern match with syntax `ImportSelector(name:, namePos, rename, renamePos)`. + * This is not an AST node, it is used as a part of the `Import` node. + */ + abstract class ImportSelectorExtractor { + def apply(name: Name, namePos: Int, rename: Name, renamePos: Int): ImportSelector + def unapply(importSelector: ImportSelector): Option[(Name, Int, Name, Int)] + } + + /** Import clause + * + * @param expr + * @param selectors + */ + type Import >: Null <: SymTree + + /** A tag that preserves the identity of the `Import` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val ImportTag: ClassTag[Import] + + /** The constructor/deconstructor for `Import` instances. */ + val Import: ImportExtractor + + /** An extractor class to create and pattern match with syntax `Import(expr, selectors)`. + * This AST node corresponds to the following Scala code: + * + * import expr.{selectors} + * + * Selectors are a list of pairs of names (from, to). // [Eugene++] obviously, they no longer are. please, document! + * The last (and maybe only name) may be a nme.WILDCARD. For instance: + * + * import qual.{x, y => z, _} + * + * Would be represented as: + * + * Import(qual, List(("x", "x"), ("y", "z"), (WILDCARD, null))) + * + * The symbol of an `Import` is an import symbol @see Symbol.newImport. + * It's used primarily as a marker to check that the import has been typechecked. + */ + abstract class ImportExtractor { + def apply(expr: Tree, selectors: List[ImportSelector]): Import + def unapply(import_ : Import): Option[(Tree, List[ImportSelector])] + } + + /** Instantiation template of a class or trait + * + * @param parents + * @param body + */ + type Template >: Null <: SymTree + + /** A tag that preserves the identity of the `Template` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val TemplateTag: ClassTag[Template] + + /** The constructor/deconstructor for `Template` instances. */ + val Template: TemplateExtractor + + /** An extractor class to create and pattern match with syntax `Template(parents, self, body)`. + * This AST node corresponds to the following Scala code: + * + * `extends` parents { self => body } + * + * In case when the self-type annotation is missing, it is represented as + * an empty value definition with nme.WILDCARD as name and NoType as type. + * + * The symbol of a template is a local dummy. @see Symbol.newLocalDummy + * The owner of the local dummy is the enclosing trait or class. + * The local dummy is itself the owner of any local blocks. For example: + * + * class C { + * def foo { // owner is C + * def bar // owner is local dummy + * } + * } + */ + abstract class TemplateExtractor { + def apply(parents: List[Tree], self: ValDef, body: List[Tree]): Template + def unapply(template: Template): Option[(List[Tree], ValDef, List[Tree])] + } + + /** Block of expressions (semicolon separated expressions) */ + type Block >: Null <: TermTree + + /** A tag that preserves the identity of the `Block` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val BlockTag: ClassTag[Block] + + /** The constructor/deconstructor for `Block` instances. */ + val Block: BlockExtractor + + /** An extractor class to create and pattern match with syntax `Block(stats, expr)`. + * This AST node corresponds to the following Scala code: + * + * { stats; expr } + * + * If the block is empty, the `expr` is set to `Literal(Constant(()))`. // [Eugene++] check this + */ + abstract class BlockExtractor { + def apply(stats: List[Tree], expr: Tree): Block + def unapply(block: Block): Option[(List[Tree], Tree)] + } + + /** Case clause in a pattern match, eliminated during explicitouter + * (except for occurrences in switch statements). + * Eliminated by patmat/explicitouter. + */ + type CaseDef >: Null <: AnyRef with Tree + + /** A tag that preserves the identity of the `CaseDef` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val CaseDefTag: ClassTag[CaseDef] + + /** The constructor/deconstructor for `CaseDef` instances. */ + val CaseDef: CaseDefExtractor + + /** An extractor class to create and pattern match with syntax `CaseDef(pat, guard, body)`. + * This AST node corresponds to the following Scala code: + * + * `case` pat `if` guard => body + * + * If the guard is not present, the `guard` is set to `EmptyTree`. // [Eugene++] check this + * If the body is not specified, the `body` is set to `EmptyTree`. // [Eugene++] check this + */ + abstract class CaseDefExtractor { + def apply(pat: Tree, guard: Tree, body: Tree): CaseDef + def unapply(caseDef: CaseDef): Option[(Tree, Tree, Tree)] + } + + /** Alternatives of patterns, eliminated by explicitouter, except for + * occurrences in encoded Switch stmt (=remaining Match(CaseDef(...))) + * Eliminated by patmat/explicitouter. + */ + type Alternative >: Null <: TermTree + + /** A tag that preserves the identity of the `Alternative` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val AlternativeTag: ClassTag[Alternative] + + /** The constructor/deconstructor for `Alternative` instances. */ + val Alternative: AlternativeExtractor + + /** An extractor class to create and pattern match with syntax `Alternative(trees)`. + * This AST node corresponds to the following Scala code: + * + * pat1 | ... | patn + */ + abstract class AlternativeExtractor { + def apply(trees: List[Tree]): Alternative + def unapply(alternative: Alternative): Option[List[Tree]] + } + + /** Repetition of pattern. + * Eliminated by patmat/explicitouter. + */ + type Star >: Null <: TermTree + + /** A tag that preserves the identity of the `Star` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val StarTag: ClassTag[Star] + + /** The constructor/deconstructor for `Star` instances. */ + val Star: StarExtractor + + /** An extractor class to create and pattern match with syntax `Star(elem)`. + * This AST node corresponds to the following Scala code: + * + * pat* + */ + abstract class StarExtractor { + def apply(elem: Tree): Star + def unapply(star: Star): Option[Tree] + } + + /** Bind of a variable to a rhs pattern, eliminated by explicitouter + * Eliminated by patmat/explicitouter. + * + * @param name + * @param body + */ + type Bind >: Null <: DefTree + + /** A tag that preserves the identity of the `Bind` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val BindTag: ClassTag[Bind] + + /** The constructor/deconstructor for `Bind` instances. */ + val Bind: BindExtractor + + /** An extractor class to create and pattern match with syntax `Bind(name, body)`. + * This AST node corresponds to the following Scala code: + * + * pat* + */ + abstract class BindExtractor { + def apply(name: Name, body: Tree): Bind + def unapply(bind: Bind): Option[(Name, Tree)] + } + + /** Noone knows what this is. + * It is not idempotent w.r.t typechecking. + * Can we, please, remove it? + * Introduced by typer, eliminated by patmat/explicitouter. + */ + type UnApply >: Null <: TermTree + + /** A tag that preserves the identity of the `UnApply` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val UnApplyTag: ClassTag[UnApply] + + /** The constructor/deconstructor for `UnApply` instances. */ + val UnApply: UnApplyExtractor + + /** An extractor class to create and pattern match with syntax `UnApply(fun, args)`. + * This AST node does not have direct correspondence to Scala code, + * and is introduced when typechecking pattern matches and `try` blocks. + */ + abstract class UnApplyExtractor { + def apply(fun: Tree, args: List[Tree]): UnApply + def unapply(unApply: UnApply): Option[(Tree, List[Tree])] + } + + /** Array of expressions, needs to be translated in backend. + * This AST node is used to pass arguments to vararg arguments. + * Introduced by uncurry. + */ + type ArrayValue >: Null <: TermTree + + /** A tag that preserves the identity of the `ArrayValue` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val ArrayValueTag: ClassTag[ArrayValue] + + /** The constructor/deconstructor for `ArrayValue` instances. */ + val ArrayValue: ArrayValueExtractor + + /** An extractor class to create and pattern match with syntax `ArrayValue(elemtpt, elems)`. + * This AST node does not have direct correspondence to Scala code, + * and is used to pass arguments to vararg arguments. For instance: + * + * printf("%s%d", foo, 42) + * + * Is translated to after uncurry to: + * + * Apply( + * Ident("printf"), + * Literal("%s%d"), + * ArrayValue(<Any>, List(Ident("foo"), Literal(42)))) + */ + abstract class ArrayValueExtractor { + def apply(elemtpt: Tree, elems: List[Tree]): ArrayValue + def unapply(arrayValue: ArrayValue): Option[(Tree, List[Tree])] + } + + /** Anonymous function, eliminated by lambdalift */ + type Function >: Null <: TermTree with SymTree + + /** A tag that preserves the identity of the `Function` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val FunctionTag: ClassTag[Function] + + /** The constructor/deconstructor for `Function` instances. */ + val Function: FunctionExtractor + + /** An extractor class to create and pattern match with syntax `Function(vparams, body)`. + * This AST node corresponds to the following Scala code: + * + * vparams => body + * + * The symbol of a Function is a synthetic value of name nme.ANON_FUN_NAME + * It is the owner of the function's parameters. + */ + abstract class FunctionExtractor { + def apply(vparams: List[ValDef], body: Tree): Function + def unapply(function: Function): Option[(List[ValDef], Tree)] + } + + /** Assignment */ + type Assign >: Null <: TermTree + + /** A tag that preserves the identity of the `Assign` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val AssignTag: ClassTag[Assign] + + /** The constructor/deconstructor for `Assign` instances. */ + val Assign: AssignExtractor + + /** An extractor class to create and pattern match with syntax `Assign(lhs, rhs)`. + * This AST node corresponds to the following Scala code: + * + * lhs = rhs + */ + abstract class AssignExtractor { + def apply(lhs: Tree, rhs: Tree): Assign + def unapply(assign: Assign): Option[(Tree, Tree)] + } + + /** Either an assignment or a named argument. Only appears in argument lists, + * eliminated by typecheck (doTypedApply), resurrected by reifier. + */ + type AssignOrNamedArg >: Null <: TermTree + + /** A tag that preserves the identity of the `AssignOrNamedArg` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val AssignOrNamedArgTag: ClassTag[AssignOrNamedArg] + + /** The constructor/deconstructor for `AssignOrNamedArg` instances. */ + val AssignOrNamedArg: AssignOrNamedArgExtractor + + /** An extractor class to create and pattern match with syntax `AssignOrNamedArg(lhs, rhs)`. + * This AST node corresponds to the following Scala code: + * + * @annotation(lhs = rhs) + * + * m.f(lhs = rhs) + */ + abstract class AssignOrNamedArgExtractor { + def apply(lhs: Tree, rhs: Tree): AssignOrNamedArg + def unapply(assignOrNamedArg: AssignOrNamedArg): Option[(Tree, Tree)] + } + + /** Conditional expression */ + type If >: Null <: TermTree + + /** A tag that preserves the identity of the `If` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val IfTag: ClassTag[If] + + /** The constructor/deconstructor for `If` instances. */ + val If: IfExtractor + + /** An extractor class to create and pattern match with syntax `If(cond, thenp, elsep)`. + * This AST node corresponds to the following Scala code: + * + * `if` (cond) thenp `else` elsep + * + * If the alternative is not present, the `elsep` is set to `EmptyTree`. // [Eugene++] check this + */ + abstract class IfExtractor { + def apply(cond: Tree, thenp: Tree, elsep: Tree): If + def unapply(if_ : If): Option[(Tree, Tree, Tree)] + } + + /** - Pattern matching expression (before explicitouter) + * - Switch statements (after explicitouter) + * + * After explicitouter, cases will satisfy the following constraints: + * + * - all guards are `EmptyTree`, + * - all patterns will be either `Literal(Constant(x:Int))` + * or `Alternative(lit|...|lit)` + * - except for an "otherwise" branch, which has pattern + * `Ident(nme.WILDCARD)` + */ + type Match >: Null <: TermTree + + /** A tag that preserves the identity of the `Match` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val MatchTag: ClassTag[Match] + + /** The constructor/deconstructor for `Match` instances. */ + val Match: MatchExtractor + + /** An extractor class to create and pattern match with syntax `Match(selector, cases)`. + * This AST node corresponds to the following Scala code: + * + * selector `match` { cases } + * + * // [Eugene++] say something about `val (foo, bar) = baz` and likes. + */ + abstract class MatchExtractor { + def apply(selector: Tree, cases: List[CaseDef]): Match + def unapply(match_ : Match): Option[(Tree, List[CaseDef])] + } + + /** Return expression */ + type Return >: Null <: TermTree with SymTree + + /** A tag that preserves the identity of the `Return` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val ReturnTag: ClassTag[Return] + + /** The constructor/deconstructor for `Return` instances. */ + val Return: ReturnExtractor + + /** An extractor class to create and pattern match with syntax `Return(expr)`. + * This AST node corresponds to the following Scala code: + * + * `return` expr + * + * The symbol of a Return node is the enclosing method + */ + abstract class ReturnExtractor { + def apply(expr: Tree): Return + def unapply(return_ : Return): Option[Tree] + } + + /** [Eugene++] comment me! */ + type Try >: Null <: TermTree + + /** A tag that preserves the identity of the `Try` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val TryTag: ClassTag[Try] + + /** The constructor/deconstructor for `Try` instances. */ + val Try: TryExtractor + + /** An extractor class to create and pattern match with syntax `Try(block, catches, finalizer)`. + * This AST node corresponds to the following Scala code: + * + * `try` block `catch` { catches } `finally` finalizer + * + * If the finalizer is not present, the `finalizer` is set to `EmptyTree`. // [Eugene++] check this + */ + abstract class TryExtractor { + def apply(block: Tree, catches: List[CaseDef], finalizer: Tree): Try + def unapply(try_ : Try): Option[(Tree, List[CaseDef], Tree)] + } + + /** Throw expression */ + type Throw >: Null <: TermTree + + /** A tag that preserves the identity of the `Throw` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val ThrowTag: ClassTag[Throw] + + /** The constructor/deconstructor for `Throw` instances. */ + val Throw: ThrowExtractor + + /** An extractor class to create and pattern match with syntax `Throw(expr)`. + * This AST node corresponds to the following Scala code: + * + * `throw` expr + */ + abstract class ThrowExtractor { + def apply(expr: Tree): Throw + def unapply(throw_ : Throw): Option[Tree] + } + + /** Object instantiation + * One should always use factory method below to build a user level new. + * + * @param tpt a class type + */ + type New >: Null <: TermTree + + /** A tag that preserves the identity of the `New` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val NewTag: ClassTag[New] + + /** The constructor/deconstructor for `New` instances. */ + val New: NewExtractor + + /** An extractor class to create and pattern match with syntax `New(tpt)`. + * This AST node corresponds to the following Scala code: + * + * `new` T + * + * This node always occurs in the following context: + * + * (`new` tpt).<init>[targs](args) + */ + abstract class NewExtractor { + def apply(tpt: Tree): New + def unapply(new_ : New): Option[Tree] + } + + /** Type annotation, eliminated by cleanup */ + type Typed >: Null <: TermTree + + /** A tag that preserves the identity of the `Typed` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val TypedTag: ClassTag[Typed] + + /** The constructor/deconstructor for `Typed` instances. */ + val Typed: TypedExtractor + + /** An extractor class to create and pattern match with syntax `Typed(expr, tpt)`. + * This AST node corresponds to the following Scala code: + * + * expr: tpt + */ + abstract class TypedExtractor { + def apply(expr: Tree, tpt: Tree): Typed + def unapply(typed: Typed): Option[(Tree, Tree)] + } + + /** Common base class for Apply and TypeApply. This could in principle + * be a SymTree, but whether or not a Tree is a SymTree isn't used + * to settle any interesting questions, and it would add a useless + * field to all the instances (useless, since GenericApply forwards to + * the underlying fun.) + */ + type GenericApply >: Null <: TermTree + + /** A tag that preserves the identity of the `GenericApply` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val GenericApplyTag: ClassTag[GenericApply] + + /** Explicit type application. + * @PP: All signs point toward it being a requirement that args.nonEmpty, + * but I can't find that explicitly stated anywhere. Unless your last name + * is odersky, you should probably treat it as true. + */ + type TypeApply >: Null <: GenericApply + + /** A tag that preserves the identity of the `TypeApply` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val TypeApplyTag: ClassTag[TypeApply] + + /** The constructor/deconstructor for `TypeApply` instances. */ + val TypeApply: TypeApplyExtractor + + /** An extractor class to create and pattern match with syntax `TypeApply(fun, args)`. + * This AST node corresponds to the following Scala code: + * + * fun[args] + */ + abstract class TypeApplyExtractor { + def apply(fun: Tree, args: List[Tree]): TypeApply + def unapply(typeApply: TypeApply): Option[(Tree, List[Tree])] + } + + /** Value application */ + type Apply >: Null <: GenericApply + + /** A tag that preserves the identity of the `Apply` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val ApplyTag: ClassTag[Apply] + + /** The constructor/deconstructor for `Apply` instances. */ + val Apply: ApplyExtractor + + /** An extractor class to create and pattern match with syntax `Apply(fun, args)`. + * This AST node corresponds to the following Scala code: + * + * fun(args) + * + * For instance: + * + * fun[targs](args) + * + * Is expressed as: + * + * Apply(TypeApply(fun, targs), args) + */ + abstract class ApplyExtractor { + def apply(fun: Tree, args: List[Tree]): Apply + def unapply(apply: Apply): Option[(Tree, List[Tree])] + } + + /** Dynamic value application. + * In a dynamic application q.f(as) + * - q is stored in qual + * - as is stored in args + * - f is stored as the node's symbol field. + * [Eugene++] what is it used for? + * Introduced by erasure, eliminated by cleanup. + */ + type ApplyDynamic >: Null <: TermTree with SymTree + + /** A tag that preserves the identity of the `ApplyDynamic` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val ApplyDynamicTag: ClassTag[ApplyDynamic] + + /** The constructor/deconstructor for `ApplyDynamic` instances. */ + val ApplyDynamic: ApplyDynamicExtractor + + /** An extractor class to create and pattern match with syntax `ApplyDynamic(qual, args)`. + * This AST node corresponds to the following Scala code: + * + * fun(args) + * + * The symbol of an ApplyDynamic is the function symbol of `qual`, or NoSymbol, if there is none. + */ + abstract class ApplyDynamicExtractor { + def apply(qual: Tree, args: List[Tree]): ApplyDynamic + def unapply(applyDynamic: ApplyDynamic): Option[(Tree, List[Tree])] + } + + /** Super reference, qual = corresponding this reference + * A super reference C.super[M] is represented as Super(This(C), M). + */ + type Super >: Null <: TermTree + + /** A tag that preserves the identity of the `Super` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val SuperTag: ClassTag[Super] + + /** The constructor/deconstructor for `Super` instances. */ + val Super: SuperExtractor + + /** An extractor class to create and pattern match with syntax `Super(qual, mix)`. + * This AST node corresponds to the following Scala code: + * + * C.super[M] + * + * Which is represented as: + * + * Super(This(C), M) + * + * If `mix` is empty, it is tpnme.EMPTY. + * + * The symbol of a Super is the class _from_ which the super reference is made. + * For instance in C.super(...), it would be C. + */ + abstract class SuperExtractor { + def apply(qual: Tree, mix: TypeName): Super + def unapply(super_ : Super): Option[(Tree, TypeName)] + } + + /** Self reference */ + type This >: Null <: TermTree with SymTree + + /** A tag that preserves the identity of the `This` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val ThisTag: ClassTag[This] + + /** The constructor/deconstructor for `This` instances. */ + val This: ThisExtractor + + /** An extractor class to create and pattern match with syntax `This(qual)`. + * This AST node corresponds to the following Scala code: + * + * qual.this + * + * The symbol of a This is the class to which the this refers. + * For instance in C.this, it would be C. + * + * If `mix` is empty, then ??? + */ + abstract class ThisExtractor { + def apply(qual: TypeName): This + def unapply(this_ : This): Option[TypeName] + } + + /** Designator <qualifier> . <name> */ + type Select >: Null <: RefTree + + /** A tag that preserves the identity of the `Select` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val SelectTag: ClassTag[Select] + + /** The constructor/deconstructor for `Select` instances. */ + val Select: SelectExtractor + + /** An extractor class to create and pattern match with syntax `Select(qual, name)`. + * This AST node corresponds to the following Scala code: + * + * qualifier.selector + */ + abstract class SelectExtractor { + def apply(qualifier: Tree, name: Name): Select + def unapply(select: Select): Option[(Tree, Name)] + } + + /** Identifier <name> */ + type Ident >: Null <: RefTree + + /** A tag that preserves the identity of the `Ident` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val IdentTag: ClassTag[Ident] + + /** The constructor/deconstructor for `Ident` instances. */ + val Ident: IdentExtractor + + /** An extractor class to create and pattern match with syntax `Ident(qual, name)`. + * This AST node corresponds to the following Scala code: + * + * name + * + * Type checker converts idents that refer to enclosing fields or methods to selects. + * For example, name ==> this.name + */ + abstract class IdentExtractor { + def apply(name: Name): Ident + def unapply(ident: Ident): Option[Name] + } + + /** Marks underlying reference to id as boxed. + * @pre id must refer to a captured variable + * A reference such marked will refer to the boxed entity, no dereferencing + * with `.elem` is done on it. + * This tree node can be emitted by macros such as reify that call referenceCapturedVariable. + * It is eliminated in LambdaLift, where the boxing conversion takes place. + */ + type ReferenceToBoxed >: Null <: TermTree + + /** A tag that preserves the identity of the `ReferenceToBoxed` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val ReferenceToBoxedTag: ClassTag[ReferenceToBoxed] + + /** The constructor/deconstructor for `ReferenceToBoxed` instances. */ + val ReferenceToBoxed: ReferenceToBoxedExtractor + + /** An extractor class to create and pattern match with syntax `ReferenceToBoxed(ident)`. + * This AST node does not have direct correspondence to Scala code, + * and is emitted by macros to reference capture vars directly without going through `elem`. + * + * For example: + * + * var x = ... + * fun { x } + * + * Will emit: + * + * Ident(x) + * + * Which gets transformed to: + * + * Select(Ident(x), "elem") + * + * If `ReferenceToBoxed` were used instead of Ident, no transformation would be performed. + */ + abstract class ReferenceToBoxedExtractor { + def apply(ident: Ident): ReferenceToBoxed + def unapply(referenceToBoxed: ReferenceToBoxed): Option[Ident] + } + + /** Literal */ + type Literal >: Null <: TermTree + + /** A tag that preserves the identity of the `Literal` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val LiteralTag: ClassTag[Literal] + + /** The constructor/deconstructor for `Literal` instances. */ + val Literal: LiteralExtractor + + /** An extractor class to create and pattern match with syntax `Literal(value)`. + * This AST node corresponds to the following Scala code: + * + * value + */ + abstract class LiteralExtractor { + def apply(value: Constant): Literal + def unapply(literal: Literal): Option[Constant] + } + + /** A tree that has an annotation attached to it. Only used for annotated types and + * annotation ascriptions, annotations on definitions are stored in the Modifiers. + * Eliminated by typechecker (typedAnnotated), the annotations are then stored in + * an AnnotatedType. + */ + type Annotated >: Null <: AnyRef with Tree + + /** A tag that preserves the identity of the `Annotated` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val AnnotatedTag: ClassTag[Annotated] + + /** The constructor/deconstructor for `Annotated` instances. */ + val Annotated: AnnotatedExtractor + + /** An extractor class to create and pattern match with syntax `Annotated(annot, arg)`. + * This AST node corresponds to the following Scala code: + * + * arg @annot // for types + * arg: @annot // for exprs + */ + abstract class AnnotatedExtractor { + def apply(annot: Tree, arg: Tree): Annotated + def unapply(annotated: Annotated): Option[(Tree, Tree)] + } + + /** Singleton type, eliminated by RefCheck */ + type SingletonTypeTree >: Null <: TypTree + + /** A tag that preserves the identity of the `SingletonTypeTree` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val SingletonTypeTreeTag: ClassTag[SingletonTypeTree] + + /** The constructor/deconstructor for `SingletonTypeTree` instances. */ + val SingletonTypeTree: SingletonTypeTreeExtractor + + /** An extractor class to create and pattern match with syntax `SingletonTypeTree(ref)`. + * This AST node corresponds to the following Scala code: + * + * ref.type + */ + abstract class SingletonTypeTreeExtractor { + def apply(ref: Tree): SingletonTypeTree + def unapply(singletonTypeTree: SingletonTypeTree): Option[Tree] + } + + /** Type selection <qualifier> # <name>, eliminated by RefCheck */ + // [Eugene++] don't see why we need it, when we have Select + type SelectFromTypeTree >: Null <: TypTree with RefTree + + /** A tag that preserves the identity of the `SelectFromTypeTree` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val SelectFromTypeTreeTag: ClassTag[SelectFromTypeTree] + + /** The constructor/deconstructor for `SelectFromTypeTree` instances. */ + val SelectFromTypeTree: SelectFromTypeTreeExtractor + + /** An extractor class to create and pattern match with syntax `SelectFromTypeTree(qualifier, name)`. + * This AST node corresponds to the following Scala code: + * + * qualifier # selector + * + * Note: a path-dependent type p.T is expressed as p.type # T + */ + abstract class SelectFromTypeTreeExtractor { + def apply(qualifier: Tree, name: TypeName): SelectFromTypeTree + def unapply(selectFromTypeTree: SelectFromTypeTree): Option[(Tree, TypeName)] + } + + /** Intersection type <parent1> with ... with <parentN> { <decls> }, eliminated by RefCheck */ + type CompoundTypeTree >: Null <: TypTree + + /** A tag that preserves the identity of the `CompoundTypeTree` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val CompoundTypeTreeTag: ClassTag[CompoundTypeTree] + + /** The constructor/deconstructor for `CompoundTypeTree` instances. */ + val CompoundTypeTree: CompoundTypeTreeExtractor + + /** An extractor class to create and pattern match with syntax `CompoundTypeTree(templ)`. + * This AST node corresponds to the following Scala code: + * + * parent1 with ... with parentN { refinement } + */ + abstract class CompoundTypeTreeExtractor { + def apply(templ: Template): CompoundTypeTree + def unapply(compoundTypeTree: CompoundTypeTree): Option[Template] + } + + /** Applied type <tpt> [ <args> ], eliminated by RefCheck */ + type AppliedTypeTree >: Null <: TypTree + + /** A tag that preserves the identity of the `AppliedTypeTree` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val AppliedTypeTreeTag: ClassTag[AppliedTypeTree] + + /** The constructor/deconstructor for `AppliedTypeTree` instances. */ + val AppliedTypeTree: AppliedTypeTreeExtractor + + /** An extractor class to create and pattern match with syntax `AppliedTypeTree(tpt, args)`. + * This AST node corresponds to the following Scala code: + * + * tpt[args] + */ + abstract class AppliedTypeTreeExtractor { + def apply(tpt: Tree, args: List[Tree]): AppliedTypeTree + def unapply(appliedTypeTree: AppliedTypeTree): Option[(Tree, List[Tree])] + } + + /** Document me! */ + type TypeBoundsTree >: Null <: TypTree + + /** A tag that preserves the identity of the `TypeBoundsTree` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val TypeBoundsTreeTag: ClassTag[TypeBoundsTree] + + /** The constructor/deconstructor for `TypeBoundsTree` instances. */ + val TypeBoundsTree: TypeBoundsTreeExtractor + + /** An extractor class to create and pattern match with syntax `TypeBoundsTree(lo, hi)`. + * This AST node corresponds to the following Scala code: + * + * >: lo <: hi + */ + abstract class TypeBoundsTreeExtractor { + def apply(lo: Tree, hi: Tree): TypeBoundsTree + def unapply(typeBoundsTree: TypeBoundsTree): Option[(Tree, Tree)] + } + + /** Document me! */ + type ExistentialTypeTree >: Null <: TypTree + + /** A tag that preserves the identity of the `ExistentialTypeTree` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val ExistentialTypeTreeTag: ClassTag[ExistentialTypeTree] + + /** The constructor/deconstructor for `ExistentialTypeTree` instances. */ + val ExistentialTypeTree: ExistentialTypeTreeExtractor + + /** An extractor class to create and pattern match with syntax `ExistentialTypeTree(tpt, whereClauses)`. + * This AST node corresponds to the following Scala code: + * + * tpt forSome { whereClauses } + */ + abstract class ExistentialTypeTreeExtractor { + def apply(tpt: Tree, whereClauses: List[Tree]): ExistentialTypeTree + def unapply(existentialTypeTree: ExistentialTypeTree): Option[(Tree, List[Tree])] + } + + /** A synthetic tree holding an arbitrary type. Not to be confused with + * with TypTree, the trait for trees that are only used for type trees. + * TypeTree's are inserted in several places, but most notably in + * `RefCheck`, where the arbitrary type trees are all replaced by + * TypeTree's. */ + type TypeTree >: Null <: TypTree + + /** A tag that preserves the identity of the `TypeTree` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val TypeTreeTag: ClassTag[TypeTree] + + /** The constructor/deconstructor for `TypeTree` instances. */ + val TypeTree: TypeTreeExtractor + + /** An extractor class to create and pattern match with syntax `TypeTree()`. + * This AST node does not have direct correspondence to Scala code, + * and is emitted by everywhere when we want to wrap a `Type` in a `Tree`. + */ + abstract class TypeTreeExtractor { + def apply(): TypeTree + def unapply(typeTree: TypeTree): Boolean + } + + /** ... */ + type Modifiers >: Null <: ModifiersBase + + /** A tag that preserves the identity of the `Modifiers` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val ModifiersTag: ClassTag[Modifiers] + + /** ... */ + abstract class ModifiersBase { + def flags: FlagSet + def hasFlag(flags: FlagSet): Boolean + def hasAllFlags(flags: FlagSet): Boolean + def privateWithin: Name // default: EmptyTypeName + def annotations: List[Tree] // default: List() + def mapAnnotations(f: List[Tree] => List[Tree]): Modifiers = + Modifiers(flags, privateWithin, f(annotations)) + } + + val Modifiers: ModifiersCreator + + abstract class ModifiersCreator { + def apply(): Modifiers = Modifiers(NoFlags, EmptyTypeName, List()) + def apply(flags: FlagSet, privateWithin: Name, annotations: List[Tree]): Modifiers + } + + def Modifiers(flags: FlagSet, privateWithin: Name): Modifiers = Modifiers(flags, privateWithin, List()) + def Modifiers(flags: FlagSet): Modifiers = Modifiers(flags, EmptyTypeName) + + /** ... */ + lazy val NoMods = Modifiers() + + // [Eugene++] temporarily moved here until SI-5863 is fixed +// ---------------------- factories ---------------------------------------------- + + /** @param sym the class symbol + * @param impl the implementation template + */ + def ClassDef(sym: Symbol, impl: Template): ClassDef + + /** + * @param sym the class symbol + * @param impl the implementation template + */ + def ModuleDef(sym: Symbol, impl: Template): ModuleDef + + def ValDef(sym: Symbol, rhs: Tree): ValDef + + def ValDef(sym: Symbol): ValDef + + def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef + + def DefDef(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree): DefDef + + def DefDef(sym: Symbol, mods: Modifiers, rhs: Tree): DefDef + + def DefDef(sym: Symbol, rhs: Tree): DefDef + + def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef + + /** A TypeDef node which defines given `sym` with given tight hand side `rhs`. */ + def TypeDef(sym: Symbol, rhs: Tree): TypeDef + + /** A TypeDef node which defines abstract type or type parameter for given `sym` */ + def TypeDef(sym: Symbol): TypeDef + + def LabelDef(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef + + /** Block factory that flattens directly nested blocks. + */ + def Block(stats: Tree*): Block + + /** casedef shorthand */ + def CaseDef(pat: Tree, body: Tree): CaseDef + + def Bind(sym: Symbol, body: Tree): Bind + + def Try(body: Tree, cases: (Tree, Tree)*): Try + + def Throw(tpe: Type, args: Tree*): Throw + + /** 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 + + /** 0-1 argument list new, based on a type. + */ + def New(tpe: Type, args: Tree*): Tree + + def New(sym: Symbol, args: Tree*): Tree + + def Apply(sym: Symbol, args: Tree*): Tree + + def ApplyConstructor(tpt: Tree, args: List[Tree]): Tree + + def Super(sym: Symbol, mix: TypeName): Tree + + def This(sym: Symbol): Tree + + def Select(qualifier: Tree, name: String): Select + + def Select(qualifier: Tree, sym: Symbol): Select + + def Ident(name: String): Ident + + def Ident(sym: Symbol): Ident + + def TypeTree(tp: Type): TypeTree +}
\ No newline at end of file diff --git a/src/library/scala/reflect/base/TypeCreator.scala b/src/library/scala/reflect/base/TypeCreator.scala new file mode 100644 index 0000000000..8a14e53dd3 --- /dev/null +++ b/src/library/scala/reflect/base/TypeCreator.scala @@ -0,0 +1,6 @@ +package scala.reflect +package base + +abstract class TypeCreator { + def apply[U <: Universe with Singleton](m: MirrorOf[U]): U # Type +} diff --git a/src/library/scala/reflect/api/TypeTags.scala b/src/library/scala/reflect/base/TypeTags.scala index c58b0fcec2..5c55f45cf7 100644 --- a/src/library/scala/reflect/api/TypeTags.scala +++ b/src/library/scala/reflect/base/TypeTags.scala @@ -4,7 +4,7 @@ */ package scala.reflect -package api +package base import java.lang.{ Class => jClass } import language.implicitConversions @@ -16,34 +16,29 @@ import language.implicitConversions * * === Overview === * - * Type tags are organized in a hierarchy of five classes: - * [[scala.reflect.ArrayTag]], [[scala.reflect.ErasureTag]], [[scala.reflect.ClassTag]], - * [[scala.reflect.api.Universe#TypeTag]] and [[scala.reflect.api.Universe#ConcreteTypeTag]]. + * Type tags are organized in a hierarchy of four classes: + * [[scala.reflect.ArrayTag]], [[scala.reflect.ClassTag]], + * [[scala.reflect.base.Universe#TypeTag]] and [[scala.reflect.base.Universe#ConcreteTypeTag]]. * * An [[scala.reflect.ArrayTag]] value carries knowledge about how to build an array of elements of type T. - * Typically such operation is performed by storing an erasure and instantiating arrays via Java reflection, + * Typically such operation is performed by storing an erasure and instantiating arrays via reflection, * but [[scala.reflect.ArrayTag]] only defines an interface, not an implementation, hence it only contains the factory methods * `newArray` and `wrap` that can be used to build, correspondingly, single-dimensional and multi-dimensional arrays. * - * An [[scala.reflect.ErasureTag]] value wraps a Java class, which can be accessed via the `erasure` method. - * This notion, previously embodied in a [[scala.reflect.ClassManifest]] together with the notion of array creation, - * deserves a concept of itself. Quite often (e.g. for serialization or classloader introspection) it's useful to - * know an erasure, and only it, so we've implemented this notion in [[scala.reflect.ErasureTag]]. - * - * A [[scala.reflect.ClassTag]] is a standard implementation of both [[scala.reflect.ArrayTag]] and [[scala.reflect.ErasureTag]]. + * A [[scala.reflect.ClassTag]] is a standard implementation of [[scala.reflect.ArrayTag]]. * It guarantees that the source type T did not to contain any references to type parameters or abstract types. * [[scala.reflect.ClassTag]] corresponds to a previous notion of [[scala.reflect.ClassManifest]]. * - * A [[scala.reflect.api.Universe#TypeTag]] value wraps a full Scala type in its tpe field. - * A [[scala.reflect.api.Universe#ConcreteTypeTag]] value is a [[scala.reflect.api.Universe#TypeTag]] + * A [[scala.reflect.base.Universe#TypeTag]] value wraps a full Scala type in its tpe field. + * A [[scala.reflect.base.Universe#ConcreteTypeTag]] value is a [[scala.reflect.base.Universe#TypeTag]] * that is guaranteed not to contain any references to type parameters or abstract types. - * Both flavors of TypeTags also carry an erasure, so [[scala.reflect.api.Universe#TypeTag]] is also an [[scala.reflect.ErasureTag]], - * and [[scala.reflect.api.Universe#ConcreteTypeTag]] is additionally an [[scala.reflect.ArrayTag]] and a [[scala.reflect.ClassTag]] * * It is recommended to use the tag supertypes of to precisely express your intent, i.e.: - * use ArrayTag when you want to construct arrays, - * use ErasureTag when you need an erasure and don't mind it being generated for untagged abstract types, - * use ClassTag only when you need an erasure of a type that doesn't refer to untagged abstract types. + * use ArrayTag when you just want to construct arrays, + * use ClassTag only when you need an erasure, e.g. for serialization or pattern matching. + * + * [Eugene++] also mention sensitivity to prefixes, i.e. that rb.TypeTag is different from ru.TypeTag + * [Eugene++] migratability between mirrors and universes is also worth mentioning * * === Splicing === * @@ -63,9 +58,9 @@ import language.implicitConversions * * Note that T has been replaced by String, because it comes with a TypeTag in f, whereas U was left as a type parameter. * - * === ErasureTag vs ClassTag and TypeTag vs ConcreteTypeTag === + * === TypeTag vs ConcreteTypeTag === * - * Be careful with ErasureTag and TypeTag, because they will reify types even if these types are abstract. + * Be careful with TypeTag, because it will reify types even if these types are abstract. * This makes it easy to forget to tag one of the methods in the call chain and discover it much later in the runtime * by getting cryptic errors far away from their source. For example, consider the following snippet: * @@ -77,7 +72,7 @@ import language.implicitConversions * } * * This fragment of Scala REPL implementation defines a `bind` function that carries a named value along with its type - * into the heart of the REPL. Using a [[scala.reflect.api.Universe#TypeTag]] here is reasonable, because it is desirable + * into the heart of the REPL. Using a [[scala.reflect.base.Universe#TypeTag]] here is reasonable, because it is desirable * to work with all types, even if they are type parameters or abstract type members. * * However if any of the three `TypeTag` context bounds is omitted, the resulting code will be incorrect, @@ -100,10 +95,11 @@ import language.implicitConversions * however there are a few caveats: * * 1) The notion of OptManifest is no longer supported. Tags can reify arbitrary types, so they are always available. - * // [Eugene] it might be useful, though, to guard against abstractness of the incoming type. + * // [Eugene++] it might be useful, though, to guard against abstractness of the incoming type. * - * 2) There's no equivalent for AnyValManifest. Consider comparing your tag with one of the core tags + * 2) There's no equivalent for AnyValManifest. Consider comparing your tag with one of the base tags * (defined in the corresponding companion objects) to find out whether it represents a primitive value class. + * You can also use `<tag>.tpe.typeSymbol.isPrimitiveValueClass` for that purpose (requires scala-reflect.jar). * * 3) There's no replacement for factory methods defined in `ClassManifest` and `Manifest` companion objects. * Consider assembling corresponding types using reflection API provided by Java (for classes) and Scala (for types). @@ -111,6 +107,7 @@ import language.implicitConversions * 4) Certain manifest functions (such as `<:<`, `>:>` and `typeArguments`) weren't included in the tag API. * Consider using reflection API provided by Java (for classes) and Scala (for types) instead. */ +// [Eugene++] implement serialization for typetags trait TypeTags { self: Universe => /** @@ -119,23 +116,19 @@ trait TypeTags { self: Universe => * In that value, any occurrences of type parameters or abstract types U * which come themselves with a TypeTag are represented by the type referenced by that TypeTag. * - * @see [[scala.reflect.api.TypeTags]] + * @see [[scala.reflect.base.TypeTags]] */ @annotation.implicitNotFound(msg = "No TypeTag available for ${T}") - trait TypeTag[T] extends ErasureTag[T] with Equals with Serializable { - + trait TypeTag[T] extends Equals with Serializable { + val mirror: Mirror + def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # TypeTag[T] def tpe: Type - def sym: Symbol = tpe.typeSymbol - - def isConcrete: Boolean = tpe.isConcrete - def notConcrete: Boolean = !isConcrete - def toConcrete: ConcreteTypeTag[T] = ConcreteTypeTag[T](tpe, erasure) /** case class accessories */ override def canEqual(x: Any) = x.isInstanceOf[TypeTag[_]] - override def equals(x: Any) = x.isInstanceOf[TypeTag[_]] && this.tpe == x.asInstanceOf[TypeTag[_]].tpe - override def hashCode = scala.runtime.ScalaRunTime.hash(tpe) - override def toString = if (!self.isInstanceOf[DummyMirror]) (if (isConcrete) "*ConcreteTypeTag" else "TypeTag") + "[" + tpe + "]" else "TypeTag[?]" + override def equals(x: Any) = x.isInstanceOf[TypeTag[_]] && this.mirror == x.asInstanceOf[TypeTag[_]].mirror && this.tpe == x.asInstanceOf[TypeTag[_]].tpe + override def hashCode = mirror.hashCode * 31 + tpe.hashCode + override def toString = "TypeTag[" + tpe + "]" } object TypeTag { @@ -150,16 +143,12 @@ trait TypeTags { self: Universe => val Unit : TypeTag[scala.Unit] = ConcreteTypeTag.Unit val Any : TypeTag[scala.Any] = ConcreteTypeTag.Any val Object : TypeTag[java.lang.Object] = ConcreteTypeTag.Object - val AnyVal : TypeTag[scala.AnyVal] = ConcreteTypeTag.AnyVal - val AnyRef : TypeTag[scala.AnyRef] = ConcreteTypeTag.AnyRef val Nothing : TypeTag[scala.Nothing] = ConcreteTypeTag.Nothing val Null : TypeTag[scala.Null] = ConcreteTypeTag.Null val String : TypeTag[java.lang.String] = ConcreteTypeTag.String - // todo. uncomment after I redo the starr - // def apply[T](tpe1: Type, erasure1: jClass[_]): TypeTag[T] = - def apply[T](tpe1: Type, erasure1: jClass[_]): TypeTag[T] = - tpe1 match { + def apply[T](mirror1: MirrorOf[self.type], tpec1: TypeCreator): TypeTag[T] = + tpec1(mirror1) match { case ByteTpe => TypeTag.Byte.asInstanceOf[TypeTag[T]] case ShortTpe => TypeTag.Short.asInstanceOf[TypeTag[T]] case CharTpe => TypeTag.Char.asInstanceOf[TypeTag[T]] @@ -171,58 +160,56 @@ trait TypeTags { self: Universe => case UnitTpe => TypeTag.Unit.asInstanceOf[TypeTag[T]] case AnyTpe => TypeTag.Any.asInstanceOf[TypeTag[T]] case ObjectTpe => TypeTag.Object.asInstanceOf[TypeTag[T]] - case AnyValTpe => TypeTag.AnyVal.asInstanceOf[TypeTag[T]] - case AnyRefTpe => TypeTag.AnyRef.asInstanceOf[TypeTag[T]] case NothingTpe => TypeTag.Nothing.asInstanceOf[TypeTag[T]] case NullTpe => TypeTag.Null.asInstanceOf[TypeTag[T]] case StringTpe => TypeTag.String.asInstanceOf[TypeTag[T]] - case _ => new TypeTag[T]{ def tpe = tpe1; def erasure = erasure1 } + case _ => new TypeTagImpl[T](mirror1.asInstanceOf[Mirror], tpec1) } def unapply[T](ttag: TypeTag[T]): Option[Type] = Some(ttag.tpe) } + private class TypeTagImpl[T](val mirror: Mirror, val tpec: TypeCreator) extends TypeTag[T] { + lazy val tpe: Type = tpec[self.type](mirror) + def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # TypeTag[T] = { + val otherMirror1 = otherMirror.asInstanceOf[MirrorOf[otherMirror.universe.type]] + otherMirror.universe.TypeTag[T](otherMirror1, tpec) + } + } + /** * If an implicit value of type u.ConcreteTypeTag[T] is required, the compiler will make one up on demand following the same procedure as for TypeTags. * However, if the resulting type still contains references to type parameters or abstract types, a static error results. * - * @see [[scala.reflect.api.TypeTags]] + * @see [[scala.reflect.base.TypeTags]] */ @annotation.implicitNotFound(msg = "No ConcreteTypeTag available for ${T}") - trait ConcreteTypeTag[T] extends TypeTag[T] with ClassTag[T] with Equals with Serializable { - if (!self.isInstanceOf[DummyMirror]) { - if (notConcrete) throw new Error("%s (%s) is not concrete and cannot be used to construct a concrete type tag".format(tpe, tpe.kind)) - } - + trait ConcreteTypeTag[T] extends TypeTag[T] with Equals with Serializable { /** case class accessories */ - override def canEqual(x: Any) = x.isInstanceOf[TypeTag[_]] // this is done on purpose. TypeTag(tpe) and ConcreteTypeTag(tpe) should be equal if tpe's are equal - override def equals(x: Any) = x.isInstanceOf[TypeTag[_]] && this.tpe == x.asInstanceOf[TypeTag[_]].tpe - override def hashCode = scala.runtime.ScalaRunTime.hash(tpe) - override def toString = if (!self.isInstanceOf[DummyMirror]) "ConcreteTypeTag[" + tpe + "]" else "ConcreteTypeTag[?]" + override def canEqual(x: Any) = x.isInstanceOf[ConcreteTypeTag[_]] + override def equals(x: Any) = x.isInstanceOf[ConcreteTypeTag[_]] && this.mirror == x.asInstanceOf[ConcreteTypeTag[_]].mirror && this.tpe == x.asInstanceOf[ConcreteTypeTag[_]].tpe + override def hashCode = mirror.hashCode * 31 + tpe.hashCode + override def toString = "ConcreteTypeTag[" + tpe + "]" } object ConcreteTypeTag { - val Byte : ConcreteTypeTag[scala.Byte] = new ConcreteTypeTag[scala.Byte]{ def tpe = ByteTpe; def erasure = ClassTag.Byte.erasure; private def readResolve() = ConcreteTypeTag.Byte } - val Short : ConcreteTypeTag[scala.Short] = new ConcreteTypeTag[scala.Short]{ def tpe = ShortTpe; def erasure = ClassTag.Short.erasure; private def readResolve() = ConcreteTypeTag.Short } - val Char : ConcreteTypeTag[scala.Char] = new ConcreteTypeTag[scala.Char]{ def tpe = CharTpe; def erasure = ClassTag.Char.erasure; private def readResolve() = ConcreteTypeTag.Char } - val Int : ConcreteTypeTag[scala.Int] = new ConcreteTypeTag[scala.Int]{ def tpe = IntTpe; def erasure = ClassTag.Int.erasure; private def readResolve() = ConcreteTypeTag.Int } - val Long : ConcreteTypeTag[scala.Long] = new ConcreteTypeTag[scala.Long]{ def tpe = LongTpe; def erasure = ClassTag.Long.erasure; private def readResolve() = ConcreteTypeTag.Long } - val Float : ConcreteTypeTag[scala.Float] = new ConcreteTypeTag[scala.Float]{ def tpe = FloatTpe; def erasure = ClassTag.Float.erasure; private def readResolve() = ConcreteTypeTag.Float } - val Double : ConcreteTypeTag[scala.Double] = new ConcreteTypeTag[scala.Double]{ def tpe = DoubleTpe; def erasure = ClassTag.Double.erasure; private def readResolve() = ConcreteTypeTag.Double } - val Boolean : ConcreteTypeTag[scala.Boolean] = new ConcreteTypeTag[scala.Boolean]{ def tpe = BooleanTpe; def erasure = ClassTag.Boolean.erasure; private def readResolve() = ConcreteTypeTag.Boolean } - val Unit : ConcreteTypeTag[scala.Unit] = new ConcreteTypeTag[scala.Unit]{ def tpe = UnitTpe; def erasure = ClassTag.Unit.erasure; private def readResolve() = ConcreteTypeTag.Unit } - val Any : ConcreteTypeTag[scala.Any] = new ConcreteTypeTag[scala.Any]{ def tpe = AnyTpe; def erasure = ClassTag.Any.erasure; private def readResolve() = ConcreteTypeTag.Any } - val Object : ConcreteTypeTag[java.lang.Object] = new ConcreteTypeTag[java.lang.Object]{ def tpe = ObjectTpe; def erasure = ClassTag.Object.erasure; private def readResolve() = ConcreteTypeTag.Object } - val AnyVal : ConcreteTypeTag[scala.AnyVal] = new ConcreteTypeTag[scala.AnyVal]{ def tpe = AnyValTpe; def erasure = ClassTag.AnyVal.erasure; private def readResolve() = ConcreteTypeTag.AnyVal } - val AnyRef : ConcreteTypeTag[scala.AnyRef] = new ConcreteTypeTag[scala.AnyRef]{ def tpe = AnyRefTpe; def erasure = ClassTag.AnyRef.erasure; private def readResolve() = ConcreteTypeTag.AnyRef } - val Nothing : ConcreteTypeTag[scala.Nothing] = new ConcreteTypeTag[scala.Nothing]{ def tpe = NothingTpe; def erasure = ClassTag.Nothing.erasure; private def readResolve() = ConcreteTypeTag.Nothing } - val Null : ConcreteTypeTag[scala.Null] = new ConcreteTypeTag[scala.Null]{ def tpe = NullTpe; def erasure = ClassTag.Null.erasure; private def readResolve() = ConcreteTypeTag.Null } - val String : ConcreteTypeTag[java.lang.String] = new ConcreteTypeTag[java.lang.String]{ def tpe = StringTpe; def erasure = ClassTag.String.erasure; private def readResolve() = ConcreteTypeTag.String } - - // todo. uncomment after I redo the starr - // def apply[T](tpe1: Type, erasure1: jClass[_]): ConcreteTypeTag[T] = - def apply[T](tpe1: Type, erasure1: jClass[_] = null): ConcreteTypeTag[T] = - tpe1 match { + val Byte: ConcreteTypeTag[scala.Byte] = new PredefConcreteTypeTag[scala.Byte] (ByteTpe, _.ConcreteTypeTag.Byte) + val Short: ConcreteTypeTag[scala.Short] = new PredefConcreteTypeTag[scala.Short] (ShortTpe, _.ConcreteTypeTag.Short) + val Char: ConcreteTypeTag[scala.Char] = new PredefConcreteTypeTag[scala.Char] (CharTpe, _.ConcreteTypeTag.Char) + val Int: ConcreteTypeTag[scala.Int] = new PredefConcreteTypeTag[scala.Int] (IntTpe, _.ConcreteTypeTag.Int) + val Long: ConcreteTypeTag[scala.Long] = new PredefConcreteTypeTag[scala.Long] (LongTpe, _.ConcreteTypeTag.Long) + val Float: ConcreteTypeTag[scala.Float] = new PredefConcreteTypeTag[scala.Float] (FloatTpe, _.ConcreteTypeTag.Float) + val Double: ConcreteTypeTag[scala.Double] = new PredefConcreteTypeTag[scala.Double] (DoubleTpe, _.ConcreteTypeTag.Double) + val Boolean: ConcreteTypeTag[scala.Boolean] = new PredefConcreteTypeTag[scala.Boolean] (BooleanTpe, _.ConcreteTypeTag.Boolean) + val Unit: ConcreteTypeTag[scala.Unit] = new PredefConcreteTypeTag[scala.Unit] (UnitTpe, _.ConcreteTypeTag.Unit) + val Any: ConcreteTypeTag[scala.Any] = new PredefConcreteTypeTag[scala.Any] (AnyTpe, _.ConcreteTypeTag.Any) + val Object: ConcreteTypeTag[java.lang.Object] = new PredefConcreteTypeTag[java.lang.Object] (ObjectTpe, _.ConcreteTypeTag.Object) + val Nothing: ConcreteTypeTag[scala.Nothing] = new PredefConcreteTypeTag[scala.Nothing] (NothingTpe, _.ConcreteTypeTag.Nothing) + val Null: ConcreteTypeTag[scala.Null] = new PredefConcreteTypeTag[scala.Null] (NullTpe, _.ConcreteTypeTag.Null) + val String: ConcreteTypeTag[java.lang.String] = new PredefConcreteTypeTag[java.lang.String] (StringTpe, _.ConcreteTypeTag.String) + + def apply[T](mirror1: MirrorOf[self.type], tpec1: TypeCreator): ConcreteTypeTag[T] = + tpec1(mirror1) match { case ByteTpe => ConcreteTypeTag.Byte.asInstanceOf[ConcreteTypeTag[T]] case ShortTpe => ConcreteTypeTag.Short.asInstanceOf[ConcreteTypeTag[T]] case CharTpe => ConcreteTypeTag.Char.asInstanceOf[ConcreteTypeTag[T]] @@ -234,21 +221,33 @@ trait TypeTags { self: Universe => case UnitTpe => ConcreteTypeTag.Unit.asInstanceOf[ConcreteTypeTag[T]] case AnyTpe => ConcreteTypeTag.Any.asInstanceOf[ConcreteTypeTag[T]] case ObjectTpe => ConcreteTypeTag.Object.asInstanceOf[ConcreteTypeTag[T]] - case AnyValTpe => ConcreteTypeTag.AnyVal.asInstanceOf[ConcreteTypeTag[T]] - case AnyRefTpe => ConcreteTypeTag.AnyRef.asInstanceOf[ConcreteTypeTag[T]] case NothingTpe => ConcreteTypeTag.Nothing.asInstanceOf[ConcreteTypeTag[T]] case NullTpe => ConcreteTypeTag.Null.asInstanceOf[ConcreteTypeTag[T]] case StringTpe => ConcreteTypeTag.String.asInstanceOf[ConcreteTypeTag[T]] - case _ => new ConcreteTypeTag[T]{ def tpe = tpe1; def erasure = erasure1 } + case _ => new ConcreteTypeTagImpl[T](mirror1.asInstanceOf[Mirror], tpec1) } - def unapply[T](ttag: TypeTag[T]): Option[Type] = if (ttag.isConcrete) Some(ttag.tpe) else None + def unapply[T](ttag: ConcreteTypeTag[T]): Option[Type] = Some(ttag.tpe) + } + + private class ConcreteTypeTagImpl[T](mirror: Mirror, tpec: TypeCreator) extends TypeTagImpl[T](mirror, tpec) with ConcreteTypeTag[T] { + override def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # TypeTag[T] = { + val otherMirror1 = otherMirror.asInstanceOf[MirrorOf[otherMirror.universe.type]] + otherMirror.universe.ConcreteTypeTag[T](otherMirror1, tpec) + } } - // incantations for summoning - // moved to Context, since rm.tags have their own incantations in Predef, and these guys are only useful in macros -// def tag[T](implicit ttag: TypeTag[T]) = ttag -// def typeTag[T](implicit ttag: TypeTag[T]) = ttag -// def concreteTag[T](implicit gttag: ConcreteTypeTag[T]) = cttag -// def concreteTypeTag[T](implicit gttag: ConcreteTypeTag[T]) = cttag + private class PredefConcreteTypeTag[T](_tpe: Type, copyIn: Universe => Universe # TypeTag[T]) extends ConcreteTypeTagImpl[T](rootMirror, null) { + override lazy val tpe: Type = _tpe + override def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # TypeTag[T] = + copyIn(otherMirror.universe).asInstanceOf[U # TypeTag[T]] + private def readResolve() = copyIn(self) + } + + // incantations + def typeTag[T](implicit ttag: TypeTag[T]) = ttag + def concreteTypeTag[T](implicit cttag: ConcreteTypeTag[T]) = cttag + + // big thanks to Viktor Klang for this brilliant idea! + def typeOf[T](implicit ttag: TypeTag[T]): Type = ttag.tpe } diff --git a/src/library/scala/reflect/base/Types.scala b/src/library/scala/reflect/base/Types.scala new file mode 100644 index 0000000000..6106e3fde7 --- /dev/null +++ b/src/library/scala/reflect/base/Types.scala @@ -0,0 +1,432 @@ +package scala.reflect +package base + +trait Types { self: Universe => + + /** The base API that all types support */ + abstract class TypeBase { + + /** The type symbol associated with the type, or `NoSymbol` for types + * that do not refer to a type symbol. + */ + def typeSymbol: Symbol + } + + /** The type of Scala types, and also Scala type signatures. + * (No difference is internally made between the two). + */ + type Type >: Null <: TypeBase + + /** A tag that preserves the identity of the `Type` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val TypeTagg: ClassTag[Type] // [Eugene++] rename! + + /** This constant is used as a special value that indicates that no meaningful type exists. + */ + val NoType: Type + + /** This constant is used as a special value denoting the empty prefix in a path dependent type. + * For instance `x.type` is represented as `SingleType(NoPrefix, <x>)`, where `<x>` stands for + * the symbol for `x`. + */ + val NoPrefix: Type + + /** The type of Scala singleton types, i.e. types that are inhabited + * by only one nun-null value. These include types of the forms + * {{{ + * C.this.type + * C.super.type + * x.type + * }}} + * as well as constant types. + */ + type SingletonType >: Null <: Type + + /** A tag that preserves the identity of the `SingletonType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val SingletonTypeTag: ClassTag[SingletonType] + + /** The `ThisType` type describes types of the form on the left with the + * correspnding ThisType representations to the right. + * {{{ + * C.this.type ThisType(C) + * }}} + */ + type ThisType >: Null <: AnyRef with SingletonType + + /** A tag that preserves the identity of the `ThisType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val ThisTypeTag: ClassTag[ThisType] + + /** The constructor/deconstructor for `ThisType` instances. */ + val ThisType: ThisTypeExtractor + + /** An extractor class to create and pattern match with syntax `ThisType(sym)` + * where `sym` is the class prefix of the this type. + */ + abstract class ThisTypeExtractor { + def apply(sym: Symbol): Type // not ThisTypebecause of implementation details + def unapply(tpe: ThisType): Option[Symbol] + } + + /** The `SingleType` type describes types of any of the forms on the left, + * with their TypeRef representations to the right. + * {{{ + * (T # x).type SingleType(T, x) + * p.x.type SingleType(p.type, x) + * x.type SingleType(NoPrefix, x) + * }}} + */ + type SingleType >: Null <: AnyRef with SingletonType + + /** A tag that preserves the identity of the `SingleType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val SingleTypeTag: ClassTag[SingleType] + + /** The constructor/deconstructor for `SingleType` instances. */ + val SingleType: SingleTypeExtractor + + /** An extractor class to create and pattern match with syntax `SingleType(pre, sym)` + * Here, `pre` is the prefix of the single-type, and `sym` is the stable value symbol + * referred to by the single-type. + */ + abstract class SingleTypeExtractor { + def apply(pre: Type, sym: Symbol): Type // not SingleTypebecause of implementation details + def unapply(tpe: SingleType): Option[(Type, Symbol)] + } + + /** The `SuperType` type is not directly written, but arises when `C.super` is used + * as a prefix in a `TypeRef` or `SingleType`. It's internal presentation is + * {{{ + * SuperType(thistpe, supertpe) + * }}} + * Here, `thistpe` is the type of the corresponding this-type. For instance, + * in the type arising from C.super, the `thistpe` part would be `ThisType(C)`. + * `supertpe` is the type of the super class referred to by the `super`. + */ + type SuperType >: Null <: AnyRef with SingletonType + + /** A tag that preserves the identity of the `SuperType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val SuperTypeTag: ClassTag[SuperType] + + /** The constructor/deconstructor for `SuperType` instances. */ + val SuperType: SuperTypeExtractor + + /** An extractor class to create and pattern match with syntax `SingleType(thistpe, supertpe)` + */ + abstract class SuperTypeExtractor { + def apply(thistpe: Type, supertpe: Type): Type // not SuperTypebecause of implementation details + def unapply(tpe: SuperType): Option[(Type, Type)] + } + + /** The `ConstantType` type is not directly written in user programs, but arises as the type of a constant. + * The REPL expresses constant types like Int(11). Here are some constants with their types. + * {{{ + * 1 ConstantType(Constant(1)) + * "abc" ConstantType(Constant("abc")) + * }}} + */ + type ConstantType >: Null <: AnyRef with SingletonType + + /** A tag that preserves the identity of the `ConstantType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val ConstantTypeTag: ClassTag[ConstantType] + + /** The constructor/deconstructor for `ConstantType` instances. */ + val ConstantType: ConstantTypeExtractor + + /** An extractor class to create and pattern match with syntax `ConstantType(constant)` + * Here, `constant` is the constant value represented by the type. + */ + abstract class ConstantTypeExtractor { + def apply(value: Constant): ConstantType + def unapply(tpe: ConstantType): Option[Constant] + } + + /** The `TypeRef` type describes types of any of the forms on the left, + * with their TypeRef representations to the right. + * {{{ + * T # C[T_1, ..., T_n] TypeRef(T, C, List(T_1, ..., T_n)) + * p.C[T_1, ..., T_n] TypeRef(p.type, C, List(T_1, ..., T_n)) + * C[T_1, ..., T_n] TypeRef(NoPrefix, C, List(T_1, ..., T_n)) + * T # C TypeRef(T, C, Nil) + * p.C TypeRef(p.type, C, Nil) + * C TypeRef(NoPrefix, C, Nil) + * }}} + */ + type TypeRef >: Null <: AnyRef with Type + + /** A tag that preserves the identity of the `TypeRef` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val TypeRefTag: ClassTag[TypeRef] + + /** The constructor/deconstructor for `TypeRef` instances. */ + val TypeRef: TypeRefExtractor + + /** An extractor class to create and pattern match with syntax `TypeRef(pre, sym, args)` + * Here, `pre` is the prefix of the type reference, `sym` is the symbol + * referred to by the type reference, and `args` is a possible empty list of + * type argumenrts. + */ + abstract class TypeRefExtractor { + def apply(pre: Type, sym: Symbol, args: List[Type]): Type // not TypeRefbecause of implementation details + def unapply(tpe: TypeRef): Option[(Type, Symbol, List[Type])] + } + + /** A subtype of Type representing refined types as well as `ClassInfo` signatures. + */ + type CompoundType >: Null <: AnyRef with Type + + /** A tag that preserves the identity of the `CompoundType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val CompoundTypeTag: ClassTag[CompoundType] + + /** The `RefinedType` type defines types of any of the forms on the left, + * with their RefinedType representations to the right. + * {{{ + * P_1 with ... with P_m { D_1; ...; D_n} RefinedType(List(P_1, ..., P_m), Scope(D_1, ..., D_n)) + * P_1 with ... with P_m RefinedType(List(P_1, ..., P_m), Scope()) + * { D_1; ...; D_n} RefinedType(List(AnyRef), Scope(D_1, ..., D_n)) + * }}} + */ + type RefinedType >: Null <: AnyRef with CompoundType + + /** A tag that preserves the identity of the `RefinedType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val RefinedTypeTag: ClassTag[RefinedType] + + /** The constructor/deconstructor for `RefinedType` instances. */ + val RefinedType: RefinedTypeExtractor + + /** An extractor class to create and pattern match with syntax `RefinedType(parents, decls)` + * Here, `parents` is the list of parent types of the class, and `decls` is the scope + * containing all declarations in the class. + */ + abstract class RefinedTypeExtractor { + def apply(parents: List[Type], decls: Scope): RefinedType + + /** An alternative constructor that passes in the synthetic classs symbol + * that backs the refined type. (Normally, a fresh class symbol is created automatically). + */ + def apply(parents: List[Type], decls: Scope, clazz: Symbol): RefinedType + def unapply(tpe: RefinedType): Option[(List[Type], Scope)] + } + + /** The `ClassInfo` type signature is used to define parents and declarations + * of classes, traits, and objects. If a class, trait, or object C is declared like this + * {{{ + * C extends P_1 with ... with P_m { D_1; ...; D_n} + * }}} + * its `ClassInfo` type has the following form: + * {{{ + * ClassInfo(List(P_1, ..., P_m), Scope(D_1, ..., D_n), C) + * }}} + */ + type ClassInfoType >: Null <: AnyRef with CompoundType + + /** A tag that preserves the identity of the `ClassInfoType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val ClassInfoTypeTag: ClassTag[ClassInfoType] + + /** The constructor/deconstructor for `ClassInfoType` instances. */ + val ClassInfoType: ClassInfoTypeExtractor + + /** An extractor class to create and pattern match with syntax `ClassInfo(parents, decls, clazz)` + * Here, `parents` is the list of parent types of the class, `decls` is the scope + * containing all declarations in the class, and `clazz` is the symbol of the class + * itself. + */ + abstract class ClassInfoTypeExtractor { + def apply(parents: List[Type], decls: Scope, typeSymbol: Symbol): ClassInfoType + def unapply(tpe: ClassInfoType): Option[(List[Type], Scope, Symbol)] + } + + /** The `MethodType` type signature is used to indicate parameters and result type of a method + */ + type MethodType >: Null <: AnyRef with Type + + /** A tag that preserves the identity of the `MethodType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val MethodTypeTag: ClassTag[MethodType] + + /** The constructor/deconstructor for `MethodType` instances. */ + val MethodType: MethodTypeExtractor + + /** An extractor class to create and pattern match with syntax `MethodType(params, respte)` + * Here, `params` is a potentially empty list of parameter symbols of the method, + * and `restpe` is the result type of the method. If the method is curried, `restpe` would + * be another `MethodType`. + * Note: `MethodType(Nil, Int)` would be the type of a method defined with an empty parameter list. + * {{{ + * def f(): Int + * }}} + * If the method is completely parameterless, as in + * {{{ + * def f: Int + * }}} + * its type is a `NullaryMethodType`. + */ + abstract class MethodTypeExtractor { + def apply(params: List[Symbol], resultType: Type): MethodType + def unapply(tpe: MethodType): Option[(List[Symbol], Type)] + } + + /** The `NullaryMethodType` type signature is used for parameterless methods + * with declarations of the form `def foo: T` + */ + type NullaryMethodType >: Null <: AnyRef with Type + + /** A tag that preserves the identity of the `NullaryMethodType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val NullaryMethodTypeTag: ClassTag[NullaryMethodType] + + /** The constructor/deconstructor for `NullaryMethodType` instances. */ + val NullaryMethodType: NullaryMethodTypeExtractor + + /** An extractor class to create and pattern match with syntax `NullaryMethodType(resultType)`. + * Here, `resultType` is the result type of the parameterless method. + */ + abstract class NullaryMethodTypeExtractor { + def apply(resultType: Type): NullaryMethodType + def unapply(tpe: NullaryMethodType): Option[(Type)] + } + + /** The `PolyType` type signature is used for polymorphic methods + * that have at least one type parameter. + */ + type PolyType >: Null <: AnyRef with Type + + /** A tag that preserves the identity of the `PolyType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val PolyTypeTag: ClassTag[PolyType] + + /** The constructor/deconstructor for `PolyType` instances. */ + val PolyType: PolyTypeExtractor + + /** An extractor class to create and pattern match with syntax `PolyType(typeParams, resultType)`. + * Here, `typeParams` are the type parameters of the method and `resultType` + * is the type signature following the type parameters. + */ + abstract class PolyTypeExtractor { + def apply(typeParams: List[Symbol], resultType: Type): PolyType + def unapply(tpe: PolyType): Option[(List[Symbol], Type)] + } + + /** The `ExistentialType` type signature is used for existential types and + * wildcard types. + */ + type ExistentialType >: Null <: AnyRef with Type + + /** A tag that preserves the identity of the `ExistentialType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val ExistentialTypeTag: ClassTag[ExistentialType] + + /** The constructor/deconstructor for `ExistentialType` instances. */ + val ExistentialType: ExistentialTypeExtractor + + /** An extractor class to create and pattern match with syntax + * `ExistentialType(quantified, underlying)`. + * Here, `quantified` are the type variables bound by the existential type and `underlying` + * is the type that's existentially quantified. + */ + abstract class ExistentialTypeExtractor { + def apply(quantified: List[Symbol], underlying: Type): ExistentialType + def unapply(tpe: ExistentialType): Option[(List[Symbol], Type)] + } + + /** The `AnnotatedType` type signature is used for annotated types of the + * for `<type> @<annotation>`. + */ + type AnnotatedType >: Null <: AnyRef with Type + + /** A tag that preserves the identity of the `AnnotatedType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val AnnotatedTypeTag: ClassTag[AnnotatedType] + + /** The constructor/deconstructor for `AnnotatedType` instances. */ + val AnnotatedType: AnnotatedTypeExtractor + + /** An extractor class to create and pattern match with syntax + * `AnnotatedType(annotations, underlying, selfsym)`. + * Here, `annotations` are the annotations decorating the underlying type `underlying`. + * `selfSym` is a symbol representing the annotated type itself. + */ + abstract class AnnotatedTypeExtractor { + def apply(annotations: List[AnnotationInfo], underlying: Type, selfsym: Symbol): AnnotatedType + def unapply(tpe: AnnotatedType): Option[(List[AnnotationInfo], Type, Symbol)] + } + + /** The `TypeBounds` type signature is used to indicate lower and upper type bounds + * of type parameters and abstract types. It is not a first-class type. + * If an abstract type or type parameter is declared with any of the forms + * on the left, its type signature is the TypeBounds type on the right. + * {{{ + * T >: L <: U TypeBounds(L, U) + * T >: L TypeBounds(L, Any) + * T <: U TypeBounds(Nothing, U) + * }}} + */ + type TypeBounds >: Null <: AnyRef with Type + + /** A tag that preserves the identity of the `TypeBounds` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val TypeBoundsTag: ClassTag[TypeBounds] + + /** The constructor/deconstructor for `TypeBounds` instances. */ + val TypeBounds: TypeBoundsExtractor + + /** An extractor class to create and pattern match with syntax `TypeBound(lower, upper)` + * Here, `lower` is the lower bound of the `TypeBounds` pair, and `upper` is + * the upper bound. + */ + abstract class TypeBoundsExtractor { + def apply(lo: Type, hi: Type): TypeBounds + def unapply(tpe: TypeBounds): Option[(Type, Type)] + } + + /** An object representing an unknown type, used during type inference. + * If you see WildcardType outside of inference it is almost certainly a bug. + */ + val WildcardType: Type + + /** 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. + */ + type BoundedWildcardType >: Null <: AnyRef with Type + + /** A tag that preserves the identity of the `BoundedWildcardType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val BoundedWildcardTypeTag: ClassTag[BoundedWildcardType] + + val BoundedWildcardType: BoundedWildcardTypeExtractor + + abstract class BoundedWildcardTypeExtractor { + def apply(bounds: TypeBounds): BoundedWildcardType + def unapply(tpe: BoundedWildcardType): Option[TypeBounds] + } +} diff --git a/src/library/scala/reflect/base/Universe.scala b/src/library/scala/reflect/base/Universe.scala new file mode 100644 index 0000000000..93ddcb9f55 --- /dev/null +++ b/src/library/scala/reflect/base/Universe.scala @@ -0,0 +1,18 @@ +package scala.reflect +package base + +abstract class Universe extends Symbols + with Types + with FlagSets + with Scopes + with Names + with Trees + with Constants + with AnnotationInfos + with Positions + with TypeTags + with TagInterop + with StandardDefinitions + with StandardNames + with BuildUtils + with Mirrors
\ No newline at end of file diff --git a/src/library/scala/reflect/compat.scala b/src/library/scala/reflect/compat.scala new file mode 100644 index 0000000000..7bfe9f38e1 --- /dev/null +++ b/src/library/scala/reflect/compat.scala @@ -0,0 +1,29 @@ +// [Eugene++] delete this once we merge with trunk and have a working IDE + +package scala.reflect { + trait ErasureTag[T] +} + +package scala.reflect.api { + trait TypeTags { + trait TypeTag[T] + trait ConcreteTypeTag[T] + } +} + +package scala { + import scala.reflect.base.{Universe => BaseUniverse} + + trait reflect_compat { + lazy val mirror: BaseUniverse = ??? + } +} + +package scala.reflect { + import language.experimental.macros + import scala.reflect.base.{Universe => BaseUniverse} + + trait internal_compat { + private[scala] def materializeErasureTag[T](u: BaseUniverse): ErasureTag[T] = ??? + } +}
\ No newline at end of file diff --git a/src/library/scala/reflect/makro/Aliases.scala b/src/library/scala/reflect/makro/Aliases.scala index 38b1065a40..d7dd111f22 100644 --- a/src/library/scala/reflect/makro/Aliases.scala +++ b/src/library/scala/reflect/makro/Aliases.scala @@ -8,14 +8,16 @@ trait Aliases { type Type = mirror.Type type Name = mirror.Name type Tree = mirror.Tree - type Position = mirror.Position + // type Position = mirror.Position type Scope = mirror.Scope type Modifiers = mirror.Modifiers type Expr[+T] = mirror.Expr[T] type TypeTag[T] = mirror.TypeTag[T] + type ConcreteTypeTag[T] = mirror.ConcreteTypeTag[T] /** Creator/extractor objects for Expr and TypeTag values */ val TypeTag = mirror.TypeTag + val ConcreteTypeTag = mirror.ConcreteTypeTag val Expr = mirror.Expr /** incantations for summoning tags */ diff --git a/src/library/scala/reflect/makro/Context.scala b/src/library/scala/reflect/makro/Context.scala index b0e15fd572..fb77405d37 100644 --- a/src/library/scala/reflect/makro/Context.scala +++ b/src/library/scala/reflect/makro/Context.scala @@ -14,12 +14,13 @@ trait Context extends Aliases with Reifiers with FrontEnds with Settings - with Symbols with Typers + with Exprs + with TypeTags with Util { /** The mirror that corresponds to the compile-time universe */ - val mirror: scala.reflect.api.Universe + val mirror: Universe /** The type of the prefix tree from which the macro is selected */ type PrefixType diff --git a/src/library/scala/reflect/makro/Exprs.scala b/src/library/scala/reflect/makro/Exprs.scala new file mode 100644 index 0000000000..ab0ea83d73 --- /dev/null +++ b/src/library/scala/reflect/makro/Exprs.scala @@ -0,0 +1,7 @@ +package scala.reflect.makro + +trait Exprs { + self: Context => + + def Expr[T: TypeTag](tree: Tree): Expr[T] +} diff --git a/src/library/scala/reflect/makro/FrontEnds.scala b/src/library/scala/reflect/makro/FrontEnds.scala index a1e24dcea3..d76907cdc8 100644 --- a/src/library/scala/reflect/makro/FrontEnds.scala +++ b/src/library/scala/reflect/makro/FrontEnds.scala @@ -1,10 +1,12 @@ package scala.reflect.makro -trait FrontEnds { +trait FrontEnds extends scala.reflect.api.FrontEnds { self: Context => import mirror._ + type Position = mirror.Position + /** Exposes means to control the compiler UI */ def frontEnd: FrontEnd def setFrontEnd(frontEnd: FrontEnd): this.type diff --git a/src/library/scala/reflect/makro/Reifiers.scala b/src/library/scala/reflect/makro/Reifiers.scala index b1de8d9957..0e0a4a765e 100644 --- a/src/library/scala/reflect/makro/Reifiers.scala +++ b/src/library/scala/reflect/makro/Reifiers.scala @@ -72,6 +72,6 @@ trait Reifiers { // made these guys non path-dependent, otherwise exception handling quickly becomes a mess -case class ReificationError(var pos: reflect.api.Position, val msg: String) extends Throwable(msg) +case class ReificationError(var pos: reflect.api.PositionApi, val msg: String) extends Throwable(msg) -case class UnexpectedReificationError(val pos: reflect.api.Position, val msg: String, val cause: Throwable = null) extends Throwable(msg, cause)
\ No newline at end of file +case class UnexpectedReificationError(val pos: reflect.api.PositionApi, val msg: String, val cause: Throwable = null) extends Throwable(msg, cause) diff --git a/src/library/scala/reflect/makro/Symbols.scala b/src/library/scala/reflect/makro/Symbols.scala deleted file mode 100644 index ca1c17534c..0000000000 --- a/src/library/scala/reflect/makro/Symbols.scala +++ /dev/null @@ -1,24 +0,0 @@ -package scala.reflect.makro - -trait Symbols { - self: Context => - - /** Can this symbol be loaded by a reflective mirror? - * - * Scalac relies on `ScalaSignature' annotation to retain symbols across compilation runs. - * Such annotations (also called "pickles") are applied on top-level classes and include information - * about all symbols reachable from the annotee. However, local symbols (e.g. classes or definitions local to a block) - * are typically unreachable and information about them gets lost. - * - * This method is useful for macro writers who wish to save certain ASTs to be used at runtime. - * With `isLocatable' it's possible to check whether a tree can be retained as is, or it needs special treatment. - */ - def isLocatable(sym: Symbol): Boolean - - /** 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(sym: Symbol): Boolean -}
\ No newline at end of file diff --git a/src/library/scala/reflect/makro/TreeBuilder.scala b/src/library/scala/reflect/makro/TreeBuilder.scala new file mode 100644 index 0000000000..3510932c13 --- /dev/null +++ b/src/library/scala/reflect/makro/TreeBuilder.scala @@ -0,0 +1,59 @@ +package scala.reflect.makro + +// [Eugene] I added some stuff that was necessary for typetag materialization macros +// but we should think it over and pick other generally useful stuff +// same goes for tree traversers/transformers, type maps, etc +// and once we expose all that, there's another question: how do we stay in sync? +abstract class TreeBuilder { + val global: Universe + + import global._ + import definitions._ + + /** 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 + + /** 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 + + /** Builds a typed reference to given symbol with given stable prefix. */ + def mkAttributedRef(pre: Type, sym: Symbol): Tree + + /** Builds a typed reference to given symbol. */ + def mkAttributedRef(sym: Symbol): Tree + + /** Builds a typed This reference to given symbol. */ + def mkAttributedThis(sym: Symbol): Tree + + /** Builds a typed Ident with an underlying symbol. */ + def mkAttributedIdent(sym: Symbol): Tree + + /** Builds a typed Select with an underlying symbol. */ + def mkAttributedSelect(qual: Tree, sym: Symbol): Tree + + /** 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 + def mkMethodCall(method: Symbol, targs: List[Type], args: List[Tree]): Tree + def mkMethodCall(method: Symbol, args: List[Tree]): Tree + def mkMethodCall(target: Tree, args: List[Tree]): Tree + def mkMethodCall(receiver: Symbol, methodName: Name, args: List[Tree]): Tree + def mkMethodCall(receiver: Tree, method: Symbol, targs: List[Type], args: List[Tree]): Tree + def mkMethodCall(target: Tree, targs: List[Type], args: List[Tree]): Tree + def mkNullaryCall(method: Symbol, targs: List[Type]): Tree +} diff --git a/src/library/scala/reflect/makro/TypeTags.scala b/src/library/scala/reflect/makro/TypeTags.scala new file mode 100644 index 0000000000..7b98f391a7 --- /dev/null +++ b/src/library/scala/reflect/makro/TypeTags.scala @@ -0,0 +1,8 @@ +package scala.reflect.makro + +trait TypeTags { + self: Context => + + def TypeTag[T](tpe: Type): TypeTag[T] + def ConcreteTypeTag[T](tpe: Type): ConcreteTypeTag[T] +} diff --git a/src/library/scala/reflect/makro/Universe.scala b/src/library/scala/reflect/makro/Universe.scala new file mode 100644 index 0000000000..d970e2474e --- /dev/null +++ b/src/library/scala/reflect/makro/Universe.scala @@ -0,0 +1,117 @@ +package scala.reflect.makro + +abstract class Universe extends scala.reflect.api.Universe { + + val treeBuild: TreeBuilder { val global: Universe.this.type } + + // Symbol extensions --------------------------------------------------------------- + + override type Symbol >: Null <: SymbolContextApi + + /** The extended API of symbols that's supported in macro context universes + */ + trait SymbolContextApi extends SymbolApi { this: Symbol => + + // [Eugene++ to Martin] should we also add mutability methods here (similarly to what's done below for trees)? + // I'm talking about `setAnnotations` and friends + + /** Can this symbol be loaded by a reflective mirror? + * + * Scalac relies on `ScalaSignature' annotation to retain symbols across compilation runs. + * Such annotations (also called "pickles") are applied on top-level classes and include information + * about all symbols reachable from the annotee. However, local symbols (e.g. classes or definitions local to a block) + * are typically unreachable and information about them gets lost. + * + * This method is useful for macro writers who wish to save certain ASTs to be used at runtime. + * With `isLocatable' it's possible to check whether a tree can be retained as is, or it needs special treatment. + */ + def isLocatable: Boolean + + /** 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: Boolean + } + + // Tree extensions --------------------------------------------------------------- + + override type Tree >: Null <: TreeContextApi + + /** The extended API of trees that's supported in macro context universes + */ + trait TreeContextApi extends TreeApi { this: Tree => + + /** ... */ + def pos_=(pos: Position): Unit + + /** ... */ + def setPos(newpos: Position): this.type + + /** ... */ + def tpe_=(t: Type): Unit + + /** Set tpe to give `tp` and return this. + */ + def setType(tp: Type): this.type + + /** Like `setType`, but if this is a previously empty TypeTree that + * fact is remembered so that resetAllAttrs will snap back. + * + * @PP: Attempting to elaborate on the above, I find: If defineType + * is called on a TypeTree whose type field is null or NoType, + * this is recorded as "wasEmpty = true". That value is used in + * ResetAttrsTraverser, which nulls out the type field of TypeTrees + * for which wasEmpty is true, leaving the others alone. + * + * resetAllAttrs is used in situations where some speculative + * typing of a tree takes place, fails, and the tree needs to be + * returned to its former state to try again. So according to me: + * using `defineType` instead of `setType` is how you communicate + * that the type being set does not depend on any previous state, + * and therefore should be abandoned if the current line of type + * inquiry doesn't work out. + */ + def defineType(tp: Type): this.type + + /** ... */ + def symbol_=(sym: Symbol): Unit + + /** ... */ + def setSymbol(sym: Symbol): this.type + + /** ... */ + def attachments: scala.reflect.base.Attachments { type Pos = Position } + + /** ... */ + def addAttachment(attachment: Any): this.type + + /** ... */ + def removeAttachment[T: ClassTag]: this.type + } + + override type SymTree >: Null <: Tree with SymTreeContextApi + + /** The extended API of sym trees that's supported in macro context universes + */ + trait SymTreeContextApi extends SymTreeApi { this: SymTree => + var symbol: Symbol + } + + override type TypeTree >: Null <: TypTree with TypeTreeContextApi + + /** The extended API of sym trees that's supported in macro context universes + */ + trait TypeTreeContextApi extends TypeTreeApi { this: TypeTree => + def setOriginal(tree: Tree): this.type + } + + override type Ident >: Null <: RefTree with IdentContextApi + + /** The extended API of idents that's supported in macro context universes + */ + trait IdentContextApi extends IdentApi { this: Ident => + def isBackquoted: Boolean + } +}
\ No newline at end of file diff --git a/src/library/scala/reflect/makro/internal/package.scala b/src/library/scala/reflect/makro/internal/package.scala index 4c4acec096..c0518384ab 100644 --- a/src/library/scala/reflect/makro/internal/package.scala +++ b/src/library/scala/reflect/makro/internal/package.scala @@ -1,17 +1,16 @@ package scala.reflect.makro import language.experimental.macros -import scala.reflect.api.{Universe => ApiUniverse} +import scala.reflect.base.{Universe => BaseUniverse} // anchors for materialization macros emitted during tag materialization in Implicits.scala // implementation is magically hardwired into `scala.reflect.reify.Taggers` // // todo. once we have implicit macros for tag generation, we can remove these anchors // [Eugene++] how do I hide this from scaladoc? -package object internal { - private[scala] def materializeArrayTag[T](u: ApiUniverse): ArrayTag[T] = macro ??? - private[scala] def materializeErasureTag[T](u: ApiUniverse): ErasureTag[T] = macro ??? - private[scala] def materializeClassTag[T](u: ApiUniverse): ClassTag[T] = macro ??? - private[scala] def materializeTypeTag[T](u: ApiUniverse): u.TypeTag[T] = macro ??? - private[scala] def materializeConcreteTypeTag[T](u: ApiUniverse): u.ConcreteTypeTag[T] = macro ??? +package object internal extends scala.reflect.internal_compat { + private[scala] def materializeArrayTag[T](u: BaseUniverse): ArrayTag[T] = macro ??? + private[scala] def materializeClassTag[T](u: BaseUniverse): ClassTag[T] = macro ??? + private[scala] def materializeTypeTag[T](u: BaseUniverse): u.TypeTag[T] = macro ??? + private[scala] def materializeConcreteTypeTag[T](u: BaseUniverse): u.ConcreteTypeTag[T] = macro ??? } diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala index 38a144cd49..ba93a1c91f 100644 --- a/src/library/scala/reflect/package.scala +++ b/src/library/scala/reflect/package.scala @@ -1,42 +1,8 @@ package scala -package object reflect { +package object reflect extends reflect_compat { - import ReflectionUtils._ - import scala.compat.Platform.EOL - - // !!! This was a val; we can't throw exceptions that aggressively without breaking - // non-standard environments, e.g. google app engine. I made it a lazy val, but - // I think it would be better yet to throw the exception somewhere else - not during - // initialization, but in response to a doomed attempt to utilize it. - - // todo. default mirror (a static object) might become a source for memory leaks (because it holds a strong reference to a classloader)! - lazy val mirror: api.Mirror = - try mkMirror(defaultReflectionClassLoader) - catch { - case ex: UnsupportedOperationException => - new DummyMirror(defaultReflectionClassLoader) - } - - private[scala] def mirrorDiagnostics(cl: ClassLoader): String = """ - | - | This error has happened because `scala.reflect.runtime.package` located in - | scala-compiler.jar cannot be loaded. Classloader you are using is: - | %s. - | - | For the instructions for some of the situations that might be relevant - | visit our knowledge base at https://gist.github.com/2391081. - """.stripMargin('|').format(show(cl)) - - def mkMirror(classLoader: ClassLoader): api.Mirror = { - val coreClassLoader = getClass.getClassLoader - val instance = invokeFactoryOpt(coreClassLoader, "scala.reflect.runtime.package", "mkMirror", classLoader) - instance match { - case Some(x: api.Mirror) => x - case Some(_) => throw new UnsupportedOperationException("Available scala reflection implementation is incompatible with this interface." + mirrorDiagnostics(coreClassLoader)) - case None => throw new UnsupportedOperationException("Scala reflection not available on this platform." + mirrorDiagnostics(coreClassLoader)) - } - } + lazy val basis: base.Universe = new base.Base @deprecated("Use `@scala.beans.BeanDescription` instead", "2.10.0") type BeanDescription = scala.beans.BeanDescription @@ -53,18 +19,12 @@ package object reflect { @deprecated("Use `@scala.beans.ScalaBeanInfo` instead", "2.10.0") type ScalaBeanInfo = scala.beans.ScalaBeanInfo - // ArrayTag trait is defined separately from the mirror - // ErasureTag trait is defined separately from the mirror - // ConcreteErasureTag trait is defined separately from the mirror - // ClassTag class is defined separately from the mirror - type TypeTag[T] = scala.reflect.mirror.TypeTag[T] - type ConcreteTypeTag[T] = scala.reflect.mirror.ConcreteTypeTag[T] - - // ClassTag object is defined separately from the mirror - lazy val TypeTag = scala.reflect.mirror.TypeTag - lazy val ConcreteTypeTag = scala.reflect.mirror.ConcreteTypeTag + // ArrayTag trait is defined outside the basis + // ClassTag class is defined outside the basis + type TypeTag[T] = scala.reflect.basis.TypeTag[T] + type ConcreteTypeTag[T] = scala.reflect.basis.ConcreteTypeTag[T] - def arrayTagToClassManifest[T](tag: ArrayTag[T]): ClassManifest[T] = TagInterop.arrayTagToClassManifest[T](tag) - def concreteTypeTagToManifest[T](tag: ConcreteTypeTag[T]): Manifest[T] = TagInterop.concreteTypeTagToManifest[T](tag) - def manifestToConcreteTypeTag[T](tag: Manifest[T]): ConcreteTypeTag[T] = TagInterop.manifestToConcreteTypeTag[T](tag) + // ClassTag object is defined outside the basis + lazy val TypeTag = scala.reflect.basis.TypeTag + lazy val ConcreteTypeTag = scala.reflect.basis.ConcreteTypeTag } |